Skip to content

Commit

Permalink
TEMP: handle macOS keyboard steal
Browse files Browse the repository at this point in the history
  • Loading branch information
CendioOssman committed Dec 14, 2021
1 parent 0854775 commit c2b852a
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 15 deletions.
3 changes: 3 additions & 0 deletions vncviewer/KeyboardMacOS.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ class KeyboardMacOS : public Keyboard {
virtual unsigned getLEDState();
virtual void setLEDState(unsigned state);

// Special helper on macOS
static bool isKeyboardSync(const void* event);

protected:
bool isKeyboardEvent(const NSEvent* nsevent);
bool isKeyPress(const NSEvent* nsevent);
Expand Down
22 changes: 22 additions & 0 deletions vncviewer/KeyboardMacOS.mm
Original file line number Diff line number Diff line change
Expand Up @@ -296,12 +296,34 @@
// No support for Scroll Lock //
}

bool KeyboardMacOS::isKeyboardSync(const void* event)
{
const NSEvent* nsevent = (const NSEvent*)event;

assert(event);

// If we get a NSFlagsChanged event with key code 0 then this isn't
// an actual keyboard event but rather the system trying to sync up
// modifier state after it has stolen input for some reason (e.g.
// Cmd+Tab)

if ([nsevent type] != NSFlagsChanged)
return false;
if ([nsevent keyCode] != 0)
return false;

return true;
}

bool KeyboardMacOS::isKeyboardEvent(const NSEvent* nsevent)
{
switch ([nsevent type]) {
case NSKeyDown:
case NSKeyUp:
return true;
case NSFlagsChanged:
if (isKeyboardSync(nsevent))
return false;
return true;
default:
return false;
Expand Down
43 changes: 28 additions & 15 deletions vncviewer/Viewport.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -457,21 +457,8 @@ int Viewport::handle(int event)
return 1;

case FL_UNFOCUS:
// Release all keys that were pressed as that generally makes most
// sense (e.g. Alt+Tab where we only see the Alt press)
try {
cc->releaseAllKeys();
} catch (rdr::Exception& e) {
vlog.error("%s", e.str());
abort_connection(_("An unexpected error occurred when communicating "
"with the server:\n\n%s"), e.str());
}
keyboard->reset();

hotKeyHandler.reset();
hotKeyBypass = false;
hotKeyActive = false;
pressedKeys.clear();
// We won't get more key events, so reset our knowledge about keys
resetKeyboard();

//Fl::enable_im();
return 1;
Expand Down Expand Up @@ -610,6 +597,24 @@ void Viewport::handlePointerTimeout(void *data)
}
}

void Viewport::resetKeyboard()
{
// Release all keys that were pressed as that generally makes most
// sense (e.g. Alt+Tab where we only see the Alt press)
try {
cc->releaseAllKeys();
} catch (rdr::Exception& e) {
vlog.error("%s", e.str());
abort_connection(_("An unexpected error occurred when communicating "
"with the server:\n\n%s"), e.str());
}
keyboard->reset();

hotKeyHandler.reset();
hotKeyBypass = false;
hotKeyActive = false;
pressedKeys.clear();
}

void Viewport::handleKeyPress(int systemKeyCode,
rdr::U32 keyCode, rdr::U32 keySym)
Expand Down Expand Up @@ -807,6 +812,14 @@ int Viewport::handleSystemEvent(void *event, void *data)
if (!self->hasFocus())
return 0;

#ifdef __APPLE__
// Special event that means we temporarily lost some input
if (KeyboardMacOS::isKeyboardSync(event)) {
self->resetKeyboard();
return 1;
}
#endif

consumed = self->keyboard->handleEvent(event);
if (consumed)
return 1;
Expand Down
2 changes: 2 additions & 0 deletions vncviewer/Viewport.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,8 @@ class Viewport : public Fl_Widget, protected EmulateMB,
void handlePointerEvent(const rfb::Point& pos, int buttonMask);
static void handlePointerTimeout(void *data);

void resetKeyboard();

virtual void handleKeyPress(int systemKeyCode,
rdr::U32 keyCode, rdr::U32 keySym);
virtual void handleKeyRelease(int systemKeyCode);
Expand Down

0 comments on commit c2b852a

Please sign in to comment.