annotate libervia/frontends/tools/display_servers.py @ 4229:dd9bc7d791d7

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