By using this site, you agree to have cookies stored on your device, strictly for functional purposes, such as storing your session and preferences.

Dismiss

file-listing: a few improvements

roundabout,
created on Sunday, 7 December 2025, 19:33:21 (1765136001), received on Sunday, 7 December 2025, 19:33:24 (1765136004)
Author identity: Vlad <vlad.muntoiu@gmail.com>

54b18941e275c25f95587c5e4856e06989bfa20a

applets/file-listing/__init__.py

@@ -24,7 +24,7 @@ import panorama_panel

                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            import gi
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            gi.require_version("Gtk", "4.0")
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        from gi.repository import Gtk, GLib, Gio, Gdk, GObject
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        from gi.repository import Gtk, GLib, Gio, Gdk, GObject, GioUnix
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            module_directory = Path(__file__).resolve().parent
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            locale.bindtextdomain("panorama-panel-file-listing", module_directory / "locale")
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        

@@ -60,7 +60,7 @@ class FileMenuLinkIter(Gio.MenuLinkIter, GObject.Object):

                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            class FileMenu(Gio.MenuModel, GObject.Object):
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            def __init__(self, root: Path, storage: dict[str, GObject.Object], new_action_callback, prune_action_callback, **kwargs):
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            def __init__(self, root: Path, storage: dict[str, GObject.Object], new_action_callback, prune_action_callback, show_hidden=False, **kwargs):
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                    GObject.Object.__init__(self, **kwargs)
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                    self.root: Path = root
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                    self.links: dict[str, Gio.MenuModel] = {}
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        

@@ -68,6 +68,7 @@ class FileMenu(Gio.MenuModel, GObject.Object):

                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                    self.storage = storage
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                    self.callback = new_action_callback
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                    self.callback_prune = prune_action_callback
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                self.show_hidden = show_hidden
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                    self.enabled = False
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                def do_is_mutable(self):
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        

@@ -76,7 +77,16 @@ class FileMenu(Gio.MenuModel, GObject.Object):

                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                def do_get_n_items(self):
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                    if not self.enabled:
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                        return 0
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                self.files = list(self.root.iterdir())
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                if self.show_hidden:
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                    self.files = sorted(
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                            self.root.iterdir(),
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                            key=lambda p: GLib.utf8_collate_key_for_filename(p.name, len(p.name))
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                    )
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                else:
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                    self.files = sorted(
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                            (p for p in self.root.iterdir() if not p.name.startswith(".")),
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                            key=lambda p: GLib.utf8_collate_key_for_filename(p.name, len(p.name))
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                    )
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                    return len(self.files)
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                def do_get_item_attribute_value(self, item_index, attribute, expected_type = None):
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        

@@ -96,7 +106,7 @@ class FileMenu(Gio.MenuModel, GObject.Object):

                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                def make_submenu(self, name):
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                    action_id = hashlib.md5(str(self.root / name).encode())
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                    if name not in self.links:
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                    menu = FileMenu(self.root / name, self.storage, self.callback, self.callback_prune)
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                    menu = FileMenu(self.root / name, self.storage, self.callback, self.callback_prune, show_hidden=self.show_hidden)
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                        container = Gio.Menu()
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                        options_section = Gio.Menu()
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                        open_directory = Gio.MenuItem()
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        

@@ -181,6 +191,18 @@ class FileListingApplet(panorama_panel.Applet):

                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                    self.button = Gtk.MenuButton()
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                    self.button.set_has_frame(False)
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                    self.append(self.button)
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                self.inner_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                self.button.set_child(self.inner_box)
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                self.icon_name = config.get("icon_name")
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                self.show_hidden = config.get("show_hidden", False)
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                self.icon_size = config.get("icon_size", 24)
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                self.label = config.get("label")
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                if config.get("icon_name"):
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                    self.inner_box.append(Gtk.Image(icon_name=config["icon_name"], pixel_size=config.get("icon_size", 24)))
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                if config.get("label"):
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                    self.inner_box.append(Gtk.Label.new(config["label"]))
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                    self.button.set_always_show_arrow(True)
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                    self.popover = Gtk.PopoverMenu(flags=Gtk.PopoverMenuFlags.NESTED, has_arrow=False)
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                    self.actions = {}
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        

@@ -192,7 +214,7 @@ class FileListingApplet(panorama_panel.Applet):

                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                    self.options_section.append_item(open_directory)
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                    self.container_menu.append_section(None, self.options_section)
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                self.menu = FileMenu(self.directory, self.actions, self.new_action, self.delete_action)
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                self.menu = FileMenu(self.directory, self.actions, self.new_action, self.delete_action, show_hidden=self.show_hidden)
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                    self.container_menu.append_section(None, self.menu)
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                    self.container_menu.file_list = self.menu
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        

@@ -222,7 +244,11 @@ class FileListingApplet(panorama_panel.Applet):

                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                    self.action_group.remove(f"submenu-status-{action_id.hexdigest()}")
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                def open_file(self, action, data: GLib.Variant):
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                Gio.AppInfo.launch_default_for_uri(GLib.filename_to_uri(data.get_string()))
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                uri = GLib.filename_to_uri(data.get_string())
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                try:
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                    GioUnix.DesktopAppInfo.new_from_filename(data.get_string()).launch()
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                except TypeError:
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                    Gio.AppInfo.launch_default_for_uri(uri)
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                def submenu_changed(self, action, parameter):
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                    if action.get_state():
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        

@@ -231,7 +257,13 @@ class FileListingApplet(panorama_panel.Applet):

                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                        action.submenu.prune()
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                def get_config(self):
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                return {"directory": str(self.directory)}
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                return {
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                    "directory": str(self.directory),
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                    "icon_name": self.icon_name,
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                    "icon_size": self.icon_size,
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                    "label": self.label,
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                    "show_hidden": self.show_hidden,
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                }
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                def set_panel_position(self, position):
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                    self.button.set_direction(panorama_panel.POSITION_TO_ARROW[panorama_panel.OPPOSITE_POSITION[position]])
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                            
                                

config.yaml

@@ -95,4 +95,4 @@ panels:

                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                centre: []
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                right:
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                - FileListingApplet:
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                directory: /home/vlad
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                directory: "~"
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                            
                                

shared/panorama_panel.py

@@ -1,7 +1,7 @@

                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            import gi
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            gi.require_version("Gtk", "4.0")
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        from gi.repository import Gtk, Gdk, GObject, GLib
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        from gi.repository import Gtk, Gdk, Gio, GObject, GLib
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            class Applet(Gtk.Box):