mirror of
https://github.com/italicsjenga/winit-sonoma-fix.git
synced 2024-10-17 07:21:33 +11:00
Implemented focus_window
(#1944)
This commit is contained in:
parent
91591c4e94
commit
b371b406d5
|
@ -1,3 +1,7 @@
|
||||||
|
# Unreleased
|
||||||
|
|
||||||
|
- Added `Window::focus_window`to bring the window to the front and set input focus.
|
||||||
|
|
||||||
# 0.25.0 (2021-05-15)
|
# 0.25.0 (2021-05-15)
|
||||||
|
|
||||||
- **Breaking:** On macOS, replace `WindowBuilderExtMacOS::with_activation_policy` with `EventLoopExtMacOS::set_activation_policy`
|
- **Breaking:** On macOS, replace `WindowBuilderExtMacOS::with_activation_policy` with `EventLoopExtMacOS::set_activation_policy`
|
||||||
|
|
|
@ -539,6 +539,8 @@ impl Window {
|
||||||
|
|
||||||
pub fn set_ime_position(&self, _position: Position) {}
|
pub fn set_ime_position(&self, _position: Position) {}
|
||||||
|
|
||||||
|
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>) {}
|
||||||
|
|
||||||
pub fn set_cursor_icon(&self, _: window::CursorIcon) {}
|
pub fn set_cursor_icon(&self, _: window::CursorIcon) {}
|
||||||
|
|
|
@ -271,6 +271,10 @@ impl Inner {
|
||||||
warn!("`Window::set_ime_position` is ignored on iOS")
|
warn!("`Window::set_ime_position` is ignored on iOS")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn focus_window(&self) {
|
||||||
|
warn!("`Window::set_focus` is ignored on iOS")
|
||||||
|
}
|
||||||
|
|
||||||
pub fn request_user_attention(&self, _request_type: Option<UserAttentionType>) {
|
pub fn request_user_attention(&self, _request_type: Option<UserAttentionType>) {
|
||||||
warn!("`Window::request_user_attention` is ignored on iOS")
|
warn!("`Window::request_user_attention` is ignored on iOS")
|
||||||
}
|
}
|
||||||
|
|
|
@ -430,6 +430,14 @@ impl Window {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
pub fn focus_window(&self) {
|
||||||
|
match self {
|
||||||
|
#[cfg(feature = "x11")]
|
||||||
|
&Window::X(ref w) => w.focus_window(),
|
||||||
|
#[cfg(feature = "wayland")]
|
||||||
|
_ => (),
|
||||||
|
}
|
||||||
|
}
|
||||||
pub fn request_user_attention(&self, _request_type: Option<UserAttentionType>) {
|
pub fn request_user_attention(&self, _request_type: Option<UserAttentionType>) {
|
||||||
match self {
|
match self {
|
||||||
#[cfg(feature = "x11")]
|
#[cfg(feature = "x11")]
|
||||||
|
|
|
@ -1,4 +1,9 @@
|
||||||
|
use x11_dl::xmd::CARD32;
|
||||||
pub use x11_dl::{
|
pub use x11_dl::{
|
||||||
error::OpenError, keysym::*, xcursor::*, xinput::*, xinput2::*, xlib::*, xlib_xcb::*,
|
error::OpenError, keysym::*, xcursor::*, xinput::*, xinput2::*, xlib::*, xlib_xcb::*,
|
||||||
xrandr::*, xrender::*,
|
xrandr::*, xrender::*,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Isn't defined by x11_dl
|
||||||
|
#[allow(non_upper_case_globals)]
|
||||||
|
pub const IconicState: CARD32 = 3;
|
||||||
|
|
|
@ -1340,6 +1340,41 @@ impl UnownedWindow {
|
||||||
self.set_ime_position_physical(x, y);
|
self.set_ime_position_physical(x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn focus_window(&self) {
|
||||||
|
let state_atom = unsafe { self.xconn.get_atom_unchecked(b"WM_STATE\0") };
|
||||||
|
let state_type_atom = unsafe { self.xconn.get_atom_unchecked(b"CARD32\0") };
|
||||||
|
let is_minimized = if let Ok(state) =
|
||||||
|
self.xconn
|
||||||
|
.get_property(self.xwindow, state_atom, state_type_atom)
|
||||||
|
{
|
||||||
|
state.contains(&(ffi::IconicState as c_ulong))
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
};
|
||||||
|
let is_visible = match self.shared_state.lock().visibility {
|
||||||
|
Visibility::Yes => true,
|
||||||
|
Visibility::YesWait | Visibility::No => false,
|
||||||
|
};
|
||||||
|
|
||||||
|
if is_visible && !is_minimized {
|
||||||
|
let atom = unsafe { self.xconn.get_atom_unchecked(b"_NET_ACTIVE_WINDOW\0") };
|
||||||
|
let flusher = self.xconn.send_client_msg(
|
||||||
|
self.xwindow,
|
||||||
|
self.root,
|
||||||
|
atom,
|
||||||
|
Some(ffi::SubstructureRedirectMask | ffi::SubstructureNotifyMask),
|
||||||
|
[1, ffi::CurrentTime as c_long, 0, 0, 0],
|
||||||
|
);
|
||||||
|
if let Err(e) = flusher.flush() {
|
||||||
|
log::error!(
|
||||||
|
"`flush` returned an error when focusing the window. Error was: {}",
|
||||||
|
e
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn request_user_attention(&self, request_type: Option<UserAttentionType>) {
|
pub fn request_user_attention(&self, request_type: Option<UserAttentionType>) {
|
||||||
let mut wm_hints = self
|
let mut wm_hints = self
|
||||||
|
|
|
@ -970,6 +970,21 @@ impl UnownedWindow {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn focus_window(&self) {
|
||||||
|
let is_minimized: BOOL = unsafe { msg_send![*self.ns_window, isMiniaturized] };
|
||||||
|
let is_minimized = is_minimized == YES;
|
||||||
|
let is_visible: BOOL = unsafe { msg_send![*self.ns_window, isVisible] };
|
||||||
|
let is_visible = is_visible == YES;
|
||||||
|
|
||||||
|
if !is_minimized && is_visible {
|
||||||
|
unsafe {
|
||||||
|
NSApp().activateIgnoringOtherApps_(YES);
|
||||||
|
util::make_key_and_order_front_async(*self.ns_window);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn request_user_attention(&self, request_type: Option<UserAttentionType>) {
|
pub fn request_user_attention(&self, request_type: Option<UserAttentionType>) {
|
||||||
let ns_request_type = request_type.map(|ty| match ty {
|
let ns_request_type = request_type.map(|ty| match ty {
|
||||||
|
|
|
@ -281,6 +281,11 @@ impl Window {
|
||||||
// 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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn focus_window(&self) {
|
||||||
|
// Currently a no-op as it does not seem there is good support for this on web
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn request_user_attention(&self, _request_type: Option<UserAttentionType>) {
|
pub fn request_user_attention(&self, _request_type: Option<UserAttentionType>) {
|
||||||
// Currently an intentional no-op
|
// Currently an intentional no-op
|
||||||
|
|
|
@ -685,6 +685,20 @@ impl Window {
|
||||||
pub fn theme(&self) -> Theme {
|
pub fn theme(&self) -> Theme {
|
||||||
self.window_state.lock().current_theme
|
self.window_state.lock().current_theme
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn focus_window(&self) {
|
||||||
|
let window = self.window.clone();
|
||||||
|
let window_flags = self.window_state.lock().window_flags();
|
||||||
|
|
||||||
|
let is_visible = window_flags.contains(WindowFlags::VISIBLE);
|
||||||
|
let is_minimized = window_flags.contains(WindowFlags::MINIMIZED);
|
||||||
|
let is_foreground = window.0 == unsafe { winuser::GetForegroundWindow() };
|
||||||
|
|
||||||
|
if is_visible && !is_minimized && !is_foreground {
|
||||||
|
unsafe { force_window_active(window.0) };
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Drop for Window {
|
impl Drop for Window {
|
||||||
|
|
|
@ -731,6 +731,21 @@ impl Window {
|
||||||
self.window.set_ime_position(position.into())
|
self.window.set_ime_position(position.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Brings the window to the front and sets input focus. Has no effect if the window is
|
||||||
|
/// already in focus, minimized, or not visible.
|
||||||
|
///
|
||||||
|
/// This method steals input focus from other applications. Do not use this method unless
|
||||||
|
/// you are certain that's what the user wants. Focus stealing can cause an extremely disruptive
|
||||||
|
/// user experience.
|
||||||
|
///
|
||||||
|
/// ## Platform-specific
|
||||||
|
///
|
||||||
|
/// - **iOS / Android / Web / Wayland:** Unsupported.
|
||||||
|
#[inline]
|
||||||
|
pub fn focus_window(&self) {
|
||||||
|
self.window.focus_window()
|
||||||
|
}
|
||||||
|
|
||||||
/// Requests user attention to the window, this has no effect if the application
|
/// Requests user attention to the window, this has no effect if the application
|
||||||
/// is already focused. How requesting for user attention manifests is platform dependent,
|
/// is already focused. How requesting for user attention manifests is platform dependent,
|
||||||
/// see `UserAttentionType` for details.
|
/// see `UserAttentionType` for details.
|
||||||
|
|
Loading…
Reference in a new issue