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

Initial app menu

roundabout,
created on Thursday, 14 August 2025, 13:11:32 (1755177092), received on Thursday, 14 August 2025, 13:11:35 (1755177095)
Author identity: Vlad <vlad.muntoiu@gmail.com>

11b989bd7696b1e1b3e70aca01f45d89ea130d48

applets/app-menu/__init__.py

@@ -0,0 +1,243 @@

                                
                                
                                
                            
                                
                                    
                                        
                                        """
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        MATE-like app menu applet for the Panorama panel.
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        Copyright 2025, roundabout-host.com <vlad@roundabout-host.com>
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        This program is free software: you can redistribute it and/or modify
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        it under the terms of the GNU General Public Licence as published by
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        the Free Software Foundation, either version 3 of the Licence, or
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        (at your option) any later version.
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        This program is distributed in the hope that it will be useful,
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        but WITHOUT ANY WARRANTY; without even the implied warranty of
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        GNU General Public Licence for more details.
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        You should have received a copy of the GNU General Public Licence
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        along with this program. If not, see <https://www.gnu.org/licenses/>.
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        """
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        import os
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        from pathlib import Path
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        import locale
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        import panorama_panel
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        import gi
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        gi.require_version("Gtk", "4.0")
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        from gi.repository import Gtk, GLib, Gio, Gdk
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        module_directory = Path(__file__).resolve().parent
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        locale.bindtextdomain("panorama-app-menu", module_directory / "locale")
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        _ = lambda x: locale.dgettext("panorama-app-menu", x)
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        CATEGORY_MAPPINGS = {
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            "Utility": (_("Accessories"), "applications-accessories"),
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            "Development": (_("Programming"), "applications-development"),
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            "Game": (_("Games"), "applications-games"),
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            "Graphics": (_("Graphics"), "applications-graphics"),
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            "Network": (_("Network"), "applications-internet"),
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            "AudioVideo": (_("Multimedia"), "applications-multimedia"),
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            "Office": (_("Office"), "applications-office"),
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            "Science": (_("Science"), "applications-science"),
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            "Education": (_("Education"), "applications-education"),
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            "System": (_("System"), "applications-system"),
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            "Settings": (_("Settings"), "preferences-desktop"),
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            "Other": (_("Other"), "applications-other"),
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        }
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        custom_css = """
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        .no-menu-item-padding:dir(ltr) {
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            padding-left: 0;
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        }
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        .no-menu-item-padding:dir(rtl) {
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            padding-right: 0;
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        }
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        """
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        css_provider = Gtk.CssProvider()
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        css_provider.load_from_data(custom_css)
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        Gtk.StyleContext.add_provider_for_display(
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            Gdk.Display.get_default(),
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            css_provider,
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        )
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        def force_visible_on_visible_notify(widget, *args):
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            if not widget.get_visible():
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                widget.set_visible(True)
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        def add_icons_to_menu(popover: Gtk.PopoverMenu):
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            section = popover.get_child().get_first_child().get_first_child().get_first_child()
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            while section is not None:
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                child = section.get_first_child().get_first_child()
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                while child is not None:
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                    gutter_box: Gtk.Box = child.get_first_child()
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                    if isinstance(gutter_box.get_next_sibling(), Gtk.Image):
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                        # For some reason GTK creates images but they're hidden?
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                        image: Gtk.Image = gutter_box.get_next_sibling()
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                        label: Gtk.Label = image.get_next_sibling()
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                        image.unparent()
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                        gutter_box.unparent()
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                        gutter_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                        gutter_box.insert_before(child, label)
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                        gutter_box.append(image)
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                        image.set_icon_size(Gtk.IconSize.LARGE)
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                        image.set_margin_start(8)
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                        image.set_margin_end(8)
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                        child.add_css_class("no-menu-item-padding")
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                        # Push the arrow to the left
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                        label.set_halign(Gtk.Align.FILL)
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                        label.set_hexpand(True)
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                        label.set_xalign(0)
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                        # GTK pushes its stance on icons so hard it makes them invisible multiple times;
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                        # force it visible
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                        image.set_visible(True)
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                        image.connect("notify::visible", force_visible_on_visible_notify)
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                    # Find the submenu if there is one
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                    subchild = child.get_first_child()
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                    submenu = None
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                    while subchild is not None:
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                        if isinstance(subchild, Gtk.PopoverMenu):
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                            submenu = subchild
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                        subchild = subchild.get_next_sibling()
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                    # Recursive
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                    if submenu is not None:
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                        add_icons_to_menu(submenu)
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                    child = child.get_next_sibling()
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                section = section.get_next_sibling()
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        class AppMenu(panorama_panel.Applet):
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            name = _("App menu")
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            description = _("Show apps installed on your system, grouped by category")
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            def __init__(self, orientation=Gtk.Orientation.HORIZONTAL, config=None):
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                super().__init__(orientation=orientation, config=config)
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                if config is None:
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                    config = {}
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                self.button = Gtk.MenuButton()
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                self.button.set_has_frame(False)   # flat look
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                self.icon = Gtk.Image.new_from_icon_name("start-here")
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                self.button.set_child(self.icon)
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                self.apps_by_id: dict[int, Gio.AppInfo] = {}
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                self.menu = Gio.Menu()
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                self.popover = Gtk.PopoverMenu.new_from_model_full(self.menu, Gtk.PopoverMenuFlags.NESTED)
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                self.popover.set_has_arrow(False)
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                panorama_panel.track_popover(self.popover)
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                self.button.set_popover(self.popover)
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                self.generate_app_menu()
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                self.append(self.button)
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                self.context_menu = self.make_context_menu()
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                panorama_panel.track_popover(self.context_menu)
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                right_click_controller = Gtk.GestureClick()
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                right_click_controller.set_button(3)
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                right_click_controller.connect("pressed", self.show_context_menu)
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                self.add_controller(right_click_controller)
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                action_group = Gio.SimpleActionGroup()
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                options_action = Gio.SimpleAction.new("options", None)
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                options_action.connect("activate", self.show_options)
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                action_group.add_action(options_action)
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                options_action = Gio.SimpleAction.new("launch-app", GLib.VariantType.new("s"))
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                options_action.connect("activate", self.launch_app)
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                action_group.add_action(options_action)
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                self.insert_action_group("applet", action_group)
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                self.options_window = None
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            def launch_app(self, action, id: GLib.Variant):
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                app = self.apps_by_id[int(id.get_string())]
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                app.launch()
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            def make_context_menu(self):
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                menu = Gio.Menu()
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                menu.append(_("Menu _options"), "applet.options")
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                context_menu = Gtk.PopoverMenu.new_from_model(menu)
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                context_menu.set_has_arrow(False)
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                context_menu.set_parent(self)
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                context_menu.set_halign(Gtk.Align.START)
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                context_menu.set_flags(Gtk.PopoverMenuFlags.NESTED)
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                return context_menu
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            def show_context_menu(self, gesture, n_presses, x, y):
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                rect = Gdk.Rectangle()
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                rect.x = int(x)
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                rect.y = int(y)
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                rect.width = 1
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                rect.height = 1
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                self.context_menu.set_pointing_to(rect)
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                self.context_menu.popup()
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            def show_options(self, _0=None, _1=None):
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                ...
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            def get_config(self):
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                return {}
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            def set_panel_position(self, position):
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                self.popover.set_position(panorama_panel.OPPOSITE_POSITION[position])
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                self.button.set_direction(panorama_panel.POSITION_TO_ARROW[panorama_panel.OPPOSITE_POSITION[position]])
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            def generate_app_menu(self):
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                self.menu.remove_all()
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                self.apps_by_id = {}
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                all_apps = Gio.AppInfo.get_all()
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                apps_by_category: dict[str, list[Gio.AppInfo]] = {}
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                for category, info in CATEGORY_MAPPINGS.items():
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                    apps_by_category[category] = []
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                for app in all_apps:
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                    category_found = False
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                    if isinstance(app, Gio.DesktopAppInfo):
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                        if app.get_categories() is not None:
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                            categories = app.get_categories().split(";")
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                            for category in categories:
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                                if category in apps_by_category:
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                                    apps_by_category[category].append(app)
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                                    category_found = True
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                    if not category_found:
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                        apps_by_category["Other"].append(app)
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                for category, info in CATEGORY_MAPPINGS.items():
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                    if apps_by_category[category]:
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                        item = Gio.MenuItem.new(info[0])
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                        item.set_icon(Gio.ThemedIcon.new(info[1]))
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                        submenu = Gio.Menu()
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                        for app in apps_by_category[category]:
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                            if isinstance(app, Gio.DesktopAppInfo) and (app.get_is_hidden() or app.get_nodisplay()):
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                                continue
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                            subitem = Gio.MenuItem.new(app.get_display_name(), f"applet.launch-app::{id(app)}")
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                            subitem.set_icon(app.get_icon() or Gio.ThemedIcon.new("image-missing"))
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                            self.apps_by_id[id(app)] = app
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                            submenu.append_item(subitem)
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                        item.set_submenu(submenu)
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                        self.menu.append_item(item)
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                add_icons_to_menu(self.popover)
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                            
                                

config.yaml

@@ -7,6 +7,7 @@ panels:

                                
                                
                                
                            
                                
                                    
                                        
                                            
                                              can_capture_keyboard: false
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                              applets:
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                left:
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            - AppMenu: {}
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                - WFWindowList:
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                    max_button_width: 256
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                centre: []
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                            
                                

docs/accessibility.md

@@ -11,8 +11,8 @@ Get a plugin like

                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            [wf-panel-focus by Scott Moreau (for Wayfire)](https://github.com/soreau/wf-panel-focus)
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            which will add a keybinding to cycle between displayed panels (default:
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            Control-Alt-Tab) and one to return to the working area (Control-Alt-Esc). Enable
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        `can_capture_keyboard` on your panels so it will be able to be focused.
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        Then you can use normal GTK widget navigation in the panel.
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        `can_capture_keyboard` on your panels, so they will be able to be focused.
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        Then you can use normal GTK widget navigation in the panels.
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            If you enable that option without a suitable plugin, panels can be focused in
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            Wayfire by clicking them, which is not the expected UX, so don't enable it