Mercurial > libervia-backend
annotate libervia/frontends/tools/display_servers.py @ 4326:5fd6a4dc2122
cli (output/std): use `rich` to output JSON.
author | Goffi <goffi@goffi.org> |
---|---|
date | Wed, 20 Nov 2024 11:38:44 +0100 |
parents | 4af030d4d3d8 |
children |
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 |