Fix mouse scroll in terminal items

This commit is contained in:
K Simmons 2022-09-13 17:37:24 -07:00
parent a7d0732f95
commit ad77bb7b92
4 changed files with 124 additions and 23 deletions

View File

@ -6,6 +6,7 @@ use alacritty_terminal::grid::Dimensions;
/// with modifications for our circumstances
use alacritty_terminal::index::{Column as GridCol, Line as GridLine, Point, Side};
use alacritty_terminal::term::TermMode;
use gpui::scene::ScrollWheelRegionEvent;
use gpui::{geometry::vector::Vector2F, MouseButtonEvent, MouseMovedEvent, ScrollWheelEvent};
use crate::TerminalSize;
@ -114,7 +115,7 @@ impl MouseButton {
pub fn scroll_report(
point: Point,
scroll_lines: i32,
e: &ScrollWheelEvent,
e: &ScrollWheelRegionEvent,
mode: TermMode,
) -> Option<impl Iterator<Item = Vec<u8>>> {
if mode.intersects(TermMode::MOUSE_MODE) {

View File

@ -49,9 +49,10 @@ use thiserror::Error;
use gpui::{
geometry::vector::{vec2f, Vector2F},
keymap::Keystroke,
scene::{ClickRegionEvent, DownRegionEvent, DragRegionEvent, UpRegionEvent},
ClipboardItem, Entity, ModelContext, MouseButton, MouseMovedEvent, MutableAppContext,
ScrollWheelEvent, Task,
scene::{
ClickRegionEvent, DownRegionEvent, DragRegionEvent, ScrollWheelRegionEvent, UpRegionEvent,
},
ClipboardItem, Entity, ModelContext, MouseButton, MouseMovedEvent, MutableAppContext, Task,
};
use crate::mappings::{
@ -904,10 +905,10 @@ impl Terminal {
}
///Scroll the terminal
pub fn scroll_wheel(&mut self, e: &ScrollWheelEvent, origin: Vector2F) {
pub fn scroll_wheel(&mut self, e: ScrollWheelRegionEvent, origin: Vector2F) {
let mouse_mode = self.mouse_mode(e.shift);
if let Some(scroll_lines) = self.determine_scroll_lines(e, mouse_mode) {
if let Some(scroll_lines) = self.determine_scroll_lines(&e, mouse_mode) {
if mouse_mode {
let point = mouse_point(
e.position.sub(origin),
@ -916,7 +917,7 @@ impl Terminal {
);
if let Some(scrolls) =
scroll_report(point, scroll_lines as i32, e, self.last_content.mode)
scroll_report(point, scroll_lines as i32, &e, self.last_content.mode)
{
for scroll in scrolls {
self.pty_tx.notify(scroll);
@ -939,7 +940,11 @@ impl Terminal {
}
}
fn determine_scroll_lines(&mut self, e: &ScrollWheelEvent, mouse_mode: bool) -> Option<i32> {
fn determine_scroll_lines(
&mut self,
e: &ScrollWheelRegionEvent,
mouse_mode: bool,
) -> Option<i32> {
let scroll_multiplier = if mouse_mode { 1. } else { SCROLL_MULTIPLIER };
match e.phase {

View File

@ -427,7 +427,14 @@ impl TerminalElement {
position: e.position,
});
}
});
})
.on_scroll(TerminalElement::generic_button_handler(
connection,
origin,
move |terminal, origin, e, _cx| {
terminal.scroll_wheel(e, origin);
},
));
// Mouse mode handlers:
// All mouse modes need the extra click handlers
@ -742,24 +749,13 @@ impl Element for TerminalElement {
fn dispatch_event(
&mut self,
event: &gpui::Event,
bounds: gpui::geometry::rect::RectF,
visible_bounds: gpui::geometry::rect::RectF,
layout: &mut Self::LayoutState,
_bounds: gpui::geometry::rect::RectF,
_visible_bounds: gpui::geometry::rect::RectF,
_layout: &mut Self::LayoutState,
_paint: &mut Self::PaintState,
cx: &mut gpui::EventContext,
) -> bool {
match event {
Event::ScrollWheel(e) => visible_bounds
.contains_point(e.position)
.then(|| {
let origin = bounds.origin() + vec2f(layout.size.cell_width, 0.);
if let Some(terminal) = self.terminal.upgrade(cx.app) {
terminal.update(cx.app, |term, _| term.scroll_wheel(e, origin));
cx.notify();
}
})
.is_some(),
Event::KeyDown(KeyDownEvent { keystroke, .. }) => {
if !cx.is_parent_view_focused() {
return false;

View File

@ -369,3 +369,102 @@ impl StatusItemView for ToggleDockButton {
//Not applicable
}
}
#[cfg(test)]
mod tests {
use super::*;
use gpui::{TestAppContext, ViewContext};
use project::{FakeFs, Project};
use settings::Settings;
use crate::{tests::TestItem, ItemHandle, Workspace};
pub fn default_item_factory(
_workspace: &mut Workspace,
cx: &mut ViewContext<Workspace>,
) -> Box<dyn ItemHandle> {
Box::new(cx.add_view(|_| TestItem::new()))
}
#[gpui::test]
async fn test_dock_hides_when_pane_empty(cx: &mut TestAppContext) {
cx.foreground().forbid_parking();
Settings::test_async(cx);
let fs = FakeFs::new(cx.background());
let project = Project::test(fs, [], cx).await;
let (_, workspace) = cx.add_window(|cx| Workspace::new(project, default_item_factory, cx));
// Open dock
workspace.update(cx, |workspace, cx| {
Dock::show(workspace, cx);
});
// Ensure dock has an item in it
let dock_item_handle = workspace.read_with(cx, |workspace, cx| {
let dock = workspace.dock_pane().read(cx);
dock.items()
.next()
.expect("Dock should have an item in it")
.clone()
});
// Close item
let close_task = workspace.update(cx, |workspace, cx| {
Pane::close_item(
workspace,
workspace.dock_pane().clone(),
dock_item_handle.id(),
cx,
)
});
close_task.await.expect("Dock item closed successfully");
// Ensure dock closes
workspace.read_with(cx, |workspace, cx| {
assert!(workspace.dock.visible_pane().is_some())
});
// Open again
workspace.update(cx, |workspace, cx| {
Dock::show(workspace, cx);
});
// Ensure dock has item in it
workspace.read_with(cx, |workspace, cx| {
let dock = workspace.dock_pane().read(cx);
dock.items().next().expect("Dock should have an item in it");
});
}
#[gpui::test]
async fn test_dock_panel_collisions(cx: &mut TestAppContext) {
// Open dock expanded
// Open left panel
// Ensure dock closes
// Open dock to the right
// Open left panel
// Ensure dock is left open
// Open right panel
// Ensure dock closes
// Open dock bottom
// Open left panel
// Open right panel
// Ensure dock still open
}
#[gpui::test]
async fn test_focusing_panes_shows_and_hides_dock(cx: &mut TestAppContext) {
// Open item in center pane
// Open dock expanded
// Focus new item
// Ensure the dock gets hidden
// Open dock to the right
// Focus new item
// Ensure dock stays shown but inactive
// Add item to dock and hide it
// Focus the added item
// Ensure the dock is open
}
}