From 87b87f9a83167e7474051fd4c7b45f6e474f002c Mon Sep 17 00:00:00 2001 From: ellieplayswow <164806095+ellieplayswow@users.noreply.github.com> Date: Thu, 20 Feb 2025 21:31:42 +0000 Subject: [PATCH 1/2] Change calculation of virtual drag area to work with subscription by not relying on mouse movements --- src/mouse_area.rs | 60 ++++++++++++++++++++++++++++++++++------------- src/tab.rs | 39 ++++++++++++++++-------------- 2 files changed, 66 insertions(+), 33 deletions(-) diff --git a/src/mouse_area.rs b/src/mouse_area.rs index 22fe1bc..671a47c 100644 --- a/src/mouse_area.rs +++ b/src/mouse_area.rs @@ -23,7 +23,7 @@ use cosmic::{ widget::Id, Element, Renderer, Theme, }; - +use cosmic::iced::window::RedrawRequest; use crate::tab::DOUBLE_CLICK_DURATION; /// Emit messages on mouse events. @@ -223,6 +223,7 @@ struct State { last_position: Option, last_virtual_position: Option, last_in_bounds_position: Option, + last_cursor_offset: Option, drag_initiated: Option, modifiers: Modifiers, prev_click: Option<(mouse::Click, Instant)>, @@ -515,23 +516,31 @@ fn update( } } - if let Event::Mouse(mouse::Event::CursorMoved { .. }) = event { - let position_in = cursor.position_in(layout_bounds); - match (position_in, state.last_position) { - (None, Some(_)) => { - if let Some(message) = widget.on_exit.as_ref() { - shell.publish(message()) - } + // check if offset differs to calculate virtual position + let mut need_to_recalculate = false; + match (state.last_cursor_offset, widget.cursor_offset) { + // check if offset has changed between updates + (Some(last_cursor_offset), Some(cursor_offset)) => { + if last_cursor_offset != cursor_offset { + state.last_cursor_offset = Some(cursor_offset); + need_to_recalculate = true; } - (Some(_), None) => { - if let Some(message) = widget.on_enter.as_ref() { - shell.publish(message()) - } - } - _ => {} - } - state.last_position = position_in; + }, + // we've started moving out of bounds + (None, Some(cursor_offset)) => { + state.last_cursor_offset = Some(cursor_offset); + need_to_recalculate = true; + }, + + // we've moved inbounds + (Some(_), None) => { + state.last_cursor_offset = None; + } + _ => {} + } + + if need_to_recalculate { // if we have a cursor_offset, we need to calculate our "virtual" position // (where we think the ABSOLUTE cursor is) - we'll take the last in bounds position and // clamp it to the layout bounds @@ -562,6 +571,25 @@ fn update( state.last_virtual_position = Some(new_virtual_pos); } } + } + + + if let Event::Mouse(mouse::Event::CursorMoved { .. }) = event { + let position_in = cursor.position_in(layout_bounds); + match (position_in, state.last_position) { + (None, Some(_)) => { + if let Some(message) = widget.on_exit.as_ref() { + shell.publish(message()) + } + } + (Some(_), None) => { + if let Some(message) = widget.on_enter.as_ref() { + shell.publish(message()) + } + } + _ => {} + } + state.last_position = position_in; // set the last in bounds position to be the ABSOLUTE version of position_in if position_in.is_some() { diff --git a/src/tab.rs b/src/tab.rs index f0a1071..2fca5b4 100644 --- a/src/tab.rs +++ b/src/tab.rs @@ -2241,24 +2241,7 @@ impl Tab { 0.0 }; - let mut new_offset = Point { - x: 0.0, - y: scroll_y - }; - if let Some(virtual_cursor_offset) = self.virtual_cursor_offset { - new_offset = Point { - x: new_offset.x + virtual_cursor_offset.x, - y: new_offset.y + virtual_cursor_offset.y, - }; - } - - if let Some(last_scroll_position) = self.last_scroll_position { - new_offset.x = pos.x - last_scroll_position.x; - } - - self.virtual_cursor_offset = Some(new_offset); - self.last_scroll_offset = Some(new_offset); commands.push(Command::AutoScroll(Some(scroll_y))); } @@ -2962,6 +2945,28 @@ impl Tab { self.scroll_opt = Some(viewport.absolute_offset()); } Message::ScrollTab(scroll_speed) => { + let mut new_offset = Point { + x: 0.0, + y: scroll_speed + }; + + if let Some(virtual_cursor_offset) = self.virtual_cursor_offset { + new_offset = Point { + x: new_offset.x + virtual_cursor_offset.x, + y: new_offset.y + virtual_cursor_offset.y, + }; + } + + if let Some(last_scroll_position) = self.last_scroll_position { + if let Some(global_cursor_position) = self.global_cursor_position { + new_offset.x = global_cursor_position.x - last_scroll_position.x; + } + + } + + self.virtual_cursor_offset = Some(new_offset); + self.last_scroll_offset = Some(new_offset); + commands.push(Command::Iced( scrollable::scroll_by(self.scrollable_id.clone(), AbsoluteOffset { x: 0.0, From 9a474d8ecad3430eba60bab38ab283cbe65da9b5 Mon Sep 17 00:00:00 2001 From: ellieplayswow <164806095+ellieplayswow@users.noreply.github.com> Date: Thu, 20 Feb 2025 21:38:25 +0000 Subject: [PATCH 2/2] Removing unused import --- src/mouse_area.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/mouse_area.rs b/src/mouse_area.rs index 671a47c..67c4dfa 100644 --- a/src/mouse_area.rs +++ b/src/mouse_area.rs @@ -23,7 +23,6 @@ use cosmic::{ widget::Id, Element, Renderer, Theme, }; -use cosmic::iced::window::RedrawRequest; use crate::tab::DOUBLE_CLICK_DURATION; /// Emit messages on mouse events.