feat: add qtile config
This commit is contained in:
parent
6ff1c6d2a3
commit
a5daaf2761
1 changed files with 623 additions and 0 deletions
623
users/infinidoge/config/qtile.py
Normal file
623
users/infinidoge/config/qtile.py
Normal file
|
@ -0,0 +1,623 @@
|
|||
"""
|
||||
Infinidoge's Qtile Configuration
|
||||
|
||||
Sets up
|
||||
- Keybindings
|
||||
- Widgets
|
||||
- Screens
|
||||
"""
|
||||
import subprocess
|
||||
import os
|
||||
|
||||
from typing import List, Any # noqa: F401
|
||||
|
||||
from libqtile import bar, layout, widget, hook
|
||||
from libqtile.config import Click, Drag, Group, Key, KeyChord, Match, Screen
|
||||
from libqtile.lazy import lazy
|
||||
from libqtile.utils import guess_terminal
|
||||
|
||||
|
||||
colors = [
|
||||
# panel background
|
||||
["#282c34", "#282c34"], # 0
|
||||
# background for current screen tab
|
||||
["#3d3f4b", "#434758"], # 1
|
||||
# font color for group names
|
||||
["#ffffff", "#ffffff"], # 2
|
||||
# border line color for current tab
|
||||
["#ff5555", "#ff5555"], # 3
|
||||
# border line color for 'other tabs' and color for 'odd widgets'
|
||||
["#74438f", "#74438f"], # 4
|
||||
# color for the 'even widgets'
|
||||
["#4f76c7", "#4f76c7"], # 5
|
||||
# window name
|
||||
["#e1acff", "#e1acff"], # 6
|
||||
# background for inactive screens
|
||||
["#ecbbfb", "#ecbbfb"], # 7
|
||||
]
|
||||
|
||||
|
||||
class Apps:
|
||||
"""
|
||||
Commonly referenced apps, such as the terminal or editor
|
||||
"""
|
||||
|
||||
TERMINAL = guess_terminal(preference="kitty") # Set preference if necessary
|
||||
SHELL = "zsh"
|
||||
EDITOR = "emacsclient -c -a 'emacs'"
|
||||
|
||||
@classmethod
|
||||
def terminal_command(cls, program, args=tuple(), *, terminal=None):
|
||||
"""
|
||||
Returns a string of a command to open a program in the terminal, with the given arguments.
|
||||
"""
|
||||
return f"{terminal or cls.TERMINAL} {' '.join(args)} -- {program}"
|
||||
|
||||
@classmethod
|
||||
def open_in_terminal(cls, program, args=tuple(), *, terminal=None):
|
||||
"""
|
||||
Opens a program in the terminal, with the given arguments.
|
||||
"""
|
||||
return lazy.spawn(cls.terminal_command(program, args=args, terminal=terminal))
|
||||
|
||||
@classmethod
|
||||
def open_in_editor(cls, file_, args=tuple()):
|
||||
"""
|
||||
Opens a file in the editor, with the given arguments
|
||||
"""
|
||||
return lazy.spawn(f"{cls.EDITOR} {' '.join(args)} {file_}")
|
||||
|
||||
|
||||
class Keys:
|
||||
"""
|
||||
Common modifier keys used in key configuration.
|
||||
"""
|
||||
|
||||
SUPER = "mod4" # Windows key/super key
|
||||
CONTROL = "control"
|
||||
SHIFT = "shift"
|
||||
ALT = "mod1"
|
||||
ALT_GR = "mod5"
|
||||
META = None # "mod3" # Not assigned to key yet
|
||||
CAPS_LOCK = "lock"
|
||||
NUM_LOCK = "mod2"
|
||||
|
||||
|
||||
# fmt: off
|
||||
keys = [
|
||||
# Switch between windows
|
||||
Key(
|
||||
[Keys.SUPER], "Left",
|
||||
lazy.layout.left(),
|
||||
desc="Move focus to left",
|
||||
),
|
||||
Key(
|
||||
[Keys.SUPER], "Right",
|
||||
lazy.layout.right(),
|
||||
desc="Move focus to right",
|
||||
),
|
||||
Key(
|
||||
[Keys.SUPER], "Down",
|
||||
lazy.layout.down(),
|
||||
desc="Move focus down",
|
||||
),
|
||||
Key(
|
||||
[Keys.SUPER], "Up",
|
||||
lazy.layout.up(),
|
||||
desc="Move focus up",
|
||||
),
|
||||
Key(
|
||||
[Keys.SUPER], "space",
|
||||
lazy.layout.next(),
|
||||
desc="Move window focus to other window",
|
||||
),
|
||||
|
||||
# Switch focus of monitors
|
||||
Key(
|
||||
[Keys.SUPER, Keys.CONTROL], "1",
|
||||
lazy.to_screen(1),
|
||||
desc="Keyboard focus to left monitor"
|
||||
),
|
||||
Key(
|
||||
[Keys.SUPER, Keys.CONTROL], "2",
|
||||
lazy.to_screen(0),
|
||||
desc="Keyboard focus to middle monitor"
|
||||
),
|
||||
Key(
|
||||
[Keys.SUPER, Keys.CONTROL], "3",
|
||||
lazy.to_screen(2),
|
||||
desc="Keyboard focus to right monitor"
|
||||
),
|
||||
Key(
|
||||
[Keys.SUPER, Keys.CONTROL, Keys.SHIFT], "comma",
|
||||
lazy.next_screen(),
|
||||
desc="Move focus to next monitor"
|
||||
),
|
||||
Key(
|
||||
[Keys.SUPER, Keys.CONTROL, Keys.SHIFT], "period",
|
||||
lazy.prev_screen(),
|
||||
desc="Move focus to prev monitor"
|
||||
),
|
||||
|
||||
# Move windows between left/right columns or move up/down in current stack.
|
||||
# Moving out of range in Columns layout will create new column.
|
||||
Key(
|
||||
[Keys.SUPER, Keys.SHIFT], "Left",
|
||||
lazy.layout.shuffle_left(),
|
||||
desc="Move window to the left",
|
||||
),
|
||||
Key(
|
||||
[Keys.SUPER, Keys.SHIFT], "Right",
|
||||
lazy.layout.shuffle_right(),
|
||||
desc="Move window to the right",
|
||||
),
|
||||
Key(
|
||||
[Keys.SUPER, Keys.SHIFT], "Down",
|
||||
lazy.layout.shuffle_down(),
|
||||
desc="Move window down",
|
||||
),
|
||||
Key(
|
||||
[Keys.SUPER, Keys.SHIFT], "Up",
|
||||
lazy.layout.shuffle_up(),
|
||||
desc="Move window up",
|
||||
),
|
||||
|
||||
# Toggle between split and unsplit sides of stack.
|
||||
# Split = all windows displayed
|
||||
# Unsplit = 1 window displayed, like Max layout, but still with
|
||||
# multiple stack panes
|
||||
Key(
|
||||
[Keys.SUPER, Keys.SHIFT], "Return",
|
||||
lazy.layout.toggle_split(),
|
||||
desc="Toggle between split and unsplit sides of stack",
|
||||
),
|
||||
|
||||
# Grow windows. If current window is on the edge of screen and direction
|
||||
# will be to screen edge - window would shrink.
|
||||
Key(
|
||||
[Keys.SUPER, Keys.CONTROL], "Left",
|
||||
lazy.layout.grow_left(),
|
||||
desc="Grow window to the left",
|
||||
),
|
||||
Key(
|
||||
[Keys.SUPER, Keys.CONTROL], "Right",
|
||||
lazy.layout.grow_right(),
|
||||
desc="Grow window to the right",
|
||||
),
|
||||
Key(
|
||||
[Keys.SUPER, Keys.CONTROL], "Down",
|
||||
lazy.layout.grow_down(),
|
||||
desc="Grow window down",
|
||||
),
|
||||
Key(
|
||||
[Keys.SUPER, Keys.CONTROL], "Up",
|
||||
lazy.layout.grow_up(),
|
||||
desc="Grow window up",
|
||||
),
|
||||
Key(
|
||||
[Keys.SUPER, Keys.CONTROL], "n",
|
||||
lazy.layout.normalize(),
|
||||
desc="Reset all window sizes",
|
||||
),
|
||||
Key(
|
||||
[Keys.SUPER, Keys.CONTROL], "m",
|
||||
lazy.layout.maximize(),
|
||||
desc="Maximize the selected window",
|
||||
),
|
||||
|
||||
# Toggle between different layouts as defined below
|
||||
Key(
|
||||
[Keys.SUPER], "Tab",
|
||||
lazy.next_layout(),
|
||||
desc="Move forward through layouts",
|
||||
),
|
||||
Key(
|
||||
[Keys.SUPER, Keys.SHIFT], "Tab",
|
||||
lazy.prev_layout(),
|
||||
desc="Move backward through layouts",
|
||||
),
|
||||
|
||||
# Qtile management keys (close, restart, shutdown, lock, spawn)
|
||||
Key(
|
||||
[Keys.SUPER], "w",
|
||||
lazy.window.kill(),
|
||||
desc="Kill focused window",
|
||||
),
|
||||
Key(
|
||||
[Keys.SUPER, Keys.CONTROL], "r",
|
||||
lazy.restart(),
|
||||
desc="Restart Qtile",
|
||||
),
|
||||
Key(
|
||||
[Keys.SUPER, Keys.CONTROL], "q",
|
||||
lazy.shutdown(),
|
||||
desc="Shutdown Qtile",
|
||||
),
|
||||
Key(
|
||||
[Keys.SUPER, Keys.CONTROL], "l",
|
||||
lazy.spawn("xsecurelock"),
|
||||
desc="Lock Screen",
|
||||
),
|
||||
Key(
|
||||
[Keys.SUPER], "r",
|
||||
lazy.spawncmd(),
|
||||
desc="Spawn a command using a prompt widget",
|
||||
),
|
||||
Key(
|
||||
[Keys.SUPER, Keys.SHIFT], "r",
|
||||
lazy.spawncmd(prompt="shell", command=Apps.terminal_command("%s", args=("--hold",))),
|
||||
desc="Spawn a command in a shell using a prompt widget",
|
||||
),
|
||||
|
||||
# Power management
|
||||
KeyChord(
|
||||
[Keys.SUPER], "p",
|
||||
[
|
||||
Key(
|
||||
[], "h",
|
||||
lazy.spawn("systemctl hibernate"),
|
||||
desc="Hibernates the system",
|
||||
),
|
||||
Key(
|
||||
[], "s",
|
||||
lazy.spawn("systemctl suspend"),
|
||||
desc="Suspends the system",
|
||||
),
|
||||
Key(
|
||||
[], "b",
|
||||
lazy.spawn("xset dpms force off"),
|
||||
desc="Turns off the screen",
|
||||
),
|
||||
Key(
|
||||
[], "r",
|
||||
lazy.spawn("reboot"),
|
||||
desc="Reboots the system",
|
||||
),
|
||||
Key(
|
||||
[], "p",
|
||||
lazy.spawn("shutdown now"),
|
||||
desc="Shuts down the system",
|
||||
),
|
||||
Key(
|
||||
[], "k",
|
||||
lazy.spawn("systemctl kexec"),
|
||||
desc="Quick reboots system, directly loading kernel into memory",
|
||||
),
|
||||
Key(
|
||||
[], "l",
|
||||
lazy.spawn("kill -9 -1"),
|
||||
desc="Logs out of the system",
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
# Volume
|
||||
Key(
|
||||
[], "XF86AudioRaiseVolume",
|
||||
lazy.spawn("amixer set Master 2%+"),
|
||||
desc="Raise volume",
|
||||
),
|
||||
Key(
|
||||
[], "XF86AudioLowerVolume",
|
||||
lazy.spawn("amixer set Master 2%-"),
|
||||
desc="Lower volume",
|
||||
),
|
||||
Key(
|
||||
[], "XF86AudioMute",
|
||||
lazy.spawn("amixer set Master toggle"),
|
||||
desc="Toggle mute",
|
||||
),
|
||||
|
||||
# Application shortcuts
|
||||
Key(
|
||||
[Keys.SUPER], "Return",
|
||||
lazy.spawn(Apps.TERMINAL),
|
||||
desc="Launch terminal",
|
||||
),
|
||||
Key(
|
||||
[Keys.SUPER, Keys.ALT], "f",
|
||||
lazy.spawn("firefox --new-window"),
|
||||
desc="Start Firefox (New Window)",
|
||||
),
|
||||
Key(
|
||||
[Keys.SUPER, Keys.ALT], "e",
|
||||
lazy.spawn("emacsclient -c -a 'emacs'"),
|
||||
desc="Launch Emacs",
|
||||
),
|
||||
Key(
|
||||
[Keys.SUPER, Keys.ALT], "d",
|
||||
lazy.spawn("discord-canary"),
|
||||
desc="Launch Discord",
|
||||
),
|
||||
]
|
||||
# fmt: on
|
||||
|
||||
groups = [
|
||||
*[Group(i) for i in "123456789"],
|
||||
Group("0", layouts=[layout.TreeTab()]),
|
||||
]
|
||||
|
||||
for i in groups:
|
||||
keys.extend(
|
||||
[
|
||||
Key(
|
||||
[Keys.SUPER],
|
||||
i.name,
|
||||
lazy.group[i.name].toscreen(),
|
||||
desc=f"Switch to group {i.name}",
|
||||
),
|
||||
Key(
|
||||
[Keys.SUPER, Keys.SHIFT],
|
||||
i.name,
|
||||
lazy.window.togroup(i.name, switch_group=True),
|
||||
desc=f"Switch to & move focused window to group {i.name}",
|
||||
),
|
||||
Key(
|
||||
[Keys.SUPER, Keys.CONTROL, Keys.SHIFT],
|
||||
i.name,
|
||||
lazy.window.togroup(i.name),
|
||||
desc=f"Move focused window to group {i.name}",
|
||||
),
|
||||
]
|
||||
)
|
||||
|
||||
layouts = [
|
||||
layout.Columns(border_focus_stack="#d75f5f"),
|
||||
layout.Max(),
|
||||
layout.TreeTab(),
|
||||
# Try more layouts by unleashing below layouts.
|
||||
# layout.Stack(num_stacks=2),
|
||||
# layout.Bsp(),
|
||||
# layout.Matrix(),
|
||||
# layout.MonadTall(),
|
||||
# layout.MonadWide(),
|
||||
# layout.RatioTile(),
|
||||
# layout.Tile(),
|
||||
# layout.VerticalTile(),
|
||||
]
|
||||
|
||||
widget_defaults = dict(font="sans", fontsize=12, padding=2, background=colors[0])
|
||||
extension_defaults = widget_defaults.copy()
|
||||
|
||||
|
||||
def create_powerline(
|
||||
widgets: List[List[Any]],
|
||||
*,
|
||||
base,
|
||||
foreground,
|
||||
backgrounds,
|
||||
sep="",
|
||||
padding=0,
|
||||
fontsize=37,
|
||||
):
|
||||
"""
|
||||
Takes in a list of widgets and produces a powerline-style bar as the result.
|
||||
Cycles through the provided colors and uses the provided character as a separator.
|
||||
|
||||
Takes input as a list of widgets, then base, foreground, and backgrounds as keyword arguments.
|
||||
Setting sep changes the separator
|
||||
"""
|
||||
output = []
|
||||
|
||||
for i, widgets_list in enumerate(widgets):
|
||||
bg_index = (len(widgets) - i) % len(backgrounds)
|
||||
output.append(
|
||||
widget.TextBox(
|
||||
text=sep,
|
||||
foreground=backgrounds[bg_index],
|
||||
background=base
|
||||
if i == 0
|
||||
else backgrounds[bg_index - (len(backgrounds) - 1)],
|
||||
fontsize=fontsize,
|
||||
padding=padding,
|
||||
)
|
||||
)
|
||||
|
||||
for elem in widgets_list:
|
||||
elem.foreground = foreground
|
||||
elem.background = backgrounds[bg_index]
|
||||
output.append(elem)
|
||||
|
||||
return output
|
||||
|
||||
|
||||
def init_widget_list(main=True):
|
||||
"""
|
||||
Returns a list of widgets suitable for a qtile bar
|
||||
"""
|
||||
|
||||
widget_list = [
|
||||
widget.Sep(linewidth=0, padding=6, foreground=colors[2], background=colors[0]),
|
||||
widget.GroupBox(
|
||||
font="Ubuntu Mono",
|
||||
fontsize=14,
|
||||
margin_y=3,
|
||||
margin_x=0,
|
||||
padding_y=5,
|
||||
padding_x=3,
|
||||
borderwidth=3,
|
||||
active=colors[2],
|
||||
inactive=colors[7],
|
||||
rounded=False,
|
||||
highlight_color=colors[1],
|
||||
highlight_method="line",
|
||||
this_current_screen_border=colors[5],
|
||||
this_screen_border=colors[6],
|
||||
other_current_screen_border=colors[5],
|
||||
other_screen_border=colors[4],
|
||||
foreground=colors[2],
|
||||
background=colors[0],
|
||||
invert_mouse_wheel=True,
|
||||
),
|
||||
widget.Chord(
|
||||
font="Ubuntu Mono",
|
||||
padding=10,
|
||||
foreground=colors[3],
|
||||
background=colors[1],
|
||||
max_chars=10,
|
||||
),
|
||||
widget.Sep(linewidth=0, padding=6, foreground=colors[2], background=colors[0]),
|
||||
widget.Prompt(
|
||||
prompt="{prompt}: ",
|
||||
font="Ubuntu Mono",
|
||||
padding=10,
|
||||
foreground=colors[3],
|
||||
background=colors[1],
|
||||
),
|
||||
widget.Sep(linewidth=0, padding=40, foreground=colors[2], background=colors[0]),
|
||||
widget.WindowName(foreground=colors[6], background=colors[0], padding=0),
|
||||
*(
|
||||
[
|
||||
widget.Systray(background=colors[0], padding=5),
|
||||
]
|
||||
if main
|
||||
else []
|
||||
),
|
||||
widget.Sep(linewidth=0, padding=6, foreground=colors[0], background=colors[0]),
|
||||
*create_powerline(
|
||||
[
|
||||
# Widgets only found on the main screen's powerline
|
||||
*(
|
||||
[
|
||||
[
|
||||
widget.TextBox(text="Wireless (wlp41s0):", padding=2),
|
||||
widget.Net(
|
||||
interface="wlp41s0",
|
||||
format="{down} ↓↑ {up}",
|
||||
padding=5,
|
||||
),
|
||||
widget.Sep(linewidth=2, padding=3),
|
||||
widget.TextBox(text="Ethernet (eth0):", padding=2),
|
||||
widget.Net(
|
||||
interface="eth0",
|
||||
format="{down} ↓↑ {up}",
|
||||
padding=5,
|
||||
),
|
||||
],
|
||||
[
|
||||
widget.TextBox(
|
||||
text=" 🖬",
|
||||
padding=0,
|
||||
fontsize=14,
|
||||
),
|
||||
widget.Memory(
|
||||
padding=5,
|
||||
),
|
||||
],
|
||||
[
|
||||
widget.TextBox(
|
||||
text=" Vol:",
|
||||
padding=0,
|
||||
),
|
||||
widget.Volume(
|
||||
padding=5,
|
||||
),
|
||||
],
|
||||
]
|
||||
if main
|
||||
else []
|
||||
),
|
||||
# Widgets found on the powerline of all screens
|
||||
[
|
||||
widget.CurrentLayoutIcon(
|
||||
custom_icon_paths=[os.path.expanduser("~/.config/qtile/icons")],
|
||||
padding=0,
|
||||
scale=0.7,
|
||||
),
|
||||
widget.CurrentLayout(
|
||||
padding=5,
|
||||
),
|
||||
],
|
||||
[
|
||||
widget.Clock(
|
||||
format="%A, %B %d, %Y - %H:%M:%S ",
|
||||
),
|
||||
],
|
||||
],
|
||||
base=colors[0],
|
||||
foreground=colors[2],
|
||||
backgrounds=[
|
||||
colors[4],
|
||||
colors[5],
|
||||
],
|
||||
),
|
||||
]
|
||||
|
||||
return widget_list
|
||||
|
||||
|
||||
screens = [
|
||||
Screen(
|
||||
bottom=bar.Bar(init_widget_list(main=True), size=20, opacity=1.0), # width
|
||||
wallpaper="~/Pictures/BotanBackground.jpg",
|
||||
wallpaper_mode="fill",
|
||||
),
|
||||
Screen(
|
||||
bottom=bar.Bar(init_widget_list(main=False), size=20, opacity=1.0), # width
|
||||
wallpaper="~/Pictures/BotanBackground.jpg",
|
||||
wallpaper_mode="fill",
|
||||
),
|
||||
Screen(
|
||||
bottom=bar.Bar(init_widget_list(main=False), size=20, opacity=1.0), # width
|
||||
wallpaper="~/Pictures/BotanBackground.jpg",
|
||||
wallpaper_mode="fill",
|
||||
),
|
||||
]
|
||||
|
||||
# Drag floating layouts.
|
||||
mouse = [
|
||||
Drag(
|
||||
[Keys.SUPER],
|
||||
"Button1",
|
||||
lazy.window.set_position_floating(),
|
||||
start=lazy.window.get_position(),
|
||||
),
|
||||
Drag(
|
||||
[Keys.SUPER],
|
||||
"Button3",
|
||||
lazy.window.set_size_floating(),
|
||||
start=lazy.window.get_size(),
|
||||
),
|
||||
Click(
|
||||
[Keys.SUPER],
|
||||
"Button2",
|
||||
lazy.window.bring_to_front(),
|
||||
),
|
||||
]
|
||||
|
||||
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(title="branchdialog"), # gitk
|
||||
Match(title="pinentry"), # GPG key password entry
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
dgroups_key_binder = None
|
||||
dgroups_app_rules = [] # type: List
|
||||
follow_mouse_focus = True
|
||||
bring_front_click = False
|
||||
cursor_warp = True
|
||||
auto_fullscreen = True
|
||||
focus_on_window_activation = "never"
|
||||
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
|
||||
|
||||
# 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"
|
Loading…
Add table
Add a link
Reference in a new issue