From ad77bb7b92f489d0531472cd216c4e4784ebcecf Mon Sep 17 00:00:00 2001 From: K Simmons Date: Tue, 13 Sep 2022 17:37:24 -0700 Subject: [PATCH] Fix mouse scroll in terminal items --- crates/terminal/src/mappings/mouse.rs | 3 +- crates/terminal/src/terminal.rs | 19 +++-- crates/terminal/src/terminal_element.rs | 26 +++---- crates/workspace/src/dock.rs | 99 +++++++++++++++++++++++++ 4 files changed, 124 insertions(+), 23 deletions(-) diff --git a/crates/terminal/src/mappings/mouse.rs b/crates/terminal/src/mappings/mouse.rs index c90cbb5cd3..7d92036b71 100644 --- a/crates/terminal/src/mappings/mouse.rs +++ b/crates/terminal/src/mappings/mouse.rs @@ -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>> { if mode.intersects(TermMode::MOUSE_MODE) { diff --git a/crates/terminal/src/terminal.rs b/crates/terminal/src/terminal.rs index 24c51d0cca..29454ce9c8 100644 --- a/crates/terminal/src/terminal.rs +++ b/crates/terminal/src/terminal.rs @@ -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 { + fn determine_scroll_lines( + &mut self, + e: &ScrollWheelRegionEvent, + mouse_mode: bool, + ) -> Option { let scroll_multiplier = if mouse_mode { 1. } else { SCROLL_MULTIPLIER }; match e.phase { diff --git a/crates/terminal/src/terminal_element.rs b/crates/terminal/src/terminal_element.rs index fb2fb0211a..97a6aa9133 100644 --- a/crates/terminal/src/terminal_element.rs +++ b/crates/terminal/src/terminal_element.rs @@ -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; diff --git a/crates/workspace/src/dock.rs b/crates/workspace/src/dock.rs index a059687193..24286a54ab 100644 --- a/crates/workspace/src/dock.rs +++ b/crates/workspace/src/dock.rs @@ -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, + ) -> Box { + 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 + } +}