mirror of
https://github.com/LGUG2Z/komorebi.git
synced 2026-11-14 04:43:42 +01:00
refactor(mac): use EventChannel for the window events
Same change as the KDE revision: the OnceLock channel, the try_send with the drop warning and the ResizeStep claim/release flag in window_manager_event_listener.rs are now a komorebi_transport::EventChannel<WindowManagerEvent> (capacity 20, predicate matches!(.., ResizeStep(_, _, _))), behind the same three functions. The overflow flag exists and nothing reads it. The macOS keeps its early resize_step_taken call in process_event.rs untouched. The three macOS unit tests of the coalescing (claim/release helpers) moved to the transport crate as tests of EventChannel (D23); the helper functions they tested no longer exist here. The Cargo.lock of the macOS workspace gets the crossbeam-channel dependency of the transport crate. Logs use the target komorebi::transport (D29). Verified: macOS fake-CC cargo check --locked --target aarch64-apple-darwin --workspace --all-targets: 0 errors. macOS unit tests cannot run on Linux (the 3 moved tests run in the transport crate).
This commit is contained in:
1 parent
36ed4b9b29
commit
5cc38da61d
2 files changed
+16
-76
No files matched your search
Generated
+1
@@ -3311,6 +3311,7 @@ name = "komorebi-transport"
|
||||
version = "0.1.42"
|
||||
dependencies = [
|
||||
"color-eyre",
|
||||
"crossbeam-channel",
|
||||
"komorebi-protocol",
|
||||
"tracing",
|
||||
"uds_windows",
|
||||
|
||||
@@ -1,39 +1,24 @@
|
||||
use crate::window_manager_event::WindowManagerEvent;
|
||||
use crossbeam_channel::Receiver;
|
||||
use crossbeam_channel::Sender;
|
||||
use komorebi_transport::EventChannel;
|
||||
use std::sync::OnceLock;
|
||||
use std::sync::atomic::AtomicBool;
|
||||
use std::sync::atomic::Ordering;
|
||||
|
||||
static CHANNEL: OnceLock<(Sender<WindowManagerEvent>, Receiver<WindowManagerEvent>)> =
|
||||
OnceLock::new();
|
||||
static CHANNEL: OnceLock<EventChannel<WindowManagerEvent>> = OnceLock::new();
|
||||
|
||||
/// Whether a step of a drag is waiting in the channel for the window manager to take it
|
||||
static RESIZE_STEP_WAITING: AtomicBool = AtomicBool::new(false);
|
||||
|
||||
fn channel() -> &'static (Sender<WindowManagerEvent>, Receiver<WindowManagerEvent>) {
|
||||
CHANNEL.get_or_init(|| crossbeam_channel::bounded(20))
|
||||
}
|
||||
|
||||
fn event_tx() -> Sender<WindowManagerEvent> {
|
||||
channel().0.clone()
|
||||
fn channel() -> &'static EventChannel<WindowManagerEvent> {
|
||||
// A step of a drag is only a signal that the window has moved, and what is done about it is to
|
||||
// look at where the window is, which is the newest of what any number of them would have said.
|
||||
// So one that waits is enough, and the channel is not filled with the ones that come faster
|
||||
// than they are handled.
|
||||
CHANNEL.get_or_init(|| {
|
||||
EventChannel::coalescing(20, |event| {
|
||||
matches!(event, WindowManagerEvent::ResizeStep(_, _, _))
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
pub fn event_rx() -> Receiver<WindowManagerEvent> {
|
||||
channel().1.clone()
|
||||
}
|
||||
|
||||
/// Whether a step of a drag may be sent, which it may if none is waiting. Says that one is.
|
||||
///
|
||||
/// A step is only a signal that the window has moved, and what is done about it is to look at where
|
||||
/// the window is, which is the newest of what any number of them would have said. So one that waits
|
||||
/// is enough, and the channel is not filled with the ones that come faster than they are handled.
|
||||
fn claim_resize_step(waiting: &AtomicBool) -> bool {
|
||||
!waiting.swap(true, Ordering::AcqRel)
|
||||
}
|
||||
|
||||
fn release_resize_step(waiting: &AtomicBool) {
|
||||
waiting.store(false, Ordering::Release);
|
||||
channel().receiver()
|
||||
}
|
||||
|
||||
/// Say that a step of a drag is being taken, so the next one that comes is let through.
|
||||
@@ -41,55 +26,9 @@ fn release_resize_step(waiting: &AtomicBool) {
|
||||
/// This is for the start of a step and not the end of it: one that comes while a step is being
|
||||
/// taken waits for the next, and the last frame of a drag is never lost.
|
||||
pub fn resize_step_taken() {
|
||||
release_resize_step(&RESIZE_STEP_WAITING);
|
||||
channel().coalesced_taken();
|
||||
}
|
||||
|
||||
pub fn send_notification(notification: WindowManagerEvent) {
|
||||
let is_step = matches!(notification, WindowManagerEvent::ResizeStep(_, _, _));
|
||||
|
||||
if is_step && !claim_resize_step(&RESIZE_STEP_WAITING) {
|
||||
return;
|
||||
}
|
||||
|
||||
if event_tx().try_send(notification).is_err() {
|
||||
// there is nothing in the channel for a step that was not sent to wait for
|
||||
if is_step {
|
||||
resize_step_taken();
|
||||
}
|
||||
|
||||
tracing::warn!("channel is full; dropping notification")
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn a_step_is_let_through_when_none_is_waiting() {
|
||||
let waiting = AtomicBool::new(false);
|
||||
|
||||
assert!(claim_resize_step(&waiting));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn only_one_step_waits_however_many_come() {
|
||||
let waiting = AtomicBool::new(false);
|
||||
|
||||
assert!(claim_resize_step(&waiting));
|
||||
assert!(!claim_resize_step(&waiting));
|
||||
assert!(!claim_resize_step(&waiting));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_step_that_comes_while_one_is_being_taken_is_let_through_for_after() {
|
||||
let waiting = AtomicBool::new(false);
|
||||
assert!(claim_resize_step(&waiting));
|
||||
|
||||
// the handler says that it has begun, and what comes after is the next one
|
||||
release_resize_step(&waiting);
|
||||
|
||||
assert!(claim_resize_step(&waiting));
|
||||
assert!(!claim_resize_step(&waiting));
|
||||
}
|
||||
channel().send(notification);
|
||||
}
|
||||
Reference in new issue
Block a user