Skip to content

Commit

Permalink
refactor(linux): reduce channel redirect (#588)
Browse files Browse the repository at this point in the history
* refactor(linux): reduce channel redirect

* Add version bump in change file

Co-authored-by: Wu Yu Wei <wusyong9104@gmail.com>
  • Loading branch information
wusyong and Wu Yu Wei committed Oct 16, 2022
1 parent 5e3d344 commit dd86a9e
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 30 deletions.
5 changes: 5 additions & 0 deletions .changes/tx-reduce.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"tao": patch
---

On Linux, reduce channel redirect. Now sending user events and redraw request will send to event loops directly.
38 changes: 16 additions & 22 deletions src/platform_impl/linux/event_loop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ use std::{
error::Error,
process,
rc::Rc,
sync::mpsc::SendError,
time::Instant,
};

use cairo::{RectangleInt, Region};
use crossbeam_channel::SendError;
use gdk::{Cursor, CursorType, EventKey, EventMask, ScrollDirection, WindowEdge, WindowState};
use gio::{prelude::*, Cancellable};
use glib::{source::Priority, Continue, MainContext};
Expand Down Expand Up @@ -50,6 +50,8 @@ pub struct EventLoopWindowTarget<T> {
pub(crate) windows: Rc<RefCell<HashSet<WindowId>>>,
/// Window requests sender
pub(crate) window_requests_tx: glib::Sender<(WindowId, WindowRequest)>,
/// Draw event sender
pub(crate) draw_tx: crossbeam_channel::Sender<WindowId>,
_marker: std::marker::PhantomData<T>,
}

Expand Down Expand Up @@ -98,7 +100,7 @@ pub struct EventLoop<T: 'static> {
/// Window target.
window_target: RootELW<T>,
/// User event sender for EventLoopProxy
user_event_tx: glib::Sender<T>,
user_event_tx: crossbeam_channel::Sender<Event<'static, T>>,
/// Event queue of EventLoop
events: crossbeam_channel::Receiver<Event<'static, T>>,
/// Draw queue of EventLoop
Expand Down Expand Up @@ -134,6 +136,8 @@ impl<T: 'static> EventLoop<T> {
log::warn!("Failed to send init event to event channel: {}", e);
}
});
let draw_tx_ = draw_tx.clone();
let user_event_tx = event_tx.clone();

// Create event loop window target.
let (window_requests_tx, window_requests_rx) = glib::MainContext::channel(Priority::default());
Expand All @@ -145,19 +149,10 @@ impl<T: 'static> EventLoop<T> {
app,
windows: Rc::new(RefCell::new(HashSet::new())),
window_requests_tx,
draw_tx: draw_tx_,
_marker: std::marker::PhantomData,
};

// Create user event channel
let (user_event_tx, user_event_rx) = glib::MainContext::channel(Priority::default());
let event_tx_ = event_tx.clone();
user_event_rx.attach(Some(&context), move |event| {
if let Err(e) = event_tx_.send(Event::UserEvent(event)) {
log::warn!("Failed to send user event to event channel: {}", e);
}
Continue(true)
});

// Window Request
window_requests_rx.attach(Some(&context), move |(id, request)| {
if let Some(window) = app_.window_by_id(id.0) {
Expand Down Expand Up @@ -760,13 +755,6 @@ impl<T: 'static> EventLoop<T> {
Inhibit(false)
});
}
WindowRequest::Redraw => {
if let Err(e) = draw_tx.send(id) {
log::warn!("Failed to send redraw event to event channel: {}", e);
}

window.queue_draw();
}
WindowRequest::Menu(m) => match m {
(None, Some(menu_id)) => {
if let Err(e) = event_tx.send(Event::MenuEvent {
Expand Down Expand Up @@ -1055,7 +1043,7 @@ impl<T: 'static> EventLoop<T> {
/// Used to send custom events to `EventLoop`.
#[derive(Debug)]
pub struct EventLoopProxy<T: 'static> {
user_event_tx: glib::Sender<T>,
user_event_tx: crossbeam_channel::Sender<Event<'static, T>>,
}

impl<T: 'static> Clone for EventLoopProxy<T> {
Expand All @@ -1075,8 +1063,14 @@ impl<T: 'static> EventLoopProxy<T> {
pub fn send_event(&self, event: T) -> Result<(), EventLoopClosed<T>> {
self
.user_event_tx
.send(event)
.map_err(|SendError(error)| EventLoopClosed(error))
.send(Event::UserEvent(event))
.map_err(|SendError(event)| {
if let Event::UserEvent(error) = event {
EventLoopClosed(error)
} else {
unreachable!();
}
})
}
}

Expand Down
16 changes: 8 additions & 8 deletions src/platform_impl/linux/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ pub struct Window {
maximized: Rc<AtomicBool>,
minimized: Rc<AtomicBool>,
fullscreen: RefCell<Option<Fullscreen>>,
/// Draw event Sender
draw_tx: crossbeam_channel::Sender<WindowId>,
}

impl Window {
Expand All @@ -73,6 +75,7 @@ impl Window {
) -> Result<Self, RootOsError> {
let app = &event_loop_window_target.app;
let window_requests_tx = event_loop_window_target.window_requests_tx.clone();
let draw_tx = event_loop_window_target.draw_tx.clone();
let window = gtk::ApplicationWindow::builder()
.application(app)
.accept_focus(attributes.focused)
Expand Down Expand Up @@ -318,14 +321,15 @@ impl Window {
log::warn!("Fail to send wire up events request: {}", e);
}

if let Err(e) = window_requests_tx.send((window_id, WindowRequest::Redraw)) {
log::warn!("Fail to send redraw request: {}", e);
if let Err(e) = draw_tx.send(window_id) {
log::warn!("Failed to send redraw event to event channel: {}", e);
}

let win = Self {
window_id,
window,
window_requests_tx,
draw_tx,
accel_group,
menu_bar,
scale_factor,
Expand All @@ -350,11 +354,8 @@ impl Window {
}

pub fn request_redraw(&self) {
if let Err(e) = self
.window_requests_tx
.send((self.window_id, WindowRequest::Redraw))
{
log::warn!("Fail to send redraw request: {}", e);
if let Err(e) = self.draw_tx.send(self.window_id) {
log::warn!("Failed to send redraw event to event channel: {}", e);
}
}

Expand Down Expand Up @@ -820,7 +821,6 @@ pub enum WindowRequest {
CursorPosition((i32, i32)),
CursorIgnoreEvents(bool),
WireUpEvents { transparent: bool },
Redraw,
Menu((Option<MenuItem>, Option<MenuId>)),
SetMenu((Option<menu::Menu>, AccelGroup, gtk::MenuBar)),
GlobalHotKey(u16),
Expand Down

0 comments on commit dd86a9e

Please sign in to comment.