refactor: change PopupSurface args to PopupKind of position_popup_within_rect() paths

- to support InputMethod popup kind in later commit
This commit is contained in:
KENZ 2026-04-24 06:31:35 +09:00 committed by Jacob Kauffmann
parent f62c88a3d9
commit 7a10fb1cc8
3 changed files with 45 additions and 33 deletions

View file

@ -40,7 +40,10 @@ impl WlrLayerShellHandler for State {
} }
fn new_popup(&mut self, _parent: WlrLayerSurface, popup: PopupSurface) { fn new_popup(&mut self, _parent: WlrLayerSurface, popup: PopupSurface) {
self.common.shell.read().unconstrain_popup(&popup); self.common
.shell
.read()
.unconstrain_popup(&PopupKind::from(popup.clone()));
if let Err(err) = popup.send_configure() { if let Err(err) = popup.send_configure() {
tracing::warn!("Unable to configure popup. {err:?}",); tracing::warn!("Unable to configure popup. {err:?}",);

View file

@ -65,7 +65,10 @@ impl XdgShellHandler for State {
if surface.get_parent_surface().is_some() { if surface.get_parent_surface().is_some() {
// let other shells deal with their popups // let other shells deal with their popups
self.common.shell.read().unconstrain_popup(&surface); self.common
.shell
.read()
.unconstrain_popup(&PopupKind::from(surface.clone()));
if let Err(err) = surface.send_configure() { if let Err(err) = surface.send_configure() {
warn!("Unable to configure popup. {err:?}",); warn!("Unable to configure popup. {err:?}",);
@ -165,7 +168,10 @@ impl XdgShellHandler for State {
state.positioner = positioner; state.positioner = positioner;
}); });
self.common.shell.read().unconstrain_popup(&surface); self.common
.shell
.read()
.unconstrain_popup(&PopupKind::from(surface.clone()));
surface.send_repositioned(token); surface.send_repositioned(token);
} }

View file

@ -15,16 +15,14 @@ use smithay::{
wayland::{ wayland::{
compositor::{get_role, with_states}, compositor::{get_role, with_states},
seat::WaylandFocus, seat::WaylandFocus,
shell::xdg::{ shell::xdg::{PopupCachedState, ToplevelSurface, XDG_POPUP_ROLE, XdgPopupSurfaceData},
PopupCachedState, PopupSurface, ToplevelSurface, XDG_POPUP_ROLE, XdgPopupSurfaceData,
},
}, },
}; };
use tracing::warn; use tracing::warn;
impl Shell { impl Shell {
pub fn unconstrain_popup(&self, surface: &PopupSurface) { pub fn unconstrain_popup(&self, surface: &PopupKind) {
if let Some(parent) = get_popup_toplevel(&PopupKind::from(surface.clone())) { if let Some(parent) = get_popup_toplevel(surface) {
if let Some(elem) = self.element_for_surface(&parent) { if let Some(elem) = self.element_for_surface(&parent) {
let (mut element_geo, output, is_tiled) = let (mut element_geo, output, is_tiled) =
if let Some(workspace) = self.space_for(elem) { if let Some(workspace) = self.space_for(elem) {
@ -110,7 +108,7 @@ pub fn update_reactive_popups<'a>(
.find(|geo| geo.contains(anchor_point)) .find(|geo| geo.contains(anchor_point))
.copied() .copied()
{ {
unconstrain_xdg_popup(&surface, loc, rect); unconstrain_xdg_popup(&PopupKind::from(surface.clone()), loc, rect);
if let Err(err) = surface.send_configure() { if let Err(err) = surface.send_configure() {
warn!( warn!(
?err, ?err,
@ -126,54 +124,59 @@ pub fn update_reactive_popups<'a>(
} }
// Attempt to constraint to tile, without resize. Return `true` if it fits. // Attempt to constraint to tile, without resize. Return `true` if it fits.
fn unconstrain_xdg_popup_tile(surface: &PopupSurface, mut rect: Rectangle<i32, Logical>) -> bool { fn unconstrain_xdg_popup_tile(surface: &PopupKind, mut rect: Rectangle<i32, Logical>) -> bool {
rect.loc -= get_popup_toplevel_coords(&PopupKind::Xdg(surface.clone())); rect.loc -= get_popup_toplevel_coords(surface);
position_popup_within_rect(surface, rect.as_global(), true) position_popup_within_rect(surface, rect.as_global(), true)
} }
fn unconstrain_xdg_popup( fn unconstrain_xdg_popup(
surface: &PopupSurface, surface: &PopupKind,
window_loc: Point<i32, Global>, window_loc: Point<i32, Global>,
mut rect: Rectangle<i32, Global>, mut rect: Rectangle<i32, Global>,
) { ) {
rect.loc -= window_loc; rect.loc -= window_loc;
rect.loc -= get_popup_toplevel_coords(&PopupKind::Xdg(surface.clone())).as_global(); rect.loc -= get_popup_toplevel_coords(surface).as_global();
position_popup_within_rect(surface, rect, false); position_popup_within_rect(surface, rect, false);
} }
fn unconstrain_layer_popup(surface: &PopupSurface, output: &Output, layer_surface: &LayerSurface) { fn unconstrain_layer_popup(surface: &PopupKind, output: &Output, layer_surface: &LayerSurface) {
let map = layer_map_for_output(output); let map = layer_map_for_output(output);
let layer_geo = map.layer_geometry(layer_surface).unwrap(); let layer_geo = map.layer_geometry(layer_surface).unwrap();
// the output_rect represented relative to the parents coordinate system // the output_rect represented relative to the parents coordinate system
let mut relative = Rectangle::from_size(output.geometry().size).as_logical(); let mut relative = Rectangle::from_size(output.geometry().size).as_logical();
relative.loc -= layer_geo.loc; relative.loc -= layer_geo.loc;
relative.loc -= get_popup_toplevel_coords(&PopupKind::Xdg(surface.clone())); relative.loc -= get_popup_toplevel_coords(surface);
position_popup_within_rect(surface, relative.as_global(), false); position_popup_within_rect(surface, relative.as_global(), false);
} }
fn position_popup_within_rect( fn position_popup_within_rect(
surface: &PopupSurface, surface: &PopupKind,
rect: Rectangle<i32, Global>, rect: Rectangle<i32, Global>,
is_tiled: bool, is_tiled: bool,
) -> bool { ) -> bool {
let rect = rect.as_logical(); match surface {
let geometry = surface.with_pending_state(|state| { PopupKind::Xdg(surface) => {
let positioner = if is_tiled { let rect = rect.as_logical();
let mut positioner_no_resize = state.positioner; let geometry = surface.with_pending_state(|state| {
positioner_no_resize let positioner = if is_tiled {
.constraint_adjustment let mut positioner_no_resize = state.positioner;
.remove(ConstraintAdjustment::ResizeX | ConstraintAdjustment::ResizeY); positioner_no_resize
positioner_no_resize .constraint_adjustment
} else { .remove(ConstraintAdjustment::ResizeX | ConstraintAdjustment::ResizeY);
state.positioner positioner_no_resize
}; } else {
positioner.get_unconstrained_geometry(rect) state.positioner
}); };
surface.with_pending_state(|state| { positioner.get_unconstrained_geometry(rect)
state.geometry = geometry; });
}); surface.with_pending_state(|state| {
rect.contains_rect(geometry) state.geometry = geometry;
});
rect.contains_rect(geometry)
}
PopupKind::InputMethod(_) => false,
}
} }
pub fn get_popup_toplevel(popup: &PopupKind) -> Option<WlSurface> { pub fn get_popup_toplevel(popup: &PopupKind) -> Option<WlSurface> {