diff options
| author | Ivan Molodetskikh <yalterz@gmail.com> | 2023-08-11 10:39:17 +0400 |
|---|---|---|
| committer | Ivan Molodetskikh <yalterz@gmail.com> | 2023-08-11 10:39:17 +0400 |
| commit | 91a809b755977f57c1c1fc0da09dfc1cd2483d87 (patch) | |
| tree | 9d11a98451370a2564150ed6217138b15e37aafd | |
| parent | f9c7fe4112e91754d6866f105384eb12f27aa5eb (diff) | |
| download | niri-91a809b755977f57c1c1fc0da09dfc1cd2483d87.tar.gz niri-91a809b755977f57c1c1fc0da09dfc1cd2483d87.tar.bz2 niri-91a809b755977f57c1c1fc0da09dfc1cd2483d87.zip | |
Add un/fullscreen support
| -rw-r--r-- | src/handlers/xdg_shell.rs | 76 |
1 files changed, 75 insertions, 1 deletions
diff --git a/src/handlers/xdg_shell.rs b/src/handlers/xdg_shell.rs index 6a12d4e9..0e1ad760 100644 --- a/src/handlers/xdg_shell.rs +++ b/src/handlers/xdg_shell.rs @@ -2,12 +2,14 @@ use smithay::delegate_xdg_shell; use smithay::desktop::{PopupKind, Window}; use smithay::input::pointer::{Focus, GrabStartData as PointerGrabStartData}; use smithay::input::Seat; +use smithay::output::Output; use smithay::reexports::wayland_protocols::xdg::shell::server::xdg_toplevel; -use smithay::reexports::wayland_server::protocol::wl_seat; use smithay::reexports::wayland_server::protocol::wl_surface::WlSurface; +use smithay::reexports::wayland_server::protocol::{wl_output, wl_seat}; use smithay::reexports::wayland_server::Resource; use smithay::utils::{Rectangle, Serial}; use smithay::wayland::compositor::with_states; +use smithay::wayland::seat::WaylandFocus; use smithay::wayland::shell::xdg::{ PopupSurface, PositionerState, ToplevelSurface, XdgPopupSurfaceData, XdgShellHandler, XdgShellState, XdgToplevelSurfaceData, @@ -173,6 +175,78 @@ impl XdgShellHandler for Niri { surface.send_pending_configure(); } + fn fullscreen_request( + &mut self, + surface: ToplevelSurface, + wl_output: Option<wl_output::WlOutput>, + ) { + if surface + .current_state() + .capabilities + .contains(xdg_toplevel::WmCapabilities::Fullscreen) + { + // NOTE: This is only one part of the solution. We can set the + // location and configure size here, but the surface should be rendered fullscreen + // independently from its buffer size + let wl_surface = surface.wl_surface(); + + let output = wl_output + .as_ref() + .and_then(Output::from_resource) + .or_else(|| { + let w = self + .space + .elements() + .find(|window| { + window + .wl_surface() + .map(|s| s == *wl_surface) + .unwrap_or(false) + }) + .cloned(); + w.and_then(|w| self.space.outputs_for_element(&w).get(0).cloned()) + }); + + if let Some(output) = output { + let geometry = self.space.output_geometry(&output).unwrap(); + + surface.with_pending_state(|state| { + state.states.set(xdg_toplevel::State::Fullscreen); + state.size = Some(geometry.size); + }); + + let window = self + .space + .elements() + .find(|w| w.toplevel().wl_surface() == wl_surface) + .unwrap() + .clone(); + self.space.map_element(window, geometry.loc, true); + } + } + + // The protocol demands us to always reply with a configure, + // regardless of we fulfilled the request or not + surface.send_configure(); + } + + fn unfullscreen_request(&mut self, surface: ToplevelSurface) { + if !surface + .current_state() + .states + .contains(xdg_toplevel::State::Fullscreen) + { + return; + } + + surface.with_pending_state(|state| { + state.states.unset(xdg_toplevel::State::Fullscreen); + state.size = None; + }); + + surface.send_pending_configure(); + } + fn toplevel_destroyed(&mut self, _surface: ToplevelSurface) { self.queue_redraw(); } |
