Move grab requests, clean up stuff

This commit is contained in:
Ottatop 2023-07-28 14:33:14 -05:00
parent 43d6cde926
commit 94d7c4463e
13 changed files with 252 additions and 279 deletions

View file

@ -51,7 +51,7 @@ fn nearest_images(size: u32, images: &[Image]) -> impl Iterator<Item = &Image> {
let nearest_image = images let nearest_image = images
.iter() .iter()
.min_by_key(|image| (size as i32 - image.size as i32).abs()) .min_by_key(|image| (size as i32 - image.size as i32).abs())
.unwrap(); .expect("no nearest image");
images.iter().filter(move |image| { images.iter().filter(move |image| {
image.width == nearest_image.width && image.height == nearest_image.height image.width == nearest_image.width && image.height == nearest_image.height

View file

@ -5,13 +5,14 @@ use smithay::{
// NOTE: maybe alias this to PointerGrabStartData because there's another GrabStartData in // NOTE: maybe alias this to PointerGrabStartData because there's another GrabStartData in
// | input::keyboard // | input::keyboard
input::{ input::{
pointer::PointerGrab,
pointer::{ pointer::{
AxisFrame, ButtonEvent, GrabStartData, MotionEvent, PointerInnerHandle, AxisFrame, ButtonEvent, GrabStartData, MotionEvent, PointerInnerHandle,
RelativeMotionEvent, RelativeMotionEvent,
}, },
SeatHandler, pointer::{Focus, PointerGrab},
Seat, SeatHandler,
}, },
reexports::wayland_server::protocol::wl_surface::WlSurface,
utils::{IsAlive, Logical, Point, Rectangle}, utils::{IsAlive, Logical, Point, Rectangle},
}; };
@ -140,3 +141,69 @@ impl<B: Backend> PointerGrab<State<B>> for MoveSurfaceGrab<State<B>> {
&self.start_data &self.start_data
} }
} }
pub fn move_request_client<B: Backend>(
state: &mut State<B>,
surface: &WlSurface,
seat: &Seat<State<B>>,
serial: smithay::utils::Serial,
) {
let pointer = seat.get_pointer().expect("seat had no pointer");
if let Some(start_data) = crate::pointer::pointer_grab_start_data(&pointer, surface, serial) {
let Some(window) = state.window_for_surface(surface) else {
tracing::error!("Surface had no window, cancelling move request");
return;
};
let initial_window_loc = state
.space
.element_location(&window)
.expect("move request was called on an unmapped window");
let grab = MoveSurfaceGrab {
start_data,
window,
initial_window_loc,
};
pointer.set_grab(state, grab, serial, Focus::Clear);
} else {
tracing::warn!("no grab start data");
}
}
pub fn move_request_server<B: Backend>(
state: &mut State<B>,
surface: &WlSurface,
seat: &Seat<State<B>>,
serial: smithay::utils::Serial,
) {
let pointer = seat.get_pointer().expect("seat had no pointer");
let Some(window) = state.window_for_surface(surface) else {
tracing::error!("Surface had no window, cancelling move request");
return;
};
let initial_window_loc = state
.space
.element_location(&window)
.expect("move request was called on an unmapped window");
const BUTTON_LEFT: u32 = 0x110;
let start_data = smithay::input::pointer::GrabStartData {
focus: pointer
.current_focus()
.map(|focus| (focus, initial_window_loc)),
button: BUTTON_LEFT,
location: pointer.current_location(),
};
let grab = MoveSurfaceGrab {
start_data,
window,
initial_window_loc,
};
pointer.set_grab(state, grab, serial, Focus::Clear);
}

View file

@ -3,8 +3,8 @@
use smithay::{ use smithay::{
desktop::space::SpaceElement, desktop::space::SpaceElement,
input::{ input::{
pointer::{AxisFrame, ButtonEvent, GrabStartData, PointerGrab, PointerInnerHandle}, pointer::{AxisFrame, ButtonEvent, Focus, GrabStartData, PointerGrab, PointerInnerHandle},
SeatHandler, Seat, SeatHandler,
}, },
reexports::{ reexports::{
wayland_protocols::xdg::shell::server::xdg_toplevel::{self}, wayland_protocols::xdg::shell::server::xdg_toplevel::{self},
@ -335,3 +335,105 @@ pub fn handle_commit<B: Backend>(state: &mut State<B>, surface: &WlSurface) -> O
Some(()) Some(())
} }
pub fn resize_request_client<B: Backend>(
state: &mut State<B>,
surface: &WlSurface,
seat: &Seat<State<B>>,
serial: smithay::utils::Serial,
edges: xdg_toplevel::ResizeEdge,
button_used: u32,
) {
let pointer = seat.get_pointer().expect("seat had no pointer");
if let Some(start_data) = crate::pointer::pointer_grab_start_data(&pointer, surface, serial) {
let Some(window) = state.window_for_surface(surface) else {
tracing::error!("Surface had no window, cancelling resize request");
return;
};
if window.with_state(|state| state.floating.is_tiled()) {
return;
}
let initial_window_loc = state
.space
.element_location(&window)
.expect("resize request called on unmapped window");
let initial_window_size = window.geometry().size;
if let Some(WindowElement::Wayland(window)) = state.window_for_surface(surface) {
window.toplevel().with_pending_state(|state| {
state.states.set(xdg_toplevel::State::Resizing);
});
window.toplevel().send_pending_configure();
}
let grab = ResizeSurfaceGrab::start(
start_data,
window,
ResizeEdge(edges),
Rectangle::from_loc_and_size(initial_window_loc, initial_window_size),
button_used,
);
if let Some(grab) = grab {
pointer.set_grab(state, grab, serial, Focus::Clear);
}
}
}
pub fn resize_request_server<B: Backend>(
state: &mut State<B>,
surface: &WlSurface,
seat: &Seat<State<B>>,
serial: smithay::utils::Serial,
edges: xdg_toplevel::ResizeEdge,
button_used: u32,
) {
let pointer = seat.get_pointer().expect("seat had no pointer");
let Some(window) = state.window_for_surface(surface) else {
tracing::error!("Surface had no window, cancelling resize request");
return;
};
if window.with_state(|state| state.floating.is_tiled()) {
return;
}
let initial_window_loc = state
.space
.element_location(&window)
.expect("resize request called on unmapped window");
let initial_window_size = window.geometry().size;
if let Some(WindowElement::Wayland(window)) = state.window_for_surface(surface) {
window.toplevel().with_pending_state(|state| {
state.states.set(xdg_toplevel::State::Resizing);
});
window.toplevel().send_pending_configure();
}
let start_data = smithay::input::pointer::GrabStartData {
focus: pointer
.current_focus()
.map(|focus| (focus, initial_window_loc)),
button: button_used,
location: pointer.current_location(),
};
let grab = ResizeSurfaceGrab::start(
start_data,
window,
ResizeEdge(edges),
Rectangle::from_loc_and_size(initial_window_loc, initial_window_size),
button_used,
);
if let Some(grab) = grab {
pointer.set_grab(state, grab, serial, Focus::Clear);
}
}

View file

@ -221,13 +221,14 @@ impl<B: Backend> SeatHandler for State<B> {
} }
fn focus_changed(&mut self, seat: &Seat<Self>, focused: Option<&Self::KeyboardFocus>) { fn focus_changed(&mut self, seat: &Seat<Self>, focused: Option<&Self::KeyboardFocus>) {
if let Some(focus) = focused.and_then(|focus| focus.wl_surface()) { if let Some(focus) =
if let Some(window) = self.window_for_surface(&focus) { focused.and_then(|focused| self.window_for_surface(&focused.wl_surface()?))
self.focus_state.set_focus(window); {
// let focus = focused.and_then(|surf| self.display_handle.get_client(surf.id()).ok()); self.focus_state.set_focus(focus);
// set_data_device_focus(&self.display_handle, seat, focus);
}
} }
let focus_client =
focused.and_then(|surf| self.display_handle.get_client(surf.wl_surface()?.id()).ok());
set_data_device_focus(&self.display_handle, seat, focus_client);
} }
} }
delegate_seat!(@<B: Backend> State<B>); delegate_seat!(@<B: Backend> State<B>);
@ -286,7 +287,7 @@ impl<B: Backend> XdgShellHandler for State<B> {
self.focus_state self.focus_state
.focused_output .focused_output
.as_ref() .as_ref()
.unwrap() .expect("no focused output")
.with_state(|op_state| { .with_state(|op_state| {
op_state op_state
.tags .tags
@ -392,9 +393,9 @@ impl<B: Backend> XdgShellHandler for State<B> {
} }
fn move_request(&mut self, surface: ToplevelSurface, seat: WlSeat, serial: Serial) { fn move_request(&mut self, surface: ToplevelSurface, seat: WlSeat, serial: Serial) {
crate::xdg::request::move_request( crate::grab::move_grab::move_request_client(
self, self,
&surface, surface.wl_surface(),
&Seat::from_resource(&seat).expect("Couldn't get seat from WlSeat"), &Seat::from_resource(&seat).expect("Couldn't get seat from WlSeat"),
serial, serial,
); );
@ -408,7 +409,7 @@ impl<B: Backend> XdgShellHandler for State<B> {
edges: ResizeEdge, edges: ResizeEdge,
) { ) {
const BUTTON_LEFT: u32 = 0x110; const BUTTON_LEFT: u32 = 0x110;
crate::xdg::request::resize_request( crate::grab::resize_grab::resize_request_client(
self, self,
surface.wl_surface(), surface.wl_surface(),
&Seat::from_resource(&seat).expect("Couldn't get seat from WlSeat"), &Seat::from_resource(&seat).expect("Couldn't get seat from WlSeat"),

View file

@ -4,11 +4,8 @@
// //
// SPDX-License-Identifier: MPL-2.0 // SPDX-License-Identifier: MPL-2.0
use std::time::Duration;
use smithay::{ use smithay::{
desktop::{space::SpaceElement, utils::surface_primary_scanout_output},
input::pointer::Focus,
reexports::wayland_server::Resource, reexports::wayland_server::Resource,
utils::{Logical, Rectangle, SERIAL_COUNTER}, utils::{Logical, Rectangle, SERIAL_COUNTER},
wayland::compositor::{self, CompositorHandler}, wayland::compositor::{self, CompositorHandler},
@ -20,7 +17,6 @@ use smithay::{
use crate::{ use crate::{
backend::Backend, backend::Backend,
grab::resize_grab::{ResizeSurfaceGrab, ResizeSurfaceState},
state::{CalloopData, WithState}, state::{CalloopData, WithState},
window::{WindowBlocker, WindowElement, BLOCKER_COUNTER, window_state::Float}, focus::FocusTarget, window::{WindowBlocker, WindowElement, BLOCKER_COUNTER, window_state::Float}, focus::FocusTarget,
}; };
@ -52,7 +48,7 @@ impl<B: Backend> XwmHandler for CalloopData<B> {
window.set_mapped(true).expect("failed to map x11 window"); window.set_mapped(true).expect("failed to map x11 window");
let window = WindowElement::X11(window); let window = WindowElement::X11(window);
self.state.space.map_element(window.clone(), (0, 0), true); self.state.space.map_element(window.clone(), (0, 0), true);
let bbox = self.state.space.element_bbox(&window).unwrap(); let bbox = self.state.space.element_bbox(&window).expect("called element_bbox on an unmapped window");
let WindowElement::X11(surface) = &window else { unreachable!() }; let WindowElement::X11(surface) = &window else { unreachable!() };
tracing::debug!("map_window_request, configuring with bbox {bbox:?}"); tracing::debug!("map_window_request, configuring with bbox {bbox:?}");
surface surface
@ -109,7 +105,7 @@ impl<B: Backend> XwmHandler for CalloopData<B> {
.focus_state .focus_state
.focused_output .focused_output
.as_ref() .as_ref()
.unwrap() .expect("no focused output")
.with_state(|op_state| { .with_state(|op_state| {
op_state op_state
.tags .tags
@ -228,7 +224,7 @@ impl<B: Backend> XwmHandler for CalloopData<B> {
} }
} }
fn destroyed_window(&mut self, xwm: XwmId, window: X11Surface) { fn destroyed_window(&mut self, _xwm: XwmId, window: X11Surface) {
let win = self let win = self
.state .state
.windows .windows
@ -253,13 +249,13 @@ impl<B: Backend> XwmHandler for CalloopData<B> {
fn configure_request( fn configure_request(
&mut self, &mut self,
xwm: XwmId, _xwm: XwmId,
window: X11Surface, window: X11Surface,
x: Option<i32>, _x: Option<i32>,
y: Option<i32>, _y: Option<i32>,
w: Option<u32>, w: Option<u32>,
h: Option<u32>, h: Option<u32>,
reorder: Option<Reorder>, _reorder: Option<Reorder>,
) { ) {
let mut geo = window.geometry(); let mut geo = window.geometry();
if let Some(w) = w { if let Some(w) = w {
@ -276,10 +272,10 @@ impl<B: Backend> XwmHandler for CalloopData<B> {
fn configure_notify( fn configure_notify(
&mut self, &mut self,
xwm: XwmId, _xwm: XwmId,
window: X11Surface, window: X11Surface,
geometry: Rectangle<i32, Logical>, geometry: Rectangle<i32, Logical>,
above: Option<smithay::reexports::x11rb::protocol::xproto::Window>, _above: Option<smithay::reexports::x11rb::protocol::xproto::Window>,
) { ) {
// tracing::debug!("x11 configure_notify"); // tracing::debug!("x11 configure_notify");
let Some(win) = self let Some(win) = self
@ -299,81 +295,34 @@ impl<B: Backend> XwmHandler for CalloopData<B> {
// TODO: anvil has a TODO here // TODO: anvil has a TODO here
} }
fn maximize_request(&mut self, xwm: XwmId, window: X11Surface) { // fn maximize_request(&mut self, xwm: XwmId, window: X11Surface) {
// TODO: // // TODO:
} // }
//
fn unmaximize_request(&mut self, xwm: XwmId, window: X11Surface) { // fn unmaximize_request(&mut self, xwm: XwmId, window: X11Surface) {
// TODO: // // TODO:
} // }
//
fn fullscreen_request(&mut self, xwm: XwmId, window: X11Surface) { // fn fullscreen_request(&mut self, xwm: XwmId, window: X11Surface) {
// TODO: // // TODO:
// window.set_fullscreen(true).unwrap(); // // window.set_fullscreen(true).unwrap();
} // }
//
fn unfullscreen_request(&mut self, xwm: XwmId, window: X11Surface) { // fn unfullscreen_request(&mut self, xwm: XwmId, window: X11Surface) {
// TODO: // // TODO:
} // }
fn resize_request( fn resize_request(
&mut self, &mut self,
_xwm: XwmId, _xwm: XwmId,
window: X11Surface, _window: X11Surface,
button: u32, _button: u32,
resize_edge: smithay::xwayland::xwm::ResizeEdge, _resize_edge: smithay::xwayland::xwm::ResizeEdge,
) { ) {
// let seat = &self.state.seat; // TODO:
// let pointer = seat.get_pointer().expect("failed to get pointer");
// let start_data = pointer.grab_start_data().expect("no grab start data");
//
// let Some(win) = self
// .state
// .space
// .elements()
// .find(|elem| matches!(elem, WindowElement::X11(surface) if surface == &window))
// else {
// return;
// };
//
// let initial_window_location = self
// .state
// .space
// .element_location(win)
// .expect("failed to get x11 loc");
// let initial_window_size = win.geometry().size;
//
// if let Some(wl_surface) = win.wl_surface() {
// wl_surface.with_state(|state| {
// state.resize_state = ResizeSurfaceState::Resizing {
// edges: resize_edge.into(),
// initial_window_rect: Rectangle::from_loc_and_size(
// initial_window_location,
// initial_window_size,
// ),
// };
// });
//
// let grab = ResizeSurfaceGrab::start(
// start_data,
// win.clone(),
// resize_edge.into(),
// Rectangle::from_loc_and_size(initial_window_location, initial_window_size),
// button, // BUTTON_LEFT
// );
//
// if let Some(grab) = grab {
// pointer.set_grab(
// &mut self.state,
// grab,
// SERIAL_COUNTER.next_serial(),
// Focus::Clear,
// );
// }
// }
} }
fn move_request(&mut self, xwm: XwmId, window: X11Surface, button: u32) { fn move_request(&mut self, _xwm: XwmId, _window: X11Surface, _button: u32) {
// TODO: // TODO:
} }

View file

@ -79,7 +79,7 @@ impl<B: Backend> State<B> {
if self.move_mode { if self.move_mode {
if event.button_code() == BUTTON_LEFT { if event.button_code() == BUTTON_LEFT {
if let Some(wl_surf) = window.wl_surface() { if let Some(wl_surf) = window.wl_surface() {
crate::xdg::request::move_request_force( crate::grab::move_grab::move_request_server(
self, self,
&wl_surf, &wl_surf,
&self.seat.clone(), &self.seat.clone(),
@ -127,7 +127,7 @@ impl<B: Backend> State<B> {
}; };
if let Some(wl_surf) = window.wl_surface() { if let Some(wl_surf) = window.wl_surface() {
crate::xdg::request::resize_request_force( crate::grab::resize_grab::resize_request_server(
self, self,
&wl_surf, &wl_surf,
&self.seat.clone(), &self.seat.clone(),
@ -146,7 +146,9 @@ impl<B: Backend> State<B> {
.expect("no xwm") .expect("no xwm")
.raise_window(surface) .raise_window(surface)
.expect("failed to raise x11 win"); .expect("failed to raise x11 win");
surface.set_activated(true).unwrap(); surface
.set_activated(true)
.expect("failed to set x11 win to activated");
} }
tracing::debug!( tracing::debug!(

View file

@ -432,7 +432,12 @@ impl<B: Backend> State<B> {
} }
} }
let output = self.focus_state.focused_output.clone().unwrap(); // FIXME: unwrap // TODO: don't use the focused output, use the outputs the two windows are on
let output = self
.focus_state
.focused_output
.clone()
.expect("no focused output");
self.re_layout(&output); self.re_layout(&output);
} }
} }

View file

@ -8,7 +8,7 @@
//! While Pinnacle is not a library, this documentation serves to guide those who want to //! While Pinnacle is not a library, this documentation serves to guide those who want to
//! contribute or learn how building something like this works. //! contribute or learn how building something like this works.
// #![deny(unused_imports)] // gonna force myself to keep stuff clean #![deny(unused_imports)] // gonna force myself to keep stuff clean
#![warn(clippy::unwrap_used)] #![warn(clippy::unwrap_used)]
mod api; mod api;
@ -25,7 +25,6 @@ mod render;
mod state; mod state;
mod tag; mod tag;
mod window; mod window;
mod xdg;
use std::error::Error; use std::error::Error;

View file

@ -5,7 +5,7 @@ use smithay::{
element::{surface::WaylandSurfaceRenderElement, AsRenderElements, Wrap}, element::{surface::WaylandSurfaceRenderElement, AsRenderElements, Wrap},
ImportAll, ImportMem, Renderer, Texture, ImportAll, ImportMem, Renderer, Texture,
}, },
desktop::space::{SpaceElement, SpaceRenderElements}, desktop::space::SpaceRenderElements,
render_elements, render_elements,
utils::{Physical, Point, Scale}, utils::{Physical, Point, Scale},
}; };
@ -44,7 +44,7 @@ where
scale: Scale<f64>, scale: Scale<f64>,
alpha: f32, alpha: f32,
) -> Vec<C> { ) -> Vec<C> {
let window_bbox = self.bbox(); // let window_bbox = self.bbox();
match self { match self {
WindowElement::Wayland(window) => { WindowElement::Wayland(window) => {
AsRenderElements::<R>::render_elements::<WaylandSurfaceRenderElement<R>>( AsRenderElements::<R>::render_elements::<WaylandSurfaceRenderElement<R>>(

View file

@ -47,7 +47,7 @@ use smithay::{
Display, DisplayHandle, Display, DisplayHandle,
}, },
}, },
utils::{Clock, IsAlive, Logical, Monotonic, Point, Size}, utils::{Clock, Logical, Monotonic, Point, Size},
wayland::{ wayland::{
compositor::{self, CompositorClientState, CompositorState}, compositor::{self, CompositorClientState, CompositorState},
data_device::DataDeviceState, data_device::DataDeviceState,
@ -159,7 +159,13 @@ impl<B: Backend> State<B> {
.space .space
.element_location(&window) .element_location(&window)
.unwrap_or((0, 0).into()); .unwrap_or((0, 0).into());
let window_size = window.geometry().size; let mut window_size = window.geometry().size;
if let Some(width) = width {
window_size.w = width;
}
if let Some(height) = height {
window_size.h = height;
}
window.request_size_change(self, window_loc, window_size); window.request_size_change(self, window_loc, window_size);
} }
Msg::MoveWindowToTag { window_id, tag_id } => { Msg::MoveWindowToTag { window_id, tag_id } => {

View file

@ -206,7 +206,9 @@ impl WindowElement {
// state.resize_state = WindowResizeState::Acknowledged(new_loc); // state.resize_state = WindowResizeState::Acknowledged(new_loc);
// }); // });
if !surface.is_override_redirect() { if !surface.is_override_redirect() {
surface.set_mapped(true).unwrap(); surface
.set_mapped(true)
.expect("failed to set x11 win to mapped");
} }
state.space.map_element(self.clone(), new_loc, false); state.space.map_element(self.clone(), new_loc, false);
// if let Some(focused_output) = state.focus_state.focused_output.clone() { // if let Some(focused_output) = state.focus_state.focused_output.clone() {
@ -500,7 +502,12 @@ pub fn toggle_floating<B: Backend>(state: &mut State<B>, window: &WindowElement)
window_state.floating = Float::Tiled(Some(( window_state.floating = Float::Tiled(Some((
// We get the location this way because window.geometry().loc // We get the location this way because window.geometry().loc
// doesn't seem to be the actual location // doesn't seem to be the actual location
state.space.element_location(window).unwrap(),
// TODO: remove the expect, maybe store the location in state
state
.space
.element_location(window)
.expect("toggled float on an unmapped floating window"),
window.geometry().size, window.geometry().size,
))); )));
@ -520,7 +527,12 @@ pub fn toggle_floating<B: Backend>(state: &mut State<B>, window: &WindowElement)
window.request_size_change(state, prev_loc, prev_size); window.request_size_change(state, prev_loc, prev_size);
} }
let output = state.focus_state.focused_output.clone().unwrap(); // TODO: don't use the focused output, use the one the window is on
let output = state
.focus_state
.focused_output
.clone()
.expect("no focused output");
state.re_layout(&output); state.re_layout(&output);
let render = output.with_state(|op_state| { let render = output.with_state(|op_state| {

View file

@ -1,3 +0,0 @@
// SPDX-License-Identifier: GPL-3.0-or-later
pub mod request;

View file

@ -1,167 +0,0 @@
// SPDX-License-Identifier: GPL-3.0-or-later
use smithay::{
desktop::space::SpaceElement,
input::{pointer::Focus, Seat},
reexports::{
wayland_protocols::xdg::shell::server::xdg_toplevel,
wayland_server::protocol::wl_surface::WlSurface,
},
utils::Rectangle,
wayland::shell::xdg::ToplevelSurface,
};
use crate::{
backend::Backend,
grab::{
move_grab::MoveSurfaceGrab,
resize_grab::{ResizeEdge, ResizeSurfaceGrab},
},
state::{State, WithState},
window::WindowElement,
};
pub fn move_request<B: Backend>(
state: &mut State<B>,
surface: &ToplevelSurface,
seat: &Seat<State<B>>,
serial: smithay::utils::Serial,
) {
let wl_surface = surface.wl_surface();
let pointer = seat.get_pointer().unwrap();
if let Some(start_data) = crate::pointer::pointer_grab_start_data(&pointer, wl_surface, serial)
{
let window = state.window_for_surface(wl_surface).unwrap();
let initial_window_loc = state.space.element_location(&window).unwrap();
let grab = MoveSurfaceGrab {
start_data,
window,
initial_window_loc,
};
pointer.set_grab(state, grab, serial, Focus::Clear);
} else {
tracing::warn!("no grab start data");
}
}
// TODO: see how this interacts with drag and drop and other grabs
pub fn move_request_force<B: Backend>(
state: &mut State<B>,
surface: &WlSurface,
seat: &Seat<State<B>>,
serial: smithay::utils::Serial,
) {
let pointer = seat.get_pointer().unwrap();
let window = state.window_for_surface(surface).unwrap();
let initial_window_loc = state.space.element_location(&window).unwrap();
let start_data = smithay::input::pointer::GrabStartData {
focus: pointer
.current_focus()
.map(|focus| (focus, initial_window_loc)),
button: 0x110,
location: pointer.current_location(),
};
let grab = MoveSurfaceGrab {
start_data,
window,
initial_window_loc,
};
pointer.set_grab(state, grab, serial, Focus::Clear);
}
pub fn resize_request<B: Backend>(
state: &mut State<B>,
surface: &WlSurface,
seat: &Seat<State<B>>,
serial: smithay::utils::Serial,
edges: xdg_toplevel::ResizeEdge,
button_used: u32,
) {
let pointer = seat.get_pointer().unwrap();
if let Some(start_data) = crate::pointer::pointer_grab_start_data(&pointer, surface, serial) {
let window = state.window_for_surface(surface).unwrap();
if window.with_state(|state| state.floating.is_tiled()) {
return;
}
let initial_window_loc = state.space.element_location(&window).unwrap();
let initial_window_size = window.geometry().size;
if let Some(WindowElement::Wayland(window)) = state.window_for_surface(surface) {
window.toplevel().with_pending_state(|state| {
state.states.set(xdg_toplevel::State::Resizing);
});
window.toplevel().send_pending_configure();
}
let grab = ResizeSurfaceGrab::start(
start_data,
window,
ResizeEdge(edges),
Rectangle::from_loc_and_size(initial_window_loc, initial_window_size),
button_used,
);
if let Some(grab) = grab {
pointer.set_grab(state, grab, serial, Focus::Clear);
}
}
}
pub fn resize_request_force<B: Backend>(
state: &mut State<B>,
surface: &WlSurface,
seat: &Seat<State<B>>,
serial: smithay::utils::Serial,
edges: xdg_toplevel::ResizeEdge,
button_used: u32,
) {
let pointer = seat.get_pointer().unwrap();
let window = state.window_for_surface(surface).unwrap();
if window.with_state(|state| state.floating.is_tiled()) {
return;
}
let initial_window_loc = state.space.element_location(&window).unwrap();
let initial_window_size = window.geometry().size;
if let Some(WindowElement::Wayland(window)) = state.window_for_surface(surface) {
window.toplevel().with_pending_state(|state| {
state.states.set(xdg_toplevel::State::Resizing);
});
window.toplevel().send_pending_configure();
}
let start_data = smithay::input::pointer::GrabStartData {
focus: pointer
.current_focus()
.map(|focus| (focus, initial_window_loc)),
button: button_used,
location: pointer.current_location(),
};
let grab = ResizeSurfaceGrab::start(
start_data,
window,
ResizeEdge(edges),
Rectangle::from_loc_and_size(initial_window_loc, initial_window_size),
button_used,
);
if let Some(grab) = grab {
pointer.set_grab(state, grab, serial, Focus::Clear);
}
}