diff --git a/src/mouse_area.rs b/src/mouse_area.rs index 22fe1bc..67c4dfa 100644 --- a/src/mouse_area.rs +++ b/src/mouse_area.rs @@ -23,7 +23,6 @@ use cosmic::{ widget::Id, Element, Renderer, Theme, }; - use crate::tab::DOUBLE_CLICK_DURATION; /// Emit messages on mouse events. @@ -223,6 +222,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 +515,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 +570,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 c69f38e..15f6e94 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,