diff --git a/.changes/surcor-moved.md b/.changes/surcor-moved.md new file mode 100644 index 000000000..7e35a317c --- /dev/null +++ b/.changes/surcor-moved.md @@ -0,0 +1,5 @@ +--- +"tao": patch +--- + +Add `with_cursor_moved` Unix extension trait method. diff --git a/examples/window.rs b/examples/window.rs index 1ce064d09..2212d0263 100644 --- a/examples/window.rs +++ b/examples/window.rs @@ -42,7 +42,7 @@ fn main() { } Event::MainEventsCleared => { if let Some(w) = &window { - w.request_redraw(); + // w.request_redraw(); } } _ => (), diff --git a/src/platform/unix.rs b/src/platform/unix.rs index ab6f333ab..fa1962c1a 100644 --- a/src/platform/unix.rs +++ b/src/platform/unix.rs @@ -74,6 +74,13 @@ pub trait WindowBuilderExtUnix { /// /// Default is `false` but is always `true` if [`WindowAttributes::transparent`](crate::window::WindowAttributes::transparent) is `true` fn with_app_paintable(self, app_paintable: bool) -> WindowBuilder; + + /// Whether to set cursor moved event. Cursor event is suited for native GUI frameworks and + /// games. But it can block gtk's own pipeline occasionally. Turn this off can help Gtk looks + /// smoother. + /// + /// Default is `true`. + fn with_cursor_moved_event(self, cursor_moved: bool) -> WindowBuilder; } impl WindowBuilderExtUnix for WindowBuilder { @@ -106,6 +113,11 @@ impl WindowBuilderExtUnix for WindowBuilder { self.platform_specific.app_paintable = app_paintable; self } + + fn with_cursor_moved_event(mut self, cursor_moved: bool) -> WindowBuilder { + self.platform_specific.cursor_moved = cursor_moved; + self + } } /// Additional methods on `EventLoop` that are specific to Unix. diff --git a/src/platform_impl/linux/event_loop.rs b/src/platform_impl/linux/event_loop.rs index 97624cc1b..283c55555 100644 --- a/src/platform_impl/linux/event_loop.rs +++ b/src/platform_impl/linux/event_loop.rs @@ -351,7 +351,10 @@ impl EventLoop { window.input_shape_combine_region(None) }; } - WindowRequest::WireUpEvents { transparent } => { + WindowRequest::WireUpEvents { + transparent, + cursor_moved, + } => { window.add_events( EventMask::POINTER_MOTION_MASK | EventMask::BUTTON1_MOTION_MASK @@ -534,19 +537,21 @@ impl EventLoop { let tx_clone = event_tx.clone(); window.connect_motion_notify_event(move |window, motion| { - if let Some(cursor) = motion.device() { - let scale_factor = window.scale_factor(); - let (_, x, y) = cursor.window_at_position(); - if let Err(e) = tx_clone.send(Event::WindowEvent { - window_id: RootWindowId(id), - event: WindowEvent::CursorMoved { - position: LogicalPosition::new(x, y).to_physical(scale_factor as f64), - device_id: DEVICE_ID, - // this field is depracted so it is fine to pass empty state - modifiers: ModifiersState::empty(), - }, - }) { - log::warn!("Failed to send cursor moved event to event channel: {}", e); + if cursor_moved { + if let Some(cursor) = motion.device() { + let scale_factor = window.scale_factor(); + let (_, x, y) = cursor.window_at_position(); + if let Err(e) = tx_clone.send(Event::WindowEvent { + window_id: RootWindowId(id), + event: WindowEvent::CursorMoved { + position: LogicalPosition::new(x, y).to_physical(scale_factor as f64), + device_id: DEVICE_ID, + // this field is depracted so it is fine to pass empty state + modifiers: ModifiersState::empty(), + }, + }) { + log::warn!("Failed to send cursor moved event to event channel: {}", e); + } } } Inhibit(false) diff --git a/src/platform_impl/linux/mod.rs b/src/platform_impl/linux/mod.rs index e592558b4..9da134403 100644 --- a/src/platform_impl/linux/mod.rs +++ b/src/platform_impl/linux/mod.rs @@ -66,6 +66,7 @@ pub struct PlatformSpecificWindowBuilderAttributes { pub double_buffered: bool, pub app_paintable: bool, pub rgba_visual: bool, + pub cursor_moved: bool, } impl Default for PlatformSpecificWindowBuilderAttributes { @@ -77,6 +78,7 @@ impl Default for PlatformSpecificWindowBuilderAttributes { double_buffered: true, app_paintable: false, rgba_visual: false, + cursor_moved: true, } } } diff --git a/src/platform_impl/linux/window.rs b/src/platform_impl/linux/window.rs index 7996979b8..8e7aff785 100644 --- a/src/platform_impl/linux/window.rs +++ b/src/platform_impl/linux/window.rs @@ -317,9 +317,14 @@ impl Window { if attributes.transparent && pl_attribs.auto_transparent { transparent = true; } - if let Err(e) = - window_requests_tx.send((window_id, WindowRequest::WireUpEvents { transparent })) - { + let cursor_moved = pl_attribs.cursor_moved; + if let Err(e) = window_requests_tx.send(( + window_id, + WindowRequest::WireUpEvents { + transparent, + cursor_moved, + }, + )) { log::warn!("Fail to send wire up events request: {}", e); } @@ -832,7 +837,10 @@ pub enum WindowRequest { CursorIcon(Option), CursorPosition((i32, i32)), CursorIgnoreEvents(bool), - WireUpEvents { transparent: bool }, + WireUpEvents { + transparent: bool, + cursor_moved: bool, + }, Menu((Option, Option)), SetMenu((Option, AccelGroup, gtk::MenuBar)), GlobalHotKey(u16),