From fc36c706d33acaeb020347f3228dc125adaf3d27 Mon Sep 17 00:00:00 2001 From: Keith Simmons Date: Tue, 8 Mar 2022 15:34:44 -0800 Subject: [PATCH 1/2] Add missing mouse button events and mouse history navigation Co-Authored-By: Max Brunsfeld Co-Authored-By: Nathan Sobo --- crates/gpui/src/elements/event_handler.rs | 38 +++++++++++- crates/gpui/src/platform/event.rs | 24 +++++++ crates/gpui/src/platform/mac/event.rs | 42 +++++++++++++ crates/gpui/src/platform/mac/window.rs | 16 +++++ crates/workspace/src/pane.rs | 76 +++++++++++++++-------- crates/zed/src/zed.rs | 20 +++--- 6 files changed, 179 insertions(+), 37 deletions(-) diff --git a/crates/gpui/src/elements/event_handler.rs b/crates/gpui/src/elements/event_handler.rs index 0eea82fa02..2132939c1c 100644 --- a/crates/gpui/src/elements/event_handler.rs +++ b/crates/gpui/src/elements/event_handler.rs @@ -10,6 +10,8 @@ pub struct EventHandler { child: ElementBox, capture: Option bool>>, mouse_down: Option bool>>, + right_mouse_down: Option bool>>, + other_mouse_down: Option bool>>, } impl EventHandler { @@ -18,6 +20,8 @@ impl EventHandler { child, capture: None, mouse_down: None, + right_mouse_down: None, + other_mouse_down: None, } } @@ -29,6 +33,22 @@ impl EventHandler { self } + pub fn on_right_mouse_down(mut self, callback: F) -> Self + where + F: 'static + FnMut(&mut EventContext) -> bool, + { + self.right_mouse_down = Some(Box::new(callback)); + self + } + + pub fn on_other_mouse_down(mut self, callback: F) -> Self + where + F: 'static + FnMut(u16, &mut EventContext) -> bool, + { + self.other_mouse_down = Some(Box::new(callback)); + self + } + pub fn capture(mut self, callback: F) -> Self where F: 'static + FnMut(&Event, RectF, &mut EventContext) -> bool, @@ -86,7 +106,23 @@ impl Element for EventHandler { } } false - } + }, + Event::RightMouseDown { position, .. } => { + if let Some(callback) = self.right_mouse_down.as_mut() { + if bounds.contains_point(*position) { + return callback(cx); + } + } + false + }, + Event::OtherMouseDown { position, button, .. } => { + if let Some(callback) = self.other_mouse_down.as_mut() { + if bounds.contains_point(*position) { + return callback(*button, cx); + } + } + false + }, _ => false, } } diff --git a/crates/gpui/src/platform/event.rs b/crates/gpui/src/platform/event.rs index 98762b306a..19b8eec189 100644 --- a/crates/gpui/src/platform/event.rs +++ b/crates/gpui/src/platform/event.rs @@ -26,6 +26,30 @@ pub enum Event { LeftMouseDragged { position: Vector2F, }, + RightMouseDown { + position: Vector2F, + ctrl: bool, + alt: bool, + shift: bool, + cmd: bool, + click_count: usize, + }, + RightMouseUp { + position: Vector2F, + }, + OtherMouseDown { + position: Vector2F, + button: u16, + ctrl: bool, + alt: bool, + shift: bool, + cmd: bool, + click_count: usize, + }, + OtherMouseUp { + position: Vector2F, + button: u16, + }, MouseMoved { position: Vector2F, left_mouse_down: bool, diff --git a/crates/gpui/src/platform/mac/event.rs b/crates/gpui/src/platform/mac/event.rs index 7c870e4720..4b1f9d3a38 100644 --- a/crates/gpui/src/platform/mac/event.rs +++ b/crates/gpui/src/platform/mac/event.rs @@ -125,6 +125,48 @@ impl Event { window_height - native_event.locationInWindow().y as f32, ), }), + NSEventType::NSRightMouseDown => { + let modifiers = native_event.modifierFlags(); + window_height.map(|window_height| Self::RightMouseDown { + position: vec2f( + native_event.locationInWindow().x as f32, + window_height - native_event.locationInWindow().y as f32, + ), + ctrl: modifiers.contains(NSEventModifierFlags::NSControlKeyMask), + alt: modifiers.contains(NSEventModifierFlags::NSAlternateKeyMask), + shift: modifiers.contains(NSEventModifierFlags::NSShiftKeyMask), + cmd: modifiers.contains(NSEventModifierFlags::NSCommandKeyMask), + click_count: native_event.clickCount() as usize, + }) + } + NSEventType::NSRightMouseUp => window_height.map(|window_height| Self::RightMouseUp { + position: vec2f( + native_event.locationInWindow().x as f32, + window_height - native_event.locationInWindow().y as f32, + ), + }), + NSEventType::NSOtherMouseDown => { + let modifiers = native_event.modifierFlags(); + window_height.map(|window_height| Self::OtherMouseDown { + position: vec2f( + native_event.locationInWindow().x as f32, + window_height - native_event.locationInWindow().y as f32, + ), + button: native_event.buttonNumber() as u16, + ctrl: modifiers.contains(NSEventModifierFlags::NSControlKeyMask), + alt: modifiers.contains(NSEventModifierFlags::NSAlternateKeyMask), + shift: modifiers.contains(NSEventModifierFlags::NSShiftKeyMask), + cmd: modifiers.contains(NSEventModifierFlags::NSCommandKeyMask), + click_count: native_event.clickCount() as usize, + }) + } + NSEventType::NSOtherMouseUp => window_height.map(|window_height| Self::OtherMouseUp { + position: vec2f( + native_event.locationInWindow().x as f32, + window_height - native_event.locationInWindow().y as f32, + ), + button: native_event.buttonNumber() as u16, + }), NSEventType::NSLeftMouseDragged => { window_height.map(|window_height| Self::LeftMouseDragged { position: vec2f( diff --git a/crates/gpui/src/platform/mac/window.rs b/crates/gpui/src/platform/mac/window.rs index 9fd34166ff..5281009155 100644 --- a/crates/gpui/src/platform/mac/window.rs +++ b/crates/gpui/src/platform/mac/window.rs @@ -95,6 +95,22 @@ unsafe fn build_classes() { sel!(mouseUp:), handle_view_event as extern "C" fn(&Object, Sel, id), ); + decl.add_method( + sel!(rightMouseDown:), + handle_view_event as extern "C" fn(&Object, Sel, id), + ); + decl.add_method( + sel!(rightMouseUp:), + handle_view_event as extern "C" fn(&Object, Sel, id), + ); + decl.add_method( + sel!(otherMouseDown:), + handle_view_event as extern "C" fn(&Object, Sel, id), + ); + decl.add_method( + sel!(otherMouseUp:), + handle_view_event as extern "C" fn(&Object, Sel, id), + ); decl.add_method( sel!(mouseMoved:), handle_view_event as extern "C" fn(&Object, Sel, id), diff --git a/crates/workspace/src/pane.rs b/crates/workspace/src/pane.rs index 78f84d7da2..02a7c03c90 100644 --- a/crates/workspace/src/pane.rs +++ b/crates/workspace/src/pane.rs @@ -8,7 +8,7 @@ use gpui::{ keymap::Binding, platform::CursorStyle, AnyViewHandle, Entity, MutableAppContext, Quad, RenderContext, Task, View, ViewContext, - ViewHandle, + ViewHandle, WeakViewHandle, }; use postage::watch; use project::ProjectPath; @@ -27,8 +27,8 @@ action!(ActivateNextItem); action!(CloseActiveItem); action!(CloseInactiveItems); action!(CloseItem, usize); -action!(GoBack); -action!(GoForward); +action!(GoBack, Option>); +action!(GoForward, Option>); const MAX_NAVIGATION_HISTORY_LEN: usize = 1024; @@ -54,11 +54,19 @@ pub fn init(cx: &mut MutableAppContext) { cx.add_action(|pane: &mut Pane, action: &Split, cx| { pane.split(action.0, cx); }); - cx.add_action(|workspace: &mut Workspace, _: &GoBack, cx| { - Pane::go_back(workspace, cx).detach(); + cx.add_action(|workspace: &mut Workspace, action: &GoBack, cx| { + Pane::go_back( + workspace, + action.0.as_ref().and_then(|weak_handle| weak_handle.upgrade(cx)), + cx + ).detach(); }); - cx.add_action(|workspace: &mut Workspace, _: &GoForward, cx| { - Pane::go_forward(workspace, cx).detach(); + cx.add_action(|workspace: &mut Workspace, action: &GoForward, cx| { + Pane::go_forward( + workspace, + action.0.as_ref().and_then(|weak_handle| weak_handle.upgrade(cx)), + cx + ).detach(); }); cx.add_bindings(vec![ @@ -70,8 +78,8 @@ pub fn init(cx: &mut MutableAppContext) { Binding::new("cmd-k down", Split(SplitDirection::Down), Some("Pane")), Binding::new("cmd-k left", Split(SplitDirection::Left), Some("Pane")), Binding::new("cmd-k right", Split(SplitDirection::Right), Some("Pane")), - Binding::new("ctrl--", GoBack, Some("Pane")), - Binding::new("shift-ctrl-_", GoForward, Some("Pane")), + Binding::new("ctrl--", GoBack(None), Some("Pane")), + Binding::new("shift-ctrl-_", GoForward(None), Some("Pane")), ]); } @@ -163,19 +171,19 @@ impl Pane { cx.emit(Event::Activate); } - pub fn go_back(workspace: &mut Workspace, cx: &mut ViewContext) -> Task<()> { + pub fn go_back(workspace: &mut Workspace, pane: Option>, cx: &mut ViewContext) -> Task<()> { Self::navigate_history( workspace, - workspace.active_pane().clone(), + pane.unwrap_or_else(|| workspace.active_pane().clone()), NavigationMode::GoingBack, cx, ) } - pub fn go_forward(workspace: &mut Workspace, cx: &mut ViewContext) -> Task<()> { + pub fn go_forward(workspace: &mut Workspace, pane: Option>, cx: &mut ViewContext) -> Task<()> { Self::navigate_history( workspace, - workspace.active_pane().clone(), + pane.unwrap_or_else(|| workspace.active_pane().clone()), NavigationMode::GoingForward, cx, ) @@ -187,6 +195,8 @@ impl Pane { mode: NavigationMode, cx: &mut ViewContext, ) -> Task<()> { + workspace.activate_pane(pane.clone(), cx); + let to_load = pane.update(cx, |pane, cx| { // Retrieve the weak item handle from the history. let entry = pane.nav_history.borrow_mut().pop(mode)?; @@ -634,19 +644,33 @@ impl View for Pane { } fn render(&mut self, cx: &mut RenderContext) -> ElementBox { - if let Some(active_item) = self.active_item() { - Flex::column() - .with_child(self.render_tabs(cx)) - .with_children( - self.active_toolbar() - .as_ref() - .map(|view| ChildView::new(view).boxed()), - ) - .with_child(ChildView::new(active_item).flexible(1., true).boxed()) - .named("pane") - } else { - Empty::new().named("pane") - } + let this = cx.handle(); + + EventHandler::new( + if let Some(active_item) = self.active_item() { + Flex::column() + .with_child(self.render_tabs(cx)) + .with_children( + self.active_toolbar() + .as_ref() + .map(|view| ChildView::new(view).boxed()), + ) + .with_child(ChildView::new(active_item).flexible(1., true).boxed()) + .boxed() + } else { + Empty::new().boxed() + } + ) + .on_other_mouse_down(move |button, cx| { + match button { + 3 => cx.dispatch_action(GoBack(Some(this.clone()))), + 4 => cx.dispatch_action(GoForward(Some(this.clone()))), + _ => return false, + }; + true + }) + .named("pane") + } fn on_focus(&mut self, cx: &mut ViewContext) { diff --git a/crates/zed/src/zed.rs b/crates/zed/src/zed.rs index c9a14bf236..75e7735f24 100644 --- a/crates/zed/src/zed.rs +++ b/crates/zed/src/zed.rs @@ -747,44 +747,44 @@ mod tests { (file3.clone(), DisplayPoint::new(15, 0)) ); - workspace.update(cx, |w, cx| Pane::go_back(w, cx)).await; + workspace.update(cx, |w, cx| Pane::go_back(w, None, cx)).await; assert_eq!( active_location(&workspace, cx), (file3.clone(), DisplayPoint::new(0, 0)) ); - workspace.update(cx, |w, cx| Pane::go_back(w, cx)).await; + workspace.update(cx, |w, cx| Pane::go_back(w, None, cx)).await; assert_eq!( active_location(&workspace, cx), (file2.clone(), DisplayPoint::new(0, 0)) ); - workspace.update(cx, |w, cx| Pane::go_back(w, cx)).await; + workspace.update(cx, |w, cx| Pane::go_back(w, None, cx)).await; assert_eq!( active_location(&workspace, cx), (file1.clone(), DisplayPoint::new(10, 0)) ); - workspace.update(cx, |w, cx| Pane::go_back(w, cx)).await; + workspace.update(cx, |w, cx| Pane::go_back(w, None, cx)).await; assert_eq!( active_location(&workspace, cx), (file1.clone(), DisplayPoint::new(0, 0)) ); // Go back one more time and ensure we don't navigate past the first item in the history. - workspace.update(cx, |w, cx| Pane::go_back(w, cx)).await; + workspace.update(cx, |w, cx| Pane::go_back(w, None, cx)).await; assert_eq!( active_location(&workspace, cx), (file1.clone(), DisplayPoint::new(0, 0)) ); - workspace.update(cx, |w, cx| Pane::go_forward(w, cx)).await; + workspace.update(cx, |w, cx| Pane::go_forward(w, None, cx)).await; assert_eq!( active_location(&workspace, cx), (file1.clone(), DisplayPoint::new(10, 0)) ); - workspace.update(cx, |w, cx| Pane::go_forward(w, cx)).await; + workspace.update(cx, |w, cx| Pane::go_forward(w, None, cx)).await; assert_eq!( active_location(&workspace, cx), (file2.clone(), DisplayPoint::new(0, 0)) @@ -798,7 +798,7 @@ mod tests { .update(cx, |pane, cx| pane.close_item(editor3.id(), cx)); drop(editor3); }); - workspace.update(cx, |w, cx| Pane::go_forward(w, cx)).await; + workspace.update(cx, |w, cx| Pane::go_forward(w, None, cx)).await; assert_eq!( active_location(&workspace, cx), (file3.clone(), DisplayPoint::new(0, 0)) @@ -818,12 +818,12 @@ mod tests { }) .await .unwrap(); - workspace.update(cx, |w, cx| Pane::go_back(w, cx)).await; + workspace.update(cx, |w, cx| Pane::go_back(w, None, cx)).await; assert_eq!( active_location(&workspace, cx), (file1.clone(), DisplayPoint::new(10, 0)) ); - workspace.update(cx, |w, cx| Pane::go_forward(w, cx)).await; + workspace.update(cx, |w, cx| Pane::go_forward(w, None, cx)).await; assert_eq!( active_location(&workspace, cx), (file3.clone(), DisplayPoint::new(0, 0)) From 6ee0cceb14337c48495c56c62e50508bf1febfd2 Mon Sep 17 00:00:00 2001 From: Keith Simmons Date: Wed, 9 Mar 2022 15:04:04 -0800 Subject: [PATCH 2/2] Switch to using mouse navigation events instead of other in order to get rid of opaque button id --- crates/gpui/src/elements/event_handler.rs | 28 +++++---- crates/gpui/src/gpui.rs | 2 +- crates/gpui/src/platform.rs | 2 +- crates/gpui/src/platform/event.rs | 14 +++-- crates/gpui/src/platform/mac/event.rs | 40 +++++++++--- crates/workspace/src/pane.rs | 74 ++++++++++++++--------- crates/zed/src/zed.rs | 40 +++++++++--- 7 files changed, 132 insertions(+), 68 deletions(-) diff --git a/crates/gpui/src/elements/event_handler.rs b/crates/gpui/src/elements/event_handler.rs index 2132939c1c..469bebee1a 100644 --- a/crates/gpui/src/elements/event_handler.rs +++ b/crates/gpui/src/elements/event_handler.rs @@ -3,7 +3,7 @@ use serde_json::json; use crate::{ geometry::vector::Vector2F, DebugContext, Element, ElementBox, Event, EventContext, - LayoutContext, PaintContext, SizeConstraint, + LayoutContext, NavigationDirection, PaintContext, SizeConstraint, }; pub struct EventHandler { @@ -11,7 +11,7 @@ pub struct EventHandler { capture: Option bool>>, mouse_down: Option bool>>, right_mouse_down: Option bool>>, - other_mouse_down: Option bool>>, + navigate_mouse_down: Option bool>>, } impl EventHandler { @@ -21,7 +21,7 @@ impl EventHandler { capture: None, mouse_down: None, right_mouse_down: None, - other_mouse_down: None, + navigate_mouse_down: None, } } @@ -41,11 +41,11 @@ impl EventHandler { self } - pub fn on_other_mouse_down(mut self, callback: F) -> Self + pub fn on_navigate_mouse_down(mut self, callback: F) -> Self where - F: 'static + FnMut(u16, &mut EventContext) -> bool, + F: 'static + FnMut(NavigationDirection, &mut EventContext) -> bool, { - self.other_mouse_down = Some(Box::new(callback)); + self.navigate_mouse_down = Some(Box::new(callback)); self } @@ -106,7 +106,7 @@ impl Element for EventHandler { } } false - }, + } Event::RightMouseDown { position, .. } => { if let Some(callback) = self.right_mouse_down.as_mut() { if bounds.contains_point(*position) { @@ -114,15 +114,19 @@ impl Element for EventHandler { } } false - }, - Event::OtherMouseDown { position, button, .. } => { - if let Some(callback) = self.other_mouse_down.as_mut() { + } + Event::NavigateMouseDown { + position, + direction, + .. + } => { + if let Some(callback) = self.navigate_mouse_down.as_mut() { if bounds.contains_point(*position) { - return callback(*button, cx); + return callback(*direction, cx); } } false - }, + } _ => false, } } diff --git a/crates/gpui/src/gpui.rs b/crates/gpui/src/gpui.rs index 49fc74d47b..9803a2aa2f 100644 --- a/crates/gpui/src/gpui.rs +++ b/crates/gpui/src/gpui.rs @@ -29,7 +29,7 @@ pub mod keymap; pub mod platform; pub use gpui_macros::test; pub use platform::FontSystem; -pub use platform::{Event, PathPromptOptions, Platform, PromptLevel}; +pub use platform::{Event, NavigationDirection, PathPromptOptions, Platform, PromptLevel}; pub use presenter::{ Axis, DebugContext, EventContext, LayoutContext, PaintContext, SizeConstraint, Vector2FExt, }; diff --git a/crates/gpui/src/platform.rs b/crates/gpui/src/platform.rs index c04145294c..66bd44b26f 100644 --- a/crates/gpui/src/platform.rs +++ b/crates/gpui/src/platform.rs @@ -19,7 +19,7 @@ use crate::{ }; use anyhow::Result; use async_task::Runnable; -pub use event::Event; +pub use event::{Event, NavigationDirection}; use postage::oneshot; use std::{ any::Any, diff --git a/crates/gpui/src/platform/event.rs b/crates/gpui/src/platform/event.rs index 19b8eec189..72e1c24d6b 100644 --- a/crates/gpui/src/platform/event.rs +++ b/crates/gpui/src/platform/event.rs @@ -1,5 +1,11 @@ use crate::{geometry::vector::Vector2F, keymap::Keystroke}; +#[derive(Copy, Clone, Debug)] +pub enum NavigationDirection { + Back, + Forward, +} + #[derive(Clone, Debug)] pub enum Event { KeyDown { @@ -37,18 +43,18 @@ pub enum Event { RightMouseUp { position: Vector2F, }, - OtherMouseDown { + NavigateMouseDown { position: Vector2F, - button: u16, + direction: NavigationDirection, ctrl: bool, alt: bool, shift: bool, cmd: bool, click_count: usize, }, - OtherMouseUp { + NavigateMouseUp { position: Vector2F, - button: u16, + direction: NavigationDirection, }, MouseMoved { position: Vector2F, diff --git a/crates/gpui/src/platform/mac/event.rs b/crates/gpui/src/platform/mac/event.rs index 4b1f9d3a38..33f9f22e11 100644 --- a/crates/gpui/src/platform/mac/event.rs +++ b/crates/gpui/src/platform/mac/event.rs @@ -1,4 +1,8 @@ -use crate::{geometry::vector::vec2f, keymap::Keystroke, platform::Event}; +use crate::{ + geometry::vector::vec2f, + keymap::Keystroke, + platform::{Event, NavigationDirection}, +}; use cocoa::{ appkit::{NSEvent, NSEventModifierFlags, NSEventType}, base::{id, nil, YES}, @@ -146,13 +150,20 @@ impl Event { ), }), NSEventType::NSOtherMouseDown => { + let direction = match native_event.buttonNumber() { + 3 => NavigationDirection::Back, + 4 => NavigationDirection::Forward, + // Other mouse buttons aren't tracked currently + _ => return None, + }; + let modifiers = native_event.modifierFlags(); - window_height.map(|window_height| Self::OtherMouseDown { + window_height.map(|window_height| Self::NavigateMouseDown { position: vec2f( native_event.locationInWindow().x as f32, window_height - native_event.locationInWindow().y as f32, ), - button: native_event.buttonNumber() as u16, + direction, ctrl: modifiers.contains(NSEventModifierFlags::NSControlKeyMask), alt: modifiers.contains(NSEventModifierFlags::NSAlternateKeyMask), shift: modifiers.contains(NSEventModifierFlags::NSShiftKeyMask), @@ -160,13 +171,22 @@ impl Event { click_count: native_event.clickCount() as usize, }) } - NSEventType::NSOtherMouseUp => window_height.map(|window_height| Self::OtherMouseUp { - position: vec2f( - native_event.locationInWindow().x as f32, - window_height - native_event.locationInWindow().y as f32, - ), - button: native_event.buttonNumber() as u16, - }), + NSEventType::NSOtherMouseUp => { + let direction = match native_event.buttonNumber() { + 3 => NavigationDirection::Back, + 4 => NavigationDirection::Forward, + // Other mouse buttons aren't tracked currently + _ => return None, + }; + + window_height.map(|window_height| Self::NavigateMouseUp { + position: vec2f( + native_event.locationInWindow().x as f32, + window_height - native_event.locationInWindow().y as f32, + ), + direction, + }) + } NSEventType::NSLeftMouseDragged => { window_height.map(|window_height| Self::LeftMouseDragged { position: vec2f( diff --git a/crates/workspace/src/pane.rs b/crates/workspace/src/pane.rs index 02a7c03c90..15195f2434 100644 --- a/crates/workspace/src/pane.rs +++ b/crates/workspace/src/pane.rs @@ -6,7 +6,7 @@ use gpui::{ elements::*, geometry::{rect::RectF, vector::vec2f}, keymap::Binding, - platform::CursorStyle, + platform::{CursorStyle, NavigationDirection}, AnyViewHandle, Entity, MutableAppContext, Quad, RenderContext, Task, View, ViewContext, ViewHandle, WeakViewHandle, }; @@ -57,16 +57,24 @@ pub fn init(cx: &mut MutableAppContext) { cx.add_action(|workspace: &mut Workspace, action: &GoBack, cx| { Pane::go_back( workspace, - action.0.as_ref().and_then(|weak_handle| weak_handle.upgrade(cx)), - cx - ).detach(); + action + .0 + .as_ref() + .and_then(|weak_handle| weak_handle.upgrade(cx)), + cx, + ) + .detach(); }); cx.add_action(|workspace: &mut Workspace, action: &GoForward, cx| { Pane::go_forward( workspace, - action.0.as_ref().and_then(|weak_handle| weak_handle.upgrade(cx)), - cx - ).detach(); + action + .0 + .as_ref() + .and_then(|weak_handle| weak_handle.upgrade(cx)), + cx, + ) + .detach(); }); cx.add_bindings(vec![ @@ -171,7 +179,11 @@ impl Pane { cx.emit(Event::Activate); } - pub fn go_back(workspace: &mut Workspace, pane: Option>, cx: &mut ViewContext) -> Task<()> { + pub fn go_back( + workspace: &mut Workspace, + pane: Option>, + cx: &mut ViewContext, + ) -> Task<()> { Self::navigate_history( workspace, pane.unwrap_or_else(|| workspace.active_pane().clone()), @@ -180,7 +192,11 @@ impl Pane { ) } - pub fn go_forward(workspace: &mut Workspace, pane: Option>, cx: &mut ViewContext) -> Task<()> { + pub fn go_forward( + workspace: &mut Workspace, + pane: Option>, + cx: &mut ViewContext, + ) -> Task<()> { Self::navigate_history( workspace, pane.unwrap_or_else(|| workspace.active_pane().clone()), @@ -646,31 +662,29 @@ impl View for Pane { fn render(&mut self, cx: &mut RenderContext) -> ElementBox { let this = cx.handle(); - EventHandler::new( - if let Some(active_item) = self.active_item() { - Flex::column() - .with_child(self.render_tabs(cx)) - .with_children( - self.active_toolbar() - .as_ref() - .map(|view| ChildView::new(view).boxed()), - ) - .with_child(ChildView::new(active_item).flexible(1., true).boxed()) - .boxed() - } else { - Empty::new().boxed() + EventHandler::new(if let Some(active_item) = self.active_item() { + Flex::column() + .with_child(self.render_tabs(cx)) + .with_children( + self.active_toolbar() + .as_ref() + .map(|view| ChildView::new(view).boxed()), + ) + .with_child(ChildView::new(active_item).flexible(1., true).boxed()) + .boxed() + } else { + Empty::new().boxed() + }) + .on_navigate_mouse_down(move |direction, cx| { + let this = this.clone(); + match direction { + NavigationDirection::Back => cx.dispatch_action(GoBack(Some(this))), + NavigationDirection::Forward => cx.dispatch_action(GoForward(Some(this))), } - ) - .on_other_mouse_down(move |button, cx| { - match button { - 3 => cx.dispatch_action(GoBack(Some(this.clone()))), - 4 => cx.dispatch_action(GoForward(Some(this.clone()))), - _ => return false, - }; + true }) .named("pane") - } fn on_focus(&mut self, cx: &mut ViewContext) { diff --git a/crates/zed/src/zed.rs b/crates/zed/src/zed.rs index 75e7735f24..9299988ffe 100644 --- a/crates/zed/src/zed.rs +++ b/crates/zed/src/zed.rs @@ -747,44 +747,58 @@ mod tests { (file3.clone(), DisplayPoint::new(15, 0)) ); - workspace.update(cx, |w, cx| Pane::go_back(w, None, cx)).await; + workspace + .update(cx, |w, cx| Pane::go_back(w, None, cx)) + .await; assert_eq!( active_location(&workspace, cx), (file3.clone(), DisplayPoint::new(0, 0)) ); - workspace.update(cx, |w, cx| Pane::go_back(w, None, cx)).await; + workspace + .update(cx, |w, cx| Pane::go_back(w, None, cx)) + .await; assert_eq!( active_location(&workspace, cx), (file2.clone(), DisplayPoint::new(0, 0)) ); - workspace.update(cx, |w, cx| Pane::go_back(w, None, cx)).await; + workspace + .update(cx, |w, cx| Pane::go_back(w, None, cx)) + .await; assert_eq!( active_location(&workspace, cx), (file1.clone(), DisplayPoint::new(10, 0)) ); - workspace.update(cx, |w, cx| Pane::go_back(w, None, cx)).await; + workspace + .update(cx, |w, cx| Pane::go_back(w, None, cx)) + .await; assert_eq!( active_location(&workspace, cx), (file1.clone(), DisplayPoint::new(0, 0)) ); // Go back one more time and ensure we don't navigate past the first item in the history. - workspace.update(cx, |w, cx| Pane::go_back(w, None, cx)).await; + workspace + .update(cx, |w, cx| Pane::go_back(w, None, cx)) + .await; assert_eq!( active_location(&workspace, cx), (file1.clone(), DisplayPoint::new(0, 0)) ); - workspace.update(cx, |w, cx| Pane::go_forward(w, None, cx)).await; + workspace + .update(cx, |w, cx| Pane::go_forward(w, None, cx)) + .await; assert_eq!( active_location(&workspace, cx), (file1.clone(), DisplayPoint::new(10, 0)) ); - workspace.update(cx, |w, cx| Pane::go_forward(w, None, cx)).await; + workspace + .update(cx, |w, cx| Pane::go_forward(w, None, cx)) + .await; assert_eq!( active_location(&workspace, cx), (file2.clone(), DisplayPoint::new(0, 0)) @@ -798,7 +812,9 @@ mod tests { .update(cx, |pane, cx| pane.close_item(editor3.id(), cx)); drop(editor3); }); - workspace.update(cx, |w, cx| Pane::go_forward(w, None, cx)).await; + workspace + .update(cx, |w, cx| Pane::go_forward(w, None, cx)) + .await; assert_eq!( active_location(&workspace, cx), (file3.clone(), DisplayPoint::new(0, 0)) @@ -818,12 +834,16 @@ mod tests { }) .await .unwrap(); - workspace.update(cx, |w, cx| Pane::go_back(w, None, cx)).await; + workspace + .update(cx, |w, cx| Pane::go_back(w, None, cx)) + .await; assert_eq!( active_location(&workspace, cx), (file1.clone(), DisplayPoint::new(10, 0)) ); - workspace.update(cx, |w, cx| Pane::go_forward(w, None, cx)).await; + workspace + .update(cx, |w, cx| Pane::go_forward(w, None, cx)) + .await; assert_eq!( active_location(&workspace, cx), (file3.clone(), DisplayPoint::new(0, 0))