aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIvan Molodetskikh <yalterz@gmail.com>2023-08-11 10:39:17 +0400
committerIvan Molodetskikh <yalterz@gmail.com>2023-08-11 10:39:17 +0400
commit91a809b755977f57c1c1fc0da09dfc1cd2483d87 (patch)
tree9d11a98451370a2564150ed6217138b15e37aafd
parentf9c7fe4112e91754d6866f105384eb12f27aa5eb (diff)
downloadniri-91a809b755977f57c1c1fc0da09dfc1cd2483d87.tar.gz
niri-91a809b755977f57c1c1fc0da09dfc1cd2483d87.tar.bz2
niri-91a809b755977f57c1c1fc0da09dfc1cd2483d87.zip
Add un/fullscreen support
-rw-r--r--src/handlers/xdg_shell.rs76
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();
}