Browse Source

Merge branch 'grab' of https://github.com/CendioOssman/tigervnc

tags/v1.8.90
Pierre Ossman 5 years ago
parent
commit
0f73ee021c
1 changed files with 48 additions and 9 deletions
  1. 48
    9
      vncviewer/DesktopWindow.cxx

+ 48
- 9
vncviewer/DesktopWindow.cxx View File

@@ -684,23 +684,18 @@ int DesktopWindow::fltkHandle(int event, Fl_Window *win)

if (dw) {
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:
if (fullscreenSystemKeys) {
// 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:
if (fullscreenSystemKeys) {
// 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;
@@ -766,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
@@ -793,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) {
@@ -806,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;
@@ -832,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
}


Loading…
Cancel
Save