Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add xdotool type --aftermodifiers option #406

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 13 additions & 3 deletions cmd_click.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ int cmd_click(context_t *context) {
char *cmd = context->argv[0];
int ret = 0;
int clear_modifiers = 0;
int after_keys = 0;
charcodemap_t *active_mods = NULL;
int active_mods_n;
char *window_arg = NULL;
Expand All @@ -14,11 +15,12 @@ int cmd_click(context_t *context) {

int c;
enum {
opt_unused, opt_help, opt_clearmodifiers, opt_window, opt_delay,
opt_unused, opt_help, opt_clearmodifiers, opt_afterkeys, opt_window, opt_delay,
opt_repeat
};
static struct option longopts[] = {
{ "clearmodifiers", no_argument, NULL, opt_clearmodifiers },
{ "afterkeys", no_argument, NULL, opt_afterkeys },
{ "help", no_argument, NULL, opt_help },
{ "window", required_argument, NULL, opt_window },
{ "delay", required_argument, NULL, opt_delay },
Expand All @@ -27,7 +29,8 @@ int cmd_click(context_t *context) {
};
static const char *usage =
"Usage: %s [options] <button>\n"
"--clearmodifiers - reset active modifiers (alt, etc) while typing\n"
"--clearmodifiers - reset active modifiers (alt, etc) while moving\n"
"--afterkeys - wait for all keys to be released before typing\n"
"--window WINDOW - specify a window to send click to\n"
"--repeat REPEATS - number of times to click. Default is 1\n"
"--delay MILLISECONDS - delay in milliseconds between clicks.\n"
Expand All @@ -38,7 +41,7 @@ int cmd_click(context_t *context) {
"right = 3, wheel up = 4, wheel down = 5\n";
int option_index;

while ((c = getopt_long_only(context->argc, context->argv, "+cw:h",
while ((c = getopt_long_only(context->argc, context->argv, "+caw:h",
longopts, &option_index)) != -1) {
switch (c) {
case 'h':
Expand All @@ -51,6 +54,10 @@ int cmd_click(context_t *context) {
case opt_clearmodifiers:
clear_modifiers = 1;
break;
case 'a':
case opt_afterkeys:
after_keys = 1;
break;
case 'w':
case opt_window:
clear_modifiers = 1;
Expand Down Expand Up @@ -86,6 +93,9 @@ int cmd_click(context_t *context) {
button = atoi(context->argv[0]);

window_each(context, window_arg, {
if (after_keys) {
xdo_wait_for_key_release(context->xdo);
}
if (clear_modifiers) {
xdo_get_active_modifiers(context->xdo, &active_mods, &active_mods_n);
xdo_clear_active_modifiers(context->xdo, window, active_mods, active_mods_n);
Expand Down
11 changes: 10 additions & 1 deletion cmd_key.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,11 @@ int cmd_key(context_t *context) {

/* Options */
int clear_modifiers = 0;
int after_keys = 0;

static struct option longopts[] = {
{ "clearmodifiers", no_argument, NULL, 'c' },
{ "afterkeys", no_argument, NULL, 'a' },
{ "delay", required_argument, NULL, 'd' },
{ "repeat-delay", required_argument, NULL, 'R' },
{ "help", no_argument, NULL, 'h' },
Expand All @@ -36,6 +38,7 @@ int cmd_key(context_t *context) {
static const char *usage =
"Usage: %s [options] <keysequence> [keysequence ...]\n"
"--clearmodifiers - clear active keyboard modifiers during keystrokes\n"
"--afterkeys - wait for all keys to be released before typing\n"
"--delay DELAY - Use DELAY milliseconds between keystrokes\n"
"--repeat TIMES - How many times to repeat the key sequence\n"
"--repeat-delay DELAY - DELAY milliseconds between repetitions\n"
Expand All @@ -51,7 +54,7 @@ int cmd_key(context_t *context) {

int option_index;

while ((c = getopt_long_only(context->argc, context->argv, "+d:hcw:",
while ((c = getopt_long_only(context->argc, context->argv, "+d:hcaw:",
longopts, &option_index)) != -1) {
switch (c) {
case 'w':
Expand All @@ -61,6 +64,9 @@ int cmd_key(context_t *context) {
case 'c':
clear_modifiers = 1;
break;
case 'a':
after_keys = 1;
break;
case 'h':
printf(usage, cmd);
consume_args(context, context->argc);
Expand Down Expand Up @@ -115,6 +121,9 @@ int cmd_key(context_t *context) {

int max_arg = context->argc;
window_each(context, window_arg, {
if (after_keys) {
xdo_wait_for_key_release(context->xdo);
}
if (clear_modifiers) {
xdo_get_active_modifiers(context->xdo, &active_mods, &active_mods_n);
xdo_clear_active_modifiers(context->xdo, window, active_mods, active_mods_n);
Expand Down
14 changes: 12 additions & 2 deletions cmd_mousedown.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,27 +8,34 @@ int cmd_mousedown(context_t *context) {
charcodemap_t *active_mods = NULL;
int active_mods_n;
int clear_modifiers = 0;
int after_keys = 0;
char *window_arg = NULL;

int c;
static struct option longopts[] = {
{ "clearmodifiers", no_argument, NULL, 'c' },
{ "afterkeys", no_argument, NULL, 'a' },
{ "help", no_argument, NULL, 'h' },
{ "window", required_argument, NULL, 'w' },
{ 0, 0, 0, 0 },
};
static const char *usage =
"Usage: %s [--clearmodifiers] [--window WINDOW] <button>\n"
"--window <windowid> - specify a window to send keys to\n"
"--clearmodifiers - reset active modifiers (alt, etc) while typing\n";
"--clearmodifiers - reset active modifiers (alt, etc) while clicking\n"
"--afterkeys - wait for all keys to be released before clicking\n";

int option_index;

while ((c = getopt_long_only(context->argc, context->argv, "+chw:",
while ((c = getopt_long_only(context->argc, context->argv, "+cahw:",
longopts, &option_index)) != -1) {
switch (c) {
case 'c':
clear_modifiers = 1;
break;
case 'a':
after_keys = 1;
break;
case 'h':
printf(usage, cmd);
consume_args(context, context->argc);
Expand All @@ -54,6 +61,9 @@ int cmd_mousedown(context_t *context) {
button = atoi(context->argv[0]);

window_each(context, window_arg, {
if (after_keys) {
xdo_wait_for_key_release(context->xdo);
}
if (clear_modifiers) {
xdo_get_active_modifiers(context->xdo, &active_mods, &active_mods_n);
xdo_clear_active_modifiers(context->xdo, window, active_mods, active_mods_n);
Expand Down
17 changes: 14 additions & 3 deletions cmd_mousemove.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
struct mousemove {
Window window;
int clear_modifiers;
int after_keys;
int opsync;
int polar_coordinates;
int x;
Expand Down Expand Up @@ -32,11 +33,12 @@ int cmd_mousemove(context_t *context) {

int c;
enum {
opt_unused, opt_help, opt_sync, opt_clearmodifiers, opt_polar,
opt_unused, opt_help, opt_sync, opt_clearmodifiers, opt_afterkeys, opt_polar,
opt_screen, opt_step, opt_delay, opt_window
};
static struct option longopts[] = {
{ "clearmodifiers", no_argument, NULL, opt_clearmodifiers },
{ "afterkeys", no_argument, NULL, opt_afterkeys },
{ "help", no_argument, NULL, opt_help},
{ "polar", no_argument, NULL, opt_polar },
{ "screen", required_argument, NULL, opt_screen },
Expand All @@ -48,21 +50,27 @@ int cmd_mousemove(context_t *context) {
};
static const char *usage =
"Usage: %s [options] <x> <y>\n"
"-c, --clearmodifiers - reset active modifiers (alt, etc) while typing\n"
"-c, --clearmodifiers - reset active modifiers (alt, etc) while moving\n"
"-a, --afterkeys - wait for all keys to be released before moving\n"

//"-d, --delay <MS> - sleeptime in milliseconds between steps.\n"
//"--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"
"--screen SCREEN - which screen to move on, default is current screen\n"
"--sync - only exit once the mouse has moved\n"
"-w, --window <windowid> - specify a window to move relative to.\n";
int option_index;

while ((c = getopt_long_only(context->argc, context->argv, "+chw:pd:",
while ((c = getopt_long_only(context->argc, context->argv, "+cahw:pd:",
longopts, &option_index)) != -1) {
switch (c) {
case 'c':
case opt_clearmodifiers:
mousemove.clear_modifiers = 1;
break;
case 'a':
case opt_afterkeys:
mousemove.after_keys = 1;
break;
case 'h':
case opt_help:
printf(usage, cmd);
Expand Down Expand Up @@ -187,6 +195,9 @@ static int _mousemove(context_t *context, struct mousemove *mousemove) {
int mx, my, mscreen;
xdo_get_mouse_location(context->xdo, &mx, &my, &mscreen);

if (mousemove->after_keys) {
xdo_wait_for_key_release(context->xdo);
}

if (mousemove->clear_modifiers) {
xdo_get_active_modifiers(context->xdo, &active_mods, &active_mods_n);
Expand Down
16 changes: 13 additions & 3 deletions cmd_mousemove_relative.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,25 +7,28 @@ int cmd_mousemove_relative(context_t *context) {
char *cmd = *context->argv;
int polar_coordinates = 0;
int clear_modifiers = 0;
int after_keys = 0;
int opsync = 0;
int origin_x = -1, origin_y = -1;

charcodemap_t *active_mods = NULL;
int active_mods_n;
int c;
enum {
opt_unused, opt_help, opt_sync, opt_clearmodifiers, opt_polar
opt_unused, opt_help, opt_sync, opt_clearmodifiers, opt_afterkeys, opt_polar
};
static struct option longopts[] = {
{ "help", no_argument, NULL, opt_help },
{ "sync", no_argument, NULL, opt_sync },
{ "polar", no_argument, NULL, opt_polar },
{ "clearmodifiers", no_argument, NULL, opt_clearmodifiers },
{ "afterkeys", no_argument, NULL, opt_afterkeys },
{ 0, 0, 0, 0 },
};
static const char *usage =
"Usage: %s [options] <x> <y>\n"
"-c, --clearmodifiers - reset active modifiers (alt, etc) while typing\n"
"-c, --clearmodifiers - reset active modifiers (alt, etc) while moving\n"
"-a, --afterkeys - wait for all keys to be released before moving\n"
"-p, --polar - Use polar coordinates. X as an angle, Y as distance\n"
"--sync - only exit once the mouse has moved\n"
"\n"
Expand All @@ -39,7 +42,7 @@ int cmd_mousemove_relative(context_t *context) {
" %s 100 140\n";
int option_index;

while ((c = getopt_long_only(context->argc, context->argv, "+cph",
while ((c = getopt_long_only(context->argc, context->argv, "+cpah",
longopts, &option_index)) != -1) {
switch (c) {
case 'h':
Expand All @@ -59,6 +62,10 @@ int cmd_mousemove_relative(context_t *context) {
case opt_clearmodifiers:
clear_modifiers = 1;
break;
case 'a':
case opt_afterkeys:
clear_modifiers = 1;
break;
default:
fprintf(stderr, usage, cmd, cmd, cmd);
return EXIT_FAILURE;
Expand Down Expand Up @@ -95,6 +102,9 @@ int cmd_mousemove_relative(context_t *context) {
y = (-sin(radians) * distance);
}

if (after_keys) {
xdo_wait_for_key_release(context->xdo);
}
if (clear_modifiers) {
xdo_get_active_modifiers(context->xdo, &active_mods, &active_mods_n);
xdo_clear_active_modifiers(context->xdo, CURRENTWINDOW, active_mods, active_mods_n);
Expand Down
13 changes: 11 additions & 2 deletions cmd_mouseup.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,24 @@ int cmd_mouseup(context_t *context) {
charcodemap_t *active_mods = NULL;
int active_mods_n;
int clear_modifiers = 0;
int after_keys = 0;

int c;
static struct option longopts[] = {
{ "clearmodifiers", no_argument, NULL, 'c' },
{ "afterkeys", no_argument, NULL, 'a' },
{ "help", no_argument, NULL, 'h' },
{ "window", required_argument, NULL, 'w' },
{ 0, 0, 0, 0 },
};
static const char *usage =
"Usage: %s [--clearmodifiers] [--window WINDOW] <button>\n"
"--window <windowid> - specify a window to send keys to\n"
"--clearmodifiers - reset active modifiers (alt, etc) while typing\n";
"--clearmodifiers - reset active modifiers (alt, etc) while clicking\n"
"--afterkeys - wait for all keys to be released before clicking\n";
int option_index;

while ((c = getopt_long_only(context->argc, context->argv, "+cw:h",
while ((c = getopt_long_only(context->argc, context->argv, "+caw:h",
longopts, &option_index)) != -1) {
switch (c) {
case 'h':
Expand All @@ -34,6 +37,9 @@ int cmd_mouseup(context_t *context) {
case 'c':
clear_modifiers = 1;
break;
case 'a':
after_keys = 1;
break;
case 'w':
window_arg = strdup(optarg);
break;
Expand All @@ -54,6 +60,9 @@ int cmd_mouseup(context_t *context) {
button = atoi(context->argv[0]);

window_each(context, window_arg, {
if (after_keys) {
xdo_wait_for_key_release(context->xdo);
}
if (clear_modifiers) {
xdo_get_active_modifiers(context->xdo, &active_mods, &active_mods_n);
xdo_clear_active_modifiers(context->xdo, window, active_mods, active_mods_n);
Expand Down
13 changes: 11 additions & 2 deletions cmd_type.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,17 @@ int cmd_type(context_t *context) {

/* Options */
int clear_modifiers = 0;
int after_keys = 0;
useconds_t delay = 12000; /* 12ms between keystrokes default */

enum {
opt_unused, opt_clearmodifiers, opt_delay, opt_help, opt_window, opt_args,
opt_terminator, opt_file
opt_unused, opt_clearmodifiers, opt_afterkeys, opt_delay, opt_help,
opt_window, opt_args, opt_terminator, opt_file
};

struct option longopts[] = {
{ "clearmodifiers", no_argument, NULL, opt_clearmodifiers },
{ "afterkeys", no_argument, NULL, opt_afterkeys },
{ "delay", required_argument, NULL, opt_delay },
{ "help", no_argument, NULL, opt_help },
{ "window", required_argument, NULL, opt_window },
Expand All @@ -50,6 +52,7 @@ int cmd_type(context_t *context) {
"--window <windowid> - specify a window to send keys to\n"
"--delay <milliseconds> - delay between keystrokes\n"
"--clearmodifiers - reset active modifiers (alt, etc) while typing\n"
"--afterkeys - wait for all keys to be released before typing\n"
"--args N - how many arguments to expect in the exec command. This is\n"
" useful for ending an exec and continuing with more xdotool\n"
" commands\n"
Expand All @@ -76,6 +79,9 @@ int cmd_type(context_t *context) {
case opt_clearmodifiers:
clear_modifiers = 1;
break;
case opt_afterkeys:
after_keys = 1;
break;
case opt_help:
printf(usage, cmd);
consume_args(context, context->argc);
Expand Down Expand Up @@ -180,6 +186,9 @@ int cmd_type(context_t *context) {
}

window_each(context, window_arg, {
if (after_keys) {
xdo_wait_for_key_release(context->xdo);
}
if (clear_modifiers) {
xdo_get_active_modifiers(context->xdo, &active_mods, &active_mods_n);
xdo_clear_active_modifiers(context->xdo, window, active_mods, active_mods_n);
Expand Down
17 changes: 17 additions & 0 deletions xdo.c
Original file line number Diff line number Diff line change
Expand Up @@ -1672,6 +1672,23 @@ int xdo_get_active_modifiers(const xdo_t *xdo, charcodemap_t **keys,
return XDO_SUCCESS;
}

void xdo_wait_for_key_release(const xdo_t *xdo) {
char keymap[32]; /* keycode map: 256 bits */
for (;;) {
XQueryKeymap(xdo->xdpy, keymap);
int any_key_down = 0;
for (size_t i = 0; i < sizeof(keymap); i++) {
if (keymap[i]) {
any_key_down = 1;
break;
}
}
if (!any_key_down)
return;
usleep(30000);
}
}

unsigned int xdo_get_input_state(const xdo_t *xdo) {
Window root, dummy;
int root_x, root_y, win_x, win_y;
Expand Down
Loading