Detailed changes
@@ -41,6 +41,7 @@ pub struct Keystroke {
pub alt: bool,
pub shift: bool,
pub cmd: bool,
+ pub function: bool,
pub key: String,
}
@@ -277,6 +278,7 @@ impl Keystroke {
let mut alt = false;
let mut shift = false;
let mut cmd = false;
+ let mut function = false;
let mut key = None;
let mut components = source.split("-").peekable();
@@ -286,6 +288,7 @@ impl Keystroke {
"alt" => alt = true,
"shift" => shift = true,
"cmd" => cmd = true,
+ "fn" => function = true,
_ => {
if let Some(component) = components.peek() {
if component.is_empty() && source.ends_with('-') {
@@ -306,6 +309,7 @@ impl Keystroke {
alt,
shift,
cmd,
+ function,
key: key.unwrap(),
})
}
@@ -464,6 +468,7 @@ mod tests {
alt: false,
shift: false,
cmd: false,
+ function: false,
}
);
@@ -475,6 +480,7 @@ mod tests {
alt: true,
shift: true,
cmd: false,
+ function: false,
}
);
@@ -486,6 +492,7 @@ mod tests {
alt: false,
shift: true,
cmd: true,
+ function: false,
}
);
@@ -210,19 +210,24 @@ impl Event {
unsafe fn parse_keystroke(native_event: id) -> Keystroke {
use cocoa::appkit::*;
+ let mut chars_ignoring_modifiers =
+ CStr::from_ptr(native_event.charactersIgnoringModifiers().UTF8String() as *mut c_char)
+ .to_str()
+ .unwrap();
+ let first_char = chars_ignoring_modifiers.chars().next().map(|ch| ch as u16);
let modifiers = native_event.modifierFlags();
+
let ctrl = modifiers.contains(NSEventModifierFlags::NSControlKeyMask);
let alt = modifiers.contains(NSEventModifierFlags::NSAlternateKeyMask);
let mut shift = modifiers.contains(NSEventModifierFlags::NSShiftKeyMask);
let cmd = modifiers.contains(NSEventModifierFlags::NSCommandKeyMask);
-
- let mut chars_ignoring_modifiers =
- CStr::from_ptr(native_event.charactersIgnoringModifiers().UTF8String() as *mut c_char)
- .to_str()
- .unwrap();
+ let function = modifiers.contains(NSEventModifierFlags::NSFunctionKeyMask)
+ && first_char.map_or(true, |ch| {
+ ch < NSUpArrowFunctionKey || ch > NSModeSwitchFunctionKey
+ });
#[allow(non_upper_case_globals)]
- let key = match chars_ignoring_modifiers.chars().next().map(|ch| ch as u16) {
+ let key = match first_char {
Some(SPACE_KEY) => "space",
Some(BACKSPACE_KEY) => "backspace",
Some(ENTER_KEY) | Some(NUMPAD_ENTER_KEY) => "enter",
@@ -282,6 +287,7 @@ unsafe fn parse_keystroke(native_event: id) -> Keystroke {
alt,
shift,
cmd,
+ function,
key: key.into(),
}
}
@@ -711,14 +711,16 @@ extern "C" fn handle_key_event(this: &Object, native_event: id, key_equivalent:
let window_state = unsafe { get_window_state(this) };
let mut window_state_borrow = window_state.as_ref().borrow_mut();
- if key_equivalent {
- window_state_borrow.performed_key_equivalent = true;
- } else if window_state_borrow.performed_key_equivalent {
- return NO;
- }
let event = unsafe { Event::from_native(native_event, Some(window_state_borrow.size().y())) };
if let Some(event) = event {
+ if key_equivalent {
+ window_state_borrow.performed_key_equivalent = true;
+ } else if window_state_borrow.performed_key_equivalent {
+ return NO;
+ }
+
+ let function_is_held;
window_state_borrow.pending_key_down = match event {
Event::KeyDown(event) => {
let keydown = event.keystroke.clone();
@@ -732,15 +734,18 @@ extern "C" fn handle_key_event(this: &Object, native_event: id, key_equivalent:
window_state_borrow.last_fresh_keydown = Some(keydown);
}
+ function_is_held = event.keystroke.function;
Some((event, None))
}
_ => return NO,
};
drop(window_state_borrow);
- unsafe {
- let input_context: id = msg_send![this, inputContext];
- let _: BOOL = msg_send![input_context, handleEvent: native_event];
+ if !function_is_held {
+ unsafe {
+ let input_context: id = msg_send![this, inputContext];
+ let _: BOOL = msg_send![input_context, handleEvent: native_event];
+ }
}
let mut handled = false;
@@ -856,6 +861,7 @@ extern "C" fn cancel_operation(this: &Object, _sel: Sel, _sender: id) {
ctrl: false,
alt: false,
shift: false,
+ function: false,
key: ".".into(),
};
let event = Event::KeyDown(KeyDownEvent {
@@ -311,6 +311,7 @@ mod test {
alt: false,
shift: false,
cmd: false,
+ function: false,
key: "🖖🏻".to_string(), //2 char string
};
assert_eq!(to_esc_str(&ks, &TermMode::NONE), None);