diff options
| author | Ivan Molodetskikh <yalterz@gmail.com> | 2023-12-20 09:18:32 +0400 |
|---|---|---|
| committer | Ivan Molodetskikh <yalterz@gmail.com> | 2023-12-20 09:18:32 +0400 |
| commit | 9ac925ea0cece76e59e0b35147eb98d85754773f (patch) | |
| tree | 26342652f262e1dc886907f7601d955012f4de08 | |
| parent | 0f83eacb4208c301e9f402d5ccd7ae474b51d24e (diff) | |
| download | niri-9ac925ea0cece76e59e0b35147eb98d85754773f.tar.gz niri-9ac925ea0cece76e59e0b35147eb98d85754773f.tar.bz2 niri-9ac925ea0cece76e59e0b35147eb98d85754773f.zip | |
Try unconstraining popups with padding first
| -rw-r--r-- | src/handlers/xdg_shell.rs | 48 |
1 files changed, 45 insertions, 3 deletions
diff --git a/src/handlers/xdg_shell.rs b/src/handlers/xdg_shell.rs index 29bedb70..3a290796 100644 --- a/src/handlers/xdg_shell.rs +++ b/src/handlers/xdg_shell.rs @@ -4,11 +4,12 @@ use smithay::desktop::{ }; use smithay::output::Output; use smithay::reexports::wayland_protocols::xdg::decoration::zv1::server::zxdg_toplevel_decoration_v1; +use smithay::reexports::wayland_protocols::xdg::shell::server::xdg_positioner::ConstraintAdjustment; use smithay::reexports::wayland_protocols::xdg::shell::server::xdg_toplevel::{self, ResizeEdge}; use smithay::reexports::wayland_server::protocol::wl_output; use smithay::reexports::wayland_server::protocol::wl_seat::WlSeat; use smithay::reexports::wayland_server::protocol::wl_surface::WlSurface; -use smithay::utils::{Rectangle, Serial}; +use smithay::utils::{Logical, Rectangle, Serial}; use smithay::wayland::compositor::{send_surface_state, with_states}; use smithay::wayland::shell::kde::decoration::{KdeDecorationHandler, KdeDecorationState}; use smithay::wayland::shell::xdg::decoration::XdgDecorationHandler; @@ -329,7 +330,7 @@ impl State { target.loc -= get_popup_toplevel_coords(&PopupKind::Xdg(popup.clone())); popup.with_pending_state(|state| { - state.geometry = state.positioner.get_unconstrained_geometry(target); + state.geometry = unconstrain_with_padding(state.positioner, target); }); } @@ -352,7 +353,7 @@ impl State { target.loc -= get_popup_toplevel_coords(&PopupKind::Xdg(popup.clone())); popup.with_pending_state(|state| { - state.geometry = state.positioner.get_unconstrained_geometry(target); + state.geometry = unconstrain_with_padding(state.positioner, target); }); } @@ -374,3 +375,44 @@ impl State { } } } + +fn unconstrain_with_padding( + positioner: PositionerState, + target: Rectangle<i32, Logical>, +) -> Rectangle<i32, Logical> { + // Try unconstraining with a small padding first which looks nicer, then if it doesn't fit try + // unconstraining without padding. + const PADDING: i32 = 8; + + let mut padded = target; + if PADDING * 2 < padded.size.w { + padded.loc.x += PADDING; + padded.size.w -= PADDING * 2; + } + if PADDING * 2 < padded.size.h { + padded.loc.y += PADDING; + padded.size.h -= PADDING * 2; + } + + // No padding, so just unconstrain with the original target. + if padded == target { + return positioner.get_unconstrained_geometry(target); + } + + // Do not try to resize to fit the padded target rectangle. + let mut no_resize = positioner; + no_resize + .constraint_adjustment + .remove(ConstraintAdjustment::ResizeX); + no_resize + .constraint_adjustment + .remove(ConstraintAdjustment::ResizeY); + + let geo = no_resize.get_unconstrained_geometry(padded); + if padded.contains_rect(geo) { + return geo; + } + + // Could not unconstrain into the padded target, so resort to the regular one. + positioner.get_unconstrained_geometry(target) +} |
