diff options
author | Mathias Gumz <akira at fluxbox dot org> | 2013-01-31 08:13:45 (GMT) |
---|---|---|
committer | Mathias Gumz <akira at fluxbox dot org> | 2013-01-31 08:14:06 (GMT) |
commit | dc47491533e0ca7cf5a5386a10e68fbaf873e9db (patch) | |
tree | 4ee0c68722207189912a106d3f77e9cab52e65a8 /util | |
parent | 716532dd47d718cb548da5f65b53a8b744ce235f (diff) | |
download | fluxbox-dc47491533e0ca7cf5a5386a10e68fbaf873e9db.zip fluxbox-dc47491533e0ca7cf5a5386a10e68fbaf873e9db.tar.bz2 |
Adds 'ClientPatternTest' command
ClientPatterns might be tricky to get right. Instead of fiddling around in
either the keys-file or the apps-file and restarting fluxbox to see if the
changes had any effect / matched the right windows, 'ClientPatternTest' and
the fluxbox-remote should make this easier:
$> fluxbox-remote "clientpatterntest (title=.*vim*)"
This causes fluxbox to store the list of matched windows in the
_FLUXBOX_ACTION_RESULT property onto the rootwindow. This property might
then be read by:
$> xprop -root _FLUXBOX_ACTION_RESULT
or
$> fluxbox-remote result
The format of the list is:
win_id \t title_of_window \n
win_id is '-1' when fluxbox wasn't able to parse the given ClientPattern.
win_id is '0' when there are no windows matching the given ClientPattern.
Diffstat (limited to 'util')
-rw-r--r-- | util/fluxbox-remote.cc | 61 |
1 files changed, 44 insertions, 17 deletions
diff --git a/util/fluxbox-remote.cc b/util/fluxbox-remote.cc index 5c66583..340ac5b 100644 --- a/util/fluxbox-remote.cc +++ b/util/fluxbox-remote.cc | |||
@@ -21,50 +21,77 @@ | |||
21 | 21 | ||
22 | #include <X11/Xlib.h> | 22 | #include <X11/Xlib.h> |
23 | #include <X11/Xatom.h> | 23 | #include <X11/Xatom.h> |
24 | #include <X11/Xutil.h> | ||
24 | #include <string.h> | 25 | #include <string.h> |
25 | #include <stdlib.h> | 26 | #include <stdlib.h> |
26 | #include <stdio.h> | 27 | #include <stdio.h> |
27 | 28 | ||
28 | bool g_gotError; | 29 | |
30 | bool g_gotError = false; | ||
29 | static int HandleIPCError(Display *disp, XErrorEvent*ptr) | 31 | static int HandleIPCError(Display *disp, XErrorEvent*ptr) |
30 | { | 32 | { |
31 | // ptr->error_code contains the actual error flags | 33 | // ptr->error_code contains the actual error flags |
32 | g_gotError=true; | 34 | g_gotError = true; |
33 | return( 0 ); | 35 | return( 0 ); |
34 | } | 36 | } |
35 | 37 | ||
38 | typedef int (*xerror_cb_t)(Display*,XErrorEvent*); | ||
39 | |||
40 | |||
36 | int main(int argc, char **argv) { | 41 | int main(int argc, char **argv) { |
37 | 42 | ||
43 | int rc; | ||
44 | Display* disp; | ||
45 | Window root; | ||
46 | Atom atom_utf8; | ||
47 | Atom atom_fbcmd; | ||
48 | Atom atom_result; | ||
49 | xerror_cb_t error_cb; | ||
50 | char* cmd; | ||
51 | |||
38 | if (argc <= 1) { | 52 | if (argc <= 1) { |
39 | printf("fluxbox-remote <fluxbox-command>\n"); | 53 | printf("fluxbox-remote <fluxbox-command>\n"); |
40 | return EXIT_SUCCESS; | 54 | return EXIT_SUCCESS; |
41 | } | 55 | } |
42 | 56 | ||
43 | Display *disp = XOpenDisplay(NULL); | 57 | disp = XOpenDisplay(NULL); |
44 | if (!disp) { | 58 | if (!disp) { |
45 | perror("error, can't open display."); | 59 | perror("error, can't open display."); |
46 | return EXIT_FAILURE; | 60 | return rc; |
47 | } | 61 | } |
48 | 62 | ||
49 | Atom fbcmd_atom = XInternAtom(disp, "_FLUXBOX_ACTION", False); | 63 | cmd = argv[1]; |
50 | Window root = DefaultRootWindow(disp); | 64 | atom_utf8 = XInternAtom(disp, "UTF8_STRING", False); |
65 | atom_fbcmd = XInternAtom(disp, "_FLUXBOX_ACTION", False); | ||
66 | atom_result = XInternAtom(disp, "_FLUXBOX_ACTION_RESULT", False); | ||
67 | root = DefaultRootWindow(disp); | ||
51 | 68 | ||
52 | char *str = argv[1]; | 69 | // assign the custom handler, clear the flag, sync the data, |
70 | // then check it for success/failure | ||
71 | error_cb = XSetErrorHandler(HandleIPCError); | ||
53 | 72 | ||
54 | typedef int (*x_error_handler_t)(Display*,XErrorEvent*); | ||
55 | 73 | ||
56 | // assign the custom handler, clear the flag, sync the data, then check it for success/failure | 74 | if (strcmp(cmd, "result") == 0) { |
57 | x_error_handler_t handler = XSetErrorHandler( HandleIPCError ); | 75 | XTextProperty text_prop; |
58 | g_gotError=false; | 76 | if (XGetTextProperty(disp, root, &text_prop, atom_result) != 0 |
59 | XChangeProperty(disp, root, fbcmd_atom, | 77 | && text_prop.value > 0 |
78 | && text_prop.nitems > 0) { | ||
79 | |||
80 | printf("%s", text_prop.value); | ||
81 | XFree(text_prop.value); | ||
82 | } | ||
83 | } else { | ||
84 | XChangeProperty(disp, root, atom_fbcmd, | ||
60 | XA_STRING, 8, PropModeReplace, | 85 | XA_STRING, 8, PropModeReplace, |
61 | (unsigned char *) str, strlen(str)); | 86 | (unsigned char *)cmd, strlen(cmd)); |
62 | XSync(disp,False); | 87 | XSync(disp, false); |
63 | int ret=(g_gotError?EXIT_FAILURE:EXIT_SUCCESS); | 88 | } |
64 | XSetErrorHandler(handler); | 89 | |
90 | rc = (g_gotError ? EXIT_FAILURE : EXIT_SUCCESS); | ||
65 | 91 | ||
92 | XSetErrorHandler(error_cb); | ||
66 | XCloseDisplay(disp); | 93 | XCloseDisplay(disp); |
67 | 94 | ||
68 | return ret; | 95 | return rc; |
69 | } | 96 | } |
70 | 97 | ||