Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement Frame::allow_ime method #3313

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions crates/eframe/src/epi/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -455,6 +455,9 @@ pub struct NativeOptions {
/// }
/// ```
pub app_id: Option<String>,

/// Enable/disable IME at startup.
pub allow_ime: bool,
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please describe this a bit more.

If true, will an on-screen-keyboard usually be shown for touch-screens on start? Will it hide once the user stops editing text?

If false, will it still show up when you start editing text? Will it hide once you stop editing the text?

Copy link
Contributor Author

@Barugon Barugon Sep 6, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If true, will an on-screen-keyboard usually be shown for touch-screens on start? Will it hide once the user stops editing text?

The keyboard will be shown on startup (Phosh) and you have to manually hide it on.

If false, will it still show up when you start editing text? Will it hide once you stop editing the text?

It will not automatically show the keyboard when you enter a text edit. You have to manually show it.

Adding this to my code will automatically show/hide the keyboard on Phosh:

          let response = ui.text_edit_singleline(&mut self.text);
          if response.gained_focus() {
            frame.allow_ime(true);
          } else if response.lost_focus() {
            frame.allow_ime(false);
          }

I added allow_ime to NativeOptions in case someone wants to keep the previous behavior.

Copy link
Contributor Author

@Barugon Barugon Sep 14, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I may be that enabling and disabling IME shows and hides the keyboard for other OS/desktops but I really don't have a way to test that.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems to me the desirable behavior is to have one flag that controls wether or not the on-screen-keyboard shows on startup (with false being a reasonable default).

And then, regardless of that flag, always show the on-screen-keyboard when the user clicks a text field

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's my ultimate goal but egui is rather disconnected from the windowing system, so this was the best that I could come up with.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

egui is disconnected yes, but communicates the necessary information to the backend.
egui-winit already reads PlatformOutput::text_cursor_pos to check if the user is editing text

}

#[cfg(not(target_arch = "wasm32"))]
Expand Down Expand Up @@ -529,6 +532,7 @@ impl Default for NativeOptions {
wgpu_options: egui_wgpu::WgpuConfiguration::default(),

app_id: None,
allow_ime: false,
}
}
}
Expand Down Expand Up @@ -730,6 +734,9 @@ pub struct Frame {
/// Raw platform display handle for window
#[cfg(not(target_arch = "wasm32"))]
pub(crate) raw_display_handle: RawDisplayHandle,

/// Option for enabling/disabling IME.
pub(crate) allow_ime: Option<bool>,
}

// Implementing `Clone` would violate the guarantees of `HasRawWindowHandle` and `HasRawDisplayHandle`.
Expand Down Expand Up @@ -978,6 +985,11 @@ impl Frame {
self.output.always_on_top = Some(always_on_top);
}

/// Enable/disable IME.
pub fn allow_ime(&mut self, allow: bool) {
self.allow_ime = Some(allow);
}

/// On desktop: Set the window to be centered.
///
/// (Wayland desktop currently not supported)
Expand Down
5 changes: 5 additions & 0 deletions crates/eframe/src/native/epi_integration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,7 @@ impl EpiIntegration {
screenshot: std::cell::Cell::new(None),
raw_display_handle: window.raw_display_handle(),
raw_window_handle: window.raw_window_handle(),
allow_ime: None,
};

let mut egui_winit = egui_winit::State::new(event_loop);
Expand Down Expand Up @@ -520,6 +521,10 @@ impl EpiIntegration {
app.update(egui_ctx, &mut self.frame);
});

if let Some(allow_ime) = self.frame.allow_ime.take() {
window.set_ime_allowed(allow_ime);
}

self.pending_full_output.append(full_output);
let full_output = std::mem::take(&mut self.pending_full_output);

Expand Down
7 changes: 5 additions & 2 deletions crates/eframe/src/native/run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -744,7 +744,10 @@ mod glow_integration {
let theme = system_theme.unwrap_or(self.native_options.default_theme);
integration.egui_ctx.set_visuals(theme.egui_visuals());

gl_window.window().set_ime_allowed(true);
gl_window
.window()
.set_ime_allowed(self.native_options.allow_ime);

if self.native_options.mouse_passthrough {
gl_window.window().set_cursor_hittest(false).unwrap();
}
Expand Down Expand Up @@ -1222,7 +1225,7 @@ mod wgpu_integration {
let theme = system_theme.unwrap_or(self.native_options.default_theme);
integration.egui_ctx.set_visuals(theme.egui_visuals());

window.set_ime_allowed(true);
window.set_ime_allowed(self.native_options.allow_ime);

{
let event_loop_proxy = self.repaint_proxy.clone();
Expand Down
1 change: 1 addition & 0 deletions crates/eframe/src/web/app_runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ impl AppRunner {
wgpu_render_state: painter.render_state(),
#[cfg(all(feature = "wgpu", feature = "glow"))]
wgpu_render_state: None,
allow_ime: None,
};

let needs_repaint: std::sync::Arc<NeedRepaint> = Default::default();
Expand Down