refactor: allow changing the menu event sender

This commit is contained in:
amrbashir
2023-01-03 04:05:00 +02:00
parent c6d65d12f8
commit cbf5c44b11
6 changed files with 53 additions and 32 deletions

View File

@@ -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);
}
```

View File

@@ -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();
}
}

View File

@@ -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();
}
}

View File

@@ -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 {

View File

@@ -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)

View File

@@ -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) => {