Skip to content

Instantly share code, notes, and snippets.

@cchudant
Last active June 4, 2020 04:30
Show Gist options
  • Save cchudant/75b0999101942fd5abb0b991e181a5af to your computer and use it in GitHub Desktop.
Save cchudant/75b0999101942fd5abb0b991e181a5af to your computer and use it in GitHub Desktop.
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