Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

feat: toggle_floating_state and is_floating (#306) #307

Merged
merged 6 commits into from
Aug 15, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 19 additions & 1 deletion src/builtin/actions/floating.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ pub fn reposition<X: XConn>(dx: i32, dy: i32) -> Box<dyn KeyEventHandler<X>> {
})
}

/// Move the currently focused windo to the floating layer in its current on screen position
/// Move the currently focused window to the floating layer in its current on screen position
pub fn float_focused<X: XConn>() -> Box<dyn KeyEventHandler<X>> {
key_handler(|state, x: &X| {
let id = match state.client_set.current_client() {
Expand Down Expand Up @@ -82,6 +82,24 @@ pub fn sink_focused<X: XConn>() -> Box<dyn KeyEventHandler<X>> {
})
}

/// Sink the current window if it was floating, float it if it was tiled.
pub fn toggle_floating_focused<X: XConn>() -> Box<dyn KeyEventHandler<X>> {
key_handler(|state, x: &X| {
let id = match state.client_set.current_client() {
Some(&id) => id,
None => return Ok(()),
};

let r = x.client_geometry(id)?;

x.modify_and_refresh(state, |cs| {
if let Err(err) = cs.toggle_floating_state(id, r) {
error!(%err, %id, "unable to float requested client window");
}
})
})
}

/// Float all windows in their current tiled position
pub fn float_all<X: XConn>() -> Box<dyn KeyEventHandler<X>> {
key_handler(|state, x: &X| {
Expand Down
25 changes: 25 additions & 0 deletions src/pure/stack_set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,11 @@ where
.map(|rr| rr.applied_to(&self.screens.focus.r))
}

/// Check whether a given client is currently floating.
pub fn is_floating(&mut self, client: &C) -> bool {
self.floating.contains_key(client)
}

/// Check whether a given tag currently has any floating windows present.
///
/// Returns false if the tag given is unknown to this StackSet.
Expand Down Expand Up @@ -799,6 +804,26 @@ impl StackSet<Xid> {
Ok(())
}

/// If a known client is floating, sink it.
/// Otherwise, record it as floating with its preferred screen position.
///
/// # Errors
/// This method with return [Error::UnknownClient] if the given client is
/// not already managed in this stack_set.
///
/// This method with return [Error::ClientIsNotVisible] if the given client is
/// not currently mapped to a screen. This is required to determine the correct
/// relative positioning for the floating client as is it is moved between
/// screens.
pub fn toggle_floating_state(&mut self, client: Xid, r: Rect) -> Result<Option<Rect>> {
Ok(if self.is_floating(&client) {
self.sink(&client)
} else {
self.float(client, r)?;
None
})
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this be bound to a variable and returned as Ok(rect) rather wrapping the whole if statement

}

pub(crate) fn update_screens(&mut self, rects: Vec<Rect>) -> Result<()> {
let n_old = self.screens.len();
let n_new = rects.len();
Expand Down
Loading