Soreau's Menu: Improvements
This patch discards menu entries that either have no categories or no icon. Also improve keyboard navigation semantics. Most notable is Enter works to run the command for the highlighted menu item now.
This patch discards menu entries that either have no categories or no icon. Also improve keyboard navigation semantics. Most notable is Enter works to run the command for the highlighted menu item now.
by soreau, Friday, 15 August 2025, 05:38:57 (1755236337), pushed by roundabout, Friday, 15 August 2025, 10:38:33 (1755254313)
Author identity: Scott Moreau <oreaus@gmail.com>
c49241a2a3658992dca587b275f72d7d0760f319
self.popover = Gtk.Popover()
self.popover.set_parent(self)
self.flowbox = Gtk.FlowBox()
self.flowbox_item_focus_signal = self.flowbox.connect("selected-children-changed", on_flowbox_item_focus)
self.populate_menu_entries()
self.scrolled_window = Gtk.ScrolledWindow()
self.scrolled_window.set_child(self.flowbox)
self.popover.set_child(self.scrolled_window)
self.popover.set_size_request(300, 400)
self.popover.connect("show", self.on_popover_popup)
self.button.set_popover(self.popover)
def popover_popup(self, parent):
def on_flowbox_item_focus(self, flowbox):
selected_children = flowbox.get_selected_children()
if len(selected_children) >= 1:
selected_children[0].get_child().grab_focus()
def on_popover_popup(self, parent):
for child in self.flowbox.get_selected_children():
self.flowbox.unselect_child(child)
self.popover.popup()
def app_button_clicked(self, app_button):
print(f"Launching: {app_button.command}")
if os.getenv("LD_PRELOAD") is not None:
del os.environ["LD_PRELOAD"]
subprocess.Popen(app_button.command, start_new_session=True)
self.popover.popdown()
app_infos = Gio.AppInfo.get_all() # Get all registered applications
for app_info in app_infos:
app_categories = app_info.get_categories()
if app_categories == None:
continue
app_name = app_info.get_display_name()
app_button = Gtk.Button()
app_button.command = app_info.get_executable()
app_button_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
app_button_box.append(app_label)
app_button.set_child(app_button_box)
self.flowbox.append(app_button)
app_button.connect("clicked", lambda *_, app_button=app_button: self.app_button_clicked(app_button))
image = Gtk.Image.new_from_icon_name("foobarbaz")
image = Gtk.Image()
image.set_icon_size(Gtk.IconSize.LARGE)
icon = app_info.get_icon()
if icon:
icon_name = icon.to_string()
if not Gtk.IconTheme.get_for_display(Gdk.Display.get_default()).has_icon(icon_name):
continue
if icon_name[0] == '/':
image.set_from_file(icon_name)
else:
image.set_from_icon_name(icon_name)
else:
print(f"No icon found: {app_name}")
if not Gtk.IconTheme.get_for_display(Gdk.Display.get_default()).has_icon(app_name.lower()):
continue
image.set_from_icon_name(app_name.lower())
app_button_box.prepend(image)
self.flowbox.append(app_button)
app_button.connect("clicked", self.app_button_clicked)
app_button_box.prepend(image)