diff options
-rw-r--r-- | vncviewer/DesktopWindow.cxx | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/vncviewer/DesktopWindow.cxx b/vncviewer/DesktopWindow.cxx index 17be6e03..e8750b4e 100644 --- a/vncviewer/DesktopWindow.cxx +++ b/vncviewer/DesktopWindow.cxx @@ -761,6 +761,23 @@ void DesktopWindow::fullscreen_on() fullscreen(); } +#if !defined(WIN32) && !defined(__APPLE__) +Bool eventIsFocusWithSerial(Display *display, XEvent *event, XPointer arg) +{ + unsigned long serial; + + serial = *(unsigned long*)arg; + + if (event->xany.serial != serial) + return False; + + if ((event->type != FocusIn) && (event->type != FocusOut)) + return False; + + return True; +} +#endif + void DesktopWindow::grabKeyboard() { // Grabbing the keyboard is fairly safe as FLTK reroutes events to the @@ -788,6 +805,11 @@ void DesktopWindow::grabKeyboard() #else int ret; + XEvent xev; + unsigned long serial; + + serial = XNextRequest(fl_display); + ret = XGrabKeyboard(fl_display, fl_xid(this), True, GrabModeAsync, GrabModeAsync, CurrentTime); if (ret) { @@ -801,6 +823,16 @@ void DesktopWindow::grabKeyboard() } return; } + + // Xorg 1.20+ generates FocusIn/FocusOut even when there is no actual + // change of focus. This causes us to get stuck in an endless loop + // grabbing and ungrabbing the keyboard. Avoid this by filtering out + // any focus events generated by XGrabKeyboard(). + XSync(fl_display, False); + while (XCheckIfEvent(fl_display, &xev, &eventIsFocusWithSerial, + (XPointer)&serial) == True) { + vlog.debug("Ignored synthetic focus event cause by grab change"); + } #endif keyboardGrabbed = true; @@ -827,7 +859,19 @@ void DesktopWindow::ungrabKeyboard() if (Fl::grab()) return; + XEvent xev; + unsigned long serial; + + serial = XNextRequest(fl_display); + XUngrabKeyboard(fl_display, CurrentTime); + + // See grabKeyboard() + XSync(fl_display, False); + while (XCheckIfEvent(fl_display, &xev, &eventIsFocusWithSerial, + (XPointer)&serial) == True) { + vlog.debug("Ignored synthetic focus event cause by grab change"); + } #endif } |