git.lucas.co / hou-control
SideFX Houdini customization package
git clone https://git.lucas.co/hou-control.git

commitd0f027dee592d6f580f4f926ff70cd57bfd7aec6
parent7bf6960b08
authorLucas Galante <[email protected]>
date2026-09-15 12:29
startup: main menu bar hidden by default, in both desktop modes

A startup.show_main_menu setting (default off, restart-only) that
uiready applies in attached mode too; only detached mode hid the bar
before, and showmenu.val is a persisted Houdini preference, so the
attached desktop kept whatever the last session left.

restartPending() treats a setting missing from the startup snapshot as
its schema default, so adding a setting and reloading mid-session does
not raise a false restart notice.

Co-Authored-By: Claude Fable 5.1 <[email protected]>

 python3.13libs/hc/hcschema.py   |  7 +++++++
 python3.13libs/hc/hcsettings.py | 12 ++++++++++--
 python3.13libs/uiready.py       | 11 ++++++++++-
 tools/check.py                  |  3 ++-
 4 files changed, 29 insertions(+), 4 deletions(-)

diff --git a/python3.13libs/hc/hcschema.py b/python3.13libs/hc/hcschema.py
index 600e279..47a8238 100644
--- a/python3.13libs/hc/hcschema.py
+++ b/python3.13libs/hc/hcschema.py
@@ -76,6 +76,13 @@ SCHEMA = {
         "default_autosave_state": Setting(
             "bool", True, label="Default Autosave State", restart=True,
         ),
+        "show_main_menu": Setting(
+            "bool", False, label="Show Main Menu Bar",
+            help="Houdini's main menu bar at startup. Hidden, its runnable "
+                 "entries are in the status circle's menu, which can also "
+                 "show the bar again.",
+            restart=True,
+        ),
     },
     "keycam": {
         "guides": {
diff --git a/python3.13libs/hc/hcsettings.py b/python3.13libs/hc/hcsettings.py
index 171a4d6..4d61e1f 100644
--- a/python3.13libs/hc/hcsettings.py
+++ b/python3.13libs/hc/hcsettings.py
@@ -192,8 +192,16 @@ class HCSettings:
         value this session started with -- what the panel's notice lists."""
         current = self.prefs()
         startup = self.startupValues()
-        return [path for path in hcschema.restart_paths()
-                if _dig(current, path) != _dig(startup, path)]
+        pending = []
+        for path in hcschema.restart_paths():
+            was = _dig(startup, path)
+            if was is None:
+                # A setting added to the schema after this session started
+                # (a reload after an edit) is not a change the user made.
+                was = hcschema.lookup(path).default
+            if _dig(current, path) != was:
+                pending.append(path)
+        return pending
 
     def desktopMode(self):
         return self.get("desktop_mode", self.DEFAULTS["desktop_mode"])
diff --git a/python3.13libs/uiready.py b/python3.13libs/uiready.py
index 9535eed..7a0d27d 100644
--- a/python3.13libs/uiready.py
+++ b/python3.13libs/uiready.py
@@ -66,6 +66,14 @@ _step("viewRegions", _startViewRegions)
 
 desktop_mode = HCSettings().desktopMode()
 
+
+def _applyMainMenuSetting():
+    """Houdini's main menu bar is a persisted preference (showmenu.val), so
+    without this the last session's choice would carry over regardless of
+    the setting."""
+    show = HCSettings().section("startup").get("show_main_menu", False)
+    hc_session.showMainMenu(int(bool(show)))
+
 if desktop_mode == "detached":
     def _deferredInit():
         """Two-phase deferred init for detached mode.
@@ -94,7 +102,7 @@ if desktop_mode == "detached":
                     break
             hc_session.toggleStowbars()
             hc_session.hideShelf()
-            hc_session.showMainMenu(0)
+            _applyMainMenuSetting()
             from hc import HCStatusBar
             HCStatusBar().show()
             from hc.hclayout import HCLayout
@@ -135,5 +143,6 @@ else:
 
     _step("set hc_attached desktop", _setDesktop)
     _step("toggleStowbars", hc_session.toggleStowbars)
+    _step("mainMenu", _applyMainMenuSetting)
     _step("splitHandles", lambda: hc_session.splitHandles().show())
     _step("statusBar", _showStatusBar)
diff --git a/tools/check.py b/tools/check.py
index b2491ea..8430840 100644
--- a/tools/check.py
+++ b/tools/check.py
@@ -170,7 +170,8 @@ def check_settings():
         with the snapshot uiready captured."""
         paths = hcschema.restart_paths()
         for expected in (("desktop_mode",), ("startup", "show_prompt"),
-                         ("startup", "default_autosave_state")):
+                         ("startup", "default_autosave_state"),
+                         ("startup", "show_main_menu")):
             assert expected in paths, f"{expected} not declared restart-only: {paths}"
         assert all(hcschema.lookup(p).restart for p in paths)
         assert not hcschema.lookup(("node_graph", "node_shape")).restart, \