Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
tigervnc: update Xvnc server to 1.19.6, fix vncviewer compatibility w…
…ith Xorg 1.20.0+.
- Loading branch information
Showing
with
122 additions
and 3 deletions.
| @@ -0,0 +1,119 @@ | |||
| From 46665b6c791597d5f4f7a0351c491e4dd38b0d71 Mon Sep 17 00:00:00 2001 | |||
| From: Pierre Ossman <ossman@cendio.se> | |||
| Date: Tue, 12 Jun 2018 15:57:27 +0200 | |||
| Subject: [PATCH 1/2] Update comment about keyboard grab on focus changes | |||
|
|
|||
| It is no longer a workaround but rather intended behaviour. | |||
|
|
|||
| From 1d94124f6854e73eef58c595b2b1a4d2a7333962 Mon Sep 17 00:00:00 2001 | |||
| From: Pierre Ossman <ossman@cendio.se> | |||
| Date: Tue, 12 Jun 2018 15:58:34 +0200 | |||
| Subject: [PATCH 2/2] Ignore fake focus events from XGrabKeyboard() | |||
|
|
|||
| Grabbing (and ungrabbing) the keyboard generates fake focus events | |||
| with modern versions of Xorg. This causes an infinite loop since we | |||
| update the grab status on focus events. | |||
|
|
|||
| Work around this by ignoring these fake events. | |||
|
|
|||
| --- vncviewer/DesktopWindow.cxx | |||
| +++ vncviewer/DesktopWindow.cxx | |||
| @@ -662,20 +662,16 @@ int DesktopWindow::fltkHandle(int event, | |||
|
|
|||
| if (dw && fullscreenSystemKeys) { | |||
| switch (event) { | |||
| + // Focus might not stay with us just because we have grabbed the | |||
| + // keyboard. E.g. we might have sub windows, or we're not using | |||
| + // all monitors and the user clicked on another application. | |||
| + // Make sure we update our grabs with the focus changes. | |||
| case FL_FOCUS: | |||
| - // FIXME: We reassert the keyboard grabbing on focus as FLTK there are | |||
| - // some issues we need to work around: | |||
| - // a) Fl::grab(0) on X11 will release the keyboard grab for us. | |||
| - // b) Gaining focus on the system level causes FLTK to switch | |||
| - // window level on OS X. | |||
| if (dw->fullscreen_active()) | |||
| dw->grabKeyboard(); | |||
| break; | |||
|
|
|||
| case FL_UNFOCUS: | |||
| - // FIXME: We need to relinquish control when the entire window loses | |||
| - // focus as it is very tied to this specific window on some | |||
| - // platforms and we want to be able to open subwindows. | |||
| dw->ungrabKeyboard(); | |||
| break; | |||
| } | |||
| @@ -729,6 +725,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 | |||
| @@ -752,6 +765,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) { | |||
| @@ -774,6 +792,16 @@ void DesktopWindow::grabKeyboard() | |||
| None, None, CurrentTime); | |||
| if (ret) | |||
| vlog.error(_("Failure grabbing mouse")); | |||
| + | |||
| + // 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 | |||
| } | |||
|
|
|||
| @@ -791,8 +819,20 @@ void DesktopWindow::ungrabKeyboard() | |||
| if (Fl::grab()) | |||
| return; | |||
|
|
|||
| + XEvent xev; | |||
| + unsigned long serial; | |||
| + | |||
| + serial = XNextRequest(fl_display); | |||
| + | |||
| XUngrabPointer(fl_display, fl_event_time); | |||
| XUngrabKeyboard(fl_display, fl_event_time); | |||
| + | |||
| + // 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 | |||
| } | |||
|
|
|||