Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions crates/egui-term/src/display/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,11 @@ impl TerminalView<'_> {
.term_ctx
.to_range()
.is_some_and(|r| r.contains(indexed.point));
let is_hovered_hyperlink =
self.term_ctx.hovered_hyperlink.as_ref().is_some_and(|r| {
r.contains(&indexed.point) && r.contains(&state.mouse_position)
});
let is_hovered_hyperlink = self
.term_ctx
.hovered_hyperlink
.as_ref()
.is_some_and(|r| r.contains(&indexed.point) && r.contains(&state.mouse_point));
let is_text_cell = indexed.c != ' ' && indexed.c != '\t';

let x = layout_min.x + indexed.point.column.saturating_mul(cell_width as usize) as f32;
Expand Down Expand Up @@ -112,6 +113,7 @@ impl TerminalView<'_> {
cell_width / 2.
};

state.cursor_position = Some(Pos2::new(x, y));
shapes.push(Shape::Rect(RectShape::filled(
Rect::from_min_size(Pos2::new(x, y), Vec2::new(cursor_width, cell_height)),
CornerRadius::default(),
Expand Down
35 changes: 20 additions & 15 deletions crates/egui-term/src/input/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use crate::{BindingAction, InputKind, TerminalView};
use alacritty_terminal::grid::Dimensions;
use alacritty_terminal::selection::SelectionType;
use alacritty_terminal::term::TermMode;
use egui::{Key, Modifiers, MouseWheelUnit, PointerButton, Pos2, Response, Vec2};
use egui::{Key, Modifiers, MouseWheelUnit, PointerButton, Pos2, Rect, Response, Vec2};
use std::cmp::min;

/// Minimum number of pixels at the bottom/top where selection scrolling is performed.
Expand Down Expand Up @@ -134,7 +134,7 @@ impl TerminalView<'_> {
self.left_button_click(state, layout, position, modifiers, pressed)
}
PointerButton::Secondary => {
state.cursor_position = Some(position);
state.context_menu_position = Some(position);
None
}
_ => None,
Expand All @@ -149,18 +149,18 @@ impl TerminalView<'_> {
modifiers: &Modifiers,
pressed: bool,
) -> Option<InputAction> {
if state.cursor_position.is_some() {
if state.context_menu_position.is_some() {
return None;
}
let terminal_mode = self.term_ctx.terminal.mode();
if terminal_mode.intersects(TermMode::MOUSE_MODE) {
Some(InputAction::BackendCall(BackendCommand::MouseReport(
MouseButton::LeftButton,
*modifiers,
state.mouse_position,
state.mouse_point,
pressed,
)))
} else if pressed {
} else if pressed && is_in_terminal(position, layout.rect) {
state.is_dragged = true;
Some(InputAction::BackendCall(start_select_command(
layout, position,
Expand Down Expand Up @@ -189,7 +189,7 @@ impl TerminalView<'_> {
*self.term_ctx.terminal.mode(),
) {
Some(BindingAction::LinkOpen) => Some(InputAction::BackendCall(
BackendCommand::ProcessLink(LinkAction::Open, state.mouse_position),
BackendCommand::ProcessLink(LinkAction::Open, state.mouse_point),
)),
_ => None,
}
Expand All @@ -203,21 +203,22 @@ impl TerminalView<'_> {
position: Pos2,
modifiers: &Modifiers,
) -> Vec<InputAction> {
let cursor_x = position.x - layout.rect.min.x;
let cursor_y = position.y - layout.rect.min.y;
let mouse_x = position.x - layout.rect.min.x;
let mouse_y = position.y - layout.rect.min.y;

state.mouse_position = selection_point(
cursor_x,
cursor_y,
state.mouse_point = selection_point(
mouse_x,
mouse_y,
self.term_ctx.size,
self.term_ctx.terminal.grid().display_offset(),
);
state.mouse_position = Some(position);

let mut actions = vec![];
// Handle command or selection update based on terminal mode and modifiers
if state.is_dragged {
if !self.term_ctx.selection_is_empty() {
if let Some(action) = self.update_selection_scrolling(cursor_y as i32) {
if let Some(action) = self.update_selection_scrolling(mouse_y as i32) {
actions.push(action);
}
}
Expand All @@ -232,11 +233,11 @@ impl TerminalView<'_> {
InputAction::BackendCall(BackendCommand::MouseReport(
MouseButton::LeftMove,
*modifiers,
state.mouse_position,
state.mouse_point,
true,
))
} else {
InputAction::BackendCall(BackendCommand::SelectUpdate(cursor_x, cursor_y))
InputAction::BackendCall(BackendCommand::SelectUpdate(mouse_x, mouse_y))
};

actions.push(cmd);
Expand All @@ -245,7 +246,7 @@ impl TerminalView<'_> {
// Handle link hover if applicable
actions.push(InputAction::BackendCall(BackendCommand::ProcessLink(
LinkAction::Hover,
state.mouse_position,
state.mouse_point,
)));

actions
Expand Down Expand Up @@ -293,3 +294,7 @@ fn start_select_command(layout: &Response, cursor_position: Pos2) -> BackendComm
cursor_position.y - layout.rect.min.y,
)
}

pub fn is_in_terminal(pos: Pos2, rect: Rect) -> bool {
pos.x > rect.min.x && pos.x < rect.max.x && pos.y > rect.min.y && pos.y < rect.max.y
}
61 changes: 36 additions & 25 deletions crates/egui-term/src/view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,30 @@ use crate::alacritty::{BackendCommand, TerminalContext};
use crate::bindings::Binding;
use crate::bindings::{BindingAction, Bindings, InputKind};
use crate::font::TerminalFont;
use crate::input::InputAction;
use crate::input::{is_in_terminal, InputAction};
use crate::scroll_bar::{InteractiveScrollbar, ScrollbarState};
use crate::theme::TerminalTheme;
use crate::types::Size;
use alacritty_terminal::grid::{Dimensions, Scroll};
use alacritty_terminal::index::Point;
use alacritty_terminal::vte::ansi::{Color, NamedColor};
use egui::ImeEvent;
use egui::output::IMEOutput;
use egui::Widget;
use egui::{Context, Event};
use egui::{CursorIcon, Key};
use egui::{Id, Pos2};
use egui::{ImeEvent, Rect};
use egui::{Response, Vec2};

#[derive(Clone, Default)]
pub struct TerminalViewState {
pub is_dragged: bool,
pub scroll_pixels: f32,
// for terminal
pub mouse_position: Point,
pub mouse_point: Point,
pub mouse_position: Option<Pos2>,
pub context_menu_position: Option<Pos2>,
pub cursor_position: Option<Pos2>,
// ime_enabled: bool,
// ime_cursor_range: CursorRange,
pub scrollbar_state: ScrollbarState,
}

Expand Down Expand Up @@ -80,13 +81,14 @@ impl Widget for TerminalView<'_> {
}

// context menu
if let Some(pos) = state.cursor_position {
if !out_of_terminal(pos, &layout) {
if let Some(pos) = state.context_menu_position {
if is_in_terminal(pos, layout.rect) {
self.context_menu(pos, &layout, ui);
}
}

if ui.input(|input_state| input_state.pointer.primary_clicked()) {
state.cursor_position = None;
state.context_menu_position = None;
ui.close();
}

Expand All @@ -97,6 +99,20 @@ impl Widget for TerminalView<'_> {
.resize(&layout)
.process_input(&mut state, &layout);

if let Some(pos) = state.mouse_position {
if is_in_terminal(pos, layout.rect) {
if let Some(cur_pos) = state.cursor_position {
ui.ctx().output_mut(|output| {
let vec = Vec2::new(15., 15.);
output.ime = Some(IMEOutput {
rect: Rect::from_min_size(cur_pos, vec),
cursor_rect: Rect::from_min_size(cur_pos, vec),
})
});
}
}
}

let grid = term.term_ctx.terminal.grid_mut();
let total_lines = grid.total_lines() as f32;
let display_offset = grid.display_offset() as f32;
Expand Down Expand Up @@ -241,10 +257,10 @@ impl<'a> TerminalView<'a> {
modifiers,
pos,
} => {
let new_pos = if out_of_terminal(pos, layout) {
pos.clamp(layout.rect.min, layout.rect.max)
} else {
let new_pos = if is_in_terminal(pos, layout.rect) {
pos
} else {
pos.clamp(layout.rect.min, layout.rect.max)
};

if let Some(action) =
Expand All @@ -257,15 +273,17 @@ impl<'a> TerminalView<'a> {
input_actions = self.mouse_move(state, layout, pos, &modifiers)
}
Event::Ime(event) => match event {
ImeEvent::Disabled => {
// state.ime_enabled = false;
ImeEvent::Preedit(text_mark) => {
if text_mark != "\n" && text_mark != "\r" {
// TODO: handle preedit
}
}
ImeEvent::Enabled | ImeEvent::Preedit(_) => {
// state.ime_enabled = true;
}
ImeEvent::Commit(text) => {
input_actions.push(self.text_input(&text));
ImeEvent::Commit(prediction) => {
if prediction != "\n" && prediction != "\r" {
input_actions.push(self.text_input(&prediction));
}
}
_ => {}
},
_ => {}
};
Expand All @@ -285,10 +303,3 @@ impl<'a> TerminalView<'a> {
self
}
}

fn out_of_terminal(pos: Pos2, layout: &Response) -> bool {
!(pos.x > layout.rect.min.x
&& pos.x < layout.rect.max.x
&& pos.y > layout.rect.min.y
&& pos.y < layout.rect.max.y)
}
5 changes: 0 additions & 5 deletions nxshell/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,11 +126,6 @@ impl eframe::App for NxShell {
ui.with_layout(egui::Layout::left_to_right(egui::Align::TOP), |ui| {
ui.label("Sessions");
});

// TODO: add close menu
// ui.with_layout(egui::Layout::right_to_left(egui::Align::TOP), |ui| {
// ui.label("Sessions");
// });
});

self.search_sessions(ui);
Expand Down
Loading