Wayland compositor (wlroots)
git clone https://git.lucas.co/cce-compositor.git
feat: border move/resize controls work at any zoom
get_border_zone returned None outright in Overview and the motion path
gated hover on mode == Normal, so the resize controls neither revealed
nor worked at any zoom other than 1 — even though the zone math, band
scaling, and the snap/resize pipeline were already zoom-aware. Drop
both gates and split the overview press three ways: a border-band press
falls through to the normal zone handling (resize/move, zoom-aware), a
content press keeps the whole-window overview grab (drag moves, tap
zooms into the window), and only a true background press exits
overview. Verified nested at zoom 0.83: right-edge drag resized
798->936 with the left edge anchored, overview mode retained; content
drag/tap and background exit unchanged.
Co-Authored-By: Claude Fable 5 <[email protected]>
src/server/cursor.rs | 23 +++++++++++++++++------
1 file changed, 17 insertions(+), 6 deletions(-)
diff --git a/src/server/cursor.rs b/src/server/cursor.rs
index d441eeb..90eaf5b 100644
--- a/src/server/cursor.rs
+++ b/src/server/cursor.rs
@@ -546,12 +546,14 @@ impl Cursor {
if !(*window).is_status_bar() && !(*window).is_wallpaper() {
is_window = true;
}
+ // No mode gate: the band scales with the window
+ // (get_border_zone is zoom-aware), so the resize/move
+ // controls reveal and work at any zoom, not just 1.
if !(*window).is_status_bar()
&& !(*window).is_wallpaper()
&& (*window).tiling_mode != crate::tiling::TilingMode::Popup
&& (*window).tiling_mode != crate::tiling::TilingMode::Fullscreen
&& (*window).tiling_mode != crate::tiling::TilingMode::Status
- && (*server).wm.mode == crate::window_manager::WindowManagerMode::Normal
{
match get_border_zone(window, lx, ly) {
BorderZone::Resize(edges) => {
@@ -900,7 +902,19 @@ unsafe extern "C" fn handle_button(listener: *mut ffi::wl_listener, data: *mut s
}
}
- if !clicked_win.is_null() && !(*clicked_win).is_status_bar() && !(*clicked_win).is_wallpaper() {
+ // A press on the border band falls through to the normal
+ // border path below (move/resize by zone, zoom-aware) — the
+ // resize controls work at any zoom. Content presses grab the
+ // whole window; true background presses exit overview.
+ let overview_win_valid = !clicked_win.is_null()
+ && !(*clicked_win).is_status_bar()
+ && !(*clicked_win).is_wallpaper();
+ let overview_border_zone = if overview_win_valid {
+ get_border_zone(clicked_win, lx, ly)
+ } else {
+ BorderZone::None
+ };
+ if overview_win_valid && matches!(overview_border_zone, BorderZone::None) {
(*server).wm.stop_panning_animation();
let cursor_x = (*cursor.wlr_cursor).x;
let cursor_y = (*cursor.wlr_cursor).y;
@@ -929,7 +943,7 @@ unsafe extern "C" fn handle_button(listener: *mut ffi::wl_listener, data: *mut s
cursor.pressed.insert((*event).button, None);
cursor.set_xcursor(b"grab\0".as_ptr() as *const _);
return;
- } else {
+ } else if !overview_win_valid {
cursor.left_click_on_bg_in_overview = true;
(*server).wm.execute_action(&crate::config::Action::Expose, None);
cursor.pressed.insert((*event).button, None);
@@ -2399,9 +2413,6 @@ pub enum BorderZone {
pub use crate::window::HOVER_BAND_MIN;
pub unsafe fn get_border_zone(window: *mut crate::window::Window, lx: f64, ly: f64) -> BorderZone {
- if (*(*window).server).wm.mode == crate::window_manager::WindowManagerMode::Overview {
- return BorderZone::None;
- }
if (*window).tiling_mode == crate::tiling::TilingMode::Popup
|| (*window).tiling_mode == crate::tiling::TilingMode::Fullscreen
|| (*window).tiling_mode == crate::tiling::TilingMode::Status