Last active
June 4, 2020 04:30
-
-
Save cchudant/75b0999101942fd5abb0b991e181a5af to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import os | |
from Xlib.display import Display | |
from Xlib.xobject.drawable import Window | |
from Xlib.protocol.event import ClientMessage | |
from Xlib import X | |
from collections import namedtuple | |
WindowGeometry = namedtuple('WindowGeometry', 'x y width height') | |
WindowPosition = namedtuple('WindowPosition', 'x y') | |
WindowSize = namedtuple('WindowSize', 'width height') | |
class WindowManager: | |
def __init__(self, display = os.environ['DISPLAY']): | |
if display is str: | |
display = Display(display) | |
self._display = display | |
self._screen = display.screen() | |
self._root = _screen.root | |
def find_window_by_name(self, win: Window, name: str) -> Window: | |
""" | |
Returns the window which has that name, or none if none was found. | |
""" | |
if win.get_wm_name() == name: | |
return win | |
for child in win.query_tree().children: | |
ret = find_window_by_name(child, name) | |
if ret is not None: | |
return ret | |
def get_window_geometry(self, win: Window) -> WindowGeometry: | |
""" | |
Returns the (x, y, width, height) of a window relative to the top-left | |
of the screen. | |
""" | |
geom = win.get_geometry() | |
x, y = geom.x, geom.y | |
while True: | |
parent = win.query_tree().parent | |
pgeom = parent.get_geometry() | |
x += pgeom.x | |
y += pgeom.y | |
if parent.id == self._root.id: | |
break | |
win = parent | |
return WindowGeometry(x, y, geom.width, geom.height) | |
def get_window_position(self, win: Window) -> WindowPosition: | |
""" | |
Returns the (x, y) of a window relative to the top-left of the screen. | |
""" | |
x, y, _, _ = get_geometry(win) | |
return WindowPosition(x, y) | |
def get_window_size(self, win: Window) -> WindowSize: | |
""" | |
Returns the (width, height) of a window. | |
""" | |
geom = win.get_geometry() | |
return WindowSize(geom.width, geom.height) | |
def set_window_geometry(self, win: Window, geom: WindowGeometry): | |
""" | |
Sets the geometry (x, y, width, height) of a window. | |
""" | |
win.configure(x=geom[0], y=geom[1], width=geom[2], height=geom[3]) | |
self._display.flush() | |
def set_window_position(self, win: Window, geom: WindowPosition): | |
""" | |
Sets the position (x, y) of a window. | |
""" | |
win.configure(x=geom[0], y=geom[1]) | |
self._display.flush() | |
def set_window_size(self, win: Window, geom: WindowSize): | |
""" | |
Sets the size (width, height) of a window. | |
""" | |
win.configure(width=geom[0], height=geom[1]) | |
self._display.flush() | |
def close_window(self, win: Window): | |
""" | |
Ask a window to be closed. | |
""" | |
event = ClientMessage( | |
window=win, | |
client_type=display.intern_atom('WM_PROTOCOLS', 1), | |
data=(32, display.intern_atom('WM_DELETE_WINDOW').to_bytes(4, 'little') + b"\0" * 16) | |
) | |
win.send_event(event) | |
self._display.sync() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment