git.lucas.co / cce-compositor
Wayland compositor (wlroots)
git clone https://git.lucas.co/cce-compositor.git

commit7fcfb97ed390485ceadc5b2f4e6ee6b2851a8cbf
parenta6618f65d7
authorLucas Galante <[email protected]>
date2026-06-23 16:03
fix: allow dragging pinned windows anywhere on the screen and keeping them at their drop coordinates

 src/server/seat.rs           | 35 -----------------------------------
 src/server/window_manager.rs | 44 +++++++++++++++++++++++++-------------------
 2 files changed, 25 insertions(+), 54 deletions(-)

diff --git a/src/server/seat.rs b/src/server/seat.rs
index c34aa1b..1fed336 100644
--- a/src/server/seat.rs
+++ b/src/server/seat.rs
@@ -950,41 +950,6 @@ impl Seat {
                 }
                 if let PointerOpType::Move = op.op_type {
                     if (*win).tiling_mode == crate::tiling::TilingMode::Pinned {
-                        let outputs_list = &mut (*(*self.server).wm.server).om.outputs as *mut ffi::wl_list as *mut WlList;
-                        let mut curr_out = (*outputs_list).next;
-                        let mut target_output: *mut crate::output::Output = std::ptr::null_mut();
-                        while curr_out != outputs_list {
-                            let output = crate::container_of!(curr_out, crate::output::Output, link);
-                            if (*output).sent.state == crate::output::OutputStateValue::Enabled {
-                                target_output = output;
-                                let wlr_box = (*output).sent.box_layout();
-                                let wx = (*win).box_geom.x;
-                                let wy = (*win).box_geom.y;
-                                if wx >= wlr_box.x && wx < wlr_box.x + wlr_box.width
-                                    && wy >= wlr_box.y && wy < wlr_box.y + wlr_box.height
-                                {
-                                    break;
-                                }
-                            }
-                            curr_out = (*curr_out).next;
-                        }
-
-                        if !target_output.is_null() {
-                            let wlr_box = (*target_output).sent.box_layout();
-                            let rx = (*win).box_geom.x - wlr_box.x;
-                            let mid_x = wlr_box.width / 2;
-                            let new_position = if rx < mid_x {
-                                "left".to_string()
-                            } else {
-                                "right".to_string()
-                            };
-
-                            let wm = &mut (*self.server).wm;
-                            if wm.layout.pinned_position != new_position {
-                                wm.layout.pinned_position = new_position;
-                                log::info!("Pinned window moved/dropped, updating pinned_position to {:?}", wm.layout.pinned_position);
-                            }
-                        }
                         (*self.server).wm.dirty_windowing();
                     }
                 }
diff --git a/src/server/window_manager.rs b/src/server/window_manager.rs
index bd020e6..4f1603b 100644
--- a/src/server/window_manager.rs
+++ b/src/server/window_manager.rs
@@ -942,31 +942,37 @@ fn get_closest_tag(x: f64, y: f64) -> i32 {
                 }
             }
 
-            // Arrange pinned windows (fixed on screen, scale = 1.0)
-            let pinned_win = pinned_windows.first().copied();
-            let mut pinned_w = 0;
             let bw = self.layout.border_width;
-            if let Some(sp_win) = pinned_win {
-                let hint_min_w = (*sp_win).wm_scheduled.dimensions_hint.min_width as i32;
-                pinned_w = if hint_min_w > 32 {
-                    std::cmp::max(self.layout.pinned_width, hint_min_w)
-                } else {
-                    self.layout.pinned_width
-                };
-            }
 
             let g = self.layout.pinned_border_gap;
             let dec_h = std::cmp::max(bw, 16);
             for (sp_idx, &win_ptr) in pinned_windows.iter().enumerate() {
                 if sp_idx == 0 {
-                    let sp_x = if self.layout.pinned_position == "right" {
-                        usable_x + usable_w - pinned_w - g + bw
-                    } else {
-                        usable_x + g + bw
-                    };
-                    let sp_y = usable_y + dec_h + g;
-                    let sp_h = (usable_h - (dec_h + bw) - 2 * g).max(1);
-                    let sp_w = (pinned_w - bw * 2).max(1);
+                    let mut sp_x = (*win_ptr).box_geom.x;
+                    let mut sp_y = (*win_ptr).box_geom.y;
+                    let mut sp_w = (*win_ptr).box_geom.width as i32;
+                    let mut sp_h = (*win_ptr).box_geom.height as i32;
+
+                    if sp_w == 0 || sp_h == 0 {
+                        sp_w = if (*win_ptr).wm_scheduled.dimensions_hint.min_width > 32 {
+                            std::cmp::max(self.layout.pinned_width, (*win_ptr).wm_scheduled.dimensions_hint.min_width as i32)
+                        } else {
+                            self.layout.pinned_width
+                        };
+                        sp_h = (usable_h - (dec_h + bw) - 2 * g).max(1);
+
+                        sp_x = if self.layout.pinned_position == "right" {
+                            usable_x + usable_w - sp_w - g + bw
+                        } else {
+                            usable_x + g + bw
+                        };
+                        sp_y = usable_y + dec_h + g;
+
+                        (*win_ptr).box_geom.x = sp_x;
+                        (*win_ptr).box_geom.y = sp_y;
+                        (*win_ptr).box_geom.width = sp_w;
+                        (*win_ptr).box_geom.height = sp_h;
+                    }
 
                     (*win_ptr).rendering_requested.x = sp_x;
                     (*win_ptr).rendering_requested.y = sp_y;