mirror of
https://github.com/zed-industries/zed.git
synced 2024-09-20 02:47:34 +03:00
Fix mouse scroll in terminal items
This commit is contained in:
parent
a7d0732f95
commit
ad77bb7b92
@ -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) {
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user