Fix mouse scroll in terminal items
This commit is contained in:
parent
a7d0732f95
commit
ad77bb7b92
4 changed files with 124 additions and 23 deletions
|
@ -6,6 +6,7 @@ use alacritty_terminal::grid::Dimensions;
|
||||||
/// with modifications for our circumstances
|
/// with modifications for our circumstances
|
||||||
use alacritty_terminal::index::{Column as GridCol, Line as GridLine, Point, Side};
|
use alacritty_terminal::index::{Column as GridCol, Line as GridLine, Point, Side};
|
||||||
use alacritty_terminal::term::TermMode;
|
use alacritty_terminal::term::TermMode;
|
||||||
|
use gpui::scene::ScrollWheelRegionEvent;
|
||||||
use gpui::{geometry::vector::Vector2F, MouseButtonEvent, MouseMovedEvent, ScrollWheelEvent};
|
use gpui::{geometry::vector::Vector2F, MouseButtonEvent, MouseMovedEvent, ScrollWheelEvent};
|
||||||
|
|
||||||
use crate::TerminalSize;
|
use crate::TerminalSize;
|
||||||
|
@ -114,7 +115,7 @@ impl MouseButton {
|
||||||
pub fn scroll_report(
|
pub fn scroll_report(
|
||||||
point: Point,
|
point: Point,
|
||||||
scroll_lines: i32,
|
scroll_lines: i32,
|
||||||
e: &ScrollWheelEvent,
|
e: &ScrollWheelRegionEvent,
|
||||||
mode: TermMode,
|
mode: TermMode,
|
||||||
) -> Option<impl Iterator<Item = Vec<u8>>> {
|
) -> Option<impl Iterator<Item = Vec<u8>>> {
|
||||||
if mode.intersects(TermMode::MOUSE_MODE) {
|
if mode.intersects(TermMode::MOUSE_MODE) {
|
||||||
|
|
|
@ -49,9 +49,10 @@ use thiserror::Error;
|
||||||
use gpui::{
|
use gpui::{
|
||||||
geometry::vector::{vec2f, Vector2F},
|
geometry::vector::{vec2f, Vector2F},
|
||||||
keymap::Keystroke,
|
keymap::Keystroke,
|
||||||
scene::{ClickRegionEvent, DownRegionEvent, DragRegionEvent, UpRegionEvent},
|
scene::{
|
||||||
ClipboardItem, Entity, ModelContext, MouseButton, MouseMovedEvent, MutableAppContext,
|
ClickRegionEvent, DownRegionEvent, DragRegionEvent, ScrollWheelRegionEvent, UpRegionEvent,
|
||||||
ScrollWheelEvent, Task,
|
},
|
||||||
|
ClipboardItem, Entity, ModelContext, MouseButton, MouseMovedEvent, MutableAppContext, Task,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::mappings::{
|
use crate::mappings::{
|
||||||
|
@ -904,10 +905,10 @@ impl Terminal {
|
||||||
}
|
}
|
||||||
|
|
||||||
///Scroll the 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);
|
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 {
|
if mouse_mode {
|
||||||
let point = mouse_point(
|
let point = mouse_point(
|
||||||
e.position.sub(origin),
|
e.position.sub(origin),
|
||||||
|
@ -916,7 +917,7 @@ impl Terminal {
|
||||||
);
|
);
|
||||||
|
|
||||||
if let Some(scrolls) =
|
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 {
|
for scroll in scrolls {
|
||||||
self.pty_tx.notify(scroll);
|
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 };
|
let scroll_multiplier = if mouse_mode { 1. } else { SCROLL_MULTIPLIER };
|
||||||
|
|
||||||
match e.phase {
|
match e.phase {
|
||||||
|
|
|
@ -427,7 +427,14 @@ impl TerminalElement {
|
||||||
position: e.position,
|
position: e.position,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
|
.on_scroll(TerminalElement::generic_button_handler(
|
||||||
|
connection,
|
||||||
|
origin,
|
||||||
|
move |terminal, origin, e, _cx| {
|
||||||
|
terminal.scroll_wheel(e, origin);
|
||||||
|
},
|
||||||
|
));
|
||||||
|
|
||||||
// Mouse mode handlers:
|
// Mouse mode handlers:
|
||||||
// All mouse modes need the extra click handlers
|
// All mouse modes need the extra click handlers
|
||||||
|
@ -742,24 +749,13 @@ impl Element for TerminalElement {
|
||||||
fn dispatch_event(
|
fn dispatch_event(
|
||||||
&mut self,
|
&mut self,
|
||||||
event: &gpui::Event,
|
event: &gpui::Event,
|
||||||
bounds: gpui::geometry::rect::RectF,
|
_bounds: gpui::geometry::rect::RectF,
|
||||||
visible_bounds: gpui::geometry::rect::RectF,
|
_visible_bounds: gpui::geometry::rect::RectF,
|
||||||
layout: &mut Self::LayoutState,
|
_layout: &mut Self::LayoutState,
|
||||||
_paint: &mut Self::PaintState,
|
_paint: &mut Self::PaintState,
|
||||||
cx: &mut gpui::EventContext,
|
cx: &mut gpui::EventContext,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
match event {
|
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, .. }) => {
|
Event::KeyDown(KeyDownEvent { keystroke, .. }) => {
|
||||||
if !cx.is_parent_view_focused() {
|
if !cx.is_parent_view_focused() {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -369,3 +369,102 @@ impl StatusItemView for ToggleDockButton {
|
||||||
//Not applicable
|
//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…
Add table
Add a link
Reference in a new issue