feat: support focus follows mouse
This commit is contained in:
1 parent
29af1bec9c
commit
95b15b6e0d
3 files changed
+29
-1
No files matched your search
@@ -59,6 +59,7 @@ Keyboard and direct-session touchpad settings are applied at startup:
|
|||||||
|
|
||||||
```toml
|
```toml
|
||||||
[input]
|
[input]
|
||||||
|
focus_follows_mouse = false
|
||||||
xkb_layout = "us"
|
xkb_layout = "us"
|
||||||
xkb_variant = ""
|
xkb_variant = ""
|
||||||
xkb_options = []
|
xkb_options = []
|
||||||
|
|||||||
@@ -112,6 +112,7 @@ struct BindingConfig {
|
|||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
pub struct InputSettings {
|
pub struct InputSettings {
|
||||||
|
pub focus_follows_mouse: bool,
|
||||||
pub xkb_layout: String,
|
pub xkb_layout: String,
|
||||||
pub xkb_variant: String,
|
pub xkb_variant: String,
|
||||||
pub xkb_options: Vec<String>,
|
pub xkb_options: Vec<String>,
|
||||||
@@ -129,6 +130,8 @@ pub struct TouchpadSettings {
|
|||||||
|
|
||||||
#[derive(Debug, Deserialize)]
|
#[derive(Debug, Deserialize)]
|
||||||
struct InputConfig {
|
struct InputConfig {
|
||||||
|
#[serde(default)]
|
||||||
|
focus_follows_mouse: bool,
|
||||||
#[serde(default = "default_xkb_layout")]
|
#[serde(default = "default_xkb_layout")]
|
||||||
xkb_layout: String,
|
xkb_layout: String,
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
@@ -146,6 +149,7 @@ struct InputConfig {
|
|||||||
impl Default for InputConfig {
|
impl Default for InputConfig {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
focus_follows_mouse: false,
|
||||||
xkb_layout: default_xkb_layout(),
|
xkb_layout: default_xkb_layout(),
|
||||||
xkb_variant: String::new(),
|
xkb_variant: String::new(),
|
||||||
xkb_options: Vec::new(),
|
xkb_options: Vec::new(),
|
||||||
@@ -454,6 +458,7 @@ impl Config {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Ok(InputSettings {
|
Ok(InputSettings {
|
||||||
|
focus_follows_mouse: self.input.focus_follows_mouse,
|
||||||
xkb_layout: self.input.xkb_layout.clone(),
|
xkb_layout: self.input.xkb_layout.clone(),
|
||||||
xkb_variant: self.input.xkb_variant.clone(),
|
xkb_variant: self.input.xkb_variant.clone(),
|
||||||
xkb_options: self.input.xkb_options.clone(),
|
xkb_options: self.input.xkb_options.clone(),
|
||||||
@@ -1095,12 +1100,13 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn parses_input_and_touchpad_settings() {
|
fn parses_input_and_touchpad_settings() {
|
||||||
let config = parse(
|
let config = parse(
|
||||||
"[input]\nxkb_layout = \"us,de\"\nxkb_variant = \",nodeadkeys\"\nxkb_options = [\"grp:alt_shift_toggle\"]\nrepeat_rate = 30\nrepeat_delay_ms = 450\n\n[input.touchpad]\ntap = false\nnatural_scroll = false\ndisable_while_typing = true",
|
"[input]\nfocus_follows_mouse = true\nxkb_layout = \"us,de\"\nxkb_variant = \",nodeadkeys\"\nxkb_options = [\"grp:alt_shift_toggle\"]\nrepeat_rate = 30\nrepeat_delay_ms = 450\n\n[input.touchpad]\ntap = false\nnatural_scroll = false\ndisable_while_typing = true",
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
config.input_settings().unwrap(),
|
config.input_settings().unwrap(),
|
||||||
InputSettings {
|
InputSettings {
|
||||||
|
focus_follows_mouse: true,
|
||||||
xkb_layout: "us,de".to_owned(),
|
xkb_layout: "us,de".to_owned(),
|
||||||
xkb_variant: ",nodeadkeys".to_owned(),
|
xkb_variant: ",nodeadkeys".to_owned(),
|
||||||
xkb_options: vec!["grp:alt_shift_toggle".to_owned()],
|
xkb_options: vec!["grp:alt_shift_toggle".to_owned()],
|
||||||
|
|||||||
@@ -121,6 +121,7 @@ impl Ferese {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
pointer.frame(self);
|
pointer.frame(self);
|
||||||
|
self.focus_window_under_pointer(&pointer, position);
|
||||||
self.activate_focused_pointer_constraint(&pointer);
|
self.activate_focused_pointer_constraint(&pointer);
|
||||||
crate::backends::direct::render_all(self);
|
crate::backends::direct::render_all(self);
|
||||||
}
|
}
|
||||||
@@ -158,6 +159,7 @@ impl Ferese {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
pointer.frame(self);
|
pointer.frame(self);
|
||||||
|
self.focus_window_under_pointer(&pointer, location);
|
||||||
self.activate_focused_pointer_constraint(&pointer);
|
self.activate_focused_pointer_constraint(&pointer);
|
||||||
crate::backends::direct::render_all(self);
|
crate::backends::direct::render_all(self);
|
||||||
}
|
}
|
||||||
@@ -327,6 +329,25 @@ impl Ferese {
|
|||||||
self.relayout();
|
self.relayout();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn focus_window_under_pointer(
|
||||||
|
&mut self,
|
||||||
|
pointer: &PointerHandle<Self>,
|
||||||
|
position: Point<f64, Logical>,
|
||||||
|
) {
|
||||||
|
if !self.input_settings.focus_follows_mouse || pointer.is_grabbed() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let Some(window) = self.window_under_visual(position) else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
if self.window_ids.get(&window).copied() == self.focused_window {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.focus_window_at(position, SERIAL_COUNTER.next_serial());
|
||||||
|
}
|
||||||
|
|
||||||
fn clamp_pointer_position(&self, requested: Point<f64, Logical>) -> Point<f64, Logical> {
|
fn clamp_pointer_position(&self, requested: Point<f64, Logical>) -> Point<f64, Logical> {
|
||||||
self.space
|
self.space
|
||||||
.outputs()
|
.outputs()
|
||||||
|
|||||||
Reference in new issue
Block a user