diff --git a/jay-config/src/_private/client.rs b/jay-config/src/_private/client.rs index 45729b09..b9200780 100644 --- a/jay-config/src/_private/client.rs +++ b/jay-config/src/_private/client.rs @@ -383,6 +383,10 @@ impl ConfigClient { self.send(&ClientMessage::SeatFocusLayerRel { seat, direction }); } + pub fn seat_focus_tiles(&self, seat: Seat) { + self.send(&ClientMessage::SeatFocusTiles { seat }); + } + pub fn seat_focus(&self, seat: Seat, direction: Direction) { self.send(&ClientMessage::SeatFocus { seat, direction }); } diff --git a/jay-config/src/_private/ipc.rs b/jay-config/src/_private/ipc.rs index 700335bc..6d370b4b 100644 --- a/jay-config/src/_private/ipc.rs +++ b/jay-config/src/_private/ipc.rs @@ -741,6 +741,9 @@ pub enum ClientMessage<'a> { seat: Seat, direction: LayerDirection, }, + SeatFocusTiles { + seat: Seat, + }, } #[derive(Serialize, Deserialize, Debug)] diff --git a/jay-config/src/input.rs b/jay-config/src/input.rs index e1f12633..f1319203 100644 --- a/jay-config/src/input.rs +++ b/jay-config/src/input.rs @@ -316,6 +316,11 @@ impl Seat { get!().seat_focus_layer_rel(self, direction) } + /// Moves the keyboard focus to the tile layer. + pub fn focus_tiles(self) { + get!().seat_focus_tiles(self) + } + /// Moves the keyboard focus of the seat in the specified direction. pub fn focus(self, direction: Direction) { get!().seat_focus(self, direction) diff --git a/src/config/handler.rs b/src/config/handler.rs index 07e9bdf9..995880ae 100644 --- a/src/config/handler.rs +++ b/src/config/handler.rs @@ -2198,6 +2198,12 @@ impl ConfigProxyHandler { Ok(()) } + fn handle_seat_focus_tiles(&self, seat: Seat) -> Result<(), CphError> { + let seat = self.get_seat(seat)?; + seat.focus_tiles(); + Ok(()) + } + fn spaces_change(&self) { struct V; impl NodeVisitorBase for V { @@ -3055,6 +3061,9 @@ impl ConfigProxyHandler { ClientMessage::SeatFocusLayerRel { seat, direction } => self .handle_seat_focus_layer_rel(seat, direction) .wrn("seat_focus_layer_rel")?, + ClientMessage::SeatFocusTiles { seat } => { + self.handle_seat_focus_tiles(seat).wrn("seat_focus_tiles")? + } } Ok(()) } diff --git a/src/ifs/wl_seat.rs b/src/ifs/wl_seat.rs index 4cc0058a..abda9a9e 100644 --- a/src/ifs/wl_seat.rs +++ b/src/ifs/wl_seat.rs @@ -936,6 +936,32 @@ impl WlSeatGlobal { ); } + pub fn focus_tiles(self: &Rc) { + let current = self.keyboard_node.get(); + if matches!( + current.node_layer().layer(), + NodeLayer::Tiled | NodeLayer::Fullscreen, + ) { + return; + } + let Some(output) = current.node_output() else { + return; + }; + let Some(ws) = output.workspace.get() else { + return; + }; + let node = match ws.fullscreen.get() { + Some(fs) => fs as Rc, + _ => match ws.container.get() { + Some(c) => c, + _ => return, + }, + }; + if node.node_visible() && node.node_accepts_focus() { + node.node_do_focus(self, Direction::Unspecified); + } + } + fn set_selection_( self: &Rc, field: &CloneCell>>, diff --git a/toml-config/src/config.rs b/toml-config/src/config.rs index 12051f42..75b17815 100644 --- a/toml-config/src/config.rs +++ b/toml-config/src/config.rs @@ -76,6 +76,7 @@ pub enum SimpleCommand { ToggleBar, FocusHistory(Timeline), FocusLayerRel(LayerDirection), + FocusTiles, } #[derive(Debug, Clone)] diff --git a/toml-config/src/config/parsers/action.rs b/toml-config/src/config/parsers/action.rs index f4746cf2..48428cf1 100644 --- a/toml-config/src/config/parsers/action.rs +++ b/toml-config/src/config/parsers/action.rs @@ -141,6 +141,7 @@ impl ActionParser<'_> { "focus-next" => FocusHistory(Timeline::Newer), "focus-below" => FocusLayerRel(LayerDirection::Below), "focus-above" => FocusLayerRel(LayerDirection::Above), + "focus-tiles" => FocusTiles, _ => { return Err( ActionParserError::UnknownSimpleAction(string.to_string()).spanned(span) diff --git a/toml-config/src/lib.rs b/toml-config/src/lib.rs index 47c80080..7caac63c 100644 --- a/toml-config/src/lib.rs +++ b/toml-config/src/lib.rs @@ -164,6 +164,10 @@ impl Action { let persistent = state.persistent.clone(); B::new(move || persistent.seat.focus_layer_rel(direction)) } + SimpleCommand::FocusTiles => { + let persistent = state.persistent.clone(); + B::new(move || persistent.seat.focus_tiles()) + } }, Action::Multi { actions } => { let actions: Vec<_> = actions.into_iter().map(|a| a.into_fn(state)).collect(); diff --git a/toml-spec/spec/spec.generated.json b/toml-spec/spec/spec.generated.json index 75eadf01..90a3d3e3 100644 --- a/toml-spec/spec/spec.generated.json +++ b/toml-spec/spec/spec.generated.json @@ -1616,7 +1616,8 @@ "focus-prev", "focus-next", "focus-below", - "focus-above" + "focus-above", + "focus-tiles" ] }, "Status": { diff --git a/toml-spec/spec/spec.generated.md b/toml-spec/spec/spec.generated.md index a97edd37..1abda90a 100644 --- a/toml-spec/spec/spec.generated.md +++ b/toml-spec/spec/spec.generated.md @@ -3683,6 +3683,10 @@ The string should have one of the following values: Focuses the layer above the currently focused layer. +- `focus-tiles`: + + Focuses the tile layer. + diff --git a/toml-spec/spec/spec.yaml b/toml-spec/spec/spec.yaml index 67ff709f..ba6c5f69 100644 --- a/toml-spec/spec/spec.yaml +++ b/toml-spec/spec/spec.yaml @@ -868,6 +868,8 @@ SimpleActionName: description: Focuses the layer below the currently focused layer. - value: focus-above description: Focuses the layer above the currently focused layer. + - value: focus-tiles + description: Focuses the tile layer. Color: