96 lines
3.2 KiB
Python
96 lines
3.2 KiB
Python
#!/usr/bin/env python3
|
|
"""horizon-dock — a hover-scrollable orbital dock for hyprdrive, matching
|
|
orbit-menu's visual language.
|
|
|
|
Single-instance, same pattern as astal-menu/orbit-menu's main.py: the first
|
|
launch builds the (hidden) window and holds; later invocations forward their
|
|
verb over D-Bus via scripts/horizon-dock.sh instead of spawning a second
|
|
python3+GTK4 process.
|
|
|
|
main.py run the resident instance (stays hidden until toggled)
|
|
main.py --show slide/fade in
|
|
main.py --hide slide/fade out
|
|
main.py --toggle whichever of the above applies
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import os
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
# horizon-dock-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 (see astal-menu/orbit-menu's main.py for the same
|
|
# rationale — some GTK4 apps abort at startup with the layer-shell lib preloaded).
|
|
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 config # noqa: E402
|
|
import theme # noqa: E402
|
|
from dock import HorizonDock # noqa: E402
|
|
from paths import APP_ID # noqa: E402
|
|
|
|
|
|
class HorizonDockApp(Gtk.Application):
|
|
def __init__(self) -> None:
|
|
super().__init__(application_id=APP_ID,
|
|
flags=Gio.ApplicationFlags.HANDLES_COMMAND_LINE)
|
|
self.window: HorizonDock | None = None
|
|
|
|
def do_startup(self) -> None:
|
|
Gtk.Application.do_startup(self)
|
|
theme.load_css()
|
|
self.window = HorizonDock(tray_enabled=config.tray_enabled(),
|
|
hologram_enabled=config.hologram_enabled())
|
|
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_dock()))
|
|
add("hide", guarded(lambda w: w.hide_dock()))
|
|
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_dock()
|
|
elif verb == "--hide":
|
|
self.window.hide_dock()
|
|
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("horizon-dock")
|
|
return HorizonDockApp().run(sys.argv)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
raise SystemExit(main())
|