linux: Fix IME positioning on scaled display on Wayland (#37600)
Removes IME bounds scaling on Wayland since it uses logical pixels, unlike X11. We now scale only on X11. Windows and macOS don’t use these bounds for IME anyway. Release Notes: - Fixed an issue where the IME popover could appear outside the window or fail to show on Wayland.
This commit is contained in:
@@ -39,9 +39,9 @@ use crate::{
|
||||
Action, AnyWindowHandle, App, AsyncWindowContext, BackgroundExecutor, Bounds,
|
||||
DEFAULT_WINDOW_SIZE, DevicePixels, DispatchEventResult, Font, FontId, FontMetrics, FontRun,
|
||||
ForegroundExecutor, GlyphId, GpuSpecs, ImageSource, Keymap, LineLayout, Pixels, PlatformInput,
|
||||
Point, RenderGlyphParams, RenderImage, RenderImageParams, RenderSvgParams, ScaledPixels, Scene,
|
||||
ShapedGlyph, ShapedRun, SharedString, Size, SvgRenderer, SvgSize, SystemWindowTab, Task,
|
||||
TaskLabel, Window, WindowControlArea, hash, point, px, size,
|
||||
Point, RenderGlyphParams, RenderImage, RenderImageParams, RenderSvgParams, Scene, ShapedGlyph,
|
||||
ShapedRun, SharedString, Size, SvgRenderer, SvgSize, SystemWindowTab, Task, TaskLabel, Window,
|
||||
WindowControlArea, hash, point, px, size,
|
||||
};
|
||||
use anyhow::Result;
|
||||
use async_task::Runnable;
|
||||
@@ -548,7 +548,7 @@ pub(crate) trait PlatformWindow: HasWindowHandle + HasDisplayHandle {
|
||||
fn set_client_inset(&self, _inset: Pixels) {}
|
||||
fn gpu_specs(&self) -> Option<GpuSpecs>;
|
||||
|
||||
fn update_ime_position(&self, _bounds: Bounds<ScaledPixels>);
|
||||
fn update_ime_position(&self, _bounds: Bounds<Pixels>);
|
||||
|
||||
#[cfg(any(test, feature = "test-support"))]
|
||||
fn as_test(&mut self) -> Option<&mut TestWindow> {
|
||||
|
||||
@@ -75,8 +75,8 @@ use crate::{
|
||||
FileDropEvent, ForegroundExecutor, KeyDownEvent, KeyUpEvent, Keystroke, LinuxCommon,
|
||||
LinuxKeyboardLayout, Modifiers, ModifiersChangedEvent, MouseButton, MouseDownEvent,
|
||||
MouseExitEvent, MouseMoveEvent, MouseUpEvent, NavigationDirection, Pixels, PlatformDisplay,
|
||||
PlatformInput, PlatformKeyboardLayout, Point, SCROLL_LINES, ScaledPixels, ScrollDelta,
|
||||
ScrollWheelEvent, Size, TouchPhase, WindowParams, point, px, size,
|
||||
PlatformInput, PlatformKeyboardLayout, Point, SCROLL_LINES, ScrollDelta, ScrollWheelEvent,
|
||||
Size, TouchPhase, WindowParams, point, px, size,
|
||||
};
|
||||
use crate::{
|
||||
SharedString,
|
||||
@@ -323,7 +323,7 @@ impl WaylandClientStatePtr {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn update_ime_position(&self, bounds: Bounds<ScaledPixels>) {
|
||||
pub fn update_ime_position(&self, bounds: Bounds<Pixels>) {
|
||||
let client = self.get_client();
|
||||
let mut state = client.borrow_mut();
|
||||
if state.composing || state.text_input.is_none() || state.pre_edit_text.is_some() {
|
||||
|
||||
@@ -25,9 +25,8 @@ use crate::scene::Scene;
|
||||
use crate::{
|
||||
AnyWindowHandle, Bounds, Decorations, Globals, GpuSpecs, Modifiers, Output, Pixels,
|
||||
PlatformDisplay, PlatformInput, Point, PromptButton, PromptLevel, RequestFrameOptions,
|
||||
ResizeEdge, ScaledPixels, Size, Tiling, WaylandClientStatePtr, WindowAppearance,
|
||||
WindowBackgroundAppearance, WindowBounds, WindowControlArea, WindowControls, WindowDecorations,
|
||||
WindowParams, px, size,
|
||||
ResizeEdge, Size, Tiling, WaylandClientStatePtr, WindowAppearance, WindowBackgroundAppearance,
|
||||
WindowBounds, WindowControlArea, WindowControls, WindowDecorations, WindowParams, px, size,
|
||||
};
|
||||
use crate::{
|
||||
Capslock,
|
||||
@@ -1078,7 +1077,7 @@ impl PlatformWindow for WaylandWindow {
|
||||
}
|
||||
}
|
||||
|
||||
fn update_ime_position(&self, bounds: Bounds<ScaledPixels>) {
|
||||
fn update_ime_position(&self, bounds: Bounds<Pixels>) {
|
||||
let state = self.borrow();
|
||||
state.client.update_ime_position(bounds);
|
||||
}
|
||||
|
||||
@@ -62,8 +62,7 @@ use crate::{
|
||||
AnyWindowHandle, Bounds, ClipboardItem, CursorStyle, DisplayId, FileDropEvent, Keystroke,
|
||||
LinuxKeyboardLayout, Modifiers, ModifiersChangedEvent, MouseButton, Pixels, Platform,
|
||||
PlatformDisplay, PlatformInput, PlatformKeyboardLayout, Point, RequestFrameOptions,
|
||||
ScaledPixels, ScrollDelta, Size, TouchPhase, WindowParams, X11Window,
|
||||
modifiers_from_xinput_info, point, px,
|
||||
ScrollDelta, Size, TouchPhase, WindowParams, X11Window, modifiers_from_xinput_info, point, px,
|
||||
};
|
||||
|
||||
/// Value for DeviceId parameters which selects all devices.
|
||||
@@ -252,7 +251,7 @@ impl X11ClientStatePtr {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn update_ime_position(&self, bounds: Bounds<ScaledPixels>) {
|
||||
pub fn update_ime_position(&self, bounds: Bounds<Pixels>) {
|
||||
let Some(client) = self.get_client() else {
|
||||
return;
|
||||
};
|
||||
@@ -270,6 +269,7 @@ impl X11ClientStatePtr {
|
||||
state.ximc = Some(ximc);
|
||||
return;
|
||||
};
|
||||
let scaled_bounds = bounds.scale(state.scale_factor);
|
||||
let ic_attributes = ximc
|
||||
.build_ic_attributes()
|
||||
.push(
|
||||
@@ -282,8 +282,8 @@ impl X11ClientStatePtr {
|
||||
b.push(
|
||||
xim::AttributeName::SpotLocation,
|
||||
xim::Point {
|
||||
x: u32::from(bounds.origin.x + bounds.size.width) as i16,
|
||||
y: u32::from(bounds.origin.y + bounds.size.height) as i16,
|
||||
x: u32::from(scaled_bounds.origin.x + scaled_bounds.size.width) as i16,
|
||||
y: u32::from(scaled_bounds.origin.y + scaled_bounds.size.height) as i16,
|
||||
},
|
||||
);
|
||||
})
|
||||
@@ -703,14 +703,14 @@ impl X11Client {
|
||||
state.xim_handler = Some(xim_handler);
|
||||
return;
|
||||
};
|
||||
if let Some(area) = window.get_ime_area() {
|
||||
if let Some(scaled_area) = window.get_ime_area() {
|
||||
ic_attributes =
|
||||
ic_attributes.nested_list(xim::AttributeName::PreeditAttributes, |b| {
|
||||
b.push(
|
||||
xim::AttributeName::SpotLocation,
|
||||
xim::Point {
|
||||
x: u32::from(area.origin.x + area.size.width) as i16,
|
||||
y: u32::from(area.origin.y + area.size.height) as i16,
|
||||
x: u32::from(scaled_area.origin.x + scaled_area.size.width) as i16,
|
||||
y: u32::from(scaled_area.origin.y + scaled_area.size.height) as i16,
|
||||
},
|
||||
);
|
||||
});
|
||||
@@ -1351,7 +1351,7 @@ impl X11Client {
|
||||
drop(state);
|
||||
window.handle_ime_preedit(text);
|
||||
|
||||
if let Some(area) = window.get_ime_area() {
|
||||
if let Some(scaled_area) = window.get_ime_area() {
|
||||
let ic_attributes = ximc
|
||||
.build_ic_attributes()
|
||||
.push(
|
||||
@@ -1364,8 +1364,8 @@ impl X11Client {
|
||||
b.push(
|
||||
xim::AttributeName::SpotLocation,
|
||||
xim::Point {
|
||||
x: u32::from(area.origin.x + area.size.width) as i16,
|
||||
y: u32::from(area.origin.y + area.size.height) as i16,
|
||||
x: u32::from(scaled_area.origin.x + scaled_area.size.width) as i16,
|
||||
y: u32::from(scaled_area.origin.y + scaled_area.size.height) as i16,
|
||||
},
|
||||
);
|
||||
})
|
||||
|
||||
@@ -1019,8 +1019,9 @@ impl X11WindowStatePtr {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_ime_area(&self) -> Option<Bounds<Pixels>> {
|
||||
pub fn get_ime_area(&self) -> Option<Bounds<ScaledPixels>> {
|
||||
let mut state = self.state.borrow_mut();
|
||||
let scale_factor = state.scale_factor;
|
||||
let mut bounds: Option<Bounds<Pixels>> = None;
|
||||
if let Some(mut input_handler) = state.input_handler.take() {
|
||||
drop(state);
|
||||
@@ -1030,7 +1031,7 @@ impl X11WindowStatePtr {
|
||||
let mut state = self.state.borrow_mut();
|
||||
state.input_handler = Some(input_handler);
|
||||
};
|
||||
bounds
|
||||
bounds.map(|b| b.scale(scale_factor))
|
||||
}
|
||||
|
||||
pub fn set_bounds(&self, bounds: Bounds<i32>) -> anyhow::Result<()> {
|
||||
@@ -1618,7 +1619,7 @@ impl PlatformWindow for X11Window {
|
||||
}
|
||||
}
|
||||
|
||||
fn update_ime_position(&self, bounds: Bounds<ScaledPixels>) {
|
||||
fn update_ime_position(&self, bounds: Bounds<Pixels>) {
|
||||
let mut state = self.0.state.borrow_mut();
|
||||
let client = state.client.clone();
|
||||
drop(state);
|
||||
|
||||
@@ -4,10 +4,9 @@ use crate::{
|
||||
ForegroundExecutor, KeyDownEvent, Keystroke, Modifiers, ModifiersChangedEvent, MouseButton,
|
||||
MouseDownEvent, MouseMoveEvent, MouseUpEvent, Pixels, PlatformAtlas, PlatformDisplay,
|
||||
PlatformInput, PlatformWindow, Point, PromptButton, PromptLevel, RequestFrameOptions,
|
||||
ScaledPixels, SharedString, Size, SystemWindowTab, Timer, WindowAppearance,
|
||||
WindowBackgroundAppearance, WindowBounds, WindowControlArea, WindowKind, WindowParams,
|
||||
dispatch_get_main_queue, dispatch_sys::dispatch_async_f, platform::PlatformInputHandler, point,
|
||||
px, size,
|
||||
SharedString, Size, SystemWindowTab, Timer, WindowAppearance, WindowBackgroundAppearance,
|
||||
WindowBounds, WindowControlArea, WindowKind, WindowParams, dispatch_get_main_queue,
|
||||
dispatch_sys::dispatch_async_f, platform::PlatformInputHandler, point, px, size,
|
||||
};
|
||||
use block::ConcreteBlock;
|
||||
use cocoa::{
|
||||
@@ -1480,7 +1479,7 @@ impl PlatformWindow for MacWindow {
|
||||
None
|
||||
}
|
||||
|
||||
fn update_ime_position(&self, _bounds: Bounds<ScaledPixels>) {
|
||||
fn update_ime_position(&self, _bounds: Bounds<Pixels>) {
|
||||
let executor = self.0.lock().executor.clone();
|
||||
executor
|
||||
.spawn(async move {
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
use crate::{
|
||||
AnyWindowHandle, AtlasKey, AtlasTextureId, AtlasTile, Bounds, DispatchEventResult, GpuSpecs,
|
||||
Pixels, PlatformAtlas, PlatformDisplay, PlatformInput, PlatformInputHandler, PlatformWindow,
|
||||
Point, PromptButton, RequestFrameOptions, ScaledPixels, Size, TestPlatform, TileId,
|
||||
WindowAppearance, WindowBackgroundAppearance, WindowBounds, WindowControlArea, WindowParams,
|
||||
Point, PromptButton, RequestFrameOptions, Size, TestPlatform, TileId, WindowAppearance,
|
||||
WindowBackgroundAppearance, WindowBounds, WindowControlArea, WindowParams,
|
||||
};
|
||||
use collections::HashMap;
|
||||
use parking_lot::Mutex;
|
||||
@@ -289,7 +289,7 @@ impl PlatformWindow for TestWindow {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn update_ime_position(&self, _bounds: Bounds<ScaledPixels>) {}
|
||||
fn update_ime_position(&self, _bounds: Bounds<Pixels>) {}
|
||||
|
||||
fn gpu_specs(&self) -> Option<GpuSpecs> {
|
||||
None
|
||||
|
||||
@@ -839,7 +839,7 @@ impl PlatformWindow for WindowsWindow {
|
||||
self.0.state.borrow().renderer.gpu_specs().log_err()
|
||||
}
|
||||
|
||||
fn update_ime_position(&self, _bounds: Bounds<ScaledPixels>) {
|
||||
fn update_ime_position(&self, _bounds: Bounds<Pixels>) {
|
||||
// There is no such thing on Windows.
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4096,9 +4096,7 @@ impl Window {
|
||||
self.on_next_frame(|window, cx| {
|
||||
if let Some(mut input_handler) = window.platform_window.take_input_handler() {
|
||||
if let Some(bounds) = input_handler.selected_bounds(window, cx) {
|
||||
window
|
||||
.platform_window
|
||||
.update_ime_position(bounds.scale(window.scale_factor()));
|
||||
window.platform_window.update_ime_position(bounds);
|
||||
}
|
||||
window.platform_window.set_input_handler(input_handler);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user