diff --git a/Cargo.toml b/Cargo.toml index 3675f0b..e764e50 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,10 +24,10 @@ palette = "0.7" git = "https://github.com/pop-os/cosmic-text.git" [dependencies.libcosmic] -git = "https://github.com/pop-os/libcosmic.git" +#git = "https://github.com/pop-os/libcosmic.git" default-features = false features = ["tokio", "winit"] -#path = "../libcosmic" +path = "../libcosmic" [features] default = ["wgpu"] diff --git a/i18n/en/cosmic_term.ftl b/i18n/en/cosmic_term.ftl index de8681a..76badf6 100644 --- a/i18n/en/cosmic_term.ftl +++ b/i18n/en/cosmic_term.ftl @@ -2,6 +2,7 @@ ## Settings settings = Settings +focus-follow-mouse = Focus Follow Mouse ### Appearance appearance = Appearance diff --git a/src/config.rs b/src/config.rs index ed855b5..d2c4680 100644 --- a/src/config.rs +++ b/src/config.rs @@ -43,6 +43,7 @@ pub struct Config { pub use_bright_bold: bool, pub syntax_theme_dark: String, pub syntax_theme_light: String, + pub focus_follow_mouse: bool, } impl Default for Config { @@ -60,6 +61,7 @@ impl Default for Config { use_bright_bold: false, syntax_theme_dark: "COSMIC Dark".to_string(), syntax_theme_light: "COSMIC Light".to_string(), + focus_follow_mouse: false, } } } diff --git a/src/main.rs b/src/main.rs index 498b2c6..f892ff5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -260,6 +260,7 @@ pub enum Message { PaneDragged(pane_grid::DragEvent), PaneResized(pane_grid::ResizeEvent), Modifiers(Modifiers), + MouseEnter(pane_grid::Pane), Paste(Option), PasteValue(Option, String), SelectAll(Option), @@ -284,6 +285,7 @@ pub enum Message { ZoomIn, ZoomOut, ZoomReset, + FocusFollowMouse(bool), } #[derive(Clone, Copy, Debug, Eq, PartialEq)] @@ -637,6 +639,10 @@ impl App { .add( widget::settings::item::builder(fl!("show-headerbar")) .toggler(self.config.show_headerbar, Message::ShowHeaderBar), + ) + .add( + widget::settings::item::builder(fl!("focus-follow-mouse")) + .toggler(self.config.focus_follow_mouse, Message::FocusFollowMouse), ); widget::settings::view_column(vec![settings_view.into()]).into() @@ -1047,6 +1053,10 @@ impl Application for App { Message::Modifiers(modifiers) => { self.modifiers = modifiers; } + Message::MouseEnter(pane) => { + self.pane_model.focus = pane; + return self.update_focus(); + } Message::PaneClicked(pane) => { self.pane_model.focus = pane; return self.update_title(Some(pane)); @@ -1125,6 +1135,12 @@ impl Application for App { return self.save_config(); } } + Message::FocusFollowMouse(focus_follow_mouse) => { + if focus_follow_mouse != self.config.focus_follow_mouse { + self.config.focus_follow_mouse = focus_follow_mouse; + return self.save_config(); + } + } Message::SystemThemeModeChange(_theme_mode) => { return self.update_config(); } @@ -1403,10 +1419,15 @@ impl Application for App { .unwrap_or_else(widget::Id::unique); match tab_model.data::>(entity) { 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), ); + if self.config.focus_follow_mouse { + terminal_box = + terminal_box.on_mouse_enter(move || Message::MouseEnter(pane)); + } + let context_menu = { let terminal = terminal.lock().unwrap(); terminal.context_menu diff --git a/src/terminal_box.rs b/src/terminal_box.rs index 6d06515..9cb80e2 100644 --- a/src/terminal_box.rs +++ b/src/terminal_box.rs @@ -47,6 +47,8 @@ pub struct TerminalBox<'a, Message> { click_timing: Duration, context_menu: Option, on_context_menu: Option) -> Message + 'a>>, + on_mouse_enter: Option Message + 'a>>, + mouse_inside_boundary: Option, } impl<'a, Message> TerminalBox<'a, Message> @@ -61,6 +63,8 @@ where click_timing: Duration::from_millis(500), context_menu: None, on_context_menu: None, + on_mouse_enter: None, + mouse_inside_boundary: None, } } @@ -91,6 +95,11 @@ where self.on_context_menu = Some(Box::new(on_context_menu)); self } + + pub fn on_mouse_enter(mut self, on_mouse_enter: impl Fn() -> Message + 'a) -> Self { + self.on_mouse_enter = Some(Box::new(on_mouse_enter)); + self + } } pub fn terminal_box<'a, Message>(terminal: &'a Mutex) -> TerminalBox<'a, Message> @@ -998,6 +1007,19 @@ where status = Status::Captured; } Event::Mouse(MouseEvent::CursorMoved { .. }) => { + if let Some(on_mouse_enter) = &self.on_mouse_enter { + let mouse_is_inside = cursor_position.position_in(layout.bounds()).is_some(); + if let Some(known_is_inside) = self.mouse_inside_boundary { + if mouse_is_inside != known_is_inside { + if mouse_is_inside { + shell.publish(on_mouse_enter()); + } + self.mouse_inside_boundary = Some(mouse_is_inside); + } + } else { + self.mouse_inside_boundary = Some(mouse_is_inside); + } + } if let Some(dragging) = &state.dragging { if let Some(p) = cursor_position.position() { let x = (p.x - layout.bounds().x) - self.padding.left;