def test_default_float_hints(xmanager): xmanager.c.next_layout() w = None conn = xcbq.Connection(xmanager.display) def size_hints(): nonlocal w w = conn.create_window(5, 5, 10, 10) # set the size hints hints = [0] * 18 hints[0] = xcbq.NormalHintsFlags["PMinSize"] | xcbq.NormalHintsFlags["PMaxSize"] hints[5] = hints[6] = hints[7] = hints[8] = 10 w.set_property("WM_NORMAL_HINTS", hints, type="WM_SIZE_HINTS", format=32) w.map() conn.conn.flush() try: xmanager.create_window(size_hints) assert xmanager.c.window.info()['floating'] is True finally: w.kill_client() conn.finalize() w = None conn = xcbq.Connection(xmanager.display) def size_hints(): nonlocal w w = conn.create_window(5, 5, 10, 10) # set the aspect hints hints = [0] * 18 hints[0] = xcbq.NormalHintsFlags["PAspect"] hints[11] = hints[12] = hints[13] = hints[14] = 1 w.set_property("WM_NORMAL_HINTS", hints, type="WM_SIZE_HINTS", format=32) w.map() conn.conn.flush() try: xmanager.create_window(size_hints) assert xmanager.c.window.info()['floating'] is True info = xmanager.c.window.info() assert info['width'] == 10 assert info['height'] == 10 xmanager.c.window.toggle_floating() assert xmanager.c.window.info()['floating'] is False info = xmanager.c.window.info() assert info['width'] == 398 assert info['height'] == 578 xmanager.c.window.toggle_fullscreen() info = xmanager.c.window.info() assert info['width'] == 800 assert info['height'] == 600 finally: w.kill_client() conn.finalize()
def test_user_position(xmanager): w = None conn = xcbq.Connection(xmanager.display) def user_position_window(): nonlocal w w = conn.create_window(5, 5, 10, 10) # xmanager config automatically floats "float" w.set_property("WM_CLASS", "float", type="STRING", format=8) # set the user specified position flag hints = [0] * 18 hints[0] = xcbq.NormalHintsFlags["USPosition"] w.set_property("WM_NORMAL_HINTS", hints, type="WM_SIZE_HINTS", format=32) w.map() conn.conn.flush() try: xmanager.create_window(user_position_window) assert xmanager.c.window.info()['floating'] is True assert xmanager.c.window.info()['x'] == 5 assert xmanager.c.window.info()['y'] == 5 assert xmanager.c.window.info()['width'] == 10 assert xmanager.c.window.info()['height'] == 10 finally: w.kill_client() conn.finalize()
def test_only_input_hint_focus(manager): w = None conn = xcbq.Connection(manager.display) def only_input_hint(): nonlocal w w = conn.create_window(5, 5, 10, 10) w.set_attribute(eventmask=xcffib.xproto.EventMask.FocusChange) # manager config automatically floats xclock w.set_property("WM_CLASS", "xclock", type="STRING", format=8) # set the input hint hints = [0] * 14 hints[0] = xcbq.HintsFlags["InputHint"] hints[1] = 1 # set hints to 1, i.e. we want them w.set_property("WM_HINTS", hints, type="WM_HINTS", format=32) w.map() conn.conn.flush() try: manager.create_window(only_input_hint) assert manager.c.window.info()['floating'] is True got_take_focus, got_focus_in = wait_for_focus_events(conn) assert not got_take_focus assert got_focus_in finally: w.kill_client() conn.finalize()
def test_no_focus(xmanager): w = None conn = xcbq.Connection(xmanager.display) def no_focus(): nonlocal w w = conn.create_window(5, 5, 10, 10) w.set_attribute(eventmask=xcffib.xproto.EventMask.FocusChange) # xmanager config automatically floats "float" w.set_property("WM_CLASS", "float", type="STRING", format=8) hints = [0] * 14 hints[0] = xcbq.HintsFlags["InputHint"] w.set_property("WM_HINTS", hints, type="WM_HINTS", format=32) w.map() conn.conn.flush() try: xmanager.create_window(no_focus) assert xmanager.c.window.info()['floating'] is True got_take_focus, got_focus_in = wait_for_focus_events(conn) assert not got_take_focus assert not got_focus_in finally: w.kill_client() conn.finalize()
def test_net_client_list(xmanager): conn = xcbq.Connection(xmanager.display) def assert_clients(number): clients = conn.default_screen.root.get_property("_NET_CLIENT_LIST", unpack=int) assert len(clients) == number # ManagerConfig has a Bar, which should not appear in _NET_CLIENT_LIST assert_clients(0) one = xmanager.test_window("one") assert_clients(1) two = xmanager.test_window("two") xmanager.c.window.toggle_minimize() three = xmanager.test_window("three") xmanager.c.screen.next_group() assert_clients( 3) # Minimized windows and windows on other groups are included xmanager.kill_window(one) xmanager.c.screen.next_group() assert_clients(2) xmanager.kill_window(three) assert_clients(1) xmanager.c.screen.next_group() one = xmanager.test_window("one") assert_clients(2) xmanager.c.window.static() # Static windows are not included assert_clients(1) xmanager.kill_window(two) assert_clients(0)
def test_net_client_list(xmanager): conn = xcbq.Connection(xmanager.display) def assert_clients(number): clients = conn.default_screen.root.get_property('_NET_CLIENT_LIST', unpack=int) assert len(clients) == number assert_clients(0) one = xmanager.test_window("one") assert_clients(1) two = xmanager.test_window("two") wins = xmanager.c.windows() xmanager.c.window.toggle_minimize() three = xmanager.test_window("three") xmanager.c.screen.next_group() assert_clients(3) xmanager.kill_window(one) xmanager.c.screen.next_group() assert_clients(2) xmanager.kill_window(three) assert_clients(1) xmanager.c.screen.next_group() one = xmanager.test_window("one") assert_clients(2) xmanager.kill_window(one) xmanager.kill_window(two) assert_clients(0)
def test_cursor_warp(xmanager): conn = xcbq.Connection(xmanager.display) root = conn.default_screen.root.wid assert xmanager.c.screen.info()["index"] == 0 xmanager.test_window("one") xmanager.c.window.set_position_floating(50, 50) xmanager.c.window.set_size_floating(50, 50) xmanager.c.to_screen(1) assert xmanager.c.screen.info()["index"] == 1 p = conn.conn.core.QueryPointer(root).reply() # Here pointer should warp to the second screen as there are no windows # there. assert p.root_x == WIDTH + SECOND_WIDTH // 2 # Reduce the bar height from the screen height. assert p.root_y == (SECOND_HEIGHT - 20) // 2 xmanager.c.to_screen(0) assert xmanager.c.window.info()["name"] == "one" p = conn.conn.core.QueryPointer(xmanager.c.window.info()["id"]).reply() # Here pointer should warp to the window. assert p.win_x == 25 assert p.win_y == 25 assert p.same_screen
def test_max_size_hint(xmanager): w = None conn = xcbq.Connection(xmanager.display) def size_hints(): nonlocal w w = conn.create_window(0, 0, 100, 100) # set the size hints hints = [0] * 18 hints[0] = xcbq.NormalHintsFlags["PMaxSize"] hints[7] = hints[8] = 100 w.set_property("WM_NORMAL_HINTS", hints, type="WM_SIZE_HINTS", format=32) w.map() conn.conn.flush() try: xmanager.create_window(size_hints) xmanager.c.window.enable_floating() assert xmanager.c.window.info()['width'] == 100 assert xmanager.c.window.info()['height'] == 100 xmanager.c.window.set_size_floating(50, 50) assert xmanager.c.window.info()['width'] == 50 assert xmanager.c.window.info()['height'] == 50 xmanager.c.window.set_size_floating(200, 200) assert xmanager.c.window.info()['width'] == 100 assert xmanager.c.window.info()['height'] == 100 finally: w.kill_client() conn.finalize()
def get_valid_timestamp(self): """Get a valid timestamp, i.e. not CurrentTime, for X server. It may be used in cases where CurrentTime is unacceptable for X server.""" # do a zero length append to get the time offset as suggested by ICCCM # https://tronche.com/gui/x/icccm/sec-2.html#s-2.1 # we do this on a separate connection since we can't receive events # without returning control to the event loop, which we can't do # because the event loop (via some window event) wants to know the # current time. conn = None try: conn = xcbq.Connection(self._display_name) conn.default_screen.root.set_attribute( eventmask=EventMask.PropertyChange) conn.conn.core.ChangePropertyChecked( xcffib.xproto.PropMode.Append, self._root.wid, self.conn.atoms["WM_CLASS"], self.conn.atoms["STRING"], 8, 0, "", ).check() while True: event = conn.conn.wait_for_event() if event.__class__ != xcffib.xproto.PropertyNotifyEvent: continue return event.time finally: if conn is not None: conn.finalize()
def test_min_size_hint_no_flag(manager): w = None conn = xcbq.Connection(manager.display) def size_hints(): nonlocal w w = conn.create_window(0, 0, 100, 100) # set the size hints hints = [0] * 18 hints[5] = hints[6] = 100 w.set_property("WM_NORMAL_HINTS", hints, type="WM_SIZE_HINTS", format=32) w.map() conn.conn.flush() try: manager.create_window(size_hints) manager.c.window.enable_floating() print(w.get_wm_normal_hints()) assert manager.c.window.info()['width'] == 100 assert manager.c.window.info()['height'] == 100 manager.c.window.set_size_floating(50, 50) assert manager.c.window.info()['width'] == 50 assert manager.c.window.info()['height'] == 50 manager.c.window.set_size_floating(200, 200) assert manager.c.window.info()['width'] == 200 assert manager.c.window.info()['height'] == 200 finally: w.kill_client() conn.finalize()
def test_widgetbox_widget(manager): manager.conn = xcbq.Connection(manager.display) # We need to trick the widgets into thinking this is libqtile.qtile so # we add some methods that are called when the widgets are configured manager.call_soon = no_op manager.register_widget = no_op tb_one = TextBox(name="tb_one", text="TB ONE") tb_two = TextBox(name="tb_two", text="TB TWO") # Give widgetbox invalid value for button location widget_box = WidgetBox([tb_one, tb_two], close_button_location="middle", fontsize=10) # Create a bar and set attributes needed to run widget fakebar = Bar([widget_box], 24) fakebar.window = FakeWindow() fakebar.width = 10 fakebar.height = 10 fakebar.draw = no_op # Configure the widget box widget_box._configure(manager, fakebar) # Invalid value should be corrected to default assert widget_box.close_button_location == "left" # Check only widget in bar is widgetbox assert fakebar.widgets == [widget_box] # Open box widget_box.cmd_toggle() # Check it's open assert widget_box.box_is_open # Default text position is left assert fakebar.widgets == [widget_box, tb_one, tb_two] # Close box widget_box.cmd_toggle() # Check it's closed assert not widget_box.box_is_open # Check widgets have been removed assert fakebar.widgets == [widget_box] # Move button to right-hand side widget_box.close_button_location = "right" # Re-open box with new layout widget_box.cmd_toggle() # Now widgetbox is on the right assert fakebar.widgets == [tb_one, tb_two, widget_box]
def test_bring_front_click(manager, bring_front_click): def get_all_windows(conn): root = conn.default_screen.root.wid q = conn.conn.core.QueryTree(root).reply() return list(q.children) def fake_click(conn, xtest, x, y): root = conn.default_screen.root.wid xtest.FakeInput(6, 0, xcffib.xproto.Time.CurrentTime, root, x, y, 0) xtest.FakeInput(4, 1, xcffib.xproto.Time.CurrentTime, root, 0, 0, 0) xtest.FakeInput(5, 1, xcffib.xproto.Time.CurrentTime, root, 0, 0, 0) conn.conn.flush() conn = xcbq.Connection(manager.display) xtest = conn.conn(xcffib.xtest.key) # this is a tiled window. manager.test_window("one") manager.c.sync() manager.test_window("two") manager.c.window.set_position_floating(50, 50) manager.c.window.set_size_floating(50, 50) manager.c.sync() manager.test_window("three") manager.c.window.set_position_floating(150, 50) manager.c.window.set_size_floating(50, 50) manager.c.sync() wids = [x["id"] for x in manager.c.windows()] names = [x["name"] for x in manager.c.windows()] assert names == ["one", "two", "three"] wins = get_all_windows(conn) assert wins.index(wids[0]) < wins.index(wids[1]) < wins.index(wids[2]) # Click on window two fake_click(conn, xtest, 55, 55) manager.c.sync() wins = get_all_windows(conn) if bring_front_click: assert wins.index(wids[0]) < wins.index(wids[2]) < wins.index(wids[1]) else: assert wins.index(wids[0]) < wins.index(wids[1]) < wins.index(wids[2]) # Click on window one fake_click(conn, xtest, 10, 10) manager.c.sync() wins = get_all_windows(conn) if bring_front_click == "floating_only": assert wins.index(wids[0]) < wins.index(wids[2]) < wins.index(wids[1]) elif bring_front_click: assert wins.index(wids[2]) < wins.index(wids[1]) < wins.index(wids[0]) else: assert wins.index(wids[0]) < wins.index(wids[1]) < wins.index(wids[2])
def test_kill_via_message(xmanager): xmanager.test_window("one") window_info = xmanager.c.window.info() conn = xcbq.Connection(xmanager.display) data = xcffib.xproto.ClientMessageData.synthetic([0, 0, 0, 0, 0], "IIIII") ev = xcffib.xproto.ClientMessageEvent.synthetic( 32, window_info["id"], conn.atoms['_NET_CLOSE_WINDOW'], data) conn.default_screen.root.send_event( ev, mask=xcffib.xproto.EventMask.SubstructureRedirect) conn.xsync() conn.finalize() assert_window_died(xmanager.c, window_info)
def test_new_window(xdisplay): conn = xcbq.Connection(xdisplay) win = conn.create_window(1, 2, 640, 480) assert isinstance(win, xcbq.Window) geom = win.get_geometry() assert geom.x == 1 assert geom.y == 2 assert geom.width == 640 assert geom.height == 480 win.kill_client() with pytest.raises(xcffib.ConnectionException): win.get_geometry()
def test_focus(qtile): qtile.conn = xcbq.Connection(qtile.display) qtile.test_xeyes() popup = Popup(qtile) popup.width = qtile.c.screen.info()["width"] popup.height = qtile.c.screen.info()["height"] popup.place() popup.unhide() assert qtile.c.group.info()['focus'] == 'xeyes' assert qtile.c.group.info()['windows'] == ['xeyes'] assert len(qtile.c.windows()) == 1 popup.hide() popup.kill()
def test_net_frame_extents(xmanager): conn = xcbq.Connection(xmanager.display) def assert_frame(wid, frame): r = conn.conn.core.GetProperty( False, wid, conn.atoms["_NET_FRAME_EXTENTS"], conn.atoms["CARDINAL"], 0, (2**32) - 1 ).reply() assert r.value.to_atoms() == frame pid = xmanager.test_window("one") wid = xmanager.c.window.info()["id"] assert_frame(wid, (2, 2, 2, 2)) xmanager.c.next_layout() assert_frame(wid, (4, 4, 4, 4)) xmanager.c.window.enable_floating() assert_frame(wid, (6, 6, 6, 6)) xmanager.kill_window(pid)
def test_hints_setting_unsetting(xmanager): w = None conn = xcbq.Connection(xmanager.display) def no_input_hint(): nonlocal w w = conn.create_window(5, 5, 10, 10) w.map() conn.conn.flush() try: xmanager.create_window(no_input_hint) # We default the input hint to true since some non-trivial number of # windows don't set it, and most of them want focus. The spec allows # WMs to assume "convenient" values. assert xmanager.c.window.hints()['input'] # now try to "update" it, but don't really set an update (i.e. the # InputHint bit is 0, so the WM should not derive a new hint from the # content of the message at the input hint's offset) hints = [0] * 14 w.set_property("WM_HINTS", hints, type="WM_HINTS", format=32) conn.flush() # should still have the hint assert xmanager.c.window.hints()['input'] # now do an update: turn it off hints[0] = xcbq.HintsFlags["InputHint"] hints[1] = 0 w.set_property("WM_HINTS", hints, type="WM_HINTS", format=32) conn.flush() assert not xmanager.c.window.hints()['input'] # turn it back on hints[0] = xcbq.HintsFlags["InputHint"] hints[1] = 1 w.set_property("WM_HINTS", hints, type="WM_HINTS", format=32) conn.flush() assert xmanager.c.window.hints()['input'] finally: w.kill_client() conn.finalize()
def test_popup_focus(manager): manager.test_xeyes() manager.windows_map = {} # we have to add .conn so that Popup thinks this is libqtile.qtile manager.conn = xcbq.Connection(manager.display) try: popup = Popup(manager) popup.width = manager.c.screen.info()["width"] popup.height = manager.c.screen.info()["height"] popup.place() popup.unhide() assert manager.c.group.info()['focus'] == 'xeyes' assert manager.c.group.info()['windows'] == ['xeyes'] assert len(manager.c.windows()) == 1 popup.hide() finally: popup.kill() manager.conn.finalize()
def test_strut_handling(manager): w = None conn = xcbq.Connection(manager.display) def has_struts(): nonlocal w w = conn.create_window(0, 0, 10, 10) w.set_property("_NET_WM_STRUT", [0, 0, 0, 10]) w.map() conn.conn.flush() def test_initial_state(): assert manager.c.window.info()['width'] == 798 assert manager.c.window.info()['height'] == 578 assert manager.c.window.info()['x'] == 0 assert manager.c.window.info()['y'] == 0 bar_id = manager.c.bar["bottom"].info()["window"] bar = manager.c.window[bar_id].info() assert bar["height"] == 20 assert bar["y"] == 580 manager.test_xcalc() test_initial_state() try: manager.create_window(has_struts) manager.c.window.static(0, None, None, None, None) assert manager.c.window.info()['width'] == 798 assert manager.c.window.info()['height'] == 568 assert manager.c.window.info()['x'] == 0 assert manager.c.window.info()['y'] == 0 bar_id = manager.c.bar["bottom"].info()["window"] bar = manager.c.window[bar_id].info() assert bar["height"] == 20 assert bar["y"] == 570 finally: w.kill_client() conn.finalize() test_initial_state()
def test_only_one_focus(xmanager): w = None conn = xcbq.Connection(xmanager.display) def both_wm_take_focus_and_input_hint(): nonlocal w w = conn.create_window(5, 5, 10, 10) w.set_attribute(eventmask=xcffib.xproto.EventMask.FocusChange) # xmanager config automatically floats "float" w.set_property("WM_CLASS", "float", type="STRING", format=8) # set both the input hit hints = [0] * 14 hints[0] = xcbq.HintsFlags["InputHint"] hints[1] = 1 # set hints to 1, i.e. we want them w.set_property("WM_HINTS", hints, type="WM_HINTS", format=32) # and add the WM_PROTOCOLS protocol WM_TAKE_FOCUS conn.conn.core.ChangePropertyChecked( xcffib.xproto.PropMode.Append, w.wid, conn.atoms["WM_PROTOCOLS"], conn.atoms["ATOM"], 32, 1, [conn.atoms["WM_TAKE_FOCUS"]], ).check() w.map() conn.conn.flush() try: xmanager.create_window(both_wm_take_focus_and_input_hint) assert xmanager.c.window.info()['floating'] is True got_take_focus, got_focus_in = wait_for_focus_events(conn) assert not got_take_focus assert got_focus_in finally: w.kill_client() conn.finalize()
def test_change_state_via_message(manager): manager.test_window("one") window_info = manager.c.window.info() conn = xcbq.Connection(manager.display) data = xcffib.xproto.ClientMessageData.synthetic([libqtile.window.IconicState, 0, 0, 0, 0], "IIIII") ev = xcffib.xproto.ClientMessageEvent.synthetic( 32, window_info["id"], conn.atoms['WM_CHANGE_STATE'], data ) conn.default_screen.root.send_event(ev, mask=xcffib.xproto.EventMask.SubstructureRedirect) conn.xsync() assert manager.c.window.info()["minimized"] data = xcffib.xproto.ClientMessageData.synthetic([libqtile.window.NormalState, 0, 0, 0, 0], "IIIII") ev = xcffib.xproto.ClientMessageEvent.synthetic( 32, window_info["id"], conn.atoms['WM_CHANGE_STATE'], data ) conn.default_screen.root.send_event(ev, mask=xcffib.xproto.EventMask.SubstructureRedirect) conn.xsync() assert not manager.c.window.info()["minimized"] conn.finalize()
def test_net_wm_states(xdisplay): conn = xcbq.Connection(xdisplay) win = conn.create_window(1, 1, 640, 480) assert isinstance(win, xcbq.Window) def attr_name(x): return x.lstrip('_').lower() names = [attr_name(x) for x in xcbq.net_wm_states] for name in names: val = getattr(win, name) assert val is False setattr(win, name, True) val = getattr(win, name) assert val is True for name in names: assert getattr(win, name) is True for name in names: setattr(win, name, False) val = getattr(win, name) assert val is False
def __init__(self, display_name: str = None) -> None: """Setup the X11 core backend :param display_name: The display name to setup the X11 connection to. Uses the DISPLAY environment variable if not given. """ if display_name is None: display_name = os.environ.get("DISPLAY") if not display_name: raise QtileError("No DISPLAY set") self.conn = xcbq.Connection(display_name) self._display_name = display_name self._fd = None # type: Optional[int] # Because we only do Xinerama multi-screening, # we can assume that the first # screen's root is _the_ root. self._root = self.conn.default_screen.root self._root.set_attribute( eventmask=(xcffib.xproto.EventMask.StructureNotify | xcffib.xproto.EventMask.SubstructureNotify | xcffib.xproto.EventMask.SubstructureRedirect | xcffib.xproto.EventMask.EnterWindow | xcffib.xproto.EventMask.LeaveWindow)) self._root.set_property( "_NET_SUPPORTED", [self.conn.atoms[x] for x in xcbq.SUPPORTED_ATOMS]) self._last_event_timestamp = xcffib.CurrentTime self._wmname = "qtile" self._supporting_wm_check_window = self.conn.create_window( -1, -1, 1, 1) self._supporting_wm_check_window.set_property("_NET_WM_NAME", self._wmname) self._supporting_wm_check_window.set_property( "_NET_SUPPORTING_WM_CHECK", self._supporting_wm_check_window.wid) self._root.set_property("_NET_SUPPORTING_WM_CHECK", self._supporting_wm_check_window.wid) self._selection = { "PRIMARY": { "owner": None, "selection": "" }, "CLIPBOARD": { "owner": None, "selection": "" }, } self._selection_window = self.conn.create_window(-1, -1, 1, 1) self._selection_window.set_attribute( eventmask=xcffib.xproto.EventMask.PropertyChange) if hasattr(self.conn, "xfixes"): self.conn.xfixes.select_selection_input(self._selection_window, "PRIMARY") # type: ignore self.conn.xfixes.select_selection_input( self._selection_window, "CLIPBOARD") # type: ignore primary_atom = self.conn.atoms["PRIMARY"] reply = self.conn.conn.core.GetSelectionOwner(primary_atom).reply() self._selection["PRIMARY"]["owner"] = reply.owner clipboard_atom = self.conn.atoms["CLIPBOARD"] reply = self.conn.conn.core.GetSelectionOwner(primary_atom).reply() self._selection["CLIPBOARD"]["owner"] = reply.owner # ask for selection on start-up self.convert_selection(primary_atom) self.convert_selection(clipboard_atom) # setup the default cursor self._root.set_cursor("left_ptr") self.qtile = None # type: Optional[Qtile] self._painter = None numlock_code = self.conn.keysym_to_keycode(xcbq.keysyms["Num_Lock"]) self._numlock_mask = xcbq.ModMasks.get( self.conn.get_modifier(numlock_code), 0) self._valid_mask = ~(self._numlock_mask | xcbq.ModMasks["lock"])
def test_strut_handling(xmanager): w = [] conn = xcbq.Connection(xmanager.display) def has_struts(): nonlocal w w.append(conn.create_window(0, 0, 10, 10)) w[-1].set_property("_NET_WM_STRUT_PARTIAL", [0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 800]) w[-1].map() conn.conn.flush() def with_gaps_left(): nonlocal w w.append(conn.create_window(800, 0, 10, 10)) w[-1].set_property("_NET_WM_STRUT_PARTIAL", [820, 0, 0, 0, 0, 480, 0, 0, 0, 0, 0, 0]) w[-1].map() conn.conn.flush() def with_gaps_bottom(): nonlocal w w.append(conn.create_window(800, 0, 10, 10)) w[-1].set_property("_NET_WM_STRUT_PARTIAL", [0, 0, 0, 130, 0, 0, 0, 0, 0, 0, 800, 1440]) w[-1].map() conn.conn.flush() def test_initial_state(): while xmanager.c.screen.info()["index"] != 0: xmanager.c.next_screen() assert xmanager.c.window.info()['width'] == 798 assert xmanager.c.window.info()['height'] == 578 assert xmanager.c.window.info()['x'] == 0 assert xmanager.c.window.info()['y'] == 0 bar_id = xmanager.c.bar["bottom"].info()["window"] bar = xmanager.c.window[bar_id].info() assert bar["height"] == 20 assert bar["y"] == 580 xmanager.c.next_screen() assert xmanager.c.window.info()['width'] == 638 assert xmanager.c.window.info()['height'] == 478 assert xmanager.c.window.info()['x'] == 800 assert xmanager.c.window.info()['y'] == 0 xmanager.test_window('one') xmanager.c.next_screen() xmanager.test_window('two') test_initial_state() try: while xmanager.c.screen.info()["index"] != 0: xmanager.c.next_screen() xmanager.create_window(has_struts) xmanager.c.window.static(None, None, None, None, None) assert xmanager.c.window.info()['width'] == 798 assert xmanager.c.window.info()['height'] == 568 assert xmanager.c.window.info()['x'] == 0 assert xmanager.c.window.info()['y'] == 0 bar_id = xmanager.c.bar["bottom"].info()["window"] bar = xmanager.c.window[bar_id].info() assert bar["height"] == 20 assert bar["y"] == 570 xmanager.c.next_screen() xmanager.create_window(with_gaps_bottom) xmanager.c.window.static(None, None, None, None, None) xmanager.create_window(with_gaps_left) xmanager.c.window.static(None, None, None, None, None) assert xmanager.c.window.info()['width'] == 618 assert xmanager.c.window.info()['height'] == 468 assert xmanager.c.window.info()['x'] == 820 assert xmanager.c.window.info()['y'] == 0 finally: for win in w: win.kill_client() conn.finalize() test_initial_state()
def __init__(self, display_name: str = None) -> None: """Setup the X11 core backend :param display_name: The display name to setup the X11 connection to. Uses the DISPLAY environment variable if not given. """ if display_name is None: display_name = os.environ.get("DISPLAY") if not display_name: raise QtileError("No DISPLAY set") self.conn = xcbq.Connection(display_name) self._display_name = display_name # Because we only do Xinerama multi-screening, # we can assume that the first # screen's root is _the_ root. self._root = self.conn.default_screen.root supporting_wm_wid = self._root.get_property("_NET_SUPPORTING_WM_CHECK", "WINDOW", unpack=int) if len(supporting_wm_wid) > 0: supporting_wm_wid = supporting_wm_wid[0] supporting_wm = window.XWindow(self.conn, supporting_wm_wid) existing_wmname = supporting_wm.get_property("_NET_WM_NAME", "UTF8_STRING", unpack=str) if existing_wmname: logger.error("not starting; existing window manager {}".format( existing_wmname)) raise ExistingWMException(existing_wmname) self.eventmask = (EventMask.StructureNotify | EventMask.SubstructureNotify | EventMask.SubstructureRedirect | EventMask.EnterWindow | EventMask.LeaveWindow | EventMask.ButtonPress) self._root.set_attribute(eventmask=self.eventmask) self._root.set_property( "_NET_SUPPORTED", [self.conn.atoms[x] for x in xcbq.SUPPORTED_ATOMS]) self._wmname = "qtile" self._supporting_wm_check_window = self.conn.create_window( -1, -1, 1, 1) self._supporting_wm_check_window.set_property("_NET_WM_NAME", self._wmname) self._supporting_wm_check_window.set_property( "_NET_SUPPORTING_WM_CHECK", self._supporting_wm_check_window.wid) self._root.set_property("_NET_SUPPORTING_WM_CHECK", self._supporting_wm_check_window.wid) self._selection = { "PRIMARY": { "owner": None, "selection": "" }, "CLIPBOARD": { "owner": None, "selection": "" }, } self._selection_window = self.conn.create_window(-1, -1, 1, 1) self._selection_window.set_attribute( eventmask=EventMask.PropertyChange) if hasattr(self.conn, "xfixes"): self.conn.xfixes.select_selection_input(self._selection_window, "PRIMARY") # type: ignore self.conn.xfixes.select_selection_input( self._selection_window, "CLIPBOARD") # type: ignore primary_atom = self.conn.atoms["PRIMARY"] reply = self.conn.conn.core.GetSelectionOwner(primary_atom).reply() self._selection["PRIMARY"]["owner"] = reply.owner clipboard_atom = self.conn.atoms["CLIPBOARD"] reply = self.conn.conn.core.GetSelectionOwner(primary_atom).reply() self._selection["CLIPBOARD"]["owner"] = reply.owner # ask for selection on start-up self.convert_selection(primary_atom) self.convert_selection(clipboard_atom) # setup the default cursor self._root.set_cursor("left_ptr") self.qtile = None # type: Optional[Qtile] self._painter = None numlock_code = self.conn.keysym_to_keycode(xcbq.keysyms["Num_Lock"])[0] self._numlock_mask = xcbq.ModMasks.get( self.conn.get_modifier(numlock_code), 0) self._valid_mask = ~(self._numlock_mask | xcbq.ModMasks["lock"] | xcbq.AllButtonsMask)