Why Xgrabkey Generates Extra Focus-Out and Focus-In Events

Why XGrabKey generates extra focus-out and focus-in events?

Finally, as you know linux means freedom, i modified xserver to get rid of grab-style focusout:

sudo apt-get build-dep xorg-server
apt-get source xorg-server
cd xorg-server-*
#modify or patch dix/events.c: comment off "DoFocusEvents(keybd, oldWin, grab->window, NotifyGrab);" in ActivateKeyboardGrab(), comment off "DoFocusEvents(keybd, grab->window, focusWin, NotifyUngrab);" in DeactivateKeyboardGrab()
sudo apt-get install devscripts
debuild -us -uc #"-us -uc" to avoid the signature step
cd ..
sudo dpkg --install xserver-xorg-core_*.deb
#clear dependencies:
sudo apt-mark auto $(apt-cache showsrc xorg-server | grep Build-Depends | perl -p -e 's/(?:[\[(].+?[\])]|Build-Depends:|,|\|)//g')
sudo apt-get autoremove

And i also need to get rid of XGrabKeyboard in gtk context menu:

sudo apt-get build-dep gtk+2.0
apt-get source gtk+2.0
cd gtk+2.0-*
#modify or patch it: add "return TRUE;" in first line of popup_grab_on_window() of gtk/gtkmenu.c
dpkg-source --commit
debuild -us -uc #"-us -uc" to avoid the signature step, maybe need: sudo apt-get install devscripts
cd ..
sudo dpkg --install libgtk2.0-0_*.deb
#clear dependencies:
sudo apt-mark auto $(apt-cache showsrc gtk+2.0 | grep Build-Depends | perl -p -e 's/(?:[\[(].+?[\])]|Build-Depends:|,|\|)//g')
sudo apt-get autoremove

Now myboard.py works well.

If you are using ubuntu raring-updates edition, you could give a try to:

https://code.google.com/p/diyism-myboard/downloads/detail?name=xserver-xorg-core_1.13.3-0ubuntu6.2_i386.deb

and:

https://code.google.com/p/diyism-myboard/downloads/detail?name=libgtk2.0-0_2.24.17-0ubuntu2_i386.deb

During XGrabKey(board), discover which window had been focused

Wait for the next FocusOut event, verify that the mode is set to NotifyUngrab, get the focus with XGetInputFocus(), and send away your synthetic events.

FocusIn/FocusOut not generated

Having focus refers to the window which receives keyboard input when you press a key.

The focus handling depends on your window manager. The most common mode is click to focus, which your window manager is set to, where you only get focus when you click on the window. An alternative is that the keyboard focus follows the mouse, which is what you are expecting.

There should be a setting to change this in your window manager settings.

The cursor changing does not indicate focus, just that the terminal has defined a different cursor.

To demonstrate, open a terminal and an xev window.

  • Click on the xev window and press a key, you will see key events.
  • Move the mouse to the terminal window, you'll see the motion and leave events
  • Press a key and you'll still see key events from xev
  • Click on the terminal window, xev will give a focus out event
  • Press a key, the characters will be displayed in the terminal window
  • Move the mouse over the xev window and press a key, the character will still come out in the terminal window

How to prevent window from loosing focus when receiving a grabbed key from X11

Finally got it to work in a "proper" way:

bool MainWidget::nativeEvent(const QByteArray &eventType, void *message, long *)
{
#ifdef Q_OS_LINUX
if (eventType == "xcb_generic_event_t")
{
xcb_generic_event_t* event = static_cast<xcb_generic_event_t *>(message);
switch (event->response_type & 127)
{
case XCB_FOCUS_OUT: {
xcb_focus_out_event_t *fe = (xcb_focus_out_event_t *)event;
if ((fe->mode==XCB_NOTIFY_MODE_GRAB && fe->detail==XCB_NOTIFY_DETAIL_NONLINEAR)
|| (fe->mode==XCB_NOTIFY_MODE_NORMAL && fe->detail==XCB_NOTIFY_DETAIL_NONLINEAR ))
hide();
break;
}
}
}
#endif
return false;
}

X11 FocusIn is not working

It appears as though I set the FocusChangeMask at the wrong place. By adding the line XSelectInput(x_display, opengl_window, FocusChangeMask)
, it now triggers the FocusIn event. It was triggering the other display because it had the mask but this one didn't.

Why does XGrabKey return BadRequest?

A return value of 1 does not mean that a BadRequest error occured. Xlib handles errors via an error handler, and the function will always return 1, if it returns at all.

Your code does not work because you have to do the XGrabKey on the root window (GetDefaultRootWindow(Gtk::gdk_display)). Here's a pure Xlib demo:

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

int main() {
Display *d = XOpenDisplay(0);
Window root = DefaultRootWindow(d);
int keycode = XKeysymToKeycode(d, XK_BackSpace);

int rv = XGrabKey(d, keycode, AnyModifier, root, 1, GrabModeAsync, GrabModeAsync);
printf("XGrabKey returned %d\n", rv);

XEvent evt;
while(1) {
XNextEvent(d, &evt);
printf("Got event %d\n", evt.type);
}
}

To then capture the X11 events from GTK use gdk_window_add_filter on a NULL or on the root window and a GdkFilterFunc that processes the events associated with your global hotkey:

#include <X11/Xlib.h>
#include <X11/keysym.h>
#include <gtk/gtk.h>
#include <gdk/gdkx.h>
#include <stdio.h>

GdkFilterReturn filter(GdkXEvent *xevent, GdkEvent *event, gpointer data) {
XKeyEvent *ev = (XKeyEvent *)xevent;
if(ev->type == 2) {
printf("Backspace hit.\n");
}

return GDK_FILTER_CONTINUE;
}

int main(int argc, char *argv[]) {
gtk_init(&argc, &argv);

GdkScreen *scr = gdk_screen_get_default();
GdkWindow *groot = gdk_screen_get_root_window(scr);
gdk_window_set_events(groot, GDK_KEY_PRESS_MASK);
gdk_window_add_filter(groot, filter, NULL);

Display *d = gdk_x11_get_default_xdisplay();
Window root = GDK_WINDOW_XID(groot);
int keycode = XKeysymToKeycode(d, XK_BackSpace);
XGrabKey(d, keycode, AnyModifier, root, 1, GrabModeAsync, GrabModeAsync);

gtk_main();
}

As a side note, a modifier mask of 0 means that no modifiers must be enabled, even those that would not modify the meaning of a key. A grab on the letter "A" with a 0 modifier would not match NumLock + A. That's why I used AnyModifer.

X sends many key up events when a key is held

Here is the more definitive answer, right from these boards. First result on Google:

Ignore auto repeat in X11 applications



Related Topics



Leave a reply



Submit