Просмотр исходного кода

Release pointer grab when cursor leaves window

We don't need the grab any more if the pointer cannot click on our
window. This makes it possible to shift focus to another application
when we aren't covering all monitors.
tags/v1.8.90
Pierre Ossman 6 лет назад
Родитель
Сommit
7e546febad
2 измененных файлов: 77 добавлений и 13 удалений
  1. 72
    13
      vncviewer/DesktopWindow.cxx
  2. 5
    0
      vncviewer/DesktopWindow.h

+ 72
- 13
vncviewer/DesktopWindow.cxx Просмотреть файл

@@ -65,6 +65,7 @@ DesktopWindow::DesktopWindow(int w, int h, const char *name,
: Fl_Window(w, h), cc(cc_), offscreen(NULL), overlay(NULL),
firstUpdate(true),
delayedFullscreen(false), delayedDesktopSize(false),
keyboardGrabbed(false), mouseGrabbed(false),
statsLastFrame(0), statsLastPixels(0), statsLastPosition(0),
statsGraph(NULL)
{
@@ -633,9 +634,18 @@ int DesktopWindow::handle(int event)
break;

case FL_ENTER:
if (keyboardGrabbed)
grabPointer();
case FL_LEAVE:
case FL_DRAG:
case FL_MOVE:
// We don't get FL_LEAVE with a grabbed pointer, so check manually
if (mouseGrabbed) {
if ((Fl::event_x() < 0) || (Fl::event_x() >= w()) ||
(Fl::event_y() < 0) || (Fl::event_y() >= h())) {
ungrabPointer();
}
}
if (fullscreen_active()) {
if (((viewport->x() < 0) && (Fl::event_x() < EDGE_SCROLL_SIZE)) ||
((viewport->x() + viewport->w() > w()) && (Fl::event_x() > w() - EDGE_SCROLL_SIZE)) ||
@@ -692,6 +702,16 @@ int DesktopWindow::fltkHandle(int event, Fl_Window *win)
dw->ungrabKeyboard();
}
break;

case FL_RELEASE:
// We usually fail to grab the mouse if a mouse button was
// pressed when we gained focus (e.g. clicking on our window),
// so we may need to try again when the button is released.
// (We do it here rather than handle() because a window does not
// see FL_RELEASE events if a child widget grabs it first)
if (dw->keyboardGrabbed && !dw->mouseGrabbed)
dw->grabPointer();
break;
}
}

@@ -755,14 +775,18 @@ void DesktopWindow::grabKeyboard()
int ret;
ret = win32_enable_lowlevel_keyboard(fl_xid(this));
if (ret != 0)
if (ret != 0) {
vlog.error(_("Failure grabbing keyboard"));
return;
}
#elif defined(__APPLE__)
int ret;
ret = cocoa_capture_display(this, fullScreenAllMonitors);
if (ret != 0)
if (ret != 0) {
vlog.error(_("Failure grabbing keyboard"));
return;
}
#else
int ret;

@@ -777,18 +801,14 @@ void DesktopWindow::grabKeyboard()
} else {
vlog.error(_("Failure grabbing keyboard"));
}
return;
}

// We also need to grab the pointer as some WMs like to grab buttons
// combined with modifies (e.g. Alt+Button0 in metacity).
ret = XGrabPointer(fl_display, fl_xid(this), True,
ButtonPressMask|ButtonReleaseMask|
ButtonMotionMask|PointerMotionMask,
GrabModeAsync, GrabModeAsync,
None, None, CurrentTime);
if (ret)
vlog.error(_("Failure grabbing mouse"));
#endif

keyboardGrabbed = true;

if (contains(Fl::belowmouse()))
grabPointer();
}


@@ -796,6 +816,10 @@ void DesktopWindow::ungrabKeyboard()
{
Fl::remove_timeout(handleGrab, this);

keyboardGrabbed = false;

ungrabPointer();

#if defined(WIN32)
win32_disable_lowlevel_keyboard(fl_xid(this));
#elif defined(__APPLE__)
@@ -805,12 +829,47 @@ void DesktopWindow::ungrabKeyboard()
if (Fl::grab())
return;

XUngrabPointer(fl_display, fl_event_time);
XUngrabKeyboard(fl_display, fl_event_time);
#endif
}


void DesktopWindow::grabPointer()
{
#if !defined(WIN32) && !defined(__APPLE__)
int ret;

// We also need to grab the pointer as some WMs like to grab buttons
// combined with modifies (e.g. Alt+Button0 in metacity).
ret = XGrabPointer(fl_display, fl_xid(this), True,
ButtonPressMask|ButtonReleaseMask|
ButtonMotionMask|PointerMotionMask,
GrabModeAsync, GrabModeAsync,
None, None, CurrentTime);
if (ret) {
// Having a button pressed prevents us from grabbing, we make
// a new attempt in fltkHandle()
if (ret == AlreadyGrabbed)
return;
vlog.error(_("Failure grabbing mouse"));
return;
}
#endif

mouseGrabbed = true;
}


void DesktopWindow::ungrabPointer()
{
vlog.info("ungrabPointer");
mouseGrabbed = false;
#if !defined(WIN32) && !defined(__APPLE__)
XUngrabPointer(fl_display, fl_event_time);
#endif
}


void DesktopWindow::handleGrab(void *data)
{
DesktopWindow *self = (DesktopWindow*)data;

+ 5
- 0
vncviewer/DesktopWindow.h Просмотреть файл

@@ -87,6 +87,8 @@ private:

void grabKeyboard();
void ungrabKeyboard();
void grabPointer();
void ungrabPointer();

static void handleGrab(void *data);

@@ -123,6 +125,9 @@ private:
bool delayedFullscreen;
bool delayedDesktopSize;

bool keyboardGrabbed;
bool mouseGrabbed;

struct statsEntry {
unsigned fps;
unsigned pps;

Загрузка…
Отмена
Сохранить