fix(core): handle AllModifiersRelease event on macOS to prevent modifier state getting out-of-sync with shortcuts. Fix #791
This commit is contained in:
parent
0b23a5cc30
commit
44dd54e2e1
|
@ -37,12 +37,12 @@ impl<'a> funnel::Source<'a> for DetectSource {
|
|||
select.recv(&self.receiver)
|
||||
}
|
||||
|
||||
fn receive(&self, op: SelectedOperation) -> Event {
|
||||
fn receive(&self, op: SelectedOperation) -> Option<Event> {
|
||||
let (input_event, source_id) = op
|
||||
.recv(&self.receiver)
|
||||
.expect("unable to select data from DetectSource receiver");
|
||||
match input_event {
|
||||
InputEvent::Keyboard(keyboard_event) => Event {
|
||||
InputEvent::Keyboard(keyboard_event) => Some(Event {
|
||||
source_id,
|
||||
etype: EventType::Keyboard(KeyboardEvent {
|
||||
key: convert_to_engine_key(keyboard_event.key),
|
||||
|
@ -50,20 +50,21 @@ impl<'a> funnel::Source<'a> for DetectSource {
|
|||
status: convert_to_engine_status(keyboard_event.status),
|
||||
variant: keyboard_event.variant.map(convert_to_engine_variant),
|
||||
}),
|
||||
},
|
||||
InputEvent::Mouse(mouse_event) => Event {
|
||||
}),
|
||||
InputEvent::Mouse(mouse_event) => Some(Event {
|
||||
source_id,
|
||||
etype: EventType::Mouse(MouseEvent {
|
||||
status: convert_to_engine_status(mouse_event.status),
|
||||
button: convert_to_engine_mouse_button(mouse_event.button),
|
||||
}),
|
||||
},
|
||||
InputEvent::HotKey(hotkey_event) => Event {
|
||||
}),
|
||||
InputEvent::HotKey(hotkey_event) => Some(Event {
|
||||
source_id,
|
||||
etype: EventType::HotKey(HotKeyEvent {
|
||||
hotkey_id: hotkey_event.hotkey_id,
|
||||
}),
|
||||
},
|
||||
}),
|
||||
InputEvent::AllModifiersReleased => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -45,13 +45,13 @@ impl<'a> funnel::Source<'a> for ExitSource<'a> {
|
|||
select.recv(&self.exit_signal)
|
||||
}
|
||||
|
||||
fn receive(&self, op: SelectedOperation) -> Event {
|
||||
fn receive(&self, op: SelectedOperation) -> Option<Event> {
|
||||
let mode = op
|
||||
.recv(&self.exit_signal)
|
||||
.expect("unable to select data from ExitSource receiver");
|
||||
Event {
|
||||
Some(Event {
|
||||
source_id: self.sequencer.next_id(),
|
||||
etype: EventType::ExitRequested(mode),
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -81,6 +81,8 @@ pub fn init_and_spawn(
|
|||
// Update the modifiers state
|
||||
if let Some((modifier, is_pressed)) = get_modifier_status(&event) {
|
||||
modifier_state_store_clone.update_state(modifier, is_pressed);
|
||||
} else if let InputEvent::AllModifiersReleased = &event {
|
||||
modifier_state_store_clone.clear_state();
|
||||
}
|
||||
|
||||
// Update the key state (if needed)
|
||||
|
|
|
@ -91,6 +91,13 @@ impl ModifierStateStore {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn clear_state(&self) {
|
||||
let mut state = self.state.lock().expect("unable to obtain modifier state");
|
||||
for (_, status) in &mut state.modifiers {
|
||||
status.release();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct ModifiersState {
|
||||
|
|
|
@ -50,13 +50,13 @@ impl<'a> funnel::Source<'a> for SecureInputSource<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn receive(&self, op: SelectedOperation) -> Event {
|
||||
fn receive(&self, op: SelectedOperation) -> Option<Event> {
|
||||
if cfg!(target_os = "macos") {
|
||||
let si_event = op
|
||||
.recv(&self.receiver)
|
||||
.expect("unable to select data from SecureInputSource receiver");
|
||||
|
||||
Event {
|
||||
Some(Event {
|
||||
source_id: self.sequencer.next_id(),
|
||||
etype: match si_event {
|
||||
SecureInputEvent::Disabled => EventType::SecureInputDisabled,
|
||||
|
@ -64,13 +64,12 @@ impl<'a> funnel::Source<'a> for SecureInputSource<'a> {
|
|||
EventType::SecureInputEnabled(SecureInputEnabledEvent { app_name, app_path })
|
||||
}
|
||||
},
|
||||
}
|
||||
})
|
||||
} else {
|
||||
println!("noop");
|
||||
Event {
|
||||
Some(Event {
|
||||
source_id: self.sequencer.next_id(),
|
||||
etype: EventType::NOOP,
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,12 +46,12 @@ impl<'a> funnel::Source<'a> for UISource<'a> {
|
|||
select.recv(&self.ui_receiver)
|
||||
}
|
||||
|
||||
fn receive(&self, op: SelectedOperation) -> Event {
|
||||
fn receive(&self, op: SelectedOperation) -> Option<Event> {
|
||||
let ui_event = op
|
||||
.recv(&self.ui_receiver)
|
||||
.expect("unable to select data from UISource receiver");
|
||||
|
||||
Event {
|
||||
Some(Event {
|
||||
source_id: self.sequencer.next_id(),
|
||||
etype: match ui_event {
|
||||
UIEvent::TrayIconClick => EventType::TrayIconClicked,
|
||||
|
@ -60,6 +60,6 @@ impl<'a> funnel::Source<'a> for UISource<'a> {
|
|||
}
|
||||
UIEvent::Heartbeat => EventType::Heartbeat,
|
||||
},
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user