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

soreaus menu: Implement logout dialog

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