prevent stuck scrollbar (#2003)

* prevent stuck scrollbar

* update changelog

* remove debug

* remove debug
This commit is contained in:
Will McGugan
2023-03-09 14:13:12 +00:00
committed by GitHub
parent aad6d98aa5
commit f61a50b790
3 changed files with 38 additions and 26 deletions

View File

@@ -34,7 +34,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- Fixed bug that prevented pilot from pressing some keys https://github.com/Textualize/textual/issues/1815
- DataTable race condition that caused crash https://github.com/Textualize/textual/pull/1962
- Fixed scrollbar getting "stuck" to cursor when cursor leaves window during drag https://github.com/Textualize/textual/pull/1968
- Fixed scrollbar getting "stuck" to cursor when cursor leaves window during drag https://github.com/Textualize/textual/pull/1968 https://github.com/Textualize/textual/pull/2003
- DataTable crash when enter pressed when table is empty https://github.com/Textualize/textual/pull/1973
## [0.13.0] - 2023-03-02

View File

@@ -27,8 +27,8 @@ class Driver(ABC):
self._size = size
self._loop = asyncio.get_running_loop()
self._mouse_down_time = _clock.get_time_no_wait()
self._dragging = False
self._dragging_button = None
self._down_buttons: list[int] = []
self._last_move_event: events.MouseMove | None = None
@property
def is_headless(self) -> bool:
@@ -44,29 +44,37 @@ class Driver(ABC):
"""Performs some additional processing of events."""
if isinstance(event, events.MouseDown):
self._mouse_down_time = event.time
if event.button:
self._down_buttons.append(event.button)
elif isinstance(event, events.MouseUp):
if event.button:
self._down_buttons.remove(event.button)
elif isinstance(event, events.MouseMove):
if event.button and not self._dragging:
self._dragging = True
self._dragging_button = event.button
elif self._dragging and self._dragging_button != event.button:
# Artificially generate a MouseUp event when we stop "dragging"
self.send_event(
MouseUp(
x=event.x,
y=event.y,
delta_x=event.delta_x,
delta_y=event.delta_y,
button=self._dragging_button,
shift=event.shift,
meta=event.meta,
ctrl=event.ctrl,
screen_x=event.screen_x,
screen_y=event.screen_y,
style=event.style,
if (
self._down_buttons
and not event.button
and self._last_move_event is not None
):
buttons = list(dict.fromkeys(self._down_buttons).keys())
self._down_buttons.clear()
move_event = self._last_move_event
for button in buttons:
self.send_event(
MouseUp(
x=move_event.x,
y=move_event.y,
delta_x=0,
delta_y=0,
button=button,
shift=event.shift,
meta=event.meta,
ctrl=event.ctrl,
screen_x=move_event.screen_x,
screen_y=move_event.screen_y,
style=event.style,
)
)
)
self._dragging = False
self._dragging_button = None
self._last_move_event = event
self.send_event(event)

View File

@@ -291,6 +291,7 @@ class ScrollBar(Widget):
def _on_hide(self, event: events.Hide) -> None:
if self.grabbed:
self.release_mouse()
self.grabbed = None
def _on_enter(self, event: events.Enter) -> None:
self.mouse_over = True
@@ -299,10 +300,12 @@ class ScrollBar(Widget):
self.mouse_over = False
def action_scroll_down(self) -> None:
self.post_message(ScrollDown() if self.vertical else ScrollRight())
if not self.grabbed:
self.post_message(ScrollDown() if self.vertical else ScrollRight())
def action_scroll_up(self) -> None:
self.post_message(ScrollUp() if self.vertical else ScrollLeft())
if not self.grabbed:
self.post_message(ScrollUp() if self.vertical else ScrollLeft())
def action_grab(self) -> None:
self.capture_mouse()
@@ -313,6 +316,7 @@ class ScrollBar(Widget):
async def _on_mouse_up(self, event: events.MouseUp) -> None:
if self.grabbed:
self.release_mouse()
self.grabbed = None
event.stop()
def _on_mouse_capture(self, event: events.MouseCapture) -> None: