Unconstrain the IME popup when it appeared, resized, requested to

repositioned

- places the IME popup correctly.
- adjusts its position to considering the output (screen) rect.
  - offset if right edge overflows
  - flip vertically if bottom edge overflows
This commit is contained in:
KENZ 2026-04-25 07:10:18 +09:00 committed by Jacob Kauffmann
parent 7a10fb1cc8
commit 677be79635
3 changed files with 40 additions and 3 deletions

View file

@ -4,7 +4,7 @@ use crate::{shell::Shell, utils::prelude::*};
use smithay::{
desktop::{
LayerSurface, PopupKind, PopupManager, WindowSurfaceType, get_popup_toplevel_coords,
layer_map_for_output, space::SpaceElement,
layer_map_for_output, space::SpaceElement, utils,
},
output::Output,
reexports::{
@ -175,7 +175,33 @@ fn position_popup_within_rect(
});
rect.contains_rect(geometry)
}
PopupKind::InputMethod(_) => false,
PopupKind::InputMethod(popup) => {
let input_rect = popup.text_input_rectangle();
// We basically place the IME popup below the input rect.
let mut popup_bbox = utils::bbox_from_surface_tree(popup.wl_surface(), input_rect.loc);
popup_bbox.loc.y += input_rect.size.h;
// tracing::debug!(
// "IME input_rect: {:?}, popup_bbox: {:?}",
// input_rect,
// popup_bbox
// );
// Handle the right edge overflow
let popup_right = popup_bbox.loc.x + popup_bbox.size.w;
let rect_right = rect.loc.x + rect.size.w;
popup_bbox.loc.x -= (popup_right - rect_right).max(0);
// Flip vertically if the bottom edge overflows
let popup_bottom = popup_bbox.loc.y + popup_bbox.size.h;
let rect_bottom = rect.loc.y + rect.size.h;
if popup_bottom > rect_bottom {
popup_bbox.loc.y = input_rect.loc.y - popup_bbox.size.h;
}
popup.set_location(popup_bbox.loc);
rect.as_logical().contains_rect(popup_bbox)
}
}
}