Skip to content

Commit b4db1bf

Browse files
committed
implement --aftermodifiers for all commands that accept --clearmodifiers, and add it to the manpage
1 parent 8337cf9 commit b4db1bf

File tree

10 files changed

+124
-22
lines changed

10 files changed

+124
-22
lines changed

cmd_click.c

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ int cmd_click(context_t *context) {
66
char *cmd = context->argv[0];
77
int ret = 0;
88
int clear_modifiers = 0;
9+
int after_modifiers = 0;
910
charcodemap_t *active_mods = NULL;
1011
int active_mods_n;
1112
char *window_arg = NULL;
@@ -14,11 +15,12 @@ int cmd_click(context_t *context) {
1415

1516
int c;
1617
enum {
17-
opt_unused, opt_help, opt_clearmodifiers, opt_window, opt_delay,
18+
opt_unused, opt_help, opt_clearmodifiers, opt_aftermodifiers, opt_window, opt_delay,
1819
opt_repeat
1920
};
2021
static struct option longopts[] = {
2122
{ "clearmodifiers", no_argument, NULL, opt_clearmodifiers },
23+
{ "aftermodifiers", no_argument, NULL, opt_aftermodifiers },
2224
{ "help", no_argument, NULL, opt_help },
2325
{ "window", required_argument, NULL, opt_window },
2426
{ "delay", required_argument, NULL, opt_delay },
@@ -27,7 +29,8 @@ int cmd_click(context_t *context) {
2729
};
2830
static const char *usage =
2931
"Usage: %s [options] <button>\n"
30-
"--clearmodifiers - reset active modifiers (alt, etc) while typing\n"
32+
"--clearmodifiers - reset active modifiers (alt, etc) while moving\n"
33+
"--aftermodifiers - wait for modifiers to be released before typing\n"
3134
"--window WINDOW - specify a window to send click to\n"
3235
"--repeat REPEATS - number of times to click. Default is 1\n"
3336
"--delay MILLISECONDS - delay in milliseconds between clicks.\n"
@@ -38,7 +41,7 @@ int cmd_click(context_t *context) {
3841
"right = 3, wheel up = 4, wheel down = 5\n";
3942
int option_index;
4043

41-
while ((c = getopt_long_only(context->argc, context->argv, "+cw:h",
44+
while ((c = getopt_long_only(context->argc, context->argv, "+caw:h",
4245
longopts, &option_index)) != -1) {
4346
switch (c) {
4447
case 'h':
@@ -51,6 +54,10 @@ int cmd_click(context_t *context) {
5154
case opt_clearmodifiers:
5255
clear_modifiers = 1;
5356
break;
57+
case 'a':
58+
case opt_aftermodifiers:
59+
after_modifiers = 1;
60+
break;
5461
case 'w':
5562
case opt_window:
5663
clear_modifiers = 1;
@@ -86,6 +93,9 @@ int cmd_click(context_t *context) {
8693
button = atoi(context->argv[0]);
8794

8895
window_each(context, window_arg, {
96+
if (after_modifiers) {
97+
xdo_wait_for_modifier_release(context->xdo);
98+
}
8999
if (clear_modifiers) {
90100
xdo_get_active_modifiers(context->xdo, &active_mods, &active_mods_n);
91101
xdo_clear_active_modifiers(context->xdo, window, active_mods, active_mods_n);

cmd_key.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,11 @@ int cmd_key(context_t *context) {
2222

2323
/* Options */
2424
int clear_modifiers = 0;
25+
int after_modifiers = 0;
2526

2627
static struct option longopts[] = {
2728
{ "clearmodifiers", no_argument, NULL, 'c' },
29+
{ "aftermodifiers", no_argument, NULL, 'a' },
2830
{ "delay", required_argument, NULL, 'd' },
2931
{ "repeat-delay", required_argument, NULL, 'R' },
3032
{ "help", no_argument, NULL, 'h' },
@@ -36,6 +38,7 @@ int cmd_key(context_t *context) {
3638
static const char *usage =
3739
"Usage: %s [options] <keysequence> [keysequence ...]\n"
3840
"--clearmodifiers - clear active keyboard modifiers during keystrokes\n"
41+
"--aftermodifiers - wait for modifiers to be released before typing\n"
3942
"--delay DELAY - Use DELAY milliseconds between keystrokes\n"
4043
"--repeat TIMES - How many times to repeat the key sequence\n"
4144
"--repeat-delay DELAY - DELAY milliseconds between repetitions\n"
@@ -51,7 +54,7 @@ int cmd_key(context_t *context) {
5154

5255
int option_index;
5356

54-
while ((c = getopt_long_only(context->argc, context->argv, "+d:hcw:",
57+
while ((c = getopt_long_only(context->argc, context->argv, "+d:hcaw:",
5558
longopts, &option_index)) != -1) {
5659
switch (c) {
5760
case 'w':
@@ -61,6 +64,9 @@ int cmd_key(context_t *context) {
6164
case 'c':
6265
clear_modifiers = 1;
6366
break;
67+
case 'a':
68+
after_modifiers = 1;
69+
break;
6470
case 'h':
6571
printf(usage, cmd);
6672
consume_args(context, context->argc);
@@ -115,6 +121,9 @@ int cmd_key(context_t *context) {
115121

116122
int max_arg = context->argc;
117123
window_each(context, window_arg, {
124+
if (after_modifiers) {
125+
xdo_wait_for_modifier_release(context->xdo);
126+
}
118127
if (clear_modifiers) {
119128
xdo_get_active_modifiers(context->xdo, &active_mods, &active_mods_n);
120129
xdo_clear_active_modifiers(context->xdo, window, active_mods, active_mods_n);

cmd_mousedown.c

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,27 +8,34 @@ int cmd_mousedown(context_t *context) {
88
charcodemap_t *active_mods = NULL;
99
int active_mods_n;
1010
int clear_modifiers = 0;
11+
int after_modifiers = 0;
1112
char *window_arg = NULL;
1213

1314
int c;
1415
static struct option longopts[] = {
1516
{ "clearmodifiers", no_argument, NULL, 'c' },
17+
{ "aftermodifiers", no_argument, NULL, 'a' },
1618
{ "help", no_argument, NULL, 'h' },
1719
{ "window", required_argument, NULL, 'w' },
1820
{ 0, 0, 0, 0 },
1921
};
2022
static const char *usage =
2123
"Usage: %s [--clearmodifiers] [--window WINDOW] <button>\n"
2224
"--window <windowid> - specify a window to send keys to\n"
23-
"--clearmodifiers - reset active modifiers (alt, etc) while typing\n";
25+
"--clearmodifiers - reset active modifiers (alt, etc) while clicking\n"
26+
"--aftermodifiers - wait for modifiers to be released before clicking\n";
27+
2428
int option_index;
2529

26-
while ((c = getopt_long_only(context->argc, context->argv, "+chw:",
30+
while ((c = getopt_long_only(context->argc, context->argv, "+cahw:",
2731
longopts, &option_index)) != -1) {
2832
switch (c) {
2933
case 'c':
3034
clear_modifiers = 1;
3135
break;
36+
case 'a':
37+
after_modifiers = 1;
38+
break;
3239
case 'h':
3340
printf(usage, cmd);
3441
consume_args(context, context->argc);
@@ -54,6 +61,9 @@ int cmd_mousedown(context_t *context) {
5461
button = atoi(context->argv[0]);
5562

5663
window_each(context, window_arg, {
64+
if (after_modifiers) {
65+
xdo_wait_for_modifier_release(context->xdo);
66+
}
5767
if (clear_modifiers) {
5868
xdo_get_active_modifiers(context->xdo, &active_mods, &active_mods_n);
5969
xdo_clear_active_modifiers(context->xdo, window, active_mods, active_mods_n);

cmd_mousemove.c

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
struct mousemove {
66
Window window;
77
int clear_modifiers;
8+
int after_modifiers;
89
int opsync;
910
int polar_coordinates;
1011
int x;
@@ -32,11 +33,12 @@ int cmd_mousemove(context_t *context) {
3233

3334
int c;
3435
enum {
35-
opt_unused, opt_help, opt_sync, opt_clearmodifiers, opt_polar,
36+
opt_unused, opt_help, opt_sync, opt_clearmodifiers, opt_aftermodifiers, opt_polar,
3637
opt_screen, opt_step, opt_delay, opt_window
3738
};
3839
static struct option longopts[] = {
3940
{ "clearmodifiers", no_argument, NULL, opt_clearmodifiers },
41+
{ "aftermodifiers", no_argument, NULL, opt_aftermodifiers },
4042
{ "help", no_argument, NULL, opt_help},
4143
{ "polar", no_argument, NULL, opt_polar },
4244
{ "screen", required_argument, NULL, opt_screen },
@@ -48,21 +50,27 @@ int cmd_mousemove(context_t *context) {
4850
};
4951
static const char *usage =
5052
"Usage: %s [options] <x> <y>\n"
51-
"-c, --clearmodifiers - reset active modifiers (alt, etc) while typing\n"
53+
"-c, --clearmodifiers - reset active modifiers (alt, etc) while moving\n"
54+
"-a, --aftermodifiers - wait for modifiers to be released before moving\n"
55+
5256
//"-d, --delay <MS> - sleeptime in milliseconds between steps.\n"
5357
//"--step <STEP> - pixels to move each time along path to x,y.\n" "-p, --polar - Use polar coordinates. X as an angle, Y as distance\n"
5458
"--screen SCREEN - which screen to move on, default is current screen\n"
5559
"--sync - only exit once the mouse has moved\n"
5660
"-w, --window <windowid> - specify a window to move relative to.\n";
5761
int option_index;
5862

59-
while ((c = getopt_long_only(context->argc, context->argv, "+chw:pd:",
63+
while ((c = getopt_long_only(context->argc, context->argv, "+cahw:pd:",
6064
longopts, &option_index)) != -1) {
6165
switch (c) {
6266
case 'c':
6367
case opt_clearmodifiers:
6468
mousemove.clear_modifiers = 1;
6569
break;
70+
case 'a':
71+
case opt_aftermodifiers:
72+
mousemove.after_modifiers = 1;
73+
break;
6674
case 'h':
6775
case opt_help:
6876
printf(usage, cmd);
@@ -187,6 +195,9 @@ static int _mousemove(context_t *context, struct mousemove *mousemove) {
187195
int mx, my, mscreen;
188196
xdo_get_mouse_location(context->xdo, &mx, &my, &mscreen);
189197

198+
if (mousemove->after_modifiers) {
199+
xdo_wait_for_modifier_release(context->xdo);
200+
}
190201

191202
if (mousemove->clear_modifiers) {
192203
xdo_get_active_modifiers(context->xdo, &active_mods, &active_mods_n);

cmd_mousemove_relative.c

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,25 +7,28 @@ int cmd_mousemove_relative(context_t *context) {
77
char *cmd = *context->argv;
88
int polar_coordinates = 0;
99
int clear_modifiers = 0;
10+
int after_modifiers = 0;
1011
int opsync = 0;
1112
int origin_x = -1, origin_y = -1;
1213

1314
charcodemap_t *active_mods = NULL;
1415
int active_mods_n;
1516
int c;
1617
enum {
17-
opt_unused, opt_help, opt_sync, opt_clearmodifiers, opt_polar
18+
opt_unused, opt_help, opt_sync, opt_clearmodifiers, opt_aftermodifiers, opt_polar
1819
};
1920
static struct option longopts[] = {
2021
{ "help", no_argument, NULL, opt_help },
2122
{ "sync", no_argument, NULL, opt_sync },
2223
{ "polar", no_argument, NULL, opt_polar },
2324
{ "clearmodifiers", no_argument, NULL, opt_clearmodifiers },
25+
{ "aftermodifiers", no_argument, NULL, opt_aftermodifiers },
2426
{ 0, 0, 0, 0 },
2527
};
2628
static const char *usage =
2729
"Usage: %s [options] <x> <y>\n"
28-
"-c, --clearmodifiers - reset active modifiers (alt, etc) while typing\n"
30+
"-c, --clearmodifiers - reset active modifiers (alt, etc) while moving\n"
31+
"-a, --aftermodifiers - wait for modifiers to be released before moving\n"
2932
"-p, --polar - Use polar coordinates. X as an angle, Y as distance\n"
3033
"--sync - only exit once the mouse has moved\n"
3134
"\n"
@@ -39,7 +42,7 @@ int cmd_mousemove_relative(context_t *context) {
3942
" %s 100 140\n";
4043
int option_index;
4144

42-
while ((c = getopt_long_only(context->argc, context->argv, "+cph",
45+
while ((c = getopt_long_only(context->argc, context->argv, "+cpah",
4346
longopts, &option_index)) != -1) {
4447
switch (c) {
4548
case 'h':
@@ -59,6 +62,10 @@ int cmd_mousemove_relative(context_t *context) {
5962
case opt_clearmodifiers:
6063
clear_modifiers = 1;
6164
break;
65+
case 'a':
66+
case opt_aftermodifiers:
67+
clear_modifiers = 1;
68+
break;
6269
default:
6370
fprintf(stderr, usage, cmd, cmd, cmd);
6471
return EXIT_FAILURE;
@@ -95,6 +102,9 @@ int cmd_mousemove_relative(context_t *context) {
95102
y = (-sin(radians) * distance);
96103
}
97104

105+
if (after_modifiers) {
106+
xdo_wait_for_modifier_release(context->xdo);
107+
}
98108
if (clear_modifiers) {
99109
xdo_get_active_modifiers(context->xdo, &active_mods, &active_mods_n);
100110
xdo_clear_active_modifiers(context->xdo, CURRENTWINDOW, active_mods, active_mods_n);

cmd_mouseup.c

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,21 +9,24 @@ int cmd_mouseup(context_t *context) {
99
charcodemap_t *active_mods = NULL;
1010
int active_mods_n;
1111
int clear_modifiers = 0;
12+
int after_modifiers = 0;
1213

1314
int c;
1415
static struct option longopts[] = {
1516
{ "clearmodifiers", no_argument, NULL, 'c' },
17+
{ "aftermodifiers", no_argument, NULL, 'a' },
1618
{ "help", no_argument, NULL, 'h' },
1719
{ "window", required_argument, NULL, 'w' },
1820
{ 0, 0, 0, 0 },
1921
};
2022
static const char *usage =
2123
"Usage: %s [--clearmodifiers] [--window WINDOW] <button>\n"
2224
"--window <windowid> - specify a window to send keys to\n"
23-
"--clearmodifiers - reset active modifiers (alt, etc) while typing\n";
25+
"--clearmodifiers - reset active modifiers (alt, etc) while clicking\n"
26+
"--aftermodifiers - wait for modifiers to be released before clicking\n";
2427
int option_index;
2528

26-
while ((c = getopt_long_only(context->argc, context->argv, "+cw:h",
29+
while ((c = getopt_long_only(context->argc, context->argv, "+caw:h",
2730
longopts, &option_index)) != -1) {
2831
switch (c) {
2932
case 'h':
@@ -34,6 +37,9 @@ int cmd_mouseup(context_t *context) {
3437
case 'c':
3538
clear_modifiers = 1;
3639
break;
40+
case 'a':
41+
after_modifiers = 1;
42+
break;
3743
case 'w':
3844
window_arg = strdup(optarg);
3945
break;
@@ -54,6 +60,9 @@ int cmd_mouseup(context_t *context) {
5460
button = atoi(context->argv[0]);
5561

5662
window_each(context, window_arg, {
63+
if (after_modifiers) {
64+
xdo_wait_for_modifier_release(context->xdo);
65+
}
5766
if (clear_modifiers) {
5867
xdo_get_active_modifiers(context->xdo, &active_mods, &active_mods_n);
5968
xdo_clear_active_modifiers(context->xdo, window, active_mods, active_mods_n);

cmd_type.c

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -187,13 +187,7 @@ int cmd_type(context_t *context) {
187187

188188
window_each(context, window_arg, {
189189
if (after_modifiers) {
190-
for (;;) {
191-
xdo_get_active_modifiers(context->xdo, NULL, &active_mods_n);
192-
if (active_mods_n == 0) {
193-
break;
194-
}
195-
usleep(30000);
196-
}
190+
xdo_wait_for_modifier_release(context->xdo);
197191
}
198192
if (clear_modifiers) {
199193
xdo_get_active_modifiers(context->xdo, &active_mods, &active_mods_n);

xdo.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1682,6 +1682,17 @@ int xdo_get_active_modifiers(const xdo_t *xdo, charcodemap_t **keys,
16821682
return XDO_SUCCESS;
16831683
}
16841684

1685+
void xdo_wait_for_modifier_release(const xdo_t *xdo) {
1686+
int active_mods_n;
1687+
for (;;) {
1688+
xdo_get_active_modifiers(xdo, NULL, &active_mods_n);
1689+
if (active_mods_n == 0) {
1690+
return;
1691+
}
1692+
usleep(30000);
1693+
}
1694+
}
1695+
16851696
unsigned int xdo_get_input_state(const xdo_t *xdo) {
16861697
Window root, dummy;
16871698
int root_x, root_y, win_x, win_y;

xdo.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -806,6 +806,11 @@ const char **xdo_get_symbol_map(void);
806806
int xdo_get_active_modifiers(const xdo_t *xdo, charcodemap_t **keys,
807807
int *nkeys);
808808

809+
/**
810+
* Wait for any currently pressed modifier keys to be released.
811+
*/
812+
void xdo_wait_for_modifier_release(const xdo_t *xdo);
813+
809814
/**
810815
* Send any events necessary to clear the active modifiers.
811816
* For example, if you are holding 'alt' when xdo_get_active_modifiers is

0 commit comments

Comments
 (0)