I haven’t tried using shaders yet but I have also experienced some problems switching from Intel Mac (MacOS 10.9) to M1 Mac (MacOS 14.6, Python 3.12).
Most severely a crash when switching from “pseudo fullscreen” or “desktop fullscreen” (don’t know how you call it) to fullscreen.
I mean the mode that is activated when clicking the green button in the title bar. It used to be “maximize” or “zoom” but now it says “enter fullscreen”. When you activate that and then tell panda to switch to fullscreen the program crashes.
To replicate (a simple “hello world” program that accepts “f” to enter/exit fullscreen):
from direct.showbase.ShowBase import ShowBase
from panda3d import core
class MyApp(ShowBase):
def __init__(self):
ShowBase.__init__(self)
self.accept("f", self.toggle_fullscreen, [])
def toggle_fullscreen(self):
isFullscreen = self.win.getProperties().getFullscreen()
print(f"Fullscreen {isFullscreen}")
window_props = core.WindowProperties()
if not isFullscreen:
window_props.setFullscreen(True)
else:
window_props.setFullscreen(False)
self.win.requestProperties(window_props)
app = MyApp()
app.run()
I split off your posts to a new thread since they were not directly related to the original thread.
I can reproduce your problems with switching to fullscreen while macOS’ own fullscreen mode is active. I have checked in some fixes to Git, the next Panda release will not have these problems.
Panda’s fullscreen doesn’t play well with macOS’ fullscreen, so I made a change so that it will switch out of macOS’ fullscreen mode when switching to Panda’s fullscreen mode.
Maybe in the future we can think about how to better integrate these different fullscreen modes. Perhaps we should just use macOS’ fullscreen mode on versions that support it, if we can make the resolution switching work right.
Thank you for looking into this!
The problem is Panda knows only 3 window modes: windowed, minimized and fullscreen.
For comparison, in Godot there are 5:
WindowMode WINDOW_MODE_WINDOWED = 0
WindowMode WINDOW_MODE_MINIMIZED = 1
WindowMode WINDOW_MODE_MAXIMIZED = 2
WindowMode WINDOW_MODE_FULLSCREEN = 3
WindowMode WINDOW_MODE_EXCLUSIVE_FULLSCREEN = 4
(DisplayServer — Godot Engine (stable) documentation in English)
Another problem with this ‘non exclusive fullscreen’ mode is that the system mouse cursor remains hidden (in case you have your own mouse cursor like most games do) when you hit the upper edge of the screen which brings up the menu bar.
So, then there is no mouse cursor. I worked around it by temporarily unhiding the system cursor in this case:
def hide_system_cursor(self, do_hide):
window_props = core.WindowProperties()
window_props.setCursorHidden(do_hide)
self.win.requestProperties(window_props)
def unhide_system_cursor_temporarily_on_top_screen_edge(self, mouse_y):
""" check if mouse is at the top edge of the screen in 'non exclusive
fullscreen mode'.
On MacOS, make the system cursor reappear for a period of time
so that the now active menu bar and title bar can be used
Todo: What about Linux, Windows?
"""
props = self.win.getProperties()
if (not props.getFullscreen()
and self.pipe.get_display_width() == props.getXSize()
and self.pipe.get_display_height() == props.getYSize()
and mouse_y > 1 - 2/props.getYSize()):
pf = platform.system()
if pf == "Darwin":
if props.getCursorHidden():
self.hide_system_cursor(False)
self.taskMgr.doMethodLater(7.0, self.hide_system_cursor,
'Hide_System_Cursor', extraArgs=[True])
Does Godot map one of those to macOS’ native fullscreen mode?
Usually, the difference between non-exclusive and exclusive fullscreen mode is that the non-exclusive one is really just a screen-filling undecorated window, which you can do with the undecorated window property. It doesn’t necessarily have anything to do with macOS’ own fullscreen mode.
Possibly, these lines address the problem with the mouse cursor:
if (borderless_full) {
// If the window covers up the screen set the level to above the main menu and hide on deactivate.
[(NSWindow *)p_wd.window_object setLevel:NSMainMenuWindowLevel + 1];
[(NSWindow *)p_wd.window_object setHidesOnDeactivate:YES];
But if that means that the menu bar is suppressed completely (the window is always above the menu bar), then I don’t think it is a good solution.
Anyway, i think it’s important to be able to query which of these 5 modes are active when switching to and from fullscreen because when going fullscreen → windowed one doesn’t want to restore the window to either maximized or “borderless fullscreen” mode but to the original window size. But I noticed there is now (in 1.10.11) a method getMaximized() in addition to getMinimized() and getFullscreen() for the window properties. I think this is good enough since
props = self.win.get_properties()
not props.getFullscreen()
and self.pipe.get_display_width() == props.getXSize()
and self.pipe.get_display_height() == props.getYSize()
seems to be a suitable test for this “non exclusive” or borderless fullscreen mode.