Skip to content
Open
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
41 changes: 34 additions & 7 deletions genesis/ext/pyrender/viewer.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -1212,6 +1217,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()
Expand Down Expand Up @@ -1240,6 +1255,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()
Expand Down
4 changes: 2 additions & 2 deletions genesis/vis/visualizer.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,9 @@ 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":
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.")
Expand Down
2 changes: 2 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down
Loading