diff --git a/changes/3345.bugfix.rst b/changes/3345.bugfix.rst new file mode 100644 index 0000000000..667bb89314 --- /dev/null +++ b/changes/3345.bugfix.rst @@ -0,0 +1 @@ +Window visibility and focus events in the web backend no longer raise errors when the browser window loses focus diff --git a/web/src/toga_web/libs.py b/web/src/toga_web/libs.py index 669230a680..b98eb8abdc 100644 --- a/web/src/toga_web/libs.py +++ b/web/src/toga_web/libs.py @@ -4,15 +4,12 @@ except ModuleNotFoundError: # To ensure the code can be imported, provide a js symbol as a fallback js = None - - try: - # Try to import pyodide from the PyScript namespace import pyodide except ModuleNotFoundError: - # To ensure the code can be imported, provide a pyodide symbol as a fallback pyodide = None +from pyscript.web import document create_proxy = pyodide.ffi.create_proxy if pyodide else lambda f: f @@ -43,7 +40,7 @@ def create_element( events or methods. :returns: A newly created DOM element. """ - element = js.document.createElement(tag) + element = document.createElement(tag) if id: element.id = id diff --git a/web/src/toga_web/window.py b/web/src/toga_web/window.py index 9eadb9edd1..0ebdf897c8 100644 --- a/web/src/toga_web/window.py +++ b/web/src/toga_web/window.py @@ -1,7 +1,7 @@ from toga.command import Group, Separator from toga.constants import WindowState from toga.types import Position, Size -from toga_web.libs import create_element, js +from toga_web.libs import create_element, create_proxy, js from .screens import Screen as ScreenImpl @@ -21,9 +21,15 @@ def __init__(self, interface, title, position, size): app_placeholder = js.document.getElementById("app-placeholder") app_placeholder.appendChild(self.native) - js.document.body.onfocus = self.dom_on_gain_focus - js.document.body.onblur = self.dom_on_lose_focus - js.document.addEventListener("visibilitychange", self.dom_on_visibility_change) + js.document.body.addEventListener( + "focus", create_proxy(self.dom_on_gain_focus), True + ) + js.document.body.addEventListener( + "blur", create_proxy(self.dom_on_lose_focus), True + ) + js.document.addEventListener( + "visibilitychange", create_proxy(self.dom_on_visibility_change) + ) self.set_title(title) @@ -44,11 +50,10 @@ def dom_on_lose_focus(self, event): self.interface.on_lose_focus() def dom_on_visibility_change(self, event): - if hasattr(js.document, "hidden"): - if js.document.visibilityState == "visible": - self.interface.on_show() - else: - self.interface.on_hide() + if js.document.visibilityState == "visible": + self.interface.on_show() + else: + self.interface.on_hide() ###################################################################### # Window properties