feat: touch resize, move, window menu

This commit is contained in:
Hojjat 2026-09-03 22:11:55 -06:00 • committed by Jeremy Soller
parent 71ce08c043
commit 9567503d34
2 changed files with 39 additions and 7 deletions

View file

@ -19,7 +19,7 @@ impl TouchHandler for WinitState {
_: &Connection, _: &Connection,
_: &QueueHandle<Self>, _: &QueueHandle<Self>,
touch: &WlTouch, touch: &WlTouch,
_: u32, serial: u32,
_: u32, _: u32,
surface: WlSurface, surface: WlSurface,
id: i32, id: i32,
@ -27,7 +27,12 @@ impl TouchHandler for WinitState {
) { ) {
let window_id = crate::make_wid(&surface); let window_id = crate::make_wid(&surface);
let scale_factor = match self.windows.get_mut().get(&window_id) { let scale_factor = match self.windows.get_mut().get(&window_id) {
Some(window) => window.lock().unwrap().scale_factor(), Some(window) => {
let mut window = window.lock().unwrap();
// Remember the serial so drag/resize requests can use it while the finger is down.
window.touch_down = Some((touch.seat().clone(), serial));
window.scale_factor()
},
None => return, None => return,
}; };
@ -105,8 +110,15 @@ impl TouchHandler for WinitState {
} }
let window_id = crate::make_wid(&touch_point.surface); let window_id = crate::make_wid(&touch_point.surface);
let still_touched = seat_state.touch_map.values().any(|p| p.surface == touch_point.surface);
let scale_factor = match self.windows.get_mut().get(&window_id) { let scale_factor = match self.windows.get_mut().get(&window_id) {
Some(window) => window.lock().unwrap().scale_factor(), Some(window) => {
let mut window = window.lock().unwrap();
if !still_touched {
window.touch_down = None;
}
window.scale_factor()
},
None => return, None => return,
}; };
@ -193,7 +205,11 @@ impl TouchHandler for WinitState {
for (id, touch_point) in seat_state.touch_map.drain() { for (id, touch_point) in seat_state.touch_map.drain() {
let window_id = crate::make_wid(&touch_point.surface); let window_id = crate::make_wid(&touch_point.surface);
let scale_factor = match self.windows.get_mut().get(&window_id) { let scale_factor = match self.windows.get_mut().get(&window_id) {
Some(window) => window.lock().unwrap().scale_factor(), Some(window) => {
let mut window = window.lock().unwrap();
window.touch_down = None;
window.scale_factor()
},
None => return, None => return,
}; };

View file

@ -69,6 +69,9 @@ pub struct WindowState {
/// The pointers observed on the window. /// The pointers observed on the window.
pub pointers: Vec<Weak<ThemedPointer<WinitPointerData>>>, pub pointers: Vec<Weak<ThemedPointer<WinitPointerData>>>,
/// The seat and serial of the touch currently down on the window, if any.
pub touch_down: Option<(WlSeat, u32)>,
selected_cursor: SelectedCursor, selected_cursor: SelectedCursor,
/// Whether the cursor is visible. /// Whether the cursor is visible.
@ -224,6 +227,7 @@ impl WindowState {
min_surface_size: MIN_WINDOW_SIZE, min_surface_size: MIN_WINDOW_SIZE,
pointer_constraints, pointer_constraints,
pointers: Default::default(), pointers: Default::default(),
touch_down: None,
queue_handle: queue_handle.clone(), queue_handle: queue_handle.clone(),
resizable: true, resizable: true,
scale_factor: 1., scale_factor: 1.,
@ -414,7 +418,11 @@ impl WindowState {
pub fn drag_resize_window(&self, direction: ResizeDirection) -> Result<(), RequestError> { pub fn drag_resize_window(&self, direction: ResizeDirection) -> Result<(), RequestError> {
let xdg_toplevel = self.window.xdg_toplevel(); let xdg_toplevel = self.window.xdg_toplevel();
// TODO(kchibisov) handle touch serials. if let Some((seat, serial)) = &self.touch_down {
xdg_toplevel.resize(seat, *serial, resize_direction_to_xdg(direction));
return Ok(());
}
self.apply_on_pointer(|_, data| { self.apply_on_pointer(|_, data| {
let serial = data.latest_button_serial(); let serial = data.latest_button_serial();
let seat = data.seat(); let seat = data.seat();
@ -427,7 +435,11 @@ impl WindowState {
/// Start the window drag. /// Start the window drag.
pub fn drag_window(&self) -> Result<(), RequestError> { pub fn drag_window(&self) -> Result<(), RequestError> {
let xdg_toplevel = self.window.xdg_toplevel(); let xdg_toplevel = self.window.xdg_toplevel();
// TODO(kchibisov) handle touch serials. if let Some((seat, serial)) = &self.touch_down {
xdg_toplevel._move(seat, *serial);
return Ok(());
}
self.apply_on_pointer(|_, data| { self.apply_on_pointer(|_, data| {
let serial = data.latest_button_serial(); let serial = data.latest_button_serial();
let seat = data.seat(); let seat = data.seat();
@ -916,7 +928,11 @@ impl WindowState {
} }
pub fn show_window_menu(&self, position: LogicalPosition<u32>) { pub fn show_window_menu(&self, position: LogicalPosition<u32>) {
// TODO(kchibisov) handle touch serials. if let Some((seat, serial)) = &self.touch_down {
self.window.show_window_menu(seat, *serial, position.into());
return;
}
self.apply_on_pointer(|_, data| { self.apply_on_pointer(|_, data| {
let serial = data.latest_button_serial(); let serial = data.latest_button_serial();
let seat = data.seat(); let seat = data.seat();