Fix more bugs around terminal2 and focus (#3534)
This commit is contained in:
commit
49d30b4f67
11 changed files with 87 additions and 38 deletions
|
@ -1110,6 +1110,10 @@ impl AppContext {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn has_active_drag(&self) -> bool {
|
||||||
|
self.active_drag.is_some()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Context for AppContext {
|
impl Context for AppContext {
|
||||||
|
|
|
@ -193,6 +193,12 @@ impl Deref for MouseExitEvent {
|
||||||
#[derive(Debug, Clone, Default)]
|
#[derive(Debug, Clone, Default)]
|
||||||
pub struct ExternalPaths(pub(crate) SmallVec<[PathBuf; 2]>);
|
pub struct ExternalPaths(pub(crate) SmallVec<[PathBuf; 2]>);
|
||||||
|
|
||||||
|
impl ExternalPaths {
|
||||||
|
pub fn paths(&self) -> &[PathBuf] {
|
||||||
|
&self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Render for ExternalPaths {
|
impl Render for ExternalPaths {
|
||||||
type Element = Div;
|
type Element = Div;
|
||||||
|
|
||||||
|
|
|
@ -4,12 +4,12 @@ use crate::{
|
||||||
DevicePixels, DispatchNodeId, DispatchTree, DisplayId, Edges, Effect, Entity, EntityId,
|
DevicePixels, DispatchNodeId, DispatchTree, DisplayId, Edges, Effect, Entity, EntityId,
|
||||||
EventEmitter, FileDropEvent, Flatten, FocusEvent, FontId, GlobalElementId, GlyphId, Hsla,
|
EventEmitter, FileDropEvent, Flatten, FocusEvent, FontId, GlobalElementId, GlyphId, Hsla,
|
||||||
ImageData, InputEvent, IsZero, KeyBinding, KeyContext, KeyDownEvent, LayoutId, Model,
|
ImageData, InputEvent, IsZero, KeyBinding, KeyContext, KeyDownEvent, LayoutId, Model,
|
||||||
ModelContext, Modifiers, MonochromeSprite, MouseButton, MouseDownEvent, MouseMoveEvent,
|
ModelContext, Modifiers, MonochromeSprite, MouseButton, MouseMoveEvent, MouseUpEvent, Path,
|
||||||
MouseUpEvent, Path, Pixels, PlatformAtlas, PlatformDisplay, PlatformInputHandler,
|
Pixels, PlatformAtlas, PlatformDisplay, PlatformInputHandler, PlatformWindow, Point,
|
||||||
PlatformWindow, Point, PolychromeSprite, PromptLevel, Quad, Render, RenderGlyphParams,
|
PolychromeSprite, PromptLevel, Quad, Render, RenderGlyphParams, RenderImageParams,
|
||||||
RenderImageParams, RenderSvgParams, ScaledPixels, SceneBuilder, Shadow, SharedString, Size,
|
RenderSvgParams, ScaledPixels, SceneBuilder, Shadow, SharedString, Size, Style, SubscriberSet,
|
||||||
Style, SubscriberSet, Subscription, Surface, TaffyLayoutEngine, Task, Underline,
|
Subscription, Surface, TaffyLayoutEngine, Task, Underline, UnderlineStyle, View, VisualContext,
|
||||||
UnderlineStyle, View, VisualContext, WeakView, WindowBounds, WindowOptions, SUBPIXEL_VARIANTS,
|
WeakView, WindowBounds, WindowOptions, SUBPIXEL_VARIANTS,
|
||||||
};
|
};
|
||||||
use anyhow::{anyhow, Context as _, Result};
|
use anyhow::{anyhow, Context as _, Result};
|
||||||
use collections::HashMap;
|
use collections::HashMap;
|
||||||
|
@ -1269,10 +1269,9 @@ impl<'a> WindowContext<'a> {
|
||||||
cursor_offset: position,
|
cursor_offset: position,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
InputEvent::MouseDown(MouseDownEvent {
|
InputEvent::MouseMove(MouseMoveEvent {
|
||||||
position,
|
position,
|
||||||
button: MouseButton::Left,
|
pressed_button: Some(MouseButton::Left),
|
||||||
click_count: 1,
|
|
||||||
modifiers: Modifiers::default(),
|
modifiers: Modifiers::default(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -1285,6 +1284,7 @@ impl<'a> WindowContext<'a> {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
FileDropEvent::Submit { position } => {
|
FileDropEvent::Submit { position } => {
|
||||||
|
self.activate(true);
|
||||||
self.window.mouse_position = position;
|
self.window.mouse_position = position;
|
||||||
InputEvent::MouseUp(MouseUpEvent {
|
InputEvent::MouseUp(MouseUpEvent {
|
||||||
button: MouseButton::Left,
|
button: MouseButton::Left,
|
||||||
|
|
|
@ -38,6 +38,7 @@ pub fn action(input: TokenStream) -> TokenStream {
|
||||||
|
|
||||||
let build_impl = if is_unit_struct {
|
let build_impl = if is_unit_struct {
|
||||||
quote! {
|
quote! {
|
||||||
|
let _ = value;
|
||||||
Ok(std::boxed::Box::new(Self {}))
|
Ok(std::boxed::Box::new(Self {}))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
1
crates/recent_projects2/src/projects.rs
Normal file
1
crates/recent_projects2/src/projects.rs
Normal file
|
@ -0,0 +1 @@
|
||||||
|
gpui::actions!(OpenRecent);
|
|
@ -1,9 +1,10 @@
|
||||||
mod highlighted_workspace_location;
|
mod highlighted_workspace_location;
|
||||||
|
mod projects;
|
||||||
|
|
||||||
use fuzzy::{StringMatch, StringMatchCandidate};
|
use fuzzy::{StringMatch, StringMatchCandidate};
|
||||||
use gpui::{
|
use gpui::{
|
||||||
actions, AppContext, DismissEvent, Div, EventEmitter, FocusHandle, FocusableView, Result, Task,
|
AppContext, DismissEvent, Div, EventEmitter, FocusHandle, FocusableView, Result, Task, View,
|
||||||
View, ViewContext, WeakView,
|
ViewContext, WeakView,
|
||||||
};
|
};
|
||||||
use highlighted_workspace_location::HighlightedWorkspaceLocation;
|
use highlighted_workspace_location::HighlightedWorkspaceLocation;
|
||||||
use ordered_float::OrderedFloat;
|
use ordered_float::OrderedFloat;
|
||||||
|
@ -16,7 +17,7 @@ use workspace::{
|
||||||
WORKSPACE_DB,
|
WORKSPACE_DB,
|
||||||
};
|
};
|
||||||
|
|
||||||
actions!(OpenRecent);
|
pub use projects::OpenRecent;
|
||||||
|
|
||||||
pub fn init(cx: &mut AppContext) {
|
pub fn init(cx: &mut AppContext) {
|
||||||
cx.observe_new_views(RecentProjects::register).detach();
|
cx.observe_new_views(RecentProjects::register).detach();
|
||||||
|
|
|
@ -50,7 +50,7 @@ use std::{
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
use gpui::{
|
use gpui::{
|
||||||
px, AnyWindowHandle, AppContext, Bounds, ClipboardItem, EventEmitter, Hsla, Keystroke,
|
actions, px, AnyWindowHandle, AppContext, Bounds, ClipboardItem, EventEmitter, Hsla, Keystroke,
|
||||||
ModelContext, Modifiers, MouseButton, MouseDownEvent, MouseMoveEvent, MouseUpEvent, Pixels,
|
ModelContext, Modifiers, MouseButton, MouseDownEvent, MouseMoveEvent, MouseUpEvent, Pixels,
|
||||||
Point, ScrollWheelEvent, Size, Task, TouchPhase,
|
Point, ScrollWheelEvent, Size, Task, TouchPhase,
|
||||||
};
|
};
|
||||||
|
@ -58,6 +58,16 @@ use gpui::{
|
||||||
use crate::mappings::{colors::to_alac_rgb, keys::to_esc_str};
|
use crate::mappings::{colors::to_alac_rgb, keys::to_esc_str};
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
|
|
||||||
|
actions!(
|
||||||
|
Clear,
|
||||||
|
Copy,
|
||||||
|
Paste,
|
||||||
|
ShowCharacterPalette,
|
||||||
|
SearchTest,
|
||||||
|
SendText,
|
||||||
|
SendKeystroke,
|
||||||
|
);
|
||||||
|
|
||||||
///Scrolling is unbearably sluggish by default. Alacritty supports a configurable
|
///Scrolling is unbearably sluggish by default. Alacritty supports a configurable
|
||||||
///Scroll multiplier that is set to 3 by default. This will be removed when I
|
///Scroll multiplier that is set to 3 by default. This will be removed when I
|
||||||
///Implement scroll bars.
|
///Implement scroll bars.
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
use editor::{Cursor, HighlightedRange, HighlightedRangeLine};
|
use editor::{Cursor, HighlightedRange, HighlightedRangeLine};
|
||||||
use gpui::{
|
use gpui::{
|
||||||
black, div, point, px, red, relative, transparent_black, AnyElement, AsyncWindowContext,
|
black, div, point, px, red, relative, transparent_black, AnyElement, AsyncWindowContext,
|
||||||
AvailableSpace, Bounds, DispatchPhase, Element, ElementId, FocusHandle, Font, FontStyle,
|
AvailableSpace, Bounds, DispatchPhase, Element, ElementId, ExternalPaths, FocusHandle, Font,
|
||||||
FontWeight, HighlightStyle, Hsla, InteractiveElement, InteractiveElementState, IntoElement,
|
FontStyle, FontWeight, HighlightStyle, Hsla, InteractiveElement, InteractiveElementState,
|
||||||
LayoutId, Model, ModelContext, ModifiersChangedEvent, MouseButton, Pixels,
|
IntoElement, LayoutId, Model, ModelContext, ModifiersChangedEvent, MouseButton, Pixels,
|
||||||
PlatformInputHandler, Point, Rgba, ShapedLine, Size, StatefulInteractiveElement, Styled,
|
PlatformInputHandler, Point, Rgba, ShapedLine, Size, StatefulInteractiveElement, Styled,
|
||||||
TextRun, TextStyle, TextSystem, UnderlineStyle, View, WhiteSpace, WindowContext,
|
TextRun, TextStyle, TextSystem, UnderlineStyle, View, WhiteSpace, WindowContext,
|
||||||
};
|
};
|
||||||
|
@ -643,15 +643,13 @@ impl TerminalElement {
|
||||||
let connection = connection.clone();
|
let connection = connection.clone();
|
||||||
let focus = focus.clone();
|
let focus = focus.clone();
|
||||||
move |e, cx| {
|
move |e, cx| {
|
||||||
if e.pressed_button.is_some() {
|
if e.pressed_button.is_some() && focus.is_focused(cx) && !cx.has_active_drag() {
|
||||||
if focus.is_focused(cx) {
|
|
||||||
connection.update(cx, |terminal, cx| {
|
connection.update(cx, |terminal, cx| {
|
||||||
terminal.mouse_drag(e, origin, bounds);
|
terminal.mouse_drag(e, origin, bounds);
|
||||||
cx.notify();
|
cx.notify();
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
})
|
})
|
||||||
.on_mouse_up(
|
.on_mouse_up(
|
||||||
MouseButton::Left,
|
MouseButton::Left,
|
||||||
|
@ -806,7 +804,28 @@ impl Element for TerminalElement {
|
||||||
.map(|cursor| cursor.bounding_rect(origin)),
|
.map(|cursor| cursor.bounding_rect(origin)),
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut this = self.register_mouse_listeners(origin, layout.mode, bounds, cx);
|
let terminal_focus_handle = self.focus.clone();
|
||||||
|
let terminal_handle = self.terminal.clone();
|
||||||
|
let mut this: TerminalElement = self
|
||||||
|
.register_mouse_listeners(origin, layout.mode, bounds, cx)
|
||||||
|
.drag_over::<ExternalPaths>(|style| {
|
||||||
|
// todo!() why does not it work? z-index of elements?
|
||||||
|
style.bg(cx.theme().colors().ghost_element_hover)
|
||||||
|
})
|
||||||
|
.on_drop::<ExternalPaths>(move |external_paths, cx| {
|
||||||
|
cx.focus(&terminal_focus_handle);
|
||||||
|
let mut new_text = external_paths
|
||||||
|
.read(cx)
|
||||||
|
.paths()
|
||||||
|
.iter()
|
||||||
|
.map(|path| format!(" {path:?}"))
|
||||||
|
.join("");
|
||||||
|
new_text.push(' ');
|
||||||
|
terminal_handle.update(cx, |terminal, _| {
|
||||||
|
// todo!() long paths are not displayed properly albeit the text is there
|
||||||
|
terminal.paste(&new_text);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
let interactivity = mem::take(&mut this.interactivity);
|
let interactivity = mem::take(&mut this.interactivity);
|
||||||
|
|
||||||
|
|
|
@ -9,9 +9,9 @@ pub mod terminal_panel;
|
||||||
// use crate::terminal_element::TerminalElement;
|
// use crate::terminal_element::TerminalElement;
|
||||||
use editor::{scroll::autoscroll::Autoscroll, Editor};
|
use editor::{scroll::autoscroll::Autoscroll, Editor};
|
||||||
use gpui::{
|
use gpui::{
|
||||||
actions, div, Action, AnyElement, AppContext, Div, EventEmitter, FocusEvent, FocusHandle,
|
div, Action, AnyElement, AppContext, Div, EventEmitter, FocusEvent, FocusHandle, Focusable,
|
||||||
Focusable, FocusableElement, FocusableView, KeyContext, KeyDownEvent, Keystroke, Model,
|
FocusableElement, FocusableView, KeyContext, KeyDownEvent, Keystroke, Model, MouseButton,
|
||||||
MouseButton, MouseDownEvent, Pixels, Render, Subscription, Task, View, VisualContext, WeakView,
|
MouseDownEvent, Pixels, Render, Subscription, Task, View, VisualContext, WeakView,
|
||||||
};
|
};
|
||||||
use language::Bias;
|
use language::Bias;
|
||||||
use persistence::TERMINAL_DB;
|
use persistence::TERMINAL_DB;
|
||||||
|
@ -22,7 +22,7 @@ use terminal::{
|
||||||
term::{search::RegexSearch, TermMode},
|
term::{search::RegexSearch, TermMode},
|
||||||
},
|
},
|
||||||
terminal_settings::{TerminalBlink, TerminalSettings, WorkingDirectory},
|
terminal_settings::{TerminalBlink, TerminalSettings, WorkingDirectory},
|
||||||
Event, MaybeNavigationTarget, Terminal,
|
Clear, Copy, Event, MaybeNavigationTarget, Paste, ShowCharacterPalette, Terminal,
|
||||||
};
|
};
|
||||||
use terminal_element::TerminalElement;
|
use terminal_element::TerminalElement;
|
||||||
use ui::{h_stack, prelude::*, ContextMenu, Icon, IconElement, Label};
|
use ui::{h_stack, prelude::*, ContextMenu, Icon, IconElement, Label};
|
||||||
|
@ -60,8 +60,6 @@ pub struct SendText(String);
|
||||||
#[derive(Clone, Debug, Default, Deserialize, PartialEq, Action)]
|
#[derive(Clone, Debug, Default, Deserialize, PartialEq, Action)]
|
||||||
pub struct SendKeystroke(String);
|
pub struct SendKeystroke(String);
|
||||||
|
|
||||||
actions!(Clear, Copy, Paste, ShowCharacterPalette, SearchTest);
|
|
||||||
|
|
||||||
pub fn init(cx: &mut AppContext) {
|
pub fn init(cx: &mut AppContext) {
|
||||||
terminal_panel::init(cx);
|
terminal_panel::init(cx);
|
||||||
terminal::init(cx);
|
terminal::init(cx);
|
||||||
|
|
|
@ -133,13 +133,13 @@ pub struct Dock {
|
||||||
panel_entries: Vec<PanelEntry>,
|
panel_entries: Vec<PanelEntry>,
|
||||||
is_open: bool,
|
is_open: bool,
|
||||||
active_panel_index: usize,
|
active_panel_index: usize,
|
||||||
|
focus_handle: FocusHandle,
|
||||||
|
focus_subscription: Subscription,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FocusableView for Dock {
|
impl FocusableView for Dock {
|
||||||
fn focus_handle(&self, cx: &AppContext) -> FocusHandle {
|
fn focus_handle(&self, _: &AppContext) -> FocusHandle {
|
||||||
self.panel_entries[self.active_panel_index]
|
self.focus_handle.clone()
|
||||||
.panel
|
|
||||||
.focus_handle(cx)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -190,12 +190,20 @@ pub struct PanelButtons {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Dock {
|
impl Dock {
|
||||||
pub fn new(position: DockPosition) -> Self {
|
pub fn new(position: DockPosition, cx: &mut ViewContext<'_, Self>) -> Self {
|
||||||
|
let focus_handle = cx.focus_handle();
|
||||||
|
let focus_subscription = cx.on_focus(&focus_handle, |dock, cx| {
|
||||||
|
if let Some(active_entry) = dock.panel_entries.get(dock.active_panel_index) {
|
||||||
|
active_entry.panel.focus_handle(cx).focus(cx)
|
||||||
|
}
|
||||||
|
});
|
||||||
Self {
|
Self {
|
||||||
position,
|
position,
|
||||||
panel_entries: Default::default(),
|
panel_entries: Default::default(),
|
||||||
active_panel_index: 0,
|
active_panel_index: 0,
|
||||||
is_open: false,
|
is_open: false,
|
||||||
|
focus_handle,
|
||||||
|
focus_subscription,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -207,6 +215,7 @@ impl Dock {
|
||||||
self.is_open
|
self.is_open
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// todo!()
|
||||||
// pub fn has_focus(&self, cx: &WindowContext) -> bool {
|
// pub fn has_focus(&self, cx: &WindowContext) -> bool {
|
||||||
// self.visible_panel()
|
// self.visible_panel()
|
||||||
// .map_or(false, |panel| panel.has_focus(cx))
|
// .map_or(false, |panel| panel.has_focus(cx))
|
||||||
|
|
|
@ -566,9 +566,9 @@ impl Workspace {
|
||||||
|
|
||||||
cx.emit(Event::WorkspaceCreated(weak_handle.clone()));
|
cx.emit(Event::WorkspaceCreated(weak_handle.clone()));
|
||||||
|
|
||||||
let left_dock = cx.build_view(|_| Dock::new(DockPosition::Left));
|
let left_dock = cx.build_view(|cx| Dock::new(DockPosition::Left, cx));
|
||||||
let bottom_dock = cx.build_view(|_| Dock::new(DockPosition::Bottom));
|
let bottom_dock = cx.build_view(|cx| Dock::new(DockPosition::Bottom, cx));
|
||||||
let right_dock = cx.build_view(|_| Dock::new(DockPosition::Right));
|
let right_dock = cx.build_view(|cx| Dock::new(DockPosition::Right, cx));
|
||||||
let left_dock_buttons =
|
let left_dock_buttons =
|
||||||
cx.build_view(|cx| PanelButtons::new(left_dock.clone(), weak_handle.clone(), cx));
|
cx.build_view(|cx| PanelButtons::new(left_dock.clone(), weak_handle.clone(), cx));
|
||||||
let bottom_dock_buttons =
|
let bottom_dock_buttons =
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue