Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 4 additions & 14 deletions engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -1040,21 +1040,11 @@ def _create_dialog(self, title, bundle, widget, parent):
dialog.raise_()
dialog.activateWindow()

# special case to get windows to raise the dialog
if sgtk.util.is_windows():
# Anything beyond 16.5.481 bundles a PySide2 version that gives us
# a usable hwnd directly. We also check to make sure this is Qt5,
# since SideFX still offers Qt4/PySide builds of modern Houdinis.
if hou.applicationVersion() >= (
16,
5,
481,
) and QtCore.__version__.startswith("5."):
hwnd = dialog.winId()
else:
ctypes.pythonapi.PyCObject_AsVoidPtr.restype = ctypes.c_void_p
ctypes.pythonapi.PyCObject_AsVoidPtr.argtypes = [ctypes.py_object]
hwnd = ctypes.pythonapi.PyCObject_AsVoidPtr(dialog.winId())
# special case to get windows to raise the dialog

hwnd = dialog.winId()

ctypes.windll.user32.SetActiveWindow(hwnd)

Comment on lines 1048 to 1049
Copy link

Copilot AI Sep 9, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code assumes dialog.winId() returns a valid Windows handle without validation. This could fail if winId() returns None or an invalid handle, potentially causing ctypes.windll.user32.SetActiveWindow to fail silently or raise an exception.

Suggested change
ctypes.windll.user32.SetActiveWindow(hwnd)
# Validate hwnd before using it
if hwnd is not None and int(hwnd) != 0:
ctypes.windll.user32.SetActiveWindow(hwnd)
else:
self.logger.warning(
"Could not activate dialog window: invalid winId() returned ({})".format(hwnd)
)

Copilot uses AI. Check for mistakes.
return dialog
Expand Down
27 changes: 27 additions & 0 deletions startup.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,33 @@ def prepare_launch(self, exec_path, args, file_to_open=None):

self.logger.debug("Launch environment: %s" % (required_env,))

# TODO - only for Houdini version 21.0+
enable_sg_menu = self.get_setting("enable_sg_menu", True)
if enable_sg_menu:

class MockEngine:
pass

mock_engine = MockEngine()
mock_engine.logger = self.logger

mock_engine._menu_name = "Flow Production Tracking"
if self.get_setting("use_short_menu_name", False):
mock_engine._menu_name = "FPTR"
Comment on lines +139 to +146
Copy link

Copilot AI Sep 9, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Creating a mock engine class inline with dynamic attribute assignment is fragile. Consider defining a proper MockEngine class with init method or using a more structured approach like a namedtuple or dataclass.

Suggested change
pass
mock_engine = MockEngine()
mock_engine.logger = self.logger
mock_engine._menu_name = "Flow Production Tracking"
if self.get_setting("use_short_menu_name", False):
mock_engine._menu_name = "FPTR"
def __init__(self, logger, menu_name):
self.logger = logger
self._menu_name = menu_name
menu_name = "Flow Production Tracking"
if self.get_setting("use_short_menu_name", False):
menu_name = "FPTR"
mock_engine = MockEngine(self.logger, menu_name)

Copilot uses AI. Check for mistakes.

import tk_houdini
Copy link

Copilot AI Sep 9, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The import statement should be moved to the top of the file with other imports to follow Python best practices and improve code readability.

Copilot uses AI. Check for mistakes.

xml_tmp_dir = required_env[bootstrap.g_temp_env]
menu_file = os.path.join(xml_tmp_dir, "MainMenuCommon.xml").replace(
os.path.sep, "/"
)

menu = tk_houdini.AppCommandsMenu(mock_engine, [])
self.logger.debug(
"Constructing dynamic PTR menu - before starting Houdini - special 21.0 behaviour"
)
menu._create_dynamic_menu(menu_file)

return LaunchInformation(exec_path, args, required_env)

def scan_software(self):
Expand Down