commit e2b5659eb4c42162b847d5a9f87c23b845e5849a
parent 07595089fee6aac5953af8acb2f2e98682fa03d5
Author: Bastien Dejean <nihilhill@gmail.com>
Date: Mon, 6 Apr 2015 08:54:17 +0200
Provide a notation for synchronous execution
If a command starts with a semicolon it will be executed synchronously.
We need this for the *bspwm* pointer interactions: if we send the
grabbing message asynchronously, *bspwm* might not see the window below
the pointer because the pointer might have moved outside of the window
while the message was being transmitted.
Diffstat:
7 files changed, 35 insertions(+), 19 deletions(-)
diff --git a/doc/sxhkd.1 b/doc/sxhkd.1
@@ -2,12 +2,12 @@
.\" Title: sxhkd
.\" Author: [see the "Author" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\" Date: 04/05/2015
+.\" Date: 04/06/2015
.\" Manual: Sxhkd Manual
.\" Source: Sxhkd 0.5.5
.\" Language: English
.\"
-.TH "SXHKD" "1" "04/05/2015" "Sxhkd 0\&.5\&.5" "Sxhkd Manual"
+.TH "SXHKD" "1" "04/06/2015" "Sxhkd 0\&.5\&.5" "Sxhkd Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
@@ -168,6 +168,8 @@ When multiple chords are separated by semicolons, the hotkey is a chord chain: t
.sp
The colon character can be used instead of the semicolon to indicate that the chord chain shall not be aborted when the chain tail is reached\&.
.sp
+If a command starts with a semicolon, it will be executed synchronously, otherwise asynchronously\&.
+.sp
The \fIEscape\fR key can be used to abort a chord chain\&.
.sp
If \fB@\fR is added at the beginning of the keysym, the command will be run on key release events, otherwise on key press events\&.
@@ -212,7 +214,7 @@ super + {alt,ctrl,alt + ctrl} + XF86Eject
bspc pointer \-g focus
super + button{1\-3}
- bspc pointer \-g {move,resize_side,resize_corner}
+ ; bspc pointer \-g {move,resize_side,resize_corner}
super + @button{1\-3}
bspc pointer \-u
diff --git a/doc/sxhkd.1.txt b/doc/sxhkd.1.txt
@@ -102,6 +102,8 @@ When multiple chords are separated by semicolons, the hotkey is a chord chain: t
The colon character can be used instead of the semicolon to indicate that the chord chain shall not be aborted when the chain tail is reached.
+If a command starts with a semicolon, it will be executed synchronously, otherwise asynchronously.
+
The _Escape_ key can be used to abort a chord chain.
If *@* is added at the beginning of the keysym, the command will be run on key release events, otherwise on key press events.
@@ -146,7 +148,7 @@ super + {alt,ctrl,alt + ctrl} + XF86Eject
bspc pointer -g focus
super + button{1-3}
- bspc pointer -g {move,resize_side,resize_corner}
+ ; bspc pointer -g {move,resize_side,resize_corner}
super + @button{1-3}
bspc pointer -u
diff --git a/helpers.c b/helpers.c
@@ -50,29 +50,38 @@ void err(char *fmt, ...)
exit(EXIT_FAILURE);
}
-void spawn(char *cmd[])
+void run(char *command, bool sync)
+{
+ char *cmd[] = {shell, "-c", command, NULL};
+ spawn(cmd, sync);
+}
+
+void spawn(char *cmd[], bool sync)
{
if (fork() == 0) {
if (dpy != NULL)
close(xcb_get_file_descriptor(dpy));
- if (fork() == 0) {
- setsid();
- if (redir_fd != -1) {
- dup2(redir_fd, STDOUT_FILENO);
- dup2(redir_fd, STDERR_FILENO);
+ if (sync) {
+ execute(cmd);
+ } else {
+ if (fork() == 0) {
+ execute(cmd);
}
- execvp(cmd[0], cmd);
- err("Spawning failed.\n");
+ exit(EXIT_SUCCESS);
}
- exit(EXIT_SUCCESS);
}
wait(NULL);
}
-void run(char *command)
+void execute(char *cmd[])
{
- char *cmd[] = {shell, "-c", command, NULL};
- spawn(cmd);
+ setsid();
+ if (redir_fd != -1) {
+ dup2(redir_fd, STDOUT_FILENO);
+ dup2(redir_fd, STDERR_FILENO);
+ }
+ execvp(cmd[0], cmd);
+ err("Spawning failed.\n");
}
char *lgraph(char *s)
diff --git a/helpers.h b/helpers.h
@@ -39,8 +39,9 @@
void warn(char *fmt, ...);
__attribute__((noreturn))
void err(char *fmt, ...);
-void spawn(char *cmd[]);
-void run(char *command);
+void execute(char *cmd[]);
+void spawn(char *cmd[], bool sync);
+void run(char *command, bool sync);
char *lgraph(char *s);
char *rgraph(char *s);
diff --git a/sxhkd.c b/sxhkd.c
@@ -233,7 +233,7 @@ void key_button_event(xcb_generic_event_t *evt, uint8_t event_type)
if (keysym != XCB_NO_SYMBOL || button != XCB_NONE) {
hotkey_t *hk = find_hotkey(keysym, button, modfield, event_type, &replay_event);
if (hk != NULL) {
- run(hk->command);
+ run(hk->command, hk->sync);
if (status_fifo != NULL)
put_status(COMMAND_PREFIX, hk->command);
}
diff --git a/types.c b/types.c
@@ -194,6 +194,7 @@ hotkey_t *make_hotkey(chain_t *chain, char *command)
hotkey_t *hk = malloc(sizeof(hotkey_t));
hk->chain = chain;
snprintf(hk->command, sizeof(hk->command), "%s", command);
+ hk->sync = (command[0] == ';');
hk->cycle = NULL;
hk->next = hk->prev = NULL;
return hk;
diff --git a/types.h b/types.h
@@ -61,6 +61,7 @@ typedef struct hotkey_t hotkey_t;
struct hotkey_t {
chain_t *chain;
char command[2 * MAXLEN];
+ bool sync;
cycle_t *cycle;
hotkey_t *next;
hotkey_t *prev;