SYNERGY-1397 MacOS function keys (#7135)
* SYNERGY-1397 MacOS function keys * SYNERGY-1397 Update ChangeLog and version number * SYNERGY-1397 Remove extra comment * SYNERGY-1397 Remove assertions * SYNERGY-1397 Change log level to warning
This commit is contained in:
parent
c6918b74cf
commit
dc72af7a7b
4 changed files with 112 additions and 42 deletions
|
|
@ -1,3 +1,9 @@
|
||||||
|
v1.14.3-snapshot
|
||||||
|
===========
|
||||||
|
Bug fixes:
|
||||||
|
- #7135 Fix issue with function keys on macOS
|
||||||
|
===========
|
||||||
|
|
||||||
v1.14.2-stable
|
v1.14.2-stable
|
||||||
===========
|
===========
|
||||||
Bug fixes:
|
Bug fixes:
|
||||||
|
|
|
||||||
|
|
@ -6,9 +6,9 @@ cmake_minimum_required (VERSION 3.4)
|
||||||
|
|
||||||
set (SYNERGY_VERSION_MAJOR 1)
|
set (SYNERGY_VERSION_MAJOR 1)
|
||||||
set (SYNERGY_VERSION_MINOR 14)
|
set (SYNERGY_VERSION_MINOR 14)
|
||||||
set (SYNERGY_VERSION_PATCH 2)
|
set (SYNERGY_VERSION_PATCH 3)
|
||||||
set (SYNERGY_VERSION_BUILD 1)
|
set (SYNERGY_VERSION_BUILD 1)
|
||||||
set (SYNERGY_VERSION_STAGE "stable")
|
set (SYNERGY_VERSION_STAGE "snapshot")
|
||||||
|
|
||||||
#
|
#
|
||||||
# Version from CI
|
# Version from CI
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@
|
||||||
#include "base/Log.h"
|
#include "base/Log.h"
|
||||||
|
|
||||||
#include <Carbon/Carbon.h>
|
#include <Carbon/Carbon.h>
|
||||||
|
#include <IOKit/hidsystem/IOHIDLib.h>
|
||||||
|
|
||||||
// Note that some virtual keys codes appear more than once. The
|
// Note that some virtual keys codes appear more than once. The
|
||||||
// first instance of a virtual key code maps to the KeyID that we
|
// first instance of a virtual key code maps to the KeyID that we
|
||||||
|
|
@ -129,6 +130,65 @@ static const KeyEntry s_controlKeys[] = {
|
||||||
{ kKeyBrightnessDown, s_brightnessDown }
|
{ kKeyBrightnessDown, s_brightnessDown }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
io_connect_t
|
||||||
|
getService(io_iterator_t iter) {
|
||||||
|
io_connect_t service = 0;
|
||||||
|
auto nextIterator = IOIteratorNext(iter);
|
||||||
|
|
||||||
|
if (nextIterator) {
|
||||||
|
IOServiceOpen(nextIterator, mach_task_self(), kIOHIDParamConnectType, &service);
|
||||||
|
IOObjectRelease(nextIterator);
|
||||||
|
}
|
||||||
|
|
||||||
|
return service;
|
||||||
|
}
|
||||||
|
|
||||||
|
io_connect_t
|
||||||
|
getEventDriver()
|
||||||
|
{
|
||||||
|
static io_connect_t sEventDrvrRef = 0;
|
||||||
|
|
||||||
|
if (!sEventDrvrRef) {
|
||||||
|
// Get master device port
|
||||||
|
mach_port_t masterPort = 0;
|
||||||
|
if (!IOMasterPort(bootstrap_port, &masterPort)) {
|
||||||
|
io_iterator_t iter = 0;
|
||||||
|
auto dict = IOServiceMatching(kIOHIDSystemClass);
|
||||||
|
|
||||||
|
if (!IOServiceGetMatchingServices(masterPort, dict, &iter)) {
|
||||||
|
sEventDrvrRef = getService(iter);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
LOG((CLOG_WARN, "IOService not found"));
|
||||||
|
}
|
||||||
|
|
||||||
|
IOObjectRelease(iter);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
LOG((CLOG_WARN, "Couldn't obtain IO master port"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return sEventDrvrRef;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
isModifier(UInt8 virtualKey) {
|
||||||
|
static std::set<UInt8> modifiers {
|
||||||
|
s_shiftVK,
|
||||||
|
s_superVK,
|
||||||
|
s_altVK,
|
||||||
|
s_controlVK,
|
||||||
|
s_capsLockVK
|
||||||
|
};
|
||||||
|
|
||||||
|
return (modifiers.find(virtualKey) != modifiers.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
} //namespace
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// OSXKeyState
|
// OSXKeyState
|
||||||
|
|
@ -336,11 +396,11 @@ OSXKeyState::fakeCtrlAltDel()
|
||||||
bool
|
bool
|
||||||
OSXKeyState::fakeMediaKey(KeyID id)
|
OSXKeyState::fakeMediaKey(KeyID id)
|
||||||
{
|
{
|
||||||
return fakeNativeMediaKey(id);;
|
return fakeNativeMediaKey(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
CGEventFlags
|
CGEventFlags
|
||||||
OSXKeyState::getModifierStateAsOSXFlags()
|
OSXKeyState::getModifierStateAsOSXFlags() const
|
||||||
{
|
{
|
||||||
CGEventFlags modifiers = 0;
|
CGEventFlags modifiers = 0;
|
||||||
|
|
||||||
|
|
@ -476,30 +536,6 @@ OSXKeyState::getKeyMap(synergy::KeyMap& keyMap)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CGEventFlags
|
|
||||||
OSXKeyState::getDeviceIndependedFlags() const
|
|
||||||
{
|
|
||||||
CGEventFlags modifiers = 0;
|
|
||||||
|
|
||||||
if (m_shiftPressed) {
|
|
||||||
modifiers |= kCGEventFlagMaskShift;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_controlPressed) {
|
|
||||||
modifiers |= kCGEventFlagMaskControl;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_altPressed) {
|
|
||||||
modifiers |= kCGEventFlagMaskAlternate;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_superPressed) {
|
|
||||||
modifiers |= kCGEventFlagMaskCommand;
|
|
||||||
}
|
|
||||||
|
|
||||||
return modifiers;
|
|
||||||
}
|
|
||||||
|
|
||||||
CGEventFlags
|
CGEventFlags
|
||||||
OSXKeyState::getDeviceDependedFlags() const
|
OSXKeyState::getDeviceDependedFlags() const
|
||||||
{
|
{
|
||||||
|
|
@ -530,12 +566,9 @@ OSXKeyState::getKeyboardEventFlags() const
|
||||||
{
|
{
|
||||||
// set the event flags for special keys
|
// set the event flags for special keys
|
||||||
// http://tinyurl.com/pxl742y
|
// http://tinyurl.com/pxl742y
|
||||||
CGEventFlags modifiers = getDeviceIndependedFlags();
|
CGEventFlags modifiers = getModifierStateAsOSXFlags();
|
||||||
|
|
||||||
if (m_capsPressed) {
|
if (!m_capsPressed) {
|
||||||
modifiers |= kCGEventFlagMaskAlphaShift;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
modifiers |= getDeviceDependedFlags();
|
modifiers |= getDeviceDependedFlags();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -567,6 +600,29 @@ OSXKeyState::setKeyboardModifiers(CGKeyCode virtualKey, bool keyDown)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
kern_return_t
|
||||||
|
OSXKeyState::postHIDVirtualKey(UInt8 virtualKey, bool postDown)
|
||||||
|
{
|
||||||
|
NXEventData event;
|
||||||
|
bzero(&event, sizeof(NXEventData));
|
||||||
|
auto driver = getEventDriver();
|
||||||
|
kern_return_t result = KERN_FAILURE;
|
||||||
|
|
||||||
|
if (driver) {
|
||||||
|
if (isModifier(virtualKey)) {
|
||||||
|
result = IOHIDPostEvent(driver, NX_FLAGSCHANGED, {0,0}, &event, kNXEventDataVersion, getKeyboardEventFlags(), true);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
event.key.keyCode = virtualKey;
|
||||||
|
const auto eventType = postDown ? NX_KEYDOWN : NX_KEYUP;
|
||||||
|
result = IOHIDPostEvent(driver, eventType, {0,0}, &event, kNXEventDataVersion, 0, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
OSXKeyState::postKeyboardKey(CGKeyCode virtualKey, bool keyDown)
|
OSXKeyState::postKeyboardKey(CGKeyCode virtualKey, bool keyDown)
|
||||||
{
|
{
|
||||||
|
|
@ -596,7 +652,11 @@ OSXKeyState::fakeKey(const Keystroke& keystroke)
|
||||||
button, virtualKey, keyDown ? "down" : "up", client));
|
button, virtualKey, keyDown ? "down" : "up", client));
|
||||||
|
|
||||||
setKeyboardModifiers(virtualKey, keyDown);
|
setKeyboardModifiers(virtualKey, keyDown);
|
||||||
postKeyboardKey(virtualKey, keyDown);
|
if (postHIDVirtualKey(virtualKey, keyDown) != KERN_SUCCESS) {
|
||||||
|
LOG((CLOG_WARN, "Fail to post HID event"));
|
||||||
|
postKeyboardKey(virtualKey, keyDown);
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -99,7 +99,7 @@ public:
|
||||||
virtual SInt32 pollActiveGroup() const;
|
virtual SInt32 pollActiveGroup() const;
|
||||||
virtual void pollPressedKeys(KeyButtonSet& pressedKeys) const;
|
virtual void pollPressedKeys(KeyButtonSet& pressedKeys) const;
|
||||||
|
|
||||||
CGEventFlags getModifierStateAsOSXFlags();
|
CGEventFlags getModifierStateAsOSXFlags() const;
|
||||||
protected:
|
protected:
|
||||||
// KeyState overrides
|
// KeyState overrides
|
||||||
virtual void getKeyMap(synergy::KeyMap& keyMap);
|
virtual void getKeyMap(synergy::KeyMap& keyMap);
|
||||||
|
|
@ -151,9 +151,13 @@ private:
|
||||||
|
|
||||||
void init();
|
void init();
|
||||||
|
|
||||||
|
// Post a key event to HID manager. It posts an event to HID client, a
|
||||||
|
// much lower level than window manager which's the target from carbon
|
||||||
|
// CGEventPost
|
||||||
|
kern_return_t postHIDVirtualKey(UInt8 virtualKeyCode, bool postDown);
|
||||||
|
|
||||||
// Get keyboard event flags accorfing to keyboard modifiers
|
// Get keyboard event flags accorfing to keyboard modifiers
|
||||||
CGEventFlags getKeyboardEventFlags() const;
|
CGEventFlags getKeyboardEventFlags() const;
|
||||||
CGEventFlags getDeviceIndependedFlags() const;
|
|
||||||
CGEventFlags getDeviceDependedFlags() const;
|
CGEventFlags getDeviceDependedFlags() const;
|
||||||
|
|
||||||
void setKeyboardModifiers(CGKeyCode virtualKey, bool keyDown);
|
void setKeyboardModifiers(CGKeyCode virtualKey, bool keyDown);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue