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

 __init__.py

View raw Download
text/x-script.python • 4.57 kiB
Python script, ASCII text executable
        
            
1
import os
2
from pathlib import Path
3
from pywayland.client import Display
4
from pywayland.protocol.wayland import WlRegistry
5
from pywayland.protocol.wlr_foreign_toplevel_management_unstable_v1 import (
6
ZwlrForeignToplevelManagerV1,
7
ZwlrForeignToplevelHandleV1
8
)
9
import panorama_panel
10
11
import gi
12
13
gi.require_version("Gtk", "4.0")
14
15
from gi.repository import Gtk, GLib, Gio, Gdk
16
17
18
module_directory = Path(__file__).resolve().parent
19
20
21
class WindowButton(Gtk.ToggleButton):
22
def __init__(self, window_id, window_title, **kwargs):
23
super().__init__(**kwargs)
24
25
self.window_id = window_id
26
self.window_title = window_title
27
self.set_has_frame(False)
28
29
self.set_label(self.window_title)
30
31
self.last_state = False
32
33
34
class WFWindowList(panorama_panel.Applet):
35
name = "Wayfire window list"
36
description = "Traditional window list (for Wayfire)"
37
38
def __init__(self, orientation=Gtk.Orientation.HORIZONTAL, config=None):
39
super().__init__(orientation=orientation, config=config)
40
if config is None:
41
config = {}
42
43
self.toplevel_buttons: dict[ZwlrForeignToplevelHandleV1, WindowButton] = {}
44
# This button doesn't belong to any window but is used for the button group and to be
45
# selected when no window is focused
46
self.initial_button = Gtk.ToggleButton()
47
48
self.display = Display()
49
self.display.connect()
50
self.registry = self.display.get_registry()
51
self.registry.dispatcher["global"] = self.on_global
52
self.display.roundtrip()
53
fd = self.display.get_fd()
54
GLib.io_add_watch(fd, GLib.IO_IN, self.on_display_event)
55
56
self.context_menu = self.make_context_menu()
57
panorama_panel.track_popover(self.context_menu)
58
59
right_click_controller = Gtk.GestureClick()
60
right_click_controller.set_button(3)
61
right_click_controller.connect("pressed", self.show_context_menu)
62
63
self.add_controller(right_click_controller)
64
65
action_group = Gio.SimpleActionGroup()
66
options_action = Gio.SimpleAction.new("options", None)
67
options_action.connect("activate", self.show_options)
68
action_group.add_action(options_action)
69
self.insert_action_group("applet", action_group)
70
71
self.options_window = None
72
73
def on_display_event(self, source, condition):
74
if condition == GLib.IO_IN:
75
self.display.dispatch(block=True)
76
return True
77
78
def on_global(self, registry, name, interface, version):
79
print(f"Global: {interface} (v{version})")
80
if interface == "zwlr_foreign_toplevel_manager_v1":
81
print("Interface registered")
82
self.manager = registry.bind(name, ZwlrForeignToplevelManagerV1, version)
83
self.manager.dispatcher["toplevel"] = self.on_new_toplevel
84
self.manager.dispatcher["finished"] = lambda *a: print("Toplevel manager finished")
85
self.display.roundtrip()
86
self.display.flush()
87
88
def on_new_toplevel(self, manager: ZwlrForeignToplevelManagerV1,
89
handle: ZwlrForeignToplevelHandleV1):
90
print("Toplevel received")
91
handle.dispatcher["title"] = lambda h, title: self.on_title_changed(h, title)
92
#handle.dispatcher["app_id"] = lambda h, app_id: self.on_app_id_changed(h, app_id)
93
#handle.dispatcher["state"] = lambda h, states: self.on_state_changed(h, states)
94
#handle.dispatcher["closed"] = lambda h: self.on_closed(h)
95
96
def on_title_changed(self, handle, title):
97
print(f"Window title: {title}")
98
if handle not in self.toplevel_buttons:
99
button = WindowButton(id(handle), title)
100
button.set_group(self.initial_button)
101
button.connect("clicked", lambda *a: self.on_button_click(handle))
102
self.toplevel_buttons[handle] = button
103
self.append(button)
104
105
def make_context_menu(self):
106
menu = Gio.Menu()
107
menu.append("Window list _options", "applet.options")
108
context_menu = Gtk.PopoverMenu.new_from_model(menu)
109
context_menu.set_has_arrow(False)
110
context_menu.set_parent(self)
111
context_menu.set_halign(Gtk.Align.START)
112
context_menu.set_flags(Gtk.PopoverMenuFlags.NESTED)
113
return context_menu
114
115
def show_context_menu(self, gesture, n_presses, x, y):
116
rect = Gdk.Rectangle()
117
rect.x = int(x)
118
rect.y = int(y)
119
rect.width = 1
120
rect.height = 1
121
122
self.context_menu.set_pointing_to(rect)
123
self.context_menu.popup()
124
125
def show_options(self, _0=None, _1=None):
126
pass
127
128
def get_config(self):
129
return {}
130