diff --git a/vncviewer/DesktopWindow.cxx b/vncviewer/DesktopWindow.cxx index def70bd52..7a0912185 100644 --- a/vncviewer/DesktopWindow.cxx +++ b/vncviewer/DesktopWindow.cxx @@ -850,6 +850,18 @@ void DesktopWindow::toggleForceGrab() { } } +bool DesktopWindow::isKeyboardGrabbed() const { + return keyboardGrabbed; +} + +bool DesktopWindow::isMouseGrabbed() const { + return mouseGrabbed; +} + +bool DesktopWindow::isForceGrabbed() const { + return forceGrabbed; +} + int DesktopWindow::handle(int event) { switch (event) { diff --git a/vncviewer/DesktopWindow.h b/vncviewer/DesktopWindow.h index 56689251a..dbbc71000 100644 --- a/vncviewer/DesktopWindow.h +++ b/vncviewer/DesktopWindow.h @@ -84,6 +84,10 @@ class DesktopWindow : public Fl_Window { void toggleForceGrab(); + bool isKeyboardGrabbed() const; + bool isMouseGrabbed() const; + bool isForceGrabbed() const; + private: static void menuOverlay(void *data); diff --git a/vncviewer/Viewport.cxx b/vncviewer/Viewport.cxx index 3d792d9f0..27fbd898b 100644 --- a/vncviewer/Viewport.cxx +++ b/vncviewer/Viewport.cxx @@ -235,7 +235,7 @@ void Viewport::setCursor(int width, int height, const Point& hotspot, void Viewport::showCursor() { - if (viewOnly) { + if (viewOnly || ungrabbedGrabOnlyMouse()) { window()->cursor(FL_CURSOR_DEFAULT); return; } @@ -249,7 +249,7 @@ void Viewport::showCursor() void Viewport::handleClipboardRequest() { - if (viewOnly) + if (viewOnly || ungrabbedGrabOnlyKeyboard()) return; Fl::paste(*this, clipboardSource); @@ -257,7 +257,7 @@ void Viewport::handleClipboardRequest() void Viewport::handleClipboardAnnounce(bool available) { - if (viewOnly) + if (viewOnly || ungrabbedGrabOnlyKeyboard()) return; if (!acceptClipboard) @@ -314,7 +314,7 @@ void Viewport::setLEDState(unsigned int ledState) return; } - if (viewOnly) + if (viewOnly || ungrabbedGrabOnlyKeyboard()) return; if (!hasFocus()) @@ -327,7 +327,7 @@ void Viewport::pushLEDState() { unsigned int ledState; - if (viewOnly) + if (viewOnly || ungrabbedGrabOnlyKeyboard()) return; // Server support? @@ -517,7 +517,7 @@ int Viewport::handle(int event) void Viewport::sendPointerEvent(const rfb::Point& pos, uint16_t buttonMask) { - if (viewOnly) + if (viewOnly || ungrabbedGrabOnlyMouse()) return; if ((pointerEventInterval == 0) || (buttonMask != lastButtonMask)) { @@ -553,7 +553,7 @@ void Viewport::handleClipboardChange(int source, void *data) assert(self); - if (viewOnly) + if (viewOnly || self->ungrabbedGrabOnlyKeyboard()) return; if (!sendClipboard) @@ -672,7 +672,7 @@ void Viewport::handleKeyPress(int systemKeyCode, return; } - if (viewOnly) + if (viewOnly || ungrabbedGrabOnlyKeyboard()) return; try { @@ -696,9 +696,13 @@ void Viewport::handleKeyRelease(int systemKeyCode, // Right Ctrl if (keySym == FL_Control_R) { ((DesktopWindow*)window())->toggleForceGrab(); + showCursor(); return; } + if (ungrabbedGrabOnlyKeyboard()) + return; + try { cc->sendKeyRelease(systemKeyCode); } catch (std::exception& e) { @@ -824,6 +828,7 @@ void Viewport::popupContextMenu() window()->fullscreen_off(); else ((DesktopWindow*)window())->fullscreen_on(); + showCursor(); break; case ID_MINIMIZE: #ifdef __APPLE__ @@ -900,3 +905,17 @@ void Viewport::handleOptions(void *data) if (Fl::belowmouse() == self) self->showCursor(); } + +bool Viewport::ungrabbedGrabOnlyKeyboard() const { + if (grabOnly || grabOnlyKeyboard) { + return !((DesktopWindow*)window())->isKeyboardGrabbed(); + } + return false; +} + +bool Viewport::ungrabbedGrabOnlyMouse() const { + if (grabOnly || grabOnlyMouse) { + return !((DesktopWindow*)window())->isMouseGrabbed(); + } + return false; +} diff --git a/vncviewer/Viewport.h b/vncviewer/Viewport.h index cb33978ac..35de7e428 100644 --- a/vncviewer/Viewport.h +++ b/vncviewer/Viewport.h @@ -104,6 +104,9 @@ class Viewport : public Fl_Widget, protected EmulateMB, static void handleOptions(void *data); + bool ungrabbedGrabOnlyKeyboard() const; + bool ungrabbedGrabOnlyMouse() const; + private: CConn* cc; diff --git a/vncviewer/parameters.cxx b/vncviewer/parameters.cxx index f0ca5353a..e9097fe16 100644 --- a/vncviewer/parameters.cxx +++ b/vncviewer/parameters.cxx @@ -141,6 +141,15 @@ BoolParameter remoteResize("RemoteResize", BoolParameter viewOnly("ViewOnly", "Don't send any mouse or keyboard events to the server", false); +BoolParameter grabOnlyKeyboard("GrabOnlyKeyboard", + "Send keyboard events to the server only when keyboard grab is active.", + false); +BoolParameter grabOnlyMouse("GrabOnlyMouse", + "Send mouse events to the server only when mouse grab is active.", + false); +BoolParameter grabOnly("GrabOnly", + "Activates both GrabOnlyKeyboard and GrabOnlyMouse.", + false); BoolParameter shared("Shared", "Don't disconnect other viewers upon connection - " "share the desktop instead", @@ -207,6 +216,9 @@ static VoidParameter* parameterArray[] = { &fullScreenSelectedMonitors, /* Input */ &viewOnly, + &grabOnlyKeyboard, + &grabOnlyMouse, + &grabOnly, &emulateMiddleButton, &alwaysCursor, &cursorType, diff --git a/vncviewer/parameters.h b/vncviewer/parameters.h index f9ee28fa6..2b2cd9dfe 100644 --- a/vncviewer/parameters.h +++ b/vncviewer/parameters.h @@ -62,6 +62,9 @@ extern rfb::BoolParameter remoteResize; extern rfb::BoolParameter listenMode; extern rfb::BoolParameter viewOnly; +extern rfb::BoolParameter grabOnlyKeyboard; +extern rfb::BoolParameter grabOnlyMouse; +extern rfb::BoolParameter grabOnly; extern rfb::BoolParameter shared; extern rfb::BoolParameter acceptClipboard;