From e31b21e5543bb0654e780f2763cb2eb4a4ecd003 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?= Date: Tue, 27 May 2025 16:24:25 +0200 Subject: [PATCH] Use glib's native asyncio integration when available Glib >= 3.50 has native asyncio integration. When available, use it instead of gbulb. This requires few minor changes: - asyncio.run() doesn't work there (asyncio.set_event_loop() cannot be called on the main thread with glib...) QubesOS/qubes-issues#9809 --- debian/control | 2 +- qui/clipboard.py | 12 +++++++++--- qui/devices/device_widget.py | 13 +++++++++---- qui/tools/qubes_device_agent.py | 13 ++++++++++--- qui/tray/domains.py | 9 +++++++-- qui/tray/updates.py | 9 +++++++-- qui/updater/summary_page.py | 3 ++- rpm_spec/qubes-desktop-linux-manager.spec.in | 4 ++++ 8 files changed, 49 insertions(+), 16 deletions(-) diff --git a/debian/control b/debian/control index 54346e59..0dd3439c 100644 --- a/debian/control +++ b/debian/control @@ -6,7 +6,7 @@ Build-Depends: debhelper (>= 9), dh-python, python3-all, - python3-gbulb, + python3-gi (>= 3.50.0) | python3-gbulb, python3-setuptools, python3-systemd, Standards-Version: 3.9.5 diff --git a/qui/clipboard.py b/qui/clipboard.py index 1d910122..d04dff62 100644 --- a/qui/clipboard.py +++ b/qui/clipboard.py @@ -45,7 +45,15 @@ gi.require_version("Gtk", "3.0") # isort:skip from gi.repository import Gtk, Gio, Gdk # isort:skip -import gbulb +try: + from gi.events import GLibEventLoopPolicy + + asyncio.set_event_loop_policy(GLibEventLoopPolicy()) +except ImportError: + import gbulb + + gbulb.install() + import pyinotify import gettext @@ -55,8 +63,6 @@ from .utils import run_asyncio_and_show_errors -gbulb.install() - DATA = "/var/run/qubes/qubes-clipboard.bin" METADATA = "/var/run/qubes/qubes-clipboard.bin.metadata" FROM = "/var/run/qubes/qubes-clipboard.bin.source" diff --git a/qui/devices/device_widget.py b/qui/devices/device_widget.py index a296161c..d325c3a6 100644 --- a/qui/devices/device_widget.py +++ b/qui/devices/device_widget.py @@ -44,15 +44,20 @@ gi.require_version("Gtk", "3.0") # isort:skip from gi.repository import Gtk, Gdk, Gio # isort:skip +try: + from gi.events import GLibEventLoopPolicy + + asyncio.set_event_loop_policy(GLibEventLoopPolicy()) +except ImportError: + import gbulb + + gbulb.install() + from qui.devices import backend from qui.devices import actionable_widgets from qubes_config.widgets.gtk_utils import is_theme_light -import gbulb - -gbulb.install() - import gettext t = gettext.translation("desktop-linux-manager", fallback=True) diff --git a/qui/tools/qubes_device_agent.py b/qui/tools/qubes_device_agent.py index b2a7c5b8..bcd0bf41 100644 --- a/qui/tools/qubes_device_agent.py +++ b/qui/tools/qubes_device_agent.py @@ -36,7 +36,14 @@ # pylint: enable=import-error # pylint: disable=wrong-import-order -import gbulb +try: + from gi.events import GLibEventLoopPolicy + + asyncio.set_event_loop_policy(GLibEventLoopPolicy()) +except ImportError: + import gbulb + + gbulb.install() # pylint: enable=wrong-import-position @@ -256,10 +263,10 @@ async def handle_request(self, params, service, source_domain): def main(): args = parser.parse_args() - gbulb.install() agent = DeviceAgent(args.socket_path) - asyncio.run(agent.run()) + loop = asyncio.get_event_loop() + loop.run_until_complete(agent.run()) if __name__ == "__main__": diff --git a/qui/tray/domains.py b/qui/tray/domains.py index 58b1340e..97b19c11 100644 --- a/qui/tray/domains.py +++ b/qui/tray/domains.py @@ -26,9 +26,14 @@ gi.require_version("Gtk", "3.0") # isort:skip from gi.repository import Gdk, Gio, Gtk, GLib, GdkPixbuf # isort:skip -import gbulb +try: + from gi.events import GLibEventLoopPolicy -gbulb.install() + asyncio.set_event_loop_policy(GLibEventLoopPolicy()) +except ImportError: + import gbulb + + gbulb.install() import gettext diff --git a/qui/tray/updates.py b/qui/tray/updates.py index 59032f53..3a578ee0 100644 --- a/qui/tray/updates.py +++ b/qui/tray/updates.py @@ -23,9 +23,14 @@ gi.require_version("Gtk", "3.0") # isort:skip from gi.repository import Gtk, Gio # isort:skip -import gbulb +try: + from gi.events import GLibEventLoopPolicy -gbulb.install() + asyncio.set_event_loop_policy(GLibEventLoopPolicy()) +except ImportError: + import gbulb + + gbulb.install() import gettext diff --git a/qui/updater/summary_page.py b/qui/updater/summary_page.py index fc8cdf24..f4215956 100644 --- a/qui/updater/summary_page.py +++ b/qui/updater/summary_page.py @@ -338,7 +338,8 @@ def shutdown_domains(self, to_shutdown): ) self.status = RestartStatus.ERROR_TMPL_DOWN - asyncio.run(wait_for_domain_shutdown(wait_for)) + loop = asyncio.get_event_loop() + loop.run_until_complete(wait_for_domain_shutdown(wait_for)) return wait_for diff --git a/rpm_spec/qubes-desktop-linux-manager.spec.in b/rpm_spec/qubes-desktop-linux-manager.spec.in index 30026f74..23c0d422 100644 --- a/rpm_spec/qubes-desktop-linux-manager.spec.in +++ b/rpm_spec/qubes-desktop-linux-manager.spec.in @@ -48,7 +48,11 @@ BuildRequires: python%{python3_pkgversion}-setuptools BuildRequires: gettext Requires: python%{python3_pkgversion}-setuptools +%if 0%{?fedora} < 42 Requires: python%{python3_pkgversion}-gbulb +%else +Requires: python%{python3_pkgversion}-gobject >= 3.50.0 +%endif Requires: python%{python3_pkgversion}-inotify Requires: libappindicator-gtk3 Requires: python%{python3_pkgversion}-systemd