Signal TextFieldFocused and ImeMoved to enable and position the IME. (#314)

This commit is contained in:
Aaron Muir Hamilton 2024-06-03 12:29:23 -04:00 committed by GitHub
parent 49d22aaeea
commit d2336d8b66
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 39 additions and 26 deletions

View File

@ -679,6 +679,14 @@ impl PaintCtx<'_> {
pub fn depth(&self) -> u32 {
self.depth
}
// signal may be useful elsewhere, but is currently only used on PaintCtx
/// Submit a [`RenderRootSignal`]
///
/// Note: May be removed in future, and replaced with more specific methods.
pub fn signal(&mut self, s: RenderRootSignal) {
self.global_state.signal_queue.push_back(s);
}
}
impl AccessCtx<'_> {

View File

@ -119,8 +119,6 @@ impl ApplicationHandler<accesskit_winit::Event> for MainState<'_> {
let adapter = Adapter::with_event_loop_proxy(&window, self.proxy.clone());
window.set_visible(visible);
// TODO: Use signals or some other mechanism to do fine grained ime enable
window.set_ime_allowed(true);
let window = Arc::new(window);
let size = window.inner_size();
let surface = pollster::block_on(self.render_cx.create_surface(
@ -428,23 +426,14 @@ impl MainState<'_> {
.on_action(&mut driver_ctx, widget_id, action);
});
}
render_root::RenderRootSignal::TextFieldAdded => {
// TODO
render_root::RenderRootSignal::StartIme => {
window.set_ime_allowed(true);
}
render_root::RenderRootSignal::TextFieldRemoved => {
// TODO
render_root::RenderRootSignal::EndIme => {
window.set_ime_allowed(false);
}
render_root::RenderRootSignal::TextFieldFocused => {
// TODO
}
render_root::RenderRootSignal::ImeStarted => {
// TODO
}
render_root::RenderRootSignal::ImeMoved => {
// TODO
}
render_root::RenderRootSignal::ImeInvalidated => {
// TODO
render_root::RenderRootSignal::ImeMoved(position, size) => {
window.set_ime_cursor_area(position, size);
}
render_root::RenderRootSignal::RequestRedraw => {
window.request_redraw();

View File

@ -71,12 +71,9 @@ pub enum WindowSizePolicy {
// TODO - Text fields
pub enum RenderRootSignal {
Action(Action, WidgetId),
TextFieldAdded,
TextFieldRemoved,
TextFieldFocused,
ImeStarted,
ImeMoved,
ImeInvalidated,
StartIme,
EndIme,
ImeMoved(LogicalPosition<f64>, LogicalSize<f64>),
RequestRedraw,
RequestAnimFrame,
SpawnWorker(WorkerFn),
@ -584,8 +581,12 @@ impl RenderRoot {
self.state.focused_widget = new;
self.root_lifecycle(event);
// TODO - Handle IME
// Send TextFieldFocused(focused_widget) signal
// TODO: discriminate between text focus, and non-text focus.
self.state.signal_queue.push_back(if new.is_some() {
RenderRootSignal::StartIme
} else {
RenderRootSignal::EndIme
});
}
}

View File

@ -13,6 +13,7 @@ use vello::{
peniko::{BlendMode, Color},
Scene,
};
use winit::dpi::{LogicalPosition, LogicalSize};
use crate::{
text2::{TextBrush, TextEditor, TextStorage, TextWithSelection},
@ -301,7 +302,8 @@ impl Widget for Textbox {
self.editor
.draw(scene, Point::new(TEXTBOX_PADDING, TEXTBOX_PADDING));
let outline_rect = ctx.size().to_rect().inset(1.0);
let size = ctx.size();
let outline_rect = size.to_rect().inset(1.0);
scene.stroke(
&Stroke::new(1.0),
Affine::IDENTITY,
@ -312,6 +314,19 @@ impl Widget for Textbox {
if self.line_break_mode == LineBreaking::Clip {
scene.pop_layer();
}
let origin = ctx.widget_state.window_origin();
if ctx.widget_state.has_focus {
ctx.signal(crate::render_root::RenderRootSignal::ImeMoved(
LogicalPosition {
x: origin.x,
y: origin.y + size.height,
},
LogicalSize {
width: size.width,
height: size.height,
},
));
}
}
fn accessibility_role(&self) -> Role {