Skip to content

Commit

Permalink
GameControllerWakelock: Use freedesktop portal
Browse files Browse the repository at this point in the history
  • Loading branch information
infirit committed Oct 23, 2022
1 parent 803e9b7 commit ccb4e46
Showing 1 changed file with 79 additions and 54 deletions.
133 changes: 79 additions & 54 deletions blueman/plugins/applet/GameControllerWakelock.py
Original file line number Diff line number Diff line change
@@ -1,25 +1,10 @@
from gettext import gettext as _
import logging
from typing import Any
from typing import Any, Optional

from blueman.bluez.Device import Device
from blueman.Functions import launch
from blueman.plugins.AppletPlugin import AppletPlugin
from blueman.plugins.errors import UnsupportedPlatformError

import gi
gi.require_version('Gdk', '3.0')
try:
gi.require_version('GdkX11', '3.0')
except ValueError:
raise ImportError("Couldn't find required namespace GdkX11")

from gi.repository import Gdk
from gi.repository import GdkX11


if not isinstance(Gdk.Screen.get_default(), GdkX11.X11Screen):
raise UnsupportedPlatformError('Only X11 platform is supported')
from gi.repository import Gio, GLib


class GameControllerWakelock(AppletPlugin):
Expand All @@ -28,51 +13,91 @@ class GameControllerWakelock(AppletPlugin):
__icon__ = "input-gaming-symbolic"

def on_load(self) -> None:
self.wake_lock = 0
screen = Gdk.Screen.get_default()
assert screen is not None
window = screen.get_root_window()
assert isinstance(window, GdkX11.X11Window)
self.root_window_id = "0x%x" % window.get_xid()
self.__locks: int = 0
self._inhibit_request: Optional[str] = None
self._portal_inhibit: Optional[Gio.DBusProxy] = None
self.watch = Gio.bus_watch_name(
Gio.BusType.SESSION,
"org.freedesktop.portal.Desktop",
Gio.BusNameWatcherFlags.NONE,
self._on_name_appeared,
self._on_name_vanished
)

def on_unload(self) -> None:
if self.wake_lock:
self.wake_lock = 1
self.xdg_screensaver("resume")
self.__cleanup()

def __cleanup(self) -> None:
if self._inhibit_request:
self._remove_lock(force=True)

if self._portal_inhibit is not None:
self._portal_inhibit.destroy()
self._portal_inhibit = None

def _on_name_appeared(self, connection: Gio.DBusConnection, name: str, owner: str) -> None:
logging.debug(f"Got name {name} and owner: {owner}")
self._portal_inhibit = Gio.DBusProxy.new_sync(
connection,
Gio.DBusProxyFlags.NONE,
None,
"org.freedesktop.portal.Desktop",
"/org/freedesktop/portal/desktop",
"org.freedesktop.portal.Inhibit",
None
)

def _on_name_vanished(self, _connection: Gio.DBusConnection, name: str) -> None:
logging.debug(f"ScreenSaver {name} vanished")
self.__cleanup()

def on_device_property_changed(self, path: str, key: str, value: Any) -> None:
if key == "Connected":
klass = Device(obj_path=path)["Class"] & 0x1fff

if klass == 0x504 or klass == 0x508:
if value:
self.xdg_screensaver("suspend")
self._add_lock()
else:
self.xdg_screensaver("resume")

def xdg_screensaver(self, action: str) -> None:
command = f"xdg-screensaver {action} {self.root_window_id}"

if action == "resume":
if self.wake_lock <= 0:
self.wake_lock = 0
elif self.wake_lock > 1:
self.wake_lock -= 1
else:
ret = launch(command, sn=False)
if ret:
self.wake_lock -= 1
else:
logging.error(f"{action} failed")

elif action == "suspend":
if self.wake_lock >= 1:
self.wake_lock += 1
else:
ret = launch(command, sn=False)
if ret:
self.wake_lock += 1
else:
logging.error(f"{action} failed")
self._remove_lock()

def _add_lock(self) -> None:
if self.__locks > 0:
self.__locks += 1
else:
assert self._portal_inhibit is not None
reason = GLib.Variant("s", "Gamecontroller")
request_path = self._portal_inhibit.Inhibit("(sua{sv})", "blueman-applet", 8, {"reason": reason})
logging.debug(request_path)
if request_path:
self.__locks += 1
self._inhibit_request = request_path

logging.debug(f"Adding lock, total {self.__locks}")

def _remove_lock(self, force: bool = False) -> None:
if self._inhibit_request is None:
logging.warning("No inhibit request found")
self.__locks = 0
return

if self.__locks == 1 or force:
proxy = Gio.DBusProxy.new_for_bus_sync(
Gio.BusType.SESSION,
Gio.DBusProxyFlags.NONE,
None,
"org.freedesktop.portal.Desktop",
self._inhibit_request,
"org.freedesktop.portal.Request",
None
)
proxy.Close()
proxy.destroy()
self.__locks -= 1

# We should have no locks remaining
assert self.__locks == 0
else:
self.__locks -= 1

logging.info(f"Number of locks: {self.wake_lock}")
logging.debug(f"Removed lock, total {self.__locks}")

0 comments on commit ccb4e46

Please sign in to comment.