My Qtile window manager configuration
git clone https://github.com/m-col/qtile-config
Files | Refs | Readme

-rw-r--r-- groups.py


      1 """
      2 Groups
      3 ======
      4 
      5  - 8 groups
      6  - 4 bound to each screen when using two monitors
      7 
      8 """
      9 
     10 from __future__ import annotations
     11 
     12 import os
     13 from typing import TYPE_CHECKING
     14 
     15 from libqtile import hook, qtile
     16 from libqtile.config import Group, Match
     17 from libqtile.lazy import lazy
     18 
     19 if TYPE_CHECKING:
     20     from typing import Any, Callable
     21 
     22     from libqtile.core.manager import Qtile
     23 
     24 
     25 mod = "mod1" if int(os.environ.get("QTILE_XEPHYR", 0)) else "mod4"
     26 
     27 keys_group: list[tuple[list[str], str, Any, str]] = []
     28 
     29 
     30 groups: list[Group] = [
     31     Group("1", label="html"),
     32     Group("2", label="disc", matches=[Match(wm_class="discord")]),
     33     Group("3", label="mail", matches=[Match(wm_class="evolution")]),
     34     Group("4", label="tune", matches=[
     35         Match(wm_class="dev.alextren.Spot"), Match(title="Spotify"),
     36     ]),
     37     Group("q", label="term"),
     38     Group("w", label="term"),
     39     Group("e", label="term"),
     40     Group("r", label="term"),
     41 ]
     42 
     43 
     44 def _go_to_group(qtile: Qtile, name: str) -> None:
     45     """
     46     This creates lazy functions that jump to a given group. When there is more than one
     47     screen, the first 4 and second 4 groups are kept on the first and second screen.
     48     E.g. going to the fifth group when the first group (and first screen) is focussed
     49     will also change the screen to the second screen.
     50     """
     51     if len(qtile.screens) == 1:
     52         qtile.groups_map[name].toscreen(toggle=True)
     53         return
     54 
     55     old = qtile.current_screen.group.name
     56     if name in "1234":
     57         qtile.focus_screen(0)
     58         if old in "1234" or qtile.current_screen.group.name != name:
     59             qtile.groups_map[name].toscreen(toggle=True)
     60     else:
     61         qtile.focus_screen(1)
     62         if old in "qwer" or qtile.current_screen.group.name != name:
     63             qtile.groups_map[name].toscreen(toggle=True)
     64 
     65 
     66 for i in groups:
     67     keys_group.extend(
     68         [
     69             (
     70                 [mod],
     71                 i.name,
     72                 lazy.function(_go_to_group, i.name),
     73                 f"Go to group {i.name}",
     74             ),
     75             (
     76                 [mod, "shift"],
     77                 i.name,
     78                 lazy.window.togroup(i.name),
     79                 f"Send window to group {i.name}",
     80             ),
     81         ]
     82     )
     83 
     84 
     85 def _scroll_screen(qtile: Qtile, direction: int) -> None:
     86     """
     87     Scroll to the next/prev group of the subset allocated to a specific screen. This
     88     will rotate between e.g. 1->2->3->4->1 when the first screen is focussed.
     89     """
     90     if len(qtile.screens) == 1:
     91         current = qtile.groups.index(qtile.current_group)
     92         destination = (current + direction) % 8
     93         qtile.groups[destination].toscreen()
     94         return
     95 
     96     current = qtile.groups.index(qtile.current_group)
     97     if current < 4:
     98         destination = (current + direction) % 4
     99     else:
    100         destination = ((current - 4 + direction) % 4) + 4
    101     qtile.groups[destination].toscreen()
    102 
    103 
    104 keys_group.extend(
    105     [
    106         ([mod], "m", lazy.function(_scroll_screen, 1), "Screen groups forward"),
    107         ([mod], "n", lazy.function(_scroll_screen, -1), "Screen groups backward"),
    108     ]
    109 )
    110 
    111 
    112 @hook.subscribe.startup
    113 def _():
    114     # Set initial groups
    115     if len(qtile.screens) > 1:
    116         qtile.groups_map["1"].toscreen(0, toggle=False)
    117         qtile.groups_map["q"].toscreen(1, toggle=False)
    118         qtile.focus_screen(1)
    119 
    120 
    121 @hook.subscribe.screens_reconfigured
    122 def _():
    123     # Set groups to screens
    124     if len(qtile.screens) > 1:
    125         if qtile.screens[0].group.name not in "1234":
    126             qtile.groups_map["1"].toscreen(0, toggle=False)
    127         if qtile.screens[1].group.name in "1234":
    128             qtile.groups_map["q"].toscreen(1, toggle=False)
    129