Skip to content

Commit

Permalink
[Feature] Autostart manage through Flatpak
Browse files Browse the repository at this point in the history
  • Loading branch information
melianmiko committed Nov 5, 2024
1 parent aa671ab commit 2f0faa4
Show file tree
Hide file tree
Showing 8 changed files with 113 additions and 11 deletions.
2 changes: 1 addition & 1 deletion openfreebuds_backend/dummy.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ def is_run_at_boot():
return False


def set_run_at_boot(val):
async def set_run_at_boot(val):
log.info("run_at_boot " + str(val))


Expand Down
91 changes: 91 additions & 0 deletions openfreebuds_backend/linux/dbus/background.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import asyncio

from dbus_next import BusType
from dbus_next.aio import ProxyObject, MessageBus

ALLOWED_PORTALS = [
"org.freedesktop.impl.portal.desktop.gnome",
]

introspection = """<?xml version="1.0"?>
<!--
Copyright (C) 2019 Red Hat, Inc
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library. If not, see <http://www.gnu.org/licenses/>.
Author: Matthias Clasen <[email protected]>
-->
<node name="/" xmlns:doc="http://www.freedesktop.org/dbus/1.0/doc.dtd">
<interface name="org.freedesktop.impl.portal.Background">
<method name='GetAppState'>
<arg type="a{sv}" name="apps" direction="out"/>
</method>
<method name='NotifyBackground'>
<arg type="o" name="handle" direction="in"/>
<arg type="s" name="app_id" direction="in"/>
<arg type="s" name="name" direction="in"/>
<arg type="u" name="response" direction="out"/>
<arg type="a{sv}" name="results" direction="out"/>
</method>
<method name='EnableAutostart'>
<arg type="s" name="app_id" direction="in"/>
<arg type="b" name="enable" direction="in"/>
<arg type="as" name="commandline" direction="in"/>
<arg type="u" name="flags" direction="in"/>
<arg type="b" name="result" direction="out"/>
</method>
</interface>
</node>
"""


class FreedesktopBackgroundPortalProxy:
def __init__(self, dbus_object: ProxyObject):
self.dbus_interface = dbus_object.get_interface("org.freedesktop.impl.portal.Background")

async def enable_autostart(self, app_id: str, command: list[str], value):
return await self.dbus_interface.call_enable_autostart(app_id, value, command, 0)

async def is_running(self, app_id):
return app_id in await self.get_app_state()

async def get_app_state(self):
return {k: v.value for k, v in dict(await self.dbus_interface.call_get_app_state()).items()}

@staticmethod
async def get():
bus = await MessageBus(bus_type=BusType.SESSION).connect()

dbus_introspect = await bus.introspect("org.freedesktop.DBus", "/org/freedesktop/DBus")
dbus_obj = bus.get_proxy_object("org.freedesktop.DBus", "/org/freedesktop/DBus",
dbus_introspect)
dbus = dbus_obj.get_interface("org.freedesktop.DBus")

# noinspection PyUnresolvedReferences
for name in await dbus.call_list_names():
if name in ALLOWED_PORTALS:
obj = bus.get_proxy_object(name, "/org/freedesktop/portal/desktop", introspection)
return FreedesktopBackgroundPortalProxy(obj)

return None


if __name__ == "__main__":
async def main():
o = await FreedesktopBackgroundPortalProxy.get()
r = await o.get_app_state()
print(r)

asyncio.run(main())
16 changes: 15 additions & 1 deletion openfreebuds_backend/linux/linux_misc.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import pathlib
import subprocess

from openfreebuds_backend.linux.dbus.background import FreedesktopBackgroundPortalProxy

log = logging.getLogger("OfbLinuxBackend")


Expand All @@ -20,7 +22,7 @@ def is_run_at_boot():
return os.path.isfile(_get_autostart_file_path())


def set_run_at_boot(val):
async def set_run_at_boot(val):
path = _get_autostart_file_path()
data = (f"[Desktop Entry]\n"
f"Name=OpenFreebuds\n"
Expand All @@ -43,6 +45,18 @@ def set_run_at_boot(val):
os.unlink(path)
log.debug("Removed autostart file: " + path)

# Sync with DBus (Flatpak)
try:
o = await FreedesktopBackgroundPortalProxy.get()
r = await o.enable_autostart(
"pw.mmk.OpenFreebuds",
["/usr/bin/flatpak", "run", "pw.mmk.OpenFreebuds"],
val
)
log.debug(f"Enable autostart through portal result {r}")
except AttributeError:
log.debug("Sync with portal failed, no valid portal found")


def _get_autostart_file_path():
autostart_dir = pathlib.Path.home() / ".config/autostart"
Expand Down
2 changes: 1 addition & 1 deletion openfreebuds_backend/windows/misc_win32.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ def is_run_at_boot():
return False


def set_run_at_boot(val):
async def set_run_at_boot(val):
with winreg.OpenKey(
key=winreg.HKEY_CURRENT_USER,
sub_key=r'Software\Microsoft\Windows\CurrentVersion\Run',
Expand Down
4 changes: 1 addition & 3 deletions openfreebuds_qt/app/dialog/first_run.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,6 @@ def __init__(self, ctx):
if sys.platform == "win32":
self.setStyleSheet(WIN32_BODY_STYLE)

self.autostart_checkbox.setChecked(not self.config.is_containerized_app)
self.autostart_checkbox.setEnabled(not self.config.is_containerized_app)
self.background_checkbox.setChecked(QSystemTrayIcon.isSystemTrayAvailable())
self.background_checkbox.setEnabled(QSystemTrayIcon.isSystemTrayAvailable())

Expand All @@ -41,7 +39,7 @@ async def on_confirm(self):
async with qt_error_handler("OfbQtFirstRunDialog_Confirm", self.ctx):
self.hide()

openfreebuds_backend.set_run_at_boot(self.autostart_checkbox.isChecked())
await openfreebuds_backend.set_run_at_boot(self.autostart_checkbox.isChecked())
self.config.set("ui", "background", self.background_checkbox.isChecked())
self.config.set("ui", "first_run_finished", True)
self.config.save()
Expand Down
5 changes: 1 addition & 4 deletions openfreebuds_qt/app/module/ui_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,6 @@ async def update_ui(self, event: OfbCoreEvent):
with blocked_signals(self.autostart_toggle):
self.autostart_toggle.setChecked(is_run_at_boot())

if self.config.is_containerized_app:
self.autostart_toggle.setVisible(False)

with blocked_signals(self.background_toggle):
self.background_toggle.setEnabled(QSystemTrayIcon.isSystemTrayAvailable())
self.background_toggle.setChecked(self.config.get("ui", "background", True))
Expand All @@ -89,7 +86,7 @@ async def on_background_toggle(self, value: bool):

@asyncSlot(bool)
async def on_autostart_toggle(self, value: bool):
set_run_at_boot(value)
await set_run_at_boot(value)

@asyncSlot(bool)
async def on_tray_eq_toggle(self, value: bool):
Expand Down
2 changes: 2 additions & 0 deletions scripts/build_flatpak/pw.mmk.OpenFreebuds.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ finish-args:
- --system-talk-name=org.bluez
# Display tray icon
- --talk-name=org.kde.StatusNotifierWatcher
# Check running state, enable/disable autostart
- --talk-name=org.freedesktop.impl.portal.desktop.gnome

cleanup-commands:
- /app/cleanup-BaseApp.sh
Expand Down
2 changes: 1 addition & 1 deletion scripts/flatpak_install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ cd "$(dirname "$0")"/..

# Build & install flatpak
cd scripts/build_flatpak
flatpak-builder \
flatpak run org.flatpak.Builder \
--force-clean \
--user \
--install-deps-from=flathub \
Expand Down

0 comments on commit 2f0faa4

Please sign in to comment.