SideFX Houdini customization package
git clone https://git.lucas.co/hou-control.git
hc: open the HC Panel for the pane under the cursor
_paneFromQtFocus looked up the pane containing the centre of the focused
Qt widget. Houdini draws its native panes into one RE_Window widget that
spans the whole desktop, so that widget's centre always fell in whichever
pane sat in the middle of the window -- the scene viewer -- and the HC
Panel listed scene viewer commands no matter which pane it was opened
over. The pane-under-cursor fallback never ran.
A focused widget now identifies a pane only when the pane encloses the
whole widget, which still covers Qt widgets docked in a pane such as the
HC Settings python panel. Anything larger says nothing about where the
user is and currentPane() falls through to hou.ui.paneUnderCursor().
Also rename the network editor's "Toggle Menu" command to "Toggle Network
Menu" so it reads as distinct from Toggle Main Menu and Toggle All Menus.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
python3.13libs/hc/hcnetworkeditor.py | 2 +-
python3.13libs/hc/hcsession.py | 30 ++++++++++++++++++------------
2 files changed, 19 insertions(+), 13 deletions(-)
diff --git a/python3.13libs/hc/hcnetworkeditor.py b/python3.13libs/hc/hcnetworkeditor.py
index e5f713b..2718c64 100644
--- a/python3.13libs/hc/hcnetworkeditor.py
+++ b/python3.13libs/hc/hcnetworkeditor.py
@@ -1081,7 +1081,7 @@ class HCNetworkEditor(HCPathTab):
# restored -- matching the original toggleMenus behaviour.
self.setMenuOpen(0)
- @command("Toggle Menu")
+ @command("Toggle Network Menu")
def toggleMenu(self):
map = {
'0': '1',
diff --git a/python3.13libs/hc/hcsession.py b/python3.13libs/hc/hcsession.py
index 2f51a4a..4d6acec 100644
--- a/python3.13libs/hc/hcsession.py
+++ b/python3.13libs/hc/hcsession.py
@@ -108,27 +108,33 @@ class HCSession:
return HCPane(hou_pane) if hou_pane is not None else None
def _paneFromQtFocus(self):
+ """The pane whose area encloses the focused Qt widget, or None.
+
+ Only a widget that sits entirely inside one pane counts -- a Python
+ panel such as HC Settings, say. Houdini draws its native panes into a
+ single RE_Window widget spanning the whole desktop, and that is what
+ has focus while you work in a network editor or scene viewer. Testing
+ that widget's centre used to hand back whichever pane happened to lie
+ under the middle of the window, so the HC Panel listed the scene
+ viewer's commands no matter which pane it was opened over. A widget
+ that no single pane encloses says nothing about where the user is,
+ and currentPane() falls through to the pane under the cursor.
+ """
app = QApplication.instance()
if app is None:
return None
- global_pos = None
focus_widget = app.focusWidget()
- if focus_widget is not None:
- rect = focus_widget.rect()
- global_pos = focus_widget.mapToGlobal(rect.center())
- else:
- active_window = app.activeWindow()
- if active_window is not None:
- rect = active_window.frameGeometry()
- global_pos = rect.center()
-
- if global_pos is None:
+ if focus_widget is None:
return None
+ top_left = focus_widget.mapToGlobal(focus_widget.rect().topLeft())
+ bottom_right = focus_widget.mapToGlobal(focus_widget.rect().bottomRight())
+
for pane in self.allPanes():
try:
- if pane.qtScreenGeometry().contains(global_pos):
+ geometry = pane.qtScreenGeometry()
+ if geometry.contains(top_left) and geometry.contains(bottom_right):
return pane.hou_pane
except Exception:
continue