Merge branch 'snaggen-primary'

This commit is contained in:
Jeremy Soller 2024-04-26 10:13:51 -06:00
commit 97523f689d
No known key found for this signature in database
GPG key ID: D02FD439211AF56F
3 changed files with 57 additions and 0 deletions

View file

@ -28,6 +28,7 @@ pub fn key_binds() -> HashMap<KeyBind, Action> {
bind!([Ctrl, Shift], Key::Character("Q".into()), WindowClose);
bind!([Ctrl, Shift], Key::Character("T".into()), TabNew);
bind!([Ctrl, Shift], Key::Character("V".into()), Paste);
bind!([Shift], Key::Named(Named::Insert), PastePrimary);
bind!([Ctrl, Shift], Key::Character("W".into()), TabClose);
bind!([Ctrl], Key::Character(",".into()), Settings);

View file

@ -14,6 +14,7 @@ use cosmic::{
clipboard, event,
futures::SinkExt,
keyboard::{Event as KeyEvent, Key, Modifiers},
mouse::{Button as MouseButton, Event as MouseEvent},
subscription::{self, Subscription},
window, Alignment, Color, Event, Length, Limits, Padding, Point,
},
@ -167,6 +168,7 @@ pub enum Action {
About,
ColorSchemes(ColorSchemeKind),
Copy,
CopyPrimary,
Find,
PaneFocusDown,
PaneFocusLeft,
@ -176,6 +178,7 @@ pub enum Action {
PaneSplitVertical,
PaneToggleMaximized,
Paste,
PastePrimary,
ProfileOpen(ProfileId),
Profiles,
SelectAll,
@ -211,6 +214,7 @@ impl MenuAction for Action {
Message::ToggleContextPage(ContextPage::ColorSchemes(*color_scheme_kind))
}
Action::Copy => Message::Copy(entity_opt),
Action::CopyPrimary => Message::CopyPrimary(entity_opt),
Action::Find => Message::Find(true),
Action::PaneFocusDown => Message::PaneFocusAdjacent(pane_grid::Direction::Down),
Action::PaneFocusLeft => Message::PaneFocusAdjacent(pane_grid::Direction::Left),
@ -220,6 +224,7 @@ impl MenuAction for Action {
Action::PaneSplitVertical => Message::PaneSplit(pane_grid::Axis::Vertical),
Action::PaneToggleMaximized => Message::PaneToggleMaximized,
Action::Paste => Message::Paste(entity_opt),
Action::PastePrimary => Message::PastePrimary(entity_opt),
Action::ProfileOpen(profile_id) => Message::ProfileOpen(*profile_id),
Action::Profiles => Message::ToggleContextPage(ContextPage::Profiles),
Action::SelectAll => Message::SelectAll(entity_opt),
@ -263,6 +268,7 @@ pub enum Message {
ColorSchemeTabActivate(widget::segmented_button::Entity),
Config(Config),
Copy(Option<segmented_button::Entity>),
CopyPrimary(Option<segmented_button::Entity>),
DefaultBoldFontWeight(usize),
DefaultDimFontWeight(usize),
DefaultFont(usize),
@ -275,6 +281,7 @@ pub enum Message {
FindNext,
FindPrevious,
FindSearchValueChanged(String),
MiddleClick(pane_grid::Pane, Option<segmented_button::Entity>),
FocusFollowMouse(bool),
Key(Modifiers, Key),
LaunchUrl(String),
@ -288,6 +295,7 @@ pub enum Message {
PaneSplit(pane_grid::Axis),
PaneToggleMaximized,
Paste(Option<segmented_button::Entity>),
PastePrimary(Option<segmented_button::Entity>),
PasteValue(Option<segmented_button::Entity>, String),
ProfileCollapse(ProfileId),
ProfileCommand(ProfileId, String),
@ -1679,6 +1687,20 @@ impl Application for App {
}
return self.update_focus();
}
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 Command::batch([clipboard::write_primary(text), self.update_focus()]);
}
}
} else {
log::warn!("Failed to get focused pane");
}
}
Message::DefaultFont(index) => {
match self.font_names.get(index) {
Some(font_name) => {
@ -1827,6 +1849,16 @@ impl Application for App {
Message::FindSearchValueChanged(value) => {
self.find_search_value = value;
}
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::FocusFollowMouse(focus_follow_mouse) => {
config_set!(focus_follow_mouse, focus_follow_mouse);
}
@ -1902,6 +1934,12 @@ impl Application for App {
None => message::none(),
});
}
Message::PastePrimary(entity_opt) => {
return clipboard::read_primary(move |value_opt| match value_opt {
Some(value) => message::app(Message::PasteValue(entity_opt, value)),
None => message::none(),
});
}
Message::PasteValue(entity_opt, value) => {
if let Some(tab_model) = self.pane_model.active() {
let entity = entity_opt.unwrap_or_else(|| tab_model.active());
@ -2444,6 +2482,7 @@ impl Application for App {
}
let entity = tab_model.active();
let entity_middle_click = tab_model.active();
let terminal_id = self
.terminal_ids
.get(&pane)
@ -2456,6 +2495,9 @@ impl Application for App {
.on_context_menu(move |position_opt| {
Message::TabContextMenu(pane, position_opt)
})
.on_middle_click(move || {
Message::MiddleClick(pane, Some(entity_middle_click))
})
.opacity(self.config.opacity_ratio())
.padding(space_xxs);
@ -2566,6 +2608,9 @@ impl Application for App {
Event::Keyboard(KeyEvent::ModifiersChanged(modifiers)) => {
Some(Message::Modifiers(modifiers))
}
Event::Mouse(MouseEvent::ButtonReleased(MouseButton::Left)) => {
Some(Message::CopyPrimary(None))
}
_ => None,
}),
subscription::channel(

View file

@ -54,6 +54,7 @@ pub struct TerminalBox<'a, Message> {
on_mouse_enter: Option<Box<dyn Fn() -> Message + 'a>>,
opacity: Option<f32>,
mouse_inside_boundary: Option<bool>,
on_middle_click: Option<Box<dyn Fn() -> Message + 'a>>,
key_binds: HashMap<KeyBind, Action>,
}
@ -73,6 +74,7 @@ where
on_mouse_enter: None,
opacity: None,
mouse_inside_boundary: None,
on_middle_click: None,
key_binds: key_binds(),
}
}
@ -115,6 +117,11 @@ where
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 opacity(mut self, opacity: f32) -> Self {
self.opacity = Some(opacity);
self
@ -897,6 +904,10 @@ where
}
}
}
} else if button == Button::Middle {
if let Some(on_middle_click) = &self.on_middle_click {
shell.publish(on_middle_click());
}
}
// Update context menu state
if let Some(on_context_menu) = &self.on_context_menu {