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):