mirror of
https://github.com/zed-industries/zed.git
synced 2025-01-11 13:10:54 +00:00
Debugged mouse reporting for now. Remaining bugs are GPUI level bugs
This commit is contained in:
parent
cfbda00cc4
commit
1de68a724c
4 changed files with 179 additions and 125 deletions
|
@ -237,6 +237,7 @@ impl Presenter {
|
||||||
let mut mouse_down_out_handlers = Vec::new();
|
let mut mouse_down_out_handlers = Vec::new();
|
||||||
let mut mouse_moved_region = None;
|
let mut mouse_moved_region = None;
|
||||||
let mut mouse_down_region = None;
|
let mut mouse_down_region = None;
|
||||||
|
let mut mouse_up_region = None;
|
||||||
let mut clicked_region = None;
|
let mut clicked_region = None;
|
||||||
let mut dragged_region = None;
|
let mut dragged_region = None;
|
||||||
|
|
||||||
|
@ -283,6 +284,15 @@ impl Presenter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (region, _) in self.mouse_regions.iter().rev() {
|
||||||
|
if region.bounds.contains_point(position) {
|
||||||
|
invalidated_views.push(region.view_id);
|
||||||
|
mouse_up_region =
|
||||||
|
Some((region.clone(), MouseRegionEvent::Up(e.clone())));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if let Some(moved) = &mut self.last_mouse_moved_event {
|
if let Some(moved) = &mut self.last_mouse_moved_event {
|
||||||
if moved.pressed_button == Some(button) {
|
if moved.pressed_button == Some(button) {
|
||||||
moved.pressed_button = None;
|
moved.pressed_button = None;
|
||||||
|
@ -350,6 +360,17 @@ impl Presenter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let Some((mouse_up_region, region_event)) = mouse_up_region {
|
||||||
|
handled = true;
|
||||||
|
if let Some(mouse_up_callback) =
|
||||||
|
mouse_up_region.handlers.get(®ion_event.handler_key())
|
||||||
|
{
|
||||||
|
event_cx.with_current_view(mouse_up_region.view_id, |event_cx| {
|
||||||
|
mouse_up_callback(region_event, event_cx);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if let Some((clicked_region, region_event)) = clicked_region {
|
if let Some((clicked_region, region_event)) = clicked_region {
|
||||||
handled = true;
|
handled = true;
|
||||||
if let Some(click_callback) =
|
if let Some(click_callback) =
|
||||||
|
|
|
@ -3,7 +3,10 @@ use alacritty_terminal::{
|
||||||
grid::Dimensions,
|
grid::Dimensions,
|
||||||
index::Point,
|
index::Point,
|
||||||
selection::SelectionRange,
|
selection::SelectionRange,
|
||||||
term::cell::{Cell, Flags},
|
term::{
|
||||||
|
cell::{Cell, Flags},
|
||||||
|
TermMode,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
use editor::{Cursor, CursorShape, HighlightedRange, HighlightedRangeLine};
|
use editor::{Cursor, CursorShape, HighlightedRange, HighlightedRangeLine};
|
||||||
use gpui::{
|
use gpui::{
|
||||||
|
@ -46,6 +49,7 @@ pub struct LayoutState {
|
||||||
background_color: Color,
|
background_color: Color,
|
||||||
selection_color: Color,
|
selection_color: Color,
|
||||||
size: TerminalSize,
|
size: TerminalSize,
|
||||||
|
mode: TermMode,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -428,116 +432,137 @@ impl TerminalEl {
|
||||||
origin: Vector2F,
|
origin: Vector2F,
|
||||||
view_id: usize,
|
view_id: usize,
|
||||||
visible_bounds: RectF,
|
visible_bounds: RectF,
|
||||||
|
mode: TermMode,
|
||||||
cx: &mut PaintContext,
|
cx: &mut PaintContext,
|
||||||
) {
|
) {
|
||||||
let connection = self.terminal;
|
let connection = self.terminal;
|
||||||
cx.scene.push_mouse_region(
|
|
||||||
MouseRegion::new(view_id, None, visible_bounds)
|
let mut region = MouseRegion::new(view_id, None, visible_bounds);
|
||||||
.on_move(move |event, cx| {
|
|
||||||
if cx.is_parent_view_focused() {
|
//Terminal Emulator controlled behavior:
|
||||||
if let Some(conn_handle) = connection.upgrade(cx.app) {
|
region = region
|
||||||
conn_handle.update(cx.app, |terminal, cx| {
|
//Start selections
|
||||||
terminal.mouse_move(&event, origin);
|
.on_down(
|
||||||
cx.notify();
|
MouseButton::Left,
|
||||||
})
|
TerminalEl::generic_button_handler(
|
||||||
}
|
connection,
|
||||||
}
|
origin,
|
||||||
})
|
move |terminal, origin, e, _cx| {
|
||||||
.on_drag(MouseButton::Left, move |_prev, event, cx| {
|
terminal.mouse_down(&e, origin);
|
||||||
if cx.is_parent_view_focused() {
|
|
||||||
if let Some(conn_handle) = connection.upgrade(cx.app) {
|
|
||||||
conn_handle.update(cx.app, |terminal, cx| {
|
|
||||||
terminal.mouse_drag(event, origin);
|
|
||||||
cx.notify();
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.on_down(
|
|
||||||
MouseButton::Left,
|
|
||||||
TerminalEl::generic_button_handler(
|
|
||||||
connection,
|
|
||||||
origin,
|
|
||||||
move |terminal, origin, e, _cx| {
|
|
||||||
terminal.mouse_down(&e, origin);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
)
|
|
||||||
.on_down(
|
|
||||||
MouseButton::Right,
|
|
||||||
TerminalEl::generic_button_handler(
|
|
||||||
connection,
|
|
||||||
origin,
|
|
||||||
move |terminal, origin, e, _cx| {
|
|
||||||
terminal.mouse_down(&e, origin);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
)
|
|
||||||
.on_down(
|
|
||||||
MouseButton::Middle,
|
|
||||||
TerminalEl::generic_button_handler(
|
|
||||||
connection,
|
|
||||||
origin,
|
|
||||||
move |terminal, origin, e, _cx| {
|
|
||||||
terminal.mouse_down(&e, origin);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
)
|
|
||||||
.on_up(
|
|
||||||
MouseButton::Left,
|
|
||||||
TerminalEl::generic_button_handler(
|
|
||||||
connection,
|
|
||||||
origin,
|
|
||||||
move |terminal, origin, e, _cx| {
|
|
||||||
terminal.mouse_up(&e, origin);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
)
|
|
||||||
.on_up(
|
|
||||||
MouseButton::Right,
|
|
||||||
TerminalEl::generic_button_handler(
|
|
||||||
connection,
|
|
||||||
origin,
|
|
||||||
move |terminal, origin, e, _cx| {
|
|
||||||
terminal.mouse_up(&e, origin);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
)
|
|
||||||
.on_up(
|
|
||||||
MouseButton::Middle,
|
|
||||||
TerminalEl::generic_button_handler(
|
|
||||||
connection,
|
|
||||||
origin,
|
|
||||||
move |terminal, origin, e, _cx| {
|
|
||||||
terminal.mouse_up(&e, origin);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
)
|
|
||||||
.on_click(
|
|
||||||
MouseButton::Left,
|
|
||||||
TerminalEl::generic_button_handler(
|
|
||||||
connection,
|
|
||||||
origin,
|
|
||||||
move |terminal, origin, e, _cx| {
|
|
||||||
terminal.left_click(&e, origin);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
)
|
|
||||||
.on_click(
|
|
||||||
MouseButton::Right,
|
|
||||||
move |e @ MouseButtonEvent { position, .. }, cx| {
|
|
||||||
let mouse_mode = if let Some(conn_handle) = connection.upgrade(cx.app) {
|
|
||||||
conn_handle.update(cx.app, |terminal, _cx| terminal.mouse_mode(e.shift))
|
|
||||||
} else {
|
|
||||||
//If we can't get the model handle, probably can't deploy the context menu
|
|
||||||
true
|
|
||||||
};
|
|
||||||
if !mouse_mode {
|
|
||||||
cx.dispatch_action(DeployContextMenu { position });
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
);
|
)
|
||||||
|
//Update drag selections
|
||||||
|
.on_drag(MouseButton::Left, move |_prev, event, cx| {
|
||||||
|
if cx.is_parent_view_focused() {
|
||||||
|
if let Some(conn_handle) = connection.upgrade(cx.app) {
|
||||||
|
conn_handle.update(cx.app, |terminal, cx| {
|
||||||
|
terminal.mouse_drag(event, origin);
|
||||||
|
cx.notify();
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
//Copy on up behavior
|
||||||
|
.on_up(
|
||||||
|
MouseButton::Left,
|
||||||
|
TerminalEl::generic_button_handler(
|
||||||
|
connection,
|
||||||
|
origin,
|
||||||
|
move |terminal, origin, e, _cx| {
|
||||||
|
terminal.mouse_up(&e, origin);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
)
|
||||||
|
//Handle click based selections
|
||||||
|
.on_click(
|
||||||
|
MouseButton::Left,
|
||||||
|
TerminalEl::generic_button_handler(
|
||||||
|
connection,
|
||||||
|
origin,
|
||||||
|
move |terminal, origin, e, _cx| {
|
||||||
|
terminal.left_click(&e, origin);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
)
|
||||||
|
//Context menu
|
||||||
|
.on_click(
|
||||||
|
MouseButton::Right,
|
||||||
|
move |e @ MouseButtonEvent { position, .. }, cx| {
|
||||||
|
let mouse_mode = if let Some(conn_handle) = connection.upgrade(cx.app) {
|
||||||
|
conn_handle.update(cx.app, |terminal, _cx| terminal.mouse_mode(e.shift))
|
||||||
|
} else {
|
||||||
|
//If we can't get the model handle, probably can't deploy the context menu
|
||||||
|
true
|
||||||
|
};
|
||||||
|
if !mouse_mode {
|
||||||
|
cx.dispatch_action(DeployContextMenu { position });
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
|
//This handles both drag mode and mouse motion mode
|
||||||
|
//Mouse Move TODO
|
||||||
|
//This cannot be done conditionally for unknown reasons. Pending drag and drop rework.
|
||||||
|
//This also does not fire on right-mouse-down-move events wild.
|
||||||
|
.on_move(move |event, cx| {
|
||||||
|
dbg!(event);
|
||||||
|
if cx.is_parent_view_focused() {
|
||||||
|
if let Some(conn_handle) = connection.upgrade(cx.app) {
|
||||||
|
conn_handle.update(cx.app, |terminal, cx| {
|
||||||
|
terminal.mouse_move(&event, origin);
|
||||||
|
cx.notify();
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if mode.contains(TermMode::MOUSE_MODE) {
|
||||||
|
region = region
|
||||||
|
.on_down(
|
||||||
|
MouseButton::Right,
|
||||||
|
TerminalEl::generic_button_handler(
|
||||||
|
connection,
|
||||||
|
origin,
|
||||||
|
move |terminal, origin, e, _cx| {
|
||||||
|
terminal.mouse_down(&e, origin);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.on_down(
|
||||||
|
MouseButton::Middle,
|
||||||
|
TerminalEl::generic_button_handler(
|
||||||
|
connection,
|
||||||
|
origin,
|
||||||
|
move |terminal, origin, e, _cx| {
|
||||||
|
terminal.mouse_down(&e, origin);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.on_up(
|
||||||
|
MouseButton::Right,
|
||||||
|
TerminalEl::generic_button_handler(
|
||||||
|
connection,
|
||||||
|
origin,
|
||||||
|
move |terminal, origin, e, _cx| {
|
||||||
|
terminal.mouse_up(&e, origin);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.on_up(
|
||||||
|
MouseButton::Middle,
|
||||||
|
TerminalEl::generic_button_handler(
|
||||||
|
connection,
|
||||||
|
origin,
|
||||||
|
move |terminal, origin, e, _cx| {
|
||||||
|
terminal.mouse_up(&e, origin);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO: Mouse drag isn't correct
|
||||||
|
//TODO: Nor is mouse motion. Move events aren't happening??
|
||||||
|
cx.scene.push_mouse_region(region);
|
||||||
}
|
}
|
||||||
|
|
||||||
///Configures a text style from the current settings.
|
///Configures a text style from the current settings.
|
||||||
|
@ -601,7 +626,7 @@ impl Element for TerminalEl {
|
||||||
terminal_theme.colors.background
|
terminal_theme.colors.background
|
||||||
};
|
};
|
||||||
|
|
||||||
let (cells, selection, cursor, display_offset, cursor_text) = self
|
let (cells, selection, cursor, display_offset, cursor_text, mode) = self
|
||||||
.terminal
|
.terminal
|
||||||
.upgrade(cx)
|
.upgrade(cx)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
|
@ -624,13 +649,13 @@ impl Element for TerminalEl {
|
||||||
cell: ic.cell.clone(),
|
cell: ic.cell.clone(),
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
(
|
(
|
||||||
cells,
|
cells,
|
||||||
content.selection,
|
content.selection,
|
||||||
content.cursor,
|
content.cursor,
|
||||||
content.display_offset,
|
content.display_offset,
|
||||||
cursor_text,
|
cursor_text,
|
||||||
|
content.mode,
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
@ -709,6 +734,7 @@ impl Element for TerminalEl {
|
||||||
size: dimensions,
|
size: dimensions,
|
||||||
rects,
|
rects,
|
||||||
highlights,
|
highlights,
|
||||||
|
mode,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -727,7 +753,7 @@ impl Element for TerminalEl {
|
||||||
let origin = bounds.origin() + vec2f(layout.size.cell_width, 0.);
|
let origin = bounds.origin() + vec2f(layout.size.cell_width, 0.);
|
||||||
|
|
||||||
//Elements are ephemeral, only at paint time do we know what could be clicked by a mouse
|
//Elements are ephemeral, only at paint time do we know what could be clicked by a mouse
|
||||||
self.attach_mouse_handlers(origin, self.view.id(), visible_bounds, cx);
|
self.attach_mouse_handlers(origin, self.view.id(), visible_bounds, layout.mode, cx);
|
||||||
|
|
||||||
cx.paint_layer(clip_bounds, |cx| {
|
cx.paint_layer(clip_bounds, |cx| {
|
||||||
//Start with a background color
|
//Start with a background color
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use std::cmp::min;
|
use std::cmp::{max, min};
|
||||||
use std::iter::repeat;
|
use std::iter::repeat;
|
||||||
|
|
||||||
use alacritty_terminal::grid::Dimensions;
|
use alacritty_terminal::grid::Dimensions;
|
||||||
|
@ -60,6 +60,7 @@ impl MouseFormat {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
enum MouseButton {
|
enum MouseButton {
|
||||||
LeftButton = 0,
|
LeftButton = 0,
|
||||||
MiddleButton = 1,
|
MiddleButton = 1,
|
||||||
|
@ -117,7 +118,7 @@ pub fn scroll_report(
|
||||||
e: &ScrollWheelEvent,
|
e: &ScrollWheelEvent,
|
||||||
mode: TermMode,
|
mode: TermMode,
|
||||||
) -> Option<impl Iterator<Item = Vec<u8>>> {
|
) -> Option<impl Iterator<Item = Vec<u8>>> {
|
||||||
if mode.intersects(TermMode::MOUSE_MODE) && scroll_lines >= 1 {
|
if mode.intersects(TermMode::MOUSE_MODE) {
|
||||||
mouse_report(
|
mouse_report(
|
||||||
point,
|
point,
|
||||||
MouseButton::from_scroll(e),
|
MouseButton::from_scroll(e),
|
||||||
|
@ -125,7 +126,7 @@ pub fn scroll_report(
|
||||||
Modifiers::from_scroll(),
|
Modifiers::from_scroll(),
|
||||||
MouseFormat::from_mode(mode),
|
MouseFormat::from_mode(mode),
|
||||||
)
|
)
|
||||||
.map(|report| repeat(report).take(scroll_lines as usize))
|
.map(|report| repeat(report).take(max(scroll_lines, 1) as usize))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
@ -165,14 +166,21 @@ pub fn mouse_button_report(
|
||||||
|
|
||||||
pub fn mouse_moved_report(point: Point, e: &MouseMovedEvent, mode: TermMode) -> Option<Vec<u8>> {
|
pub fn mouse_moved_report(point: Point, e: &MouseMovedEvent, mode: TermMode) -> Option<Vec<u8>> {
|
||||||
let button = MouseButton::from_move(e);
|
let button = MouseButton::from_move(e);
|
||||||
|
dbg!(&button);
|
||||||
|
|
||||||
if !button.is_other() && mode.intersects(TermMode::MOUSE_MOTION | TermMode::MOUSE_DRAG) {
|
if !button.is_other() && mode.intersects(TermMode::MOUSE_MOTION | TermMode::MOUSE_DRAG) {
|
||||||
mouse_report(
|
//Only drags are reported in drag mode, so block NoneMove.
|
||||||
point,
|
if mode.contains(TermMode::MOUSE_DRAG) && matches!(button, MouseButton::NoneMove) {
|
||||||
button,
|
None
|
||||||
true,
|
} else {
|
||||||
Modifiers::from_moved(e),
|
mouse_report(
|
||||||
MouseFormat::from_mode(mode),
|
point,
|
||||||
)
|
button,
|
||||||
|
true,
|
||||||
|
Modifiers::from_moved(e),
|
||||||
|
MouseFormat::from_mode(mode),
|
||||||
|
)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,8 +35,8 @@ use thiserror::Error;
|
||||||
use gpui::{
|
use gpui::{
|
||||||
geometry::vector::{vec2f, Vector2F},
|
geometry::vector::{vec2f, Vector2F},
|
||||||
keymap::Keystroke,
|
keymap::Keystroke,
|
||||||
ClipboardItem, Entity, ModelContext, MouseButtonEvent, MouseMovedEvent, MutableAppContext,
|
ClipboardItem, Entity, ModelContext, MouseButton, MouseButtonEvent, MouseMovedEvent,
|
||||||
ScrollWheelEvent,
|
MutableAppContext, ScrollWheelEvent,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::mappings::{
|
use crate::mappings::{
|
||||||
|
@ -627,6 +627,7 @@ impl Terminal {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mouse_move(&mut self, e: &MouseMovedEvent, origin: Vector2F) {
|
pub fn mouse_move(&mut self, e: &MouseMovedEvent, origin: Vector2F) {
|
||||||
|
dbg!("term mouse_move");
|
||||||
let position = e.position.sub(origin);
|
let position = e.position.sub(origin);
|
||||||
|
|
||||||
let point = mouse_point(position, self.cur_size, self.last_offset);
|
let point = mouse_point(position, self.cur_size, self.last_offset);
|
||||||
|
@ -653,7 +654,6 @@ impl Terminal {
|
||||||
|
|
||||||
pub fn mouse_down(&mut self, e: &MouseButtonEvent, origin: Vector2F) {
|
pub fn mouse_down(&mut self, e: &MouseButtonEvent, origin: Vector2F) {
|
||||||
let position = e.position.sub(origin);
|
let position = e.position.sub(origin);
|
||||||
|
|
||||||
let point = mouse_point(position, self.cur_size, self.last_offset);
|
let point = mouse_point(position, self.cur_size, self.last_offset);
|
||||||
let side = mouse_side(position, self.cur_size);
|
let side = mouse_side(position, self.cur_size);
|
||||||
|
|
||||||
|
@ -661,7 +661,7 @@ impl Terminal {
|
||||||
if let Some(bytes) = mouse_button_report(point, e, true, self.last_mode) {
|
if let Some(bytes) = mouse_button_report(point, e, true, self.last_mode) {
|
||||||
self.pty_tx.notify(bytes);
|
self.pty_tx.notify(bytes);
|
||||||
}
|
}
|
||||||
} else {
|
} else if e.button == MouseButton::Left {
|
||||||
self.events
|
self.events
|
||||||
.push(InternalEvent::SetSelection(Some(Selection::new(
|
.push(InternalEvent::SetSelection(Some(Selection::new(
|
||||||
SelectionType::Simple,
|
SelectionType::Simple,
|
||||||
|
@ -695,14 +695,13 @@ impl Terminal {
|
||||||
|
|
||||||
pub fn mouse_up(&mut self, e: &MouseButtonEvent, origin: Vector2F) {
|
pub fn mouse_up(&mut self, e: &MouseButtonEvent, origin: Vector2F) {
|
||||||
let position = e.position.sub(origin);
|
let position = e.position.sub(origin);
|
||||||
|
|
||||||
if self.mouse_mode(e.shift) {
|
if self.mouse_mode(e.shift) {
|
||||||
let point = mouse_point(position, self.cur_size, self.last_offset);
|
let point = mouse_point(position, self.cur_size, self.last_offset);
|
||||||
|
|
||||||
if let Some(bytes) = mouse_button_report(point, e, false, self.last_mode) {
|
if let Some(bytes) = mouse_button_report(point, e, false, self.last_mode) {
|
||||||
self.pty_tx.notify(bytes);
|
self.pty_tx.notify(bytes);
|
||||||
}
|
}
|
||||||
} else {
|
} else if e.button == MouseButton::Left {
|
||||||
// Seems pretty standard to automatically copy on mouse_up for terminals,
|
// Seems pretty standard to automatically copy on mouse_up for terminals,
|
||||||
// so let's do that here
|
// so let's do that here
|
||||||
self.copy();
|
self.copy();
|
||||||
|
|
Loading…
Reference in a new issue