aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIvan Molodetskikh <yalterz@gmail.com>2023-12-20 09:18:32 +0400
committerIvan Molodetskikh <yalterz@gmail.com>2023-12-20 09:18:32 +0400
commit9ac925ea0cece76e59e0b35147eb98d85754773f (patch)
tree26342652f262e1dc886907f7601d955012f4de08
parent0f83eacb4208c301e9f402d5ccd7ae474b51d24e (diff)
downloadniri-9ac925ea0cece76e59e0b35147eb98d85754773f.tar.gz
niri-9ac925ea0cece76e59e0b35147eb98d85754773f.tar.bz2
niri-9ac925ea0cece76e59e0b35147eb98d85754773f.zip
Try unconstraining popups with padding first
-rw-r--r--src/handlers/xdg_shell.rs48
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)
+}