smithay_client_toolkit/shell/xdg/window/
mod.rs1use std::{
4 num::NonZeroU32,
5 sync::{Arc, Weak},
6};
7
8use crate::reexports::client::{
9 protocol::{wl_output, wl_seat, wl_surface},
10 Connection, Proxy, QueueHandle,
11};
12use crate::reexports::csd_frame::{WindowManagerCapabilities, WindowState};
13use crate::reexports::protocols::{
14 xdg::decoration::zv1::client::zxdg_toplevel_decoration_v1::{self, Mode},
15 xdg::shell::client::{xdg_surface, xdg_toplevel},
16};
17
18use crate::shell::WaylandSurface;
19
20use self::inner::WindowInner;
21
22use super::XdgSurface;
23
24pub(super) mod inner;
25
26pub trait WindowHandler: Sized {
28 fn request_close(&mut self, conn: &Connection, qh: &QueueHandle<Self>, window: &Window);
33
34 fn configure(
47 &mut self,
48 conn: &Connection,
49 qh: &QueueHandle<Self>,
50 window: &Window,
51 configure: WindowConfigure,
52 serial: u32,
53 );
54}
55
56#[derive(Debug, Clone, Copy, PartialEq, Eq)]
58pub enum DecorationMode {
59 Client,
61
62 Server,
64}
65
66#[non_exhaustive]
70#[derive(Debug, Clone)]
71pub struct WindowConfigure {
72 pub new_size: (Option<NonZeroU32>, Option<NonZeroU32>),
76
77 pub suggested_bounds: Option<(u32, u32)>,
83
84 pub decoration_mode: DecorationMode,
89
90 pub state: WindowState,
94
95 pub capabilities: WindowManagerCapabilities,
99}
100
101impl Default for WindowConfigure {
102 fn default() -> Self {
103 Self {
104 new_size: (None, None),
105 suggested_bounds: None,
106 decoration_mode: DecorationMode::Client,
108 state: WindowState::empty(),
109 capabilities: WindowManagerCapabilities::all(),
111 }
112 }
113}
114
115impl WindowConfigure {
116 #[inline]
118 pub fn is_maximized(&self) -> bool {
119 self.state.contains(WindowState::MAXIMIZED)
120 }
121
122 #[inline]
124 pub fn is_fullscreen(&self) -> bool {
125 self.state.contains(WindowState::FULLSCREEN)
126 }
127
128 #[inline]
130 pub fn is_resizing(&self) -> bool {
131 self.state.contains(WindowState::RESIZING)
132 }
133
134 #[inline]
136 pub fn is_tiled(&self) -> bool {
137 self.state.contains(WindowState::TILED)
138 }
139
140 #[inline]
142 pub fn is_activated(&self) -> bool {
143 self.state.contains(WindowState::ACTIVATED)
144 }
145
146 #[inline]
148 pub fn is_tiled_left(&self) -> bool {
149 self.state.contains(WindowState::TILED_LEFT)
150 }
151
152 #[inline]
154 pub fn is_tiled_right(&self) -> bool {
155 self.state.contains(WindowState::TILED_RIGHT)
156 }
157
158 #[inline]
160 pub fn is_tiled_top(&self) -> bool {
161 self.state.contains(WindowState::TILED_TOP)
162 }
163
164 #[inline]
166 pub fn is_tiled_bottom(&self) -> bool {
167 self.state.contains(WindowState::TILED_BOTTOM)
168 }
169}
170
171#[derive(Debug, Clone, Copy, PartialEq, Eq)]
173pub enum WindowDecorations {
174 ServerDefault,
179
180 RequestServer,
185
186 RequestClient,
191
192 ClientOnly,
194
195 None,
197}
198
199#[derive(Debug, Clone)]
200pub struct Window(pub(super) Arc<WindowInner>);
201
202impl Window {
203 pub fn from_xdg_toplevel(toplevel: &xdg_toplevel::XdgToplevel) -> Option<Window> {
204 toplevel.data::<WindowData>().and_then(|data| data.0.upgrade()).map(Window)
205 }
206
207 pub fn from_xdg_surface(surface: &xdg_surface::XdgSurface) -> Option<Window> {
208 surface.data::<WindowData>().and_then(|data| data.0.upgrade()).map(Window)
209 }
210
211 pub fn from_toplevel_decoration(
212 decoration: &zxdg_toplevel_decoration_v1::ZxdgToplevelDecorationV1,
213 ) -> Option<Window> {
214 decoration.data::<WindowData>().and_then(|data| data.0.upgrade()).map(Window)
215 }
216
217 pub fn show_window_menu(&self, seat: &wl_seat::WlSeat, serial: u32, position: (i32, i32)) {
218 self.xdg_toplevel().show_window_menu(seat, serial, position.0, position.1);
219 }
220
221 pub fn set_title(&self, title: impl Into<String>) {
222 self.xdg_toplevel().set_title(title.into());
223 }
224
225 pub fn set_app_id(&self, app_id: impl Into<String>) {
226 self.xdg_toplevel().set_app_id(app_id.into());
227 }
228
229 pub fn set_parent(&self, parent: Option<&Window>) {
230 self.xdg_toplevel().set_parent(parent.map(Window::xdg_toplevel));
231 }
232
233 pub fn set_maximized(&self) {
234 self.xdg_toplevel().set_maximized()
235 }
236
237 pub fn unset_maximized(&self) {
238 self.xdg_toplevel().unset_maximized()
239 }
240
241 pub fn set_minimized(&self) {
242 self.xdg_toplevel().set_minimized()
243 }
244
245 pub fn set_fullscreen(&self, output: Option<&wl_output::WlOutput>) {
246 self.xdg_toplevel().set_fullscreen(output)
247 }
248
249 pub fn unset_fullscreen(&self) {
250 self.xdg_toplevel().unset_fullscreen()
251 }
252
253 pub fn request_decoration_mode(&self, mode: Option<DecorationMode>) {
264 if let Some(toplevel_decoration) = &self.0.toplevel_decoration {
265 match mode {
266 Some(DecorationMode::Client) => toplevel_decoration.set_mode(Mode::ClientSide),
267 Some(DecorationMode::Server) => toplevel_decoration.set_mode(Mode::ServerSide),
268 None => toplevel_decoration.unset_mode(),
269 }
270 }
271 }
272
273 pub fn move_(&self, seat: &wl_seat::WlSeat, serial: u32) {
274 self.xdg_toplevel()._move(seat, serial)
275 }
276
277 pub fn resize(&self, seat: &wl_seat::WlSeat, serial: u32, edges: xdg_toplevel::ResizeEdge) {
278 self.xdg_toplevel().resize(seat, serial, edges)
279 }
280
281 pub fn set_min_size(&self, min_size: Option<(u32, u32)>) {
284 let min_size = min_size.unwrap_or_default();
285 self.xdg_toplevel().set_min_size(min_size.0 as i32, min_size.1 as i32);
286 }
287
288 pub fn set_max_size(&self, max_size: Option<(u32, u32)>) {
292 let max_size = max_size.unwrap_or_default();
293 self.xdg_toplevel().set_max_size(max_size.0 as i32, max_size.1 as i32);
294 }
295
296 pub fn xdg_toplevel(&self) -> &xdg_toplevel::XdgToplevel {
300 &self.0.xdg_toplevel
301 }
302}
303
304impl WaylandSurface for Window {
305 fn wl_surface(&self) -> &wl_surface::WlSurface {
306 self.0.xdg_surface.wl_surface()
307 }
308}
309
310impl XdgSurface for Window {
311 fn xdg_surface(&self) -> &xdg_surface::XdgSurface {
312 self.0.xdg_surface.xdg_surface()
313 }
314}
315
316impl PartialEq for Window {
317 fn eq(&self, other: &Self) -> bool {
318 Arc::ptr_eq(&self.0, &other.0)
319 }
320}
321
322#[derive(Debug, Clone)]
323pub struct WindowData(pub(crate) Weak<WindowInner>);