I'm using devilspie2 (version 0.45) along with XFCE on Void Linux to auto position my programs as they open, but recently I noticed that devilspie2 sometimes crashes. It occurs more clearly when devilspie2 starts and there are already some window to position (tested with firefox and libreoffice). I initialezed devilspie2 with --debug flag and it returned the following error:
$ devilspie2 --debug
Rodando devilspie2 em modo debug.
Usando scripts do diretório: /home/epsm/.config/devilspie2
------------
Lista de arquivos Lua de manipulação de eventos "window_open" no diretório:
/home/epsm/.config/devilspie2/devilspie2.lua
Lista de arquivos Lua de manipulação de eventos "window_close" no diretório:
/home/epsm/.config/devilspie2/close/init.lua
Lista de arquivos Lua de manipulação de eventos "window_focus" no diretório:
/home/epsm/.config/devilspie2/focus/init.lua
Lista de arquivos Lua de manipulação de eventos "window_blur" no diretório:
/home/epsm/.config/devilspie2/blur/init.lua
Lista de arquivos Lua de manipulação de eventos "window_name_change" no diretório:
------------
Win name: Somesite — Mozilla Firefox
Proc name: firefox
loadScripts : /home/epsm/.config/devilspie2/open/dbeaver.lua
loadScripts : /home/epsm/.config/devilspie2/open/feh.lua
loadScripts : /home/epsm/.config/devilspie2/open/firefox.lua
(devilspie2:21356): Gdk-WARNING **: 13:34:25.752: The program 'devilspie2' received an X Window System error.
This probably reflects a bug in the program.
The error was 'BadMatch (invalid parameter attributes)'.
(Details: serial 351 error_code 8 request_code 18 (core protocol) minor_code 0)
(Note to programmers: normally, X errors are reported asynchronously;
that is, you will receive the error a while after causing it.
To debug your program, run it with the GDK_SYNCHRONIZE environment
variable to change this behavior. You can then get a meaningful
backtrace from your debugger if you break on the gdk_x_error() function.)
Although I've observed this behavior on devilpie2 initialization, it can also occurs after some time it successfully started. Let's say I boot my PC, devilspie2 starts and there are no windows to position, it works during some random time and then it crashes.
This is my .config/devilspie2/ directory structure:
$ tree --dirsfirst .
.
├── blur
│ └── init.lua
├── close
│ └── init.lua
├── focus
│ └── init.lua
├── open
│ ├── dbeaver.lua
│ ├── feh.lua
│ ├── firefox.lua
│ ├── init.lua
│ ├── kitty.lua
│ ├── lazarus.lua
│ ├── libreoffice.lua
│ ├── telegram.lua
│ ├── thunar.lua
│ ├── virtmanager.lua
│ ├── xfce4-terminal.lua
│ └── zathura.lua
└── devilspie2.lua
This is the devilspie2.lua contents:
function loadScripts(directory)
local pfile = io.popen("ls " .. directory)
for file in pfile:lines() do
if (file ~= "init.lua") and (file:sub(-4) ~= ".bar") then
debug_print("loadScripts : " .. directory .. file)
dofile(directory .. file)
end
end
end
local dir = debug.getinfo(1).short_src:gsub("(%g*/)(%g*)", "%1")
open_scripts_dir = dir .. 'open/'
close_scripts_dir = dir .. 'close/'
focus_scripts_dir = dir .. 'focus/'
blur_scripts_dir = dir .. 'blur/'
screen_w, screen_h = get_screen_geometry()
dofile(open_scripts_dir .. 'init.lua')
scripts_window_close = {
"close/init.lua"
}
scripts_window_focus = {
"focus/init.lua"
}
scripts_window_blur = {
"blur/init.lua"
}
And this is the open/init.lua:
win_name = get_window_name()
proc_name = get_process_name()
debug_print(
"\nWin name: " .. win_name ..
"\nProc name: " .. proc_name)
loadScripts(open_scripts_dir)
And each application has its configuration on how to be positioned, like firefox.lua:
if (proc_name == "firefox") then
set_window_workspace(2)
change_workspace(2)
maximize()
focus()
end
That being said, I think my configuration setup is ok and I have no clue why this is happening. So I asked for it on gemini which (after a lot of interventions) suggested removing that focus() function, because of the X11 asynchronous nature, it maybe had not completed change_workspace(2) when firing focus() function. This suggestion worked, and that error did not happen when starting devilspie2 with firefox/libreoffice opened.
Then I asked to deepseek:
===== Begining of deepseek response =====
The X error you’re seeing:
request_code 18 (core protocol) minor_code 0
is an XChangeProperty request. In devilspie2 0.45, set_window_workspace() is very likely implemented by directly writing the _NET_WM_DESKTOP property with XChangeProperty.
When a window already exists before devilspie2 starts, XFCE/xfwm4 has already created/managed that property on the window. Devilspie2 then tries to change it directly, and the X server returns BadMatch, which kills devilspie2. That matches why it happens more clearly when Firefox/LibreOffice are already open at startup.
Proper fix
If you are comfortable rebuilding devilspie2 from source, the correct EWMH behavior for set_window_workspace() is to send a _NET_WM_DESKTOP client message to the root window, not to call XChangeProperty directly.
The relevant C code in devilspie2 probably looks like this:
XChangeProperty(display, win, net_wm_desktop, XA_CARDINAL, 32,
PropModeReplace, (unsigned char *)&desktop, 1);
A fixed version would use something like:
XEvent e = {0};
e.xclient.type = ClientMessage;
e.xclient.window = win;
e.xclient.message_type = net_wm_desktop;
e.xclient.format = 32;
e.xclient.data.l[0] = desktop;
e.xclient.data.l[1] = CurrentTime;
XSendEvent(display, DefaultRootWindow(display), False,
SubstructureRedirectMask | SubstructureNotifyMask, &e);
XFlush(display);
That avoids the direct property write and the BadMatch race/collision with xfwm4.
If you want to confirm exactly which call is crashing, run devilspie2 like this:
GDK_SYNCHRONIZE=1 devilspie2 --debug
or add temporary debug_print("before set_window_workspace"), debug_print("after set_window_workspace"), etc. around the calls in firefox.lua. But based on the X error, set_window_workspace() is the main suspect.
=== Another prompt, after stating that removing focus() function devilspie2 worked as usually
You’ve found the culprit: focus() is also implemented with a direct X call that triggers the same BadMatch error when the window is already managed by XFCE/xfwm4.
The X error you’re seeing (request_code 18, which is XChangeProperty) happens because devilspie2 is trying to change an X property (likely _NET_ACTIVE_WINDOW) directly on a window that’s already under the window manager’s control. That’s an invalid operation under EWMH and causes the X server to kill devilspie2.
Proper fix (optional, for source builds)
If you are comfortable compiling devilspie2 yourself, the correct way to implement set_window_workspace and focus is to send EWMH client messages to the root window instead of using XChangeProperty or XSetInputFocus directly. The proper messages are:
_NET_WM_DESKTOP for workspace changes
_NET_ACTIVE_WINDOW for focus changes
The direct XChangeProperty approach is racy and will always risk BadMatch when the window manager is already managing the window.
===== Ending of deepseek response ======
I'm sorry I could not evaluate that response before posting here, since I do not have enough skill on c programming and compiling. But I hope it help to enlighten the path to solve this bug.
I'm using devilspie2 (version 0.45) along with XFCE on Void Linux to auto position my programs as they open, but recently I noticed that devilspie2 sometimes crashes. It occurs more clearly when devilspie2 starts and there are already some window to position (tested with firefox and libreoffice). I initialezed devilspie2 with --debug flag and it returned the following error:
Although I've observed this behavior on devilpie2 initialization, it can also occurs after some time it successfully started. Let's say I boot my PC, devilspie2 starts and there are no windows to position, it works during some random time and then it crashes.
This is my .config/devilspie2/ directory structure:
This is the devilspie2.lua contents:
And this is the open/init.lua:
And each application has its configuration on how to be positioned, like firefox.lua:
That being said, I think my configuration setup is ok and I have no clue why this is happening. So I asked for it on gemini which (after a lot of interventions) suggested removing that focus() function, because of the X11 asynchronous nature, it maybe had not completed change_workspace(2) when firing focus() function. This suggestion worked, and that error did not happen when starting devilspie2 with firefox/libreoffice opened.
Then I asked to deepseek:
===== Begining of deepseek response =====
The X error you’re seeing:
is an
XChangePropertyrequest. Indevilspie2 0.45,set_window_workspace()is very likely implemented by directly writing the_NET_WM_DESKTOPproperty withXChangeProperty.When a window already exists before devilspie2 starts, XFCE/xfwm4 has already created/managed that property on the window. Devilspie2 then tries to change it directly, and the X server returns
BadMatch, which kills devilspie2. That matches why it happens more clearly when Firefox/LibreOffice are already open at startup.Proper fix
If you are comfortable rebuilding devilspie2 from source, the correct EWMH behavior for
set_window_workspace()is to send a_NET_WM_DESKTOPclient message to the root window, not to callXChangePropertydirectly.The relevant C code in devilspie2 probably looks like this:
A fixed version would use something like:
That avoids the direct property write and the
BadMatchrace/collision with xfwm4.If you want to confirm exactly which call is crashing, run devilspie2 like this:
or add temporary
debug_print("before set_window_workspace"),debug_print("after set_window_workspace"), etc. around the calls infirefox.lua. But based on the X error,set_window_workspace()is the main suspect.=== Another prompt, after stating that removing focus() function devilspie2 worked as usually
You’ve found the culprit:
focus()is also implemented with a direct X call that triggers the sameBadMatcherror when the window is already managed by XFCE/xfwm4.The X error you’re seeing (
request_code 18, which isXChangeProperty) happens becausedevilspie2is trying to change an X property (likely_NET_ACTIVE_WINDOW) directly on a window that’s already under the window manager’s control. That’s an invalid operation under EWMH and causes the X server to killdevilspie2.Proper fix (optional, for source builds)
If you are comfortable compiling
devilspie2yourself, the correct way to implementset_window_workspaceandfocusis to send EWMH client messages to the root window instead of usingXChangePropertyorXSetInputFocusdirectly. The proper messages are:_NET_WM_DESKTOPfor workspace changes_NET_ACTIVE_WINDOWfor focus changesThe direct
XChangePropertyapproach is racy and will always riskBadMatchwhen the window manager is already managing the window.===== Ending of deepseek response ======
I'm sorry I could not evaluate that response before posting here, since I do not have enough skill on c programming and compiling. But I hope it help to enlighten the path to solve this bug.