Пример #1
0
 def cmd_ungrab_all_chords(self) -> None:
     """Leave all chord modes and grab the root bindings"""
     hook.fire("leave_chord")
     self.ungrab_keys()
     self.chord_stack.clear()
     for key in self.config.keys:
         self.grab_key(key)
Пример #2
0
    def _reconfigure_floating(self, new_float_state=FLOATING):
        if new_float_state == MINIMIZED:
            self.state = IconicState
            self.hide()
        else:
            width = max(self.width, self.hints.get('min_width', 0))
            height = max(self.height, self.hints.get('min_height', 0))

            if self.hints['base_width'] and self.hints['width_inc']:
                width_adjustment = (width - self.hints['base_width']) % self.hints['width_inc']
                width -= width_adjustment
                if new_float_state == FULLSCREEN:
                    self.x += int(width_adjustment / 2)

            if self.hints['base_height'] and self.hints['height_inc']:
                height_adjustment = (height - self.hints['base_height']) % self.hints['height_inc']
                height -= height_adjustment
                if new_float_state == FULLSCREEN:
                    self.y += int(height_adjustment / 2)

            self.place(
                self.x, self.y,
                width, height,
                self.borderwidth,
                self.bordercolor,
                above=True,
            )
        if self._float_state != new_float_state:
            self._float_state = new_float_state
            if self.group:  # may be not, if it's called from hook
                self.group.mark_floating(self, True)
            hook.fire('float_change')
Пример #3
0
    def update_hints(self):
        """Update the local copy of the window's WM_HINTS

        See http://tronche.com/gui/x/icccm/sec-4.html#WM_HINTS
        """
        try:
            h = self.window.get_wm_hints()
            normh = self.window.get_wm_normal_hints()
        except (xcffib.xproto.WindowError, xcffib.xproto.AccessError):
            return

        if normh:
            self.hints.update(normh)

        if h and 'UrgencyHint' in h['flags']:
            if self.qtile.current_window != self:
                self.hints['urgent'] = True
                hook.fire('client_urgent_hint_changed', self)
        elif self.urgent:
            self.hints['urgent'] = False
            hook.fire('client_urgent_hint_changed', self)

        if h and 'InputHint' in h['flags']:
            self.hints['input'] = h['input']

        if getattr(self, 'group', None):
            self.group.layout_all()

        return
Пример #4
0
 def _on_set_title(self, _listener, _data):
     logger.debug("Signal: xwindow set_title")
     title = self.surface.title
     if title != self.name:
         self.name = title
         self.ftm_handle.set_title(title)
         hook.fire("client_name_updated", self)
Пример #5
0
    def update_wm_net_icon(self):
        """Set a dict with the icons of the window"""

        icon = self.window.get_property('_NET_WM_ICON', 'CARDINAL')
        if not icon:
            return
        icon = list(map(ord, icon.value))

        icons = {}
        while True:
            if not icon:
                break
            size = icon[:8]
            if len(size) != 8 or not size[0] or not size[4]:
                break

            icon = icon[8:]

            width = size[0]
            height = size[4]

            next_pix = width * height * 4
            data = icon[:next_pix]

            arr = array.array("B", data)
            for i in range(0, len(arr), 4):
                mult = arr[i + 3] / 255.
                arr[i + 0] = int(arr[i + 0] * mult)
                arr[i + 1] = int(arr[i + 1] * mult)
                arr[i + 2] = int(arr[i + 2] * mult)
            icon = icon[next_pix:]
            icons["%sx%s" % (width, height)] = arr
        self.icons = icons
        hook.fire("net_wm_icon_change", self)
Пример #6
0
    def update_hints(self):
        """Update the local copy of the window's WM_HINTS

        See http://tronche.com/gui/x/icccm/sec-4.html#WM_HINTS
        """
        try:
            h = self.window.get_wm_hints()
            normh = self.window.get_wm_normal_hints()
        except (xcffib.xproto.WindowError, xcffib.xproto.AccessError):
            return

        # FIXME
        # h values
        # {
        #    'icon_pixmap': 4194337,
        #    'icon_window': 0,
        #    'icon_mask': 4194340,
        #    'icon_y': 0,
        #    'input': 1,
        #    'icon_x': 0,
        #    'window_group': 4194305
        #    'initial_state': 1,
        #    'flags': set(['StateHint',
        #                  'IconMaskHint',
        #                  'WindowGroupHint',
        #                  'InputHint',
        #                  'UrgencyHint',
        #                  'IconPixmapHint']),
        # }

        if normh:
            normh.pop('flags')
            normh['min_width'] = max(0, normh.get('min_width', 0))
            normh['min_height'] = max(0, normh.get('min_height', 0))
            if not normh['base_width'] and \
                    normh['min_width'] and \
                    normh['width_inc']:
                # seems xcffib does ignore base width :(
                normh['base_width'] = (normh['min_width'] % normh['width_inc'])
            if not normh['base_height'] and \
                    normh['min_height'] and \
                    normh['height_inc']:
                # seems xcffib does ignore base height :(
                normh['base_height'] = (normh['min_height'] %
                                        normh['height_inc'])
            self.hints.update(normh)

        if h and 'UrgencyHint' in h['flags']:
            if self.qtile.current_window != self:
                self.hints['urgent'] = True
                hook.fire('client_urgent_hint_changed', self)
        elif self.urgent:
            self.hints['urgent'] = False
            hook.fire('client_urgent_hint_changed', self)

        if getattr(self, 'group', None):
            self.group.layout_all()

        return
Пример #7
0
 def restart(self):
     hook.fire("restart")
     lifecycle.behavior = lifecycle.behavior.RESTART
     state_file = os.path.join(tempfile.gettempdir(), 'qtile-state')
     with open(state_file, 'wb') as f:
         self.dump_state(f)
     lifecycle.state_file = state_file
     self._stop()
Пример #8
0
 def handle_EnterNotify(self, e):  # noqa: N802
     hook.fire("client_mouse_enter", self)
     if self.qtile.config.follow_mouse_focus:
         if self.group.current_window != self:
             self.group.focus(self, False)
         if self.group.screen and self.qtile.current_screen != self.group.screen:
             self.qtile.focus_screen(self.group.screen.index, False)
     return True
Пример #9
0
    def grab_chord(self, chord) -> None:
        self.chord_stack.append(chord)
        if self.chord_stack:
            hook.fire("enter_chord", self.chord_stack[-1].mode)

        self.ungrab_keys()
        for key in chord.submappings:
            self.grab_key(key)
Пример #10
0
 def unmanage(self, win):
     c = self.windows_map.get(win)
     if c:
         hook.fire("client_killed", c)
         if isinstance(c, base.Static) and c.reserved_space:
             self.free_reserved_space(c.reserved_space, c.screen)
         if getattr(c, "group", None):
             c.group.remove(c)
         del self.windows_map[win]
         self.core.update_client_list(self.windows_map)
Пример #11
0
def test_can_unsubscribe_from_hook():
    test = Call(0)

    hook.subscribe.group_window_add(test)
    hook.fire("group_window_add", 3)
    assert test.val == 3

    hook.unsubscribe.group_window_add(test)
    hook.fire("group_window_add", 4)
    assert test.val == 3
Пример #12
0
    async def t():
        val = 0

        async def co(new_val):
            nonlocal val
            val = new_val

        hook.subscribe.group_window_add(co(8))
        hook.fire("group_window_add")
        await asyncio.sleep(0)
        assert val == 8
Пример #13
0
def test_hook_calls_subscriber_async_co():
    val = 0

    async def co(new_val):
        nonlocal val
        val = new_val

    hook.subscribe.group_window_add(co(8))
    hook.fire("group_window_add")

    assert val == 8
Пример #14
0
 def _reconfigure_floating(self, x, y, w, h, new_float_state=FloatStates.FLOATING):
     if new_float_state == FloatStates.MINIMIZED:
         self.hide()
     else:
         self.place(
             x, y, w, h, self.borderwidth, self.bordercolor, above=True, respect_hints=True
         )
     if self._float_state != new_float_state:
         self._float_state = new_float_state
         if self.group:  # may be not, if it's called from hook
             self.group.mark_floating(self, True)
         hook.fire("float_change")
Пример #15
0
 def _reconfigure_floating(self, x, y, w, h, new_float_state=FloatStates.FLOATING):
     if new_float_state == FloatStates.MINIMIZED:
         self.hide()
     else:
         # TODO: Can we get min/max size, resizing increments etc and respect them?
         self.place(
             x, y, w, h, self.borderwidth, self.bordercolor, above=True,
         )
     if self._float_state != new_float_state:
         self._float_state = new_float_state
         if self.group:  # may be not, if it's called from hook
             self.group.mark_floating(self, True)
         hook.fire('float_change')
Пример #16
0
    def focus(self, warp: bool) -> None:
        self.core.focus_window(self)
        if isinstance(self, base.Internal):
            # self.core.focus_window is enough for internal windows
            return

        if warp and self.qtile.config.cursor_warp:
            self.core.warp_pointer(
                self.x + self.width // 2,
                self.y + self.height // 2,
            )

        hook.fire("client_focus", self)
Пример #17
0
    def handle_PropertyNotify(self, event) -> None:  # noqa: N802
        name = self.conn.atoms.get_name(event.atom)
        # it's the selection property
        if name in ("PRIMARY", "CLIPBOARD"):
            assert event.window == self._selection_window.wid
            prop = self._selection_window.get_property(event.atom, "UTF8_STRING")

            # If the selection property is None, it is unset, which means the
            # clipboard is empty.
            value = prop and prop.value.to_utf8() or ""

            self._selection[name]["selection"] = value
            hook.fire("selection_change", name, self._selection[name])
Пример #18
0
 def focus_screen(self, n, warp=True):
     """Have Qtile move to screen and put focus there"""
     if n >= len(self.screens):
         return
     old = self.current_screen
     self.current_screen = self.screens[n]
     if old != self.current_screen:
         hook.fire("current_screen_change")
         hook.fire("setgroup")
         old.group.layout_all()
         self.current_group.focus(self.current_window, warp)
         if self.current_window is None and warp:
             self.warp_to_screen()
Пример #19
0
    def add_group(self, name, layout=None, layouts=None, label=None):
        if name not in self.groups_map.keys():
            g = _Group(name, layout, label=label)
            self.groups.append(g)
            if not layouts:
                layouts = self.config.layouts
            g._configure(layouts, self.config.floating_layout, self)
            self.groups_map[name] = g
            hook.fire("addgroup", name)
            hook.fire("changegroup")
            self.update_desktops()

            return True
        return False
Пример #20
0
 def add(self, win, focus=True, force=False):
     hook.fire("group_window_add", self, win)
     self.windows.add(win)
     win.group = self
     if self.qtile.config.auto_fullscreen and win.wants_to_fullscreen:
         win._float_state = FloatStates.FULLSCREEN
     elif self.floating_layout.match(win):
         win._float_state = FloatStates.FLOATING
     if win.floating:
         self.floating_layout.add(win)
     else:
         for i in self.layouts:
             i.add(win)
     if focus:
         self.focus(win, warp=True, force=force)
Пример #21
0
    def setGroup(self, new_group):
        """
        Put group on this screen
        """
        if new_group.screen == self:
            return

        if not new_group.screen is None:
            return

        self.previous_group = self.group

        if new_group is None:
            return

        if new_group.screen:
            # g1 <-> s1 (self)
            # g2 (new_group) <-> s2 to
            # g1 <-> s2
            # g2 <-> s1
            g1 = self.group
            s1 = self
            g2 = new_group
            s2 = new_group.screen

            s2.group = g1
            g1._setScreen(s2)
            s1.group = g2
            g2._setScreen(s1)
        else:
            old_group = self.group
            self.group = new_group

            # display clients of the new group and then hide from old group
            # to remove the screen flickering
            new_group._setScreen(self)

            if old_group is not None:
                old_group._setScreen(None)

        hook.fire("setgroup")
        hook.fire("focus_change")
        hook.fire(
            "layout_change",
            self.group.layouts[self.group.currentLayout],
            self.group
        )