def get_randr_screens(): conn = xcffib.connect() conn.randr = conn(xcffib.randr.key) window = conn.get_setup().roots[0].root resources = conn.randr.GetScreenResourcesCurrent(window).reply() outputs = OrderedDict() for rroutput in resources.outputs: try: cookie = conn.randr.GetOutputInfo( rroutput, resources.config_timestamp ) info = cookie.reply() name = "".join(map(chr, info.name)) cookie = conn.randr.GetCrtcInfo( info.crtc, resources.config_timestamp ) info = cookie.reply() if info: outputs[name] = (info.width, info.height, info.x, info.y) except Exception as e: logger.debug("Error when trying to fetch screens infos") logger.debug(e) continue return outputs
def xvfb(): display = ":{:d}".format(_find_display()) args = ["Xvfb", display, "-screen", "0", "800x600x16"] proc = subprocess.Popen(args) try: # wait for X display to come up start = time.time() while proc.poll() is None and time.time() < start + max_sleep: try: conn = xcffib.connect(display) except xcffib.ConnectionException: time.sleep(sleep_time) else: conn.disconnect() break else: raise OSError("Xvfb did not come up") os.environ["DISPLAY"] = display yield finally: proc.terminate() proc.wait()
def init_randr_connection (self, **kwd): """ Starts connection, construct an initial state, setup events. """ # Connection self.conn = xcffib.connect (display = kwd.get ("display")) # Randr init self.conn.randr = self.conn (xcffib.randr.key) version = Pair.from_struct (self.conn.randr.QueryVersion (*Backend.randr_version).reply (), "major_version", "minor_version") if (not version >= Backend.randr_version): raise BackendFatalError ("version: requested >= {}, got {}".format (Client.randr_version, version)) # Properties query object self.prop_manager = PropertyQuery (self.conn) # TODO # Internal state screen_setup = self.conn.setup.roots[kwd.get ("screen", self.conn.pref_screen)] self.root = screen_setup.root limits = self.conn.randr.GetScreenSizeRange (self.root).reply () self.screen_limit_min = Pair.from_size (limits, "min_{}") self.screen_limit_max = Pair.from_size (limits, "max_{}") self.reload_state () # Randr register for events masks = xcffib.randr.NotifyMask.ScreenChange | xcffib.randr.NotifyMask.CrtcChange masks |= xcffib.randr.NotifyMask.OutputChange | xcffib.randr.NotifyMask.OutputProperty self.conn.randr.SelectInput (self.root, masks) self.conn.flush ()
def run_single_trial_one_library(self, library): """Runs a single trial with one library""" connection = connect() setup = connection.get_setup() root_window = setup.roots[0].root window = self.warp_to_random_window(connection, root_window) position = self.get_pointer_position(connection, window) connection.disconnect() pointer_window = library() lib = pointer_window.library timing = pointer_window.find_window()[2] del pointer_window self.write_result_row({ 'library': lib, 'root_x': position.root_x, 'root_y': position.root_y, 'window': window, 'win_x': position.win_x, 'win_y': position.win_y, 'start': timing[0], 'gather_basics': timing[1], 'root_window': timing[2], 'recursion': timing[3], 'get_names': timing[4], 'parse_names': timing[5], 'exit': timing[6] })
def get_window_id(prop, value): window_id = 0 c = xcffib.connect() root = c.get_setup().roots[0].root _NET_CLIENT_LIST = c.core.InternAtom(True, len('_NET_CLIENT_LIST'), '_NET_CLIENT_LIST').reply().atom raw_clientlist = c.core.GetProperty(False, root, _NET_CLIENT_LIST, xcffib.xproto.GetPropertyType.Any, 0, 2 ** 32 - 1).reply() clientlist = get_property_value(raw_clientlist) cookies = {} for ident in clientlist: if prop in dir(xcffib.xproto.Atom): atom = getattr(xcffib.xproto.Atom, prop) else: atom = c.core.InternAtom(True, len(prop), prop).reply().atom cookies[ident] = c.core.GetProperty(False, ident, atom, xcffib.xproto.GetPropertyType.Any, 0, 2 ** 32 - 1) for ident in cookies: winclass = get_property_value(cookies[ident].reply()) if isinstance(winclass, list): if value in winclass: window_id = ident break c.disconnect() return window_id
def __init__(self, display): self.conn = xcffib.connect(display=display) self._connected = True self.cursors = Cursors(self) self.setup = self.conn.get_setup() extensions = self.extensions() self.screens = [Screen(self, i) for i in self.setup.roots] self.default_screen = self.screens[self.conn.pref_screen] for i in extensions: if i in self._extmap: setattr(self, i, self._extmap[i](self)) self.pseudoscreens = [] if "xinerama" in extensions: for i, s in enumerate(self.xinerama.query_screens()): scr = PseudoScreen(self, s.x_org, s.y_org, s.width, s.height) self.pseudoscreens.append(scr) elif "randr" in extensions: for i in self.randr.query_crtcs(self.screens[0].root.wid): scr = PseudoScreen(self, i["x"], i["y"], i["width"], i["height"]) self.pseudoscreens.append(scr) self.atoms = AtomCache(self) self.code_to_syms = {} self.first_sym_to_code = None self.refresh_keymap() self.modmap = None self.refresh_modmap()
def __init__(self, size=DEFAULT_SIZE, color=DEFAULT_COLOR): self.size = size self.color = color self.connection = xcffib.connect() setup = self.connection.get_setup() self.screen = setup.roots[self.connection.pref_screen] self.windows = BorderWindows._make(self.create_window() for _ in range(4))
def gather_basics(self): """Gets the connection and setup""" self.logger.info('Gathering X connection') connection = connect() self.logger.debug("Connection: %s", connection) setup = connection.get_setup() self.logger.debug("Setup: %s", setup) return [connection, setup]
def test_auth_connect(self): authname = six.b("MIT-MAGIC-COOKIE-1") authdata = six.b("\xa5\xcf\x95\xfa\x19\x49\x03\x60\xaf\xe4\x1e\xcd\xa3\xe2\xad\x47") authstr = authname + six.b(':') + authdata conn = xcffib.connect(display=os.environ['DISPLAY'], auth=authstr) assert conn.get_setup().roots[0].root > 0
def set_up_xcffib(self): self.connection = xcffib.connect() self.root = self.connection.get_setup().roots[0].root self.connection.core.ChangeWindowAttributesChecked( self.root, xcffib.xproto.CW.EventMask, [xcffib.xproto.EventMask.PropertyChange], ).check() print(int(self.connection.core.GetWindowAttributes( self.root).reply().your_event_mask))
def is_withdrawn(window_id: int) -> bool: c = xcffib.connect() atom = c.core.InternAtom(True, len('WM_STATE'), 'WM_STATE').reply().atom property_reply = c.core.GetProperty(False, window_id, atom, xcffib.xproto.GetPropertyType.Any, 0, 2 ** 32 - 1).reply() property_value = get_property_value(property_reply) c.disconnect() withdrawn = not property_value or property_value[0] == 0 return withdrawn
def property_change(self, prop, prop_type, form, mode, data): # Gobject has no API to set properties (strangely), so we have to use xcb instead conn = xcb.connect() def get_atom(atom): ia = conn.core.InternAtom(False, len(atom), atom) return ia.reply().atom conn.core.ChangePropertyChecked(int(mode), self.get_window().get_xid(), get_atom(prop), get_atom(prop_type), form, int(len(data) / form * 8), data).check()
def _waitForXephyr(self): # Wait until Xephyr process dies while self.xephyr.poll() is None: try: conn = xcffib.connect(self.display) break except xcffib.ConnectionException: pass time.sleep(0.1) else: raise AssertionError("Error launching Xephyr, quit with return code: %d" % self.xephyr.returncode) conn.disconnect() del conn
def get(DISPLAY=None, defaults=None): """ Get the X resources in an X servers resource manager. Parameters ========== DISPLAY : str (optional) DISPLAY name to query. This will be taken from the environment if not specified. defaults : dict (optional) Default values to act as a fallback for missing values or in the event of a failed connection. Returns ======= resources: dict Dictionary containing all (available) X resources. Resources that are specified in an Xresources/Xdefaults file as wildcards e.g. '*.color1' have the leading '*.' stripped. """ if DISPLAY is None: DISPLAY = os.environ.get("DISPLAY") if defaults is None: resources = {} else: resources = defaults try: conn = xcffib.connect(display=DISPLAY) except xcffib.ConnectionException as e: logger.exception(e) return resources root = conn.get_setup().roots[0].root atom = conn.core.InternAtom(False, 16, 'RESOURCE_MANAGER').reply().atom reply = conn.core.GetProperty(False, root, atom, xcffib.xproto.Atom.STRING, 0, (2**32) - 1).reply() conn.disconnect() resource_string = reply.value.buf().decode("utf-8") resource_list = filter(None, resource_string.split('\n')) for resource in resource_list: key, value = resource.split(':\t') resources[key.strip('*.')] = value return resources
def xcb_conn(request): """ Fixture that will setup and take down a xcffib.Connection object running on a display spawned by xvfb """ display = os.environ.get('DISPLAY') if display: conn = xcffib.connect(display) def teardown_conn(): conn.disconnect() else: pytest.skip('DISPLAY environment variable not set') request.addfinalizer(teardown_conn) return conn
def start_xephyr(self): """Start Xephyr instance Starts the Xephyr instance and sets the `self.display` to the display which is used to setup the instance. """ # we'll try twice to open Xephyr for _ in range(2): # get a new display self.display = ":{}".format(_find_display()) # build up arguments args = [ "Xephyr", "-name", "qtile_test", self.display, "-ac", "-screen", "%sx%s" % (self.width, self.height) ] if self.two_screens: args.extend([ "-origin", "%s,0" % self.xoffset, "-screen", "%sx%s" % (SECOND_WIDTH, SECOND_HEIGHT) ]) if self.xinerama: args.extend(["+xinerama"]) if self.randr: args.extend(["+extension", "RANDR"]) self.proc = subprocess.Popen(args) start = time.time() # wait for X display to come up while self.proc.poll() is None and time.time() < start + max_sleep: try: conn = xcffib.connect(self.display) except xcffib.ConnectionException: time.sleep(sleep_time) else: conn.disconnect() return else: # we wern't able to get a display up self.display = None raise AssertionError( "Unable to start Xephyr, quit with return code {:d}".format( self.proc.returncode))
def xcb_fetch_windows(): """ Returns an array of rects of currently visible windows. """ x = xcffib.connect() root = x.get_setup().roots[0].root rects = [] #iterate through top-level windows for child in x.core.QueryTree(root).reply().children: # make sure we only consider windows that are actually visible attributes = x.core.GetWindowAttributes(child).reply() if attributes.map_state != XCB_MAP_STATE_VIEWABLE: continue rects += [x.core.GetGeometry(child).reply()] return rects
def __init__(self, con=None, ext=None): """ con: Optional existing xcb connection or display string. ext: RandR extension object associated with con. """ if con is None or isinstance(con, str): self.con = con = xcffib.connect(display=con) if ext is None: self.ext = con(randr.key) # BackLight Atoms bla = [con.core.InternAtom(True, len(a), a.encode('latin-1')).reply().atom for a in ('Backlight', 'BACKLIGHT')] self.bla = [a for a in bla if a] if not bla: raise IOError("No outputs have backlight property") a = 'INTEGER' self.intatom = con.core.InternAtom( False, len(a), a.encode('latin-1')).reply().atom
def xcb_fetch_windows(): """ Returns an array of rects of currently visible windows. """ x = xcb.connect() root = x.get_setup().roots[0].root rects = [] # iterate through top-level windows for child in x.core.QueryTree(root).reply().children: # make sure we only consider windows that are actually visible attributes = x.core.GetWindowAttributes(child).reply() if attributes.map_state != XCB_MAP_STATE_VIEWABLE: continue rects += [x.core.GetGeometry(child).reply()] return rects
def start_xephyr(self): """Start Xephyr instance Starts the Xephyr instance and sets the `self.display` to the display which is used to setup the instance. """ # we'll try twice to open Xephyr for _ in range(2): # get a new display self.display = ":{}".format(_find_display()) # build up arguments args = [ "Xephyr", "-name", "qtile_test", self.display, "-ac", "-screen", "%sx%s" % (self.width, self.height)] if self.two_screens: args.extend(["-origin", "%s,0" % self.xoffset, "-screen", "%sx%s" % (SECOND_WIDTH, SECOND_HEIGHT)]) if self.xinerama: args.extend(["+xinerama"]) if self.randr: args.extend(["+extension", "RANDR"]) self.proc = subprocess.Popen(args) start = time.time() # wait for X display to come up while self.proc.poll() is None and time.time() < start + max_sleep: try: conn = xcffib.connect(self.display) except xcffib.ConnectionException: time.sleep(sleep_time) else: conn.disconnect() return else: # we wern't able to get a display up self.display = None raise AssertionError("Unable to start Xephyr, quit with return code {:d}".format( self.proc.returncode ))
def _waitForXephyr(self): # Wait until Xephyr process dies while self.xephyr.poll() is None: try: conn = xcffib.connect(self.display) break except xcffib.ConnectionException: pass time.sleep(0.1) else: (stdout_data, stderr_data) = self.xephyr.communicate() raise AssertionError("Error launching Xephyr, quit with return code: {:d}\n" "stderr: {}\n" "stdout: {}".format( self.xephyr.returncode, stderr_data.decode(), stdout_data.decode() ) ) conn.disconnect() del conn
def __init__(self, display=None, desktops=None, loop=None): self.log = Log("WM") # INIT SOME BASIC STUFF self.hook = Hook() self.windows = {} # mapping between window id and Window self.win2desk = {} if not display: display = os.environ.get("DISPLAY") try: self._conn = xcffib.connect(display=display) except xcffib.ConnectionException: sys.exit("cannot connect to %s" % display) self.atoms = AtomVault(self._conn) self.desktops = desktops or [Desktop()] self.cur_desktop = self.desktops[0] self.cur_desktop.show() # CREATE ROOT WINDOW xcb_setup = self._conn.get_setup() xcb_screens = [i for i in xcb_setup.roots] self.xcb_default_screen = xcb_screens[self._conn.pref_screen] root_wid = self.xcb_default_screen.root self.root = Window(self, wid=root_wid, atoms=self.atoms, mapped=True) self.windows[root_wid] = self.root # for desktop in self.desktops: # desktop.windows.append(self.root) self.root.set_attr( eventmask=( EventMask.StructureNotify | EventMask.SubstructureNotify | EventMask.FocusChange # | EventMask.SubstructureRedirect | EventMask.EnterWindow # | EventMask.LeaveWindow # | EventMask.PropertyChange | EventMask.OwnerGrabButton ) ) # INFORM X WHICH FEATURES WE SUPPORT self.root.props[self.atoms._NET_SUPPORTED] = [self.atoms[a] for a in SUPPORTED_ATOMS] # PRETEND TO BE A WINDOW MANAGER supporting_wm_check_window = self.create_window(-1, -1, 1, 1) supporting_wm_check_window.props['_NET_WM_NAME'] = "SWM" self.root.props['_NET_SUPPORTING_WM_CHECK'] = supporting_wm_check_window.wid self.root.props['_NET_NUMBER_OF_DESKTOPS'] = len(self.desktops) self.root.props['_NET_CURRENT_DESKTOP'] = 0 # TODO: set cursor # EVENTS THAT HAVE LITTLE USE FOR US... self.ignoreEvents = { "KeyRelease", "ReparentNotify", # "CreateNotify", # DWM handles this to help "broken focusing windows". # "MapNotify", "ConfigureNotify", "LeaveNotify", "FocusOut", "FocusIn", "NoExposure", } # KEYBOARD self.kbd = Keyboard(xcb_setup, self._conn) self.mouse = Mouse(conn=self._conn, root=self.root) # FLUSH XCB BUFFER self.xsync() # apply settings # the event loop is not yet there, but we might have some pending # events... self._xpoll() # TODO: self.grabMouse # NOW IT'S TIME TO GET PHYSICAL SCREEN CONFIGURATION self.xrandr = Xrandr(root=self.root, conn=self._conn) # TODO: self.update_net_desktops() # SETUP EVENT LOOP if not loop: loop = asyncio.new_event_loop() self._eventloop = loop self._eventloop.add_signal_handler(signal.SIGINT, self.stop) self._eventloop.add_signal_handler(signal.SIGTERM, self.stop) self._eventloop.add_signal_handler(signal.SIGCHLD, self.on_sigchld) self._eventloop.set_exception_handler( lambda loop, ctx: self.log.error( "Got an exception in {}: {}".format(loop, ctx)) ) fd = self._conn.get_file_descriptor() self._eventloop.add_reader(fd, self._xpoll) # HANDLE STANDARD EVENTS self.hook.register("MapRequest", self.on_map_request) self.hook.register("MapNotify", self.on_map_notify) self.hook.register("UnmapNotify", self.on_window_unmap) self.hook.register("KeyPress", self.on_key_press) # self.hook.register("KeyRelease", self.on_key_release) # self.hook.register("CreateNotify", self.on_window_create) self.hook.register("PropertyNotify", self.on_property_notify) self.hook.register("ClientMessage", self.on_client_message) self.hook.register("DestroyNotify", self.on_window_destroy) self.hook.register("EnterNotify", self.on_window_enter) self.hook.register("ConfigureRequest", self.on_configure_window) self.hook.register("MotionNotify", self.on_mouse_event) self.hook.register("ButtonPress", self.on_mouse_event) self.hook.register("ButtonRelease", self.on_mouse_event)
def __init__(self, consumer='callback', check_queue_interval=0.01, use_xlib=False, conn=None, verbose=False): ''' if the consumer param = 'callback', -> All hotkeys will require a callback function - Experimental! - Otherwise set consumer to a function to hanlde the event. parameters sent will be - event, hotkey, callbacks event is the xwindow/microsoft keyboard eventm hotkey is a tuple, callback is any info that you registerd with the hotkey check_queue_interval is in seconds and sets the sleep time on checking the queue for hotkey presses set use_xlib to true to use the xlib python bindings (GPL) instead of the xcb ones (BSD) You can pass an exisiting X display or connection using the conn keyword, otherwise one will be created for you. ''' # Changes the class methods to point to differenct functions # Depening on the operating system and library used # Consumer can be set to a function also, which will be sent the event # as well as the key and mask already broken out # Last option for consumer is False, then you have to listen to the queue yourself # data_queue self.verbose = verbose self.use_xlib = use_xlib self.consumer = consumer self.check_queue_interval = check_queue_interval def mark_event_type(event): # event gets an event_type attribute so the user has a portiabble way # actually on windows as far as i know you dont have the option of binding on keypress or release so... # anyway ahve to check it but for now u dont! if os.name == 'posix': if self.use_xlib: if event.type == X.KeyPress: event.event_type = 'keypress' elif event.type == X.KeyRelease: event.event_type = 'keyrelease' else: if isinstance(event, xproto.KeyPressEvent): event.event_type = 'keypress' if isinstance(event, xproto.KeyReleaseEvent): event.event_type = 'keyrelease' else: event.event_type = 'keypress' return event self.data_queue = queue.Queue() if os.name == 'nt': self.hk_action_queue = queue.Queue() self.modders = win_modders self._the_grab = self._nt_the_grab self.get_keycode = self._nt_get_keycode self._get_keysym = self._nt_get_keysym thread.start_new_thread(self._nt_wait,(),) elif use_xlib: # Use the python-xlib library bindings, GPL License self.modders = xlib_modifiers self.trivial_mods = xlib_trivial_mods self._the_grab = self._xlib_the_grab self.get_keycode = self._xlib_get_keycode self._get_keysym = self._xlib_get_keysym if not conn: self.disp = Display() else: self.disp = conn self.xRoot = self.disp.screen().root self.xRoot.change_attributes(event_mask=X.KeyPressMask) thread.start_new_thread(self._xlib_wait,(),) else: # Using xcb and the xcffib python bindings Apache 2 http://stackoverflow.com/questions/40100/apache-license-vs-bsd-vs-mit self.modders = xcb_modifiers self.trivial_mods = xcb_trivial_mods self._the_grab = self._xcb_the_grab self.get_keycode = self._xcb_get_keycode self._get_keysym = self._xcb_get_keysym if not conn: self.conn = xcffib.connect() else: self.conn = conn self.root = self.conn.get_setup().roots[0].root thread.start_new_thread(self._xcb_wait,(),) if consumer == 'callback': if self.verbose: print('In Callback') def thread_me(): while 1: time.sleep(self.check_queue_interval) try: event = self.data_queue.get(block=False) except queue.Empty: pass else: event = mark_event_type(event) hotkey = self.parse_event(event) #~ for cb in self.get_callback(hotkey, event.event_type): #when i was using the keypress / keyrelease shit for cb in self.get_callback(hotkey): if event.event_type == 'keypress': if self.verbose: print('calling ', repr(cb)) cb(event) # TBD either throw these up in a thread, or pass in a queue to be put onto thread.start_new_thread(thread_me,(),) elif callable(consumer): def thread_me(): while 1: time.sleep(self.check_queue_interval) try: event = self.data_queue.get(block=False) except queue.Empty: pass else: hotkey = self.parse_event(mark_event_type(event)) if event.event_type == 'keypress': args = [cb for cb in self.get_callback(hotkey)] #~ callbacks = [cb for cb in self.get_callback(hotkey, event.event_type)] consumer(event, hotkey, args) thread.start_new_thread(thread_me,(),) else: print('You need to handle grabbing events yourself!')
def can_connect_x11(disp=':0'): conn = xcffib.connect(display=disp) conn.disconnect() return True
from atom import AtomVault import xcffib from xcffib import xproto conn = xcffib.connect() def test_get_atom(): # lookup a standard atom atoms = AtomVault(conn) WM_NAME = atoms.WM_NAME assert WM_NAME.id == xproto.Atom.WM_NAME # sanity check _NET_WM_NAME = atoms._NET_WM_NAME _NET_WM_NAME.name == "_NET_WM_NAME" assert _NET_WM_NAME.type == ('UTF8_STRING', 8) assert _NET_WM_NAME.name in atoms._atoms # lookup by integer id assert atoms[_NET_WM_NAME.id] == _NET_WM_NAME
import os import xcffib from xcffib.testing import XvfbTest from xcffib.xproto import Atom, ConfigWindow, EventMask, GetPropertyType conn = xcffib.connect(os.environ['DISPLAY']) xproto = xcffib.xproto.xprotoExtension(conn) def arrange(layout, windowids): for lay, winid in zip(layout, windowids): xproto.ConfigureWindow(winid, ConfigWindow.X | ConfigWindow.Y | ConfigWindow.Width | ConfigWindow.Height, lay) conn.flush() def move(winid, x, y, sync=True): xproto.ConfigureWindow(winid, ConfigWindow.X | ConfigWindow.Y, [x, y]) if sync: conn.flush()
def test_the_script(self): NAME = "one" for i in range(20): try: conn = xcffib.connect(os.environ['DISPLAY']) except xcffib.ConnectionException: time.sleep(0.1) continue except Exception as v: print("Error opening test window: ", type(v), v, file=sys.stderr) sys.exit(1) break else: print("Could not open window on display %s" % (sys.argv[1]), file=sys.stderr) sys.exit(1) screen = conn.get_setup().roots[conn.pref_screen] window = conn.generate_id() background = conn.core.AllocColor(screen.default_colormap, 0x2828, 0x8383, 0xCECE).reply().pixel # Color "#2883ce" conn.core.CreateWindow(xcffib.CopyFromParent, window, screen.root, 100, 100, 100, 100, 1, xcffib.xproto.WindowClass.InputOutput, screen.root_visual, xcffib.xproto.CW.BackPixel | xcffib.xproto.CW.EventMask, [background, xcffib.xproto.EventMask.StructureNotify | xcffib.xproto.EventMask.Exposure]) conn.core.ChangeProperty(xcffib.xproto.PropMode.Replace, window, xcffib.xproto.Atom.WM_NAME, xcffib.xproto.Atom.STRING, 8, len(NAME), NAME) wm_protocols = "WM_PROTOCOLS" wm_protocols = conn.core.InternAtom(0, len(wm_protocols), wm_protocols).reply().atom wm_delete_window = "WM_DELETE_WINDOW" wm_delete_window = conn.core.InternAtom(0, len(wm_delete_window), wm_delete_window).reply().atom conn.core.ChangeProperty(xcffib.xproto.PropMode.Replace, window, wm_protocols, xcffib.xproto.Atom.ATOM, 32, 1, [wm_delete_window]) conn.core.ConfigureWindow(window, xcffib.xproto.ConfigWindow.X | xcffib.xproto.ConfigWindow.Y | xcffib.xproto.ConfigWindow.Width | xcffib.xproto.ConfigWindow.Height | xcffib.xproto.ConfigWindow.BorderWidth, [0, 0, 100, 100, 1]) conn.core.MapWindow(window) conn.flush() conn.core.ConfigureWindow(window, xcffib.xproto.ConfigWindow.X | xcffib.xproto.ConfigWindow.Y | xcffib.xproto.ConfigWindow.Width | xcffib.xproto.ConfigWindow.Height | xcffib.xproto.ConfigWindow.BorderWidth, [0, 0, 100, 100, 1]) # now kill the window from the "wm" side via WM_DELETE_WINDOW protocol WM_PROTOCOLS = self.conn.core.InternAtom(False, len("WM_PROTOCOLS"), "WM_PROTOCOLS").reply().atom WM_DELETE_WINDOW = self.conn.core.InternAtom(False, len("WM_DELETE_WINDOW"), "WM_DELETE_WINDOW").reply().atom vals = [ 33, # ClientMessageEvent 32, # Format 0, window, WM_PROTOCOLS, WM_DELETE_WINDOW, xcffib.xproto.Time.CurrentTime, 0, 0, 0, ] e = struct.pack('BBHII5I', *vals) self.conn.core.SendEvent(False, window, EventMask.NoEvent, e) self.conn.flush() while 1: conn.flush() event = conn.wait_for_event() if event.__class__ == xcffib.xproto.ClientMessageEvent: atom = conn.core.GetAtomName(event.type).reply().name.to_string() print(atom) if atom == "WM_PROTOCOLS": break
import time import xcffib import xcffib.xproto def configure(window): window.configure( width=100, height=100, x=0, y=0, border_width=1, ) for i in range(20): try: conn = xcffib.connect(display=sys.argv[1]) except xcffib.ConnectionException: time.sleep(0.1) continue except Exception as v: print("Error opening test window: ", type(v), v, file=sys.stderr) sys.exit(1) break else: print("Could not open window on display %s" % (sys.argv[1]), file=sys.stderr) sys.exit(1) screen = conn.get_setup().roots[conn.pref_screen] window = conn.generate_id() background = conn.core.AllocColor(screen.default_colormap, 0x2828, 0x8383, 0xCECE).reply().pixel # Color "#2883ce"
def test_wrap(self): c = xcffib.connect() c.invalid() c2 = xcffib.wrap(xcffib.ffi.cast("long", c._conn)) c2.invalid() c2.disconnect()
def test_connect(self): c = xcffib.connect() c.invalid() assert c.has_error() == 0 c.disconnect()