mirror of
https://github.com/tauri-apps/global-hotkey.git
synced 2026-01-31 00:45:22 +01:00
refactor: allow changing the menu event sender
This commit is contained in:
@@ -18,12 +18,12 @@ manager.register(hotkey);
|
||||
|
||||
## Processing global hotkey events
|
||||
|
||||
You can use `global_hotkey_event_receiver` to get a reference to the `GlobalHotKeyEventReceiver`
|
||||
You can use `GlobalHotKeyEvent::receiver` to get a reference to the `GlobalHotKeyEventReceiver`
|
||||
which you can use to listen to the hotkey pressed events.
|
||||
```rs
|
||||
use global_hotkey::global_hotkey_event_receiver;
|
||||
use global_hotkey::GlobalHotKeyEvent;
|
||||
|
||||
if let Ok(event) = global_hotkey_event_receiver().try_recv() {
|
||||
if let Ok(event) = GlobalHotKeyEvent::receiver().try_recv() {
|
||||
println!("{:?}", event);
|
||||
}
|
||||
```
|
||||
|
||||
@@ -3,9 +3,8 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
use global_hotkey::{
|
||||
global_hotkey_event_receiver,
|
||||
hotkey::{Code, HotKey, Modifiers},
|
||||
GlobalHotKeyManager,
|
||||
GlobalHotKeyEvent, GlobalHotKeyManager,
|
||||
};
|
||||
use tao::event_loop::{ControlFlow, EventLoopBuilder};
|
||||
|
||||
@@ -22,7 +21,7 @@ fn main() {
|
||||
hotkeys_manager.register(hotkey2).unwrap();
|
||||
hotkeys_manager.register(hotkey3).unwrap();
|
||||
|
||||
let global_hotkey_channel = global_hotkey_event_receiver();
|
||||
let global_hotkey_channel = GlobalHotKeyEvent::receiver();
|
||||
|
||||
event_loop.run(move |_event, _, control_flow| {
|
||||
*control_flow = ControlFlow::Poll;
|
||||
@@ -30,7 +29,7 @@ fn main() {
|
||||
if let Ok(event) = global_hotkey_channel.try_recv() {
|
||||
println!("{:?}", event);
|
||||
|
||||
if hotkey2.id() == event.id() {
|
||||
if hotkey2.id() == event.id {
|
||||
hotkeys_manager.unregister(hotkey2).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,9 +3,8 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
use global_hotkey::{
|
||||
global_hotkey_event_receiver,
|
||||
hotkey::{Code, HotKey, Modifiers},
|
||||
GlobalHotKeyManager,
|
||||
GlobalHotKeyEvent, GlobalHotKeyManager,
|
||||
};
|
||||
use winit::event_loop::{ControlFlow, EventLoopBuilder};
|
||||
|
||||
@@ -22,7 +21,7 @@ fn main() {
|
||||
hotkeys_manager.register(hotkey2).unwrap();
|
||||
hotkeys_manager.register(hotkey3).unwrap();
|
||||
|
||||
let global_hotkey_channel = global_hotkey_event_receiver();
|
||||
let global_hotkey_channel = GlobalHotKeyEvent::receiver();
|
||||
|
||||
event_loop.run(move |_event, _, control_flow| {
|
||||
*control_flow = ControlFlow::Poll;
|
||||
@@ -30,7 +29,7 @@ fn main() {
|
||||
if let Ok(event) = global_hotkey_channel.try_recv() {
|
||||
println!("{:?}", event);
|
||||
|
||||
if hotkey2.id() == event.id() {
|
||||
if hotkey2.id() == event.id {
|
||||
hotkeys_manager.unregister(hotkey2).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
53
src/lib.rs
53
src/lib.rs
@@ -39,7 +39,7 @@
|
||||
//! - Linux (X11 Only)
|
||||
|
||||
use crossbeam_channel::{unbounded, Receiver, Sender};
|
||||
use once_cell::sync::Lazy;
|
||||
use once_cell::sync::{Lazy, OnceCell};
|
||||
|
||||
mod counter;
|
||||
mod error;
|
||||
@@ -50,26 +50,53 @@ pub use self::error::*;
|
||||
use hotkey::HotKey;
|
||||
|
||||
/// Contains the id of the triggered [`HotKey`].
|
||||
/// Describes a global hotkey event emitted when a [`HotKey`] is pressed.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub struct GlobalHotKeyEvent(pub u32);
|
||||
|
||||
impl GlobalHotKeyEvent {
|
||||
/// Returns the id contained in this event
|
||||
pub fn id(&self) -> u32 {
|
||||
self.0
|
||||
}
|
||||
pub struct GlobalHotKeyEvent {
|
||||
/// Id of the associated [`HotKey`]
|
||||
pub id: u32,
|
||||
}
|
||||
|
||||
/// A reciever that could be used to listen to tray events.
|
||||
/// A reciever that could be used to listen to global hotkey events.
|
||||
pub type GlobalHotKeyEventReceiver = Receiver<GlobalHotKeyEvent>;
|
||||
type GlobalHotKeyEventHandler = Box<dyn Fn(GlobalHotKeyEvent) + Send + Sync + 'static>;
|
||||
|
||||
static GLOBAL_HOTKEY_CHANNEL: Lazy<(Sender<GlobalHotKeyEvent>, GlobalHotKeyEventReceiver)> =
|
||||
Lazy::new(unbounded);
|
||||
static GLOBAL_HOTKEY_EVENT_HANDLER: OnceCell<Option<GlobalHotKeyEventHandler>> = OnceCell::new();
|
||||
|
||||
/// Gets a reference to the event channel's [GlobalHotKeyEventReceiver]
|
||||
/// which can be used to listen for tray events.
|
||||
pub fn global_hotkey_event_receiver<'a>() -> &'a GlobalHotKeyEventReceiver {
|
||||
&GLOBAL_HOTKEY_CHANNEL.1
|
||||
impl GlobalHotKeyEvent {
|
||||
/// Gets a reference to the event channel's [`GlobalHotKeyEventReceiver`]
|
||||
/// which can be used to listen for global hotkey events.
|
||||
///
|
||||
/// ## Note
|
||||
///
|
||||
/// This will not receive any events if [`GlobalHotKeyEvent::set_event_handler`] has been called with a `Some` value.
|
||||
pub fn receiver<'a>() -> &'a GlobalHotKeyEventReceiver {
|
||||
&GLOBAL_HOTKEY_CHANNEL.1
|
||||
}
|
||||
|
||||
/// Set a handler to be called for new events. Useful for implementing custom event sender.
|
||||
///
|
||||
/// ## Note
|
||||
///
|
||||
/// Calling this function with a `Some` value,
|
||||
/// will not send new events to the channel associated with [`GlobalHotKeyEvent::receiver`]
|
||||
pub fn set_event_handler<F: Fn(GlobalHotKeyEvent) + Send + Sync + 'static>(f: Option<F>) {
|
||||
if let Some(f) = f {
|
||||
let _ = GLOBAL_HOTKEY_EVENT_HANDLER.set(Some(Box::new(f)));
|
||||
} else {
|
||||
let _ = GLOBAL_HOTKEY_EVENT_HANDLER.set(None);
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn send(event: GlobalHotKeyEvent) {
|
||||
if let Some(handler) = GLOBAL_HOTKEY_EVENT_HANDLER.get_or_init(|| None) {
|
||||
handler(event);
|
||||
} else {
|
||||
let _ = GLOBAL_HOTKEY_CHANNEL.0.send(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct GlobalHotKeyManager {
|
||||
|
||||
@@ -30,7 +30,7 @@ use windows_sys::Win32::{
|
||||
},
|
||||
};
|
||||
|
||||
use crate::{hotkey::HotKey, GLOBAL_HOTKEY_CHANNEL};
|
||||
use crate::{hotkey::HotKey, GlobalHotKeyEvent};
|
||||
|
||||
const GLOBAL_HOTKEY_SUBCLASS_ID: usize = 6001;
|
||||
|
||||
@@ -151,9 +151,7 @@ unsafe extern "system" fn global_hotkey_subclass_proc(
|
||||
_subclass_input_ptr: usize,
|
||||
) -> LRESULT {
|
||||
if msg == WM_HOTKEY {
|
||||
let _ = &GLOBAL_HOTKEY_CHANNEL
|
||||
.0
|
||||
.send(crate::GlobalHotKeyEvent(wparam as _));
|
||||
GlobalHotKeyEvent::send(GlobalHotKeyEvent { id: wparam as _ });
|
||||
}
|
||||
|
||||
DefSubclassProc(hwnd, msg, wparam, lparam)
|
||||
|
||||
@@ -8,7 +8,7 @@ use crossbeam_channel::{unbounded, Sender};
|
||||
use keyboard_types::{Code, Modifiers};
|
||||
use x11_dl::{keysym, xlib};
|
||||
|
||||
use crate::{hotkey::HotKey, GLOBAL_HOTKEY_CHANNEL};
|
||||
use {crate::hotkey::HotKey, GlobalHotKeyEvent};
|
||||
|
||||
enum ThreadMessage {
|
||||
RegisterHotKey(HotKey, Sender<crate::Result<()>>),
|
||||
@@ -57,9 +57,7 @@ impl GlobalHotKeyManager {
|
||||
{
|
||||
match (e, *repeating) {
|
||||
(xlib::KeyPress, false) => {
|
||||
let _ = &GLOBAL_HOTKEY_CHANNEL
|
||||
.0
|
||||
.send(crate::GlobalHotKeyEvent(*id));
|
||||
GlobalHotKeyEvent::send(GlobalHotKeyEvent { id: *id });
|
||||
*repeating = true;
|
||||
}
|
||||
(xlib::KeyRelease, true) => {
|
||||
|
||||
Reference in New Issue
Block a user