first commit

This commit is contained in:
2026-02-23 17:56:46 +01:00
commit 9c29be09bf
72 changed files with 3106 additions and 0 deletions

0
modules/__init__.py Normal file
View File

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

161
modules/groups.py Normal file
View File

@@ -0,0 +1,161 @@
from libqtile.config import Group, Key, Match, DropDown, ScratchPad
from libqtile.lazy import lazy
from .keys import keys, mod
import re
group_screen_map = {
"0": 0,
"1": 0,
"2": 0,
"3": 0,
"4": 2,
"5": 2,
"6": 2,
"7": 1,
"8": 1,
"9": 1,
"f1": 2,
"f2": 1,
"f3": 2,
"f4": 1,
"f5": 1,
"f6": 1,
"f7": 2,
"f8": 0,
"f9": 0,
"f10": 0,
"f11": 0,
"f12": 0,
}
groups = [
Group(
name="0",
label="󰓓",
matches=[
Match(wm_class=re.compile(r"^(steam)")),
Match(wm_class=re.compile(r"^(Minecraft*)")),
],
),
Group(name="1", label="󰲡"),
Group(name="2", label="󰲣"),
Group(name="3", label="󰲥"),
Group(name="4", label="󰲧"),
Group(name="5", label="󰲩"),
Group(name="6", label="󰲫"),
Group(name="7", label="󰲭"),
Group(name="8", label="󰲯"),
Group(name="9", label="󰲱"),
# Groups on function-keys
Group(
name="f1",
label="",
matches=[Match(wm_class=re.compile(r"^(firefox)$"))],
),
Group(
name="f2",
label="",
matches=[
Match(wm_class="discord"),
Match(wm_class=re.compile(r"^(com.github.th_ch.youtube_music)$")),
Match(wm_class="RMPC"),
],
),
Group(
name="f3",
label="",
matches=[Match(wm_class=re.compile(r"^(joplin)$"))],
),
Group(
name="f4",
label="󱊮",
),
Group(
name="f5",
label="󰝶 ",
matches=[Match(wm_class="AFFiNE")],
),
Group(
name="f6",
label="󰟵 ",
matches=[Match(wm_class="bitwarden")],
),
Group(
name="f7",
label="󰣀 ",
matches=[Match(wm_class=re.compile(r"^(XPipe)$"))],
),
Group(name="f8", label="󱊲"),
Group(name="f9", label="󱊳"),
Group(name="f10", label="󱊴"),
Group(name="f11", label="󱊵"),
Group(name="f12", label="󱊶"),
]
def go_to_group(name: str):
def _inner(qtile):
screen = group_screen_map.get(name, 0)
if len(qtile.screens) <= 2:
qtile.groups_map[name].toscreen()
else:
qtile.focus_screen(screen)
qtile.groups_map[name].toscreen()
return _inner
for i in groups:
keys.append(Key([mod], i.name, lazy.function(go_to_group(i.name))))
def go_to_group_and_move_window(name: str):
def _inner(qtile):
screen = group_screen_map.get(name, 0)
if len(qtile.screens) <= 2:
qtile.current_window.togroup(name, switch_group=False)
else:
qtile.current_window.togroup(name, switch_group=False)
qtile.focus_screen(screen)
qtile.groups_map[name].toscreen()
return _inner
for i in groups:
keys.append(
Key([mod, "shift"], i.name, lazy.function(go_to_group_and_move_window(i.name)))
)
for i in range(1, 12):
group_name = f"f{i}"
key = f"F{i}"
keys.append
groups.append(
ScratchPad(
"scratchpad",
[
DropDown(
"term",
"kitty",
width=0.7,
height=0.9,
x=0.15,
y=0.05,
opacity=0.8,
on_focus_lost_hide=True,
),
DropDown(
"calc",
"qalculate-gtk",
width=0.3,
height=0.6,
x=0.35,
y=0.2,
opacity=1,
on_focus_lost_hide=False,
),
],
)
)

46
modules/hooks.py Normal file
View File

@@ -0,0 +1,46 @@
# _ _ _ _ _
# __ _| |_(_) | ___ | |__ ___ ___ | | _____
# / _` | __| | |/ _ \ | '_ \ / _ \ / _ \| |/ / __|
# | (_| | |_| | | __/ | | | | (_) | (_) | <\__ \
# \__, |\__|_|_|\___| |_| |_|\___/ \___/|_|\_\___/
# |_|
# by cerberus
# --------------------------------------------------------------------
# --------------------------------------------------------------------
# Imports
# --------------------------------------------------------------------
from libqtile import hook, qtile
import subprocess
import os.path
from libqtile.config import Match
# --------------------------------------------------------------------
# HOOK startup
# --------------------------------------------------------------------
# Client management
FULLSCREEN_RULES = [Match(wm_class="flameshot")]
@hook.subscribe.startup_once
def autostart():
autostartscript = "~/.config/qtile/res/scripts/autostart.sh"
home = os.path.expanduser(autostartscript)
subprocess.Popen([home])
@hook.subscribe.startup_complete
def go_to_group1():
qtile.focus_screen(0)
qtile.groups_map["1"].toscreen()
@hook.subscribe.client_managed
def force_fullscreen(client) -> None:
"""
Some clients won't start fullscreen (exclusive to wayland)
With this function we force clients defined in FULLSCREEN_RULES to enter fullscreen
"""
if any(client.match(rule) for rule in FULLSCREEN_RULES):
client.fullscreen = True

161
modules/keys.py Normal file
View File

@@ -0,0 +1,161 @@
# _ _ _ _
# __ _| |_(_) | ___ | | _____ _ _ ___
# / _` | __| | |/ _ \ | |/ / _ \ | | / __|
# | (_| | |_| | | __/ | < __/ |_| \__ \
# \__, |\__|_|_|\___| |_|\_\___|\__, |___/
# |_| |___/
# by cerberus
# --------------------------------------------------------------------
# --------------------------------------------------------------------
# Imports
# --------------------------------------------------------------------
from libqtile.config import Key, Drag, Click
from libqtile.lazy import lazy
# from screens import notifier
# --------------------------------------------------------------------
# Set default apps
# --------------------------------------------------------------------
terminal = "kitty"
browser = "firefox"
filemanager = "nemo"
# --------------------------------------------------------------------
# Keybindings
# --------------------------------------------------------------------
mod = "mod4" # SUPER KEY
alt = "mod1"
# KeybindStart
keys = [
# KB_GROUP-Focus Window
Key([mod], "h", lazy.layout.left(), desc="Move focus to left"),
Key([mod], "l", lazy.layout.right(), desc="Move focus to right"),
Key([mod], "j", lazy.layout.down(), desc="Move focus down"),
Key([mod], "k", lazy.layout.up(), desc="Move focus up"),
# KB_GROUP-Move Window
# Key([mod, "shift"], "h", lazy.layout.shuffle_left(), desc="Move window to the left"),
# Key([mod, "shift"], "l", lazy.layout.shuffle_right(), desc="Move window to the right"),
Key(
[mod, "shift"],
"h",
lazy.layout.swap_left(),
desc="Move window to the left - Monad",
),
Key(
[mod, "shift"],
"l",
lazy.layout.swap_right(),
desc="Move window to the left - Monad",
),
Key([mod, "shift"], "j", lazy.layout.shuffle_down(), desc="Move window down"),
Key([mod, "shift"], "k", lazy.layout.shuffle_up(), desc="Move window up"),
# KB_GROUP-Resize Window
Key([mod], "m", lazy.layout.shrink(), desc="Grow window to the top"),
Key([mod], "i", lazy.layout.grow(), desc="Grow window to the bottom"),
# KB_GROUP-Window Controls
Key([mod], "n", lazy.layout.normalize(), desc="Normalize all window sizes"),
Key([mod, "shift"], "n", lazy.layout.reset(), desc="Reset all window sizes"),
Key([mod], "t", lazy.window.toggle_floating(), desc="Toggle floating"),
Key([mod], "o", lazy.layout.maximize(), desc="Maximize window"),
Key(
[mod, "shift"],
"s",
lazy.layout.toggle_auto_maximize(),
desc="Toggle auto maximize",
),
Key([mod], "f", lazy.window.toggle_fullscreen(), desc="Toggle full screen"),
Key([mod, "shift"], "space", lazy.layout.flip(), desc="Flip windows"),
Key(
[mod, "shift"],
"Return",
lazy.layout.toggle_split(),
desc="Toggle between split and unsplit sides of stack",
),
# KB_GROUP-System Controls
Key([mod], "Tab", lazy.next_layout(), desc="Toggle between layouts"),
Key([mod], "c", lazy.window.kill(), desc="Kill focused window"),
Key([mod, "control"], "r", lazy.reload_config(), desc="Reload the config"),
# KB_GROUP-Audio and Media Control
Key([], "XF86AudioMute", lazy.spawn("pamixer -t"), desc="Mute Audio"),
Key([], "XF86AudioLowerVolume", lazy.spawn("pamixer -d 2"), desc="Lower Volume"),
Key([], "XF86AudioRaiseVolume", lazy.spawn("pamixer -i 2"), desc="Next Song"),
Key([], "XF86AudioPrev", lazy.spawn("playerctl previous"), desc="Previous Media"),
Key(
[], "XF86AudioPlay", lazy.spawn("playerctl play-pause"), desc="Play Pause Media"
),
Key([], "XF86AudioNext", lazy.spawn("playerctl next"), desc="Next Media"),
# MPD player
# NOTE: requires rmpc to be installed
Key(["control"], "XF86AudioPrev", lazy.spawn("rmpc prev"), desc="Previous Media"),
Key(
["control"],
"XF86AudioPlay",
lazy.spawn("rmpc togglepause"),
desc="Play Pause Media",
),
Key(["control"], "XF86AudioNext", lazy.spawn("rmpc next"), desc="Next Media"),
# KB_GROUP-Rofi Menus
Key([mod], "r", lazy.spawn("rofi -show drun -show-icons"), desc="Spawn Rofi D-Run"),
# KB_GROUP-ScratchPad
Key(
["control"],
"1",
lazy.group["scratchpad"].dropdown_toggle("term"),
desc="PopUp Terminal",
),
Key(
["control"],
"2",
lazy.group["scratchpad"].dropdown_toggle("calc"),
desc="Calculator",
),
# KB_GROUP-Programs
Key([mod], "Return", lazy.spawn(terminal), desc="Launch terminal"),
Key([mod], "v", lazy.spawn("copyq toggle"), desc="Shows Clipboard"),
Key([mod, "shift"], "q", lazy.spawn("flameshot gui"), desc="Screenshot selection"),
Key(
[mod, "shift"], "b", lazy.spawn(browser), desc="Opens Browser on current screen"
),
Key(
[mod, "shift"],
"p",
lazy.spawn("firefox --private-window"),
desc="Opens Private Browser on current screen",
),
Key([mod, "shift"], "e", lazy.spawn(filemanager), desc="Opens File Manager"),
Key(
[mod, "control"],
"a",
lazy.spawn("python /home/cerberus/.config/qtile/res/scripts/autoclicker.py"),
desc="Autoclicker On",
),
Key(
[mod, "control"],
"s",
lazy.spawn("pkill -f autoclicker.py"),
desc="Autoclicker Off",
),
]
# --------------------------------------------------------------------
# Drag floating layouts
# --------------------------------------------------------------------
mouse = [
Drag(
[mod],
"Button1",
lazy.window.set_position_floating(),
start=lazy.window.get_position(),
),
Drag(
[mod], "Button3", lazy.window.set_size_floating(), start=lazy.window.get_size()
),
Click([mod], "Button2", lazy.window.bring_to_front()),
]

80
modules/layouts.py Normal file
View File

@@ -0,0 +1,80 @@
# _ _ _ _ _
# __ _| |_(_) | ___ | | __ _ _ _ ___ _ _| |_ ___
# / _` | __| | |/ _ \ | |/ _` | | | |/ _ \| | | | __/ __|
# | (_| | |_| | | __/ | | (_| | |_| | (_) | |_| | |_\__ \
# \__, |\__|_|_|\___| |_|\__,_|\__, |\___/ \__,_|\__|___/
# |_| |___/
# --------------------------------------------------------------------
# --------------------------------------------------------------------
# Imports
# --------------------------------------------------------------------
from libqtile import layout
from libqtile.config import Match
layout_defaults = dict(
margin=3,
border_width=0,
# border_focus=gruvbox_dark["red"],
# border_normal=gruvbox_dark["fg1"],
grow_amount=2,
)
floating_layout_defaults = layout_defaults.copy()
layouts = [
# layout.Max(**layout_defaults),
# layout.Plasma(),
# layout.Columns(),
# layout.Matrix(),
layout.MonadTall(
name="Monad",
auto_maximize=True,
change_ratio=0.05,
change_size=20,
ratio=0.55,
min_ratio=0.30,
max_ratio=0.75,
single_border_width=0,
**layout_defaults,
),
layout.Bsp(
name="bsp",
ratio=0.5,
lower_right=True,
**layout_defaults,
),
layout.Spiral(**layout_defaults),
# layout.Stack(num_stacks=2),
# layout.MonadWide(**layout_defaults),
# layout.RatioTile(**layout_defaults),
# layout.Tile(name="Tile", **layout_defaults),
# layout.TreeTab(**layout_defaults),
layout.VerticalTile(**layout_defaults),
# layout.Zoomy(**layout_defaults),
]
floating_layout = layout.Floating(
float_rules=[
# Run the utility of `xprop` to see the wm class and name of an X client.
*layout.Floating.default_float_rules,
Match(wm_class="confirmreset"), # gitk
Match(wm_class="makebranch"), # gitk
Match(wm_class="maketag"), # gitk
Match(wm_class="ssh-askpass"), # ssh-askpass
Match(wm_class="nm-connection-editor"), # networkmanager
Match(title="branchdialog"), # gitk
Match(title="pinentry"), # GPG key password entry
Match(title="FloatWindow"),
Match(wm_class="qalculate-qt"),
Match(wm_class="copyq"),
Match(wm_class="nitrogen"),
Match(wm_class="nemo-preview-start"),
Match(wm_class="wireguird"),
Match(wm_class="blueman-manager"),
Match(wm_class="pavucontrol"),
Match(wm_class="org.gnome.FileRoller"),
Match(wm_class="lximage-qt"),
],
**floating_layout_defaults,
)

257
modules/screens.py Normal file
View File

@@ -0,0 +1,257 @@
# _ _ _
# __ _| |_(_) | ___ ___ ___ _ __ ___ ___ _ __ ___
# / _` | __| | |/ _ \ / __|/ __| '__/ _ \/ _ \ '_ \/ __|
# | (_| | |_| | | __/ \__ \ (__| | | __/ __/ | | \__ \
# \__, |\__|_|_|\___| |___/\___|_| \___|\___|_| |_|___/
# |_|
# --------------------------------------------------------------------
# Imports
# --------------------------------------------------------------------
from libqtile.config import Screen
from libqtile import bar
from libqtile.widget import mpd2widget
from libqtile.lazy import lazy
from qtile_extras import widget
from qtile_extras.widget.groupbox2 import GroupBoxRule
# from plugins.notifications import Notifier
from plugins.graphical_notifications import Notifier
from popups.powermenu import power_menu
from popups.start_menu import start_menu
from popups.calendar import calendar
from popups.mpris2_layout import MPRIS2_LAYOUT
from popups.volume_notification import VOL_POPUP
from res.themes.colors import gruvbox_dark
# --------------------------------------------------------
# GroupBox2 rules
# --------------------------------------------------------
def get_groupbox_rules(monitor_specific=True):
# Base rules applied to all GroupBoxes
rules = [
GroupBoxRule(text_colour=gruvbox_dark["bg3"]).when(
focused=False, occupied=True
),
GroupBoxRule(text_colour=gruvbox_dark["aqua"]).when(
focused=False, occupied=False
),
GroupBoxRule(text_colour=gruvbox_dark["fg3"]).when(focused=True),
GroupBoxRule(text_colour=gruvbox_dark["red"]).when(
focused=False, occupied=True, urgent=True
),
GroupBoxRule(visible=False).when(focused=False, occupied=False),
]
# Add extra rule for a specific monitor (e.g., show "X" as label)
if monitor_specific:
rules.append(GroupBoxRule(text=""))
return rules
# --------------------------------------------------------
# Widget Defaults
# --------------------------------------------------------
widget_defaults = dict(
font="Roboto Flex",
fontsize=20,
foreground=gruvbox_dark["fg1"],
)
extension_defaults = widget_defaults.copy()
# --------------------------------------------------------
# Screens
# --------------------------------------------------------
bar.Bar
screens = [
Screen(
# Center Screen
top=bar.Bar(
[
widget.TextBox(
text="",
fontsize=24,
foreground=gruvbox_dark["blue"],
mouse_callbacks={"Button1": lazy.function(start_menu)},
),
widget.GroupBox2(
padding=5,
fontsize=22,
font="Open Sans",
center_aligned=True,
visible_groups=[
"1",
"2",
"3",
"0",
"f8",
"f9",
"f10",
"f11",
"f12",
],
hide_unused=True,
rules=get_groupbox_rules(monitor_specific=False),
),
widget.Spacer(),
widget.Systray(
icon_size=21,
),
widget.Spacer(length=6),
widget.Clock(mouse_callbacks={"Button1": lazy.function(calendar)}),
widget.Spacer(length=2),
widget.TextBox(
font="Open Sans",
fontsize=20,
text="",
mouse_callbacks={"Button1": lazy.function(power_menu)},
),
widget.PulseVolumeExtra(
mode="popup",
fmt="",
popup_layout=VOL_POPUP,
popup_hide_timeout=3,
popup_show_args={"relative_to": 8, "y": -70},
),
],
background=gruvbox_dark["bg0_hard"],
opacity=0.75,
size=32,
margin=[3, 3, 0, 3],
),
),
Screen(
# Right Screen
top=bar.Bar(
[
widget.TextBox(
text="",
fontsize=24,
foreground=gruvbox_dark["blue"],
mouse_callbacks={"Button1": lazy.function(start_menu)},
),
widget.GroupBox2(
padding=6,
fontsize=22,
margin=7,
font="Open Sans",
center_aligned=True,
visible_groups=["7", "8", "9", "f2", "f4", "f5", "f6"],
hide_unused=True,
rules=get_groupbox_rules(monitor_specific=False),
),
widget.Spacer(status_format="{play_status} {artist}/{title}"),
widget.WidgetBox(
fontsize=22,
text_closed="󱤟",
text_open="󱤠",
widgets=[
widget.Memory(
format="󰍛 {MemPercent}%",
font="Open Sans",
),
widget.CPU(
format="󰻠 {load_percent}%",
font="Open Sans",
),
],
),
widget.Spacer(length=6),
widget.Clock(mouse_callbacks={"Button1": lazy.function(calendar)}),
widget.Spacer(length=2),
widget.TextBox(
font="Open Sans",
fontsize=20,
text="",
mouse_callbacks={"Button1": lazy.function(power_menu)},
),
],
background=gruvbox_dark["bg0_hard"],
opacity=0.75,
size=32,
margin=[3, 3, 0, 3],
),
),
Screen(
# Left Screen
top=bar.Bar(
[
widget.TextBox(
text="",
fontsize=24,
foreground=gruvbox_dark["blue"],
mouse_callbacks={"Button1": lazy.function(start_menu)},
),
widget.GroupBox2(
padding=6,
fontsize=22,
font="Open Sans",
center_aligned=True,
visible_groups=[
"4",
"5",
"6",
"f1",
"f7",
"f3",
],
hide_unused=True,
rules=get_groupbox_rules(monitor_specific=False),
),
widget.Spacer(length=20),
widget.Mpris2(
name="mpris2",
width=350,
scroll=True,
scroll_clear=True,
foreground=gruvbox_dark["fg1"],
format="{xesam:title} - {xesam:artist}",
paused_text="{track} ",
popup_layout=MPRIS2_LAYOUT,
poll_interval=15,
popup_show_args={"relative_to": 2, "relative_to_bar": True, "y": 3},
mouse_callbacks={"Button1": lazy.widget["mpris2"].toggle_player()},
),
widget.Spacer(),
widget.Clock(mouse_callbacks={"Button1": lazy.function(calendar)}),
widget.Spacer(length=2),
widget.TextBox(
fontsize=20,
text="",
mouse_callbacks={"Button1": lazy.function(power_menu)},
),
],
background=gruvbox_dark["bg0_hard"],
opacity=0.75,
size=32,
margin=[3, 3, 0, 3],
),
),
]
notifier = Notifier(
x=int((2560 / 2) - (350 / 2)),
y=38,
width=350,
height=80,
format="<b>{summary}</b>\n{app_name}\n{body}",
# file_name='/home/cerberus/.config/qtile/normal.png', # Not working
foreground=gruvbox_dark["fg1"],
background=(
gruvbox_dark["bg0_hard"],
gruvbox_dark["bg0_hard"],
gruvbox_dark["orange"],
),
horizontal_padding=10,
vertical_padding=10,
opacity=0.65,
border_width=0,
font="Open Sans",
font_size=16,
overflow="more_width",
fullscreen="show",
screen=2,
actions=True,
wrap=True,
)