Wayland compositor (wlroots)
git clone https://git.lucas.co/cce-compositor.git
Implement Super + two-finger scroll panning and include other local server/seat updates
src/server/cursor.rs | 23 +++++++++++++++++++++++
src/server/seat.rs | 5 ++++-
src/server/window.rs | 4 +---
src/server/window_manager.rs | 19 +++++++++++++++++++
4 files changed, 47 insertions(+), 4 deletions(-)
diff --git a/src/server/cursor.rs b/src/server/cursor.rs
index 2471e58..b39048d 100644
--- a/src/server/cursor.rs
+++ b/src/server/cursor.rs
@@ -873,6 +873,29 @@ unsafe extern "C" fn handle_axis(listener: *mut ffi::wl_listener, data: *mut std
}
}
+ let wlr_keyboard = ffi::river_wlr_seat_get_keyboard(seat.wlr_seat);
+ let modifiers = if !wlr_keyboard.is_null() {
+ ffi::wlr_keyboard_get_modifiers(wlr_keyboard)
+ } else {
+ 0
+ };
+
+ if (modifiers & 0x40) != 0 {
+ let wm = &mut (*seat.server).wm;
+ let step = delta / wm.desk_zoom;
+ match (*event).orientation {
+ ffi::wl_pointer_axis_WL_POINTER_AXIS_VERTICAL_SCROLL => {
+ wm.desk_pan_y += step;
+ }
+ ffi::wl_pointer_axis_WL_POINTER_AXIS_HORIZONTAL_SCROLL => {
+ wm.desk_pan_x += step;
+ }
+ _ => {}
+ }
+ wm.dirty_windowing();
+ return;
+ }
+
ffi::wlr_seat_pointer_notify_axis(
seat.wlr_seat,
(*event).time_msec,
diff --git a/src/server/seat.rs b/src/server/seat.rs
index 9e8e3a1..92740d3 100644
--- a/src/server/seat.rs
+++ b/src/server/seat.rs
@@ -31,7 +31,7 @@ pub struct SeatOp {
pub start_win_virtual_y: f64,
}
-#[derive(Clone, Copy, PartialEq)]
+#[derive(Clone, Copy, PartialEq, Debug)]
pub enum Focus {
None,
LayerSurface(*mut ffi::wlr_surface),
@@ -304,6 +304,9 @@ impl Seat {
return;
}
+ let bt = std::backtrace::Backtrace::capture();
+ log::info!("[FocusDebug] Seat::focus changing from {:?} to {:?}. Backtrace:\n{}", self.focused, new_focus, bt);
+
// If an exclusive layer surface is active and scheduled for focus,
// block any window manager or other client focus requests (via focus_requested)
// from stealing focus back to a regular window or shell surface.
diff --git a/src/server/window.rs b/src/server/window.rs
index 619cfb3..c67a79e 100644
--- a/src/server/window.rs
+++ b/src/server/window.rs
@@ -2722,7 +2722,5 @@ unsafe fn wl_listener_remove_safe(listener: *mut ffi::wl_listener) {
unsafe extern "C" fn handle_window_commit(listener: *mut ffi::wl_listener, _data: *mut std::ffi::c_void) {
let window = crate::container_of!(listener, Window, commit);
- if (*window).scale != 1.0 {
- (*window).render_finish();
- }
+ (*window).render_finish();
}
diff --git a/src/server/window_manager.rs b/src/server/window_manager.rs
index 81fac4a..6cf1129 100644
--- a/src/server/window_manager.rs
+++ b/src/server/window_manager.rs
@@ -1833,6 +1833,25 @@ fn get_closest_tag(x: f64, y: f64) -> i32 {
format!("error: unknown input command: {}\n", key)
}
}
+ "pointer-move-to" => {
+ if parts.len() < 3 { return "error: usage: pointer-move-to <x> <y>\n".to_string(); }
+ if let (Ok(x), Ok(y)) = (parts[1].parse::<f64>(), parts[2].parse::<f64>()) {
+ let seats_list = &mut (*self.server).input_manager.seats as *mut ffi::wl_list as *mut WlList;
+ let mut curr_seat = (*seats_list).next;
+ while curr_seat != seats_list {
+ let next_seat = (*curr_seat).next;
+ let seat = crate::container_of!(curr_seat, crate::seat::Seat, link);
+ let cursor = &mut (*seat).cursor;
+ ffi::wlr_cursor_warp_absolute(cursor.wlr_cursor, std::ptr::null_mut(), x, y);
+ cursor.update_hovered();
+ cursor.passthrough(crate::util::msec_timestamp());
+ curr_seat = next_seat;
+ }
+ "ok\n".to_string()
+ } else {
+ "error: invalid x or y\n".to_string()
+ }
+ }
_ => format!("error: unknown command: {}\n", action),
}
}