Move most of the logic to main

This commit is contained in:
Mattias Eriksson 2024-01-21 21:13:13 +01:00
parent 449803310b
commit 45dd5aa46e
2 changed files with 56 additions and 13 deletions

View file

@ -13,6 +13,7 @@ use cosmic::{
clipboard, event, clipboard, event,
futures::SinkExt, futures::SinkExt,
keyboard::{Event as KeyEvent, KeyCode, Modifiers}, keyboard::{Event as KeyEvent, KeyCode, Modifiers},
mouse::{Button as MouseButton, Event as MouseEvent},
subscription::{self, Subscription}, subscription::{self, Subscription},
window, Alignment, Event, Length, Padding, Point, window, Alignment, Event, Length, Padding, Point,
}, },
@ -165,6 +166,8 @@ pub struct Flags {
#[derive(Clone, Copy, Debug, Eq, PartialEq)] #[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum Action { pub enum Action {
Copy, Copy,
#[cfg(target_family = "unix")]
CopyPrimary,
Find, Find,
PaneFocusDown, PaneFocusDown,
PaneFocusLeft, PaneFocusLeft,
@ -203,6 +206,8 @@ impl Action {
pub fn message(self, entity_opt: Option<segmented_button::Entity>) -> Message { pub fn message(self, entity_opt: Option<segmented_button::Entity>) -> Message {
match self { match self {
Action::Copy => Message::Copy(entity_opt), Action::Copy => Message::Copy(entity_opt),
#[cfg(target_family = "unix")]
Action::CopyPrimary => Message::CopyPrimary(entity_opt),
Action::Find => Message::Find(true), Action::Find => Message::Find(true),
Action::PaneFocusDown => Message::PaneFocusAdjacent(pane_grid::Direction::Down), Action::PaneFocusDown => Message::PaneFocusAdjacent(pane_grid::Direction::Down),
Action::PaneFocusLeft => Message::PaneFocusAdjacent(pane_grid::Direction::Left), Action::PaneFocusLeft => Message::PaneFocusAdjacent(pane_grid::Direction::Left),
@ -245,6 +250,7 @@ pub enum Message {
AppTheme(AppTheme), AppTheme(AppTheme),
Config(Config), Config(Config),
Copy(Option<segmented_button::Entity>), Copy(Option<segmented_button::Entity>),
CopyPrimary(Option<segmented_button::Entity>),
DefaultFont(usize), DefaultFont(usize),
DefaultFontSize(usize), DefaultFontSize(usize),
DefaultFontStretch(usize), DefaultFontStretch(usize),
@ -257,6 +263,8 @@ pub enum Message {
FindNext, FindNext,
FindPrevious, FindPrevious,
FindSearchValueChanged(String), FindSearchValueChanged(String),
#[cfg(target_family = "unix")]
MiddleClick(pane_grid::Pane, Option<segmented_button::Entity>),
PaneClicked(pane_grid::Pane), PaneClicked(pane_grid::Pane),
PaneSplit(pane_grid::Axis), PaneSplit(pane_grid::Axis),
PaneToggleMaximized, PaneToggleMaximized,
@ -916,6 +924,20 @@ impl Application for App {
log::warn!("Failed to get focused pane"); log::warn!("Failed to get focused pane");
} }
} }
Message::CopyPrimary(entity_opt) => {
if let Some(tab_model) = self.pane_model.active() {
let entity = entity_opt.unwrap_or_else(|| tab_model.active());
if let Some(terminal) = tab_model.data::<Mutex<Terminal>>(entity) {
let terminal = terminal.lock().unwrap();
let term = terminal.term.lock();
if let Some(text) = term.selection_to_string() {
return clipboard::write_primary(text);
}
}
} else {
log::warn!("Failed to get focused pane");
}
}
Message::DefaultFont(index) => { Message::DefaultFont(index) => {
match self.font_names.get(index) { match self.font_names.get(index) {
Some(font_name) => { Some(font_name) => {
@ -1050,6 +1072,17 @@ impl Application for App {
Message::FindSearchValueChanged(value) => { Message::FindSearchValueChanged(value) => {
self.find_search_value = value; self.find_search_value = value;
} }
#[cfg(target_family = "unix")]
Message::MiddleClick(pane, entity_opt) => {
self.pane_model.focus = pane;
return Command::batch([
self.update_focus(),
clipboard::read_primary(move |value_opt| match value_opt {
Some(value) => message::app(Message::PasteValue(entity_opt, value)),
None => message::none(),
}),
]);
}
Message::Modifiers(modifiers) => { Message::Modifiers(modifiers) => {
self.modifiers = modifiers; self.modifiers = modifiers;
} }
@ -1409,6 +1442,7 @@ impl Application for App {
} }
let entity = tab_model.active(); let entity = tab_model.active();
let entity_middle_click = tab_model.active();
let terminal_id = self let terminal_id = self
.terminal_ids .terminal_ids
.get(&pane) .get(&pane)
@ -1416,10 +1450,17 @@ impl Application for App {
.unwrap_or_else(widget::Id::unique); .unwrap_or_else(widget::Id::unique);
match tab_model.data::<Mutex<Terminal>>(entity) { match tab_model.data::<Mutex<Terminal>>(entity) {
Some(terminal) => { Some(terminal) => {
let terminal_box = terminal_box(terminal).id(terminal_id).on_context_menu( let mut terminal_box = terminal_box(terminal).id(terminal_id).on_context_menu(
move |position_opt| Message::TabContextMenu(entity, position_opt), move |position_opt| Message::TabContextMenu(entity, position_opt),
); );
#[cfg(target_family = "unix")]
{
terminal_box = terminal_box.on_middle_click(move || {
Message::MiddleClick(pane, Some(entity_middle_click))
});
}
let context_menu = { let context_menu = {
let terminal = terminal.lock().unwrap(); let terminal = terminal.lock().unwrap();
terminal.context_menu terminal.context_menu
@ -1529,6 +1570,9 @@ impl Application for App {
Event::Keyboard(KeyEvent::ModifiersChanged(modifiers)) => { Event::Keyboard(KeyEvent::ModifiersChanged(modifiers)) => {
Some(Message::Modifiers(modifiers)) Some(Message::Modifiers(modifiers))
} }
Event::Mouse(MouseEvent::ButtonReleased(MouseButton::Left)) => {
Some(Message::CopyPrimary(None))
}
_ => None, _ => None,
}), }),
subscription::channel( subscription::channel(

View file

@ -47,6 +47,7 @@ pub struct TerminalBox<'a, Message> {
click_timing: Duration, click_timing: Duration,
context_menu: Option<Point>, context_menu: Option<Point>,
on_context_menu: Option<Box<dyn Fn(Option<Point>) -> Message + 'a>>, on_context_menu: Option<Box<dyn Fn(Option<Point>) -> Message + 'a>>,
on_middle_click: Option<Box<dyn Fn() -> Message + 'a>>,
} }
impl<'a, Message> TerminalBox<'a, Message> impl<'a, Message> TerminalBox<'a, Message>
@ -61,6 +62,7 @@ where
click_timing: Duration::from_millis(500), click_timing: Duration::from_millis(500),
context_menu: None, context_menu: None,
on_context_menu: None, on_context_menu: None,
on_middle_click: None,
} }
} }
@ -91,6 +93,11 @@ where
self.on_context_menu = Some(Box::new(on_context_menu)); self.on_context_menu = Some(Box::new(on_context_menu));
self self
} }
pub fn on_middle_click(mut self, on_middle_click: impl Fn() -> Message + 'a) -> Self {
self.on_middle_click = Some(Box::new(on_middle_click));
self
}
} }
pub fn terminal_box<'a, Message>(terminal: &'a Mutex<Terminal>) -> TerminalBox<'a, Message> pub fn terminal_box<'a, Message>(terminal: &'a Mutex<Terminal>) -> TerminalBox<'a, Message>
@ -575,7 +582,7 @@ where
layout: Layout<'_>, layout: Layout<'_>,
cursor_position: mouse::Cursor, cursor_position: mouse::Cursor,
_renderer: &Renderer, _renderer: &Renderer,
clipboard: &mut dyn Clipboard, _clipboard: &mut dyn Clipboard,
shell: &mut Shell<'_, Message>, shell: &mut Shell<'_, Message>,
_viewport: &Rectangle<f32>, _viewport: &Rectangle<f32>,
) -> Status { ) -> Status {
@ -977,10 +984,9 @@ where
} }
} }
} }
} else if let Button::Middle = button { } else if button == Button::Middle {
#[cfg(target_family = "unix")] if let Some(on_middle_click) = &self.on_middle_click {
if let Some(value) = clipboard.read_primary() { shell.publish(on_middle_click());
terminal.paste(value);
} }
} }
@ -999,13 +1005,6 @@ where
} }
} }
Event::Mouse(MouseEvent::ButtonReleased(Button::Left)) => { Event::Mouse(MouseEvent::ButtonReleased(Button::Left)) => {
#[cfg(target_family = "unix")]
if let Some(Dragging::Buffer) = state.dragging {
let term = terminal.term.lock();
if let Some(text) = term.selection_to_string() {
clipboard.write_primary(text);
}
}
state.dragging = None; state.dragging = None;
status = Status::Captured; status = Status::Captured;
} }