Wayland compositor (wlroots)
git clone https://git.lucas.co/cce-compositor.git
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;