clan-core/pkgs/clan-app/clan_app/app.py

128 lines
4.0 KiB
Python
Raw Normal View History

2023-11-25 00:55:01 +00:00
#!/usr/bin/env python3
import logging
from typing import Any, ClassVar
2023-12-16 12:03:10 +00:00
2023-11-25 00:55:01 +00:00
import gi
2023-12-16 12:03:10 +00:00
2024-06-05 09:23:12 +00:00
from clan_app import assets
from clan_app.singletons.toast import InfoToast, ToastOverlay
gi.require_version("Gtk", "4.0")
gi.require_version("Adw", "1")
2024-01-02 04:54:19 +00:00
from clan_cli.custom_logger import setup_logging
from gi.repository import Adw, Gdk, Gio, Gtk
2023-12-16 12:03:10 +00:00
2024-06-05 09:23:12 +00:00
from clan_app.components.interfaces import ClanConfig
from clan_app.singletons.use_join import GLib, GObject
from .windows.main_window import MainWindow
2023-12-16 11:52:10 +00:00
log = logging.getLogger(__name__)
2023-11-28 17:19:01 +00:00
class MainApplication(Adw.Application):
"""
This class is initialized every time the app is started
Only the Adw.ApplicationWindow is a singleton.
So don't use any singletons in the Adw.Application class.
"""
__gsignals__: ClassVar = {
"join_request": (GObject.SignalFlags.RUN_FIRST, None, [str]),
}
def __init__(self, *args: Any, **kwargs: Any) -> None:
super().__init__(
2024-03-01 11:52:05 +00:00
application_id="org.clan.vm-manager",
flags=Gio.ApplicationFlags.HANDLES_COMMAND_LINE,
)
self.add_main_option(
"debug",
ord("d"),
GLib.OptionFlags.NONE,
GLib.OptionArg.NONE,
"enable debug mode",
None,
2023-12-30 10:14:45 +00:00
)
2024-05-29 10:51:43 +00:00
self.window: MainWindow | None = None
self.connect("activate", self.on_activate)
self.connect("shutdown", self.on_shutdown)
def on_shutdown(self, source: "MainApplication") -> None:
log.debug("Shutting down Adw.Application")
if self.get_windows() == []:
log.warning("No windows to destroy")
if self.window:
# TODO: Doesn't seem to raise the destroy signal. Need to investigate
# self.get_windows() returns an empty list. Desync between window and application?
self.window.close()
# Killing vms directly. This is dirty
self.window.kill_vms()
else:
log.error("No window to destroy")
2023-12-30 10:14:45 +00:00
def do_command_line(self, command_line: Any) -> int:
options = command_line.get_options_dict()
# convert GVariantDict -> GVariant -> dict
options = options.end().unpack()
if "debug" in options and self.window is None:
setup_logging(logging.DEBUG, root_log_name=__name__.split(".")[0])
setup_logging(logging.DEBUG, root_log_name="clan_cli")
elif self.window is None:
setup_logging(logging.INFO, root_log_name=__name__.split(".")[0])
log.debug("Debug logging enabled")
if "debug" in options:
ToastOverlay.use().add_toast_unique(
InfoToast("Debug logging enabled").toast, "info.debugging.enabled"
)
args = command_line.get_arguments()
self.activate()
if len(args) > 1:
uri = args[1]
self.emit("join_request", uri)
return 0
2024-02-08 13:57:02 +00:00
def on_window_hide_unhide(self, *_args: Any) -> None:
if not self.window:
log.error("No window to hide/unhide")
return
2024-02-08 13:57:02 +00:00
if self.window.is_visible():
self.window.hide()
else:
self.window.present()
2024-02-08 13:57:02 +00:00
def dummy_menu_entry(self) -> None:
log.info("Dummy menu entry called")
def on_activate(self, source: "MainApplication") -> None:
2024-02-08 13:57:02 +00:00
if not self.window:
2024-02-07 05:03:12 +00:00
self.init_style()
2024-06-05 10:10:26 +00:00
self.window = MainWindow(config=ClanConfig(initial_view="webview"))
2024-02-08 13:57:02 +00:00
self.window.set_application(self)
self.window.show()
2023-11-28 17:19:01 +00:00
# TODO: For css styling
2023-11-30 12:42:15 +00:00
def init_style(self) -> None:
resource_path = assets.loc / "style.css"
log.debug(f"Style css path: {resource_path}")
css_provider = Gtk.CssProvider()
css_provider.load_from_path(str(resource_path))
display = Gdk.Display.get_default()
assert display is not None
Gtk.StyleContext.add_provider_for_display(
display,
css_provider,
Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION,
)