mirror of
https://github.com/italicsjenga/winit-sonoma-fix.git
synced 2025-01-11 21:31:29 +11:00
parent
f51f7c0ca8
commit
cebd15bfd1
|
@ -21,6 +21,8 @@
|
||||||
- On Windows, using `CursorState::Hide` when the cursor is grabbed now ungrabs the cursor first.
|
- On Windows, using `CursorState::Hide` when the cursor is grabbed now ungrabs the cursor first.
|
||||||
- Implemented `MouseCursor::NoneCursor` on Windows.
|
- Implemented `MouseCursor::NoneCursor` on Windows.
|
||||||
- Added `WindowBuilder::with_always_on_top` and `Window::set_always_on_top`. Implemented on Windows, macOS, and X11.
|
- Added `WindowBuilder::with_always_on_top` and `Window::set_always_on_top`. Implemented on Windows, macOS, and X11.
|
||||||
|
- On X11, `WindowBuilderExt` now has `with_class`, `with_override_redirect`, and `with_x11_window_type` to allow for more control over window creation. `WindowExt` additionally has `set_urgent`.
|
||||||
|
- More hints are set by default on X11, including `_NET_WM_PID` and `WM_CLIENT_MACHINE`. Note that prior to this, the `WM_CLASS` hint was automatically set to whatever value was passed to `with_title`. It's now set to the executable name to better conform to expectations and the specification; if this is undesirable, you must explicitly use `WindowBuilderExt::with_class`.
|
||||||
|
|
||||||
# Version 0.14.0 (2018-05-09)
|
# Version 0.14.0 (2018-05-09)
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
//! - Calling `Window::new(&events_loop)`.
|
//! - Calling `Window::new(&events_loop)`.
|
||||||
//! - Calling `let builder = WindowBuilder::new()` then `builder.build(&events_loop)`.
|
//! - Calling `let builder = WindowBuilder::new()` then `builder.build(&events_loop)`.
|
||||||
//!
|
//!
|
||||||
//! The first way is the simpliest way and will give you default values for everything.
|
//! The first way is the simplest way and will give you default values for everything.
|
||||||
//!
|
//!
|
||||||
//! The second way allows you to customize the way your window will look and behave by modifying
|
//! The second way allows you to customize the way your window will look and behave by modifying
|
||||||
//! the fields of the `WindowBuilder` object before you create the window.
|
//! the fields of the `WindowBuilder` object before you create the window.
|
||||||
|
|
|
@ -17,6 +17,7 @@ use platform::x11::ffi::XVisualInfo;
|
||||||
pub use platform::x11;
|
pub use platform::x11;
|
||||||
|
|
||||||
pub use platform::XNotSupported;
|
pub use platform::XNotSupported;
|
||||||
|
pub use platform::x11::util::WindowType as XWindowType;
|
||||||
|
|
||||||
/// Additional methods on `EventsLoop` that are specific to Linux.
|
/// Additional methods on `EventsLoop` that are specific to Linux.
|
||||||
pub trait EventsLoopExt {
|
pub trait EventsLoopExt {
|
||||||
|
@ -94,6 +95,9 @@ pub trait WindowExt {
|
||||||
|
|
||||||
fn get_xlib_xconnection(&self) -> Option<Arc<XConnection>>;
|
fn get_xlib_xconnection(&self) -> Option<Arc<XConnection>>;
|
||||||
|
|
||||||
|
/// Set window urgency hint (`XUrgencyHint`). Only relevant on X.
|
||||||
|
fn set_urgent(&self, is_urgent: bool);
|
||||||
|
|
||||||
/// This function returns the underlying `xcb_connection_t` of an xlib `Display`.
|
/// This function returns the underlying `xcb_connection_t` of an xlib `Display`.
|
||||||
///
|
///
|
||||||
/// Returns `None` if the window doesn't use xlib (if it uses wayland for example).
|
/// Returns `None` if the window doesn't use xlib (if it uses wayland for example).
|
||||||
|
@ -142,6 +146,7 @@ impl WindowExt for Window {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn get_xlib_screen_id(&self) -> Option<raw::c_int> {
|
fn get_xlib_screen_id(&self) -> Option<raw::c_int> {
|
||||||
match self.window {
|
match self.window {
|
||||||
LinuxWindow::X(ref w) => Some(w.get_xlib_screen_id()),
|
LinuxWindow::X(ref w) => Some(w.get_xlib_screen_id()),
|
||||||
|
@ -149,6 +154,7 @@ impl WindowExt for Window {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn get_xlib_xconnection(&self) -> Option<Arc<XConnection>> {
|
fn get_xlib_xconnection(&self) -> Option<Arc<XConnection>> {
|
||||||
match self.window {
|
match self.window {
|
||||||
LinuxWindow::X(ref w) => Some(w.get_xlib_xconnection()),
|
LinuxWindow::X(ref w) => Some(w.get_xlib_xconnection()),
|
||||||
|
@ -156,6 +162,7 @@ impl WindowExt for Window {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn get_xcb_connection(&self) -> Option<*mut raw::c_void> {
|
fn get_xcb_connection(&self) -> Option<*mut raw::c_void> {
|
||||||
match self.window {
|
match self.window {
|
||||||
LinuxWindow::X(ref w) => Some(w.get_xcb_connection()),
|
LinuxWindow::X(ref w) => Some(w.get_xcb_connection()),
|
||||||
|
@ -163,6 +170,13 @@ impl WindowExt for Window {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn set_urgent(&self, is_urgent: bool) {
|
||||||
|
if let LinuxWindow::X(ref w) = self.window {
|
||||||
|
w.set_urgent(is_urgent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn get_wayland_surface(&self) -> Option<*mut raw::c_void> {
|
fn get_wayland_surface(&self) -> Option<*mut raw::c_void> {
|
||||||
match self.window {
|
match self.window {
|
||||||
|
@ -190,6 +204,12 @@ pub trait WindowBuilderExt {
|
||||||
fn with_x11_visual<T>(self, visual_infos: *const T) -> WindowBuilder;
|
fn with_x11_visual<T>(self, visual_infos: *const T) -> WindowBuilder;
|
||||||
fn with_x11_screen(self, screen_id: i32) -> WindowBuilder;
|
fn with_x11_screen(self, screen_id: i32) -> WindowBuilder;
|
||||||
|
|
||||||
|
/// Build window with `WM_CLASS` hint; defaults to the name of the binary. Only relevant on X11.
|
||||||
|
fn with_class(self, class: String, instance: String) -> WindowBuilder;
|
||||||
|
/// Build window with override-redirect flag; defaults to false. Only relevant on X11.
|
||||||
|
fn with_override_redirect(self, override_redirect: bool) -> WindowBuilder;
|
||||||
|
/// Build window with `_NET_WM_WINDOW_TYPE` hint; defaults to `Normal`. Only relevant on X11.
|
||||||
|
fn with_x11_window_type(self, x11_window_type: XWindowType) -> WindowBuilder;
|
||||||
/// Build window with resize increment hint. Only implemented on X11.
|
/// Build window with resize increment hint. Only implemented on X11.
|
||||||
fn with_resize_increments(self, width_inc: u32, height_inc: u32) -> WindowBuilder;
|
fn with_resize_increments(self, width_inc: u32, height_inc: u32) -> WindowBuilder;
|
||||||
/// Build window with base size hint. Only implemented on X11.
|
/// Build window with base size hint. Only implemented on X11.
|
||||||
|
@ -211,6 +231,24 @@ impl WindowBuilderExt for WindowBuilder {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn with_class(mut self, instance: String, class: String) -> WindowBuilder {
|
||||||
|
self.platform_specific.class = Some((instance, class));
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn with_override_redirect(mut self, override_redirect: bool) -> WindowBuilder {
|
||||||
|
self.platform_specific.override_redirect = override_redirect;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn with_x11_window_type(mut self, x11_window_type: XWindowType) -> WindowBuilder {
|
||||||
|
self.platform_specific.x11_window_type = x11_window_type;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn with_resize_increments(mut self, width_inc: u32, height_inc: u32) -> WindowBuilder {
|
fn with_resize_increments(mut self, width_inc: u32, height_inc: u32) -> WindowBuilder {
|
||||||
self.platform_specific.resize_increments = Some((width_inc, height_inc));
|
self.platform_specific.resize_increments = Some((width_inc, height_inc));
|
||||||
|
|
|
@ -44,6 +44,9 @@ pub struct PlatformSpecificWindowBuilderAttributes {
|
||||||
pub screen_id: Option<i32>,
|
pub screen_id: Option<i32>,
|
||||||
pub resize_increments: Option<(u32, u32)>,
|
pub resize_increments: Option<(u32, u32)>,
|
||||||
pub base_size: Option<(u32, u32)>,
|
pub base_size: Option<(u32, u32)>,
|
||||||
|
pub class: Option<(String, String)>,
|
||||||
|
pub override_redirect: bool,
|
||||||
|
pub x11_window_type: x11::util::WindowType,
|
||||||
}
|
}
|
||||||
|
|
||||||
lazy_static!(
|
lazy_static!(
|
||||||
|
|
|
@ -7,7 +7,7 @@ mod window;
|
||||||
mod xdisplay;
|
mod xdisplay;
|
||||||
mod dnd;
|
mod dnd;
|
||||||
mod ime;
|
mod ime;
|
||||||
mod util;
|
pub mod util;
|
||||||
|
|
||||||
pub use self::monitor::{
|
pub use self::monitor::{
|
||||||
MonitorId,
|
MonitorId,
|
||||||
|
|
|
@ -18,3 +18,51 @@ impl From<bool> for StateOperation {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// X window type. Maps directly to
|
||||||
|
/// [`_NET_WM_WINDOW_TYPE`](https://specifications.freedesktop.org/wm-spec/1.3/ar01s05.html).
|
||||||
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||||
|
pub enum WindowType {
|
||||||
|
/// A desktop feature. This can include a single window containing desktop icons with the same dimensions as the
|
||||||
|
/// screen, allowing the desktop environment to have full control of the desktop, without the need for proxying
|
||||||
|
/// root window clicks.
|
||||||
|
Desktop,
|
||||||
|
/// A dock or panel feature. Typically a Window Manager would keep such windows on top of all other windows.
|
||||||
|
Dock,
|
||||||
|
/// Toolbar windows. "Torn off" from the main application.
|
||||||
|
Toolbar,
|
||||||
|
/// Pinnable menu windows. "Torn off" from the main application.
|
||||||
|
Menu,
|
||||||
|
/// A small persistent utility window, such as a palette or toolbox.
|
||||||
|
Utility,
|
||||||
|
/// The window is a splash screen displayed as an application is starting up.
|
||||||
|
Splash,
|
||||||
|
/// This is a dialog window.
|
||||||
|
Dialog,
|
||||||
|
/// This is a normal, top-level window.
|
||||||
|
Normal,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for WindowType {
|
||||||
|
fn default() -> Self {
|
||||||
|
WindowType::Normal
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WindowType {
|
||||||
|
pub(crate) fn as_atom(&self, xconn: &Arc<XConnection>) -> ffi::Atom {
|
||||||
|
use self::WindowType::*;
|
||||||
|
let atom_name: &[u8] = match self {
|
||||||
|
Desktop => b"_NET_WM_WINDOW_TYPE_DESKTOP\0",
|
||||||
|
Dock => b"_NET_WM_WINDOW_TYPE_DOCK\0",
|
||||||
|
Toolbar => b"_NET_WM_WINDOW_TYPE_TOOLBAR\0",
|
||||||
|
Menu => b"_NET_WM_WINDOW_TYPE_MENU\0",
|
||||||
|
Utility => b"_NET_WM_WINDOW_TYPE_UTILITY\0",
|
||||||
|
Splash => b"_NET_WM_WINDOW_TYPE_SPLASH\0",
|
||||||
|
Dialog => b"_NET_WM_WINDOW_TYPE_DIALOG\0",
|
||||||
|
Normal => b"_NET_WM_WINDOW_TYPE_NORMAL\0",
|
||||||
|
};
|
||||||
|
unsafe { get_atom(xconn, atom_name) }
|
||||||
|
.expect("Failed to get atom for `WindowType`")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
use std::{cmp, mem};
|
use std::{cmp, env, mem};
|
||||||
use std::borrow::Borrow;
|
use std::borrow::Borrow;
|
||||||
use std::ffi::CString;
|
use std::ffi::CString;
|
||||||
use std::os::raw::*;
|
use std::os::raw::*;
|
||||||
|
use std::path::Path;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use libc;
|
use libc;
|
||||||
|
@ -115,6 +116,10 @@ impl Window2 {
|
||||||
window_attributes |= ffi::CWBackPixel;
|
window_attributes |= ffi::CWBackPixel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if pl_attribs.override_redirect {
|
||||||
|
window_attributes |= ffi::CWOverrideRedirect;
|
||||||
|
}
|
||||||
|
|
||||||
// finally creating the window
|
// finally creating the window
|
||||||
let window = unsafe {
|
let window = unsafe {
|
||||||
(xconn.xlib.XCreateWindow)(
|
(xconn.xlib.XCreateWindow)(
|
||||||
|
@ -127,12 +132,12 @@ impl Window2 {
|
||||||
0,
|
0,
|
||||||
match pl_attribs.visual_infos {
|
match pl_attribs.visual_infos {
|
||||||
Some(vi) => vi.depth,
|
Some(vi) => vi.depth,
|
||||||
None => ffi::CopyFromParent
|
None => ffi::CopyFromParent,
|
||||||
},
|
},
|
||||||
ffi::InputOutput as c_uint,
|
ffi::InputOutput as c_uint,
|
||||||
match pl_attribs.visual_infos {
|
match pl_attribs.visual_infos {
|
||||||
Some(vi) => vi.visual,
|
Some(vi) => vi.visual,
|
||||||
None => ffi::CopyFromParent as *mut _
|
None => ffi::CopyFromParent as *mut ffi::Visual,
|
||||||
},
|
},
|
||||||
window_attributes,
|
window_attributes,
|
||||||
&mut set_win_attr,
|
&mut set_win_attr,
|
||||||
|
@ -178,17 +183,42 @@ impl Window2 {
|
||||||
)
|
)
|
||||||
}.queue();
|
}.queue();
|
||||||
|
|
||||||
// Set ICCCM WM_CLASS property based on initial window title
|
// WM_CLASS must be set *before* mapping the window, as per ICCCM!
|
||||||
// Must be done *before* mapping the window by ICCCM 4.1.2.5
|
|
||||||
{
|
{
|
||||||
let name = CString::new(window_attrs.title.as_str())
|
|
||||||
.expect("Window title contained null byte");
|
|
||||||
let mut class_hints = {
|
let mut class_hints = {
|
||||||
let class_hints = unsafe { (xconn.xlib.XAllocClassHint)() };
|
let class_hints = unsafe { (xconn.xlib.XAllocClassHint)() };
|
||||||
util::XSmartPointer::new(xconn, class_hints)
|
util::XSmartPointer::new(xconn, class_hints)
|
||||||
}.expect("XAllocClassHint returned null; out of memory");
|
}.expect("`XAllocClassHint` returned null; out of memory");
|
||||||
(*class_hints).res_name = name.as_ptr() as *mut c_char;
|
|
||||||
(*class_hints).res_class = name.as_ptr() as *mut c_char;
|
let (class, instance) = if let Some((instance, class)) = pl_attribs.class {
|
||||||
|
let instance = CString::new(instance.as_str())
|
||||||
|
.expect("`WM_CLASS` instance contained null byte");
|
||||||
|
let class = CString::new(class.as_str())
|
||||||
|
.expect("`WM_CLASS` class contained null byte");
|
||||||
|
(instance, class)
|
||||||
|
} else {
|
||||||
|
let class = env::args()
|
||||||
|
.next()
|
||||||
|
.as_ref()
|
||||||
|
// Default to the name of the binary (via argv[0])
|
||||||
|
.and_then(|path| Path::new(path).file_name())
|
||||||
|
.and_then(|bin_name| bin_name.to_str())
|
||||||
|
.map(|bin_name| bin_name.to_owned())
|
||||||
|
.or_else(|| Some(window_attrs.title.clone()))
|
||||||
|
.and_then(|string| CString::new(string.as_str()).ok())
|
||||||
|
.expect("Default `WM_CLASS` class contained null byte");
|
||||||
|
// This environment variable is extraordinarily unlikely to actually be used...
|
||||||
|
let instance = env::var("RESOURCE_NAME")
|
||||||
|
.ok()
|
||||||
|
.and_then(|instance| CString::new(instance.as_str()).ok())
|
||||||
|
.or_else(|| Some(class.clone()))
|
||||||
|
.expect("Default `WM_CLASS` instance contained null byte");
|
||||||
|
(instance, class)
|
||||||
|
};
|
||||||
|
|
||||||
|
(*class_hints).res_name = class.as_ptr() as *mut c_char;
|
||||||
|
(*class_hints).res_class = instance.as_ptr() as *mut c_char;
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
(xconn.xlib.XSetClassHint)(
|
(xconn.xlib.XSetClassHint)(
|
||||||
xconn.display,
|
xconn.display,
|
||||||
|
@ -198,6 +228,17 @@ impl Window2 {
|
||||||
}//.queue();
|
}//.queue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Window2::set_pid(xconn, x_window.window)
|
||||||
|
.map(|flusher| flusher.queue());
|
||||||
|
|
||||||
|
if pl_attribs.x11_window_type != Default::default() {
|
||||||
|
Window2::set_window_type(
|
||||||
|
xconn,
|
||||||
|
x_window.window,
|
||||||
|
pl_attribs.x11_window_type,
|
||||||
|
).queue();
|
||||||
|
}
|
||||||
|
|
||||||
// set size hints
|
// set size hints
|
||||||
{
|
{
|
||||||
let mut size_hints = {
|
let mut size_hints = {
|
||||||
|
@ -338,6 +379,96 @@ impl Window2 {
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn set_pid(xconn: &Arc<XConnection>, window: ffi::Window) -> Option<util::Flusher> {
|
||||||
|
let pid_atom = unsafe { util::get_atom(xconn, b"_NET_WM_PID\0") }
|
||||||
|
.expect("Failed to call XInternAtom (_NET_WM_PID)");
|
||||||
|
let client_machine_atom = unsafe { util::get_atom(xconn, b"WM_CLIENT_MACHINE\0") }
|
||||||
|
.expect("Failed to call XInternAtom (WM_CLIENT_MACHINE)");
|
||||||
|
unsafe {
|
||||||
|
let (hostname, hostname_length) = {
|
||||||
|
// 64 would suffice for Linux, but 256 will be enough everywhere (as per SUSv2). For instance, this is
|
||||||
|
// the limit defined by OpenBSD.
|
||||||
|
const MAXHOSTNAMELEN: usize = 256;
|
||||||
|
let mut hostname: [c_char; MAXHOSTNAMELEN] = mem::uninitialized();
|
||||||
|
let status = libc::gethostname(hostname.as_mut_ptr(), hostname.len());
|
||||||
|
if status != 0 { return None; }
|
||||||
|
hostname[MAXHOSTNAMELEN - 1] = '\0' as c_char; // a little extra safety
|
||||||
|
let hostname_length = libc::strlen(hostname.as_ptr());
|
||||||
|
(hostname, hostname_length as usize)
|
||||||
|
};
|
||||||
|
util::change_property(
|
||||||
|
xconn,
|
||||||
|
window,
|
||||||
|
pid_atom,
|
||||||
|
ffi::XA_CARDINAL,
|
||||||
|
util::Format::Long,
|
||||||
|
util::PropMode::Replace,
|
||||||
|
&[libc::getpid() as util::Cardinal],
|
||||||
|
).queue();
|
||||||
|
let flusher = util::change_property(
|
||||||
|
xconn,
|
||||||
|
window,
|
||||||
|
client_machine_atom,
|
||||||
|
ffi::XA_STRING,
|
||||||
|
util::Format::Char,
|
||||||
|
util::PropMode::Replace,
|
||||||
|
&hostname[0..hostname_length],
|
||||||
|
);
|
||||||
|
Some(flusher)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_window_type(
|
||||||
|
xconn: &Arc<XConnection>,
|
||||||
|
window: ffi::Window,
|
||||||
|
window_type: util::WindowType,
|
||||||
|
) -> util::Flusher {
|
||||||
|
let hint_atom = unsafe { util::get_atom(xconn, b"_NET_WM_WINDOW_TYPE\0") }
|
||||||
|
.expect("Failed to call XInternAtom (_NET_WM_WINDOW_TYPE)");
|
||||||
|
let window_type_atom = window_type.as_atom(xconn);
|
||||||
|
unsafe {
|
||||||
|
util::change_property(
|
||||||
|
xconn,
|
||||||
|
window,
|
||||||
|
hint_atom,
|
||||||
|
ffi::XA_ATOM,
|
||||||
|
util::Format::Long,
|
||||||
|
util::PropMode::Replace,
|
||||||
|
&[window_type_atom],
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_urgent(&self, is_urgent: bool) {
|
||||||
|
let xconn = &self.x.display;
|
||||||
|
|
||||||
|
let mut wm_hints = {
|
||||||
|
let mut wm_hints = unsafe {
|
||||||
|
(xconn.xlib.XGetWMHints)(xconn.display, self.x.window)
|
||||||
|
};
|
||||||
|
xconn.check_errors().expect("`XGetWMHints` failed");
|
||||||
|
if wm_hints.is_null() {
|
||||||
|
wm_hints = unsafe { (xconn.xlib.XAllocWMHints)() };
|
||||||
|
}
|
||||||
|
util::XSmartPointer::new(xconn, wm_hints)
|
||||||
|
}.expect("`XAllocWMHints` returned null; out of memory");
|
||||||
|
|
||||||
|
if is_urgent {
|
||||||
|
(*wm_hints).flags |= ffi::XUrgencyHint;
|
||||||
|
} else {
|
||||||
|
(*wm_hints).flags &= !ffi::XUrgencyHint;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
(xconn.xlib.XSetWMHints)(
|
||||||
|
xconn.display,
|
||||||
|
self.x.window,
|
||||||
|
wm_hints.ptr,
|
||||||
|
);
|
||||||
|
util::flush_requests(xconn).expect("Failed to set urgency hint");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn set_netwm(
|
fn set_netwm(
|
||||||
xconn: &Arc<XConnection>,
|
xconn: &Arc<XConnection>,
|
||||||
window: ffi::Window,
|
window: ffi::Window,
|
||||||
|
|
|
@ -389,7 +389,7 @@ impl Window {
|
||||||
self.window.set_window_icon(window_icon)
|
self.window.set_window_icon(window_icon)
|
||||||
}
|
}
|
||||||
|
|
||||||
//// Sets location of IME candidate box in client area coordinates relative to the top left.
|
/// Sets location of IME candidate box in client area coordinates relative to the top left.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn set_ime_spot(&self, x: i32, y: i32) {
|
pub fn set_ime_spot(&self, x: i32, y: i32) {
|
||||||
self.window.set_ime_spot(x, y)
|
self.window.set_ime_spot(x, y)
|
||||||
|
|
Loading…
Reference in a new issue