Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed cocoa window content visibilty in app full screen #2800

Merged
merged 5 commits into from
Sep 2, 2024
Merged
Show file tree
Hide file tree
Changes from 3 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
1 change: 1 addition & 0 deletions changes/2796.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
The children of a window with a ``toga.Box()`` as its content are now visible in app full-screen mode.
16 changes: 12 additions & 4 deletions cocoa/src/toga_cocoa/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -379,12 +379,20 @@ def enter_full_screen(self, windows):
)

for window, screen in zip(windows, NSScreen.screens):
window.content._impl.native.enterFullScreenMode(screen, withOptions=opts)
# The widgets are actually added to window._impl.container.native, instead of
# window.content._impl.native. And window._impl.native.contentView is
# window._impl.container.native. But, directly using window._impl.container.native
# would be more implementation specific and likely to break with any future
# implementation changes. Hence, use window._impl.native.contentView, which is
# guaranteed to be present and assigned on a NSWindow.
#
# Hence, we need to go fullscreen on window._impl.native.contentView instead.
window._impl.content_view.enterFullScreenMode(screen, withOptions=opts)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

As a bonus effect of using window._impl.native.contentView, we can lift the requirement of needing a content to be assigned to a window in cocoa, for entering into PRESENTATION mode in #2473

# Going full screen causes the window content to be re-homed
# in a NSFullScreenWindow; teach the new parent window
# about its Toga representations.
window.content._impl.native.window._impl = window._impl
window.content._impl.native.window.interface = window
window._impl.content_view.window._impl = window._impl
window._impl.content_view.window.interface = window
window.content.refresh()

def exit_full_screen(self, windows):
Expand All @@ -394,5 +402,5 @@ def exit_full_screen(self, windows):
)

for window in windows:
window.content._impl.native.exitFullScreenModeWithOptions(opts)
window._impl.content_view.exitFullScreenModeWithOptions(opts)
window.content.refresh()
5 changes: 5 additions & 0 deletions cocoa/src/toga_cocoa/window.py
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,11 @@ def __init__(self, interface, title, position, size):
self.container = Container(on_refresh=self.content_refreshed)
self.native.contentView = self.container.native

# In app full-screen mode, window._impl.native.contentView is moved to a
# _NSFullScreenWindow, making NSWindow.contentView as None. Hence, retain a
# reference to the view before going full-screen.
self.content_view = self.native.contentView
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Full explaination comment that I had previously written, but felt too big to include in the source file:

Once we go fullscreen on window._impl.native.contentView, the view referenced by window._impl.native.contentView is detached from the current native NSWindow, and attached to a _NSFullScreenWindow. And the view can remain attached to 1 native window at a time i.e., either to NSWindow or NSFullScreenWindow, but not to both.

Hence, we can no longer accesss the view by window._impl.native.contentView, since window._impl.native.contentView will be None. So, it is useful to retain a reference to the view attached to window._impl.native.contentView, before going fullscreen or doing any other operation that would displace the contentView from the current window.

Copy link
Member

Choose a reason for hiding this comment

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

You may not be able to reference _impl.native.contentView, but you can reference _impl.container.native. That keeps the container as a source of truth, and removes any bugs that could leak in if the container content is changed but content_view isn't updated.


# Ensure that the container renders it's background in the same color as the window.
self.native.wantsLayer = True
self.container.native.backgroundColor = self.native.backgroundColor
Expand Down
2 changes: 1 addition & 1 deletion cocoa/tests_backend/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ def is_cursor_visible(self):
return self.app._impl._cursor_visible

def is_full_screen(self, window):
return window.content._impl.native.isInFullScreenMode()
return window._impl.content_view.isInFullScreenMode()

def content_size(self, window):
return (
Expand Down
Loading