mirror of
https://github.com/debauchee/barrier.git
synced 2026-05-11 10:56:25 +08:00
Converted win32 to new keyboard state tracking design. Also
changed locking to screen so that keys no longer count (only mouse buttons and scroll lock toggled on). This is to deal with the unreliability of key event reporting which can leave us locked to a screen with no key physically pressed. The result of this is that clients get key repeats and releases without the corresponding key press. CKeyState handles this by discarding repeat/release events on keys it hasn't seen go down. Also made a few other minor fixes to win32 keyboard handling.
This commit is contained in:
@@ -39,14 +39,7 @@ void
|
||||
CKeyState::setKeyDown(KeyButton button, bool down)
|
||||
{
|
||||
button &= kButtonMask;
|
||||
if (button != 0) {
|
||||
if (down) {
|
||||
m_keys[button] |= kDown;
|
||||
}
|
||||
else {
|
||||
m_keys[button] &= ~kDown;
|
||||
}
|
||||
}
|
||||
updateKeyState(button, button, down);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -144,7 +137,8 @@ CKeyState::fakeKeyDown(KeyID id, KeyModifierMask mask, KeyButton button)
|
||||
// get the sequence of keys to simulate key press and the final
|
||||
// modifier state.
|
||||
Keystrokes keys;
|
||||
KeyButton localID = (mapKey(keys, id, mask, false) & kButtonMask);
|
||||
KeyButton localID =
|
||||
(KeyButton)(mapKey(keys, id, mask, false) & kButtonMask);
|
||||
if (keys.empty()) {
|
||||
// do nothing if there are no associated keys
|
||||
LOG((CLOG_DEBUG2 "cannot map key 0x%08x", id));
|
||||
@@ -155,7 +149,7 @@ CKeyState::fakeKeyDown(KeyID id, KeyModifierMask mask, KeyButton button)
|
||||
fakeKeyEvents(keys, 1);
|
||||
|
||||
// note that key is down
|
||||
updateKeyState(button & kButtonMask, localID, true);
|
||||
updateKeyState((KeyButton)(button & kButtonMask), localID, true);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -174,7 +168,7 @@ CKeyState::fakeKeyRepeat(
|
||||
// get the sequence of keys to simulate key repeat and the final
|
||||
// modifier state.
|
||||
Keystrokes keys;
|
||||
KeyButton localID = (mapKey(keys, id, mask, true) & kButtonMask);
|
||||
KeyButton localID = (KeyButton)(mapKey(keys, id, mask, true) & kButtonMask);
|
||||
if (localID == 0) {
|
||||
LOG((CLOG_DEBUG2 "cannot map key 0x%08x", id));
|
||||
return;
|
||||
@@ -511,12 +505,16 @@ CKeyState::updateKeyState(KeyButton serverID, KeyButton localID, bool press)
|
||||
KeyModifierMask mask = m_keyToMask[localID];
|
||||
if (mask != 0) {
|
||||
if (isToggle(mask)) {
|
||||
m_keys[localID] ^= kToggled;
|
||||
m_mask ^= mask;
|
||||
|
||||
// never report half-duplex keys as down
|
||||
if (isHalfDuplex(mask)) {
|
||||
m_keys[localID] &= ~kDown;
|
||||
press = true;
|
||||
}
|
||||
|
||||
// toggle on the press
|
||||
if (press) {
|
||||
m_keys[localID] ^= kToggled;
|
||||
m_mask ^= mask;
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -33,9 +33,10 @@ public:
|
||||
|
||||
//! Mark key as being down
|
||||
/*!
|
||||
Sets the state of \p button to down or up.
|
||||
Sets the state of \p button to down or up. If this is overridden
|
||||
it must forward to the superclass.
|
||||
*/
|
||||
void setKeyDown(KeyButton button, bool down);
|
||||
virtual void setKeyDown(KeyButton button, bool down);
|
||||
|
||||
//! Mark modifier as being toggled on
|
||||
/*!
|
||||
@@ -47,9 +48,10 @@ public:
|
||||
//! Post a key event
|
||||
/*!
|
||||
Posts a key event. This may adjust the event or post additional
|
||||
events in some circumstances.
|
||||
events in some circumstances. If this is overridden it must forward
|
||||
to the superclass.
|
||||
*/
|
||||
void sendKeyEvent(void* target,
|
||||
virtual void sendKeyEvent(void* target,
|
||||
bool press, bool isAutoRepeat,
|
||||
KeyID key, KeyModifierMask mask,
|
||||
SInt32 count, KeyButton button);
|
||||
@@ -69,6 +71,7 @@ public:
|
||||
SInt32 count, KeyButton button);
|
||||
virtual void fakeKeyUp(KeyButton button);
|
||||
virtual void fakeToggle(KeyModifierMask modifier);
|
||||
virtual bool fakeCtrlAltDel() = 0;
|
||||
virtual bool isKeyDown(KeyButton) const;
|
||||
virtual KeyModifierMask
|
||||
getActiveModifiers() const;
|
||||
|
||||
@@ -63,6 +63,12 @@ CPlatformScreen::fakeToggle(KeyModifierMask modifier)
|
||||
getKeyState()->fakeToggle(modifier);
|
||||
}
|
||||
|
||||
bool
|
||||
CPlatformScreen::fakeCtrlAltDel()
|
||||
{
|
||||
return getKeyState()->fakeCtrlAltDel();
|
||||
}
|
||||
|
||||
bool
|
||||
CPlatformScreen::isKeyDown(KeyButton button) const
|
||||
{
|
||||
|
||||
@@ -43,7 +43,6 @@ public:
|
||||
virtual void getCursorCenter(SInt32& x, SInt32& y) const = 0;
|
||||
|
||||
// ISecondaryScreen overrides
|
||||
virtual bool fakeCtrlAltDel() const = 0;
|
||||
virtual void fakeMouseButton(ButtonID id, bool press) const = 0;
|
||||
virtual void fakeMouseMove(SInt32 x, SInt32 y) const = 0;
|
||||
virtual void fakeMouseWheel(SInt32 delta) const = 0;
|
||||
@@ -57,6 +56,7 @@ public:
|
||||
SInt32 count, KeyButton button);
|
||||
virtual void fakeKeyUp(KeyButton button);
|
||||
virtual void fakeToggle(KeyModifierMask modifier);
|
||||
virtual bool fakeCtrlAltDel();
|
||||
virtual bool isKeyDown(KeyButton) const;
|
||||
virtual KeyModifierMask
|
||||
getActiveModifiers() const;
|
||||
|
||||
@@ -98,13 +98,13 @@ CScreen::enter(KeyModifierMask toggleMask)
|
||||
// now on screen
|
||||
m_entered = true;
|
||||
|
||||
m_screen->enter();
|
||||
if (m_isPrimary) {
|
||||
enterPrimary();
|
||||
}
|
||||
else {
|
||||
enterSecondary(toggleMask);
|
||||
}
|
||||
m_screen->enter();
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -315,6 +315,16 @@ CScreen::isLockedToScreen() const
|
||||
return true;
|
||||
}
|
||||
|
||||
// note -- we don't lock to the screen if a key is down. key
|
||||
// reporting is simply not reliable enough to trust. the effect
|
||||
// of switching screens with a key down is that the client will
|
||||
// receive key repeats and key releases for keys that it hasn't
|
||||
// see go down. that's okay because CKeyState will ignore those
|
||||
// events. the user might be surprised that any modifier keys
|
||||
// held while crossing to another screen don't apply on the
|
||||
// target screen. if that ends up being a problem we can try
|
||||
// to synthesize a key press for those modifiers on entry.
|
||||
/*
|
||||
// check for any pressed key
|
||||
KeyButton key = isAnyKeyDown();
|
||||
if (key != 0) {
|
||||
@@ -332,6 +342,7 @@ CScreen::isLockedToScreen() const
|
||||
LOG((CLOG_DEBUG "spuriously locked by %s", m_screen->getKeyName(key)));
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
// not locked
|
||||
return false;
|
||||
@@ -431,9 +442,6 @@ CScreen::enterPrimary()
|
||||
void
|
||||
CScreen::enterSecondary(KeyModifierMask toggleMask)
|
||||
{
|
||||
// update our keyboard state to reflect the local state
|
||||
m_screen->updateKeys();
|
||||
|
||||
// remember toggle key state. we'll restore this when we leave.
|
||||
m_toggleKeys = getActiveModifiers();
|
||||
|
||||
|
||||
@@ -87,6 +87,13 @@ public:
|
||||
*/
|
||||
virtual void fakeToggle(KeyModifierMask modifier) = 0;
|
||||
|
||||
//! Fake ctrl+alt+del
|
||||
/*!
|
||||
Synthesize a press of ctrl+alt+del. Return true if processing is
|
||||
complete and false if normal key processing should continue.
|
||||
*/
|
||||
virtual bool fakeCtrlAltDel() = 0;
|
||||
|
||||
//@}
|
||||
//! @name accessors
|
||||
//@{
|
||||
|
||||
@@ -151,7 +151,6 @@ public:
|
||||
virtual void getCursorCenter(SInt32& x, SInt32& y) const = 0;
|
||||
|
||||
// ISecondaryScreen overrides
|
||||
virtual bool fakeCtrlAltDel() const = 0;
|
||||
virtual void fakeMouseButton(ButtonID id, bool press) const = 0;
|
||||
virtual void fakeMouseMove(SInt32 x, SInt32 y) const = 0;
|
||||
virtual void fakeMouseWheel(SInt32 delta) const = 0;
|
||||
@@ -165,6 +164,7 @@ public:
|
||||
SInt32 count, KeyButton button) = 0;
|
||||
virtual void fakeKeyUp(KeyButton button) = 0;
|
||||
virtual void fakeToggle(KeyModifierMask modifier) = 0;
|
||||
virtual bool fakeCtrlAltDel() = 0;
|
||||
virtual bool isKeyDown(KeyButton) const = 0;
|
||||
virtual KeyModifierMask
|
||||
getActiveModifiers() const = 0;
|
||||
|
||||
@@ -28,13 +28,6 @@ public:
|
||||
//! @name accessors
|
||||
//@{
|
||||
|
||||
//! Fake ctrl+alt+del
|
||||
/*!
|
||||
Synthesize a press of ctrl+alt+del. Return true if processing is
|
||||
complete and false if normal key processing should continue.
|
||||
*/
|
||||
virtual bool fakeCtrlAltDel() const = 0;
|
||||
|
||||
//! Fake mouse press/release
|
||||
/*!
|
||||
Synthesize a press or release of mouse button \c id.
|
||||
|
||||
@@ -91,10 +91,18 @@ SOURCE=.\CClipboard.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\CKeyState.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\CPacketStreamFilter.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\CPlatformScreen.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\CProtocolUtil.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -107,6 +115,10 @@ SOURCE=.\IClipboard.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\IKeyState.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\IPrimaryScreen.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -131,6 +143,10 @@ SOURCE=.\CClipboard.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\CKeyState.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\ClipboardTypes.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -139,6 +155,10 @@ SOURCE=.\CPacketStreamFilter.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\CPlatformScreen.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\CProtocolUtil.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
Reference in New Issue
Block a user