Fixed handling of modifier keys on OS X. Also made OS X client
ignore small mouse wheel events (which seem to get sent by some win32 systems). Other platforms were already ignoring them.
This commit is contained in:
parent
cf3647f7cc
commit
6284286d4f
|
@ -458,7 +458,7 @@ const KeyID COSXKeyState::s_virtualKey[] =
|
||||||
|
|
||||||
COSXKeyState::COSXKeyState()
|
COSXKeyState::COSXKeyState()
|
||||||
{
|
{
|
||||||
// do nothing
|
setHalfDuplexMask(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
COSXKeyState::~COSXKeyState()
|
COSXKeyState::~COSXKeyState()
|
||||||
|
@ -494,6 +494,12 @@ COSXKeyState::sendKeyEvent(void* target,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
COSXKeyState::setHalfDuplexMask(KeyModifierMask mask)
|
||||||
|
{
|
||||||
|
CKeyState::setHalfDuplexMask(mask | KeyModifierCapsLock);
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
COSXKeyState::fakeCtrlAltDel()
|
COSXKeyState::fakeCtrlAltDel()
|
||||||
{
|
{
|
||||||
|
@ -518,10 +524,33 @@ COSXKeyState::doUpdateKeys()
|
||||||
// FIXME -- this probably needs to be more dynamic to support
|
// FIXME -- this probably needs to be more dynamic to support
|
||||||
// non-english keyboards. also need to map modifiers needed
|
// non-english keyboards. also need to map modifiers needed
|
||||||
// for each KeyID.
|
// for each KeyID.
|
||||||
|
// FIXME -- add one so we don't use KeyButton 0 (reserved to be no key)
|
||||||
for (UInt32 i = 0; i < sizeof(s_keys) / sizeof(s_keys[0]); ++i) {
|
for (UInt32 i = 0; i < sizeof(s_keys) / sizeof(s_keys[0]); ++i) {
|
||||||
m_keyMap.insert(std::make_pair(s_keys[i].m_keyID,
|
m_keyMap.insert(std::make_pair(s_keys[i].m_keyID,
|
||||||
s_keys[i].m_button + 1));
|
s_keys[i].m_button + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// add modifiers
|
||||||
|
KeyButtons keys;
|
||||||
|
addKeyButton(keys, kKeyShift_L);
|
||||||
|
addKeyButton(keys, kKeyShift_R);
|
||||||
|
addModifier(KeyModifierShift, keys);
|
||||||
|
keys.clear();
|
||||||
|
addKeyButton(keys, kKeyControl_L);
|
||||||
|
addKeyButton(keys, kKeyControl_R);
|
||||||
|
addModifier(KeyModifierControl, keys);
|
||||||
|
keys.clear();
|
||||||
|
addKeyButton(keys, kKeyAlt_L);
|
||||||
|
addKeyButton(keys, kKeyAlt_R);
|
||||||
|
addModifier(KeyModifierAlt, keys);
|
||||||
|
keys.clear();
|
||||||
|
addKeyButton(keys, kKeySuper_L);
|
||||||
|
addKeyButton(keys, kKeySuper_R);
|
||||||
|
addModifier(KeyModifierSuper, keys);
|
||||||
|
keys.clear();
|
||||||
|
addKeyButton(keys, kKeyCapsLock);
|
||||||
|
addModifier(KeyModifierCapsLock, keys);
|
||||||
|
keys.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -529,6 +558,7 @@ COSXKeyState::doFakeKeyEvent(KeyButton button, bool press, bool isAutoRepeat)
|
||||||
{
|
{
|
||||||
LOG((CLOG_DEBUG2 "doFakeKeyEvent button:%d, press:%d", button, press));
|
LOG((CLOG_DEBUG2 "doFakeKeyEvent button:%d, press:%d", button, press));
|
||||||
// let system figure out character for us
|
// let system figure out character for us
|
||||||
|
// FIXME -- subtracting one because we added one in doUpdateKeys.
|
||||||
CGPostKeyboardEvent(0, static_cast<CGKeyCode>(button) - 1, press);
|
CGPostKeyboardEvent(0, static_cast<CGKeyCode>(button) - 1, press);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -626,5 +656,59 @@ COSXKeyState::mapKeyFromEvent(EventRef event, KeyModifierMask* maskOut) const
|
||||||
}
|
}
|
||||||
|
|
||||||
return id;
|
return id;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
COSXKeyState::addKeyButton(KeyButtons& keys, KeyID id) const
|
||||||
|
{
|
||||||
|
CKeyMap::const_iterator keyIndex = m_keyMap.find(id);
|
||||||
|
if (keyIndex == m_keyMap.end()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// XXX -- subtract one because added one in doUpdateKeys
|
||||||
|
keys.push_back(keyIndex->second - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
COSXKeyState::handleModifierKeys(void* target,
|
||||||
|
KeyModifierMask oldMask, KeyModifierMask newMask)
|
||||||
|
{
|
||||||
|
// compute changed modifiers
|
||||||
|
KeyModifierMask changed = (oldMask ^ newMask);
|
||||||
|
|
||||||
|
// synthesize changed modifier keys
|
||||||
|
if ((changed & KeyModifierShift) != 0) {
|
||||||
|
handleModifierKey(target, kKeyShift_L,
|
||||||
|
(newMask & KeyModifierShift) != 0);
|
||||||
|
}
|
||||||
|
if ((changed & KeyModifierControl) != 0) {
|
||||||
|
handleModifierKey(target, kKeyControl_L,
|
||||||
|
(newMask & KeyModifierControl) != 0);
|
||||||
|
}
|
||||||
|
if ((changed & KeyModifierAlt) != 0) {
|
||||||
|
handleModifierKey(target, kKeyAlt_L,
|
||||||
|
(newMask & KeyModifierAlt) != 0);
|
||||||
|
}
|
||||||
|
if ((changed & KeyModifierSuper) != 0) {
|
||||||
|
handleModifierKey(target, kKeySuper_L,
|
||||||
|
(newMask & KeyModifierSuper) != 0);
|
||||||
|
}
|
||||||
|
if ((changed & KeyModifierCapsLock) != 0) {
|
||||||
|
handleModifierKey(target, kKeyCapsLock,
|
||||||
|
(newMask & KeyModifierCapsLock) != 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
COSXKeyState::handleModifierKey(void* target, KeyID id, bool down)
|
||||||
|
{
|
||||||
|
CKeyMap::const_iterator keyIndex = m_keyMap.find(id);
|
||||||
|
if (keyIndex == m_keyMap.end()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// FIXME -- subtract one because we added one in doUpdateKeys
|
||||||
|
KeyButton button = keyIndex->second - 1;
|
||||||
|
setKeyDown(button, down);
|
||||||
|
sendKeyEvent(target, down, false, id, getActiveModifiers(), 0, button);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,13 +36,23 @@ public:
|
||||||
KeyID mapKeyFromEvent(EventRef event,
|
KeyID mapKeyFromEvent(EventRef event,
|
||||||
KeyModifierMask* maskOut) const;
|
KeyModifierMask* maskOut) const;
|
||||||
|
|
||||||
|
//! Handle modifier key change
|
||||||
|
/*!
|
||||||
|
Determines which modifier keys have changed and updates the modifier
|
||||||
|
state and sends key events as appropriate.
|
||||||
|
*/
|
||||||
|
void handleModifierKeys(void* target,
|
||||||
|
KeyModifierMask oldMask, KeyModifierMask newMask);
|
||||||
|
|
||||||
// IKeyState overrides
|
// IKeyState overrides
|
||||||
|
virtual void setHalfDuplexMask(KeyModifierMask);
|
||||||
virtual bool fakeCtrlAltDel();
|
virtual bool fakeCtrlAltDel();
|
||||||
virtual const char* getKeyName(KeyButton) const;
|
virtual const char* getKeyName(KeyButton) const;
|
||||||
virtual void sendKeyEvent(void* target,
|
virtual void sendKeyEvent(void* target,
|
||||||
bool press, bool isAutoRepeat,
|
bool press, bool isAutoRepeat,
|
||||||
KeyID key, KeyModifierMask mask,
|
KeyID key, KeyModifierMask mask,
|
||||||
SInt32 count, KeyButton button);
|
SInt32 count, KeyButton button);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// IKeyState overrides
|
// IKeyState overrides
|
||||||
virtual void doUpdateKeys();
|
virtual void doUpdateKeys();
|
||||||
|
@ -56,6 +66,8 @@ private:
|
||||||
bool adjustModifiers(Keystrokes& keys,
|
bool adjustModifiers(Keystrokes& keys,
|
||||||
Keystrokes& undo,
|
Keystrokes& undo,
|
||||||
KeyModifierMask desiredMask) const;
|
KeyModifierMask desiredMask) const;
|
||||||
|
void addKeyButton(KeyButtons& keys, KeyID id) const;
|
||||||
|
void handleModifierKey(void* target, KeyID id, bool down);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef std::map<KeyID, KeyButton> CKeyMap;
|
typedef std::map<KeyID, KeyButton> CKeyMap;
|
||||||
|
|
|
@ -303,6 +303,12 @@ COSXScreen::fakeMouseRelativeMove(SInt32 dx, SInt32 dy) const
|
||||||
void
|
void
|
||||||
COSXScreen::fakeMouseWheel(SInt32 delta) const
|
COSXScreen::fakeMouseWheel(SInt32 delta) const
|
||||||
{
|
{
|
||||||
|
// synergy uses a wheel step size of 120. the mac uses a step size of 1.
|
||||||
|
delta /= 120;
|
||||||
|
if (delta == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
CFPropertyListRef pref = ::CFPreferencesCopyValue(
|
CFPropertyListRef pref = ::CFPreferencesCopyValue(
|
||||||
CFSTR("com.apple.scrollwheel.scaling") ,
|
CFSTR("com.apple.scrollwheel.scaling") ,
|
||||||
kCFPreferencesAnyApplication,
|
kCFPreferencesAnyApplication,
|
||||||
|
@ -327,6 +333,8 @@ COSXScreen::fakeMouseWheel(SInt32 delta) const
|
||||||
CFRelease(pref);
|
CFRelease(pref);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// note that we ignore the magnitude of the delta. i think this is to
|
||||||
|
// avoid local wheel acceleration.
|
||||||
if (delta < 0) {
|
if (delta < 0) {
|
||||||
wheelIncr = -wheelIncr;
|
wheelIncr = -wheelIncr;
|
||||||
}
|
}
|
||||||
|
@ -799,16 +807,27 @@ COSXScreen::onKey(EventRef event) const
|
||||||
{
|
{
|
||||||
UInt32 eventKind = GetEventKind(event);
|
UInt32 eventKind = GetEventKind(event);
|
||||||
|
|
||||||
|
// get the key
|
||||||
KeyButton button;
|
KeyButton button;
|
||||||
GetEventParameter(event, kEventParamKeyCode, typeUInt32,
|
GetEventParameter(event, kEventParamKeyCode, typeUInt32,
|
||||||
NULL, sizeof(button), NULL, &button);
|
NULL, sizeof(button), NULL, &button);
|
||||||
|
LOG((CLOG_DEBUG1 "event: Key event kind: %d, keycode=%d", eventKind, button));
|
||||||
|
|
||||||
|
// sadly, OS X doesn't report the button for modifier keys. button will
|
||||||
|
// be zero for modifier keys. since that's not good enough we'll have
|
||||||
|
// to figure out what the key was.
|
||||||
|
if (button == 0 && eventKind == kEventRawKeyModifiersChanged) {
|
||||||
|
// get old and new modifier state
|
||||||
|
KeyModifierMask oldMask = getActiveModifiers();
|
||||||
|
KeyModifierMask newMask = mapMacModifiersToSynergy(event);
|
||||||
|
m_keyState->handleModifierKeys(getEventTarget(), oldMask, newMask);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool down = (eventKind == kEventRawKeyDown);
|
bool down = (eventKind == kEventRawKeyDown);
|
||||||
bool up = (eventKind == kEventRawKeyUp);
|
bool up = (eventKind == kEventRawKeyUp);
|
||||||
bool isRepeat = (eventKind == kEventRawKeyRepeat);
|
bool isRepeat = (eventKind == kEventRawKeyRepeat);
|
||||||
|
|
||||||
LOG((CLOG_DEBUG1 "event: Key event kind: %d, keycode=%d", eventKind, button));
|
|
||||||
|
|
||||||
if (down) {
|
if (down) {
|
||||||
m_keyState->setKeyDown(button, true);
|
m_keyState->setKeyDown(button, true);
|
||||||
}
|
}
|
||||||
|
@ -842,6 +861,44 @@ COSXScreen::mapMacButtonToSynergy(UInt16 macButton) const
|
||||||
return kButtonNone;
|
return kButtonNone;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
KeyModifierMask
|
||||||
|
COSXScreen::mapMacModifiersToSynergy(EventRef event) const
|
||||||
|
{
|
||||||
|
// get native bit mask
|
||||||
|
UInt32 macMask;
|
||||||
|
GetEventParameter(event, kEventParamKeyModifiers, typeUInt32,
|
||||||
|
NULL, sizeof(macMask), NULL, &macMask);
|
||||||
|
|
||||||
|
// convert
|
||||||
|
KeyModifierMask outMask = 0;
|
||||||
|
if ((macMask & shiftKey) != 0) {
|
||||||
|
outMask |= KeyModifierShift;
|
||||||
|
}
|
||||||
|
if ((macMask & rightShiftKey) != 0) {
|
||||||
|
outMask |= KeyModifierShift;
|
||||||
|
}
|
||||||
|
if ((macMask & controlKey) != 0) {
|
||||||
|
outMask |= KeyModifierControl;
|
||||||
|
}
|
||||||
|
if ((macMask & rightControlKey) != 0) {
|
||||||
|
outMask |= KeyModifierControl;
|
||||||
|
}
|
||||||
|
if ((macMask & cmdKey) != 0) {
|
||||||
|
outMask |= KeyModifierAlt;
|
||||||
|
}
|
||||||
|
if ((macMask & optionKey) != 0) {
|
||||||
|
outMask |= KeyModifierSuper;
|
||||||
|
}
|
||||||
|
if ((macMask & rightOptionKey) != 0) {
|
||||||
|
outMask |= KeyModifierSuper;
|
||||||
|
}
|
||||||
|
if ((macMask & alphaLock) != 0) {
|
||||||
|
outMask |= KeyModifierCapsLock;
|
||||||
|
}
|
||||||
|
|
||||||
|
return outMask;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
COSXScreen::updateButtons()
|
COSXScreen::updateButtons()
|
||||||
{
|
{
|
||||||
|
|
|
@ -92,6 +92,9 @@ private:
|
||||||
// map mac mouse button to synergy buttons
|
// map mac mouse button to synergy buttons
|
||||||
ButtonID mapMacButtonToSynergy(UInt16) const;
|
ButtonID mapMacButtonToSynergy(UInt16) const;
|
||||||
|
|
||||||
|
// map mac modifier mask to synergy modifier mask
|
||||||
|
KeyModifierMask mapMacModifiersToSynergy(EventRef event) const;
|
||||||
|
|
||||||
/// Resolution switch callback
|
/// Resolution switch callback
|
||||||
static pascal void displayManagerCallback(void* inUserData,
|
static pascal void displayManagerCallback(void* inUserData,
|
||||||
SInt16 inMessage, void* inNotifyData);
|
SInt16 inMessage, void* inNotifyData);
|
||||||
|
|
Loading…
Reference in New Issue