aristosv
Posts: 159
Joined: Mon Dec 08, 2014 7:47 pm

send keyboard input terminal commands while X is started

Tue Apr 07, 2020 11:04 am

I have a raspberry pi 4 running raspbian buster lite.

I installed xserver-xorg and then created a service to start X when I want to.

Code: Select all

[Unit]
Description = xorg
After = remote-fs.target network-online.target
Wants = network-online.target

[Service]
User = root
Group = root
Type = simple
ExecStart = X
Restart = on-abort
RestartSec = 5

[Install]
WantedBy = multi-user.target
My problem is that when I start X (sudo systemctl start xorg.service) all keyboard input stops working.

For example, I mapped the keyboard key F12 to run a command, and it works great as long as xorg service is stopped. As soon as I start the xorg service, any keyboard input is ignored. I can see that when I stop the xorg service and the terminal is as it was before I start it.

Is there a way to have the xorg service started, and still send keyboard input to the terminal?

bzt
Posts: 555
Joined: Sat Oct 14, 2017 9:57 pm

Re: send keyboard input terminal commands while X is started

Tue Apr 07, 2020 11:29 am

X uses a different input method than the ttys. Assuming you're using openbox for window manager under X, you can map your shortcuts in ~/.config/openbox/rc.xml in section "keyboard". For example:

Code: Select all

    <keybind key="C-W-b">
      <action name="Execute">
        <command>chromium</command>
      </action>
    </keybind>
Will start a web browser when you press Ctrl+Meta+b. Change the "key" tag and the value in "command" to your needs. To open a run application window, one could do (assuming lxpanel):

Code: Select all

    <keybind key="F12">
      <action name="Execute">
        <command>lxpanelctl run</command>
      </action>
    </keybind>
Other window managers use different configuration methods. Blackbox for example requires the bbkeys package and a .bbkeysrc file, WindowMaker has a GUI configuration tool etc.

Cheers,
bzt

aristosv
Posts: 159
Joined: Mon Dec 08, 2014 7:47 pm

Re: send keyboard input terminal commands while X is started

Tue Apr 07, 2020 11:32 am

I'm not using any window manager, I'm just starting X so I can run a mono app.

bzt
Posts: 555
Joined: Sat Oct 14, 2017 9:57 pm

Re: send keyboard input terminal commands while X is started

Tue Apr 07, 2020 9:57 pm

aristosv wrote:
Tue Apr 07, 2020 11:32 am
I'm not using any window manager, I'm just starting X so I can run a mono app.
I'm not entirely sure what you want to achieve here. Mono app or not, you should run a minimalistic window manager, because it's responsible for things required for an X session to function properly. Openbox is lightweight, and easy to configure. Just create the following file with the following content:

/home/pi/openbox_rc.xml

Code: Select all

<?xml version="1.0" encoding="UTF-8">
<openbox_config xmlns="http://openbox.org/3.4/rc" xmlns:xi="http://www.w3.org/2001/XInclude">
  <applications>
    <application class="*">
      <focus>yes</focus>
      <fullscreen>yes</fullscreen>
      <decor>no</decor>
    </application>
  </applications>
</openbox_config>
This will open all windows fullscreen without decorations. If you have only one window in your mono app, then that one, but if you open more windows, those will work too. Xlib functions like XFocusWindow or XMapWindow and XUnmapWindow will work as expected only if there's a window manager running.

If you want to send keyboard input to a terminal, then your best shot is xdotool, otherwise you'll have to use Xlib and XSendEvent calls from your mono app.

If you just want to run a command in the background, then you don't need a terminal at all, because default TTYs are still there (although you can't see them when you're in X). Try pressing Ctrl+Alt+Fx, where x is from 1 to 6 (7 is probably the X11), but this depends on your distro and configuration too. To run a command in the background and redirect it's output, you can do

Code: Select all

somecommand </dev/tty1 2>&1 >/dev/tty1 &
then you'll be able to see its output on the first TTY (Ctrl+Alt+F1). Use /dev/tty2 for Ctrl+Alt+F2 etc.

Is this what you're after?

Cheers,
bzt

aristosv
Posts: 159
Joined: Mon Dec 08, 2014 7:47 pm

Re: send keyboard input terminal commands while X is started

Wed Apr 08, 2020 4:40 am

The service I mentioned above starts X, without any window managers.
Then I run a mono app, using mono myapp.exe. So far so good.

I then want to send a command to the terminal. To do this, I mapped F12 on my keyboard with the command I want to send.

But no matter what I type on my keyboard, the focus is on X, and the mono app that's running on top of it.

Thinking about it, its a sketchy way of doing things, I'll probably have to find some other way to do this.

Heater
Posts: 15765
Joined: Tue Jul 17, 2012 3:02 pm

Re: send keyboard input terminal commands while X is started

Wed Apr 08, 2020 5:45 am

bzt wrote:
Tue Apr 07, 2020 9:57 pm
Mono app or not, you should run a minimalistic window manager, because it's responsible for things required for an X session to function properly.
I don't think that is true.

Back in the day when I was into building minimalist Linux systems on my 486 PC I discovered a fun thing: I could boot up with no X running. Then if I felt the need for it I could start it with "startx" and X would come up with the little "twm" window manager. But I could just as well start some application instead of twm. In which case the application would display in a window with no decorations, board, close buttons etc.

Of course there was no "session" as in logging in and such, but who needs that?

So what are these "things required for an X session to function properly"

Any way, seems to me that aristosv could modify the mono application running in X to catch the F12, or whatever keys, and run whatever commands.
Memory in C++ is a leaky abstraction .

bzt
Posts: 555
Joined: Sat Oct 14, 2017 9:57 pm

Re: send keyboard input terminal commands while X is started

Wed Apr 08, 2020 12:40 pm

Heater wrote:
Wed Apr 08, 2020 5:45 am
So what are these "things required for an X session to function properly"
Handling focused window for one. Even a single mono app can have multiple windows, so this is essential. Yeah, maybe the phrase "session" is not the best, I didn't mean dedicated session daemons (like gnome-session-manager or xdm), just a single X session by that. For the xorg-xinit package (which contains startx that you mentioned), session means running .xinitrc from the home folder. When that rc script starts, the session starts as well, and when it exists, the session ends, simple as that (no daemons etc.)
artistosv wrote:But no matter what I type on my keyboard, the focus is on X, and the mono app that's running on top of it.
That's normal. As I've said before, handling the focused window is a job for the window manager, not the X server.

Also note that many applications use multiple windows. For example if that mono app happens to be a webbrowser in kiosk mode, then all the dropdowns, popup menus, select box options etc. are actually independent child windows (with fixed positions and without decorations). In order to work, they need map / unmap and mouse pointer enter / leave events, all handled by the window manager.

Btw, I'm still not sure what you want to do. Running a command by pressing F12 has nothing to do with sending keyboard input commands. Would you mind to clearify a bit your goal?

Cheers,
bzt

User avatar
jojopi
Posts: 3223
Joined: Tue Oct 11, 2011 8:38 pm

Re: send keyboard input terminal commands while X is started

Wed Apr 08, 2020 1:13 pm

bzt wrote:
Wed Apr 08, 2020 12:40 pm
Handling focused window for one. Even a single mono app can have multiple windows, so this is essential.
If there is no window manager running, the X server handles focus itself, using the traditional rule that input events go to the window the mouse cursor is over.

If you have exactly one full-screen client, so you do not need to move windows around, then adding a window manager may be wasteful.

bzt
Posts: 555
Joined: Sat Oct 14, 2017 9:57 pm

Re: send keyboard input terminal commands while X is started

Thu Apr 09, 2020 9:28 am

TL;DR
Don't expect that a standard application will run on pure X without glitches.
jojopi wrote:
Wed Apr 08, 2020 1:13 pm
If there is no window manager running, the X server handles focus itself, using the traditional rule that input events go to the window the mouse cursor is over.
No, it does not. X server does not handle which window is above either. I had this problem when I made a kiosk with RPi and a web browser, displaying a site on localhost. Without a wm, chromium was unable to go to fullscreen properly because it couldn't query the parent window's dimensions (although it should have, but it didn't. I think it maybe has something to do with _NET_WM_ACTION_FULLSCREEN atom wasn't handled too). All the popup titles and drop-down option boxes were useless too, because they opened below the main window, and did not get focus.
jojopi wrote:
Wed Apr 08, 2020 1:13 pm
If you have exactly one full-screen client, so you do not need to move windows around, then adding a window manager may be wasteful.
Believe me, I've tried to eliminate the wm, I'm all about K.I.S.S. The reason why I mentioned a web browser kiosk because people think it has one fullscreen window only. But that's not true, it operates many. Tooltips, popups etc. are in fact all windows (from X's perspective), which need proper window stack. Here's a minimal, working solution I came up with. Without openbox, it simply doesn't work, just give it a try if you don't believe me!

I'm not saying you can't write an application with a single window using X only, but it must be carefully written: make sure you get the correct root window as parent, and not to wait for events which are provided by the wm. Also you can forget about high-level widget libraries (as they usually depend on those events and often use decoration-less child windows), you must use low-level Xlib only with basic events. As soon as you expect a token like WM_STATE, WM_DELETE_WINDOW or _NET_FRAME_EXTENTS etc. you'll fail. Many libraries (GTK, Qt) depend on these, and you'll get undefined behaviour if they are missing. Your application must do some of the tasks of a wm at a minimum to make it work. It can be done, sure, just questionable if it worths the effort.

Cheers,
bzt

Heater
Posts: 15765
Joined: Tue Jul 17, 2012 3:02 pm

Re: send keyboard input terminal commands while X is started

Thu Apr 09, 2020 11:38 am

Interesting. I guess complex, modern day applications have a lot more going on that whatever simple X programs I tried this out with a couple of decades ago.
Memory in C++ is a leaky abstraction .

Return to “General discussion”