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:
parent
7a10fb1cc8
commit
677be79635
3 changed files with 40 additions and 3 deletions
|
|
@ -281,6 +281,10 @@ impl CompositorHandler for State {
|
|||
|
||||
if let Some(popup) = self.common.popups.find_popup(surface) {
|
||||
xdg_popup_ensure_initial_configure(&popup);
|
||||
// The IME popup need to be repositioned when the size changed
|
||||
if let PopupKind::InputMethod(_) = popup {
|
||||
shell.unconstrain_popup(&popup);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -12,6 +12,11 @@ use tracing::warn;
|
|||
|
||||
impl InputMethodHandler for State {
|
||||
fn new_popup(&mut self, surface: PopupSurface) {
|
||||
self.common
|
||||
.shell
|
||||
.read()
|
||||
.unconstrain_popup(&PopupKind::from(surface.clone()));
|
||||
|
||||
if let Err(err) = self.common.popups.track_popup(PopupKind::from(surface)) {
|
||||
warn!("Failed to track popup: {}", err);
|
||||
}
|
||||
|
|
@ -32,7 +37,9 @@ impl InputMethodHandler for State {
|
|||
.unwrap_or_default()
|
||||
}
|
||||
|
||||
fn popup_repositioned(&mut self, _: PopupSurface) {}
|
||||
fn popup_repositioned(&mut self, popup: PopupSurface) {
|
||||
self.common.shell.read().unconstrain_popup(&popup.into());
|
||||
}
|
||||
}
|
||||
|
||||
delegate_input_method_manager!(State);
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue