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()
|
||||
{
|
||||
// do nothing
|
||||
setHalfDuplexMask(0);
|
||||
}
|
||||
|
||||
COSXKeyState::~COSXKeyState()
|
||||
|
@ -494,6 +494,12 @@ COSXKeyState::sendKeyEvent(void* target,
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
COSXKeyState::setHalfDuplexMask(KeyModifierMask mask)
|
||||
{
|
||||
CKeyState::setHalfDuplexMask(mask | KeyModifierCapsLock);
|
||||
}
|
||||
|
||||
bool
|
||||
COSXKeyState::fakeCtrlAltDel()
|
||||
{
|
||||
|
@ -518,10 +524,33 @@ COSXKeyState::doUpdateKeys()
|
|||
// FIXME -- this probably needs to be more dynamic to support
|
||||
// non-english keyboards. also need to map modifiers needed
|
||||
// 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) {
|
||||
m_keyMap.insert(std::make_pair(s_keys[i].m_keyID,
|
||||
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
|
||||
|
@ -529,6 +558,7 @@ COSXKeyState::doFakeKeyEvent(KeyButton button, bool press, bool isAutoRepeat)
|
|||
{
|
||||
LOG((CLOG_DEBUG2 "doFakeKeyEvent button:%d, press:%d", button, press));
|
||||
// let system figure out character for us
|
||||
// FIXME -- subtracting one because we added one in doUpdateKeys.
|
||||
CGPostKeyboardEvent(0, static_cast<CGKeyCode>(button) - 1, press);
|
||||
}
|
||||
|
||||
|
@ -618,7 +648,7 @@ COSXKeyState::mapKeyFromEvent(EventRef event, KeyModifierMask* maskOut) const
|
|||
if (id != kKeyNone && c != 0) {
|
||||
// FIXME
|
||||
}
|
||||
|
||||
|
||||
// map modifier key
|
||||
if (maskOut != NULL) {
|
||||
activeMask &= ~KeyModifierModeSwitch;
|
||||
|
@ -626,5 +656,59 @@ COSXKeyState::mapKeyFromEvent(EventRef event, KeyModifierMask* maskOut) const
|
|||
}
|
||||
|
||||
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,
|
||||
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
|
||||
virtual void setHalfDuplexMask(KeyModifierMask);
|
||||
virtual bool fakeCtrlAltDel();
|
||||
virtual const char* getKeyName(KeyButton) const;
|
||||
virtual void sendKeyEvent(void* target,
|
||||
bool press, bool isAutoRepeat,
|
||||
KeyID key, KeyModifierMask mask,
|
||||
SInt32 count, KeyButton button);
|
||||
|
||||
protected:
|
||||
// IKeyState overrides
|
||||
virtual void doUpdateKeys();
|
||||
|
@ -56,6 +66,8 @@ private:
|
|||
bool adjustModifiers(Keystrokes& keys,
|
||||
Keystrokes& undo,
|
||||
KeyModifierMask desiredMask) const;
|
||||
void addKeyButton(KeyButtons& keys, KeyID id) const;
|
||||
void handleModifierKey(void* target, KeyID id, bool down);
|
||||
|
||||
private:
|
||||
typedef std::map<KeyID, KeyButton> CKeyMap;
|
||||
|
|
|
@ -303,6 +303,12 @@ COSXScreen::fakeMouseRelativeMove(SInt32 dx, SInt32 dy) const
|
|||
void
|
||||
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(
|
||||
CFSTR("com.apple.scrollwheel.scaling") ,
|
||||
kCFPreferencesAnyApplication,
|
||||
|
@ -327,6 +333,8 @@ COSXScreen::fakeMouseWheel(SInt32 delta) const
|
|||
CFRelease(pref);
|
||||
}
|
||||
|
||||
// note that we ignore the magnitude of the delta. i think this is to
|
||||
// avoid local wheel acceleration.
|
||||
if (delta < 0) {
|
||||
wheelIncr = -wheelIncr;
|
||||
}
|
||||
|
@ -799,15 +807,26 @@ COSXScreen::onKey(EventRef event) const
|
|||
{
|
||||
UInt32 eventKind = GetEventKind(event);
|
||||
|
||||
// get the key
|
||||
KeyButton button;
|
||||
GetEventParameter(event, kEventParamKeyCode, typeUInt32,
|
||||
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 up = (eventKind == kEventRawKeyUp);
|
||||
bool isRepeat = (eventKind == kEventRawKeyRepeat);
|
||||
|
||||
LOG((CLOG_DEBUG1 "event: Key event kind: %d, keycode=%d", eventKind, button));
|
||||
|
||||
if (down) {
|
||||
m_keyState->setKeyDown(button, true);
|
||||
|
@ -842,6 +861,44 @@ COSXScreen::mapMacButtonToSynergy(UInt16 macButton) const
|
|||
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
|
||||
COSXScreen::updateButtons()
|
||||
{
|
||||
|
|
|
@ -91,6 +91,9 @@ private:
|
|||
|
||||
// map mac mouse button to synergy buttons
|
||||
ButtonID mapMacButtonToSynergy(UInt16) const;
|
||||
|
||||
// map mac modifier mask to synergy modifier mask
|
||||
KeyModifierMask mapMacModifiersToSynergy(EventRef event) const;
|
||||
|
||||
/// Resolution switch callback
|
||||
static pascal void displayManagerCallback(void* inUserData,
|
||||
|
|
Loading…
Reference in New Issue