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

Commit 90418e315fe36422489aaa09049fc7ee16baca4d
Parent: 4957dd312ee19f7097988154dbd556f6d1244031
Author: mcol <mcol@posteo.net>
Date: 2022-05-28 15:21:40 +0100
Committer: mcol <mcol@posteo.net>
Committed: 2022-05-28 15:21:40 +0100

many updates

wayland.py Modified

@@ -6,8 +6,10 @@
 import os
 import subprocess
 
-from libqtile import hook, qtile, backend
-
+from libqtile import hook, qtile
+from libqtile.backend import base
+from libqtile.backend.wayland import InputConfig
+from libqtile.backend.wayland.window import XdgWindow, XWindow
 from libqtile.lazy import lazy
 from libqtile.log_utils import logger
 
@@ -28,34 +30,33 @@
     ]
 )
 
-
-# Configure input devices
-try:
-    from libqtile.backend.wayland import InputConfig
-
-    wl_input_rules = {
-        "type:keyboard": InputConfig(
-            kb_options="caps:swapescape,altwin:swap_alt_win",
-            kb_layout="gb",
-            kb_repeat_rate=35,
-            kb_repeat_delay=250,
-        ),
-        "1267:12377:ELAN1300:00 04F3:3059 Touchpad": InputConfig(
-            drag=True, tap=True, dwt=False, pointer_accel=0.3
-        ),
-        "type:pointer": InputConfig(pointer_accel=-0.9),
-    }
-except ImportError:
-    wl_input_rules = None
+# Inputs configuration
+wl_input_rules = {
+    "type:keyboard": InputConfig(
+        kb_options="caps:swapescape,altwin:swap_alt_win",
+        kb_layout="gb",
+        kb_repeat_rate=35,
+        kb_repeat_delay=250,
+    ),
+    "1267:12377:ELAN1300:00 04F3:3059 Touchpad": InputConfig(
+        drag=True, tap=True, dwt=False, pointer_accel=0.3
+    ),
+    "type:pointer": InputConfig(pointer_accel=-0.9),
+}
 
 
 @hook.subscribe.client_new
 def _(win):
     # Auto-float some windows
-    if isinstance(win, base.Window):
-        state = win.surface.toplevel._ptr.current
-        if 0 < state.max_width < 1920:
+    if isinstance(win, XdgWindow):
+        max_width = win.surface.toplevel._ptr.current.max_width
+        if 0 < max_width < 1920:
             win.floating = True
+    elif isinstance(win, XWindow):
+        if hints := win.surface.size_hints:
+            max_width = hints.max_width
+            if 0 < max_width < 1920:
+                win.floating = True
 
 
 @hook.subscribe.client_managed

startup.sh Modified

@@ -8,7 +8,6 @@
 {
     foot --server &
     #swaybg -c '#1B2021' &
-    xsetroot -cursor_name left_ptr
 
     # wob
     FIFO=/tmp/wob-$WAYLAND_DISPLAY
@@ -27,11 +26,14 @@
     kanshi &
     wlsunset -t 2500 -T 5700 -l 55.7 -L -3.1 &
     run_if_new firefox &
-    run_if_new irc &
+    #run_if_new irc &
     systemctl --user import-environment WAYLAND_DISPLAY XDG_CURRENT_DESKTOP
     swayidle &
-    sleep 3
+    mpDris2 &
+    sway-mpris-idle-inhibit &
+    playerctld daemon
     check_systemd
+    run_if_new geary &
 } &> /dev/null
 
 

scratchpad.py Modified

@@ -34,12 +34,16 @@
     "opacity": 1,
 }
 
+GHCI = "ghci"
+# GHCI = "ghci-9.2.2"
+
 dropdowns = [
     DropDown("tmux", term + "tmux", height=0.4, **conf),
     DropDown(
         "ncmpcpp", term + "ncmpcpp", x=0.12, y=0.2, width=0.56, height=0.7, **conf
     ),
     DropDown("python", term + "python", x=0.05, y=0.1, width=0.2, height=0.3, **conf),
+    DropDown(GHCI, term + GHCI, y=0.6, height=0.4, **conf),
 ]
 
 
@@ -63,6 +67,12 @@
         lazy.group["scratchpad"].dropdown_toggle("python"),
         "Toggle python scratchpad",
     ),
+    (
+        [mod],
+        "g",
+        lazy.group["scratchpad"].dropdown_toggle(GHCI),
+        "Toggle GHCI scratchpad",
+    ),
 ]
 
 scratchpad = ScratchPad("scratchpad", dropdowns)

power_menu.py Modified

@@ -50,7 +50,7 @@
         width=1000,
         height=200,
         controls=controls,
-        background="00000060",
+        background="000000c0",
         initial_focus=2,
     ).show(centered=True)
 

groups.py Modified

@@ -2,8 +2,8 @@
 Groups
 ======
 
- - 6 groups
- - 3 bound to each screen when using two monitors
+ - 8 groups
+ - 4 bound to each screen when using two monitors
 
 """
 
@@ -17,31 +17,33 @@
 from libqtile.lazy import lazy
 
 if TYPE_CHECKING:
-    from typing import Any, Callable, List, Tuple
+    from typing import Any, Callable
 
     from libqtile.core.manager import Qtile
 
 
 mod = "mod1" if int(os.environ.get("QTILE_XEPHYR", 0)) else "mod4"
 
-keys_group: Tuple[List[str], str, Any, str] = []
+keys_group: tuple[list[str], str, Any, str] = []
 
 
-groups: List[Group] = [
+groups: list[Group] = [
     Group("1", label="term"),
     Group("2", label="term"),
     Group("3", label="term"),
+    Group("4", label="term"),
     Group("q", label="surf", matches=[Match(wm_class="firefox")]),
     Group("w", label="mail", matches=[Match(wm_class="geary"), Match(title="Geary")]),
-    Group("e", label="chat", matches=[Match(title="irc")]),
+    Group("e", label="work"),
+    Group("r", label="chat", matches=[Match(title="irc")]),
 ]
 
 
 def _go_to_group(name: str) -> Callable:
     """
     This creates lazy functions that jump to a given group. When there is more than one
-    screen, the first 3 and second 3 groups are kept on the first and second screen.
-    E.g. going to the fourth group when the first group (and first screen) is focussed
+    screen, the first 4 and second 4 groups are kept on the first and second screen.
+    E.g. going to the fifth group when the first group (and first screen) is focussed
     will also change the screen to the second screen.
     """
 
@@ -51,13 +53,13 @@
             return
 
         old = qtile.current_screen.group.name
-        if name in "123":
+        if name in "1234":
             qtile.focus_screen(0)
-            if old in "123" or qtile.current_screen.group.name != name:
+            if old in "1234" or qtile.current_screen.group.name != name:
                 qtile.groups_map[name].cmd_toscreen(toggle=True)
         else:
             qtile.focus_screen(1)
-            if old in "qwe" or qtile.current_screen.group.name != name:
+            if old in "qwer" or qtile.current_screen.group.name != name:
                 qtile.groups_map[name].cmd_toscreen(toggle=True)
 
     return _inner
@@ -85,21 +87,21 @@
 def _scroll_screen(direction: int) -> Callable:
     """
     Scroll to the next/prev group of the subset allocated to a specific screen. This
-    will rotate between e.g. 1->2->3->1 when the first screen is focussed.
+    will rotate between e.g. 1->2->3->4->1 when the first screen is focussed.
     """
 
     def _inner(qtile: Qtile):
         if len(qtile.screens) == 1:
             current = qtile.groups.index(qtile.current_group)
-            destination = (current + direction) % 6
+            destination = (current + direction) % 8
             qtile.groups[destination].cmd_toscreen()
             return
 
         current = qtile.groups.index(qtile.current_group)
-        if current < 3:
-            destination = (current + direction) % 3
+        if current < 4:
+            destination = (current + direction) % 4
         else:
-            destination = ((current - 3 + direction) % 3) + 3
+            destination = ((current - 4 + direction) % 4) + 4
         qtile.groups[destination].cmd_toscreen()
 
     return _inner
@@ -125,6 +127,6 @@
 def _(_):
     # Set groups to screens
     if len(qtile.screens) > 1:
-        if qtile.screens[0].group.name not in "123":
+        if qtile.screens[0].group.name not in "1234":
             qtile.groups_map["1"].cmd_toscreen(0, toggle=False)
         qtile.groups_map["q"].cmd_toscreen(1, toggle=False)

config.py Modified

@@ -82,8 +82,6 @@
 colours = [theme[f"color{n}"] for n in range(16)]
 background = theme["background"]
 foreground = theme["foreground"]
-bw = 6
-cw = 5
 colour_focussed = "#6fa3e0"
 colour_unfocussed = "#0e101c"
 inner_gaps = 8
@@ -108,8 +106,8 @@
 my_keys.extend(keys_scratchpad)
 my_keys.extend(keys_power_menu)
 
-reload("fullscreen_state")
-from fullscreen_state import toggle_fullscreen_state
+# reload("fullscreen_state")
+# from fullscreen_state import toggle_fullscreen_state
 
 
 def float_to_front(qtile: Qtile) -> None:
@@ -124,7 +122,7 @@
         # Window management
         ([mod, "control"], "q", lazy.window.kill(), "Close window"),
         ([mod], "f", lazy.window.toggle_fullscreen(), "Toggle fullscreen"),
-        ([mod], "g", lazy.function(toggle_fullscreen_state), "Toggle fullscreen state"),
+        # ([mod], "g", lazy.function(toggle_fullscreen_state), "Toggle fullscreen state"),
         ([mod, "shift"], "space", lazy.window.toggle_floating(), "Toggle floating"),
         (
             [mod],
@@ -144,9 +142,9 @@
         ([mod, alt], "k", lazy.layout.grow_up(), "Grow up"),
         ([mod, alt], "h", lazy.layout.grow_left(), "Grow left"),
         ([mod, alt], "l", lazy.layout.grow_right(), "Grow right"),
-        ([mod, "shift"], "r", lazy.reload_config(), "Reload the config"),
-        ([mod, "control"], "r", lazy.restart(), "Restart Qtile"),
+        ([mod, "control"], "r", lazy.reload_config(), "Reload the config"),
         ([mod, "control"], "Escape", lazy.shutdown(), "Shutdown Qtile"),
+        ([mod], "Tab", lazy.next_layout(), "Next layout"),
         ([mod], "b", lazy.hide_show_bar("bottom"), "Hide bar"),
         # Volume control - MyVolume widget is defined further down
         ([], "XF86AudioMute", lazy.widget["myvolume"].mute(), "Mute audio"),
@@ -194,16 +192,16 @@
         (
             [mod],
             "bracketright",
-            lazy.widget["mpd2"].function(lambda w: w.button_press(0, 0, 5)),
+            lazy.spawn("playerctl next"),
             "Next song",
         ),
         (
             [mod],
             "bracketleft",
-            lazy.widget["mpd2"].function(lambda w: w.button_press(0, 0, 4)),
+            lazy.spawn("playerctl previous"),
             "Previous song",
         ),
-        ([], "Pause", lazy.spawn("mpc toggle"), "Play/unpause music"),
+        ([], "Pause", lazy.spawn("playerctl play-pause"), "Play/unpause music"),
         # Launchers
         ([mod], "d", lazy.spawn("rofi -show run"), "Spawn with rofi"),
         ([mod], "Return", lazy.spawn(term), "Spawn terminal"),
@@ -256,15 +254,19 @@
         wrap_focus_rows=False,
         margin=0,
         margin_on_single=4,
-        corner_radius=cw,
     ),
+    # layout.Stack(
+    #    border_width=5,
+    #    border_focus=border_focus,
+    #    border_normal="00000000",
+    #    margin=0,
+    # ),
 ]
 
 floating_layout = layout.Floating(
     border_width=3,
     border_focus=border_focus,
     border_normal="00000000",
-    corner_radius=cw,
     fullscreen_border_width=0,
     float_rules=[
         Match(title="Open File"),
@@ -273,6 +275,7 @@
         Match(wm_class="thunar"),
         Match(title="Firefox — Sharing Indicator"),
         Match(wm_class="Arandr"),
+        Match(wm_class="eog"),
         Match(wm_class="org.gnome.clocks"),
         Match(wm_class="org.kde.ark"),
         Match(wm_class="confirm"),
@@ -283,6 +286,7 @@
         Match(wm_class="file_progress"),
         Match(wm_class="imv"),
         Match(wm_class="lxappearance"),
+        Match(wm_class="matplotlib"),
         Match(wm_class="mpv"),
         Match(wm_class="notification"),
         Match(wm_class="pavucontrol"),
@@ -293,6 +297,7 @@
         Match(wm_class="Dragon-drag-and-drop"),
         Match(wm_class="toolbar"),
         Match(wm_class="wlroots"),
+        Match(wm_class="wdisplays"),
         Match(wm_class="Xephyr"),
         Match(wm_type="dialog"),
         Match(role="gimp-file-export"),
@@ -323,14 +328,24 @@
     "fontsize": 12,
 }
 
-mpd2 = widget.Mpd2(
-    no_connection="",
-    status_format="mpd here" if IS_XEPHYR else "{artist} - {title}",
-    status_format_stopped="",
+# mpd2 = widget.Mpd2(
+#    no_connection="",
+#    status_format="{artist} - {title}",
+#    status_format_stopped="",
+#    foreground=colours[12],
+#    idle_format="",
+#    font="TamzenForPowerline Bold",
+#    update_interval=10,
+#    scroll=True,
+# )
+
+mpd2 = widget.Mpris2(
+    name="mpris",
+    objname=None,
+    display_metadata=["xesam:title", "xesam:artist"],
     foreground=colours[12],
-    idle_format="",
     font="TamzenForPowerline Bold",
-    update_interval=10,
+    scroll_interval=0,
 )
 
 
@@ -476,17 +491,19 @@
     font="TamzenForPowerline Bold",
     foreground=colours[7],
     update_interval=60,
+    name="date",
 )
 
 time = widget.Clock(
     fontsize=20,
     font="TamzenForPowerline Medium",
     update_interval=60,
+    name="time",
 )
 
 groupboxes = [
-    widget.GroupBox(**groupbox_config, visible_groups=["1", "2", "3", "q", "w", "e"]),
-    widget.GroupBox(**groupbox_config, visible_groups=["q", "w", "e"]),
+    widget.GroupBox(**groupbox_config),
+    widget.GroupBox(**groupbox_config, visible_groups=["q", "w", "e", "r"]),
 ]
 
 
@@ -494,18 +511,18 @@
 def _():
     # Set up initial GroupBox visible groups
     if len(qtile.screens) > 1:
-        groupboxes[0].visible_groups = ["1", "2", "3"]
+        groupboxes[0].visible_groups = ["1", "2", "3", "4"]
     else:
-        groupboxes[0].visible_groups = ["1", "2", "3", "q", "w", "e"]
+        groupboxes[0].visible_groups = None
 
 
 @hook.subscribe.screens_reconfigured
 def _():
     # Reconfigure GroupBox visible groups
     if len(qtile.screens) > 1:
-        groupboxes[0].visible_groups = ["1", "2", "3"]
+        groupboxes[0].visible_groups = ["1", "2", "3", "4"]
     else:
-        groupboxes[0].visible_groups = ["1", "2", "3", "q", "w", "e"]
+        groupboxes[0].visible_groups = None
     if hasattr(groupboxes[0], "bar"):
         groupboxes[0].bar.draw()
 
@@ -518,9 +535,9 @@
         bottom=bar.Bar(
             [
                 groupboxes[0],
-                widget.Spacer(),
+                widget.Spacer(name="s1"),
                 mpd2,
-                widget.Spacer(),
+                widget.Spacer(name="s2"),
                 systray,
                 volume,
                 bklight,
@@ -542,9 +559,9 @@
         bottom=bar.Bar(
             [
                 groupboxes[1],
-                widget.Spacer(),
+                widget.Spacer(name="s3"),
                 mpd2,
-                widget.Spacer(),
+                widget.Spacer(name="s4"),
                 volume,
                 bklight,
                 wlan,