From 8639873a71cc78bbea387e3867cd2d65582c6eed Mon Sep 17 00:00:00 2001 From: BartR Date: Sun, 21 Dec 2025 18:44:48 +0100 Subject: [PATCH 1/3] macos viewer fix --- genesis/ext/pyrender/viewer.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/genesis/ext/pyrender/viewer.py b/genesis/ext/pyrender/viewer.py index fbbf92bbb1..a52cd8ce60 100644 --- a/genesis/ext/pyrender/viewer.py +++ b/genesis/ext/pyrender/viewer.py @@ -1212,6 +1212,16 @@ def start(self, auto_refresh=True): self.set_caption(self.viewer_flags["window_title"]) self.activate() + # On macOS, we need to explicitly activate the app to bring the window to focus + # when running from terminal (not as a bundled .app) + if sys.platform.startswith("darwin"): + try: + from AppKit import NSApp, NSApplication + NSApplication.sharedApplication() + NSApp.activateIgnoringOtherApps_(True) + except ImportError: + gs.logger.debug("PyObjC not available, window may not come to focus automatically") + # The viewer can be considered as fully initialized at this point if not self._initialized_event.is_set(): self._initialized_event.set() @@ -1240,6 +1250,18 @@ def run(self): elif threading.main_thread() != threading.current_thread(): raise RuntimeError("'Viewer.run' can only be called manually from main thread on MacOS.") + # On macOS, we need to explicitly activate the app to bring the window to focus + # when running from terminal (not as a bundled .app) + if sys.platform.startswith("darwin"): + try: + from AppKit import NSApp, NSApplication + NSApplication.sharedApplication() + NSApp.activateIgnoringOtherApps_(True) + # Also request the window to be frontmost + self.activate() + except ImportError: + gs.logger.debug("PyObjC not available, window may not come to focus automatically") + while self._is_active: try: self.refresh() From 5e91042d514312da802a3154bc8720b332b2e5f2 Mon Sep 17 00:00:00 2001 From: BartR Date: Tue, 30 Dec 2025 12:45:56 +0100 Subject: [PATCH 2/3] some additional fixes --- genesis/vis/visualizer.py | 2 +- pyproject.toml | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/genesis/vis/visualizer.py b/genesis/vis/visualizer.py index 51524abbf1..c7c96221e4 100644 --- a/genesis/vis/visualizer.py +++ b/genesis/vis/visualizer.py @@ -66,7 +66,7 @@ def __init__(self, scene, show_viewer, vis_options, viewer_options, renderer_opt if viewer_options.run_in_thread is None: if sys.platform == "linux": viewer_options.run_in_thread = True - elif sys.platform == "darwin": + elif sys.platform == "darwin" or gs.platform == "macOS": viewer_options.run_in_thread = False elif sys.platform == "win32": viewer_options.run_in_thread = True diff --git a/pyproject.toml b/pyproject.toml index 0f5ff142f5..682c9fb783 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -66,6 +66,8 @@ dependencies = [ "fast_simplification>=0.1.12", # Surface reconstruction library for particle data from SPH simulations "pysplashsurf==0.14.*", + # Used on macOS to properly bring the viewer window to focus when running from terminal + "pyobjc-framework-Cocoa; sys_platform == 'darwin'", ] [project.optional-dependencies] From b6ebc167d870e4ac58b8555276ba11ef83d19c0c Mon Sep 17 00:00:00 2001 From: BartR Date: Fri, 20 Mar 2026 13:14:56 +0100 Subject: [PATCH 3/3] mac 23 adaptations --- genesis/ext/pyrender/viewer.py | 19 ++++++++++++------- genesis/vis/visualizer.py | 2 +- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/genesis/ext/pyrender/viewer.py b/genesis/ext/pyrender/viewer.py index a52cd8ce60..fa29be1551 100644 --- a/genesis/ext/pyrender/viewer.py +++ b/genesis/ext/pyrender/viewer.py @@ -19,16 +19,21 @@ # Importing tkinter and creating a first context before importing pyglet is necessary to avoid later segfault on MacOS. # Note that destroying the window will cause segfault at exit. +# On macOS 26+ (Darwin 25, Tahoe), system Tk 8.5 crashes on init due to a Darwin/product version mismatch. +# The pyglet segfault workaround is not needed on macOS 26+. root = None if sys.platform.startswith("darwin"): - try: - from tkinter import Tk + import platform as _platform + _mac_major = int(_platform.mac_ver()[0].split(".")[0]) if _platform.mac_ver()[0] else 0 + if _mac_major < 26: + try: + from tkinter import Tk - root = Tk() - root.withdraw() - except Exception: - # Some minimal Python install may not provide a working tkinter interface even if it is a standard library - pass + root = Tk() + root.withdraw() + except Exception: + # Some minimal Python install may not provide a working tkinter interface even if it is a standard library + pass import pyglet diff --git a/genesis/vis/visualizer.py b/genesis/vis/visualizer.py index c7c96221e4..b539d866c5 100644 --- a/genesis/vis/visualizer.py +++ b/genesis/vis/visualizer.py @@ -68,7 +68,7 @@ def __init__(self, scene, show_viewer, vis_options, viewer_options, renderer_opt viewer_options.run_in_thread = True elif sys.platform == "darwin" or gs.platform == "macOS": viewer_options.run_in_thread = False - elif sys.platform == "win32": + elif sys.platform == "win32" or gs.platform == "Windows": viewer_options.run_in_thread = True if sys.platform == "darwin" and viewer_options.run_in_thread: gs.raise_exception("Running viewer in background thread is not supported on MacOS.")