qtile migrate
qtile migrate
is a tool to help users update their configs to
reflect any breaking changes/deprecations introduced in later versions.
The tool can automatically apply updates but it can also be used to highlight impacted lines, allowing users to update their configs manually.
The tool can take a number of options when running:
Argument |
Description |
Default |
---|---|---|
|
Sets the path to the config file |
|
|
Lists all the available migrations that can be run by the tool. |
n/a |
|
Show more detail about the migration implement by ID. |
n/a |
|
Only runs migrations relating to changes implemented after release VERSION. |
Not set (i.e. runs all migrations). |
|
Run selected migrations identified by ID. Comma separated list if using multiple values. |
Not set (i.e. runs all migrations). |
|
Automatically apply changes without asking user for confirmation. |
Not set (i.e. users will need to confirm application of changes). |
|
When used with |
Not set. |
|
Disables colour output for diff. |
Not set |
|
Outputs linting lines showing location of changes. No changes are made to the config. |
Not set. |
Available migrations
The following migrations are currently available.
ID |
Changes introduced after version |
Summary |
---|---|---|
0.18.0 |
Updates |
|
0.23.0 |
Updates |
|
0.21.0 |
Updates |
|
0.22.1 |
Updates |
|
0.20.0 |
Updates |
|
0.23.0 |
Updates Match objects using lists |
|
0.18.1 |
Updates certain deprecated |
|
0.22.1 |
Removes |
|
0.16.1 |
Changes deprecated |
|
0.16.1 |
Changes |
|
0.16.1 |
Replaces |
|
0.16.1 |
Changes |
|
0.25.0 |
Drops UNSPECIFIED argument |
|
0.17.0 |
Updates |
|
0.18.1 |
Updates |
Running migrations
Assuming your config file is in the default location, running qtile migrate
is sufficent to start the migration process.
Let's say you had a config file with the following contents:
import libqtile.command_client
keys = [
KeyChord(
[mod],
"x",
[Key([], "Up", lazy.layout.grow()), Key([], "Down", lazy.layout.shrink())],
mode="Resize layout",
)
]
qtile.cmd_spawn("alacritty")
Running qtile migrate
will run each available migration and, where the migration would
result in changes, a diff will be shown and you will be asked whether you wish to apply the changes.
UpdateKeychordArgs: Updates ``KeyChord`` argument signature.
--- original
+++ modified
@@ -5,7 +5,8 @@
[mod],
"x",
[Key([], "Up", lazy.layout.grow()), Key([], "Down", lazy.layout.shrink())],
- mode="Resize layout",
+ name="Resize layout",
+ mode=True,
)
]
Apply changes? (y)es, (n)o, (s)kip file, (q)uit.
You will see from the output above that you are shown the name of the migration being applied and its purpose, along with the changes that will be implemented.
If you select quit
the migration will be stopped and any applied changes will
be reversed.
Once all migrations have been run on a file, you will then be asked whether you want to save changes to the file:
Save all changes to config.py? (y)es, (n)o.
At the end of the migration, backups of your original config will still
be in your config folder. NB these will be overwritten if you re-run
qtile migrate
.
Linting
If you don't want the script to modify your config directly, you can use
the --lint
option to show you where changes are required.
Running qtile migrate --lint
on the same config as shown above will result
in the following output:
config.py:
[Ln 1, Col 7]: The 'libqtile.command_*' modules have been moved to 'libqtile.command.*'. (ModuleRenames)
[Ln 8, Col 8]: The use of mode='mode name' for KeyChord is deprecated. Use mode=True and value='mode name'. (UpdateKeychordArgs)
[Ln 12, Col 6]: Use of 'cmd_' prefix is deprecated. 'cmd_spawn' should be replaced with 'spawn' (RemoveCmdPrefix)
Explanations of migrations
The table below provides more detail of the available migrations.
UpdateBitcoin
Migration introduced after version |
0.18.0 |
The BitcoinTicker
widget has been renamed CryptoTicker
. In addition, the format
keyword argument is removed during this migration as the available fields for the format
have changed.
The removal only happens on instances of BitcoinTracker
. i.e. running qtile migrate
on the following code:
BitcoinTicker(format="...")
CryptoTicker(format="...")
will return:
CryptoTicker()
CryptoTicker(format="...")
UpdateBluetoothArgs
Migration introduced after version |
0.23.0 |
The Bluetooth
widget previously accepted a hci
keyword argument. This has
been deprecated following a major overhaul of the widget and should be replaced with
a keyword argument named device
.
For example:
widget.Bluetooth(hci="/dev_XX_XX_XX_XX_XX_XX")
should be changed to:
widget.Bluetooth(device="/dev_XX_XX_XX_XX_XX_XX")
UpdateKeychordArgs
Migration introduced after version |
0.21.0 |
Previously, users could make a key chord persist by setting the mode to a string representing the name of the mode. For example:
keys = [
KeyChord(
[mod],
"x",
[
Key([], "Up", lazy.layout.grow()),
Key([], "Down", lazy.layout.shrink())
],
mode="Resize layout",
)
]
This will now result in the following warning message in the log file:
The use of `mode` to set the KeyChord name is deprecated. Please use `name='Resize Layout'` instead.
'mode' should be a boolean value to set whether the chord is persistent (True) or not."
To remove the error, the config should be amended as follows:
keys = [
KeyChord(
[mod],
"x",
[
Key([], "Up", lazy.layout.grow()),
Key([], "Down", lazy.layout.shrink())
],
name="Resize layout",
mode=True,
)
]
Note
The formatting of the inserted argument may not correctly match your own formatting. You may this
to run a tool like black
after applying this migration to tidy up your code.
UpdateStocktickerArgs
Migration introduced after version |
0.22.1 |
The StockTicker
widget had a keyword argument called function
. This needs to be
renamed to func
to prevent clashes with the function()
method of CommandObject
.
For example:
widget.StockTicker(function="TIME_SERIES_INTRADAY")
should be changed to:
widget.StockTicker(func="TIME_SERIES_INTRADAY")
UpdateWidgetboxArgs
Migration introduced after version |
0.20.0 |
The WidgetBox
widget allowed a position argument to set the contents of the widget.
This behaviour is deprecated and, instead, the contents should be specified with a
keyword argument called widgets
.
For example:
widget.WidgetBox(
[
widget.Systray(),
widget.Volume(),
]
)
should be changed to:
widget.WidgetBox(
widgets=[
widget.Systray(),
widget.Volume(),
]
)
MatchListRegex
Migration introduced after version |
0.23.0 |
The use of lists in Match
objects is deprecated and should be
replaced with a regex.
For example:
Match(wm_class=["one", "two"])
should be changed to:
Match(wm_class=re.compile(r"^(one|two)$"))
ModuleRenames
Migration introduced after version |
0.18.1 |
libqtile.window
module was moved to libqtile.backend.x11.window
.
RemoveCmdPrefix
Migration introduced after version |
0.22.1 |
The cmd_
prefix was used to identify methods that should be exposed to
qtile's command API. This has been deprecated and so calls no longer require
the prefix.
For example:
qtile.cmd_spawn("vlc")
would be replaced with:
qtile.spawn("vlc")
Where users have created their own widgets with methods using this prefix, the syntax has also changed:
For example:
class MyWidget(libqtile.widget.base._Widget):
def cmd_my_command(self):
pass
Should be updated as follows:
from libqtile.command.base import expose_command
class MyWidget(libqtile.widget.base._Widget):
@expose_command
def my_command(self):
pass
RenamePacmanWidget
Migration introduced after version |
0.16.1 |
The Pacman
widget has been renamed to CheckUpdates
.
This is because the widget supports multiple package managers.
Example:
screens = [
Screen(
top=Bar(
[
...
widget.Pacman(),
...
]
)
)
]
Should be updated as follows:
screens = [
Screen(
top=Bar(
[
...
widget.CheckUpdates(),
...
]
)
)
]
RenameWindowNameHook
Migration introduced after version |
0.16.1 |
The window_name_changed
hook has been replaced with
client_name_updated
.
Example:
@hook.subscribe.window_name_changed
def my_func(window):
...
Should be updated as follows:
@hook.subscribe.client_name_updated
def my_func(window):
...
RenameThreadedPollText
Migration introduced after version |
0.16.1 |
The ThreadedPollText
class needs to replced with ThreadPoolText
.
This is because the ThreadPoolText
class can do everything that the
ThreadedPollText
does so the redundant code was removed.
Example:
from libqtile import widget
class MyPollingWidget(widget.base.ThreadedPollText):
...
Should be updated as follows:
from libqtile import widget
class MyPollingWidget(widget.base.ThreadPoolText):
...
RenameTileMaster
Migration introduced after version |
0.16.1 |
To be consistent with other layouts, the masterWindows
property of the
Tile
layout was renamed to master_length
. Configs using the
masterWindows
argument when configuring the layout should replace this.
RenameUnspecified
Migration introduced after version |
0.25.0 |
The UNSPECIFIED object was removed in favor of using the zero values (or None) to leave behavior unspecified. That is:
font=UNSPECIFIED -> font=None fontsize=UNSPECIFIED -> fontsize=0 fontshadow=UNSPECIFIED -> fontshadow=""
UpdateMonadArgs
Migration introduced after version |
0.17.0 |
Replaces the new_at_current=True|False
argument in Monad*
layouts with
new_client_position
to be consistent with other layouts.
new_at_current=True
is replaced with new_client_position="before_current
and
new_at_current=False
is replaced with new_client_position="after_current"
.
UpdateTogroupArgs
Migration introduced after version |
0.18.1 |
To be consistent with codestyle, the groupName
argument in the togroup
command needs to be
changed to group_name
.
The following code:
lazy.window.togroup(groupName="1")
will result in a warning in your logfile: Window.togroup's groupName is deprecated; use group_name
.
The code should be updated to:
lazy.window.togroup(group_name="1")