Skip to content

Commit

Permalink
X11: Use bottom-right corner of IME cursor area as caret position
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
xorgy authored Nov 13, 2024
1 parent 9f8ac8f commit f781e13
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 5 deletions.
1 change: 1 addition & 0 deletions src/changelog/unreleased.md
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ changelog entry.
identify a finger in a multi-touch interaction. Replaces the old `Touch::id`.
- In the same spirit rename `DeviceEvent::MouseMotion` to `PointerMotion`.
- Remove `Force::Calibrated::altitude_angle`.
- On X11, use bottom-right corner for IME hotspot in `Window::set_ime_cursor_area`.

### Removed

Expand Down
15 changes: 11 additions & 4 deletions src/platform_impl/linux/x11/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2031,12 +2031,19 @@ impl UnownedWindow {
}

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

Expand Down
3 changes: 2 additions & 1 deletion src/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1005,7 +1005,8 @@ pub trait Window: AsAny + Send + Sync {
///
/// ## Platform-specific
///
/// - **X11:** - area is not supported, only position.
/// - **X11:** Area is not supported, only position. The bottom-right corner of the provided
/// area is reported as the position.
/// - **iOS / Android / Web / Orbital:** Unsupported.
///
/// [chinese]: https://support.apple.com/guide/chinese-input-method/use-the-candidate-window-cim12992/104/mac/12.0
Expand Down

0 comments on commit f781e13

Please sign in to comment.