Skip to content

Commit

Permalink
Merge pull request #187 from mahkoh/jorth/ffm
Browse files Browse the repository at this point in the history
config: make focus-follows-mouse optional
  • Loading branch information
mahkoh authored Apr 27, 2024
2 parents fe2663f + a12065a commit afc360e
Show file tree
Hide file tree
Showing 14 changed files with 96 additions and 6 deletions.
2 changes: 2 additions & 0 deletions deploy-notes.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Unreleased

- Needs jay-config release.
- Needs jay-toml-config release.
- Needs jay-compositor release.

# 1.1.0
Expand Down
9 changes: 8 additions & 1 deletion jay-config/src/_private/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@ use {
logging, Config, ConfigEntry, ConfigEntryGen, PollableId, WireMode, VERSION,
},
exec::Command,
input::{acceleration::AccelProfile, capability::Capability, InputDevice, Seat},
input::{
acceleration::AccelProfile, capability::Capability, FocusFollowsMouseMode, InputDevice,
Seat,
},
keyboard::{
mods::{Modifiers, RELEASE},
syms::KeySym,
Expand Down Expand Up @@ -924,6 +927,10 @@ impl Client {
self.send(&ClientMessage::SetForward { seat, forward })
}

pub fn set_focus_follows_mouse_mode(&self, seat: Seat, mode: FocusFollowsMouseMode) {
self.send(&ClientMessage::SetFocusFollowsMouseMode { seat, mode })
}

pub fn parse_keymap(&self, keymap: &str) -> Keymap {
let res = self.send_with_response(&ClientMessage::ParseKeymap { keymap });
get_response!(res, Keymap(0), ParseKeymap { keymap });
Expand Down
9 changes: 8 additions & 1 deletion jay-config/src/_private/ipc.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
use {
crate::{
input::{acceleration::AccelProfile, capability::Capability, InputDevice, Seat},
input::{
acceleration::AccelProfile, capability::Capability, FocusFollowsMouseMode, InputDevice,
Seat,
},
keyboard::{mods::Modifiers, syms::KeySym, Keymap},
logging::LogLevel,
theme::{colors::Colorable, sized::Resizable, Color},
Expand Down Expand Up @@ -464,6 +467,10 @@ pub enum ClientMessage<'a> {
mod_mask: Modifiers,
sym: KeySym,
},
SetFocusFollowsMouseMode {
seat: Seat,
mode: FocusFollowsMouseMode,
},
}

#[derive(Serialize, Deserialize, Debug)]
Expand Down
15 changes: 15 additions & 0 deletions jay-config/src/input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,21 @@ impl Seat {
pub fn consume(self) {
self.set_forward(false)
}

/// Sets the focus-follows-mouse mode.
pub fn set_focus_follows_mouse_mode(self, mode: FocusFollowsMouseMode) {
get!().set_focus_follows_mouse_mode(self, mode);
}
}

/// A focus-follows-mouse mode.
#[derive(Serialize, Deserialize, Copy, Clone, Debug, Hash, Eq, PartialEq)]
pub enum FocusFollowsMouseMode {
/// When the mouse moves and enters a toplevel, that toplevel gets the keyboard focus.
True,
/// The keyboard focus changes only when clicking on a window or the previously
/// focused window becomes invisible.
False,
}

/// Returns all seats.
Expand Down
1 change: 1 addition & 0 deletions release-notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
- Add support for xdg-dialog-v1.
- Add support for ext-transient-seat-v1.
- Add support for wp-drm-lease-v1.
- Focus-follows-mouse can now be disabled.

# 1.1.0 (2024-04-22)

Expand Down
19 changes: 18 additions & 1 deletion src/config/handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ use {
Capability, CAP_GESTURE, CAP_KEYBOARD, CAP_POINTER, CAP_SWITCH, CAP_TABLET_PAD,
CAP_TABLET_TOOL, CAP_TOUCH,
},
InputDevice, Seat,
FocusFollowsMouseMode, InputDevice, Seat,
},
keyboard::{mods::Modifiers, syms::KeySym, Keymap},
logging::LogLevel,
Expand Down Expand Up @@ -324,6 +324,20 @@ impl ConfigProxyHandler {
Ok(())
}

fn handle_set_focus_follows_mouse_mode(
&self,
seat: Seat,
mode: FocusFollowsMouseMode,
) -> Result<(), CphError> {
let seat = self.get_seat(seat)?;
let focus_follows_mouse = match mode {
FocusFollowsMouseMode::True => true,
FocusFollowsMouseMode::False => false,
};
seat.set_focus_follows_mouse(focus_follows_mouse);
Ok(())
}

fn handle_set_status(&self, status: &str) {
self.state.set_status(status);
}
Expand Down Expand Up @@ -1791,6 +1805,9 @@ impl ConfigProxyHandler {
} => self
.handle_add_shortcut(seat, mod_mask, mods, sym)
.wrn("add_shortcut")?,
ClientMessage::SetFocusFollowsMouseMode { seat, mode } => self
.handle_set_focus_follows_mouse_mode(seat, mode)
.wrn("set_focus_follows_mouse_mode")?,
}
Ok(())
}
Expand Down
6 changes: 6 additions & 0 deletions src/ifs/wl_seat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ pub struct WlSeatGlobal {
input_method: CloneCell<Option<Rc<ZwpInputMethodV2>>>,
input_method_grab: CloneCell<Option<Rc<ZwpInputMethodKeyboardGrabV2>>>,
forward: Cell<bool>,
focus_follows_mouse: Cell<bool>,
}

const CHANGE_CURSOR_MOVED: u32 = 1 << 0;
Expand Down Expand Up @@ -250,6 +251,7 @@ impl WlSeatGlobal {
input_method: Default::default(),
input_method_grab: Default::default(),
forward: Cell::new(false),
focus_follows_mouse: Cell::new(true),
});
state.add_cursor_size(*DEFAULT_CURSOR_SIZE);
let seat = slf.clone();
Expand Down Expand Up @@ -1165,6 +1167,10 @@ impl WlSeatGlobal {
pub fn select_workspace(self: &Rc<Self>, selector: impl WorkspaceSelector) {
self.pointer_owner.select_workspace(self, selector);
}

pub fn set_focus_follows_mouse(&self, focus_follows_mouse: bool) {
self.focus_follows_mouse.set(focus_follows_mouse);
}
}

global_base!(WlSeatGlobal, WlSeat, WlSeatError);
Expand Down
5 changes: 4 additions & 1 deletion src/ifs/wl_seat/event_handling.rs
Original file line number Diff line number Diff line change
Expand Up @@ -756,7 +756,10 @@ impl WlSeatGlobal {
// Enter callbacks
impl WlSeatGlobal {
pub fn enter_toplevel(self: &Rc<Self>, n: Rc<dyn ToplevelNode>) {
if n.tl_accepts_keyboard_focus() && self.changes.get().contains(CHANGE_CURSOR_MOVED) {
if n.tl_accepts_keyboard_focus()
&& self.changes.get().contains(CHANGE_CURSOR_MOVED)
&& self.focus_follows_mouse.get()
{
self.focus_toplevel(n);
}
}
Expand Down
1 change: 1 addition & 0 deletions toml-config/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,7 @@ pub struct Config {
pub inputs: Vec<Input>,
pub idle: Option<Duration>,
pub explicit_sync_enabled: Option<bool>,
pub focus_follows_mouse: bool,
}

#[derive(Debug, Error)]
Expand Down
4 changes: 3 additions & 1 deletion toml-config/src/config/parsers/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ impl Parser for ConfigParser<'_> {
_,
idle_val,
),
(explicit_sync, repeat_rate_val, complex_shortcuts_val),
(explicit_sync, repeat_rate_val, complex_shortcuts_val, focus_follows_mouse),
) = ext.extract((
(
opt(val("keymap")),
Expand Down Expand Up @@ -127,6 +127,7 @@ impl Parser for ConfigParser<'_> {
recover(opt(bol("explicit-sync"))),
opt(val("repeat-rate")),
opt(val("complex-shortcuts")),
recover(opt(bol("focus-follows-mouse"))),
),
))?;
let mut keymap = None;
Expand Down Expand Up @@ -307,6 +308,7 @@ impl Parser for ConfigParser<'_> {
render_device,
inputs,
idle,
focus_follows_mouse: focus_follows_mouse.despan().unwrap_or(true),
})
}
}
10 changes: 9 additions & 1 deletion toml-config/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ use {
config, config_dir,
exec::{set_env, unset_env, Command},
get_workspace,
input::{get_seat, input_devices, on_new_input_device, InputDevice, Seat},
input::{
get_seat, input_devices, on_new_input_device, FocusFollowsMouseMode, InputDevice, Seat,
},
is_reload,
keyboard::{Keymap, ModifiedKeySym},
logging::set_log_level,
Expand Down Expand Up @@ -869,6 +871,12 @@ fn load_config(initial_load: bool, persistent: &Rc<PersistentState>) {
}
}
});
persistent
.seat
.set_focus_follows_mouse_mode(match config.focus_follows_mouse {
true => FocusFollowsMouseMode::True,
false => FocusFollowsMouseMode::False,
});
}

fn create_command(exec: &Exec) -> Command {
Expand Down
4 changes: 4 additions & 0 deletions toml-spec/spec/spec.generated.json
Original file line number Diff line number Diff line change
Expand Up @@ -569,6 +569,10 @@
"idle": {
"description": "The configuration of the idle timeout.\n\nChanging thise field after compositor startup has no effect. Use `jay idle`\nor a `configure-idle` action to change the idle timeout at runtime.\n\n- Example:\n\n ```toml\n idle.minutes = 10\n ```\n",
"$ref": "#/$defs/Idle"
},
"focus-follows-mouse": {
"type": "boolean",
"description": "Configures whether moving the mouse over a window automatically moves the keyboard\nfocus to that window.\n\nThe default is `true`.\n"
}
},
"required": []
Expand Down
9 changes: 9 additions & 0 deletions toml-spec/spec/spec.generated.md
Original file line number Diff line number Diff line change
Expand Up @@ -1086,6 +1086,15 @@ The table has the following fields:
The value of this field should be a [Idle](#types-Idle).
- `focus-follows-mouse` (optional):
Configures whether moving the mouse over a window automatically moves the keyboard
focus to that window.
The default is `true`.
The value of this field should be a boolean.
<a name="types-Connector"></a>
### `Connector`
Expand Down
8 changes: 8 additions & 0 deletions toml-spec/spec/spec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2039,6 +2039,14 @@ Config:
```toml
idle.minutes = 10
```
focus-follows-mouse:
kind: boolean
required: false
description: |
Configures whether moving the mouse over a window automatically moves the keyboard
focus to that window.
The default is `true`.
Idle:
Expand Down

0 comments on commit afc360e

Please sign in to comment.