Skip to content

Commit 34f60f1

Browse files
Narsiljonatino
andcommitted
Supporting media keys on macos.
Co-Authored-By: Jonathan <[email protected]>
1 parent 15e9d94 commit 34f60f1

File tree

2 files changed

+113
-1
lines changed

2 files changed

+113
-1
lines changed

src/macos/common.rs

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ use std::time::SystemTime;
1010

1111
use crate::macos::keycodes::key_from_code;
1212

13+
use super::keycodes::key_from_special_key;
14+
1315
lazy_static! {
1416
pub static ref LAST_FLAGS: Mutex<CGEventFlags> = Mutex::new(CGEventFlags(0));
1517
pub static ref KEYBOARD_STATE: Mutex<Keyboard> = Mutex::new(Keyboard::new().unwrap());
@@ -53,6 +55,7 @@ pub unsafe fn convert(
5355
})
5456
}
5557
CGEventType::KeyDown => {
58+
println!("Received {cg_event:?}");
5659
let code = CGEvent::integer_value_field(
5760
Some(cg_event.as_ref()),
5861
CGEventField::KeyboardEventKeycode,
@@ -134,7 +137,40 @@ pub unsafe fn convert(
134137
);
135138
Some(EventType::Wheel { delta_x, delta_y })
136139
}
137-
_ => None,
140+
CGEventType(14) => {
141+
// Core graphics doesnt support NX_SYSDEFINED yet
142+
143+
let subtype =
144+
CGEvent::integer_value_field(Some(cg_event.as_ref()), CGEventField(99));
145+
let data1 =
146+
CGEvent::integer_value_field(Some(cg_event.as_ref()), CGEventField(149));
147+
let key_flags = data1 & 0x0000ffff;
148+
let key_pressed = ((key_flags & 0xff00) >> 8) == 0xa;
149+
let _key_repeat = (key_flags & 0x1) == 0x1;
150+
let key_code = (data1 & 0xffff0000) >> 16;
151+
152+
// Mouse buttons like middle click/back/forward are subtype 7
153+
// Subtype 8 means keyboard event
154+
if subtype != 8 {
155+
return None;
156+
}
157+
158+
println!("Received {key_code:?}");
159+
if let Some(code) = key_from_special_key(key_code.try_into().ok()?) {
160+
if key_pressed {
161+
Some(EventType::KeyPress(code))
162+
} else {
163+
Some(EventType::KeyRelease(code))
164+
}
165+
} else {
166+
// If we don't handle the key avoid creating an event since it can create duplicates with other keys
167+
None
168+
}
169+
}
170+
_ev => {
171+
println!("Received {_ev:?}");
172+
None
173+
}
138174
};
139175
if let Some(event_type) = option_type {
140176
let name = match event_type {

src/macos/keycodes.rs

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,82 @@ pub fn key_from_code(code: CGKeyCode) -> Key {
252252
}
253253
}
254254

255+
//https://opensource.apple.com/source/IOHIDFamily/IOHIDFamily-308/IOHIDSystem/IOKit/hidsystem/ev_keymap.h
256+
// https://github.com/acidanthera/MacKernelSDK/blob/master/Headers/IOKit/hidsystem/ev_keymap.h
257+
258+
/*
259+
* Special keys currently known to and understood by the system.
260+
* If new specialty keys are invented, extend this list as appropriate.
261+
* The presence of these keys in a particular implementation is not
262+
* guaranteed.
263+
*/
264+
265+
#[allow(unused)]
266+
const NX_NOSPECIALKEY: u32 = 0xFFFF;
267+
const NX_KEYTYPE_SOUND_UP: u32 = 0;
268+
const NX_KEYTYPE_SOUND_DOWN: u32 = 1;
269+
const NX_KEYTYPE_BRIGHTNESS_UP: u32 = 2;
270+
const NX_KEYTYPE_BRIGHTNESS_DOWN: u32 = 3;
271+
const NX_KEYTYPE_CAPS_LOCK: u32 = 4;
272+
#[allow(unused)]
273+
const NX_KEYTYPE_HELP: u32 = 5;
274+
#[allow(unused)]
275+
const NX_POWER_KEY: u32 = 6;
276+
const NX_KEYTYPE_MUTE: u32 = 7;
277+
const NX_UP_ARROW_KEY: u32 = 8;
278+
const NX_DOWN_ARROW_KEY: u32 = 9;
279+
const NX_KEYTYPE_NUM_LOCK: u32 = 10;
280+
281+
#[allow(unused)]
282+
const NX_KEYTYPE_CONTRAST_UP: u32 = 11;
283+
#[allow(unused)]
284+
const NX_KEYTYPE_CONTRAST_DOWN: u32 = 12;
285+
#[allow(unused)]
286+
const NX_KEYTYPE_LAUNCH_PANEL: u32 = 13;
287+
#[allow(unused)]
288+
const NX_KEYTYPE_EJECT: u32 = 14;
289+
#[allow(unused)]
290+
const NX_KEYTYPE_VIDMIRROR: u32 = 15;
291+
292+
const NX_KEYTYPE_PLAY: u32 = 16;
293+
const NX_KEYTYPE_NEXT: u32 = 17;
294+
const NX_KEYTYPE_PREVIOUS: u32 = 18;
295+
#[allow(unused)]
296+
const NX_KEYTYPE_FAST: u32 = 19;
297+
#[allow(unused)]
298+
const NX_KEYTYPE_REWIND: u32 = 20;
299+
300+
#[allow(unused)]
301+
const NX_KEYTYPE_ILLUMINATION_UP: u32 = 21;
302+
#[allow(unused)]
303+
const NX_KEYTYPE_ILLUMINATION_DOWN: u32 = 22;
304+
#[allow(unused)]
305+
const NX_KEYTYPE_ILLUMINATION_TOGGLE: u32 = 23;
306+
307+
#[allow(unused)]
308+
const NX_NUMSPECIALKEYS: u32 = 24; /* Maximum number of special keys */
309+
#[allow(unused)]
310+
const NX_NUM_SCANNED_SPECIALKEYS: u32 = 24; /* First 24 special keys are */
311+
/* actively scanned in kernel */
312+
313+
pub fn key_from_special_key(code: u32) -> Option<Key> {
314+
match code {
315+
NX_KEYTYPE_SOUND_UP => Some(Key::VolumeUp),
316+
NX_KEYTYPE_SOUND_DOWN => Some(Key::VolumeDown),
317+
NX_KEYTYPE_MUTE => Some(Key::VolumeMute),
318+
NX_KEYTYPE_BRIGHTNESS_UP => Some(Key::BrightnessUp),
319+
NX_KEYTYPE_BRIGHTNESS_DOWN => Some(Key::BrightnessDown),
320+
NX_KEYTYPE_PLAY => Some(Key::PlayPause),
321+
NX_KEYTYPE_NEXT => Some(Key::NextTrack),
322+
NX_KEYTYPE_PREVIOUS => Some(Key::PreviousTrack),
323+
NX_KEYTYPE_CAPS_LOCK => Some(Key::CapsLock),
324+
NX_UP_ARROW_KEY => Some(Key::UpArrow),
325+
NX_DOWN_ARROW_KEY => Some(Key::DownArrow),
326+
NX_KEYTYPE_NUM_LOCK => Some(Key::NumLock),
327+
_ => None,
328+
}
329+
}
330+
255331
#[cfg(test)]
256332
mod test {
257333
use super::{code_from_key, key_from_code};

0 commit comments

Comments
 (0)