This repository has no description
10 kB
250 lines
1import subprocess
2import threading
3import json
4import os
5from typing import Callable
6
7from libqtile import bar, layout, widget, extension, hook
8from libqtile.config import Click, Drag, Group, Key, Match, Screen, ScratchPad, DropDown
9from libqtile.lazy import lazy
10from libqtile.utils import guess_terminal
11from libqtile.command.client import InteractiveCommandClient
12from libqtile.core.manager import Qtile
13from libqtile.backend.wayland import InputConfig
14
15prompt = widget.Prompt()
16state_file = "/home/lass/.local/share/qtile/state"
17
18
19def dmenu(candidates: list[str], callback: Callable) -> None:
20 def thread() -> None:
21 dmenu = subprocess.Popen(["rofi", "-dmenu"], stdin=subprocess.PIPE, stdout=subprocess.PIPE)
22 output = dmenu.communicate(input=("\n".join(candidates)).encode())
23 callback(output[0].decode().rstrip())
24 threading.Thread(target=thread).start()
25
26@lazy.function
27def goto_workspace(qtile: Qtile) -> None:
28 def callback(name: str) -> None:
29 c=InteractiveCommandClient()
30 c.group[name].toscreen()
31 dmenu(candidates=qtile.items("group")[1], callback=callback)
32
33@lazy.function
34def moveto_workspace(qtile: Qtile) -> None:
35 def callback(name: str) -> None:
36 c=InteractiveCommandClient()
37 c.window.togroup(name)
38 dmenu(candidates=qtile.items("group")[1], callback=callback)
39
40@lazy.function
41def add_group(qtile: Qtile) -> None:
42 def callback(name: str) -> None:
43 qtile.addgroup(name)
44 prompt.start_input("Add group: ", callback=callback)
45
46@lazy.function
47def del_group(qtile: Qtile) -> None:
48 qtile.delgroup(qtile.current_group.name)
49
50@lazy.function
51def reload_config(qtile: Qtile) -> None:
52 with open(state_file, "w") as f:
53 f.write(json.dumps(qtile.get_groups(), default=tuple))
54 qtile.reload_config()
55
56mod = "mod4"
57terminal = guess_terminal()
58
59if os.path.exists(state_file):
60 with open(state_file, "r") as f:
61 state = json.loads(f.read())
62 groups = [Group(name) for name, _ in state.items()]
63else:
64 groups = [
65 Group("dashboard"),
66 Group("ff"),
67 ]
68
69keys = [
70 # A list of available commands that can be bound to keys can be found
71 # at https://docs.qtile.org/en/latest/manual/config/lazy.html
72 # Switch between windows
73 Key([mod], "Tab", lazy.layout.next(), desc="Move window focus to other window"),
74 Key([mod, "shift"], "Tab", lazy.layout.previous(), desc="Move window focus to other window"),
75
76 Key([mod], "Escape", lazy.screen.toggle_group(), desc="Switch to last active group"),
77 # Move windows between left/right columns or move up/down in current stack.
78 # Moving out of range in Columns layout will create new column.
79 Key([mod, "shift"], "a", add_group, desc="add group"),
80 Key([mod, "shift"], "backspace", del_group, desc="delete group"),
81 Key([mod, "shift"], "h", lazy.layout.shuffle_left(), desc="Move window to the left"),
82 Key([mod, "shift"], "l", lazy.layout.shuffle_right(), desc="Move window to the right"),
83 Key([mod, "shift"], "j", lazy.layout.shuffle_down(), desc="Move window down"),
84 Key([mod, "shift"], "k", lazy.layout.shuffle_up(), desc="Move window up"),
85 # Grow windows. If current window is on the edge of screen and direction
86 # will be to screen edge - window would shrink.
87 Key([mod, "control"], "h", lazy.layout.grow_left(), desc="Grow window to the left"),
88 Key([mod, "control"], "l", lazy.layout.grow_right(), desc="Grow window to the right"),
89 Key([mod, "control"], "j", lazy.layout.grow_down(), desc="Grow window down"),
90 Key([mod, "control"], "k", lazy.layout.grow_up(), desc="Grow window up"),
91 Key([mod], "f", lazy.window.toggle_fullscreen(), desc="Toggle fullscreen",),
92 Key([mod], "n", lazy.layout.normalize(), desc="Reset all window sizes"),
93 Key([mod], "d", lazy.spawn("copyq show")),
94 Key([mod, "shift"], "Return", lazy.spawn(terminal), desc="Launch terminal"),
95 # Toggle between different layouts as defined below
96 Key([mod], "Space", lazy.next_layout(), desc="Toggle between layouts"),
97 Key([mod, "shift"], "c", lazy.window.kill(), desc="Kill focused window"),
98 Key([mod], "F11", lazy.spawn("swaylock --image /var/lib/wallpaper/wallpaper")),
99 Key([mod], "t", lazy.window.toggle_floating(), desc="Toggle floating on the focused window"),
100 Key([mod, "shift"], "r", reload_config, desc="Reload the config"),
101 Key([mod, "control"], "q", lazy.shutdown(), desc="Shutdown Qtile"),
102 Key([mod], "r", lazy.spawncmd(), desc="Spawn a command using a prompt widget"),
103 Key([mod], "F1", lazy.group["scratchpad"].dropdown_toggle("term")),
104 Key([mod], "p", lazy.spawn("pass_menu")),
105 Key([mod, "shift"], "p", lazy.spawn("otpmenu")),
106 Key([mod], "v", goto_workspace, desc="Switch to group"),
107 Key([mod, "shift"], "v", moveto_workspace, desc="move window to group"),
108 Key([], "XF86AudioRaiseVolume", lazy.spawn("pactl set-sink-volume @DEFAULT_SINK@ +5%")),
109 Key([], "XF86AudioLowerVolume", lazy.spawn("pactl set-sink-volume @DEFAULT_SINK@ -5%")),
110 Key([], "XF86MonBrightnessUp", lazy.spawn("xbacklight -inc 10")),
111 Key([], "XF86MonBrightnessDown", lazy.spawn("xbacklight -dec 10")),
112
113 Key(["control", "mod1"], "F1", lazy.core.change_vt(1), desc="Switch to VT 1"),
114 Key(["control", "mod1"], "F2", lazy.core.change_vt(2), desc="Switch to VT 2"),
115 Key(["control", "mod1"], "F3", lazy.core.change_vt(3), desc="Switch to VT 3"),
116 Key(["control", "mod1"], "F4", lazy.core.change_vt(4), desc="Switch to VT 4"),
117 Key(["control", "mod1"], "F5", lazy.core.change_vt(5), desc="Switch to VT 5"),
118 Key(["control", "mod1"], "F6", lazy.core.change_vt(6), desc="Switch to VT 6"),
119]
120
121layouts = [
122 layout.Max(),
123 layout.Columns(border_focus_stack=["#d75f5f", "#8f3d3d"], border_width=4),
124 # Try more layouts by unleashing below layouts.
125 # layout.Stack(num_stacks=2),
126 # layout.Bsp(),
127 layout.Matrix(),
128 # layout.MonadTall(),
129 # layout.MonadWide(),
130 # layout.RatioTile(),
131 # layout.Tile(),
132 # layout.TreeTab(),
133 # layout.VerticalTile(),
134 # layout.Zoomy(),
135]
136
137widget_defaults = dict(
138 font="sans",
139 fontsize=12,
140 padding=3,
141)
142extension_defaults = widget_defaults.copy()
143
144screens = [
145 Screen(
146 bottom=bar.Bar(
147 [
148 widget.CurrentLayout(),
149 widget.GenPollUrl(
150 url="http://radio.r:8002/current",
151 parse=lambda r: "/".join(r["filename"].split("/")[-2:]),
152 update_interval=15,
153 ),
154 widget.Spacer(),
155 widget.Wlan(interface="wlp170s0"),
156 widget.HDDBusyGraph(device="nvme0n1", graph_color="#4fbe4f"),
157 widget.MemoryGraph(graph_color="#eed563"),
158 widget.CPUGraph(graph_color="#8575bf"),
159 widget.ThermalZone(zone="/sys/class/thermal/thermal_zone1/temp", background="#440000"),
160 widget.PulseVolume(background="#009900"),
161 widget.Backlight(background="#b18f00", backlight_name="intel_backlight"),
162 widget.Battery(background="#e52383"),
163 widget.Clock(format="%Y-%m-%d %a %H:%M"),
164 # NB Systray is incompatible with Wayland, consider using StatusNotifier instead
165 widget.StatusNotifier(),
166 ],
167 24,
168 # border_width=[2, 0, 2, 0], # Draw top and bottom borders
169 # border_color=["ff00ff", "000000", "ff00ff", "000000"] # Borders are magenta
170 ),
171 top=bar.Bar(
172 [
173 widget.GroupBox(),
174 prompt,
175 widget.WindowName(),
176 widget.Chord(
177 chords_colors={
178 "launch": ("#ff0000", "#ffffff"),
179 },
180 name_transform=lambda name: name.upper(),
181 ),
182 ],
183 24,
184 ),
185 # You can uncomment this variable if you see that on X11 floating resize/moving is laggy
186 # By default we handle these events delayed to already improve performance, however your system might still be struggling
187 # This variable is set to None (no cap) by default, but you can set it to 60 to indicate that you limit it to 60 events per second
188 # x11_drag_polling_rate = 60,
189 ),
190]
191
192# Drag floating layouts.
193mouse = [
194 Drag([mod], "Button1", lazy.window.set_position_floating(), start=lazy.window.get_position()),
195 Drag([mod], "Button3", lazy.window.set_size_floating(), start=lazy.window.get_size()),
196 Click([mod], "Button2", lazy.window.bring_to_front()),
197]
198
199dgroups_key_binder = None
200dgroups_app_rules = [] # type: list
201follow_mouse_focus = True
202bring_front_click = False
203floats_kept_above = True
204cursor_warp = False
205floating_layout = layout.Floating(
206 float_rules=[
207 # Run the utility of `xprop` to see the wm class and name of an X client.
208 *layout.Floating.default_float_rules,
209 Match(wm_class="confirmreset"), # gitk
210 Match(wm_class="makebranch"), # gitk
211 Match(wm_class="maketag"), # gitk
212 Match(wm_class="ssh-askpass"), # ssh-askpass
213 Match(title="branchdialog"), # gitk
214 Match(title="pinentry"), # GPG key password entry
215 ]
216)
217auto_fullscreen = True
218focus_on_window_activation = "smart"
219reconfigure_screens = True
220
221# If things like steam games want to auto-minimize themselves when losing
222# focus, should we respect this or not?
223auto_minimize = True
224
225# When using the Wayland backend, this can be used to configure input devices.
226wl_input_rules = {
227 "type:keyboard": InputConfig(kb_options="ctrl:nocaps", kb_layout="us", kb_variant="altgr-intl"),
228}
229
230@hook.subscribe.startup
231def autostart():
232 subprocess.run(
233 [
234 "systemctl",
235 "--user",
236 "import-environment",
237 "XDG_SESSION_PATH",
238 "WAYLAND_DISPLAY",
239 ]
240 )
241
242# XXX: Gasp! We're lying here. In fact, nobody really uses or cares about this
243# string besides java UI toolkits; you can see several discussions on the
244# mailing lists, GitHub issues, and other WM documentation that suggest setting
245# this string if your java app doesn't work correctly. We may as well just lie
246# and say that we're a working one by default.
247#
248# We choose LG3D to maximize irony: it is a 3D non-reparenting WM written in
249# java that happens to be on java's whitelist.
250wmname = "LG3D"