Merge pull request #816 from ellieplayswow/bugfix/drag-scroll-virtual-cursor-desync
Bugfix to how virtual cursor is calculated before DragEnd when drag-scrolling
This commit is contained in:
commit
cd43d722d6
2 changed files with 65 additions and 33 deletions
|
|
@ -23,7 +23,6 @@ use cosmic::{
|
||||||
widget::Id,
|
widget::Id,
|
||||||
Element, Renderer, Theme,
|
Element, Renderer, Theme,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::tab::DOUBLE_CLICK_DURATION;
|
use crate::tab::DOUBLE_CLICK_DURATION;
|
||||||
|
|
||||||
/// Emit messages on mouse events.
|
/// Emit messages on mouse events.
|
||||||
|
|
@ -223,6 +222,7 @@ struct State {
|
||||||
last_position: Option<Point>,
|
last_position: Option<Point>,
|
||||||
last_virtual_position: Option<Point>,
|
last_virtual_position: Option<Point>,
|
||||||
last_in_bounds_position: Option<Point>,
|
last_in_bounds_position: Option<Point>,
|
||||||
|
last_cursor_offset: Option<Point>,
|
||||||
drag_initiated: Option<Point>,
|
drag_initiated: Option<Point>,
|
||||||
modifiers: Modifiers,
|
modifiers: Modifiers,
|
||||||
prev_click: Option<(mouse::Click, Instant)>,
|
prev_click: Option<(mouse::Click, Instant)>,
|
||||||
|
|
@ -515,23 +515,31 @@ fn update<Message: Clone>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Event::Mouse(mouse::Event::CursorMoved { .. }) = event {
|
// check if offset differs to calculate virtual position
|
||||||
let position_in = cursor.position_in(layout_bounds);
|
let mut need_to_recalculate = false;
|
||||||
match (position_in, state.last_position) {
|
match (state.last_cursor_offset, widget.cursor_offset) {
|
||||||
(None, Some(_)) => {
|
// check if offset has changed between updates
|
||||||
if let Some(message) = widget.on_exit.as_ref() {
|
(Some(last_cursor_offset), Some(cursor_offset)) => {
|
||||||
shell.publish(message())
|
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
|
// 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
|
// (where we think the ABSOLUTE cursor is) - we'll take the last in bounds position and
|
||||||
// clamp it to the layout bounds
|
// clamp it to the layout bounds
|
||||||
|
|
@ -562,6 +570,25 @@ fn update<Message: Clone>(
|
||||||
state.last_virtual_position = Some(new_virtual_pos);
|
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
|
// set the last in bounds position to be the ABSOLUTE version of position_in
|
||||||
if position_in.is_some() {
|
if position_in.is_some() {
|
||||||
|
|
|
||||||
39
src/tab.rs
39
src/tab.rs
|
|
@ -2241,24 +2241,7 @@ impl Tab {
|
||||||
0.0
|
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)));
|
commands.push(Command::AutoScroll(Some(scroll_y)));
|
||||||
}
|
}
|
||||||
|
|
@ -2962,6 +2945,28 @@ impl Tab {
|
||||||
self.scroll_opt = Some(viewport.absolute_offset());
|
self.scroll_opt = Some(viewport.absolute_offset());
|
||||||
}
|
}
|
||||||
Message::ScrollTab(scroll_speed) => {
|
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(
|
commands.push(Command::Iced(
|
||||||
scrollable::scroll_by(self.scrollable_id.clone(), AbsoluteOffset {
|
scrollable::scroll_by(self.scrollable_id.clone(), AbsoluteOffset {
|
||||||
x: 0.0,
|
x: 0.0,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue