add toggle focus between floating and tiled layers
Adds focus_floats(), toggle_focus_float_tiled(), and their IPC bindings so users can bind a key to swap focus between the floating and tiled layers.
This commit is contained in:
parent
23ad546a39
commit
d353779c10
8 changed files with 82 additions and 0 deletions
|
|
@ -399,6 +399,14 @@ impl ConfigClient {
|
|||
self.send(&ClientMessage::SeatFocusTiles { seat });
|
||||
}
|
||||
|
||||
pub fn seat_focus_floats(&self, seat: Seat) {
|
||||
self.send(&ClientMessage::SeatFocusFloats { seat });
|
||||
}
|
||||
|
||||
pub fn seat_toggle_focus_float_tiled(&self, seat: Seat) {
|
||||
self.send(&ClientMessage::SeatToggleFocusFloatTiled { seat });
|
||||
}
|
||||
|
||||
pub fn seat_focus(&self, seat: Seat, direction: Direction) {
|
||||
self.send(&ClientMessage::SeatFocus { seat, direction });
|
||||
}
|
||||
|
|
|
|||
|
|
@ -747,6 +747,12 @@ pub enum ClientMessage<'a> {
|
|||
SeatFocusTiles {
|
||||
seat: Seat,
|
||||
},
|
||||
SeatFocusFloats {
|
||||
seat: Seat,
|
||||
},
|
||||
SeatToggleFocusFloatTiled {
|
||||
seat: Seat,
|
||||
},
|
||||
SetMiddleClickPasteEnabled {
|
||||
enabled: bool,
|
||||
},
|
||||
|
|
|
|||
|
|
@ -321,6 +321,19 @@ impl Seat {
|
|||
get!().seat_focus_tiles(self)
|
||||
}
|
||||
|
||||
/// Moves the keyboard focus to the topmost floating window.
|
||||
pub fn focus_floats(self) {
|
||||
get!().seat_focus_floats(self)
|
||||
}
|
||||
|
||||
/// Toggles keyboard focus between the floating and tiled layers.
|
||||
///
|
||||
/// If focus is on the tiled or fullscreen layer, focus moves to the topmost float.
|
||||
/// If focus is on the floating layer, focus moves to the tiled layer.
|
||||
pub fn toggle_focus_float_tiled(self) {
|
||||
get!().seat_toggle_focus_float_tiled(self)
|
||||
}
|
||||
|
||||
/// Moves the keyboard focus of the seat in the specified direction.
|
||||
pub fn focus(self, direction: Direction) {
|
||||
get!().seat_focus(self, direction)
|
||||
|
|
|
|||
|
|
@ -2359,6 +2359,18 @@ impl ConfigProxyHandler {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_seat_focus_floats(&self, seat: Seat) -> Result<(), CphError> {
|
||||
let seat = self.get_seat(seat)?;
|
||||
seat.focus_floats();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_seat_toggle_focus_float_tiled(&self, seat: Seat) -> Result<(), CphError> {
|
||||
let seat = self.get_seat(seat)?;
|
||||
seat.toggle_focus_float_tiled();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_set_middle_click_paste_enabled(&self, enabled: bool) {
|
||||
self.state.set_primary_selection_enabled(enabled);
|
||||
}
|
||||
|
|
@ -3310,6 +3322,13 @@ impl ConfigProxyHandler {
|
|||
ClientMessage::SeatFocusTiles { seat } => {
|
||||
self.handle_seat_focus_tiles(seat).wrn("seat_focus_tiles")?
|
||||
}
|
||||
ClientMessage::SeatFocusFloats { seat } => {
|
||||
self.handle_seat_focus_floats(seat).wrn("seat_focus_floats")?
|
||||
}
|
||||
ClientMessage::SeatToggleFocusFloatTiled { seat } => {
|
||||
self.handle_seat_toggle_focus_float_tiled(seat)
|
||||
.wrn("seat_toggle_focus_float_tiled")?
|
||||
}
|
||||
ClientMessage::SetMiddleClickPasteEnabled { enabled } => {
|
||||
self.handle_set_middle_click_paste_enabled(enabled)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1163,6 +1163,36 @@ impl WlSeatGlobal {
|
|||
);
|
||||
}
|
||||
|
||||
pub fn toggle_focus_float_tiled(self: &Rc<Self>) {
|
||||
let current = self.keyboard_node.get();
|
||||
match current.node_layer().layer() {
|
||||
NodeLayer::Tiled | NodeLayer::Fullscreen => self.focus_floats(),
|
||||
_ => self.focus_tiles(),
|
||||
}
|
||||
self.maybe_schedule_warp_mouse_to_focus();
|
||||
}
|
||||
|
||||
pub fn focus_floats(self: &Rc<Self>) {
|
||||
let current = self.keyboard_node.get();
|
||||
if current.node_layer().layer() == NodeLayer::Stacked {
|
||||
return;
|
||||
}
|
||||
let Some(output) = current.node_output() else {
|
||||
return;
|
||||
};
|
||||
let Some(ws) = output.workspace.get() else {
|
||||
return;
|
||||
};
|
||||
if let Some(child) = ws
|
||||
.stacked
|
||||
.rev_iter()
|
||||
.filter_map(|node| (*node).clone().node_into_float())
|
||||
.find_map(|float| float.child.get())
|
||||
{
|
||||
child.node_do_focus(self, Direction::Unspecified);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn focus_tiles(self: &Rc<Self>) {
|
||||
let current = self.keyboard_node.get();
|
||||
if matches!(
|
||||
|
|
|
|||
|
|
@ -83,6 +83,7 @@ pub enum SimpleCommand {
|
|||
FocusHistory(Timeline),
|
||||
FocusLayerRel(LayerDirection),
|
||||
FocusTiles,
|
||||
ToggleFocusFloatTiled,
|
||||
CreateMark,
|
||||
JumpToMark,
|
||||
PopMode(bool),
|
||||
|
|
|
|||
|
|
@ -158,6 +158,7 @@ impl ActionParser<'_> {
|
|||
"focus-below" => FocusLayerRel(LayerDirection::Below),
|
||||
"focus-above" => FocusLayerRel(LayerDirection::Above),
|
||||
"focus-tiles" => FocusTiles,
|
||||
"toggle-float-focus" => ToggleFocusFloatTiled,
|
||||
"create-mark" => CreateMark,
|
||||
"jump-to-mark" => JumpToMark,
|
||||
"clear-modes" => PopMode(false),
|
||||
|
|
|
|||
|
|
@ -218,6 +218,10 @@ impl Action {
|
|||
let persistent = state.persistent.clone();
|
||||
b.new(move || persistent.seat.focus_tiles())
|
||||
}
|
||||
SimpleCommand::ToggleFocusFloatTiled => {
|
||||
let persistent = state.persistent.clone();
|
||||
b.new(move || persistent.seat.toggle_focus_float_tiled())
|
||||
}
|
||||
SimpleCommand::CreateMark => {
|
||||
let persistent = state.persistent.clone();
|
||||
b.new(move || persistent.seat.create_mark(None))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue