[Pkg-wmaker-commits] [wmix] 27/44: wmix: added error catch for XGrabKey on multimedia keys
Doug Torrance
dtorrance-guest at moszumanska.debian.org
Fri Sep 29 10:40:14 UTC 2017
This is an automated email from the git hooks/post-receive script.
dtorrance-guest pushed a commit to branch upstream
in repository wmix.
commit ebd2223d5615d1e726828d3230ae43d8f69c80b1
Author: Christophe CURIS <christophe.curis at free.fr>
Date: Sat Jun 7 21:21:55 2014 +0200
wmix: added error catch for XGrabKey on multimedia keys
If another application has already set a grab on these keys then the call
would fail (BadAccess) and wmix stop. With the X error handler, we can
display a warning to user and continue anyway.
Signed-off-by: Christophe CURIS <christophe.curis at free.fr>
---
mmkeys.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
wmix.1x | 4 ++++
2 files changed, 59 insertions(+)
diff --git a/mmkeys.c b/mmkeys.c
index bc22625..2dae788 100644
--- a/mmkeys.c
+++ b/mmkeys.c
@@ -23,6 +23,7 @@
#include <string.h>
#include <X11/Xlib.h>
+#include <X11/Xproto.h>
#include <X11/keysym.h>
#include <X11/XF86keysym.h>
@@ -59,8 +60,19 @@ typedef struct {
unsigned int list[1 << lengthof(modifier_symbol)];
} modifier_masks;
+/* The structure to track grab installation for errors */
+static struct mmkey_track {
+ XErrorHandler previous_handler;
+ struct {
+ const char *key_name;
+ unsigned long serial[1 << lengthof(modifier_symbol)];
+ Bool displayed;
+ } request[lengthof(key_list)];
+} *track_install = NULL;
+
/* Local functions */
static void mmkey_build_modifier_list(Display *display, modifier_masks *result);
+static int mmkey_catch_grab_error(Display *display, XErrorEvent *event);
/*
@@ -73,6 +85,7 @@ static void mmkey_build_modifier_list(Display *display, modifier_masks *result);
void mmkey_install(Display *display)
{
modifier_masks mod_masks;
+ struct mmkey_track install_info;
Window root_window;
int i, j;
@@ -80,6 +93,9 @@ void mmkey_install(Display *display)
root_window = DefaultRootWindow(display);
+ memset(&install_info, 0, sizeof(install_info));
+ install_info.previous_handler = XSetErrorHandler(mmkey_catch_grab_error);
+ track_install = &install_info;
for (i = 0; i < lengthof(key_list); i++) {
KeyCode key;
@@ -89,13 +105,21 @@ void mmkey_install(Display *display)
if (key == None)
continue;
+ install_info.request[i].key_name = key_list[i].name;
+ install_info.request[i].displayed = False;
for (j = 0; j < mod_masks.count; j++) {
+ install_info.request[i].serial[j] = NextRequest(display);
XGrabKey(display, key, mod_masks.list[j], root_window,
False, GrabModeAsync, GrabModeAsync);
}
if (config.verbose)
printf("Found multimedia key: %s\n", key_list[i].name);
}
+
+ /* The grab may fail, so make sure it is reported now */
+ XSync(display, False);
+ XSetErrorHandler(install_info.previous_handler);
+ track_install = NULL;
}
/*
@@ -166,3 +190,34 @@ static void mmkey_build_modifier_list(Display *display, modifier_masks *result)
}
}
}
+
+/*
+ * Callback when X11 reports an error
+ *
+ * We only track errors from XGrabKey and display them to user, instead of
+ * letting the default error handler exit
+ */
+static int mmkey_catch_grab_error(Display *display, XErrorEvent *event)
+{
+ int i, j;
+
+ if ((event->error_code == BadAccess) && (event->request_code == X_GrabKey)) {
+ for (i = 0; i < lengthof(track_install->request); i++) {
+ for (j = 0; j < lengthof(track_install->request[i].serial); j++) {
+ if (track_install->request[i].serial[j] == 0L)
+ break;
+ if (event->serial == track_install->request[i].serial[j]) {
+ if (!track_install->request[i].displayed) {
+ fprintf(stderr, "wmix:warning: could not grab key %s, is another application using it?\n",
+ track_install->request[i].key_name);
+ track_install->request[i].displayed = True;
+ }
+ return 0;
+ }
+ }
+ }
+ }
+
+ /* That's not an XGrabKey known issue, let the default handler manage this */
+ return track_install->previous_handler(display, event);
+}
diff --git a/wmix.1x b/wmix.1x
index 117f42e..8e4cf68 100644
--- a/wmix.1x
+++ b/wmix.1x
@@ -134,6 +134,10 @@ if you have other application controlling the volume, and possibly
implementing mute in similar ways, because there is no way to know
that a channel has been muted.
.LP
+The X server allows only one application at a time to place a grab on a key,
+so if another application already claimed the volume control keys then \fBwmix\fP
+will warn you about it and continue without the functionality.
+.LP
If you modify the configuration file, do not expect \fBwmix\fP to reload
it automatically, this is considered a too costly feature for such a
small application.
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-wmaker/wmix.git
More information about the Pkg-wmaker-commits
mailing list