mirror of
https://github.com/italicsjenga/winit-sonoma-fix.git
synced 2024-12-23 22:01:31 +11:00
Add Window::set_ime_purpose
This adds a way to set the purpose for the IME input, implemented only on Wayland for now.
This commit is contained in:
parent
8f8da0f8bb
commit
1b4045dcb2
|
@ -65,6 +65,7 @@ And please only add new entries to the top of this list, right below the `# Unre
|
||||||
- On Wayland, support fractional scaling via the wp-fractional-scale protocol.
|
- On Wayland, support fractional scaling via the wp-fractional-scale protocol.
|
||||||
- On web, fix removal of mouse event listeners from the global object upon window distruction.
|
- On web, fix removal of mouse event listeners from the global object upon window distruction.
|
||||||
- Add WindowAttributes getter to WindowBuilder to allow introspection of default values.
|
- Add WindowAttributes getter to WindowBuilder to allow introspection of default values.
|
||||||
|
- Added `Window::set_ime_purpose` for setting the IME purpose, currently implemented on Wayland only.
|
||||||
|
|
||||||
# 0.27.5
|
# 0.27.5
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ use winit::{
|
||||||
dpi::PhysicalPosition,
|
dpi::PhysicalPosition,
|
||||||
event::{ElementState, Event, Ime, VirtualKeyCode, WindowEvent},
|
event::{ElementState, Event, Ime, VirtualKeyCode, WindowEvent},
|
||||||
event_loop::{ControlFlow, EventLoop},
|
event_loop::{ControlFlow, EventLoop},
|
||||||
window::WindowBuilder,
|
window::{ImePurpose, WindowBuilder},
|
||||||
};
|
};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
@ -18,6 +18,7 @@ fn main() {
|
||||||
println!("IME position will system default");
|
println!("IME position will system default");
|
||||||
println!("Click to set IME position to cursor's");
|
println!("Click to set IME position to cursor's");
|
||||||
println!("Press F2 to toggle IME. See the documentation of `set_ime_allowed` for more info");
|
println!("Press F2 to toggle IME. See the documentation of `set_ime_allowed` for more info");
|
||||||
|
println!("Press F3 to cycle through IME purposes.");
|
||||||
|
|
||||||
let event_loop = EventLoop::new();
|
let event_loop = EventLoop::new();
|
||||||
|
|
||||||
|
@ -26,6 +27,7 @@ fn main() {
|
||||||
.build(&event_loop)
|
.build(&event_loop)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
let mut ime_purpose = ImePurpose::Normal;
|
||||||
let mut ime_allowed = true;
|
let mut ime_allowed = true;
|
||||||
window.set_ime_allowed(ime_allowed);
|
window.set_ime_allowed(ime_allowed);
|
||||||
|
|
||||||
|
@ -90,7 +92,18 @@ fn main() {
|
||||||
{
|
{
|
||||||
ime_allowed = !ime_allowed;
|
ime_allowed = !ime_allowed;
|
||||||
window.set_ime_allowed(ime_allowed);
|
window.set_ime_allowed(ime_allowed);
|
||||||
println!("\nIME: {ime_allowed}\n");
|
println!("\nIME allowed: {ime_allowed}\n");
|
||||||
|
}
|
||||||
|
if input.state == ElementState::Pressed
|
||||||
|
&& input.virtual_keycode == Some(VirtualKeyCode::F3)
|
||||||
|
{
|
||||||
|
ime_purpose = match ime_purpose {
|
||||||
|
ImePurpose::Normal => ImePurpose::Password,
|
||||||
|
ImePurpose::Password => ImePurpose::Terminal,
|
||||||
|
_ => ImePurpose::Normal,
|
||||||
|
};
|
||||||
|
window.set_ime_purpose(ime_purpose);
|
||||||
|
println!("\nIME purpose: {ime_purpose:?}\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => (),
|
_ => (),
|
||||||
|
|
|
@ -25,7 +25,9 @@ use crate::{
|
||||||
error,
|
error,
|
||||||
event::{self, StartCause, VirtualKeyCode},
|
event::{self, StartCause, VirtualKeyCode},
|
||||||
event_loop::{self, ControlFlow, EventLoopWindowTarget as RootELW},
|
event_loop::{self, ControlFlow, EventLoopWindowTarget as RootELW},
|
||||||
window::{self, CursorGrabMode, ResizeDirection, Theme, WindowButtons, WindowLevel},
|
window::{
|
||||||
|
self, CursorGrabMode, ImePurpose, ResizeDirection, Theme, WindowButtons, WindowLevel,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static HAS_FOCUS: Lazy<RwLock<bool>> = Lazy::new(|| RwLock::new(true));
|
static HAS_FOCUS: Lazy<RwLock<bool>> = Lazy::new(|| RwLock::new(true));
|
||||||
|
@ -1006,6 +1008,8 @@ impl Window {
|
||||||
|
|
||||||
pub fn set_ime_allowed(&self, _allowed: bool) {}
|
pub fn set_ime_allowed(&self, _allowed: bool) {}
|
||||||
|
|
||||||
|
pub fn set_ime_purpose(&self, _purpose: ImePurpose) {}
|
||||||
|
|
||||||
pub fn focus_window(&self) {}
|
pub fn focus_window(&self) {}
|
||||||
|
|
||||||
pub fn request_user_attention(&self, _request_type: Option<window::UserAttentionType>) {}
|
pub fn request_user_attention(&self, _request_type: Option<window::UserAttentionType>) {}
|
||||||
|
|
|
@ -27,8 +27,8 @@ use crate::{
|
||||||
monitor, EventLoopWindowTarget, Fullscreen, MonitorHandle,
|
monitor, EventLoopWindowTarget, Fullscreen, MonitorHandle,
|
||||||
},
|
},
|
||||||
window::{
|
window::{
|
||||||
CursorGrabMode, CursorIcon, ResizeDirection, Theme, UserAttentionType, WindowAttributes,
|
CursorGrabMode, CursorIcon, ImePurpose, ResizeDirection, Theme, UserAttentionType,
|
||||||
WindowButtons, WindowId as RootWindowId, WindowLevel,
|
WindowAttributes, WindowButtons, WindowId as RootWindowId, WindowLevel,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -303,6 +303,10 @@ impl Inner {
|
||||||
warn!("`Window::set_ime_allowed` is ignored on iOS")
|
warn!("`Window::set_ime_allowed` is ignored on iOS")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_ime_purpose(&self, _purpose: ImePurpose) {
|
||||||
|
warn!("`Window::set_ime_allowed` is ignored on iOS")
|
||||||
|
}
|
||||||
|
|
||||||
pub fn focus_window(&self) {
|
pub fn focus_window(&self) {
|
||||||
warn!("`Window::set_focus` is ignored on iOS")
|
warn!("`Window::set_focus` is ignored on iOS")
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,8 +34,8 @@ use crate::{
|
||||||
},
|
},
|
||||||
icon::Icon,
|
icon::Icon,
|
||||||
window::{
|
window::{
|
||||||
CursorGrabMode, CursorIcon, ResizeDirection, Theme, UserAttentionType, WindowAttributes,
|
CursorGrabMode, CursorIcon, ImePurpose, ResizeDirection, Theme, UserAttentionType,
|
||||||
WindowButtons, WindowLevel,
|
WindowAttributes, WindowButtons, WindowLevel,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -519,6 +519,11 @@ impl Window {
|
||||||
x11_or_wayland!(match self; Window(w) => w.set_ime_allowed(allowed))
|
x11_or_wayland!(match self; Window(w) => w.set_ime_allowed(allowed))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn set_ime_purpose(&self, purpose: ImePurpose) {
|
||||||
|
x11_or_wayland!(match self; Window(w) => w.set_ime_purpose(purpose))
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn focus_window(&self) {
|
pub fn focus_window(&self) {
|
||||||
match self {
|
match self {
|
||||||
|
|
|
@ -9,7 +9,7 @@ use crate::event::{Ime, WindowEvent};
|
||||||
use crate::platform_impl::wayland;
|
use crate::platform_impl::wayland;
|
||||||
use crate::platform_impl::wayland::event_loop::WinitState;
|
use crate::platform_impl::wayland::event_loop::WinitState;
|
||||||
|
|
||||||
use super::{Preedit, TextInputHandler, TextInputInner};
|
use super::{Preedit, TextInputHandler, TextInputInner, ZwpTextInputV3Ext};
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(super) fn handle_text_input(
|
pub(super) fn handle_text_input(
|
||||||
|
@ -32,6 +32,7 @@ pub(super) fn handle_text_input(
|
||||||
// Enable text input on that surface.
|
// Enable text input on that surface.
|
||||||
if window_handle.ime_allowed.get() {
|
if window_handle.ime_allowed.get() {
|
||||||
text_input.enable();
|
text_input.enable();
|
||||||
|
text_input.set_content_type_by_purpose(window_handle.ime_purpose.get());
|
||||||
text_input.commit();
|
text_input.commit();
|
||||||
event_sink.push_window_event(WindowEvent::Ime(Ime::Enabled), window_id);
|
event_sink.push_window_event(WindowEvent::Ime(Ime::Enabled), window_id);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,13 @@
|
||||||
use sctk::reexports::client::protocol::wl_seat::WlSeat;
|
use sctk::reexports::client::protocol::wl_seat::WlSeat;
|
||||||
use sctk::reexports::client::Attached;
|
use sctk::reexports::client::Attached;
|
||||||
use sctk::reexports::protocols::unstable::text_input::v3::client::zwp_text_input_manager_v3::ZwpTextInputManagerV3;
|
use sctk::reexports::protocols::unstable::text_input::v3::client::zwp_text_input_manager_v3::ZwpTextInputManagerV3;
|
||||||
use sctk::reexports::protocols::unstable::text_input::v3::client::zwp_text_input_v3::ZwpTextInputV3;
|
use sctk::reexports::protocols::unstable::text_input::v3::client::zwp_text_input_v3::{
|
||||||
|
ContentHint, ContentPurpose, ZwpTextInputV3,
|
||||||
|
};
|
||||||
|
|
||||||
use crate::platform_impl::wayland::event_loop::WinitState;
|
use crate::platform_impl::wayland::event_loop::WinitState;
|
||||||
use crate::platform_impl::wayland::WindowId;
|
use crate::platform_impl::wayland::WindowId;
|
||||||
|
use crate::window::ImePurpose;
|
||||||
|
|
||||||
mod handlers;
|
mod handlers;
|
||||||
|
|
||||||
|
@ -14,6 +17,21 @@ pub struct TextInputHandler {
|
||||||
text_input: ZwpTextInputV3,
|
text_input: ZwpTextInputV3,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
trait ZwpTextInputV3Ext {
|
||||||
|
fn set_content_type_by_purpose(&self, purpose: ImePurpose);
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ZwpTextInputV3Ext for ZwpTextInputV3 {
|
||||||
|
fn set_content_type_by_purpose(&self, purpose: ImePurpose) {
|
||||||
|
let (hint, purpose) = match purpose {
|
||||||
|
ImePurpose::Normal => (ContentHint::None, ContentPurpose::Normal),
|
||||||
|
ImePurpose::Password => (ContentHint::SensitiveData, ContentPurpose::Password),
|
||||||
|
ImePurpose::Terminal => (ContentHint::None, ContentPurpose::Terminal),
|
||||||
|
};
|
||||||
|
self.set_content_type(hint, purpose);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl TextInputHandler {
|
impl TextInputHandler {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn set_ime_position(&self, x: i32, y: i32) {
|
pub fn set_ime_position(&self, x: i32, y: i32) {
|
||||||
|
@ -22,8 +40,15 @@ impl TextInputHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn set_input_allowed(&self, allowed: bool) {
|
pub fn set_content_type_by_purpose(&self, purpose: ImePurpose) {
|
||||||
if allowed {
|
self.text_input.set_content_type_by_purpose(purpose);
|
||||||
|
self.text_input.commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn set_input_allowed(&self, allowed: Option<ImePurpose>) {
|
||||||
|
if let Some(purpose) = allowed {
|
||||||
|
self.text_input.set_content_type_by_purpose(purpose);
|
||||||
self.text_input.enable();
|
self.text_input.enable();
|
||||||
} else {
|
} else {
|
||||||
self.text_input.disable();
|
self.text_input.disable();
|
||||||
|
|
|
@ -21,8 +21,8 @@ use crate::platform_impl::{
|
||||||
OsError, PlatformSpecificWindowBuilderAttributes as PlatformAttributes,
|
OsError, PlatformSpecificWindowBuilderAttributes as PlatformAttributes,
|
||||||
};
|
};
|
||||||
use crate::window::{
|
use crate::window::{
|
||||||
CursorGrabMode, CursorIcon, ResizeDirection, Theme, UserAttentionType, WindowAttributes,
|
CursorGrabMode, CursorIcon, ImePurpose, ResizeDirection, Theme, UserAttentionType,
|
||||||
WindowButtons,
|
WindowAttributes, WindowButtons,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::env::WindowingFeatures;
|
use super::env::WindowingFeatures;
|
||||||
|
@ -623,6 +623,11 @@ impl Window {
|
||||||
self.send_request(WindowRequest::AllowIme(allowed));
|
self.send_request(WindowRequest::AllowIme(allowed));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn set_ime_purpose(&self, purpose: ImePurpose) {
|
||||||
|
self.send_request(WindowRequest::ImePurpose(purpose));
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn display(&self) -> &Display {
|
pub fn display(&self) -> &Display {
|
||||||
&self.display
|
&self.display
|
||||||
|
|
|
@ -23,7 +23,7 @@ use crate::platform_impl::wayland::protocols::wp_fractional_scale_v1::WpFraction
|
||||||
use crate::platform_impl::wayland::seat::pointer::WinitPointer;
|
use crate::platform_impl::wayland::seat::pointer::WinitPointer;
|
||||||
use crate::platform_impl::wayland::seat::text_input::TextInputHandler;
|
use crate::platform_impl::wayland::seat::text_input::TextInputHandler;
|
||||||
use crate::platform_impl::wayland::WindowId;
|
use crate::platform_impl::wayland::WindowId;
|
||||||
use crate::window::{CursorGrabMode, CursorIcon, Theme, UserAttentionType};
|
use crate::window::{CursorGrabMode, CursorIcon, ImePurpose, Theme, UserAttentionType};
|
||||||
|
|
||||||
use super::WinitFrame;
|
use super::WinitFrame;
|
||||||
|
|
||||||
|
@ -83,6 +83,9 @@ pub enum WindowRequest {
|
||||||
/// Enable IME on the given window.
|
/// Enable IME on the given window.
|
||||||
AllowIme(bool),
|
AllowIme(bool),
|
||||||
|
|
||||||
|
/// Set the IME purpose.
|
||||||
|
ImePurpose(ImePurpose),
|
||||||
|
|
||||||
/// Mark the window as opaque.
|
/// Mark the window as opaque.
|
||||||
Transparent(bool),
|
Transparent(bool),
|
||||||
|
|
||||||
|
@ -169,6 +172,9 @@ pub struct WindowHandle {
|
||||||
/// Allow IME events for that window.
|
/// Allow IME events for that window.
|
||||||
pub ime_allowed: Cell<bool>,
|
pub ime_allowed: Cell<bool>,
|
||||||
|
|
||||||
|
/// IME purpose for that window.
|
||||||
|
pub ime_purpose: Cell<ImePurpose>,
|
||||||
|
|
||||||
/// Wether the window is transparent.
|
/// Wether the window is transparent.
|
||||||
pub transparent: Cell<bool>,
|
pub transparent: Cell<bool>,
|
||||||
|
|
||||||
|
@ -226,6 +232,7 @@ impl WindowHandle {
|
||||||
attention_requested: Cell::new(false),
|
attention_requested: Cell::new(false),
|
||||||
compositor,
|
compositor,
|
||||||
ime_allowed: Cell::new(false),
|
ime_allowed: Cell::new(false),
|
||||||
|
ime_purpose: Cell::new(ImePurpose::default()),
|
||||||
has_focus,
|
has_focus,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -399,8 +406,9 @@ impl WindowHandle {
|
||||||
self.ime_allowed.replace(allowed);
|
self.ime_allowed.replace(allowed);
|
||||||
let window_id = wayland::make_wid(self.window.surface());
|
let window_id = wayland::make_wid(self.window.surface());
|
||||||
|
|
||||||
|
let purpose = allowed.then(|| self.ime_purpose.get());
|
||||||
for text_input in self.text_inputs.iter() {
|
for text_input in self.text_inputs.iter() {
|
||||||
text_input.set_input_allowed(allowed);
|
text_input.set_input_allowed(purpose);
|
||||||
}
|
}
|
||||||
|
|
||||||
let event = if allowed {
|
let event = if allowed {
|
||||||
|
@ -412,6 +420,20 @@ impl WindowHandle {
|
||||||
event_sink.push_window_event(event, window_id);
|
event_sink.push_window_event(event, window_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_ime_purpose(&self, purpose: ImePurpose) {
|
||||||
|
if self.ime_purpose.get() == purpose {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.ime_purpose.replace(purpose);
|
||||||
|
|
||||||
|
if self.ime_allowed.get() {
|
||||||
|
for text_input in self.text_inputs.iter() {
|
||||||
|
text_input.set_content_type_by_purpose(purpose);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn set_cursor_visible(&self, visible: bool) {
|
pub fn set_cursor_visible(&self, visible: bool) {
|
||||||
self.cursor_visible.replace(visible);
|
self.cursor_visible.replace(visible);
|
||||||
let cursor_icon = match visible {
|
let cursor_icon = match visible {
|
||||||
|
@ -475,6 +497,9 @@ pub fn handle_window_requests(winit_state: &mut WinitState) {
|
||||||
let event_sink = &mut winit_state.event_sink;
|
let event_sink = &mut winit_state.event_sink;
|
||||||
window_handle.set_ime_allowed(allow, event_sink);
|
window_handle.set_ime_allowed(allow, event_sink);
|
||||||
}
|
}
|
||||||
|
WindowRequest::ImePurpose(purpose) => {
|
||||||
|
window_handle.set_ime_purpose(purpose);
|
||||||
|
}
|
||||||
WindowRequest::SetCursorGrabMode(mode) => {
|
WindowRequest::SetCursorGrabMode(mode) => {
|
||||||
window_handle.set_cursor_grab(mode);
|
window_handle.set_cursor_grab(mode);
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,7 @@ use crate::{
|
||||||
PlatformSpecificWindowBuilderAttributes, VideoMode as PlatformVideoMode,
|
PlatformSpecificWindowBuilderAttributes, VideoMode as PlatformVideoMode,
|
||||||
},
|
},
|
||||||
window::{
|
window::{
|
||||||
CursorGrabMode, CursorIcon, Icon, ResizeDirection, Theme, UserAttentionType,
|
CursorGrabMode, CursorIcon, Icon, ImePurpose, ResizeDirection, Theme, UserAttentionType,
|
||||||
WindowAttributes, WindowButtons, WindowLevel,
|
WindowAttributes, WindowButtons, WindowLevel,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -1532,6 +1532,9 @@ impl UnownedWindow {
|
||||||
.send(ImeRequest::Allow(self.xwindow, allowed));
|
.send(ImeRequest::Allow(self.xwindow, allowed));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn set_ime_purpose(&self, _purpose: ImePurpose) {}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn focus_window(&self) {
|
pub fn focus_window(&self) {
|
||||||
let state_atom = unsafe { self.xconn.get_atom_unchecked(b"WM_STATE\0") };
|
let state_atom = unsafe { self.xconn.get_atom_unchecked(b"WM_STATE\0") };
|
||||||
|
|
|
@ -33,8 +33,8 @@ use crate::{
|
||||||
Fullscreen, OsError,
|
Fullscreen, OsError,
|
||||||
},
|
},
|
||||||
window::{
|
window::{
|
||||||
CursorGrabMode, CursorIcon, ResizeDirection, Theme, UserAttentionType, WindowAttributes,
|
CursorGrabMode, CursorIcon, ImePurpose, ResizeDirection, Theme, UserAttentionType,
|
||||||
WindowButtons, WindowId as RootWindowId, WindowLevel,
|
WindowAttributes, WindowButtons, WindowId as RootWindowId, WindowLevel,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use core_graphics::display::{CGDisplay, CGPoint};
|
use core_graphics::display::{CGDisplay, CGPoint};
|
||||||
|
@ -1154,6 +1154,9 @@ impl WinitWindow {
|
||||||
unsafe { Id::from_shared(self.view()) }.set_ime_allowed(allowed);
|
unsafe { Id::from_shared(self.view()) }.set_ime_allowed(allowed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn set_ime_purpose(&self, _purpose: ImePurpose) {}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn focus_window(&self) {
|
pub fn focus_window(&self) {
|
||||||
let is_minimized = self.isMiniaturized();
|
let is_minimized = self.isMiniaturized();
|
||||||
|
|
|
@ -12,6 +12,7 @@ use crate::{
|
||||||
error,
|
error,
|
||||||
platform_impl::Fullscreen,
|
platform_impl::Fullscreen,
|
||||||
window,
|
window,
|
||||||
|
window::ImePurpose,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
|
@ -323,6 +324,9 @@ impl Window {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn set_ime_allowed(&self, _allowed: bool) {}
|
pub fn set_ime_allowed(&self, _allowed: bool) {}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn set_ime_purpose(&self, _purpose: ImePurpose) {}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn focus_window(&self) {}
|
pub fn focus_window(&self) {}
|
||||||
|
|
||||||
|
|
|
@ -3,8 +3,8 @@ use crate::error::{ExternalError, NotSupportedError, OsError as RootOE};
|
||||||
use crate::event;
|
use crate::event;
|
||||||
use crate::icon::Icon;
|
use crate::icon::Icon;
|
||||||
use crate::window::{
|
use crate::window::{
|
||||||
CursorGrabMode, CursorIcon, ResizeDirection, Theme, UserAttentionType, WindowAttributes,
|
CursorGrabMode, CursorIcon, ImePurpose, ResizeDirection, Theme, UserAttentionType,
|
||||||
WindowButtons, WindowId as RootWI, WindowLevel,
|
WindowAttributes, WindowButtons, WindowId as RootWI, WindowLevel,
|
||||||
};
|
};
|
||||||
|
|
||||||
use raw_window_handle::{RawDisplayHandle, RawWindowHandle, WebDisplayHandle, WebWindowHandle};
|
use raw_window_handle::{RawDisplayHandle, RawWindowHandle, WebDisplayHandle, WebWindowHandle};
|
||||||
|
@ -351,6 +351,11 @@ impl Window {
|
||||||
// Currently not implemented
|
// Currently not implemented
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn set_ime_purpose(&self, _purpose: ImePurpose) {
|
||||||
|
// Currently not implemented
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn focus_window(&self) {
|
pub fn focus_window(&self) {
|
||||||
// Currently a no-op as it does not seem there is good support for this on web
|
// Currently a no-op as it does not seem there is good support for this on web
|
||||||
|
|
|
@ -71,8 +71,8 @@ use crate::{
|
||||||
Fullscreen, PlatformSpecificWindowBuilderAttributes, WindowId,
|
Fullscreen, PlatformSpecificWindowBuilderAttributes, WindowId,
|
||||||
},
|
},
|
||||||
window::{
|
window::{
|
||||||
CursorGrabMode, CursorIcon, ResizeDirection, Theme, UserAttentionType, WindowAttributes,
|
CursorGrabMode, CursorIcon, ImePurpose, ResizeDirection, Theme, UserAttentionType,
|
||||||
WindowButtons, WindowLevel,
|
WindowAttributes, WindowButtons, WindowLevel,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -733,6 +733,9 @@ impl Window {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn set_ime_purpose(&self, _purpose: ImePurpose) {}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn request_user_attention(&self, request_type: Option<UserAttentionType>) {
|
pub fn request_user_attention(&self, request_type: Option<UserAttentionType>) {
|
||||||
let window = self.window.clone();
|
let window = self.window.clone();
|
||||||
|
|
|
@ -1054,6 +1054,16 @@ impl Window {
|
||||||
self.window.set_ime_allowed(allowed);
|
self.window.set_ime_allowed(allowed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Sets the IME purpose for the window using [`ImePurpose`].
|
||||||
|
///
|
||||||
|
/// ## Platform-specific
|
||||||
|
///
|
||||||
|
/// - **iOS / Android / Web / Windows / X11 / macOS / Orbital:** Unsupported.
|
||||||
|
#[inline]
|
||||||
|
pub fn set_ime_purpose(&self, purpose: ImePurpose) {
|
||||||
|
self.window.set_ime_purpose(purpose);
|
||||||
|
}
|
||||||
|
|
||||||
/// Brings the window to the front and sets input focus. Has no effect if the window is
|
/// Brings the window to the front and sets input focus. Has no effect if the window is
|
||||||
/// already in focus, minimized, or not visible.
|
/// already in focus, minimized, or not visible.
|
||||||
///
|
///
|
||||||
|
@ -1545,3 +1555,30 @@ impl Default for WindowLevel {
|
||||||
Self::Normal
|
Self::Normal
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Generic IME purposes for use in [`Window::set_ime_purpose`].
|
||||||
|
///
|
||||||
|
/// The purpose may improve UX by optimizing the IME for the specific use case,
|
||||||
|
/// if winit can express the purpose to the platform and the platform reacts accordingly.
|
||||||
|
///
|
||||||
|
/// ## Platform-specific
|
||||||
|
///
|
||||||
|
/// - **iOS / Android / Web / Windows / X11 / macOS / Orbital:** Unsupported.
|
||||||
|
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
|
||||||
|
#[non_exhaustive]
|
||||||
|
pub enum ImePurpose {
|
||||||
|
/// No special hints for the IME (default).
|
||||||
|
Normal,
|
||||||
|
/// The IME is used for password input.
|
||||||
|
Password,
|
||||||
|
/// The IME is used to input into a terminal.
|
||||||
|
///
|
||||||
|
/// For example, that could alter OSK on Wayland to show extra buttons.
|
||||||
|
Terminal,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for ImePurpose {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::Normal
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue