Add Focus Follows Mouse
This commit is contained in:
parent
d6946d40bd
commit
c749a02df8
5 changed files with 49 additions and 3 deletions
|
|
@ -24,10 +24,10 @@ palette = "0.7"
|
||||||
git = "https://github.com/pop-os/cosmic-text.git"
|
git = "https://github.com/pop-os/cosmic-text.git"
|
||||||
|
|
||||||
[dependencies.libcosmic]
|
[dependencies.libcosmic]
|
||||||
git = "https://github.com/pop-os/libcosmic.git"
|
#git = "https://github.com/pop-os/libcosmic.git"
|
||||||
default-features = false
|
default-features = false
|
||||||
features = ["tokio", "winit"]
|
features = ["tokio", "winit"]
|
||||||
#path = "../libcosmic"
|
path = "../libcosmic"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["wgpu"]
|
default = ["wgpu"]
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
## Settings
|
## Settings
|
||||||
settings = Settings
|
settings = Settings
|
||||||
|
focus-follow-mouse = Focus Follow Mouse
|
||||||
|
|
||||||
### Appearance
|
### Appearance
|
||||||
appearance = Appearance
|
appearance = Appearance
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,7 @@ pub struct Config {
|
||||||
pub use_bright_bold: bool,
|
pub use_bright_bold: bool,
|
||||||
pub syntax_theme_dark: String,
|
pub syntax_theme_dark: String,
|
||||||
pub syntax_theme_light: String,
|
pub syntax_theme_light: String,
|
||||||
|
pub focus_follow_mouse: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Config {
|
impl Default for Config {
|
||||||
|
|
@ -60,6 +61,7 @@ impl Default for Config {
|
||||||
use_bright_bold: false,
|
use_bright_bold: false,
|
||||||
syntax_theme_dark: "COSMIC Dark".to_string(),
|
syntax_theme_dark: "COSMIC Dark".to_string(),
|
||||||
syntax_theme_light: "COSMIC Light".to_string(),
|
syntax_theme_light: "COSMIC Light".to_string(),
|
||||||
|
focus_follow_mouse: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
23
src/main.rs
23
src/main.rs
|
|
@ -260,6 +260,7 @@ pub enum Message {
|
||||||
PaneDragged(pane_grid::DragEvent),
|
PaneDragged(pane_grid::DragEvent),
|
||||||
PaneResized(pane_grid::ResizeEvent),
|
PaneResized(pane_grid::ResizeEvent),
|
||||||
Modifiers(Modifiers),
|
Modifiers(Modifiers),
|
||||||
|
MouseEnter(pane_grid::Pane),
|
||||||
Paste(Option<segmented_button::Entity>),
|
Paste(Option<segmented_button::Entity>),
|
||||||
PasteValue(Option<segmented_button::Entity>, String),
|
PasteValue(Option<segmented_button::Entity>, String),
|
||||||
SelectAll(Option<segmented_button::Entity>),
|
SelectAll(Option<segmented_button::Entity>),
|
||||||
|
|
@ -284,6 +285,7 @@ pub enum Message {
|
||||||
ZoomIn,
|
ZoomIn,
|
||||||
ZoomOut,
|
ZoomOut,
|
||||||
ZoomReset,
|
ZoomReset,
|
||||||
|
FocusFollowMouse(bool),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||||
|
|
@ -637,6 +639,10 @@ impl App {
|
||||||
.add(
|
.add(
|
||||||
widget::settings::item::builder(fl!("show-headerbar"))
|
widget::settings::item::builder(fl!("show-headerbar"))
|
||||||
.toggler(self.config.show_headerbar, Message::ShowHeaderBar),
|
.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()
|
widget::settings::view_column(vec![settings_view.into()]).into()
|
||||||
|
|
@ -1047,6 +1053,10 @@ impl Application for App {
|
||||||
Message::Modifiers(modifiers) => {
|
Message::Modifiers(modifiers) => {
|
||||||
self.modifiers = modifiers;
|
self.modifiers = modifiers;
|
||||||
}
|
}
|
||||||
|
Message::MouseEnter(pane) => {
|
||||||
|
self.pane_model.focus = pane;
|
||||||
|
return self.update_focus();
|
||||||
|
}
|
||||||
Message::PaneClicked(pane) => {
|
Message::PaneClicked(pane) => {
|
||||||
self.pane_model.focus = pane;
|
self.pane_model.focus = pane;
|
||||||
return self.update_title(Some(pane));
|
return self.update_title(Some(pane));
|
||||||
|
|
@ -1125,6 +1135,12 @@ impl Application for App {
|
||||||
return self.save_config();
|
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) => {
|
Message::SystemThemeModeChange(_theme_mode) => {
|
||||||
return self.update_config();
|
return self.update_config();
|
||||||
}
|
}
|
||||||
|
|
@ -1403,10 +1419,15 @@ 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),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if self.config.focus_follow_mouse {
|
||||||
|
terminal_box =
|
||||||
|
terminal_box.on_mouse_enter(move || Message::MouseEnter(pane));
|
||||||
|
}
|
||||||
|
|
||||||
let context_menu = {
|
let context_menu = {
|
||||||
let terminal = terminal.lock().unwrap();
|
let terminal = terminal.lock().unwrap();
|
||||||
terminal.context_menu
|
terminal.context_menu
|
||||||
|
|
|
||||||
|
|
@ -47,6 +47,8 @@ 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_mouse_enter: Option<Box<dyn Fn() -> Message + 'a>>,
|
||||||
|
mouse_inside_boundary: Option<bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, Message> TerminalBox<'a, Message>
|
impl<'a, Message> TerminalBox<'a, Message>
|
||||||
|
|
@ -61,6 +63,8 @@ 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_mouse_enter: None,
|
||||||
|
mouse_inside_boundary: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -91,6 +95,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_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<Terminal>) -> TerminalBox<'a, Message>
|
pub fn terminal_box<'a, Message>(terminal: &'a Mutex<Terminal>) -> TerminalBox<'a, Message>
|
||||||
|
|
@ -998,6 +1007,19 @@ where
|
||||||
status = Status::Captured;
|
status = Status::Captured;
|
||||||
}
|
}
|
||||||
Event::Mouse(MouseEvent::CursorMoved { .. }) => {
|
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(dragging) = &state.dragging {
|
||||||
if let Some(p) = cursor_position.position() {
|
if let Some(p) = cursor_position.position() {
|
||||||
let x = (p.x - layout.bounds().x) - self.padding.left;
|
let x = (p.x - layout.bounds().x) - self.padding.left;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue