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

Add App.focus() method #3034

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
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
3 changes: 3 additions & 0 deletions android/src/toga_android/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -392,3 +392,6 @@ def request_permissions(self, permissions, on_complete):

self._listener.permission_requests[code] = on_complete
self._native_requestPermissions(permissions, code)

def focus(self):
pass # No-op on Android
5 changes: 4 additions & 1 deletion cocoa/src/toga_cocoa/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -352,7 +352,7 @@ def show_about_dialog(self):
if self.interface.author is None:
options["Copyright"] = ""
else:
options["Copyright"] = f"Copyright © {self.interface.author}"
Copy link
Member

Choose a reason for hiding this comment

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

Why have you made this change? The copyright is a valid symbol, and it displays correctly in my testing.

options["Copyright"] = f"Copyright {self.interface.author}"

self.native.orderFrontStandardAboutPanelWithOptions(options)

Expand Down Expand Up @@ -385,3 +385,6 @@ def get_current_window(self):

def set_current_window(self, window):
window._impl.native.makeKeyAndOrderFront(window._impl.native)

def focus(self):
self.native.activateIgnoringOtherApps_(True)
Copy link
Member

Choose a reason for hiding this comment

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

The trailing underscore isn't needed here; it's a valid but historical syntax.

Suggested change
self.native.activateIgnoringOtherApps_(True)
self.native.activateIgnoringOtherApps(True)

10 changes: 10 additions & 0 deletions core/src/toga/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -1020,6 +1020,16 @@ def set_full_screen(self, *windows: Window) -> None:
# End backwards compatibility
######################################################################

def focus(self):
Copy link
Member

Choose a reason for hiding this comment

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

The methods on this class are sorted; this should be added to the "Window control" section, alphabetically sorted in that section.

"""Bring the application into focus.
This method will attempt to bring the application window into focus. Note that
it is generally considered poor practice for applications to steal focus from
the user, so use this method sparingly.
This is a no-op on mobile and console platforms.
Comment on lines +1024 to +1030
Copy link
Member

Choose a reason for hiding this comment

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

We try not to call out specific platforms in docstrings; we put platform specific notes in the Notes section for the class in question.

Suggested change
"""Bring the application into focus.
This method will attempt to bring the application window into focus. Note that
it is generally considered poor practice for applications to steal focus from
the user, so use this method sparingly.
This is a no-op on mobile and console platforms.
"""Force the app to be the currently active app on the user's desktop.
This request will not be honoured by all platforms; see the :ref:`platform notes
<app-notes>` for details.
This method should be used sparingly, if at all. It is generally considered poor
practice for an application to steal focus from other applications.

(This will also require adding a .. app-notes: declaration just before the Notes header in the app documentation.)

"""
self._impl.focus()

######################################################################
# 2024-08: Backwards compatibility
Expand Down
4 changes: 4 additions & 0 deletions gtk/src/toga_gtk/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -248,3 +248,7 @@ def get_current_window(self): # pragma: no-cover-if-linux-wayland

def set_current_window(self, window):
window._impl.native.present()

def focus(self):
# GTK doesn't provide a reliable way to bring an app into focus
pass
5 changes: 4 additions & 1 deletion web/src/toga_web/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ def show_about_dialog(self):
name_and_version += f" v{self.interface.version}"

if self.interface.author is not None:
copyright = f"\n\nCopyright © {self.interface.author}"
Copy link
Member

Choose a reason for hiding this comment

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

Again - why this change?

copyright = f"\n\nCopyright {self.interface.author}"

close_button = create_element(
"sl-button", slot="footer", variant="primary", content="Ok"
Expand Down Expand Up @@ -156,3 +156,6 @@ def enter_presentation_mode(self, screen_window_dict):

def exit_presentation_mode(self):
self.interface.factory.not_implemented("App.exit_presentation_mode()")

def focus(self):
pass # No-op on web platform
5 changes: 5 additions & 0 deletions winforms/src/toga_winforms/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -264,3 +264,8 @@ def get_current_window(self):

def set_current_window(self, window):
window._impl.native.Activate()

def focus(self):
# Bring the app's main window into focus if it exists
if self.interface.main_window:
self.interface.main_window._impl.native.Activate()
Loading