Skip to content

Commit

Permalink
Fixed Android backend
Browse files Browse the repository at this point in the history
  • Loading branch information
proneon267 committed Jul 7, 2024
1 parent 71f4314 commit ccc8f11
Show file tree
Hide file tree
Showing 4 changed files with 112 additions and 38 deletions.
74 changes: 47 additions & 27 deletions android/src/toga_android/window.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,11 @@ def get_visible(self):
######################################################################

def get_window_state(self):
# Windows are always full screen
# window.state is called in _close(), which itself sometimes
# is called during early stages of app startup, during which
# the app attribute may not exist. In such cases, return NORMAL.
if getattr(self, "app", None) is None:
return WindowState.NORMAL
decor_view = self.app.native.getWindow().getDecorView()
system_ui_flags = decor_view.getSystemUiVisibility()
if system_ui_flags & (
Expand All @@ -162,33 +166,49 @@ def get_window_state(self):
def set_window_state(self, state):
current_state = self.get_window_state()
decor_view = self.app.native.getWindow().getDecorView()
# On Android Maximized state is same as the Normal state
if state in {WindowState.NORMAL, WindowState.MAXIMIZED}:
if current_state in {
WindowState.FULLSCREEN,
WindowState.PRESENTATION,
}:
decor_view.setSystemUiVisibility(0)
if current_state == WindowState.PRESENTATION:
# Marking this as no branch, since the testbed can't create a simple
# window, so we can't test the other branch.
if self._actionbar_shown_by_default: # pragma: no branch
self.app.native.getSupportActionBar().show()
self._is_presentation_mode = False
else:
if (
current_state != WindowState.NORMAL
and state != WindowState.NORMAL
and (getattr(self, "_pending_window_state_transition", None) is None)
):
# Set Window state to NORMAL before changing to other states as some
# states block changing window state without first exiting them or
# can even cause rendering glitches.
self._pending_window_state_transition = state
self.set_window_state(WindowState.NORMAL)
if state in {WindowState.FULLSCREEN, WindowState.PRESENTATION}:
decor_view.setSystemUiVisibility(
decor_view.SYSTEM_UI_FLAG_FULLSCREEN
| decor_view.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| decor_view.SYSTEM_UI_FLAG_IMMERSIVE
)
if state == WindowState.PRESENTATION:
# Marking this as no branch, since the testbed can't create a simple
# window, so we can't test the other branch.
if self._actionbar_shown_by_default: # pragma: no branch
self.app.native.getSupportActionBar().hide()
self._is_presentation_mode = True

elif state in {WindowState.FULLSCREEN, WindowState.PRESENTATION}:
decor_view.setSystemUiVisibility(
decor_view.SYSTEM_UI_FLAG_FULLSCREEN
| decor_view.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| decor_view.SYSTEM_UI_FLAG_IMMERSIVE
)
if state == WindowState.PRESENTATION:
# Marking this as no branch, since the testbed can't create a simple
# window, so we can't test the other branch.
if self._actionbar_shown_by_default: # pragma: no branch
self.app.native.getSupportActionBar().hide()
self._is_presentation_mode = True

else:
# On Android Maximized state is same as the Normal state
if state in {WindowState.NORMAL, WindowState.MAXIMIZED}:
if current_state in {
WindowState.FULLSCREEN,
WindowState.PRESENTATION,
}:
decor_view.setSystemUiVisibility(0)
if current_state == WindowState.PRESENTATION:
# Marking this as no branch, since the testbed can't create a simple
# window, so we can't test the other branch.
if self._actionbar_shown_by_default: # pragma: no branch
self.app.native.getSupportActionBar().show()
self._is_presentation_mode = False

# Complete any pending window state transition.
if getattr(self, "_pending_window_state_transition", None) is not None:
self.set_window_state(self._pending_window_state_transition)
del self._pending_window_state_transition

######################################################################
# Window capabilities
Expand Down
16 changes: 6 additions & 10 deletions android/tests_backend/window.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,18 +23,14 @@ def content_size(self):
)

def get_window_state(self):
# Windows are always full screen
decor_view = self.native.getWindow().getDecorView()
system_ui_flags = decor_view.getSystemUiVisibility()
if (
system_ui_flags
& (
decor_view.SYSTEM_UI_FLAG_FULLSCREEN
| decor_view.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| decor_view.SYSTEM_UI_FLAG_IMMERSIVE
)
) != 0:
if not self.native.getSupportActionBar().isShowing():
if system_ui_flags & (
decor_view.SYSTEM_UI_FLAG_FULLSCREEN
| decor_view.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| decor_view.SYSTEM_UI_FLAG_IMMERSIVE
):
if self.window._impl._is_presentation_mode:
current_state = WindowState.PRESENTATION
else:
current_state = WindowState.FULLSCREEN
Expand Down
8 changes: 7 additions & 1 deletion testbed/tests/app/test_desktop.py
Original file line number Diff line number Diff line change
Expand Up @@ -346,9 +346,15 @@ async def test_presentation_mode_with_excess_windows_list(app, app_probe):
],
)
async def test_presentation_mode_exit_on_window_state_change(
app, app_probe, new_window_state
app, app_probe, main_window_probe, new_window_state
):
"""Changing window state exits presentation mode and sets the new state."""
if (
new_window_state == WindowState.MINIMIZED
and not main_window_probe.supports_minimize
):
pytest.xfail("This backend doesn't reliably support minimized window state.")

try:
window1 = toga.MainWindow(
title="Test Window 1", position=(150, 150), size=(200, 200)
Expand Down
52 changes: 52 additions & 0 deletions testbed/tests/window/test_window.py
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,50 @@ async def test_window_state_presentation(main_window, main_window_probe):
assert main_window_probe.get_window_state() != WindowState.PRESENTATION
assert main_window_probe.get_window_state() == WindowState.NORMAL

@pytest.mark.parametrize(
"initial_state, final_state",
[
# Direct switch from FULLSCREEN:
(WindowState.FULLSCREEN, WindowState.PRESENTATION),
# Direct switch from PRESENTATION:
(WindowState.PRESENTATION, WindowState.FULLSCREEN),
],
)
async def test_window_state_direct_change(
app, initial_state, final_state, main_window, main_window_probe
):
assert main_window_probe.get_window_state() == WindowState.NORMAL
assert main_window_probe.get_window_state() != initial_state
assert main_window_probe.get_window_state() != final_state
try:
# Set to initial state
main_window.state = initial_state
await main_window_probe.wait_for_window(
f"Main window is in {initial_state}"
)

assert main_window_probe.get_window_state() != WindowState.NORMAL
assert main_window_probe.get_window_state() == initial_state
assert main_window_probe.get_window_state() != final_state

# Set to final state
main_window.state = final_state
await main_window_probe.wait_for_window(f"Main window is in {final_state}")

assert main_window_probe.get_window_state() != WindowState.NORMAL
assert main_window_probe.get_window_state() == final_state
assert main_window_probe.get_window_state() != initial_state
finally:
# Set to NORMAL state
main_window.state = WindowState.NORMAL
await main_window_probe.wait_for_window(
"Main window is in WindowState.NORMAL"
)

assert main_window_probe.get_window_state() == WindowState.NORMAL
assert main_window_probe.get_window_state() != final_state
assert main_window_probe.get_window_state() != initial_state

async def test_screen(main_window, main_window_probe):
"""The window can be relocated to another screen, using both absolute and relative screen positions."""
assert main_window.screen.origin == (0, 0)
Expand Down Expand Up @@ -820,6 +864,14 @@ async def test_window_state_presentation(second_window, second_window_probe):
async def test_window_state_direct_change(
app, initial_state, final_state, second_window, second_window_probe
):
if (
WindowState.MINIMIZED in {initial_state, final_state}
and not second_window_probe.supports_minimize
):
pytest.xfail(
"This backend doesn't reliably support minimized window state."
)

second_window.toolbar.add(app.cmd1)
second_window.content = toga.Box(style=Pack(background_color=CORNFLOWERBLUE))
second_window.show()
Expand Down

0 comments on commit ccc8f11

Please sign in to comment.