Fullscreen for macOS

I’m trying to figure out how to make full screen on macOS. My configuration is:
macOS Monterey
Version 12.4
MacBook Pro (13-inch, M1, 2020)
Apple M1 chip

platform.python_version: 3.9.10
platform.machine: x86_64
base.win.gsg.driver_vendor: Apple
base.win.gsg.driver_renderer: Apple M1
base.win.gsg.supports_basic_shaders: True
PandaSystem.version_string: 1.10.11

Generally, I am aware that there are some problems with fullscreen (especially on macOS). I’ve seen a lot of posts about it, but to be honest, I don’t really understand the solutions they contain, or I don’t have how to apply them (I think tips like update drivers for the Nvidia card are of little use in my case).

My first attempt was according to the documentation which suggested enabling fullscreen in Config.prc. So I turned on:

fullscreen #t

Unfortunately, I got a crash at startup:

Known pipe types:
  CocoaGraphicsPipe
(all display modules loaded.)
:display:cocoadisplay(error): Could not find a suitable display mode!
:ShowBase(warning): Unable to open 'onscreen' window.
Traceback (most recent call last):
  File "/Users/miklesz/PycharmProjects/PointCloud/main.py", line 943, in <module>
    base = ShowBase()
  File "/Users/miklesz/PycharmProjects/PointCloud/venv/lib/python3.9/site-packages/direct/showbase/ShowBase.py", line 339, in __init__
    self.openDefaultWindow(startDirect = False, props=props)
  File "/Users/miklesz/PycharmProjects/PointCloud/venv/lib/python3.9/site-packages/direct/showbase/ShowBase.py", line 1024, in openDefaultWindow
    self.openMainWindow(*args, **kw)
  File "/Users/miklesz/PycharmProjects/PointCloud/venv/lib/python3.9/site-packages/direct/showbase/ShowBase.py", line 1059, in openMainWindow
    self.openWindow(*args, **kw)
  File "/Users/miklesz/PycharmProjects/PointCloud/venv/lib/python3.9/site-packages/direct/showbase/ShowBase.py", line 804, in openWindow
    raise Exception('Could not open window.')
Exception: Could not open window.

Process finished with exit code 1

Then I tried enabling full screen in runtime:

props = WindowProperties()
props.set_fullscreen(True)
base.win.request_properties(props)

There was no crash, but there was no effect either. Instead there was an error message:

Known pipe types:
  CocoaGraphicsPipe
(all display modules loaded.)
:display:cocoadisplay(error): Could not find a suitable display mode with size 800x600!

I tried to change the window size to several popular and known resolutions, including the popular full-screen (1920x1080) or the native resolution of my display (2560x1600), but with the same effect as above. In the end I decided to “get” display sizes:

props = WindowProperties()
props.set_size(base.pipe.get_display_width(), base.pipe.get_display_height())
props.set_fullscreen(True)
base.win.request_properties(props)

This finally allowed to set fullscreen, but unfortunately nothing is displayed, and on stdout I read:

Known pipe types:
  CocoaGraphicsPipe
(all display modules loaded.)
:display:gsg:glgsg(error): GL error 0x506 : invalid framebuffer operation
:display:gsg:glgsg(error): An OpenGL error has occurred.  Set gl-check-errors #t in your PRC file to display more information.
:display:gsg:glgsg(error): GL error 0x506 : invalid framebuffer operation
:display:gsg:glgsg(error): An OpenGL error has occurred.  Set gl-check-errors #t in your PRC file to display more information.

As suggested, in Config.prc I have set:

gl-check-errors #t

This made the display of more detailed information about the errors, but from my perspective equally unhelpful:

Known pipe types:
  CocoaGraphicsPipe
(all display modules loaded.)
:display:gsg:glgsg(error): at 3820 of panda/src/glstuff/glGraphicsStateGuardian_src.cxx : invalid framebuffer operation
:display:gsg:glgsg(error): at 5465 of panda/src/glstuff/glGraphicsStateGuardian_src.cxx : invalid framebuffer operation
:display:gsg:glgsg(error): at 5465 of panda/src/glstuff/glGraphicsStateGuardian_src.cxx : invalid framebuffer operation
:display:gsg:glgsg(error): at 4936 of panda/src/glstuff/glGraphicsStateGuardian_src.cxx : invalid framebuffer operation
:display:gsg:glgsg(error): at 4936 of panda/src/glstuff/glGraphicsStateGuardian_src.cxx : invalid framebuffer operation
:display:gsg:glgsg(error): at 4936 of panda/src/glstuff/glGraphicsStateGuardian_src.cxx : invalid framebuffer operation
:display:gsg:glgsg(error): at 4936 of panda/src/glstuff/glGraphicsStateGuardian_src.cxx : invalid framebuffer operation
:display:gsg:glgsg(error): at 4936 of panda/src/glstuff/glGraphicsStateGuardian_src.cxx : invalid framebuffer operation
:display:gsg:glgsg(error): at 4936 of panda/src/glstuff/glGraphicsStateGuardian_src.cxx : invalid framebuffer operation
:display:gsg:glgsg(error): at 4936 of panda/src/glstuff/glGraphicsStateGuardian_src.cxx : invalid framebuffer operation
:display:gsg:glgsg(error): at 4936 of panda/src/glstuff/glGraphicsStateGuardian_src.cxx : invalid framebuffer operation
:display:gsg:glgsg(error): at 4936 of panda/src/glstuff/glGraphicsStateGuardian_src.cxx : invalid framebuffer operation
:display:gsg:glgsg(error): at 4936 of panda/src/glstuff/glGraphicsStateGuardian_src.cxx : invalid framebuffer operation
:display:gsg:glgsg(error): at 4936 of panda/src/glstuff/glGraphicsStateGuardian_src.cxx : invalid framebuffer operation
:display:gsg:glgsg(error): at 4936 of panda/src/glstuff/glGraphicsStateGuardian_src.cxx : invalid framebuffer operation
:display:gsg:glgsg(error): at 4936 of panda/src/glstuff/glGraphicsStateGuardian_src.cxx : invalid framebuffer operation
:display:gsg:glgsg(error): at 4936 of panda/src/glstuff/glGraphicsStateGuardian_src.cxx : invalid framebuffer operation
:display:gsg:glgsg(error): at 4936 of panda/src/glstuff/glGraphicsStateGuardian_src.cxx : invalid framebuffer operation
:display:gsg:glgsg(error): at 4936 of panda/src/glstuff/glGraphicsStateGuardian_src.cxx : invalid framebuffer operation
:display:gsg:glgsg(error): at 4936 of panda/src/glstuff/glGraphicsStateGuardian_src.cxx : invalid framebuffer operation
:display(error): Deactivating CocoaGraphicsStateGuardian.

So right now, the only solution I found for macOS is to maximize the window in the area between the top system bar and the bottom dock, which I do as follows:

props = WindowProperties()
props.set_size(base.pipe.get_display_width(), base.pipe.get_display_height())
props.setOrigin((0, 0))
base.win.request_properties(props)

As a result, I have almost fullscreen, although unfortunately I lose a lot of space for the top system bar, the top bar of the window and the bottom dock:


In the screenshot, the window area is black, but this is only because there was nothing there when the screenshot was taken - normally everything renders properly there.
Interestingly, I can manually click the green circle ‘<>’ in the corner of the window to enter fullscreen. Then fullscreen actually turns on, although there is another problem - a bit incorrect aspect ratio. The image is stretched vertically - as if Panda3D only stretched the window vertically, and did not add an image to the area previously occupied by bars and docks.

Can anyone tell me some better solutions? Ideally, they should work cross-platform (at least macOS + Windows, optimally macOS + Windows + Linux). But as there are no cross-platform solutions, I can always do it on conditional statements after the platform is detected. At the same time, there is no major problem for Windows - the problems are on macOS.

I don’t know about the main issue described in this thread, but I may be able to help with the section that I’ve quoted above.

I’m guessing that what’s happening here is that your code doesn’t update the camera-lens to account for the change in the window’s aspect ratio. As a result, it’s rendering the same space within the scene, but outputting it to a window that no longer quite corresponds to that.

(This might be done by either a call to the lens’s “setFilmSize” method or its “setFov” method, I think, depending on which works better in your circumstances. See the API for details on those methods.)

1 Like

Thank you. This essentially solves the aspect ratio problem. Basically inspired by your suggestion, I found that I can just get and set the aspect ratio using getAspectRatio() and setAspectRatio() respectively.

While appreciating your answer, I must unfortunately emphasize that this is the least of the problems I describe in my original post. Still, in order to get a full screen in this way, I would have to automatically maximize the window at the beginning, and I have no idea how to do it. Apparently I found a thread on this forum discussing this problem, but it doesn’t seem to provide a definite solution - at least not for macOS:

1 Like

Sure–I just don’t know the answer to the rest, offhand. So I answered to what I did know.

Of course, I fully understand. Thank you so much for the hint with the aspect ratio. Now maybe someone else will know the answer to any of the remaining questions and so, step by step, a solution will be found. :slight_smile:

1 Like

That’s fair, and it’s my pleasure! And indeed, hopefully someone else will have an answer to those other, more-serious problems.

(Although I’ll note that today is Sunday, so the forum might be quiet today.)

1 Like