Skip to content

Commit f781e13

Browse files
authored
X11: Use bottom-right corner of IME cursor area as caret position
XIM servers currently do not support preedit area reporting from clients and there may be no standard way to report it. Fcitx and iBus both place the candidate window descending descending from the caret, with the reported X font; but since winit does not report a font, the height of the line is assumed 0, so when we report the top left corner of the cursor area they will tend to obscure it. Taking this into account, the best default option is to report the bottom right corner of the cursor area, because it will tend not to obscure the preedit area when using `Window::set_ime_cursor_area` in the way suggested by documentation.
1 parent 9f8ac8f commit f781e13

File tree

3 files changed

+14
-5
lines changed

3 files changed

+14
-5
lines changed

src/changelog/unreleased.md

+1
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,7 @@ changelog entry.
157157
identify a finger in a multi-touch interaction. Replaces the old `Touch::id`.
158158
- In the same spirit rename `DeviceEvent::MouseMotion` to `PointerMotion`.
159159
- Remove `Force::Calibrated::altitude_angle`.
160+
- On X11, use bottom-right corner for IME hotspot in `Window::set_ime_cursor_area`.
160161

161162
### Removed
162163

src/platform_impl/linux/x11/window.rs

+11-4
Original file line numberDiff line numberDiff line change
@@ -2031,12 +2031,19 @@ impl UnownedWindow {
20312031
}
20322032

20332033
#[inline]
2034-
pub fn set_ime_cursor_area(&self, spot: Position, _size: Size) {
2035-
let (x, y) = spot.to_physical::<i32>(self.scale_factor()).into();
2034+
pub fn set_ime_cursor_area(&self, spot: Position, size: Size) {
2035+
let PhysicalPosition { x, y } = spot.to_physical::<i16>(self.scale_factor());
2036+
let PhysicalSize { width, height } = size.to_physical::<i16>(self.scale_factor());
2037+
// We only currently support reporting a caret position via XIM.
2038+
// No IM servers currently process preedit area information from XIM clients
2039+
// and it is unclear this is even part of the standard protocol.
2040+
// Fcitx and iBus both assume that the position reported is at the insertion
2041+
// caret, and by default will place the candidate window under and to the
2042+
// right of the reported point.
20362043
let _ = self.ime_sender.lock().unwrap().send(ImeRequest::Position(
20372044
self.xwindow as ffi::Window,
2038-
x,
2039-
y,
2045+
x.saturating_add(width),
2046+
y.saturating_add(height),
20402047
));
20412048
}
20422049

src/window.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1005,7 +1005,8 @@ pub trait Window: AsAny + Send + Sync {
10051005
///
10061006
/// ## Platform-specific
10071007
///
1008-
/// - **X11:** - area is not supported, only position.
1008+
/// - **X11:** Area is not supported, only position. The bottom-right corner of the provided
1009+
/// area is reported as the position.
10091010
/// - **iOS / Android / Web / Orbital:** Unsupported.
10101011
///
10111012
/// [chinese]: https://support.apple.com/guide/chinese-input-method/use-the-candidate-window-cim12992/104/mac/12.0

0 commit comments

Comments
 (0)