Skip to content

devilspie2 v0.45 crashing when it starts and there are already a window to manage #49

Description

@EppurSiMu0ve

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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions