Page 1 of 1

Replace "xdotool key Return" with bash cmd | XTEST? [SOLVED]

Posted: Mon 14 Dec 2015, 19:30
by musher0
Hello all.

In a bash script, how can I replace

Code: Select all

xdotool key Return
with an internal bash command?
I'd also need a replacement for

Code: Select all

xdotool key g
I can't seem to find on the Web info about this that I can easily understand.

Many thanks in advance for any leads.

Posted: Mon 14 Dec 2015, 21:31
by Flash
Not exactly sure what you want do, but perhaps the discussion in this thread will be of some help.

Posted: Mon 14 Dec 2015, 22:06
by musher0
Thanks, Flash.

Actually, this question concerns the less utility, and more precisely its
'!' launcher command.
~~~~~~~~~~~
Example:
Let's pretend that you're in a less window reading some text. The text
mentions a particular configuration file in /root/.config . You want to check
if you have it, so, within less, you type

Code: Select all

!rox /root/.config
less launches rox, which displays the directory, and then asks you to
press Return to go back to your original text.
~~~~~~~~~~~
I'd like to send the Enter keystroke back to less so I don't have to press
the Return key every time.

xdotool will do it with this command:

Code: Select all

xdotool key Return
But short of going into the complication of editing the less code itself (in C
or whatever; besides I don't know C), is there a way to send the Enter
keystroke to less from a script -- without using an external program?

Thanks in advance to anyone who has the answer.

Posted: Mon 14 Dec 2015, 22:55
by Peterm321
I had forgotten about the bang(!) command in less.

From what I can see the ! command spawns a shell and passes the follow on text to it as a command. As a shell can take multiple commands on one line using ; or && as separators it would follow that the rox command can be combined with xdotool:

Code: Select all

!rox /root/.config ; xdotool key Return
If your intent is to save typing the Return key specific with rox then it may be as easy just to write a short script to run rox and xdotool at the same time.

NB do not know if this will help if you find typing the long command above is more of a nuisance than a solution. Still think that a script with a name several characters long could be written that runs a command which passes the parameter originally sent to the script to that command, then completes by running the xdotool command. I think that might solve your problem.

Posted: Tue 15 Dec 2015, 00:33
by step
Less appears to pause and prompt for a Return keypress every time the shell ! command terminates. Unless less has a command-line option or configuration option to suppress its own Return prompt you will need to stuff the keyboard buffer. I don't think the shell has a 'sendkeys' built-in command, so xdotool - or a similar tool - is probably the only option to stuff the keyboard buffer.

As others have said, you could write a script that combines a command and xdotool, then invoke less with

Code: Select all

SHELL=/path/to/your/script.sh less /path/to/file_to_view
where file /path/to/your/script.sh looks somewhat like:

Code: Select all

#!/bin/sh
less_window_id()
{
  # write some code that determines the X-window id associated with
  # the less window that started this script
  echo $less_window_id
}

# invoke less' bang command arguments
"$@" &
sleep 0.5 # half a second

xdotool --window $(less_window_id) key Return
# End of script
I haven't fleshed out function less_window_id, that's your task. It could be quite tricky.

Another approach is to try lesskey (man lesskey) to create a custom keyboard command. I have never used lesskey. From a cursory review of its man mage it seems able to combine less keystroke commands together. Perhaps it can combine ! with return, who knows...

Re: How to replace "xdotool key Return" with bash command

Posted: Tue 15 Dec 2015, 02:25
by MochiMoppel
musher0 wrote:In a bash script, how can I replace

Code: Select all

xdotool key Return
with an internal bash command?
You can't.
musher0 wrote:I'd like to send the Enter keystroke back to less so I don't have to press
the Return key every time.

xdotool will do it with this command

Code: Select all

xdotool key Return
Did you really manage to send the keystroke back after invoking the shell from less with the "!" option? How?
Peterm321 wrote:

Code: Select all

!rox /root/.config ; xdotool key Return
This won't work as xdotool still runs within the shell opened by less. The Return key is sent ot ROX, not to less. Less will wait for the shell to exit and then display its "Press RETURN" prompt. At this point all the code from the "!" shell is dead and there is no way for any post mortem action to communicate with less. I would be glad if someone can prove me wrong because this would open new opportunities.

Posted: Tue 15 Dec 2015, 03:36
by musher0
@MochiMoppei & all:

I sure can, like so (from the less "bang" line):

Code: Select all

!sh -c "xemeraldia";xdotool key Return
less executes the game xemeraldia (could be any other app). When I exit
the game, less goes back to its former display without me having to hit
Enter. The xdotool command has done it for me.

Except I'd like to get rid of xdotool. I'd like to find a way to do it internally
within bash if possible, or failing that, with a tiny C (or whatever
computer language) program.

BTW, Peterm321's line:

Code: Select all

!rox /root/.config ; xdotool key Return
works like a charm.

Probably because rox "releases" the calling script as soon as it's shown
the directory. I'm not absolutely sure, but the way I understand this is
that rox has its own "nohup"?

Another example concerning rox. (Run this one from a regular terminal
though, not from the less "bang" line.)
rox acts as a xdg-open when you type

Code: Select all

rox /usr/share/applications/leafpad.desktop
rox loads the app and then gets out of the app's way by closing itself.

Or try peter's example from a terminal without the xdotool part. You'll see
that you don't even have to type an ampersand at the end.

Code: Select all

rox /root/.config # &
rox hands back the "hand" (or whatever it's called) to the terminal it was
called from.

BFN.

Posted: Tue 15 Dec 2015, 04:40
by MochiMoppel
musher0 wrote:BTW, Peterm321's line:

Code: Select all

!rox /root/.config ; xdotool key Return
works like a charm.

Probably because rox "releases" the calling script as soon as it's shown
the directory.
Doesn't work here, but it works when I
1) Add a few seconds sleep between the two commands
2) During the sleep period move focus from Rox window back to console window running less

You are right that the rox command exits as soon as the directory window is opened (because showing the window is the only purpose of the command), but then the xdotool command fires and sends the key to the active (Rox) window ... at least here.


Edit:
OK, it works now when I switch the commands:

Code: Select all

!xdotool key Return; rox /root/.config

Posted: Tue 15 Dec 2015, 07:40
by musher0
Hello all.

Does anybody have experience with Xautomation?
AFAICT, it does some of the things xdotool does, but is a bit smaller.

BFN.

Posted: Tue 15 Dec 2015, 07:51
by musher0
Hello again all.

I found this at
http://www.doctort.org/adam/nerd-notes/ ... event.html:

Code: Select all

// Send a fake keystroke event to an X window.
// by Adam Pierce - [url]http://www.doctort.org/adam/nerd-notes/x11-fake-keypress-event.html[/url]
// This is public domain software. It is free to use by anyone for any purpose.

#include <X11/Xlib.h>
#include <X11/keysym.h>

// The key code to be sent.
// A full list of available codes can be found in /usr/include/X11/keysymdef.h
#define KEYCODE XK_Down

// Function to create a keyboard event
XKeyEvent createKeyEvent(Display *display, Window &win,
                           Window &winRoot, bool press,
                           int keycode, int modifiers)
{
   XKeyEvent event;

   event.display     = display;
   event.window      = win;
   event.root        = winRoot;
   event.subwindow   = None;
   event.time        = CurrentTime;
   event.x           = 1;
   event.y           = 1;
   event.x_root      = 1;
   event.y_root      = 1;
   event.same_screen = True;
   event.keycode     = XKeysymToKeycode(display, keycode);
   event.state       = modifiers;

   if(press)
      event.type = KeyPress;
   else
      event.type = KeyRelease;

   return event;
}

main()
{
// Obtain the X11 display.
   Display *display = XOpenDisplay(0);
   if(display == NULL)
      return -1;

// Get the root window for the current display.
   Window winRoot = XDefaultRootWindow(display);

// Find the window which has the current keyboard focus.
   Window winFocus;
   int    revert;
   XGetInputFocus(display, &winFocus, &revert);

// Send a fake key press event to the window.
   XKeyEvent event = createKeyEvent(display, winFocus, winRoot, true, KEYCODE, 0);
   XSendEvent(event.display, event.window, True, KeyPressMask, (XEvent *)&event);

// Send a fake key release event to the window.
   event = createKeyEvent(display, winFocus, winRoot, false, KEYCODE, 0);
   XSendEvent(event.display, event.window, True, KeyPressMask, (XEvent *)&event);

// Done.
   XCloseDisplay(display);
   return 0;
}
Since I don't know any C, I don't know what to think of it.
I compiled it as mentioned on the page, but it doesn't seem to work.
What do you think?

Thanks in advance.

Posted: Tue 15 Dec 2015, 12:29
by some1
Musher0:
xdotool - and probably also wmctrl - uses XTEST - to be able to talk to X
The post referenced is a bit old.
Suggestion: put XTEST in the threadtitle -might catch the eyeballs of
those who know.And of course search on XTEST libxtst XTE might
give you stuff for further search.
----
MochiMoppel: Yes calling xdotool before rox seem to work
----

Posted: Tue 15 Dec 2015, 13:29
by musher0
Good idea, some1. Done, title changed.

Posted: Tue 15 Dec 2015, 22:26
by some1
Musher0: The Xautomation-tool relies on xte, and subsequently on XTEST.

Inside the xte.c-file you see this (line 45 ca.):
/* wrappers around X test functions to deal with xinput devices */
So - I guess XTE is your solution/the base for a solution- without further digging.

I have not tried it.

Posted: Tue 15 Dec 2015, 23:02
by musher0
Thanks, some1. I'll mark the thread "solved", then.

BFN.