cosmonaut-shell/transmitter-panel/main.py

93 lines
3.0 KiB
Python

#!/usr/bin/env python3
"""transmitter-panel — beacon's notification-history viewer for hyprdrive.
Single-instance, same pattern as horizon-dock/astro-menu's main.py: the first
launch builds the (hidden) window and holds; later invocations forward their
verb over D-Bus via scripts/transmitter-panel.sh instead of spawning a second
python3+GTK4 process.
main.py run the resident instance (stays hidden until toggled)
main.py --show show
main.py --hide hide
main.py --toggle whichever of the above applies
"""
from __future__ import annotations
import os
import sys
from pathlib import Path
# transmitter-panel-start.sh LD_PRELOADs libgtk4-layer-shell (load-ordering
# requirement ahead of libwayland-client). Drop it once resident so it isn't
# inherited by anything this process launches — same rationale as the rest of
# the suite's main.py.
os.environ.pop("LD_PRELOAD", None)
sys.path.insert(0, str(Path(__file__).resolve().parent))
import gi # noqa: E402
gi.require_version("Gtk", "4.0")
from gi.repository import Gio, GLib, Gtk # noqa: E402
import theme # noqa: E402
from paths import APP_ID # noqa: E402
from window import TransmitterWindow # noqa: E402
class TransmitterPanelApp(Gtk.Application):
def __init__(self) -> None:
super().__init__(application_id=APP_ID,
flags=Gio.ApplicationFlags.HANDLES_COMMAND_LINE)
self.window: TransmitterWindow | None = None
def do_startup(self) -> None:
Gtk.Application.do_startup(self)
theme.load_css()
self.window = TransmitterWindow(self)
self._register_actions()
self.hold() # stay alive with no visible window
def _register_actions(self) -> None:
def add(name: str, callback) -> None:
action = Gio.SimpleAction.new(name, None)
action.connect("activate", callback)
self.add_action(action)
def guarded(fn):
def wrapper(*_a) -> None:
assert self.window is not None
fn(self.window)
return wrapper
add("show", guarded(lambda w: w.show_panel()))
add("hide", guarded(lambda w: w.hide_panel()))
add("toggle", guarded(lambda w: w.toggle()))
def do_command_line(self, cmdline: Gio.ApplicationCommandLine) -> int:
args = list(cmdline.get_arguments()[1:])
verb = args[0] if args else "--daemon"
if self.window is None:
return 0
if verb == "--show":
self.window.show_panel()
elif verb == "--hide":
self.window.hide_panel()
elif verb == "--toggle":
self.window.toggle()
# --daemon and anything else: no-op (stay resident, hidden)
return 0
def do_activate(self) -> None:
pass # resident instance: nothing to do on plain activate
def main() -> int:
GLib.set_prgname("transmitter-panel")
return TransmitterPanelApp().run(sys.argv)
if __name__ == "__main__":
raise SystemExit(main())