mirror of
https://github.com/GRFreire/dotfiles.git
synced 2026-01-10 04:19:38 +00:00
396 lines
12 KiB
Python
396 lines
12 KiB
Python
# ____ ____ _____ _
|
|
# / ___| _ \| ___| __ ___(_)_ __ ___
|
|
# | | _| |_) | |_ | '__/ _ \ | '__/ _ \ Guilherme Rugai Freire
|
|
# | |_| | _ <| _|| | | __/ | | | __/ https://grfreire.com
|
|
# \____|_| \_\_| |_| \___|_|_| \___| https://github.com/GRFreire
|
|
#
|
|
|
|
import time
|
|
import os
|
|
import subprocess
|
|
from typing import List # noqa: F401
|
|
|
|
from libqtile import bar, layout, widget, qtile, hook
|
|
from libqtile.config import Click, Drag, Group, Key, Match, Screen
|
|
from libqtile.lazy import lazy
|
|
|
|
MOD = "mod4"
|
|
ALT = "mod1"
|
|
TERMINAL = "alacritty"
|
|
LAUNCHER = "rofi -show drun"
|
|
WEB = "google-chrome"
|
|
FILE_MANAGER = "nautilus -w"
|
|
POWER_MENU = os.path.expanduser(
|
|
"~/.local/bin/spm"
|
|
) # https://github.com/GRFreire/simple-power-menu
|
|
|
|
keys = [
|
|
# Launch programs
|
|
Key([MOD], "Return", lazy.spawn(TERMINAL), desc="Launch terminal"),
|
|
Key([MOD], "r", lazy.spawn(LAUNCHER), desc="Open application launcher"),
|
|
Key([MOD], "w", lazy.spawn(WEB), desc="Open web browser"),
|
|
Key([MOD], "f", lazy.spawn(FILE_MANAGER), desc="Open file manager"),
|
|
# Closes window.
|
|
Key([MOD], "q", lazy.window.kill(), desc="Kill focused window"),
|
|
# Switch between windows
|
|
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"),
|
|
Key([ALT], "Tab", lazy.layout.next(), desc="Move window focus to other window"),
|
|
# Move windows between left/right columns.
|
|
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"], "j", lazy.layout.shuffle_down(), desc="Move window down"),
|
|
Key([MOD, "shift"], "k", lazy.layout.shuffle_up(), desc="Move window up"),
|
|
# Grow and shrink windows.
|
|
Key(
|
|
[MOD, "control"], "h", lazy.layout.shrink_main(), desc="Grow window to the left"
|
|
),
|
|
Key(
|
|
[MOD, "control"], "l", lazy.layout.grow_main(), desc="Grow window to the right"
|
|
),
|
|
Key([MOD, "control"], "j", lazy.layout.shrink_main(), desc="Grow window down"),
|
|
Key([MOD, "control"], "k", lazy.layout.grow_main(), desc="Grow window up"),
|
|
Key([MOD], "n", lazy.layout.normalize(), desc="Reset all window sizes"),
|
|
# Toggle between different layouts.
|
|
Key([MOD], "Tab", lazy.next_layout(), desc="Toggle between layouts"),
|
|
# QTile
|
|
Key([MOD, "control"], "r", lazy.restart(), desc="Restart Qtile"),
|
|
Key([MOD, "control"], "q", lazy.shutdown(), desc="Shutdown Qtile"),
|
|
]
|
|
|
|
group_names = [
|
|
("WWW", {"layout": "monadtall"}),
|
|
("DEV", {"layout": "max"}),
|
|
("GMG", {"layout": "max"}),
|
|
("SYS", {"layout": "ratiotile"}),
|
|
("DOC", {"layout": "monadtall"}),
|
|
("CHAT", {"layout": "max"}),
|
|
("MUS", {"layout": "max"}),
|
|
("VID", {"layout": "monadtall"}),
|
|
("EDT", {"layout": "max"}),
|
|
]
|
|
|
|
groups = [Group(name, **kwargs) for name, kwargs in group_names]
|
|
|
|
for i, (name, kwargs) in enumerate(group_names, 1):
|
|
# Switch to another group
|
|
keys.append(Key([MOD], str(i), lazy.group[name].toscreen()))
|
|
|
|
# Send current window to another group
|
|
keys.append(Key([MOD, "shift"], str(i), lazy.window.togroup(name)))
|
|
|
|
|
|
colors = {
|
|
"background": "#272A34",
|
|
"background_highlight": "#363D54",
|
|
"text": "#EAEDF6",
|
|
"accent_color_dark": "#1C325E",
|
|
"accent_color_light": "#49659C",
|
|
"accent_highlight": "#214897",
|
|
"active": "#9EBEFF",
|
|
"inactive": "#B4C5E4",
|
|
}
|
|
|
|
layout_theme = {
|
|
"border_width": 2,
|
|
"margin": 6,
|
|
"border_focus": colors["accent_color_light"],
|
|
"border_normal": colors["background"],
|
|
}
|
|
|
|
layouts = [
|
|
layout.MonadTall(**layout_theme),
|
|
layout.Max(**layout_theme),
|
|
layout.MonadWide(**layout_theme),
|
|
layout.RatioTile(**layout_theme),
|
|
]
|
|
|
|
FONT = "Ubuntu"
|
|
widget_defaults = dict(
|
|
font=FONT,
|
|
fontsize=14,
|
|
padding=4,
|
|
background=colors["background"],
|
|
foreground=colors["text"],
|
|
)
|
|
extension_defaults = widget_defaults.copy()
|
|
|
|
|
|
def generate_bar(left=[], right=[]):
|
|
current_bg_color = colors["background"]
|
|
current_fg_color = colors["text"]
|
|
|
|
widgets = []
|
|
|
|
def create_sep(width=10):
|
|
widgets.append(
|
|
widget.Sep(
|
|
padding=0,
|
|
size_percent=100,
|
|
linewidth=width,
|
|
foreground=current_bg_color,
|
|
)
|
|
)
|
|
|
|
def create_arrow(bg=current_bg_color, fg=current_fg_color):
|
|
widgets.append(
|
|
widget.Sep(
|
|
padding=0,
|
|
size_percent=100,
|
|
linewidth=10,
|
|
background=fg,
|
|
foreground=bg,
|
|
)
|
|
)
|
|
widgets.append(
|
|
widget.TextBox(
|
|
text="", background=bg, foreground=fg, padding=0, fontsize=60
|
|
)
|
|
)
|
|
|
|
create_sep(4)
|
|
|
|
for w in left:
|
|
widgets.append(w)
|
|
|
|
create_sep(4)
|
|
|
|
is_even = True
|
|
is_first_widget = True
|
|
for g in right:
|
|
if is_even:
|
|
current_bg_color = colors["accent_color_dark"]
|
|
is_even = False
|
|
else:
|
|
current_bg_color = colors["accent_color_light"]
|
|
is_even = True
|
|
|
|
if is_first_widget:
|
|
create_arrow(colors["background"], colors["accent_color_dark"])
|
|
|
|
is_first_widget = False
|
|
else:
|
|
create_arrow(
|
|
colors["accent_color_dark"]
|
|
if is_even
|
|
else colors["accent_color_light"],
|
|
colors["accent_color_light"]
|
|
if is_even
|
|
else colors["accent_color_dark"],
|
|
)
|
|
|
|
for w in g:
|
|
w.background = current_bg_color
|
|
w.foreground = current_fg_color
|
|
widgets.append(w)
|
|
|
|
create_sep()
|
|
|
|
return widgets
|
|
|
|
|
|
def group_box():
|
|
return widget.GroupBox(
|
|
disable_drag=True,
|
|
use_mouse_wheel=False,
|
|
font=FONT + " Bold",
|
|
fontsize=10,
|
|
margin_y=6,
|
|
margin_x=0,
|
|
padding=5,
|
|
borderwidth=3,
|
|
highlight_method="line",
|
|
rounded=False,
|
|
active=colors["active"],
|
|
inactive=colors["text"],
|
|
highlight_color=colors["background_highlight"],
|
|
this_current_screen_border=colors["active"],
|
|
this_screen_border=colors["accent_highlight"],
|
|
other_current_screen_border=colors["active"],
|
|
other_screen_border=colors["accent_highlight"],
|
|
foreground=colors["text"],
|
|
background=colors["background"],
|
|
)
|
|
|
|
|
|
def main_bar():
|
|
return generate_bar(
|
|
left=[
|
|
group_box(),
|
|
widget.Sep(
|
|
linewidth=8,
|
|
background=colors["background"],
|
|
foreground=colors["background"],
|
|
),
|
|
widget.WindowName(),
|
|
widget.Notify(),
|
|
widget.Systray(padding=10),
|
|
],
|
|
right=[
|
|
[
|
|
widget.TextBox(text="⟳", fontsize=18),
|
|
widget.CheckUpdates(
|
|
distro="Ubuntu", display_format="{updates} Updates"
|
|
),
|
|
],
|
|
[
|
|
widget.CurrentLayoutIcon(scale=0.75),
|
|
widget.CurrentLayout(),
|
|
],
|
|
[
|
|
widget.TextBox(
|
|
text="Vol:",
|
|
mouse_callbacks={
|
|
"Button1": lambda: qtile.cmd_spawn(
|
|
"amixer -q -D pulse sset Master toggle"
|
|
)
|
|
},
|
|
),
|
|
widget.Volume(mute_command="amixer -q -D pulse sset Master toggle"),
|
|
],
|
|
[
|
|
widget.Clock(
|
|
format="%d / %m / %y",
|
|
mouse_callbacks={"Button1": lambda: qtile.cmd_spawn("gsimplecal")},
|
|
),
|
|
widget.Clock(format="%I:%M %p", font=FONT + " Bold"),
|
|
],
|
|
[
|
|
widget.TextBox(
|
|
text="⏻",
|
|
fontsize=22,
|
|
mouse_callbacks={"Button1": lambda: qtile.cmd_spawn(POWER_MENU)},
|
|
),
|
|
],
|
|
],
|
|
)
|
|
|
|
|
|
def aux_bar():
|
|
return generate_bar(
|
|
left=[
|
|
widget.CurrentLayoutIcon(scale=0.65),
|
|
group_box(),
|
|
widget.Sep(
|
|
linewidth=8,
|
|
background=colors["background"],
|
|
foreground=colors["background"],
|
|
),
|
|
widget.WindowName(),
|
|
]
|
|
)
|
|
|
|
|
|
screens = [
|
|
Screen(top=bar.Bar(main_bar(), 28)),
|
|
Screen(top=bar.Bar(aux_bar(), 28)),
|
|
]
|
|
|
|
# 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()),
|
|
]
|
|
|
|
dgroups_key_binder = None
|
|
dgroups_app_rules = [] # type: List
|
|
follow_mouse_focus = True
|
|
bring_front_click = False
|
|
cursor_warp = False
|
|
|
|
floating_layout = layout.Floating(
|
|
**layout_theme,
|
|
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(title="branchdialog"), # gitk
|
|
Match(title="pinentry"), # GPG key password entry
|
|
Match(wm_class="gnome-calculator"), # Calculator
|
|
Match(wm_class="pavucontrol"), # Audio mixer
|
|
Match(wm_class="gnome-calendar"), # Calendar
|
|
]
|
|
)
|
|
auto_fullscreen = True
|
|
focus_on_window_activation = "smart"
|
|
reconfigure_screens = True
|
|
|
|
# If things like steam games want to auto-minimize themselves when losing
|
|
# focus, should we respect this or not?
|
|
auto_minimize = True
|
|
|
|
|
|
@hook.subscribe.startup_once
|
|
def autostart():
|
|
autostart_script = os.path.expanduser("~/.config/qtile/autostart.sh")
|
|
subprocess.call([autostart_script])
|
|
|
|
|
|
@hook.subscribe.client_new
|
|
def try_regroup_window(client):
|
|
time.sleep(0.01)
|
|
apps_wm_class = {
|
|
"google-chrome": "WWW",
|
|
"Navigator": "WWW",
|
|
"code": "DEV",
|
|
"Steam": "GMG",
|
|
"nitrogen": "SYS",
|
|
"VirtualBox Manager": "SYS",
|
|
"virt-manager": "SYS",
|
|
"baobab": "SYS",
|
|
"gnome-disks": "SYS",
|
|
"gedit": "DOC",
|
|
"discord": "CHAT",
|
|
"microsoft teams - preview": "CHAT",
|
|
"spotify": "MUS",
|
|
"obs": "VID",
|
|
"ghb": "VID",
|
|
"audacity": "EDT",
|
|
"krita": "EDT",
|
|
}
|
|
|
|
# Notion for class is notion-nativefier-xxxx for example
|
|
apps_wm_class_incomplete = {
|
|
"notion": "DOC",
|
|
}
|
|
|
|
wm_class = client.window.get_wm_class()[0]
|
|
group = apps_wm_class.get(wm_class, None)
|
|
if group:
|
|
client.togroup(group, switch_group=True)
|
|
else:
|
|
for key in apps_wm_class_incomplete:
|
|
if key in wm_class:
|
|
client.togroup(apps_wm_class_incomplete[key], switch_group=True)
|
|
|
|
|
|
# XXX: Gasp! We're lying here. In fact, nobody really uses or cares about this
|
|
# string besides java UI toolkits; you can see several discussions on the
|
|
# mailing lists, GitHub issues, and other WM documentation that suggest setting
|
|
# this string if your java app doesn't work correctly. We may as well just lie
|
|
# and say that we're a working one by default.
|
|
#
|
|
# We choose LG3D to maximize irony: it is a 3D non-reparenting WM written in
|
|
# java that happens to be on java's whitelist.
|
|
wmname = "LG3D"
|