Skip to content

Commit

Permalink
Fixed forwarding of FN keys on MacOS
Browse files Browse the repository at this point in the history
  • Loading branch information
houmain committed Apr 24, 2024
1 parent a9c535f commit fe52025
Showing 1 changed file with 64 additions and 8 deletions.
72 changes: 64 additions & 8 deletions src/server/unix/VirtualDeviceMacOS.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <atomic>
#include <pqrs/karabiner/driverkit/virtual_hid_device_driver.hpp>
#include <pqrs/karabiner/driverkit/virtual_hid_device_service.hpp>
#include <IOKit/hid/IOHIDManager.h>

using namespace pqrs::karabiner::driverkit;

Expand All @@ -18,6 +19,9 @@ class VirtualDeviceImpl {
std::atomic<State> m_state{ };
virtual_hid_device_service::client m_client;
virtual_hid_device_driver::hid_report::keyboard_input m_keyboard;
virtual_hid_device_driver::hid_report::consumer_input m_consumer;
virtual_hid_device_driver::hid_report::generic_desktop_input m_desktop;
bool m_fn_key_hold{ };

public:
bool create([[maybe_unused]] const char* name) {
Expand Down Expand Up @@ -62,19 +66,71 @@ class VirtualDeviceImpl {
if (m_state.load() != State::connected)
return false;

const auto key = static_cast<uint16_t>(event.key);
if (event.state == KeyState::Down)
m_keyboard.keys.insert(key);
else
m_keyboard.keys.erase(key);

m_client.async_post_report(m_keyboard);
// TODO: FN keys are currently hardcoded for my device, find out how to map correctly
if (!m_fn_key_hold && event.key == Key::F6) {
const auto key = kHIDUsage_GD_DoNotDisturb;
if (event.state == KeyState::Down)
m_desktop.keys.insert(key);
else
m_desktop.keys.erase(key);

m_client.async_post_report(m_desktop);
}
else if (!m_fn_key_hold && event.key >= Key::F1 && event.key <= Key::F12) {
const auto key = [&]() {
switch (event.key) {
default:
case Key::F1: return kHIDUsage_Csmr_DisplayBrightnessDecrement;
case Key::F2: return kHIDUsage_Csmr_DisplayBrightnessIncrement;
case Key::F3: return kHIDUsage_Csmr_ACDesktopShowAllWindows;
case Key::F4: return kHIDUsage_Csmr_ACSearch;
case Key::F5: return kHIDUsage_Csmr_VoiceCommand;
case Key::F7: return kHIDUsage_Csmr_ScanPreviousTrack;
case Key::F8: return kHIDUsage_Csmr_PlayOrPause;
case Key::F9: return kHIDUsage_Csmr_ScanNextTrack;
case Key::F10: return kHIDUsage_Csmr_Mute;
case Key::F11: return kHIDUsage_Csmr_VolumeDecrement;
case Key::F12: return kHIDUsage_Csmr_VolumeIncrement;
}
}();
if (event.state == KeyState::Down)
m_consumer.keys.insert(key);
else
m_consumer.keys.erase(key);

m_client.async_post_report(m_consumer);
}
else {
const auto key = static_cast<uint16_t>(event.key);
if (event.state == KeyState::Down)
m_keyboard.keys.insert(key);
else
m_keyboard.keys.erase(key);

m_client.async_post_report(m_keyboard);
}
return true;
}

bool flush() {
return true;
}

bool send_event(int page, int usage, int value) {
if (page == kHIDPage_KeyboardOrKeypad &&
(usage < kHIDUsage_KeyboardA ||
usage > kHIDUsage_KeyboardRightGUI))
return false;

#if !defined(NDEBUG)
verbose("PAGE: %04x, USAGE: %04x, VALUE: %04x", page, usage, value);
#endif

if (page == 0xFF) {
m_fn_key_hold = (value != 0);
}
return true;
}
};

//-------------------------------------------------------------------------
Expand Down Expand Up @@ -106,7 +162,7 @@ bool VirtualDevice::send_key_event(const KeyEvent& event) {
}

bool VirtualDevice::send_event(int type, int code, int value) {
return false;
return (m_impl && m_impl->send_event(type, code, value));
}

bool VirtualDevice::flush() {
Expand Down

0 comments on commit fe52025

Please sign in to comment.