Mercurial > libervia-backend
comparison libervia/frontends/tools/display_servers.py @ 4203:4af030d4d3d8
frontends (tools): module to handle display servers:
rel 433
author | Goffi <goffi@goffi.org> |
---|---|
date | Tue, 16 Jan 2024 10:41:58 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
4202:b26339343076 | 4203:4af030d4d3d8 |
---|---|
1 #!/usr/bin/env python3 | |
2 | |
3 # Libervia tools for display servers | |
4 # Copyright (C) 2009-2024 Jérôme Poisson (goffi@goffi.org) | |
5 | |
6 # This program is free software: you can redistribute it and/or modify | |
7 # it under the terms of the GNU Affero General Public License as published by | |
8 # the Free Software Foundation, either version 3 of the License, or | |
9 # (at your option) any later version. | |
10 | |
11 # This program is distributed in the hope that it will be useful, | |
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 # GNU Affero General Public License for more details. | |
15 | |
16 # You should have received a copy of the GNU Affero General Public License | |
17 # along with this program. If not, see <http://www.gnu.org/licenses/>. | |
18 | |
19 | |
20 try: | |
21 from Xlib import X, display | |
22 from Xlib.xobject.drawable import Window | |
23 except ImportError: | |
24 pass | |
25 import os | |
26 | |
27 X11 = "X11" | |
28 WAYLAND = "Wayland" | |
29 | |
30 | |
31 def x11_list_windows() -> list[dict[str, object]]: | |
32 """Lists all X11 windows with their metadata. | |
33 | |
34 @param disp: The X11 display connection. | |
35 @return: A list of dictionaries with window metadata. Each dictionary contains the | |
36 metadata returned by [x11_get_window_metadata]. | |
37 """ | |
38 disp = display.Display() | |
39 window_list = [] | |
40 root = disp.screen().root | |
41 window_ids = root.get_full_property( | |
42 disp.intern_atom("_NET_CLIENT_LIST"), X.AnyPropertyType | |
43 ).value | |
44 | |
45 for window_id in window_ids: | |
46 window = disp.create_resource_object("window", window_id) | |
47 window_metadata = x11_get_window_metadata(window) | |
48 window_list.append(window_metadata) | |
49 | |
50 return window_list | |
51 | |
52 | |
53 def x11_get_window_metadata(window: Window) -> dict[str, object]: | |
54 """Extracts metadata from a given X11 window. | |
55 | |
56 @param window: The X11 window object. | |
57 @return: A dictionary with the window's metadata, including: | |
58 | |
59 ``id`` (int) | |
60 window id | |
61 ``type`` (str) | |
62 "application" or "virtual desktop" | |
63 ``title`` (str) | |
64 combined class name and window name, truncated if long | |
65 ``window_name`` (str|none) | |
66 original window name | |
67 ``class`` (tuple[str, str]|none) | |
68 window class | |
69 ``geometry`` (dict) | |
70 dictionary with keys ``x``, ``y``, ``width``, ``height`` | |
71 """ | |
72 window_id = window.id | |
73 window_name = window.get_wm_name() | |
74 window_class = window.get_wm_class() | |
75 geometry = window.get_geometry() | |
76 | |
77 # Q&D virtual desktop detection | |
78 virtual_desktop_classes = ["plasmashell", "gnome-shell", "xfdesktop", "mate-panel"] | |
79 window_type = ( | |
80 "virtual desktop" | |
81 if window_class and any(vc in window_class[1] for vc in virtual_desktop_classes) | |
82 else "application" | |
83 ) | |
84 | |
85 class_name = window_class[1] if window_class else "Unknown" | |
86 title = f"{class_name}: {window_name or ''}" | |
87 if len(title) > 50: | |
88 title = f"{title[:47]}…" | |
89 | |
90 return { | |
91 "id": window_id, | |
92 "type": window_type, | |
93 "title": title, | |
94 "window_name": window_name, | |
95 "class": window_class, | |
96 "geometry": { | |
97 "x": geometry.x, | |
98 "y": geometry.y, | |
99 "width": geometry.width, | |
100 "height": geometry.height, | |
101 }, | |
102 } | |
103 | |
104 | |
105 def detect() -> str | None: | |
106 """Detects the type of window manager or display server in use. | |
107 | |
108 @return: A string indicating the type of window manager/display server ("X11", | |
109 "Wayland", or None). | |
110 """ | |
111 if "WAYLAND_DISPLAY" in os.environ: | |
112 return WAYLAND | |
113 elif "DISPLAY" in os.environ: | |
114 return X11 | |
115 else: | |
116 return None |