Exemple #1
0
    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
Exemple #2
0
    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)
Exemple #3
0
    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)
Exemple #4
0
    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()
Exemple #5
0
    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
Exemple #6
0
 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)
Exemple #7
0
    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
Exemple #8
0
 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)
Exemple #9
0
    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)
Exemple #10
0
 def __init__(self, conn, screen):
     _Wrapper.__init__(self, screen)
     self.default_colormap = Colormap(conn, screen.default_colormap)
     self.root = window.XWindow(conn, self.root)