Copyright © 2011-2024 devilspie2 developers
This file is distributed under the same licence as the devilspie2 package (see COPYING).
Devil's Pie 2 is based on the excellent program Devil's Pie by Ross Burton. It will read Lua scripts from a folder and run them whenever a window is opened, and the rules in them are applied on the window. (See the Configuration section for more details.)
Unfortunately the rules of the original Devil's Pie are not supported.
devilspie2 will load all the Lua files in this folder in alphabetical order.
devilspie2 accepts the following options:
-h, --help |
Show help options |
-d, --debug |
Print debug information to stdout |
-D, --debug-fifo |
Print debug info & copy stdout to a FIFO |
-P, --print-fifo |
Print the debug FIFO's file name then quit |
-e, --emulate |
Don't apply any rules, only emulate execution |
-f, --folder |
Search for scripts in this folder |
-v, --version |
Print program version then quit |
-w, --wnck-version |
Show libwnck version then quit |
-l, --lua-version |
Show Lua version then quit |
If you run devilspie2 --debug-fifo, you can connect to its FIFO at any
time and see the same text as for devilspie --debug. The reason for this
is to allow devilspie2 to be dæmonised while still having access to
debugging output etc. at need.
A useful way of doing this is to run, in a terminal, this command:
cat "$(devilspie2 -P)"(No text backlog will be shown; if there's nothing reading the FIFO, nothing is written to it.)
Scripts are read from the scripts folder, which is customisable by using the
--folder option. By default, this folder is ~/.config/devilspie2/.
(~/.config is the default location as defined in the
XDG Base Directory Specification
and returned by the GLib function g_get_user_config_dir. As such, it can
also be overridden by the environment.)
This folder will be created if it doesn't already exist.
If devilspie2 doesn't find any Lua files (*.lua) in the folder, it will
stop execution. (Dot-files – those with names beginning with . – are
ignored.)
As of v0.46, each script has 5 seconds to do its job and exit or it will be unceremoniously interrupted.
If there is a file named devilspie2.lua in the script folder, it is read and
executed first. You can choose to have all script functionality in this
file or you can split it up into several.
Whilst the default behaviour is to run all scripts on window open events, Devil's Pie 2 also supports other window-related events (close, focus, blur, name/title change).
If you want actions to be taken on particular events, you'll need to define which scripts are to be run on each event type. This is done via the following variables:
scripts_window_open(See Below)scripts_window_closescripts_window_focusscripts_window_blurscripts_window_name_change
These variables can be:
- A single string, naming a file to run for that event, for example:
scripts_window_focus = "file1.lua"
- A Lua table, listing multiple files, for example:
scripts_window_close = { "file1.lua", "file2.lua" }
The files named:
- are expected to be in the scripts folder;
- will only be called when the respective events occur;
- can be run on multiple events (as with
file1.luain the above examples).
All other Lua script files in the scripts folder will be called whenever a
window is opened (unless scripts_window_open is specified).
Specifying the scripts_window_open variable in devilspie2.lua is significant for a couple of reasons:
- It affords control over which scripts in the folder are executed, which could be useful if you want to exclude scripts for any reason, or just to be sure of what is being run.
- It allows the
requireing of modules within the script folder. Lua has mechanisms to avoid executingrequired modules more than once that the default behaviour of Devil's Pie 2 circumvents and renders inoperable.
If you don't want to handle window open events (unlikely) but do want to be able to require a module within the script folder you can set scripts_window_open to an empty value:
scripts_window_open = {}
or
scripts_window_open = ""The scripting language used is Lua.
- FAQ: https://www.lua.org/faq.html
- Documentation: https://www.lua.org/docs.html
- Tutorials: http://lua-users.org/wiki/TutorialDirectory
Tips:
- If you're going to be testing certain window properties a lot, it's best to assign those property values to variables then to test the variables.
- String comparison is case sensitive. Comparing
SomeProgramwithsomeprogramwill not report equality.
The following commands are recognised by the Devil's Pie 2 Lua interpreter:
First, a function to show some debug info:
-
Debug helper which prints a string to
stdoutifdevilspie2is run with the--debugoption; otherwise does nothing.
Then there are the functions to get the properties of a window, and related information:
-
Returns a string containing the name of the current window.
-
Returns a boolean value indicating whether the window has a name.
(Available from version 0.20)
-
Returns the application name of the current window.
-
Returns the name of the process owning the current window.
On (at least) Linux, the process name is read from
/proc/<pid>/comm. If that's not possible,psis launched in a shell. For this reason, you should avoid callingget_process_name()more than necessary.This function is not compatible with busybox
ps.(Available from version 0.44)
-
Returns the window geometry as four numbers - x-position, y-position, width and height. For example, you can do something like this:
x, y, width, height = get_window_geometry(); print("X: "..x..", Y: "..y..", width: "..width..", height: "..height);
(Available from version 0.16)
-
Returns the window geometry excluding the window manager borders as four numbers, x-position, y-position, width and height.
See
get_window_geometryfor an example on how to use this function.(Available from version 0.16)
-
Returns the window frame extents as four numbers: left, right, top, bottom.
(Available from version 0.45.)
-
get_window_is_minimised<a name="user-content-get-window-is-minimised`Returns
trueif the window is minimised,falseotherwise.(Available from version 0.46; -
izedfrom 0.46) -
get_window_is_maximised<a name="user-content-get-window-is-maximised`Returns
trueif the window is maximised,falseotherwise.(Available from version 0.21; -
isefrom 0.45) -
get_window_is_maximised_vertically()Returns
trueif the window is vertically maximised,falseotherwise.(Available from version 0.21; -
isefrom 0.45) -
get_window_is_maximised_horizontally()Returns
trueif the window is horizontally maximised,falseotherwise.(Available from version 0.21; -
isefrom 0.45) -
Returns
trueif the window is decorated,falseotherwise.(Available from version 0.44.)
-
Returns the type of the window. The result type is a string, and can be one of the following:
WINDOW_TYPE_NORMALWINDOW_TYPE_DESKTOPWINDOW_TYPE_DOCKWINDOW_TYPE_DIALOGWINDOW_TYPE_TOOLBARWINDOW_TYPE_MENUWINDOW_TYPE_UTILITYWINDOW_TYPE_SPLASHSCREENWINDOW_TYPE_UNRECOGNIZED(if libwnck didn't recognise the type)WINDOW_ERROR(if there's no window to work on)
(Available from version 0.21)
-
Get the class instance name from the WM_CLASS property for the current window.
(Available from version 0.21; requires libwnck 3+)
-
Get the class group name from the WM_CLASS Property for the current window.
(Available from version 0.21; requires libwnck 3+)
-
get_window_property(string property)Returns the value of the named window property. For a list of available properties, see the Freedesktop EWMH specification.
From 0.45, returns
nilif the property doesn't exist.(Available from version 0.21)
-
window_property_is_utf8(string property)Returns whether the named window property is UTF-8. (Always returns
truefor properties which are converted to string.)Returns
nilif the property doesn't exist.(Available from version 0.45)
-
get_window_property_full(string property)Returns a list suitable for assignment to two variables, equivalent to calling
get_window_property(property), window_property_is_utf8(property)
Returns
nilif the property doesn't exist.(Available from version 0.45)
-
Returns a string describing the current window role of the matched window as defined by its
WM_WINDOW_ROLEhint. -
Returns the X window id of the current window.
-
Returns a string representing the class of the current window.
-
Returns the number of workspaces available.
(Available from version 0.27)
-
Returns 2 tables listing currently known workspaces (by Name and ID). i.e. For 3 workspaces "First space", "Second" & "Third and final" and IDs of 1, 2 & 3 the returned tables would be:
local by_name, by_id = get_workspaces() by_name = { "First space" = 1, "Second" = 2, "Third and final" = 3 } by_id = { "First space", "Second", "Third and final" } by_name["First space"] == 1 by_id[3] == "Third and final"
(Available from version 0.46)
get_active_workspace
Returns the index and name of the active workspace (Obtained via the current window's Screen)
(Available from version 0.46)
-
Returns 2 values: the index and name of the workspace the current window is on.
(Available from version 0.46)
-
Returns the screen geometry (two numbers) for the screen of the current window.
(Available from version 0.29)
-
Returns
trueif the window is fullscreen,falseotherwise.(Available from version 0.32)
-
Returns the index of the monitor containing the window centre (or some part of the window).
(Available from version 0.44)
-
get_monitor_geometry([int index])Returns x, y, width, height for the given monitor or, without parameters, for the window's monitor.
If the index is out of range, nothing is returned.
(Available from version 0.44 without parameter)
And the rest of the commands are used to modify the properties of the windows:
-
set_adjust_for_decoration([bool])Allow for situations where moving or resizing the window is done incorrectly, i.e.
set_window_position(0,0)
results in the window decoration being taken into account twice, i.e. the window (including decoration) is offset from the top left corner by the width of the left side decoration and the height of the title bar.
This is currently off by default, and is sticky: if you do not explicitly set it in your script, its current value is retained.
If used, it should be used at the start of the script.
This affects the following functions:
(Available from version 0.45)
-
set_window_position(int xpos, int ypos, [int index])Set the position of a window.
If
indexis specified then the co-ordinates are relative to a corner of the specified monitor (counting from 1) on the current workspace. Which corner is determined by the co-ordinates' signs:- +ve
X⇒ left, -veX⇒ right; - +ve
Y⇒ top, -veY⇒ bottom.
NOTE: since
-0would have a use here but is equal to+0,~(bitwise NOT) is used. To put the window 60 pixels from the right or bottom, use~60or-61.If
index=0then the ‘current’ monitor (with the window's centre point) is used (falling back on then the first monitor showing part of the window then the first monitor).If
index=-1then all monitors are treated as one large virtual monitor.(
indexparameter available from 0.46) - +ve
-
set_window_position2(int xpos, int ypos, [int index])Set the position of a window. Parameters are as for
set_window_position.This function uses
XMoveWindowinstead ofwnck_window_set_geometry; this gives a slightly different result.(Available from version 0.21,
indexfrom 0.46) -
set_window_property(string property, int-or-string value, [bool utf8])Set a property of a window to a string or a cardinal (32-bit integer or boolean).
Optionally takes a boolean to indicate
UTF8_STRINGproperties. The default is initiallyfalseand can be set viause_utf8(). Ignored for non-string values.(Available from version 0.44; UTF-8 option available from version 0.45.)
-
delete_window_property(string property)Remove a property from a window.
(Available from version 0.44)
-
set_window_size(int width, int height)Set the size of a window.
-
set_window_geometry(int xpos, int ypos, int width, int height, [int index])Set both size and position of a window in one command.
The
indexparameter works exactly as forset_window_position()and affects the given coordinates in the same way.(
indexparameter available from 0.46) -
set_window_geometry2(int xpos, int ypos, int width, int height, [int index])Set the window geometry as for
set_window_geometry(), but usingXMoveResizeWindowinstead of its libwnck alternative. This may result in different coordinates, more like the original devilspie geometry function.(Available from version 0.21;
indexfrom 0.46) -
“Shade” a window, showing only the title-bar.
-
Unshade a window; the opposite of
shade(). -
Maximise a window.
(-
isefrom 0.45) -
Unmaximise a window.
(-
isefrom 0.45) -
Maximise the current window vertically.
(-
isefrom 0.45) -
Maximise the current window horizontally.
(-
isefrom 0.45) -
Minimise a window.
(-
isefrom 0.45) -
Unminimise a window: brings it back to screen from the minimised position/size.
(-
isefrom 0.45) -
Show all (relevant) window decoration.
-
Hide all window decoration.
-
Close the window.
(Available from 0.31)
-
set_window_workspace(int-or-string workspace)Move a window to another workspace. Indicated as a 1-based number or a workspace name.
-
change_workspace(int-or-string workspace)Change the current workspace to another. Indicated as a 1-based number or a workspace name.
-
Ask the window manager to put the window on all workspaces.
-
Ask the window manager to put window only in the currently active workspace.
-
Ask the window manager to keep the window's position fixed on the screen, even when the workspace or viewport scrolls.
-
Ask the window manager not to have window's position fixed on the screen when the workspace or viewport scrolls.
-
Set this to
trueif you would like the window to skip listing in your tasklist, orfalseif not.(Available from version 0.16)
-
Set this to
trueif you would like the window to skip listing in your pager, orfalseif not.(Available from version 0.16)
-
set_window_above([bool above = true])Set the current window “always on top” (moves it to the top layer, above most windows) or, if
above=false, clears “always on top” and “always below” (moves it to the middle, default, layer).(Available from version 0.21)
-
set_window_below([bool below = true])Set the current window “always below” (moves it to the bottom layer, below most windows) or, if
below=false, clears “always on top” and “always below” (moves it to the middle, default, layer).(Available from version 0.21)
-
Raise the window to the top of its layer.
(Prior to version 0.45, this was the same as
set_window_above.) -
Lower a window to the bottom of its layer.
(Available from version 0.45.)
-
set_window_fullscreen(bool fullscreen)Ask the window manager to set or clear the fullscreen state of the window according to
fullscreen.(Available from version 0.24)
-
set_viewport(int viewport) -
With one parameter, move the window to the requested viewport. Counting starts at 1.
(Available from version 0.25)
With two parameters, move the window to the requested position within the viewport.
(Available from version 0.40)
-
centre([int index = -1,] [string direction = nil])Centre the window on one monitor or across all monitors, according to the following rules:
-
If
index=-1, all monitors are treated as one large virtual monitor. -
If
index=0, the ‘current’ monitor (with the window's centre point) is used (falling back on then the first monitor showing part of the window then the first monitor); -
If
indexis out of range then the first monitor is used. -
Otherwise, the window is centred on the specified monitor.
-
If
directionbegins withHorh, the window is horizontally centred only. -
If
directionbegins withVorv, the window is vertically centred only. -
Otherwise it is centred along both axes.
If centring only along one axis, the window may be moved along the other axis to ensure that it is on the specified monitor.
(Available from version 0.40; as
centerand without parameters from 0.26) -
-
set_window_opacity(float value)Set the window opacity to the given fractional value.
1.0is completely opaque,0.0is completely transparent.(Available from version 0.29; as
set_opacityfrom 0.28) -
Set the window type, according to
_NET_WM_WINDOW_TYPE. The allowed types are the standard_NET_WMones (formatted as a string):_NET_WM_WINDOW_TYPE_DESKTOP_NET_WM_WINDOW_TYPE_DOCK_NET_WM_WINDOW_TYPE_TOOLBAR_NET_WM_WINDOW_TYPE_MENU_NET_WM_WINDOW_TYPE_UTILITY_NET_WM_WINDOW_TYPE_SPLASH_NET_WM_WINDOW_TYPE_DIALOG_NET_WM_WINDOW_TYPE_NORMAL
You may omit
_NET_WM_.(Available from version 0.28)
-
Focus the current window.
(Available from version 0.30)
-
set_window_strut(int left, int right, int top, int bottom, int ...)Set the reserved area at the borders of the desktop for a docking area such as a taskbar or a panel. Will handle up to 12 values.
Default minimum values are 0 and default maximum values are taken from the screen size (current or maximum, depending on whether
xrandris used).(Available from version 0.32)
-
Get the reserved area at the borders of the desktop for a docking area such as a taskbar or a panel.
Returns a table (12 integers as for
_NET_WM_WINDOW_STRUT_PARTIAL) ornil. If_NET_WM_WINDOW_STRUTwas read then defaults are used as forset_window_strut().(Available from version 0.45)
-
With parameters, set the position of a window.
Without, returns the position of a window.
-
xywh([int x, int y, int w, int h])With parameters, set the position and size of a window.
Without, returns the position and size of a window.
-
Controls whether string-setting functions assume UTF-8 by default. If no value is supplied, the setting is left unchanged. Returns the previous value.
This is initially
false.(Available from version 0.45)
-
Sleep for a number of milliseconds, between 1 and 1000 (1 second).
This is a convenience function so that you don't have to use
os.execute(to runsleep) or (from LuaPosixposix.time)nanosleep.(Available from version 0.46)
get_window_is_maximizedget_window_is_maximized_verticallyget_window_is_maximized_horizontallyget_fullscreenmaximizeunmaximizemaximize_verticallymaximize_horizontallyminimizeunminimizecenterset_opacityfocus
Showing debug output and resizing and maximisation of specific windows:
-- the debug_print command only prints to stdout
-- if devilspie2 is run using the '--debug' option
debug_print("Window name: " .. get_window_name());
debug_print("Application name: " .. get_application_name())
-- I want my Xfce4 terminal to the right on the second screen (1080p) of my
-- two-monitor setup.
-- Note that this rule will only work with the window's initial title.
if (get_window_name() == "Terminal") then
set_window_position(1300, 200, 2)
set_window_size(600, 800)
end
-- Make Firefox always start maximised.
if (get_application_name() == "Firefox") then
maximise() -- maximize() for compatibility with <0.45
endShowing handling of conflict between devilspie2 and other programs (in this case,
emacs):
This example uses millisleep to enforce a short delay.
-- Make Emacs (emacs or emacs-gtk) always start maximised.
win_class = get_class_instance_name()
debug_print("Window class: " .. win_class)
if win_class == "emacs" or win_class == "Emacs" then
-- Emacs applies default window size etc. after a brief delay,
-- potentially overriding devilspie2.
--
-- A brief pause (here, of 0.1s) ensures that devilspie2's actions on the
-- window take effect after Emacs completes its initialisation. A shorter
-- pause may work, or a longer one may be needed. Experiment! Could be
-- that 'millisleep(10)' (0.01s) works well on one PC…?
--
-- If you prefer, you can have Emacs maximise its window (as in this
-- example) via one of its configuration files - early-init.el, which is
-- normally faster (and avoids a possible visual effect), or init.el –
-- using this LISP statement:
-- (push '(fullscreen . maximized) default-frame-alist)
--
-- 'millisleep' is new to 0.46. The 0.1s delay for older versions:
-- option 1:
-- os.execute("sleep 0.1")
-- option 2 (needs luaposix):
-- nanosleep = require "posix.time".nanosleep
-- nanosleep{tv_nsec=100e6}
millisleep(100)
maximise() -- maximize() for compatibility with <0.45
enddevilspie2 is translatable using gettext - see
README.translators.md for more information.
See AUTHORS.
-
Homepage: http://www.nongnu.org/devilspie2
-
Contact / Mailing list: devilspie2-discuss@nongnu.org, https://lists.nongnu.org/mailman/listinfo/devilspie2-discuss
-
See also: https://github.com/dsalt/devilspie
-
IRC: irc://irc.libera.chat/#devilspie2