Wayland compositor (wlroots)
git clone https://git.lucas.co/cce-compositor.git
feat: geometric Tiled mode + live overview displacement (policy rework)
Mechanism half of the cce-window-manager Tiled/Floating rework:
- op_end geometric detection: a move/resize that lands every content
edge on a visible grid cell edge promotes the window to Tiled (it then
reports xdg maximized); landing off-grid demotes it to Floating in
place, clearing was_tiled so the arrange Exit restore stays quiet.
- Drag start no longer restores pre-maximize geometry: a tiled window
un-tiles for the drag but keeps its cell-quantized box, so dropping it
grid-aligned re-tiles it.
- Overview moves call policy overview::displace on every motion event —
windows the drag covers scoot live to the side the drag vacated.
- configure.maximized now follows tiling_mode == Tiled. Cascade/Grid are
retired: parse_tiling_mode accepts "tiled" (and legacy "maximized");
unknown/legacy layout names fall back to Floating. The global_layout
field and saved-state entry are gone; the empty LayoutNext arm too.
- Renames: Action::Expose→Overview (IPC command "overview", "expose"
kept as alias; ccectl help updated; migrate-input writes "overview"),
set_expose_scale_iterator→set_overview_scale_iterator,
was_maximized→was_tiled, saved_maximized_*→saved_floating_*.
Live verification pending a compositor restart.
Co-Authored-By: Claude Fable 5 <[email protected]>
CLAUDE.md | 5 +-
src/cce_ctl.rs | 4 +-
src/migrate_input.rs | 2 +-
src/server/cce_window_management.rs | 2 +-
src/server/config.rs | 12 ++--
src/server/cursor.rs | 68 +++++---------------
src/server/seat.rs | 124 +++++++++++++++++++++++++++++++++++-
src/server/window.rs | 54 ++++++++--------
src/server/window_manager.rs | 38 +++++------
src/server/xdg_toplevel.rs | 2 +-
src/server/xwayland_window.rs | 2 +-
11 files changed, 198 insertions(+), 115 deletions(-)
diff --git a/CLAUDE.md b/CLAUDE.md
index 9ab19a9..b7c57ef 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -111,8 +111,9 @@ treats them as opaque.
- **`window.rs`** (~3900 lines) — per-window model and rendering (borders, blur,
viewport transforms).
- **`crate::tiling`** (from `cce-window-manager`) — `TilingMode` enum: `Floating`,
- `Cascade`, `Grid`, `Fullscreen`, `Popup`, `Overlay`, `Maximized`. Modes apply
- per-window and per-viewport.
+ `Tiled` (grid-aligned; the window reports xdg maximized), `Fullscreen`,
+ `Popup`, `Overlay`, `Status`. Tiled-ness is geometric: the seat op's end
+ (`seat.rs::op_end`) promotes/demotes via `policy::snap::is_cell_aligned`.
- Input stack: `input_manager.rs`, `seat.rs`, `cursor.rs`, `keyboard*.rs`,
`xkb_*.rs`, `libinput_*.rs`, `pointer_*.rs`, `tablet*.rs`, `text_input.rs`,
`input_relay.rs`/`input_popup.rs` (IME).
diff --git a/src/cce_ctl.rs b/src/cce_ctl.rs
index ad1f637..f26b883 100644
--- a/src/cce_ctl.rs
+++ b/src/cce_ctl.rs
@@ -54,7 +54,7 @@ fn usage(name: &str, to_stderr: bool) {
print(" close-window <app_id|id> [title-substring] # close a specific window");
print(" center-window [<app_id>] # pan focused/named window on-screen; replies x= y= w= h=");
print(" place-next <app_id> <x> <y> # one-shot: next map of app_id lands near this layout pos");
- print(" expose");
+ print(" overview");
print(" windows [--json] # list windows; --json emits one JSON object per line");
print(" status-hide-mode [true|false]");
print(" adjust-position-mode [true|false|query]");
@@ -74,7 +74,7 @@ fn usage(name: &str, to_stderr: bool) {
print(" bind <mods> <keysym> <action> [args...]");
print(" pbind <mods> <button> <action>");
print(" retile");
- print(" mode <cascade|grid|fullscreen|floating|popup|maximized|overlay> <app_id> [title]");
+ print(" mode <floating|tiled|fullscreen|popup|overlay> <app_id> [title]");
print(" pointer-location");
print(" pointer-move-to <x> <y> (layout pixels)");
print(" pointer-move-by <dx> <dy>");
diff --git a/src/migrate_input.rs b/src/migrate_input.rs
index 04875c2..33496d1 100644
--- a/src/migrate_input.rs
+++ b/src/migrate_input.rs
@@ -107,7 +107,7 @@ pub fn extract_from_config(content: &str) -> Result<Extracted, String> {
("close_window", "close_window"),
("toggle_fullscreen", "toggle_fullscreen"),
("window_switcher", "window_switcher"),
- ("toggle_overview", "expose"),
+ ("toggle_overview", "overview"),
] {
let Some(c) = child(children, prop) else { continue };
let Some(chord) = first_arg_string(c) else { continue };
diff --git a/src/server/cce_window_management.rs b/src/server/cce_window_management.rs
index e737729..3bd2ffd 100644
--- a/src/server/cce_window_management.rs
+++ b/src/server/cce_window_management.rs
@@ -160,7 +160,7 @@ unsafe extern "C" fn toplevel_set_maximized(
let server = (*data).server;
let window_key = (*data).window_key;
if let Some(window) = resolve_window(server, window_key) {
- (*window).tiling_mode = crate::tiling::TilingMode::Maximized;
+ (*window).tiling_mode = crate::tiling::TilingMode::Tiled;
(*window).mode_locked = true;
(*window).wm_scheduled.maximize_requested = crate::window::MaximizeRequest::Maximize;
(*server).wm.dirty_windowing();
diff --git a/src/server/config.rs b/src/server/config.rs
index f298e95..e627eaa 100644
--- a/src/server/config.rs
+++ b/src/server/config.rs
@@ -775,15 +775,15 @@ pub fn parse_hex_color_rgba(hex_str: &str) -> [f32; 4] {
pub fn parse_tiling_mode(s: &str) -> TilingMode {
match s.to_lowercase().as_str() {
- "floating" => TilingMode::Floating,
- "cascade" => TilingMode::Cascade,
- "grid" => TilingMode::Grid,
"fullscreen" => TilingMode::Fullscreen,
"popup" => TilingMode::Popup,
"sidepanel" | "side_panel" | "side-panel" | "pinned" | "overlay" => TilingMode::Overlay,
"status" => TilingMode::Status,
- "maximized" => TilingMode::Maximized,
- _ => TilingMode::Cascade,
+ // "maximized" is the retired name for grid-locked windows.
+ "tiled" | "maximized" => TilingMode::Tiled,
+ // Everything else — including the retired "cascade"/"grid" layout
+ // modes still present in old configs — is Floating.
+ _ => TilingMode::Floating,
}
}
@@ -2217,7 +2217,7 @@ pub fn parse_config(path: &str, state: &mut crate::window_manager::WindowManager
gesture_type: g_type.to_string(),
fingers,
direction: direction.clone(),
- action: Action::Expose,
+ action: Action::Overview,
command: None,
});
}
diff --git a/src/server/cursor.rs b/src/server/cursor.rs
index 8017da7..9323724 100644
--- a/src/server/cursor.rs
+++ b/src/server/cursor.rs
@@ -962,7 +962,7 @@ unsafe extern "C" fn handle_button(listener: *mut ffi::wl_listener, data: *mut s
return;
} else if !overview_win_valid {
cursor.left_click_on_bg_in_overview = true;
- (*server).wm.execute_action(&crate::config::Action::Expose, None);
+ (*server).wm.execute_action(&crate::config::Action::Overview, None);
cursor.pressed.insert((*event).button, None);
return;
}
@@ -1030,22 +1030,10 @@ unsafe extern "C" fn handle_button(listener: *mut ffi::wl_listener, data: *mut s
&& (*target_win).tiling_mode != crate::tiling::TilingMode::Fullscreen
&& (*target_win).tiling_mode != crate::tiling::TilingMode::Overlay
{
- if (*target_win).was_maximized {
- (*target_win).box_geom.width = (*target_win).saved_maximized_width;
- (*target_win).box_geom.height = (*target_win).saved_maximized_height;
- (*target_win).virtual_x = (*target_win).saved_maximized_virtual_x;
- (*target_win).virtual_y = (*target_win).saved_maximized_virtual_y;
- (*target_win).was_maximized = false;
-
- (*target_win).wm_requested.dimensions = Some(crate::window::Dimensions {
- width: (*target_win).saved_maximized_width as u32,
- height: (*target_win).saved_maximized_height as u32,
- });
- (*target_win).wm_requested.bounds = crate::window::Dimensions {
- width: (*target_win).saved_maximized_width as u32,
- height: (*target_win).saved_maximized_height as u32,
- };
- }
+ // A tiled window un-tiles for the drag but keeps its
+ // cell-quantized geometry; landing grid-aligned re-tiles
+ // it (op_end geometric detection).
+ (*target_win).was_tiled = false;
(*target_win).tiling_mode = crate::tiling::TilingMode::Floating;
(*target_win).mode_locked = true;
}
@@ -1136,22 +1124,10 @@ unsafe extern "C" fn handle_button(listener: *mut ffi::wl_listener, data: *mut s
BorderZone::Resize(edges) => {
if (*event).button == 0x110 { // BTN_LEFT
if initial_mode != crate::tiling::TilingMode::Floating {
- if (*border_target_win).was_maximized {
- (*border_target_win).box_geom.width = (*border_target_win).saved_maximized_width;
- (*border_target_win).box_geom.height = (*border_target_win).saved_maximized_height;
- (*border_target_win).virtual_x = (*border_target_win).saved_maximized_virtual_x;
- (*border_target_win).virtual_y = (*border_target_win).saved_maximized_virtual_y;
- (*border_target_win).was_maximized = false;
-
- (*border_target_win).wm_requested.dimensions = Some(crate::window::Dimensions {
- width: (*border_target_win).saved_maximized_width as u32,
- height: (*border_target_win).saved_maximized_height as u32,
- });
- (*border_target_win).wm_requested.bounds = crate::window::Dimensions {
- width: (*border_target_win).saved_maximized_width as u32,
- height: (*border_target_win).saved_maximized_height as u32,
- };
- }
+ // A tiled window un-tiles for the drag but keeps its
+ // cell-quantized geometry; landing grid-aligned re-tiles
+ // it (op_end geometric detection).
+ (*border_target_win).was_tiled = false;
(*border_target_win).tiling_mode = crate::tiling::TilingMode::Floating;
(*border_target_win).mode_locked = true;
}
@@ -1201,11 +1177,11 @@ unsafe extern "C" fn handle_button(listener: *mut ffi::wl_listener, data: *mut s
cursor.last_click_window = border_target_win;
if is_double_click {
- if initial_mode == crate::tiling::TilingMode::Maximized {
+ if initial_mode == crate::tiling::TilingMode::Tiled {
(*border_target_win).tiling_mode = crate::tiling::TilingMode::Floating;
(*border_target_win).mode_locked = true;
} else {
- (*border_target_win).tiling_mode = crate::tiling::TilingMode::Maximized;
+ (*border_target_win).tiling_mode = crate::tiling::TilingMode::Tiled;
(*border_target_win).mode_locked = true;
}
seat.focus(Focus::Window(border_target_win));
@@ -1218,22 +1194,10 @@ unsafe extern "C" fn handle_button(listener: *mut ffi::wl_listener, data: *mut s
if initial_mode != crate::tiling::TilingMode::Floating
&& initial_mode != crate::tiling::TilingMode::Overlay
{
- if (*border_target_win).was_maximized {
- (*border_target_win).box_geom.width = (*border_target_win).saved_maximized_width;
- (*border_target_win).box_geom.height = (*border_target_win).saved_maximized_height;
- (*border_target_win).virtual_x = (*border_target_win).saved_maximized_virtual_x;
- (*border_target_win).virtual_y = (*border_target_win).saved_maximized_virtual_y;
- (*border_target_win).was_maximized = false;
-
- (*border_target_win).wm_requested.dimensions = Some(crate::window::Dimensions {
- width: (*border_target_win).saved_maximized_width as u32,
- height: (*border_target_win).saved_maximized_height as u32,
- });
- (*border_target_win).wm_requested.bounds = crate::window::Dimensions {
- width: (*border_target_win).saved_maximized_width as u32,
- height: (*border_target_win).saved_maximized_height as u32,
- };
- }
+ // A tiled window un-tiles for the drag but keeps its
+ // cell-quantized geometry; landing grid-aligned re-tiles
+ // it (op_end geometric detection).
+ (*border_target_win).was_tiled = false;
(*border_target_win).tiling_mode = crate::tiling::TilingMode::Floating;
(*border_target_win).mode_locked = true;
}
@@ -2177,7 +2141,7 @@ unsafe extern "C" fn handle_swipe_update(listener: *mut ffi::wl_listener, data:
log::info!("Swipe gesture matched action: {:?}", matched_action);
cursor.gesture_triggered = true;
- if matched_action == crate::config::Action::Expose && (*seat.server).wm.mode == crate::window_manager::WindowManagerMode::Overview {
+ if matched_action == crate::config::Action::Overview && (*seat.server).wm.mode == crate::window_manager::WindowManagerMode::Overview {
let lx = cursor.x();
let ly = cursor.y();
let mut hovered_win: *mut crate::window::Window = std::ptr::null_mut();
diff --git a/src/server/seat.rs b/src/server/seat.rs
index d467e0f..8d254a9 100644
--- a/src/server/seat.rs
+++ b/src/server/seat.rs
@@ -803,7 +803,7 @@ impl Seat {
if window.is_null()
|| !matches!(
(*window).tiling_mode,
- crate::tiling::TilingMode::Floating | crate::tiling::TilingMode::Maximized
+ crate::tiling::TilingMode::Floating | crate::tiling::TilingMode::Tiled
)
{
return;
@@ -1015,6 +1015,10 @@ impl Seat {
if (*win).tiling_mode != crate::tiling::TilingMode::Floating
&& (*win).tiling_mode != crate::tiling::TilingMode::Overlay
{
+ // Un-tile for the drag but KEEP the geometry (clearing
+ // was_tiled suppresses the arrange Exit restore);
+ // landing grid-aligned re-tiles it in op_end.
+ (*win).was_tiled = false;
(*win).tiling_mode = crate::tiling::TilingMode::Floating;
(*win).mode_locked = true;
(*self.server).wm.raise_window(win);
@@ -1191,6 +1195,20 @@ impl Seat {
(*win).virtual_x = vx;
(*win).virtual_y = vy;
+ // Overview moves displace what they cover: any
+ // window the drag covers past the threshold
+ // scoots to the side the drag vacated.
+ if (*self.server).wm.mode
+ == crate::window_manager::WindowManagerMode::Overview
+ {
+ displace_covered(
+ self.server,
+ win,
+ (virtual_dx, virtual_dy),
+ &sp,
+ );
+ }
+
let mut out_x = 0;
let mut out_y = 0;
let outputs_list = &mut (*(*self.server).wm.server).om.outputs as *mut ffi::wl_list as *mut WlList;
@@ -1353,6 +1371,49 @@ impl Seat {
(*self.server).wm.dirty_windowing();
}
}
+ // Geometric mode detection: a move/resize that lands every
+ // content edge on a visible desktop-grid cell edge makes the
+ // window Tiled (it then reports the maximized state to its
+ // client); landing off-grid makes it Floating, in place.
+ // Only windows resolving Floating/Tiled participate —
+ // Popup/Overlay/Status/Fullscreen are untouched.
+ let resolved = (*self.server).wm.get_mode_for_window(win);
+ if matches!(
+ resolved,
+ crate::tiling::TilingMode::Floating | crate::tiling::TilingMode::Tiled
+ ) {
+ // Unscaled params: alignment classifies the resting
+ // geometry, the zoom-aware grab distance is irrelevant.
+ let sp = (*self.server).wm.layout.snap_params();
+ let (w, h) = match (*win).wm_requested.dimensions {
+ // A just-finished resize may not be acked into
+ // box_geom yet; the requested size is what the
+ // window is about to become.
+ Some(d) => (d.width as f64, d.height as f64),
+ None => ((*win).box_geom.width as f64, (*win).box_geom.height as f64),
+ };
+ let aligned = crate::policy::snap::is_cell_aligned(
+ (*win).virtual_x,
+ (*win).virtual_y,
+ w,
+ h,
+ &sp,
+ 1.0,
+ );
+ if aligned && resolved != crate::tiling::TilingMode::Tiled {
+ (*win).tiling_mode = crate::tiling::TilingMode::Tiled;
+ (*win).mode_locked = true;
+ (*self.server).wm.dirty_windowing();
+ } else if !aligned && resolved == crate::tiling::TilingMode::Tiled {
+ // Un-tile in place: clearing was_tiled keeps the
+ // arrange Exit transition from restoring the old
+ // floating geometry.
+ (*win).was_tiled = false;
+ (*win).tiling_mode = crate::tiling::TilingMode::Floating;
+ (*win).mode_locked = true;
+ (*self.server).wm.dirty_windowing();
+ }
+ }
// A border TAP — press+release without meaningful motion —
// is a click, not a drag. The press focused the window and
// killed any focus-follow pan (drag protection), which left
@@ -1376,6 +1437,67 @@ impl Seat {
}
}
+/// Live overview displacement for one motion step of a move op: every
+/// mapped, visible Floating/Tiled window the drag covers past the policy
+/// threshold relocates to the side the drag vacated
+/// (`crate::policy::overview::displace`). Single-level on purpose — a
+/// displaced window does not cascade into a third.
+unsafe fn displace_covered(
+ server: *mut Server,
+ win: *mut crate::window::Window,
+ drag_delta: (f64, f64),
+ sp: &crate::policy::snap::SnapParams,
+) {
+ let wm = &mut (*server).wm;
+ let moved = (
+ (*win).virtual_x,
+ (*win).virtual_y,
+ (*win).box_geom.width as f64,
+ (*win).box_geom.height as f64,
+ );
+ let mut ptrs: Vec<*mut crate::window::Window> = Vec::new();
+ let mut cands: Vec<crate::policy::overview::DisplaceCandidate> = Vec::new();
+ for &w in wm.windows.iter() {
+ if w.is_null() || w == win || (*w).closed || (*w).minimized {
+ continue;
+ }
+ if !matches!((*w).state, crate::window::WindowState::Mapped) {
+ continue;
+ }
+ if (*w).is_status_bar() || (*w).is_wallpaper() {
+ continue;
+ }
+ let mode = wm.get_mode_for_window(w);
+ if mode != crate::tiling::TilingMode::Floating
+ && mode != crate::tiling::TilingMode::Tiled
+ {
+ continue;
+ }
+ ptrs.push(w);
+ cands.push(crate::policy::overview::DisplaceCandidate {
+ x: (*w).virtual_x,
+ y: (*w).virtual_y,
+ w: (*w).box_geom.width as f64,
+ h: (*w).box_geom.height as f64,
+ tiled: mode == crate::tiling::TilingMode::Tiled,
+ });
+ }
+ if cands.is_empty() {
+ return;
+ }
+ let moves =
+ crate::policy::overview::displace(moved, drag_delta, &cands, sp, sp.gap_width);
+ if moves.is_empty() {
+ return;
+ }
+ for (idx, (nx, ny)) in moves {
+ let w = ptrs[idx];
+ (*w).virtual_x = nx;
+ (*w).virtual_y = ny;
+ }
+ wm.dirty_windowing();
+}
+
unsafe extern "C" fn handle_request_set_cursor(
listener: *mut ffi::wl_listener,
data: *mut std::ffi::c_void,
diff --git a/src/server/window.rs b/src/server/window.rs
index 21a3b51..14bc19e 100644
--- a/src/server/window.rs
+++ b/src/server/window.rs
@@ -420,11 +420,11 @@ pub struct Window {
pub saved_height: i32,
pub saved_virtual_x: f64,
pub saved_virtual_y: f64,
- pub was_maximized: bool,
- pub saved_maximized_width: i32,
- pub saved_maximized_height: i32,
- pub saved_maximized_virtual_x: f64,
- pub saved_maximized_virtual_y: f64,
+ pub was_tiled: bool,
+ pub saved_floating_width: i32,
+ pub saved_floating_height: i32,
+ pub saved_floating_virtual_x: f64,
+ pub saved_floating_virtual_y: f64,
pub wm_scheduled: WmScheduledState,
pub wm_sent: WmSentState,
@@ -625,11 +625,11 @@ impl Window {
saved_height: 0,
saved_virtual_x: 0.0,
saved_virtual_y: 0.0,
- was_maximized: false,
- saved_maximized_width: 0,
- saved_maximized_height: 0,
- saved_maximized_virtual_x: 0.0,
- saved_maximized_virtual_y: 0.0,
+ was_tiled: false,
+ saved_floating_width: 0,
+ saved_floating_height: 0,
+ saved_floating_virtual_x: 0.0,
+ saved_floating_virtual_y: 0.0,
wm_scheduled: WmScheduledState {
dimensions_hint: DimensionsHint { min_width: 0, min_height: 0, max_width: 0, max_height: 0 },
decoration_hint: ffi::zcce_window_v1_decoration_hint_ZCCE_WINDOW_V1_DECORATION_HINT_ONLY_SUPPORTS_CSD,
@@ -1824,9 +1824,9 @@ impl Window {
};
self.wm_requested.dimensions = None;
- let is_maximized_layout = self.tiling_mode == crate::tiling::TilingMode::Cascade
- || self.tiling_mode == crate::tiling::TilingMode::Grid
- || self.tiling_mode == crate::tiling::TilingMode::Maximized;
+ // A tiled window thinks it is maximized: the xdg maximized state
+ // follows the mode.
+ let is_maximized_layout = self.tiling_mode == crate::tiling::TilingMode::Tiled;
self.configure_scheduled = Configure {
width,
height,
@@ -2131,7 +2131,7 @@ impl Window {
ancestor: *mut ffi::wlr_scene_node,
}
- unsafe extern "C" fn set_expose_scale_iterator(
+ unsafe extern "C" fn set_overview_scale_iterator(
buffer: *mut ffi::wlr_scene_buffer,
sx: i32,
sy: i32,
@@ -2178,7 +2178,7 @@ impl Window {
let scale_data_surfaces = ScaleData { scale_x, scale_y, ancestor: self.surfaces.tree as *mut ffi::wlr_scene_node };
ffi::wlr_scene_node_for_each_buffer(
self.surfaces.tree as *mut ffi::wlr_scene_node,
- Some(set_expose_scale_iterator),
+ Some(set_overview_scale_iterator),
&scale_data_surfaces as *const ScaleData as *mut std::ffi::c_void,
);
@@ -2186,7 +2186,7 @@ impl Window {
let scale_data_saved = ScaleData { scale_x, scale_y, ancestor: self.surfaces.saved_tree as *mut ffi::wlr_scene_node };
ffi::wlr_scene_node_for_each_buffer(
self.surfaces.saved_tree as *mut ffi::wlr_scene_node,
- Some(set_expose_scale_iterator),
+ Some(set_overview_scale_iterator),
&scale_data_saved as *const ScaleData as *mut std::ffi::c_void,
);
}
@@ -2194,7 +2194,7 @@ impl Window {
let scale_data_popup = ScaleData { scale_x, scale_y, ancestor: self.popup_tree as *mut ffi::wlr_scene_node };
ffi::wlr_scene_node_for_each_buffer(
self.popup_tree as *mut ffi::wlr_scene_node,
- Some(set_expose_scale_iterator),
+ Some(set_overview_scale_iterator),
&scale_data_popup as *const ScaleData as *mut std::ffi::c_void,
);
self.last_applied_scale = self.scale;
@@ -2379,7 +2379,7 @@ impl Window {
ancestor: *mut ffi::wlr_scene_node,
}
- unsafe extern "C" fn set_expose_scale_iterator(
+ unsafe extern "C" fn set_overview_scale_iterator(
buffer: *mut ffi::wlr_scene_buffer,
sx: i32,
sy: i32,
@@ -2424,7 +2424,7 @@ impl Window {
let scale_data_surfaces = ScaleData { scale: self.scale, ancestor: self.surfaces.tree as *mut ffi::wlr_scene_node };
ffi::wlr_scene_node_for_each_buffer(
self.surfaces.tree as *mut ffi::wlr_scene_node,
- Some(set_expose_scale_iterator),
+ Some(set_overview_scale_iterator),
&scale_data_surfaces as *const ScaleData as *mut std::ffi::c_void,
);
@@ -2432,7 +2432,7 @@ impl Window {
let scale_data_saved = ScaleData { scale: self.scale, ancestor: self.surfaces.saved_tree as *mut ffi::wlr_scene_node };
ffi::wlr_scene_node_for_each_buffer(
self.surfaces.saved_tree as *mut ffi::wlr_scene_node,
- Some(set_expose_scale_iterator),
+ Some(set_overview_scale_iterator),
&scale_data_saved as *const ScaleData as *mut std::ffi::c_void,
);
}
@@ -2440,7 +2440,7 @@ impl Window {
let scale_data_popup = ScaleData { scale: self.scale, ancestor: self.popup_tree as *mut ffi::wlr_scene_node };
ffi::wlr_scene_node_for_each_buffer(
self.popup_tree as *mut ffi::wlr_scene_node,
- Some(set_expose_scale_iterator),
+ Some(set_overview_scale_iterator),
&scale_data_popup as *const ScaleData as *mut std::ffi::c_void,
);
@@ -3900,7 +3900,7 @@ impl Decoration {
ancestor: *mut ffi::wlr_scene_node,
}
- unsafe extern "C" fn set_expose_scale_iterator(
+ unsafe extern "C" fn set_overview_scale_iterator(
buffer: *mut ffi::wlr_scene_buffer,
sx: i32,
sy: i32,
@@ -3945,7 +3945,7 @@ impl Decoration {
let scale_data = ScaleData { scale, ancestor: self.surfaces.tree as *mut ffi::wlr_scene_node };
ffi::wlr_scene_node_for_each_buffer(
self.surfaces.tree as *mut ffi::wlr_scene_node,
- Some(set_expose_scale_iterator),
+ Some(set_overview_scale_iterator),
&scale_data as *const ScaleData as *mut std::ffi::c_void,
);
@@ -3953,7 +3953,7 @@ impl Decoration {
let scale_data_saved = ScaleData { scale, ancestor: self.surfaces.saved_tree as *mut ffi::wlr_scene_node };
ffi::wlr_scene_node_for_each_buffer(
self.surfaces.saved_tree as *mut ffi::wlr_scene_node,
- Some(set_expose_scale_iterator),
+ Some(set_overview_scale_iterator),
&scale_data_saved as *const ScaleData as *mut std::ffi::c_void,
);
}
@@ -3975,7 +3975,7 @@ impl Decoration {
ancestor: *mut ffi::wlr_scene_node,
}
- unsafe extern "C" fn set_expose_scale_iterator(
+ unsafe extern "C" fn set_overview_scale_iterator(
buffer: *mut ffi::wlr_scene_buffer,
sx: i32,
sy: i32,
@@ -4020,7 +4020,7 @@ impl Decoration {
let scale_data = ScaleData { scale, ancestor: self.surfaces.tree as *mut ffi::wlr_scene_node };
ffi::wlr_scene_node_for_each_buffer(
self.surfaces.tree as *mut ffi::wlr_scene_node,
- Some(set_expose_scale_iterator),
+ Some(set_overview_scale_iterator),
&scale_data as *const ScaleData as *mut std::ffi::c_void,
);
@@ -4028,7 +4028,7 @@ impl Decoration {
let scale_data_saved = ScaleData { scale, ancestor: self.surfaces.saved_tree as *mut ffi::wlr_scene_node };
ffi::wlr_scene_node_for_each_buffer(
self.surfaces.saved_tree as *mut ffi::wlr_scene_node,
- Some(set_expose_scale_iterator),
+ Some(set_overview_scale_iterator),
&scale_data_saved as *const ScaleData as *mut std::ffi::c_void,
);
}
diff --git a/src/server/window_manager.rs b/src/server/window_manager.rs
index 5bf12c9..1ab11f9 100644
--- a/src/server/window_manager.rs
+++ b/src/server/window_manager.rs
@@ -81,7 +81,6 @@ pub struct WindowManager {
pub desk_pan_y: f64,
pub desk_zoom: f64,
pub mode: WindowManagerMode,
- pub global_layout: crate::tiling::TilingMode,
pub layout: crate::config::Layout,
pub mode_rules: Vec<crate::config::ModeRule>,
pub keybinds: Vec<crate::config::Keybind>,
@@ -231,7 +230,6 @@ impl WindowManager {
self.desk_zoom = 1.0;
self.pending_screenshot = None;
self.mode = WindowManagerMode::Normal;
- self.global_layout = crate::tiling::TilingMode::Cascade;
self.restore_queue = Vec::new();
self.last_window_states = Vec::new();
self.pending_placements = Vec::new();
@@ -349,7 +347,6 @@ impl WindowManager {
self.desk_pan_y = state.desk_pan_y;
self.desk_zoom = state.desk_zoom;
self.mode = if (state.desk_zoom - 1.0).abs() > 0.001 { WindowManagerMode::Overview } else { WindowManagerMode::Normal };
- self.global_layout = state.global_layout;
self.restore_queue = state.windows;
self.last_window_states = state.last_window_states;
self.has_restored_focused_window = self.restore_queue.iter().any(|w| w.focused);
@@ -680,7 +677,6 @@ impl WindowManager {
desk_pan_x: self.desk_pan_x,
desk_pan_y: self.desk_pan_y,
desk_zoom: self.desk_zoom,
- global_layout: self.global_layout,
windows: saved_wins,
last_window_states: self.last_window_states.clone(),
};
@@ -1051,7 +1047,7 @@ impl WindowManager {
let is_wallpaper = app_id.as_deref() == Some("cce-wallpaper");
let visible = !matches!((*w).state, crate::window::WindowState::Closing | crate::window::WindowState::Init);
let resolved_mode = self.get_mode_for_window(w);
- let expose_eligible = !(*w).minimized
+ let overview_eligible = !(*w).minimized
&& !is_status
&& !is_wallpaper
&& visible
@@ -1075,7 +1071,7 @@ impl WindowManager {
resolved_mode,
visible,
focus_cyclable,
- expose_eligible,
+ overview_eligible,
});
}
@@ -1844,9 +1840,9 @@ impl WindowManager {
active_resize: self.get_active_resize_dimensions(win_ptr),
ssd: (*win_ptr).wm_requested.ssd,
decorations_size: (*win_ptr).measure_decorations(),
- was_maximized: (*win_ptr).was_maximized,
- saved_maximized_size: ((*win_ptr).saved_maximized_width, (*win_ptr).saved_maximized_height),
- saved_maximized_virtual: ((*win_ptr).saved_maximized_virtual_x, (*win_ptr).saved_maximized_virtual_y),
+ was_tiled: (*win_ptr).was_tiled,
+ saved_floating_size: ((*win_ptr).saved_floating_width, (*win_ptr).saved_floating_height),
+ saved_floating_virtual: ((*win_ptr).saved_floating_virtual_x, (*win_ptr).saved_floating_virtual_y),
});
win_ptrs.push(win_ptr);
}
@@ -1946,14 +1942,14 @@ impl WindowManager {
if let Some(opacity) = wp.opacity {
(*win_ptr).rendering_requested.opacity = opacity;
}
- if let Some(((width, height), (vx, vy))) = wp.saved_maximized {
- (*win_ptr).saved_maximized_width = width;
- (*win_ptr).saved_maximized_height = height;
- (*win_ptr).saved_maximized_virtual_x = vx;
- (*win_ptr).saved_maximized_virtual_y = vy;
+ if let Some(((width, height), (vx, vy))) = wp.saved_floating {
+ (*win_ptr).saved_floating_width = width;
+ (*win_ptr).saved_floating_height = height;
+ (*win_ptr).saved_floating_virtual_x = vx;
+ (*win_ptr).saved_floating_virtual_y = vy;
}
- if let Some(was_maximized) = wp.was_maximized {
- (*win_ptr).was_maximized = was_maximized;
+ if let Some(was_tiled) = wp.was_tiled {
+ (*win_ptr).was_tiled = was_tiled;
}
}
@@ -2558,7 +2554,6 @@ impl WindowManager {
log::info!("monolithic execute_action: Exit requested");
self.start_clean_exit();
}
- Action::LayoutNext => {}
_ => {}
}
}
@@ -2897,8 +2892,9 @@ impl WindowManager {
self.execute_action(&crate::config::Action::Close, None);
"ok\n".to_string()
}
- "expose" => {
- self.execute_action(&crate::config::Action::Expose, None);
+ // "expose" is the retired name for the overview toggle.
+ "overview" | "expose" => {
+ self.execute_action(&crate::config::Action::Overview, None);
"ok\n".to_string()
}
"wm-mode" => {
@@ -2908,12 +2904,12 @@ impl WindowManager {
let target = parts[1].to_lowercase();
if target == "normal" {
if self.mode == WindowManagerMode::Overview {
- self.execute_action(&crate::config::Action::Expose, None);
+ self.execute_action(&crate::config::Action::Overview, None);
}
return "ok\n".to_string();
} else if target == "overview" {
if self.mode == WindowManagerMode::Normal {
- self.execute_action(&crate::config::Action::Expose, None);
+ self.execute_action(&crate::config::Action::Overview, None);
}
return "ok\n".to_string();
}
diff --git a/src/server/xdg_toplevel.rs b/src/server/xdg_toplevel.rs
index 7d68c87..9b2a4ad 100644
--- a/src/server/xdg_toplevel.rs
+++ b/src/server/xdg_toplevel.rs
@@ -894,7 +894,7 @@ unsafe extern "C" fn handle_request_maximize(listener: *mut ffi::wl_listener, _d
let window = (*toplevel).window;
if ffi::river_wlr_xdg_toplevel_get_requested_maximized((*toplevel).wlr_toplevel) {
- (*window).tiling_mode = crate::tiling::TilingMode::Maximized;
+ (*window).tiling_mode = crate::tiling::TilingMode::Tiled;
(*window).mode_locked = true;
(*window).wm_scheduled.maximize_requested = crate::window::MaximizeRequest::Maximize;
} else {
diff --git a/src/server/xwayland_window.rs b/src/server/xwayland_window.rs
index 563152d..e5f4bc4 100644
--- a/src/server/xwayland_window.rs
+++ b/src/server/xwayland_window.rs
@@ -548,7 +548,7 @@ unsafe extern "C" fn handle_request_maximize(listener: *mut ffi::wl_listener, _d
let maximized = (*(*xwindow).xsurface).maximized_vert || (*(*xwindow).xsurface).maximized_horz;
let window = (*xwindow).window;
if maximized {
- (*window).tiling_mode = crate::tiling::TilingMode::Maximized;
+ (*window).tiling_mode = crate::tiling::TilingMode::Tiled;
(*window).mode_locked = true;
} else {
(*window).tiling_mode = crate::tiling::TilingMode::Floating;