diff --git a/pkgs/clan-vm-manager/clan_vm_manager/app.py b/pkgs/clan-vm-manager/clan_vm_manager/app.py index ecc240c2b..b1d8d850a 100644 --- a/pkgs/clan-vm-manager/clan_vm_manager/app.py +++ b/pkgs/clan-vm-manager/clan_vm_manager/app.py @@ -69,10 +69,10 @@ class MainApplication(Adw.Application): # convert GVariantDict -> GVariant -> dict options = options.end().unpack() - if "debug" in options: + 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") - else: + elif self.window is None: setup_logging(logging.INFO, root_log_name=__name__.split(".")[0]) log.debug("Debug logging enabled") @@ -81,7 +81,6 @@ class MainApplication(Adw.Application): self.activate() if len(args) > 1: - log.debug(f"Join request: {args[1]}") uri = args[1] self.emit("join_request", uri) return 0 diff --git a/pkgs/clan-vm-manager/clan_vm_manager/components/gkvstore.py b/pkgs/clan-vm-manager/clan_vm_manager/components/gkvstore.py index 0efa282ac..97e5a0e75 100644 --- a/pkgs/clan-vm-manager/clan_vm_manager/components/gkvstore.py +++ b/pkgs/clan-vm-manager/clan_vm_manager/components/gkvstore.py @@ -166,7 +166,6 @@ class GKVStore(GObject.GObject, Gio.ListModel, Generic[K, V]): # O(1) operation if the key does not exist, O(n) if it does def __setitem__(self, key: K, value: V) -> None: # If the key already exists, remove it O(n) - # TODO: We have to check if updating an existing key is working correctly if key in self._items: log.warning("Updating an existing key in GKVStore is O(n)") position = self.keys().index(key) diff --git a/pkgs/clan-vm-manager/clan_vm_manager/components/vmobj.py b/pkgs/clan-vm-manager/clan_vm_manager/components/vmobj.py index ee1830edd..22208265a 100644 --- a/pkgs/clan-vm-manager/clan_vm_manager/components/vmobj.py +++ b/pkgs/clan-vm-manager/clan_vm_manager/components/vmobj.py @@ -254,15 +254,15 @@ class VMObject(GObject.Object): f"VM {self.get_id()} has not stopped after {self.KILL_TIMEOUT}s. Killing it" ) self.vm_process.kill_group() - return + break if self.is_building(): log.info(f"VM {self.get_id()} is still building. Killing it") self.build_process.kill_group() - return + break if not self.machine: log.error(f"Machine object is None. Killing VM {self.get_id()}") self.vm_process.kill_group() - return + break # Try to shutdown the VM gracefully using QMP try: diff --git a/pkgs/clan-vm-manager/clan_vm_manager/singletons/use_join.py b/pkgs/clan-vm-manager/clan_vm_manager/singletons/use_join.py index a7a8b57a4..fbfb601d6 100644 --- a/pkgs/clan-vm-manager/clan_vm_manager/singletons/use_join.py +++ b/pkgs/clan-vm-manager/clan_vm_manager/singletons/use_join.py @@ -71,6 +71,18 @@ class JoinList: def on_clan_store_items_changed( self, source: Any, position: int, removed: int, added: int + ) -> None: + if added > 0: + # Rerendering the join list every time an item changes in the vmstore + ClanStore.use().clan_store.values()[position].connect( + "items-changed", self.on_vm_store_items_changed + ) + self.list_store.items_changed( + 0, self.list_store.get_n_items(), self.list_store.get_n_items() + ) + + def on_vm_store_items_changed( + self, source: Any, position: int, removed: int, added: int ) -> None: self.list_store.items_changed( 0, self.list_store.get_n_items(), self.list_store.get_n_items() diff --git a/pkgs/clan-vm-manager/clan_vm_manager/singletons/use_vms.py b/pkgs/clan-vm-manager/clan_vm_manager/singletons/use_vms.py index 0581fb19a..05f25f9c9 100644 --- a/pkgs/clan-vm-manager/clan_vm_manager/singletons/use_vms.py +++ b/pkgs/clan-vm-manager/clan_vm_manager/singletons/use_vms.py @@ -3,6 +3,7 @@ from pathlib import Path from typing import Any import gi +from clan_cli.clan_uri import ClanURI from clan_cli.history.add import HistoryEntry from clan_vm_manager import assets @@ -87,11 +88,11 @@ class ClanStore: def remove(self, vm: VMObject) -> None: del self.clan_store[vm.data.flake.flake_url][vm.data.flake.flake_attr] - def get_vm(self, flake_url: str, flake_attr: str) -> None | VMObject: - clan = self.clan_store.get(flake_url) + def get_vm(self, uri: ClanURI) -> None | VMObject: + clan = self.clan_store.get(uri.get_internal()) if clan is None: return None - return clan.get(flake_attr, None) + return clan.get(uri.params.flake_attr, None) def get_running_vms(self) -> list[VMObject]: return [ diff --git a/pkgs/clan-vm-manager/clan_vm_manager/views/list.py b/pkgs/clan-vm-manager/clan_vm_manager/views/list.py index 797bd7782..b4fb9bdca 100644 --- a/pkgs/clan-vm-manager/clan_vm_manager/views/list.py +++ b/pkgs/clan-vm-manager/clan_vm_manager/views/list.py @@ -4,7 +4,7 @@ from functools import partial from typing import Any import gi -from clan_cli import history, machines +from clan_cli import history from clan_cli.clan_uri import ClanURI from clan_vm_manager.components.interfaces import ClanConfig @@ -81,9 +81,10 @@ class ClanList(Gtk.Box): app.add_action(add_action) menu_model = Gio.Menu() - for vm in machines.list.list_machines(flake_url=vm.data.flake.flake_url): - if vm not in vm_store: - menu_model.append(vm, f"app.add::{vm}") + # TODO: Make this lazy, blocks UI startup for too long + # for vm in machines.list.list_machines(flake_url=vm.data.flake.flake_url): + # if vm not in vm_store: + # menu_model.append(vm, f"app.add::{vm}") box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=5) box.set_valign(Gtk.Align.CENTER) @@ -191,8 +192,10 @@ class ClanList(Gtk.Box): row.set_subtitle(item.url.get_internal()) row.add_css_class("trust") + vm = ClanStore.use().get_vm(item.url) + # Can't do this here because clan store is empty at this point - if item.url.get_internal() in ClanStore.use().clan_store: + if vm is not None: sub = row.get_subtitle() row.set_subtitle( sub + "\nClan already exists. Joining again will update it"