soreau,
created on Monday, 18 August 2025, 22:54:03 (1755557643),
received on Tuesday, 19 August 2025, 05:05:18 (1755579918)
Author identity: Scott Moreau <oreaus@gmail.com>
0f40d7f6cd3a5d22579de2dc6572ec642d823010
applets/soreaus-menu/__init__.py
@@ -29,10 +29,112 @@ import panorama_panel
import gi
gi.require_version("Gtk", "4.0")
gi.require_version("Gtk4LayerShell", "1.0")
from gi.repository import Gtk, GLib, Gio, Gdk, Pango
from gi.repository import Gtk, GLib, Gtk4LayerShell, Gio, Gdk, Pango
import subprocess
LOGOUT_BUTTON_SIZE = 125
LOGOUT_BUTTON_MARGIN = 10
def create_logout_ui_button(icon_name, label_text):
layout = Gtk.Box()
image = Gtk.Image()
label = Gtk.Label()
button = Gtk.Button()
button.set_size_request(LOGOUT_BUTTON_SIZE, LOGOUT_BUTTON_SIZE)
image.set_from_icon_name(icon_name)
label.set_text(label_text)
layout.set_orientation(Gtk.Orientation.VERTICAL)
layout.set_halign(Gtk.Align.CENTER)
layout.append(image)
image.set_icon_size(Gtk.IconSize.LARGE)
image.set_vexpand(True)
layout.append(label)
button.set_child(layout)
return button
class WayfireLogoutUI(Gtk.Window):
def __init__(self):
super().__init__()
hbox = Gtk.CenterBox()
main_layout = Gtk.Grid()
suspend = create_logout_ui_button("emblem-synchronizing", "Suspend")
suspend.connect("clicked", self.on_suspend_click)
main_layout.attach(suspend, 0, 0, 1, 1)
hibernate = create_logout_ui_button("weather-clear-night", "Hibernate")
hibernate.connect("clicked", self.on_hibernate_click)
main_layout.attach(hibernate, 1, 0, 1, 1)
switchuser = create_logout_ui_button("system-users", "Switch User")
switchuser.connect("clicked", self.on_switchuser_click)
main_layout.attach(switchuser, 2, 0, 1, 1)
logout = create_logout_ui_button("system-log-out", "Log Out")
logout.connect("clicked", self.on_logout_click)
main_layout.attach(logout, 0, 1, 1, 1)
reboot = create_logout_ui_button("system-reboot", "Reboot")
reboot.connect("clicked", self.on_reboot_click)
main_layout.attach(reboot, 1, 1, 1, 1)
shutdown = create_logout_ui_button("system-shutdown", "Shut Down")
shutdown.connect("clicked", self.on_shutdown_click)
main_layout.attach(shutdown, 2, 1, 1, 1)
cancel_button = Gtk.Button()
cancel_button.set_size_request(100, 50)
cancel_button.set_label("Cancel")
main_layout.attach(cancel_button, 1, 2, 1, 1)
cancel_button.connect("clicked", self.on_cancel_click)
main_layout.set_row_spacing(LOGOUT_BUTTON_MARGIN)
main_layout.set_column_spacing(LOGOUT_BUTTON_MARGIN)
# Make surfaces layer shell
Gtk4LayerShell.init_for_window(self)
Gtk4LayerShell.set_namespace(self, "com.roundabout_host.panorama.logout")
Gtk4LayerShell.set_layer(self, Gtk4LayerShell.Layer.OVERLAY)
Gtk4LayerShell.set_anchor(self, Gtk4LayerShell.Edge.TOP, True)
Gtk4LayerShell.set_anchor(self, Gtk4LayerShell.Edge.BOTTOM, True)
Gtk4LayerShell.set_anchor(self, Gtk4LayerShell.Edge.LEFT, True)
Gtk4LayerShell.set_anchor(self, Gtk4LayerShell.Edge.RIGHT, True)
main_layout.set_valign(Gtk.Align.CENTER)
hbox.set_center_widget(main_layout)
hbox.set_hexpand(True)
hbox.set_vexpand(True)
self.set_child(hbox)
self.get_style_context().add_class("logout")
display = self.get_display()
css_provider = Gtk.CssProvider()
css_provider.load_from_data("window.logout { background-color: rgba(0, 0, 0, 0.5); }")
Gtk.StyleContext.add_provider_for_display(display, css_provider, Gtk.STYLE_PROVIDER_PRIORITY_USER)
def on_suspend_click(self, button):
GLib.spawn_command_line_async("systemctl suspend")
def on_hibernate_click(self, button):
GLib.spawn_command_line_async("systemctl hibernate")
def on_switchuser_click(self, button):
GLib.spawn_command_line_async("dm-tool switch-to-greeter")
def on_logout_click(self, button):
GLib.spawn_command_line_async("wayland-logout")
def on_reboot_click(self, button):
GLib.spawn_command_line_async("systemctl reboot")
def on_shutdown_click(self, button):
GLib.spawn_command_line_async("systemctl poweroff")
def on_cancel_click(self, button):
self.hide()
class SoreausMenu(panorama_panel.Applet):
name = "Soreau's menu"
description = "Flowbox app menu"
@@ -42,6 +144,7 @@ class SoreausMenu(panorama_panel.Applet):
self.button = Gtk.MenuButton()
self.menu_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
image = Gtk.Image.new_from_icon_name("wayfire")
image.set_icon_size(Gtk.IconSize.LARGE)
self.append(self.button)
@@ -52,11 +155,29 @@ class SoreausMenu(panorama_panel.Applet):
self.flowbox_item_focus_signal = self.flowbox.connect("selected-children-changed", self.on_flowbox_item_focus)
self.populate_menu_entries()
self.scrolled_window = Gtk.ScrolledWindow()
self.scrolled_window.set_size_request(-1, 350)
self.scrolled_window.set_child(self.flowbox)
self.popover.set_child(self.scrolled_window)
self.logout_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
self.logout_button = Gtk.Button()
self.logout_button.set_margin_top(5)
self.logout_button.set_margin_bottom(5)
self.logout_button.set_margin_start(5)
self.logout_button.set_margin_end(5)
self.logout_button.set_child(Gtk.Image.new_from_icon_name("system-shutdown"))
self.logout_button.connect("clicked", self.on_logout_button_clicked)
self.logout_box.set_halign(Gtk.Align.END)
self.logout_box.append(self.logout_button)
self.menu_box.append(self.scrolled_window)
self.menu_box.append(self.logout_box)
self.popover.set_child(self.menu_box)
self.popover.set_size_request(300, 400)
self.popover.connect("show", self.on_popover_popup)
self.button.set_popover(self.popover)
self.logout_ui = WayfireLogoutUI()
def on_logout_button_clicked(self, button):
self.logout_ui.present()
self.popover.popdown()
def on_flowbox_item_focus(self, flowbox):
selected_children = flowbox.get_selected_children()