As a programmer, having an efficient and well-organized workspace is crucial for getting work done. That's why I was always on the lookout for tools that could help me customize and optimize my development environment.
When I stumbled upon Qtile, a tiling window manager written in Python, I knew I had to give it a try. In this blog post, I'll be sharing my Qtile configuration file and talking about how it has helped me streamline my workflow.
What I like about Qtile.
One of the things I love about Qtile is its highly customizable nature. With just a few lines of code in the configuration file, I was able to set up my workspace exactly how I wanted it.
Whether it's adjusting the layout of my windows, creating custom keybindings, or setting up workspaces for specific projects, Qtile has made it all possible. And because it's a tiling window manager, I no longer have to spend time manually resizing and arranging windows – Qtile takes care of that for me, saving me valuable time and energy. In the following paragraphs, I'll be diving into the specifics of my Qtile configuration and explaining how it all works.
Imports
import os
import re
import socket
import subprocess
from typing import List # noqa: F401
from libqtile import layout, bar, widget, hook, extension
from libqtile.config import Click, Drag, Group, Key, Match, Screen, Rule
from libqtile.command import lazy
#import arcobattery
This is a Python script that imports several modules and functions that are used in a Qtile window manager configuration.
The os
module provides functions for interacting with the operating system, such as reading or writing to the filesystem.
The re
(regular expression) module provides functions for searching and manipulating strings using regular expressions.
The socket
module provides functions for creating and using network sockets, which are used for communication between programs on the same or different computers.
The subprocess
module allows you to spawn new processes, connect to their input/output/error pipes, and obtain their return codes.
The typing
module is used for type hinting, which allows you to annotate variables and function signatures with their expected types. This can make your code more readable and help catch type-related bugs.
The libqtile
module is a Python library that provides classes and functions for creating and configuring a Qtile window manager.
The Click
, Drag
, Group
, Key
, Match
, Screen
, and Rule
classes from the libqtile.config
module are used to define the behavior of the window manager in response to various events, such as mouse clicks or key presses.
The lazy
decorator from the libqtile.command
module is used to delay the execution of a function until it is needed, which can be useful for optimizing the performance of the window manager.
Variables
mod = "mod4"
mod1 = "alt"
mod2 = "control"
home = os.path.expanduser('~')
browser = "firefox"
terminal = "xfce4-terminal"
fileManager = "thunar"
These lines of code define some variables that are used to configure the behavior of the window manager.
The mod
variable is assigned the string "mod4", which is probably the name of a key on the keyboard that is used as a modifier key for creating keyboard shortcuts.
The mod1
and mod2
variables are assigned the strings "alt" and "control", which are also likely names of modifier keys.
The home
variable is assigned the path to the user's home directory, as determined by the os.path.expanduser
function.
The browser
, terminal
, and fileManager
variables are assigned the strings "firefox", "xfce4-terminal", and "thunar", which are the names of executables for launching a web browser, terminal emulator, and file manager, respectively.
Colors
def init_colors():
return[["#282c34", "#282c34"],
["#1c1f24", "#1c1f24"],
["#dfdfdf", "#dfdfdf"],
["#ff6c6b", "#ff6c6b"],
["#98be65", "#98be65"],
["#da8548", "#da8548"],
["#51afef", "#51afef"],
["#c678dd", "#c678dd"],
["#46d9ff", "#46d9ff"],
["#a9a1e1", "#a9a1e1"]]
colors = init_colors()
These lines of code define a function named init_colors
that returns a list of lists, where each inner list contains two strings representing colors. It looks like the function is intended to initialize the colors
variable with a set of default color values.
The colors
variable is then assigned the return value of the init_colors
function. This will initialize colors
with the default set of color values defined in the function.
Lazy Functions
@lazy.function
def window_to_prev_group(qtile):
if qtile.currentWindow is not None:
i = qtile.groups.index(qtile.currentGroup)
qtile.currentWindow.togroup(qtile.groups[i - 1].name)
@lazy.function
def window_to_next_group(qtile):
if qtile.currentWindow is not None:
i = qtile.groups.index(qtile.currentGroup)
qtile.currentWindow.togroup(qtile.groups[i + 1].name)
These are two functions that are decorated with the @lazy.function
decorator. This decorator is provided by the libqtile.command
module and is used to delay the execution of a function until it is needed, which can be useful for optimizing the performance of the window manager.
The window_to_prev_group
function takes a single argument, qtile
, which is an instance of the libqtile.command.CommandObject
class. This function moves the current window to the previous group (workspace) in the list of groups managed by the window manager.
The window_to_next_group
function is similar to window_to_prev_group
, but moves the current window to the next group in the list instead of the previous one.
Both functions use the togroup
method of the currentWindow
attribute of the qtile
object to move the current window to a new group. The togroup
method takes a string argument representing the name of the group to move the window to. The index of the current group in the list of groups is determined using the index
method and the groups
attribute of the qtile
object. The name of the group to move the window to is constructed by either selecting the group at the previous index (for the window_to_prev_group
function) or the next index (for the window_to_next_group
function) in the list.
Key Bindings
keys = [
# SUPER + FUNCTION KEYS
Key([mod], "f", lazy.window.toggle_fullscreen()),
Key([mod], "q", lazy.window.kill()),
Key([mod], "f", lazy.spawn(browser)),
Key([mod], "return", lazy.spawn(terminal)),
Key([mod, "shift"], "return", lazy.spawn(fileManager)),
Key([mod], "x", lazy.spawn("archlinux-logout")),
Key([], "print", lazy.spawn("scrot 'ArcoLinux-%Y-%m-%d-%s_screenshot_$wx$h.jpg' -e 'mv $f $$(xdg-user-dir PICTURES)'")),
Key([mod], "a", lazy.spawn("xfce4-appfinder")),
# SUPER + SHIFT KEYS
Key([mod, "shift"], "q", lazy.window.kill()),
Key([mod, "shift"], "r", lazy.restart()),
# QTILE LAYOUT KEYS
Key([mod], "n", lazy.layout.normalize()),
Key([mod], "space", lazy.next_layout()),
# CHANGE FOCUS
Key([mod], "Up", lazy.layout.up()),
Key([mod], "Down", lazy.layout.down()),
Key([mod], "Left", lazy.layout.left()),
Key([mod], "Right", lazy.layout.right()),
Key([mod], "k", lazy.layout.up()),
Key([mod], "j", lazy.layout.down()),
Key([mod], "h", lazy.layout.left()),
Key([mod], "l", lazy.layout.right()),
# RESIZE UP, DOWN, LEFT, RIGHT
Key([mod, "control"], "l",
lazy.layout.grow_right(),
lazy.layout.grow(),
lazy.layout.increase_ratio(),
lazy.layout.delete(),
),
Key([mod, "control"], "Right",
lazy.layout.grow_right(),
lazy.layout.grow(),
lazy.layout.increase_ratio(),
lazy.layout.delete(),
),
Key([mod, "control"], "h",
lazy.layout.grow_left(),
lazy.layout.shrink(),
lazy.layout.decrease_ratio(),
lazy.layout.add(),
),
Key([mod, "control"], "Left",
lazy.layout.grow_left(),
lazy.layout.shrink(),
lazy.layout.decrease_ratio(),
lazy.layout.add(),
),
Key([mod, "control"], "k",
lazy.layout.grow_up(),
lazy.layout.grow(),
lazy.layout.decrease_nmaster(),
),
Key([mod, "control"], "Up",
lazy.layout.grow_up(),
lazy.layout.grow(),
lazy.layout.decrease_nmaster(),
),
Key([mod, "control"], "j",
lazy.layout.grow_down(),
lazy.layout.shrink(),
lazy.layout.increase_nmaster(),
),
Key([mod, "control"], "Down",
lazy.layout.grow_down(),
lazy.layout.shrink(),
lazy.layout.increase_nmaster(),
),
# FLIP LAYOUT FOR MONADTALL/MONADWIDE
Key([mod, "shift"], "f", lazy.layout.flip()),
# FLIP LAYOUT FOR BSP
Key([mod, "mod1"], "k", lazy.layout.flip_up()),
Key([mod, "mod1"], "j", lazy.layout.flip_down()),
Key([mod, "mod1"], "l", lazy.layout.flip_right()),
Key([mod, "mod1"], "h", lazy.layout.flip_left()),
# MOVE WINDOWS UP OR DOWN BSP LAYOUT
Key([mod, "shift"], "k", lazy.layout.shuffle_up()),
Key([mod, "shift"], "j", lazy.layout.shuffle_down()),
Key([mod, "shift"], "h", lazy.layout.shuffle_left()),
Key([mod, "shift"], "l", lazy.layout.shuffle_right()),
# MOVE WINDOWS UP OR DOWN MONADTALL/MONADWIDE LAYOUT
Key([mod, "shift"], "Up", lazy.layout.shuffle_up()),
Key([mod, "shift"], "Down", lazy.layout.shuffle_down()),
Key([mod, "shift"], "Left", lazy.layout.swap_left()),
Key([mod, "shift"], "Right", lazy.layout.swap_right()),
# TOGGLE FLOATING LAYOUT
Key([mod, "shift"], "space", lazy.window.toggle_floating()),
# Key([mod], "r", lazy.spawncmd(), desc="Spawn a command using a prompt widget"),
Key(['mod4'], 'd', lazy.run_extension(extension.DmenuRun(
dmenu_prompt="Run:",
dmenu_font="sans",
dmenu_lines=10,
))),
# Brightness controls
Key([], "XF86MonBrightnessUp", lazy.spawn(
'lux -a 10'), desc="Brightness Up"),
Key([], "XF86MonBrightnessDown", lazy.spawn(
'lux -s 10'), desc="Brightness Down"),
]
def window_to_previous_screen(qtile, switch_group=False, switch_screen=False):
i = qtile.screens.index(qtile.current_screen)
if i != 0:
group = qtile.screens[i - 1].group.name
qtile.current_window.togroup(group, switch_group=switch_group)
if switch_screen == True:
qtile.cmd_to_screen(i - 1)
def window_to_next_screen(qtile, switch_group=False, switch_screen=False):
i = qtile.screens.index(qtile.current_screen)
if i + 1 != len(qtile.screens):
group = qtile.screens[i + 1].group.name
qtile.current_window.togroup(group, switch_group=switch_group)
if switch_screen == True:
qtile.cmd_to_screen(i + 1)
keys.extend([
# MOVE WINDOW TO NEXT SCREEN
Key([mod,"shift"], "Right", lazy.function(window_to_next_screen, switch_screen=True)),
Key([mod,"shift"], "Left", lazy.function(window_to_previous_screen, switch_screen=True)),
])
These lines of code define a list of keybindings for the window manager. Each keybinding consists of a key combination and an action that should be taken when the key combination is pressed.
The key combinations are specified using the Key
class from the libqtile.config
module, which takes a list of modifier keys as its first argument and a key as its second argument. The action that should be taken is specified as a function or method call, which is passed as the third argument to the Key
constructor.
The lazy
decorator is used to wrap many of the function and method calls, which delays their execution until they are needed. This can be useful for optimizing the performance of the window manager.
Some examples of the keybindings defined in this list include:
Pressing
Mod4+F
(Mod4
is the key specified by themod
variable, which is likely the name of a modifier key) will toggle the current window between fullscreen and windowed mode.Pressing
Mod4+Q
will close the current window.Pressing
Mod4+F
will launch a web browser.Pressing
Mod4+Return
will launch a terminal emulator.Pressing
Mod4+Shift+Return
will launch a file manager.Pressing
Mod4+X
will log out of the system.Pressing
Print
will take a screenshot of the entire screen and save it to the user's Pictures directory.Pressing
Mod4+A
will launch an appfinder.Pressing
Mod4+Shift+Q
will close the current window.Pressing
Mod4+Shift+R
will restart the window manager.Pressing
Mod4+N
will normalize the window size and position.Pressing
Mod4+Space
will switch to the next layout.Pressing
Mod4+Up
,Mod4+Down
,Mod4+Left
, orMod4+Right
will change the focus to the window in the specified direction.Pressing
Mod4+Control+Right
,Mod4+Control+Left
,Mod4+Control+Up
, orMod4+Control+Down
will resize the current window in the specified direction.Pressing
Mod4+Shift+F
will flip the layout for the current group.Pressing
Mod4+Mod1+Up
,Mod4+Mod1+Down
,Mod4+Mod1+Left
, orMod4+Mod1+Right
will flip the layout in the specified direction for the current group.Pressing
Mod4+Shift+Up
,Mod4+Shift+Down
,Mod4+Shift+Left
, orMod4+Shift+Right
will move the current window in the specified direction for the current group.
There are many more keybindings defined in this list, but these are just a few examples.
Groups
groups = []
#["", "", "", "", "", "", "", "", "", "",]
groups = [
Group(name="1"),
Group(name="2"),
Group(name="3"),
Group(name="4"),
Group(name="5"),
Group(name="6"),
]
for i in groups:
keys.extend([
#CHANGE WORKSPACES
Key([mod], i.name, lazy.group[i.name].toscreen()),
Key([mod], "Tab", lazy.screen.next_group()),
Key([mod, "shift" ], "Tab", lazy.screen.prev_group()),
Key(["mod1"], "Tab", lazy.screen.next_group()),
Key(["mod1", "shift"], "Tab", lazy.screen.prev_group()),
# MOVE WINDOW TO SELECTED WORKSPACE 1-10 AND STAY ON WORKSPACE
#Key([mod, "shift"], i.name, lazy.window.togroup(i.name)),
# MOVE WINDOW TO SELECTED WORKSPACE 1-10 AND FOLLOW MOVED WINDOW TO WORKSPACE
Key([mod, "shift"], i.name, lazy.window.togroup(i.name) , lazy.group[i.name].toscreen()),
])
These lines of code define a list of groups for the window manager and extend the list of keybindings with additional keybindings for changing and moving windows between these groups.
The groups
list is initialized with a list of Group
objects, each of which represents a workspace managed by the window manager. The name
attribute of each Group
object specifies the name of the group, which is used to identify the group and is displayed in the window manager's user interface.
The keys
list is then extended with additional keybindings that allow the user to switch between the different groups, move windows between groups, and follow moved windows to their new group.
Some examples of the keybindings added to the keys
list include:
Pressing
Mod4+1
,Mod4+2
,Mod4+3
, etc. will switch to the group with the corresponding name.Pressing
Mod4+Tab
will switch to the next group.Pressing
Mod4+Shift+Tab
will switch to the previous group.Pressing
Mod1+Tab
will switch to the next group.Pressing
Mod1+Shift+Tab
will switch to the previous group.Pressing
Mod4+Shift+1
,Mod4+Shift+2
,Mod4+Shift+3
, etc. will move the current window to the group with the corresponding name and follow the moved window to that group.
Note that the commented out keybinding Key([mod, "shift"],
i.name
, lazy.window.togroup(
i.name
))
is identical to the keybinding that follows it, except that it does not include the lazy.group
[
i.name
].toscreen()
call. This means that the commented out keybinding will move the current window to the group with the corresponding name, but will not switch to that group.
Layouts
def init_layout_theme():
return {"margin":10,
"border_width":2,
"border_focus": colors[8],
"border_normal": colors[9]
}
layout_theme = init_layout_theme()
layouts = [
# layout.MonadTall(margin=8, border_width=2, border_focus="#5e81ac", border_normal="#4c566a"),
layout.MonadTall(**layout_theme),
# layout.Columns(**layout_theme),
# layout.MonadWide(margin=8, border_width=2, border_focus="#5e81ac", border_normal="#4c566a"),
layout.MonadWide(**layout_theme),
layout.Matrix(**layout_theme),
# layout.Bsp(**layout_theme),
# layout.Floating(**layout_theme),
# layout.RatioTile(**layout_theme),
# layout.Max(**layout_theme)
]
These lines of code define a function named init_layout_theme
that returns a dictionary containing layout theme options for the window manager. It looks like the function is intended to initialize the layout_theme
variable with a set of default layout theme values.
The layout_theme
variable is then initialized with the return value of the init_layout_theme
function. This will initialize layout_theme
with the default set of layout theme options defined in the function.
The layouts
list is then defined as a list of layout objects that the window manager can use to arrange windows on the screen. Each layout object is created using the layout
module and is passed the layout theme options contained in the layout_theme
dictionary using the **
operator. This allows the layout theme options to be passed to the layout constructor as keyword arguments.
The available layout objects include:
MonadTall
: A tiling layout with a main window and a stack of windows on the right.MonadWide
: A tiling layout with a main window and a stack of windows below.Matrix
: A tiling layout that arranges windows in a grid.Bsp
: A binary space partitioning layout that arranges windows in a tree structure.Floating
: A layout that allows windows to be freely moved and resized.RatioTile
: A tiling layout that adjusts the size of windows based on their ratios.Max
: A layout that displays only one window at a time and hides all others.
Note that some of the layout objects are commented out, which means that they will not be available to the window manager.
Widgets
# WIDGETS FOR THE BAR
def init_widgets_defaults():
return dict(
font="sans",
fontsize=14,
padding=4,
background=colors[1])
widget_defaults = init_widgets_defaults()
def init_widgets_list():
widgets_list = [
widget.Sep(
linewidth=0,
padding=6,
foreground=colors[2],
background=colors[0],
),
widget.Image(
filename="~/.config/qtile/icons/.face",
scale="False",
margin=5,
foreground=colors[2],
background=colors[0],
mouse_callbacks={'Button1': lazy.spawn('dmenu_run')},
),
widget.Sep(
linewidth=0,
padding=6,
foreground=colors[2],
background=colors[0]
),
widget.GroupBox(
font="Ubuntu Bold",
fontsize=10,
margin_y=3,
margin_x=0,
padding_y=5,
padding_x=3,
borderwidth=3,
active=colors[8],
inactive=colors[2],
rounded=True,
highlight_color=colors[1],
highlight_method="line",
this_current_screen_border=colors[6],
this_screen_border=colors[4],
other_current_screen_border=colors[6],
other_screen_border=colors[4],
foreground=colors[2],
background=colors[0]
),
widget.TextBox(
text='|',
font="Ubuntu Mono",
background=colors[0],
foreground=colors[1],
padding=0,
fontsize=50
),
widget.CurrentLayoutIcon(
custom_icon_paths=[os.path.expanduser(
"~/.config/qtile/icons")],
foreground=colors[9],
background=colors[0],
padding=0,
scale=0.45,
),
widget.CurrentLayout(
foreground=colors[9],
background=colors[0],
padding=5,
),
widget.TextBox(
text='|',
font="Ubuntu Mono",
background=colors[0],
foreground=colors[1],
padding=2,
fontsize=50
),
widget.WindowName(
foreground=colors[2],
background=colors[0],
padding=0,
),
#####
widget.TextBox(
text='|',
font="Ubuntu Mono",
background=colors[0],
foreground=colors[1],
padding=0,
fontsize=50
),
widget.Net(
foreground=colors[2],
background=colors[0],
format = ' {down} {up} ',
),
#####
widget.TextBox(
text='',
background=colors[0],
foreground=colors[1],
padding=0,
fontsize=50,
),
widget.Systray(
foreground=colors[7],
background=colors[1],
padding=5,
icon_size=17,
),
widget.Volume(
foreground=colors[2],
background=colors[1],
fmt='{}',
padding=4,
fontsize=10,
),
widget.Sep(
linewidth=0,
padding=6,
background=colors[1]
),
#####
widget.TextBox(
text='',
background=colors[1],
foreground=colors[0],
padding=0,
fontsize=50,
),
widget.ThermalSensor(
foreground=colors[2],
background=colors[0],
format = ' {temp:.1f}{unit} ',
),
widget.Sep(
linewidth=0,
padding=6,
background=colors[0]
),
#####
widget.TextBox(
text='',
background=colors[0],
foreground=colors[1],
padding=0,
fontsize=50,
),
widget.Battery(
format = ' {percent:2.0%} {char} {hour:d}:{min:02d}',
charge_char='AC',
discharge_char='DC',
foreground=colors[4],
background=colors[1],
update_interval=1,
low_percentage=0.3,
low_foreground=colors[3]
),
widget.Sep(
linewidth=0,
padding=6,
background=colors[1]
),
#####
widget.TextBox(
text='',
background=colors[1],
foreground=colors[0],
padding=0,
fontsize=50,
),
widget.Clock(
foreground=colors[2],
background=colors[0],
format=" %d %b, %a %I:%M %p"
),
widget.Sep(
linewidth=0,
padding=6,
background=colors[0]
),
]
return widgets_list
widgets_list = init_widgets_list()
Screens
def init_widgets_screen1():
widgets_screen1 = init_widgets_list()
return widgets_screen1
def init_widgets_screen2():
widgets_screen2 = init_widgets_list()
return widgets_screen2
widgets_screen1 = init_widgets_screen1()
widgets_screen2 = init_widgets_screen2()
def init_screens():
return [
Screen(top=bar.Bar(widgets=init_widgets_screen1(), size=30, opacity=0.9)),
Screen(top=bar.Bar(widgets=init_widgets_screen2(), size=30, opacity=0.9))
]
screens = init_screens()
This block of code is defining a number of widgets that can be displayed on the bar at the top of the screen by the window manager.
The init_widgets_defaults
function is defined to return a dictionary containing default options for the widgets. The widget_defaults
variable is then initialized with the return value of this function, which will set the default options for the widgets.
The init_widgets_list
function is then defined to return a list of widget objects. Each widget object is created using the widget
module and is passed the default options contained in the widget_defaults
dictionary using the **
operator. This allows the default options to be passed to the widget constructor as keyword arguments.
The available widget objects include:
Sep
: A separator widget that displays a line or other separator between other widgets.Image
: A widget that displays an image file.GroupBox
: A widget that displays a box containing the names of the groups and the windows they contain.TextBox
: A widget that displays a block of text.CurrentLayoutIcon
: A widget that displays an icon representing the current layout.CurrentLayout
: A widget that displays the name of the current layout.WindowName
: A widget that displays the name of the currently focused window.Net
: A widget that displays network usage information.Systray
: A widget that displays icons for system tray applications.Volume
: A widget that displays the current volume level.Battery
: A widget that displays battery information.Clock
: A widget that displays the current time and date.
The widgets will be displayed on the bar in the order they appear in the list.
Mouse Configuration
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())
]
dgroups_key_binder = None
dgroups_app_rules = []
This block of code is defining some mouse binding and application rules for the window manager.
The mouse
list contains two Drag
objects, which define mouse binding rules for dragging windows around the screen. The first Drag
object binds the left mouse button to the window.set_position_floating
method, which allows the window to be moved to any position on the screen by clicking and dragging the window. The second Drag
object binds the right mouse button to the window.set_size_floating
method, which allows the window to be resized by clicking and dragging the window's edges or corners.
The dgroups_key_binder
variable is set to None
, which means that there are no key bindings defined for dynamic groups (groups that can be created and destroyed at runtime).
The dgroups_app_rules
variable is set to an empty list, which means that there are no rules defined for dynamically assigning windows to dynamic groups.
Hooks
main = None
@hook.subscribe.startup_once
def start_once():
home = os.path.expanduser('~')
subprocess.call([home + '/.config/qtile/scripts/autostart.sh'])
@hook.subscribe.startup
def start_always():
# Set the cursor to something sane in X
subprocess.Popen(['xsetroot', '-cursor_name', 'left_ptr'])
@hook.subscribe.client_new
def set_floating(window):
if (window.window.get_wm_transient_for()
or window.window.get_wm_type() in floating_types):
window.floating = True
This block of code defines three hook functions and a main function. Hook functions are functions that are called at specific points in the window manager's lifecycle.
The start_once
hook function is called only once, when the window manager starts up. It expands the ~
character in the home
variable to the user's home directory, and then runs the autostart.sh
script located in the ~/.config/qtile/scripts
directory.
The start_always
hook function is called every time the window manager starts up. It sets the cursor to the left pointer using the xsetroot
command.
The set_floating
hook function is called whenever a new client (application window) is created. It sets the floating
attribute of the window
object to True
if the window is a transient window (a window that is dependent on another window) or if the window's type is in the floating_types
list. This causes the window to be treated as a floating window, which means that it will not be managed by the tiling layout and will be allowed to be positioned and resized manually.
The main
function is set to None
, which means that it is not being used in this configuration.
Floating Layout Configuration
floating_types = ["notification", "toolbar", "splash", "dialog"]
follow_mouse_focus = True
bring_front_click = False
cursor_warp = False
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
Match(wm_class='Arcolinux-welcome-app.py'),
Match(wm_class='Arcolinux-calamares-tool.py'),
Match(wm_class='confirm'),
Match(wm_class='dialog'),
Match(wm_class='download'),
Match(wm_class='error'),
Match(wm_class='file_progress'),
Match(wm_class='notification'),
Match(wm_class='splash'),
Match(wm_class='toolbar'),
Match(wm_class='Arandr'),
Match(wm_class='feh'),
Match(wm_class='Galculator'),
Match(wm_class='archlinux-logout'),
], fullscreen_border_width = 0, border_width = 0)
auto_fullscreen = True
focus_on_window_activation = "focus" # or smart
wmname = "LG3D"
The floating_types
list specifies the types of windows that should be treated as floating windows. These are windows that should not be tiled with other windows, but should instead be allowed to be moved and resized freely.
The follow_mouse_focus
setting determines whether the focus should automatically be moved to the window under the mouse cursor when the mouse is moved.
The bring_front_click
setting determines whether clicking on a window should bring it to the front of all other windows.
The cursor_warp
setting determines whether the mouse cursor should be moved to the center of the window when it is focused.
The floating_layout
variable specifies the layout that should be used for floating windows. In this case, it is set to a Floating
layout with a number of rules for specific window types and titles that should be treated as floating.
The auto_fullscreen
setting determines whether a window should be automatically set to fullscreen mode when it is opened in a floating layout.
The focus_on_window_activation
setting determines the behavior of the window focus when a window is activated (e.g. when it is clicked on or given focus by another window). The possible values are "focus", which means the window should be given focus, and "smart", which means the focus should be given to the window unless it is already focused, in which case the focus should be left unchanged.
Final Words
In conclusion, the configuration file for the Qtile window manager is a powerful tool for customizing and organizing your desktop experience. It allows you to specify keybindings, define groups of workspaces, customize the look and behavior of the bar and widgets and set rules for how windows should behave. With a little bit of scripting knowledge, the possibilities are endless. I hope this blog has helped me understand the structure and purpose of the Qtile configuration file. Happy desktop customization! And as always, Keep Reading, Keep Exploring and Keep Learning.