Patching X11::GUITest
The Problem
I'm automating my X11 desktop and watch for windows with certain titles. But
sometimes X11::GUITest doesn't find a given window anymore and then xlib
takes the complete Perl process with it because X11::GUITest doesn't install
the appropriate error handler for missing windows or windows without window
decoration.
Error message:
X Error of failed request: BadWindow (invalid Window parameter)
Major opcode of failed request: 15 (X_QueryTree)
Resource id in failed request: 0x0
Serial number of failed request: 22767
Current serial number in output stream: 22767
To debug this, I first need a way to somewhat reliably reproduce the problem. It seems that Steam is a good candidate, so I'll (re)launch it. It turns out that merely switching to the Steam window is enough.
I have a short Perl program that runs the query every second:
#!perl
use strict;
use warnings;
use X11::GUITest qw(GetInputFocus GetWindowName GetParentWindow);
sub get_named_focus_window {
my $win = GetInputFocus();
my $name;
# We return undef if the window has gone away
eval {
do {
$name = GetWindowName($win);
unless ($name) {
$win = GetParentWindow($win);
}
} until $name or ($win == 0);
};
return $win
}
while(1) {
get_named_focus_window();
}
Patching the repository
The link to the repository of X11::GUITest is now at http://svn.code.sf.net/p/x11guitest/code/trunk/ due to some internal shuffling by Sourceforge... Instead of using the CPAN tarballs for patching, I will try to use the SVN repository. This takes substantially longer to clone at 1 second per revision but I can wait the 248 seconds.
Submitting the patch via SVN means we also can't use the convenience of
git format-patch
maybe but we'll find that out shortly.
The fix itself is fairly trivial. My test program shows me that the problem
occurs whenever I call GetParentWindow()
while the Steam window is active,
so I add the appropriate guard around the call:
CODE:
RETVAL = 0;
+ OldErrorHandler = XSetErrorHandler(IgnoreBadWindow);
if (XQueryTree(TheXDisplay, win, &root, &parent, &children, &childcount)) {
XFree(children);
RETVAL = parent;
}
+ XSetErrorHandler(OldErrorHandler);
OUTPUT:
The bug report and patch are on rt.cpan.org now at RT ticket 139373