- Python 100%
| colorschemes | Rewritten the config in org-mode | |
| .gitignore | Added README.org with config.org import | |
| config.org | Minor bar tweaks | |
| config.py | Minor bar tweaks | |
| example.png | Rewritten the config in org-mode | |
| README.org | Changed the font, added margin to the bar | |
Qtile org config
- Configuration preview
- Library imports
- General variables
- Key bindings
- Workspaces
- Defining layouts
- Qtile bar
- Qtile additional settings
Configuration preview
/Moskas/qtile-org/media/branch/master/example.png
Library imports
from libqtile import bar, layout, widget, hook
from libqtile.config import Click, Drag, Group, Key, Match, Screen, ScratchPad, DropDown
from libqtile.lazy import lazy
from libqtile.utils import guess_terminal
from libqtile.layout.floating import Floating
Importing colorscheme
from colorschemes.solarized_dark import colors
General variables
Setting up main modification key and terminal variables for future use. In qtile mod4 is "windows key" or "meta key", depends on how you call it.
mod = "mod4"
terminal = "kitty"
Key bindings
Opening keys configuration:
keys = [
Window management
Window switching
I have added configuration for vim keys as well as regular arrows. Additionally with mod and space you can jump to the next window in current workspace.
# vim keys
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([mod], "space", lazy.layout.next(), desc="Move window focus to other window"),
# arrow keys
Key([mod], "left", lazy.layout.left(), desc="Move focus to left"),
Key([mod], "right", lazy.layout.right(), desc="Move focus to right"),
Key([mod], "down", lazy.layout.down(), desc="Move focus down"),
Key([mod], "up", lazy.layout.up(), desc="Move focus up"),
Changing window positions
Moving windows is achieved with keychord of mod key and shift + directional key.
# vim keys
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"),
# arrow keys
Key([mod, "shift"], "left", lazy.layout.shuffle_left(), desc="Move window to the left"),
Key([mod, "shift"], "right", lazy.layout.shuffle_right(), desc="Move window to the right"),
Key([mod, "shift"], "down", lazy.layout.shuffle_down(), desc="Move window down"),
Key([mod, "shift"], "up", lazy.layout.shuffle_up(), desc="Move window up"),
Changing window size
Resizing windows is achieved with keychord of mod key and ctrl + directional key.
Restoring default layout window sizes is done with mod + n.
# vim keys
Key([mod, "control"], "h", lazy.layout.grow_left(), desc="Grow window to the left"),
Key([mod, "control"], "l", lazy.layout.grow_right(), desc="Grow window to the right"),
Key([mod, "control"], "j", lazy.layout.grow_down(), desc="Grow window down"),
Key([mod, "control"], "k", lazy.layout.grow_up(), desc="Grow window up"),
# arrow keys
Key([mod, "control"], "left", lazy.layout.grow_left(), desc="Grow window to the left"),
Key([mod, "control"], "right", lazy.layout.grow_right(), desc="Grow window to the right"),
Key([mod, "control"], "down", lazy.layout.grow_down(), desc="Grow window down"),
Key([mod, "control"], "up", lazy.layout.grow_up(), desc="Grow window up"),
Key([mod], "n", lazy.layout.normalize(), desc="Reset all window sizes"),
Window shuffling
# vim keys
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"),
# arrow keys
Key([mod, "shift"], "left", lazy.layout.shuffle_left(), desc="Move window to the left"),
Key([mod, "shift"], "right", lazy.layout.shuffle_right(), desc="Move window to the right"),
Key([mod, "shift"], "down", lazy.layout.shuffle_down(), desc="Move window down"),
Key([mod, "shift"], "up", lazy.layout.shuffle_up(), desc="Move window up"),
Changing layouts
Fullscreen currently focused window.
Key(
[mod, "shift"],
"space",
lazy.window.toggle_floating(),
desc="Toggle fullscreen mode",
),
Toggle between all layouts.
Key([mod], "Tab", lazy.next_layout(), desc="Toggle between layouts"),
Split layout toggle
When you are in a stacked layout you can toggle between overview of each window in the stack and quickly jump to it.
Key(
[mod, "shift"],
"Return",
lazy.layout.toggle_split(),
desc="Toggle between split and unsplit sides of stack",
),
Media keys
Various media keys shortcuts such as audio volume up, down and mute. Brightness control. For audio control pulsemixer is required and for the brightness xbacklight.
Key(
[],
"XF86AudioRaiseVolume",
lazy.spawn("pulsemixer --change-volume +5"),
),
Key(
[],
"XF86AudioLowerVolume",
lazy.spawn("pulsemixer --change-volume -5"),
),
Key([], "XF86AudioMute", lazy.spawn("pulsemixer --toggle")),
# brightness keys
Key([], "XF86MonBrightnessUp", lazy.spawn("xbacklight -inc 10")),
Key([], "XF86MonBrightnessDown", lazy.spawn("xbacklight -dec 10")),
Qtile specific shortcuts
Closing currently focused window
Key([mod], "q", lazy.window.kill(), desc="Kill focused window"),
Reloading the config
Key([mod, "control"], "r", lazy.reload_config(), desc="Reload the config"),
Closing qtile session
Key([mod, "control"], "q", lazy.shutdown(), desc="Shutdown Qtile"),
Launch prompt
Key([mod], "d", lazy.spawncmd(), desc="Spawn a command using a prompt widget"),
Custom launch shortcuts
Lock screen
Launching betterlockscreen
Key(["mod1"], "l", lazy.spawn("betterlockscreen -l")),
Terminal
Launching terminal set in term variable.
Key([mod], "Return", lazy.spawn(terminal), desc="Launch terminal"),
Flameshot
I have set the shortcuts to mimic my old default shortcuts from ShareX that I have been using on Windows for years.
Print screen button by default will take a fullscreen screenshot and copy it to the clipboard. Keychord of ctrl + print screen will launch selection tool for capturing parts of the screen.
Key(["control"], "Print", lazy.spawn("flameshot gui -c")),
Key([], "Print", lazy.spawn("flameshot screen -c")),
]
Workspaces
Declaring workspaces
I'm using 10 workspaces in total, for some I have pinned applications based on categories. Also some workspaces have different layouts.
- Workspace 1 Consists of only web browsers and it has stack layout.
- Workspace 2 Consists has only text communicators and it also has a stacked layout.
- Workspace 3 Consists of gui text editors and has column layout in case I need to read some documentation.
- Workspace 4 It's for zathura and has monad three column layout.
- Workspace 5 is for steam
All the other workspaces are dynamic with some predetermined icons but without application pinning.
groups = [
Group(
"1",
label="爵",
matches=[
Match(wm_class="Firefox"),
Match(wm_class="brave-browser"),
Match(wm_class="qutebrowser"),
],
layout="stack",
# Arrowkeys
),
Group(
"2",
label="ڦ",
matches=[Match(wm_class="discord"), Match(wm_class="signal")],
layout="stack",
),
Group(
"3",
label="",
matches=[
Match(wm_class="emacs"),
Match(wm_class="jetbrains-fleet"),
Match(wm_class="neovide"),
Match(wm_class="code"),
],
layout="columns",
),
Group("4", label="", matches=[Match(wm_class="Zathura")], layout="monadthreecol"),
Group("5", label="", matches=[Match(wm_class="Steam")], layout="columns"),
Group(
"6",
label="",
matches=[Match(wm_class="obs")],
layout="columns",
),
Group("7", label="", layout="columns"),
Group("8", label="", layout="columns"),
Group("9", label="", layout="columns"),
Group(
"0",
label="",
matches=[Match(wm_class="Spotify"), Match(wm_class="mpdevil")],
layout="stack",
),
]
Workspace switching
for i in groups:
keys.extend(
[
# mod1 + letter of group = switch to group
Key(
[mod],
i.name,
lazy.group[i.name].toscreen(),
desc="Switch to group {}".format(i.name),
),
# mod1 + shift + letter of group = switch to & move focused window to group
Key(
[mod, "shift"],
i.name,
lazy.window.togroup(i.name, switch_group=True),
desc="Switch to & move focused window to group {}".format(i.name),
),
# Or, use below if you prefer not to switch to that group.
# # mod1 + shift + letter of group = move focused window to group
# Key([mod, "shift"], i.name, lazy.window.togroup(i.name),
# desc="move focused window to group {}".format(i.name)),
]
)
Scratchpads
I love qtile scratchpads.
# Append scratchpad with dropdowns to groups
groups.append(
ScratchPad(
"scratchpad",
[
DropDown(
"term", "kitty", width=0.6, height=0.7, x=0.2, y=0.0, opacity=0.9
),
DropDown(
"mixer",
"kitty -e pulsemixer",
width=0.4,
height=0.2,
x=0.3,
y=0,
opacity=0.9,
),
DropDown(
"music",
"kitty -e ncmpcpp",
width=0.6,
height=0.7,
x=0.2,
y=0.0,
opacity=0.9,
),
DropDown(
"bitwarden",
"bitwarden-desktop",
width=0.4,
height=0.6,
x=0.3,
y=0.1,
opacity=1,
),
DropDown(
"ranger",
"kitty -e ranger /home/moskas/",
width=0.6,
height=0.7,
x=0.2,
y=0.0,
opacity=0.9,
),
],
)
)
keys.extend(
[
Key(["mod1"], "1", lazy.group["scratchpad"].dropdown_toggle("term")),
Key(["mod1"], "2", lazy.group["scratchpad"].dropdown_toggle("music")),
Key(["mod1"], "3", lazy.group["scratchpad"].dropdown_toggle("mixer")),
Key(["mod1"], "4", lazy.group["scratchpad"].dropdown_toggle("ranger")),
Key(["mod1"], "9", lazy.group["scratchpad"].dropdown_toggle("bitwarden")),
]
)
Defining layouts
layouts = [
layout.Columns(
border_normal=colors["fg1"],
border_focus=colors["cyan"],
border_focus_stack=[colors["fg"],colors["bg"]],
border_width=4,
border_on_single=2,
margin=5,
margin_on_single=5,
),
layout.Max(
border_normal=colors["bg"],
border_focus=colors["cyan"],
border_focus_stack=colors["cyan"],
border_normal_stack=colors["cyan"],
border_width=2,
margin=5,
),
# Try more layouts by unleashing below layouts.
layout.Stack(
border_normal=colors["dark-gray"],
border_focus=colors["dark-blue"],
border_width=2,
num_stacks=1,
margin=5,
),
# layout.Bsp(),
# layout.Matrix(),
layout.MonadTall(
border_normal=colors["dark-gray"],
border_focus=colors["blue"],
margin=5,
border_width=2,
single_border_width=2,
single_margin=5,
),
layout.MonadThreeCol(
border_normal=colors["dark-gray"],
border_focus=colors["blue"],
margin=5,
border_width=2,
single_border_width=2,
single_margin=5,
new_client_position="bottom",
),
# layout.MonadWide(),
# layout.RatioTile(),
# layout.Tile(),
# layout.TreeTab(),
# layout.VerticalTile(),
# layout.Zoomy(),
]
Floating layout settings
Mouse settings
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()),
]
Floating rules
dgroups_key_binder = None
dgroups_app_rules = [] # type: list
follow_mouse_focus = True
bring_front_click = False
cursor_warp = False
floating_layout = Floating(
border_normal=colors["dark-gray"],
border_focus=colors["dark-blue"],
border_width=3,
float_rules=[
*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(title="Android Emulator - pixel5:5554"),
Match(wm_class="blueman-manager"),
Match(wm_class="pavucontrol"),
Match(wm_class="zoom"),
Match(wm_class="bitwarden"),
Match(wm_class="nemo"),
],
)
Qtile bar
Widget defaults
widget_defaults = dict(
font="JetBrainsMono Nerd Font",
fontsize=16,
)
extension_defaults = widget_defaults.copy()
Top bar
screens = [
Screen(
top=bar.Bar(
[
widget.TextBox(
" ",
foreground=colors["fg1"],
background=colors["blue"],
width = 40,
padding=10,
fontsize = 20,
font = "JetBrainsMono Nerd Font",
),
widget.GroupBox(
fontsize=17,
disable_drag=True,
center_aligned=True,
hide_unused=False,
active=colors["dark-blue"],
inactive=colors["fg"],
highlight_color=[colors["fg"],colors["blue"]],
highlight_method="text",
border_width=0,
urgent_alert_method="text",
#font="MesloLGS Nerd Font",
block_highlight_text_color=colors["dark-blue"],
padding=5,
),
widget.Prompt(
forground=colors["cyan"],
),
widget.Spacer(),
widget.TextBox(
" ",
foreground=colors["fg"],
#background=colors["gray"],
padding=10,
),
widget.Mpd2(
foreground=colors["fg"],
#background=colors["fg1"],
scroll=True,
width=500,
status_format="{artist} - {title} [{album}]",
idle_format="{idle_message}",
idle_message="Empty"
),
widget.Spacer(),
#widget.WindowName(),
widget.Chord(
chords_colors={
"launch": ("#ff0000", "#ffffff"),
},
name_transform=lambda name: name.upper(),
),
#widget.TextBox("<M-d>", foreground=colors["cyan"]),
# NB Systray is incompatible with Wayland, consider using StatusNotifier instead
# widget.StatusNotifier(),
widget.Wallpaper(
directory='~/Pictures/Wallpapers/',
#wallpaper='~/Pictures/Wallpapers/thinkpad.jpeg',
label="",
random_selection = True,
#wallpaper_command = ['feh','--bg-fill'],
),
widget.Systray(
iconsize = 10,
padding=30,
width=500,
),
widget.TextBox(" "),
#widget.Battery(
# format="{char}",
# charge_char="",
# discharge_char="",
# unknown_char=" ",
# foreground=colors["bg"],
# background=colors["green"],
# low_foreground=colors["red"],
# low_percentage=30,
# #padding=10,
# margin = [10,10,10,10],
#),
widget.Battery(
format="{char}{percent:2.0%}",
foreground=colors["bg"],
background=colors["green"],
low_foreground=colors["red"],
low_percentage=30,
notify_bellow=30,
charge_char="",
discharge_char="",
unknown_char=" ",
),
widget.TextBox(
"",
background=colors["dark-yellow"],
foreground=colors["bg"],
padding=10,
),
widget.Clock(
format="%a %H:%M:%S",
foreground=colors["bg"],
background=colors["yellow"],
padding=10,
),
#widget.QuickExit(),
],
size=28,
margin=[5,5,5,5],
#fontsize=64,
background=colors["bg"],
# border_width=[0, 0, 2, 0], # Draw top and bottom borders
# border_color=["ff00ff", "000000", colors["cyan"],"000000"] # Borders are magenta
),
),
]
Qtile additional settings
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
# When using the Wayland backend, this can be used to configure input devices.
wl_input_rules = None
# 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"