Sfoglia il codice sorgente

Sync LED state when gaining focus

The state might have changed when we didn't have focus. Get
everything back in sync once we're back in control.
tags/v1.8.90
Pierre Ossman 7 anni fa
parent
commit
1668cfaef2
5 ha cambiato i file con 133 aggiunte e 12 eliminazioni
  1. 20
    12
      vncviewer/DesktopWindow.cxx
  2. 81
    0
      vncviewer/Viewport.cxx
  3. 2
    0
      vncviewer/Viewport.h
  4. 3
    0
      vncviewer/cocoa.h
  5. 27
    0
      vncviewer/cocoa.mm

+ 20
- 12
vncviewer/DesktopWindow.cxx Vedi File

@@ -666,23 +666,31 @@ int DesktopWindow::fltkHandle(int event, Fl_Window *win)

DesktopWindow *dw = dynamic_cast<DesktopWindow*>(win);

if (dw && fullscreenSystemKeys) {
if (dw) {
switch (event) {
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();
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();
}

// We may have gotten our lock keys out of sync with the server
// whilst we didn't have focus. Try to sort this out.
dw->viewport->pushLEDState();
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();
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;
}
}

+ 81
- 0
vncviewer/Viewport.cxx Vedi File

@@ -329,6 +329,87 @@ void Viewport::setLEDState(unsigned int state)
#endif
}

void Viewport::pushLEDState()
{
unsigned int state;

// Server support?
if (cc->cp.ledState() == ledUnknown)
return;

state = 0;

#if defined(WIN32)
if (GetKeyState(VK_CAPITAL) & 0x1)
state |= ledCapsLock;
if (GetKeyState(VK_NUMLOCK) & 0x1)
state |= ledNumLock;
if (GetKeyState(VK_SCROLL) & 0x1)
state |= ledScrollLock;
#elif defined(__APPLE__)
int ret;
bool on;

ret = cocoa_get_caps_lock_state(&on);
if (ret != 0) {
vlog.error(_("Failed to get keyboard LED state: %d"), ret);
return;
}
if (on)
state |= ledCapsLock;

ret = cocoa_get_num_lock_state(&on);
if (ret != 0) {
vlog.error(_("Failed to get keyboard LED state: %d"), ret);
return;
}
if (on)
state |= ledNumLock;

// No support for Scroll Lock //
state |= (cc->cp.ledState() & ledScrollLock);

#else
unsigned int mask;

Status status;
XkbStateRec xkbState;

status = XkbGetState(fl_display, XkbUseCoreKbd, &xkbState);
if (status != Success) {
vlog.error(_("Failed to get keyboard LED state: %d"), status);
return;
}

if (xkbState.locked_mods & LockMask)
state |= ledCapsLock;

mask = getModifierMask(XK_Num_Lock);
if (xkbState.locked_mods & mask)
state |= ledNumLock;

mask = getModifierMask(XK_Scroll_Lock);
if (xkbState.locked_mods & mask)
state |= ledScrollLock;
#endif

if ((state & ledCapsLock) != (cc->cp.ledState() & ledCapsLock)) {
vlog.debug("Inserting fake CapsLock to get in sync with server");
handleKeyPress(fakeKeyBase + 100, XK_Caps_Lock);
handleKeyRelease(fakeKeyBase + 100);
}
if ((state & ledNumLock) != (cc->cp.ledState() & ledNumLock)) {
vlog.debug("Inserting fake NumLock to get in sync with server");
handleKeyPress(fakeKeyBase + 101, XK_Num_Lock);
handleKeyRelease(fakeKeyBase + 101);
}
if ((state & ledScrollLock) != (cc->cp.ledState() & ledScrollLock)) {
vlog.debug("Inserting fake ScrollLock to get in sync with server");
handleKeyPress(fakeKeyBase + 102, XK_Scroll_Lock);
handleKeyRelease(fakeKeyBase + 102);
}
}


void Viewport::draw(Surface* dst)
{

+ 2
- 0
vncviewer/Viewport.h Vedi File

@@ -49,6 +49,8 @@ public:

// Change client LED state
void setLEDState(unsigned int state);
// Change server LED state
void pushLEDState();

void draw(Surface* dst);


+ 3
- 0
vncviewer/cocoa.h Vedi File

@@ -36,4 +36,7 @@ int cocoa_event_keysym(const void *event);
int cocoa_set_caps_lock_state(bool on);
int cocoa_set_num_lock_state(bool on);

int cocoa_get_caps_lock_state(bool *on);
int cocoa_get_num_lock_state(bool *on);

#endif

+ 27
- 0
vncviewer/cocoa.mm Vedi File

@@ -447,6 +447,23 @@ static int cocoa_set_modifier_lock_state(int modifier, bool on)
return KERN_SUCCESS;
}

static int cocoa_get_modifier_lock_state(int modifier, bool *on)
{
kern_return_t ret;
io_connect_t ioc;

ret = cocoa_open_hid(&ioc);
if (ret != KERN_SUCCESS)
return ret;

ret = IOHIDGetModifierLockState(ioc, modifier, on);
IOServiceClose(ioc);
if (ret != KERN_SUCCESS)
return ret;

return KERN_SUCCESS;
}

int cocoa_set_caps_lock_state(bool on)
{
return cocoa_set_modifier_lock_state(kIOHIDCapsLockState, on);
@@ -456,3 +473,13 @@ int cocoa_set_num_lock_state(bool on)
{
return cocoa_set_modifier_lock_state(kIOHIDNumLockState, on);
}

int cocoa_get_caps_lock_state(bool *on)
{
return cocoa_get_modifier_lock_state(kIOHIDCapsLockState, on);
}

int cocoa_get_num_lock_state(bool *on)
{
return cocoa_get_modifier_lock_state(kIOHIDNumLockState, on);
}

Loading…
Annulla
Salva