def handle_ClientMessage(self, event): # noqa: N802 atoms = self.conn.atoms opcode = event.type data = event.data.data32 message = data[1] wid = data[2] parent = self.bar.window.window if opcode == atoms["_NET_SYSTEM_TRAY_OPCODE"] and message == 0: w = window.XWindow(self.conn, wid) icon = Icon(w, self.qtile, self) if icon not in self.tray_icons: self.tray_icons.append(icon) self.tray_icons.sort(key=lambda icon: icon.name) self.qtile.windows_map[wid] = icon self.conn.conn.core.ChangeSaveSet(SetMode.Insert, wid) self.conn.conn.core.ReparentWindow(wid, parent.wid, 0, 0) self.conn.conn.flush() info = icon.window.get_property("_XEMBED_INFO", unpack=int) if not info: self.bar.draw() return False if info[1]: self.bar.draw() return False
def create_window(self, x, y, width, height, desired_depth=32): depth, visual = self.default_screen._get_depth_and_visual( desired_depth) wid = self.conn.generate_id() value_mask = CW.BackPixmap | CW.BorderPixel | CW.EventMask | CW.Colormap values = [ xcffib.xproto.BackPixmap._None, 0, EventMask.StructureNotify | EventMask.Exposure, self.colormap(depth), ] self.conn.core.CreateWindow( depth, wid, self.default_screen.root.wid, x, y, width, height, 0, WindowClass.InputOutput, visual.visual_id, value_mask, values, ) return window.XWindow(self, wid)
def _configure(self, qtile, bar): base._Widget._configure(self, qtile, bar) if self.configured: return self.conn = conn = qtile.core.conn win = conn.create_window(-1, -1, 1, 1) window._Window.__init__(self, window.XWindow(conn, win.wid), qtile) qtile.windows_map[win.wid] = self # Even when we have multiple "Screen"s, we are setting up as the system # tray on a particular X display, that is the screen we need to # reference in the atom if qtile.current_screen: self.screen = qtile.current_screen.index self.bar = bar atoms = conn.atoms conn.conn.core.SetSelectionOwner( win.wid, atoms['_NET_SYSTEM_TRAY_S{:d}'.format(self.screen)], xcffib.CurrentTime) data = [ xcffib.CurrentTime, atoms['_NET_SYSTEM_TRAY_S{:d}'.format(self.screen)], win.wid, 0, 0 ] union = ClientMessageData.synthetic(data, "I" * 5) event = ClientMessageEvent.synthetic(format=32, window=qtile.core._root.wid, type=atoms['MANAGER'], data=union) qtile.core._root.send_event(event, mask=EventMask.StructureNotify)
def handle_MapRequest(self, event) -> None: # noqa: N802 assert self.qtile is not None xwin = window.XWindow(self.conn, event.window) try: attrs = xwin.get_attributes() internal = xwin.get_property("QTILE_INTERNAL") except (xcffib.xproto.WindowError, xcffib.xproto.AccessError): return if attrs and attrs.override_redirect: return win = self.qtile.windows_map.get(xwin.wid) if win: if isinstance(win, window.Window) and win.group is self.qtile.current_group: win.unhide() return if internal: win = window.Internal(xwin, self.qtile) self.qtile.manage(win) win.unhide() else: win = window.Window(xwin, self.qtile) if xwin.get_wm_type() == "dock" or win.reserved_space: assert self.qtile.current_screen is not None win.cmd_static(self.qtile.current_screen.index) return self.qtile.manage(win) if not win.group or not win.group.screen: return win.unhide()
def _configure(self, qtile, bar): base._Widget._configure(self, qtile, bar) if self.configured: return if Systray._instances > 0: raise ConfigError("Only one Systray can be used.") self.conn = conn = qtile.core.conn win = conn.create_window(-1, -1, 1, 1) window._Window.__init__(self, window.XWindow(conn, win.wid), qtile) qtile.windows_map[win.wid] = self # window._Window.__init__ overwrites the widget name so we need to restore it self.name = self._name # Even when we have multiple "Screen"s, we are setting up as the system # tray on a particular X display, that is the screen we need to # reference in the atom if qtile.current_screen: self.screen = qtile.current_screen.index self.bar = bar atoms = conn.atoms # We need tray to tell icons which visual to use. # This needs to be the same as the bar/widget. # This mainly benefits transparent bars. conn.conn.core.ChangeProperty( xcffib.xproto.PropMode.Replace, win.wid, atoms["_NET_SYSTEM_TRAY_VISUAL"], xcffib.xproto.Atom.VISUALID, 32, 1, [self.drawer._visual.visual_id], ) conn.conn.core.SetSelectionOwner( win.wid, atoms["_NET_SYSTEM_TRAY_S{:d}".format(self.screen)], xcffib.CurrentTime) data = [ xcffib.CurrentTime, atoms["_NET_SYSTEM_TRAY_S{:d}".format(self.screen)], win.wid, 0, 0, ] union = ClientMessageData.synthetic(data, "I" * 5) event = ClientMessageEvent.synthetic(format=32, window=qtile.core._root.wid, type=atoms["MANAGER"], data=union) qtile.core._root.send_event(event, mask=EventMask.StructureNotify) Systray._instances += 1
def create_window(self, x, y, width, height): wid = self.conn.generate_id() self.conn.core.CreateWindow( self.default_screen.root_depth, wid, self.default_screen.root.wid, x, y, width, height, 0, WindowClass.InputOutput, self.default_screen.root_visual, CW.BackPixel | CW.EventMask, [ self.default_screen.black_pixel, EventMask.StructureNotify | EventMask.Exposure ]) return window.XWindow(self, wid)
def __init__(self, conn, screen): _Wrapper.__init__(self, screen) self.default_colormap = Colormap(conn, screen.default_colormap) self.root = window.XWindow(conn, self.root) self._visuals = {} # Get visuals for 32 and 24 bit for d in [32, 24, self.root_depth]: if d not in self._visuals: visual = self.get_visual_for_depth(self, d) if visual: self._visuals[d] = visual
def handle_ConfigureRequest(self, event): # noqa: N802 # It's not managed, or not mapped, so we just obey it. cw = xcffib.xproto.ConfigWindow args = {} if event.value_mask & cw.X: args["x"] = max(event.x, 0) if event.value_mask & cw.Y: args["y"] = max(event.y, 0) if event.value_mask & cw.Height: args["height"] = max(event.height, 0) if event.value_mask & cw.Width: args["width"] = max(event.width, 0) if event.value_mask & cw.BorderWidth: args["borderwidth"] = max(event.border_width, 0) w = window.XWindow(self.conn, event.window) w.configure(**args)
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)
def __init__(self, conn, screen): _Wrapper.__init__(self, screen) self.default_colormap = Colormap(conn, screen.default_colormap) self.root = window.XWindow(conn, self.root)