frontends (tools): module to handle display servers:
rel 433
This commit is contained in:
parent
dc8078fe4c
commit
3fecc07a7e
2 changed files with 117 additions and 0 deletions
116
libervia/frontends/tools/display_servers.py
Normal file
116
libervia/frontends/tools/display_servers.py
Normal file
|
|
@ -0,0 +1,116 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
# Libervia tools for display servers
|
||||
# Copyright (C) 2009-2024 Jérôme Poisson (goffi@goffi.org)
|
||||
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
try:
|
||||
from Xlib import X, display
|
||||
from Xlib.xobject.drawable import Window
|
||||
except ImportError:
|
||||
pass
|
||||
import os
|
||||
|
||||
X11 = "X11"
|
||||
WAYLAND = "Wayland"
|
||||
|
||||
|
||||
def x11_list_windows() -> list[dict[str, object]]:
|
||||
"""Lists all X11 windows with their metadata.
|
||||
|
||||
@param disp: The X11 display connection.
|
||||
@return: A list of dictionaries with window metadata. Each dictionary contains the
|
||||
metadata returned by [x11_get_window_metadata].
|
||||
"""
|
||||
disp = display.Display()
|
||||
window_list = []
|
||||
root = disp.screen().root
|
||||
window_ids = root.get_full_property(
|
||||
disp.intern_atom("_NET_CLIENT_LIST"), X.AnyPropertyType
|
||||
).value
|
||||
|
||||
for window_id in window_ids:
|
||||
window = disp.create_resource_object("window", window_id)
|
||||
window_metadata = x11_get_window_metadata(window)
|
||||
window_list.append(window_metadata)
|
||||
|
||||
return window_list
|
||||
|
||||
|
||||
def x11_get_window_metadata(window: Window) -> dict[str, object]:
|
||||
"""Extracts metadata from a given X11 window.
|
||||
|
||||
@param window: The X11 window object.
|
||||
@return: A dictionary with the window's metadata, including:
|
||||
|
||||
``id`` (int)
|
||||
window id
|
||||
``type`` (str)
|
||||
"application" or "virtual desktop"
|
||||
``title`` (str)
|
||||
combined class name and window name, truncated if long
|
||||
``window_name`` (str|none)
|
||||
original window name
|
||||
``class`` (tuple[str, str]|none)
|
||||
window class
|
||||
``geometry`` (dict)
|
||||
dictionary with keys ``x``, ``y``, ``width``, ``height``
|
||||
"""
|
||||
window_id = window.id
|
||||
window_name = window.get_wm_name()
|
||||
window_class = window.get_wm_class()
|
||||
geometry = window.get_geometry()
|
||||
|
||||
# Q&D virtual desktop detection
|
||||
virtual_desktop_classes = ["plasmashell", "gnome-shell", "xfdesktop", "mate-panel"]
|
||||
window_type = (
|
||||
"virtual desktop"
|
||||
if window_class and any(vc in window_class[1] for vc in virtual_desktop_classes)
|
||||
else "application"
|
||||
)
|
||||
|
||||
class_name = window_class[1] if window_class else "Unknown"
|
||||
title = f"{class_name}: {window_name or ''}"
|
||||
if len(title) > 50:
|
||||
title = f"{title[:47]}…"
|
||||
|
||||
return {
|
||||
"id": window_id,
|
||||
"type": window_type,
|
||||
"title": title,
|
||||
"window_name": window_name,
|
||||
"class": window_class,
|
||||
"geometry": {
|
||||
"x": geometry.x,
|
||||
"y": geometry.y,
|
||||
"width": geometry.width,
|
||||
"height": geometry.height,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
def detect() -> str | None:
|
||||
"""Detects the type of window manager or display server in use.
|
||||
|
||||
@return: A string indicating the type of window manager/display server ("X11",
|
||||
"Wayland", or None).
|
||||
"""
|
||||
if "WAYLAND_DISPLAY" in os.environ:
|
||||
return WAYLAND
|
||||
elif "DISPLAY" in os.environ:
|
||||
return X11
|
||||
else:
|
||||
return None
|
||||
|
|
@ -49,6 +49,7 @@ dependencies = [
|
|||
# "python-potr < 1.1",
|
||||
"pyxdg < 0.30",
|
||||
"pyyaml < 7.0.0",
|
||||
"python-xlib ~= 0.33",
|
||||
"prompt_toolkit ~= 3.0",
|
||||
"rich ~= 13.5",
|
||||
"sat_tmp @ hg+https://repos.goffi.org/sat_tmp#egg=sat_tmp",
|
||||
|
|
|
|||
Loading…
Reference in a new issue