Merge branch 'snaggen-primary'
This commit is contained in:
commit
97523f689d
3 changed files with 57 additions and 0 deletions
|
|
@ -28,6 +28,7 @@ pub fn key_binds() -> HashMap<KeyBind, Action> {
|
||||||
bind!([Ctrl, Shift], Key::Character("Q".into()), WindowClose);
|
bind!([Ctrl, Shift], Key::Character("Q".into()), WindowClose);
|
||||||
bind!([Ctrl, Shift], Key::Character("T".into()), TabNew);
|
bind!([Ctrl, Shift], Key::Character("T".into()), TabNew);
|
||||||
bind!([Ctrl, Shift], Key::Character("V".into()), Paste);
|
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, Shift], Key::Character("W".into()), TabClose);
|
||||||
bind!([Ctrl], Key::Character(",".into()), Settings);
|
bind!([Ctrl], Key::Character(",".into()), Settings);
|
||||||
|
|
||||||
|
|
|
||||||
45
src/main.rs
45
src/main.rs
|
|
@ -14,6 +14,7 @@ use cosmic::{
|
||||||
clipboard, event,
|
clipboard, event,
|
||||||
futures::SinkExt,
|
futures::SinkExt,
|
||||||
keyboard::{Event as KeyEvent, Key, Modifiers},
|
keyboard::{Event as KeyEvent, Key, Modifiers},
|
||||||
|
mouse::{Button as MouseButton, Event as MouseEvent},
|
||||||
subscription::{self, Subscription},
|
subscription::{self, Subscription},
|
||||||
window, Alignment, Color, Event, Length, Limits, Padding, Point,
|
window, Alignment, Color, Event, Length, Limits, Padding, Point,
|
||||||
},
|
},
|
||||||
|
|
@ -167,6 +168,7 @@ pub enum Action {
|
||||||
About,
|
About,
|
||||||
ColorSchemes(ColorSchemeKind),
|
ColorSchemes(ColorSchemeKind),
|
||||||
Copy,
|
Copy,
|
||||||
|
CopyPrimary,
|
||||||
Find,
|
Find,
|
||||||
PaneFocusDown,
|
PaneFocusDown,
|
||||||
PaneFocusLeft,
|
PaneFocusLeft,
|
||||||
|
|
@ -176,6 +178,7 @@ pub enum Action {
|
||||||
PaneSplitVertical,
|
PaneSplitVertical,
|
||||||
PaneToggleMaximized,
|
PaneToggleMaximized,
|
||||||
Paste,
|
Paste,
|
||||||
|
PastePrimary,
|
||||||
ProfileOpen(ProfileId),
|
ProfileOpen(ProfileId),
|
||||||
Profiles,
|
Profiles,
|
||||||
SelectAll,
|
SelectAll,
|
||||||
|
|
@ -211,6 +214,7 @@ impl MenuAction for Action {
|
||||||
Message::ToggleContextPage(ContextPage::ColorSchemes(*color_scheme_kind))
|
Message::ToggleContextPage(ContextPage::ColorSchemes(*color_scheme_kind))
|
||||||
}
|
}
|
||||||
Action::Copy => Message::Copy(entity_opt),
|
Action::Copy => Message::Copy(entity_opt),
|
||||||
|
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),
|
||||||
|
|
@ -220,6 +224,7 @@ impl MenuAction for Action {
|
||||||
Action::PaneSplitVertical => Message::PaneSplit(pane_grid::Axis::Vertical),
|
Action::PaneSplitVertical => Message::PaneSplit(pane_grid::Axis::Vertical),
|
||||||
Action::PaneToggleMaximized => Message::PaneToggleMaximized,
|
Action::PaneToggleMaximized => Message::PaneToggleMaximized,
|
||||||
Action::Paste => Message::Paste(entity_opt),
|
Action::Paste => Message::Paste(entity_opt),
|
||||||
|
Action::PastePrimary => Message::PastePrimary(entity_opt),
|
||||||
Action::ProfileOpen(profile_id) => Message::ProfileOpen(*profile_id),
|
Action::ProfileOpen(profile_id) => Message::ProfileOpen(*profile_id),
|
||||||
Action::Profiles => Message::ToggleContextPage(ContextPage::Profiles),
|
Action::Profiles => Message::ToggleContextPage(ContextPage::Profiles),
|
||||||
Action::SelectAll => Message::SelectAll(entity_opt),
|
Action::SelectAll => Message::SelectAll(entity_opt),
|
||||||
|
|
@ -263,6 +268,7 @@ pub enum Message {
|
||||||
ColorSchemeTabActivate(widget::segmented_button::Entity),
|
ColorSchemeTabActivate(widget::segmented_button::Entity),
|
||||||
Config(Config),
|
Config(Config),
|
||||||
Copy(Option<segmented_button::Entity>),
|
Copy(Option<segmented_button::Entity>),
|
||||||
|
CopyPrimary(Option<segmented_button::Entity>),
|
||||||
DefaultBoldFontWeight(usize),
|
DefaultBoldFontWeight(usize),
|
||||||
DefaultDimFontWeight(usize),
|
DefaultDimFontWeight(usize),
|
||||||
DefaultFont(usize),
|
DefaultFont(usize),
|
||||||
|
|
@ -275,6 +281,7 @@ pub enum Message {
|
||||||
FindNext,
|
FindNext,
|
||||||
FindPrevious,
|
FindPrevious,
|
||||||
FindSearchValueChanged(String),
|
FindSearchValueChanged(String),
|
||||||
|
MiddleClick(pane_grid::Pane, Option<segmented_button::Entity>),
|
||||||
FocusFollowMouse(bool),
|
FocusFollowMouse(bool),
|
||||||
Key(Modifiers, Key),
|
Key(Modifiers, Key),
|
||||||
LaunchUrl(String),
|
LaunchUrl(String),
|
||||||
|
|
@ -288,6 +295,7 @@ pub enum Message {
|
||||||
PaneSplit(pane_grid::Axis),
|
PaneSplit(pane_grid::Axis),
|
||||||
PaneToggleMaximized,
|
PaneToggleMaximized,
|
||||||
Paste(Option<segmented_button::Entity>),
|
Paste(Option<segmented_button::Entity>),
|
||||||
|
PastePrimary(Option<segmented_button::Entity>),
|
||||||
PasteValue(Option<segmented_button::Entity>, String),
|
PasteValue(Option<segmented_button::Entity>, String),
|
||||||
ProfileCollapse(ProfileId),
|
ProfileCollapse(ProfileId),
|
||||||
ProfileCommand(ProfileId, String),
|
ProfileCommand(ProfileId, String),
|
||||||
|
|
@ -1679,6 +1687,20 @@ impl Application for App {
|
||||||
}
|
}
|
||||||
return self.update_focus();
|
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) => {
|
Message::DefaultFont(index) => {
|
||||||
match self.font_names.get(index) {
|
match self.font_names.get(index) {
|
||||||
Some(font_name) => {
|
Some(font_name) => {
|
||||||
|
|
@ -1827,6 +1849,16 @@ impl Application for App {
|
||||||
Message::FindSearchValueChanged(value) => {
|
Message::FindSearchValueChanged(value) => {
|
||||||
self.find_search_value = 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) => {
|
Message::FocusFollowMouse(focus_follow_mouse) => {
|
||||||
config_set!(focus_follow_mouse, focus_follow_mouse);
|
config_set!(focus_follow_mouse, focus_follow_mouse);
|
||||||
}
|
}
|
||||||
|
|
@ -1902,6 +1934,12 @@ impl Application for App {
|
||||||
None => message::none(),
|
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) => {
|
Message::PasteValue(entity_opt, value) => {
|
||||||
if let Some(tab_model) = self.pane_model.active() {
|
if let Some(tab_model) = self.pane_model.active() {
|
||||||
let entity = entity_opt.unwrap_or_else(|| tab_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 = 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)
|
||||||
|
|
@ -2456,6 +2495,9 @@ impl Application for App {
|
||||||
.on_context_menu(move |position_opt| {
|
.on_context_menu(move |position_opt| {
|
||||||
Message::TabContextMenu(pane, position_opt)
|
Message::TabContextMenu(pane, position_opt)
|
||||||
})
|
})
|
||||||
|
.on_middle_click(move || {
|
||||||
|
Message::MiddleClick(pane, Some(entity_middle_click))
|
||||||
|
})
|
||||||
.opacity(self.config.opacity_ratio())
|
.opacity(self.config.opacity_ratio())
|
||||||
.padding(space_xxs);
|
.padding(space_xxs);
|
||||||
|
|
||||||
|
|
@ -2566,6 +2608,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(
|
||||||
|
|
|
||||||
|
|
@ -54,6 +54,7 @@ pub struct TerminalBox<'a, Message> {
|
||||||
on_mouse_enter: Option<Box<dyn Fn() -> Message + 'a>>,
|
on_mouse_enter: Option<Box<dyn Fn() -> Message + 'a>>,
|
||||||
opacity: Option<f32>,
|
opacity: Option<f32>,
|
||||||
mouse_inside_boundary: Option<bool>,
|
mouse_inside_boundary: Option<bool>,
|
||||||
|
on_middle_click: Option<Box<dyn Fn() -> Message + 'a>>,
|
||||||
key_binds: HashMap<KeyBind, Action>,
|
key_binds: HashMap<KeyBind, Action>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -73,6 +74,7 @@ where
|
||||||
on_mouse_enter: None,
|
on_mouse_enter: None,
|
||||||
opacity: None,
|
opacity: None,
|
||||||
mouse_inside_boundary: None,
|
mouse_inside_boundary: None,
|
||||||
|
on_middle_click: None,
|
||||||
key_binds: key_binds(),
|
key_binds: key_binds(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -115,6 +117,11 @@ where
|
||||||
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 opacity(mut self, opacity: f32) -> Self {
|
pub fn opacity(mut self, opacity: f32) -> Self {
|
||||||
self.opacity = Some(opacity);
|
self.opacity = Some(opacity);
|
||||||
self
|
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
|
// Update context menu state
|
||||||
if let Some(on_context_menu) = &self.on_context_menu {
|
if let Some(on_context_menu) = &self.on_context_menu {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue