mirror of
https://github.com/italicsjenga/winit-sonoma-fix.git
synced 2024-12-23 22:01:31 +11:00
On Windows and MacOS, add Window::has_focus
This commit is contained in:
parent
067535eb38
commit
a88d2e079d
|
@ -8,6 +8,7 @@ And please only add new entries to the top of this list, right below the `# Unre
|
||||||
|
|
||||||
# Unreleased
|
# Unreleased
|
||||||
|
|
||||||
|
- Add `Window::has_focus`.
|
||||||
- On Windows, fix `Window::set_minimized(false)` not working for windows minimized by `Win + D` hotkey.
|
- On Windows, fix `Window::set_minimized(false)` not working for windows minimized by `Win + D` hotkey.
|
||||||
- **Breaking:** On Web, touch input no longer fires `WindowEvent::Cursor*`, `WindowEvent::MouseInput`, or `DeviceEvent::MouseMotion` like other platforms, but instead it fires `WindowEvent::Touch`.
|
- **Breaking:** On Web, touch input no longer fires `WindowEvent::Cursor*`, `WindowEvent::MouseInput`, or `DeviceEvent::MouseMotion` like other platforms, but instead it fires `WindowEvent::Touch`.
|
||||||
- **Breaking:** Removed platform specific `WindowBuilder::with_parent` API in favor of `WindowBuilder::with_parent_window`.
|
- **Breaking:** Removed platform specific `WindowBuilder::with_parent` API in favor of `WindowBuilder::with_parent_window`.
|
||||||
|
|
|
@ -5,7 +5,7 @@ use std::{
|
||||||
hash::Hash,
|
hash::Hash,
|
||||||
sync::{
|
sync::{
|
||||||
atomic::{AtomicBool, Ordering},
|
atomic::{AtomicBool, Ordering},
|
||||||
mpsc, Arc,
|
mpsc, Arc, RwLock,
|
||||||
},
|
},
|
||||||
time::{Duration, Instant},
|
time::{Duration, Instant},
|
||||||
};
|
};
|
||||||
|
@ -14,6 +14,7 @@ use android_activity::input::{InputEvent, KeyAction, Keycode, MotionAction};
|
||||||
use android_activity::{
|
use android_activity::{
|
||||||
AndroidApp, AndroidAppWaker, ConfigurationRef, InputStatus, MainEvent, Rect,
|
AndroidApp, AndroidAppWaker, ConfigurationRef, InputStatus, MainEvent, Rect,
|
||||||
};
|
};
|
||||||
|
use once_cell::sync::Lazy;
|
||||||
use raw_window_handle::{
|
use raw_window_handle::{
|
||||||
AndroidDisplayHandle, HasRawWindowHandle, RawDisplayHandle, RawWindowHandle,
|
AndroidDisplayHandle, HasRawWindowHandle, RawDisplayHandle, RawWindowHandle,
|
||||||
};
|
};
|
||||||
|
@ -27,6 +28,8 @@ use crate::{
|
||||||
window::{self, CursorGrabMode, ResizeDirection, Theme, WindowButtons, WindowLevel},
|
window::{self, CursorGrabMode, ResizeDirection, Theme, WindowButtons, WindowLevel},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static HAS_FOCUS: Lazy<RwLock<bool>> = Lazy::new(|| RwLock::new(true));
|
||||||
|
|
||||||
fn ndk_keycode_to_virtualkeycode(keycode: Keycode) -> Option<event::VirtualKeyCode> {
|
fn ndk_keycode_to_virtualkeycode(keycode: Keycode) -> Option<event::VirtualKeyCode> {
|
||||||
match keycode {
|
match keycode {
|
||||||
Keycode::A => Some(VirtualKeyCode::A),
|
Keycode::A => Some(VirtualKeyCode::A),
|
||||||
|
@ -394,6 +397,7 @@ impl<T: 'static> EventLoop<T> {
|
||||||
warn!("TODO: find a way to notify application of content rect change");
|
warn!("TODO: find a way to notify application of content rect change");
|
||||||
}
|
}
|
||||||
MainEvent::GainedFocus => {
|
MainEvent::GainedFocus => {
|
||||||
|
*HAS_FOCUS.write().unwrap() = true;
|
||||||
sticky_exit_callback(
|
sticky_exit_callback(
|
||||||
event::Event::WindowEvent {
|
event::Event::WindowEvent {
|
||||||
window_id: window::WindowId(WindowId),
|
window_id: window::WindowId(WindowId),
|
||||||
|
@ -405,6 +409,7 @@ impl<T: 'static> EventLoop<T> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
MainEvent::LostFocus => {
|
MainEvent::LostFocus => {
|
||||||
|
*HAS_FOCUS.write().unwrap() = false;
|
||||||
sticky_exit_callback(
|
sticky_exit_callback(
|
||||||
event::Event::WindowEvent {
|
event::Event::WindowEvent {
|
||||||
window_id: window::WindowId(WindowId),
|
window_id: window::WindowId(WindowId),
|
||||||
|
@ -1064,6 +1069,10 @@ impl Window {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn has_focus(&self) -> bool {
|
||||||
|
*HAS_FOCUS.read().unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn title(&self) -> String {
|
pub fn title(&self) -> String {
|
||||||
String::new()
|
String::new()
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,5 +28,8 @@ extern_methods!(
|
||||||
|
|
||||||
#[sel(makeKeyAndVisible)]
|
#[sel(makeKeyAndVisible)]
|
||||||
pub fn makeKeyAndVisible(&self);
|
pub fn makeKeyAndVisible(&self);
|
||||||
|
|
||||||
|
#[sel(isKeyWindow)]
|
||||||
|
pub fn isKeyWindow(&self) -> bool;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
|
@ -348,6 +348,10 @@ impl Inner {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn has_focus(&self) -> bool {
|
||||||
|
self.window.isKeyWindow()
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn set_theme(&self, _theme: Option<Theme>) {
|
pub fn set_theme(&self, _theme: Option<Theme>) {
|
||||||
warn!("`Window::set_theme` is ignored on iOS");
|
warn!("`Window::set_theme` is ignored on iOS");
|
||||||
|
|
|
@ -605,6 +605,10 @@ impl Window {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
pub fn has_focus(&self) -> bool {
|
||||||
|
x11_or_wayland!(match self; Window(window) => window.has_focus())
|
||||||
|
}
|
||||||
|
|
||||||
pub fn title(&self) -> String {
|
pub fn title(&self) -> String {
|
||||||
x11_or_wayland!(match self; Window(window) => window.title())
|
x11_or_wayland!(match self; Window(window) => window.title())
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
//! Handling of various keyboard events.
|
//! Handling of various keyboard events.
|
||||||
|
|
||||||
|
use std::sync::atomic::Ordering;
|
||||||
|
|
||||||
use sctk::reexports::client::protocol::wl_keyboard::KeyState;
|
use sctk::reexports::client::protocol::wl_keyboard::KeyState;
|
||||||
|
|
||||||
use sctk::seat::keyboard::Event as KeyboardEvent;
|
use sctk::seat::keyboard::Event as KeyboardEvent;
|
||||||
|
@ -22,6 +24,9 @@ pub(super) fn handle_keyboard(
|
||||||
KeyboardEvent::Enter { surface, .. } => {
|
KeyboardEvent::Enter { surface, .. } => {
|
||||||
let window_id = wayland::make_wid(&surface);
|
let window_id = wayland::make_wid(&surface);
|
||||||
|
|
||||||
|
let window_handle = winit_state.window_map.get_mut(&window_id).unwrap();
|
||||||
|
window_handle.has_focus.store(true, Ordering::Relaxed);
|
||||||
|
|
||||||
// Window gained focus.
|
// Window gained focus.
|
||||||
event_sink.push_window_event(WindowEvent::Focused(true), window_id);
|
event_sink.push_window_event(WindowEvent::Focused(true), window_id);
|
||||||
|
|
||||||
|
@ -44,6 +49,9 @@ pub(super) fn handle_keyboard(
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let window_handle = winit_state.window_map.get_mut(&window_id).unwrap();
|
||||||
|
window_handle.has_focus.store(false, Ordering::Relaxed);
|
||||||
|
|
||||||
// Window lost focus.
|
// Window lost focus.
|
||||||
event_sink.push_window_event(WindowEvent::Focused(false), window_id);
|
event_sink.push_window_event(WindowEvent::Focused(false), window_id);
|
||||||
|
|
||||||
|
|
|
@ -79,6 +79,9 @@ pub struct Window {
|
||||||
|
|
||||||
/// Grabbing mode.
|
/// Grabbing mode.
|
||||||
cursor_grab_mode: Mutex<CursorGrabMode>,
|
cursor_grab_mode: Mutex<CursorGrabMode>,
|
||||||
|
|
||||||
|
/// Whether the window has keyboard focus.
|
||||||
|
has_focus: Arc<AtomicBool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Window {
|
impl Window {
|
||||||
|
@ -244,6 +247,7 @@ impl Window {
|
||||||
window.surface().commit();
|
window.surface().commit();
|
||||||
|
|
||||||
let size = Arc::new(Mutex::new(LogicalSize::new(width, height)));
|
let size = Arc::new(Mutex::new(LogicalSize::new(width, height)));
|
||||||
|
let has_focus = Arc::new(AtomicBool::new(true));
|
||||||
|
|
||||||
// We should trigger redraw and commit the surface for the newly created window.
|
// We should trigger redraw and commit the surface for the newly created window.
|
||||||
let mut window_user_request = WindowUserRequest::new();
|
let mut window_user_request = WindowUserRequest::new();
|
||||||
|
@ -258,6 +262,7 @@ impl Window {
|
||||||
&event_loop_window_target.env,
|
&event_loop_window_target.env,
|
||||||
window,
|
window,
|
||||||
size.clone(),
|
size.clone(),
|
||||||
|
has_focus.clone(),
|
||||||
window_requests.clone(),
|
window_requests.clone(),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -318,6 +323,7 @@ impl Window {
|
||||||
resizeable: AtomicBool::new(attributes.resizable),
|
resizeable: AtomicBool::new(attributes.resizable),
|
||||||
decorated: AtomicBool::new(attributes.decorations),
|
decorated: AtomicBool::new(attributes.decorations),
|
||||||
cursor_grab_mode: Mutex::new(CursorGrabMode::None),
|
cursor_grab_mode: Mutex::new(CursorGrabMode::None),
|
||||||
|
has_focus,
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(window)
|
Ok(window)
|
||||||
|
@ -650,6 +656,10 @@ impl Window {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
pub fn has_focus(&self) -> bool {
|
||||||
|
self.has_focus.load(Ordering::Relaxed)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn title(&self) -> String {
|
pub fn title(&self) -> String {
|
||||||
String::new()
|
String::new()
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
use std::mem::ManuallyDrop;
|
use std::mem::ManuallyDrop;
|
||||||
|
use std::sync::atomic::AtomicBool;
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
use sctk::reexports::client::protocol::wl_compositor::WlCompositor;
|
use sctk::reexports::client::protocol::wl_compositor::WlCompositor;
|
||||||
|
@ -154,6 +155,9 @@ pub struct WindowHandle {
|
||||||
/// Whether the window is resizable.
|
/// Whether the window is resizable.
|
||||||
pub is_resizable: Cell<bool>,
|
pub is_resizable: Cell<bool>,
|
||||||
|
|
||||||
|
/// Whether the window has keyboard focus.
|
||||||
|
pub has_focus: Arc<AtomicBool>,
|
||||||
|
|
||||||
/// Allow IME events for that window.
|
/// Allow IME events for that window.
|
||||||
pub ime_allowed: Cell<bool>,
|
pub ime_allowed: Cell<bool>,
|
||||||
|
|
||||||
|
@ -187,6 +191,7 @@ impl WindowHandle {
|
||||||
env: &Environment<WinitEnv>,
|
env: &Environment<WinitEnv>,
|
||||||
window: Window<WinitFrame>,
|
window: Window<WinitFrame>,
|
||||||
size: Arc<Mutex<LogicalSize<u32>>>,
|
size: Arc<Mutex<LogicalSize<u32>>>,
|
||||||
|
has_focus: Arc<AtomicBool>,
|
||||||
pending_window_requests: Arc<Mutex<Vec<WindowRequest>>>,
|
pending_window_requests: Arc<Mutex<Vec<WindowRequest>>>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let xdg_activation = env.get_global::<XdgActivationV1>();
|
let xdg_activation = env.get_global::<XdgActivationV1>();
|
||||||
|
@ -209,6 +214,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),
|
||||||
|
has_focus,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -930,6 +930,10 @@ impl<T: 'static> EventProcessor<T> {
|
||||||
let window_id = mkwid(xev.event);
|
let window_id = mkwid(xev.event);
|
||||||
let position = PhysicalPosition::new(xev.event_x, xev.event_y);
|
let position = PhysicalPosition::new(xev.event_x, xev.event_y);
|
||||||
|
|
||||||
|
if let Some(window) = self.with_window(xev.event, Arc::clone) {
|
||||||
|
window.shared_state_lock().has_focus = true;
|
||||||
|
}
|
||||||
|
|
||||||
callback(Event::WindowEvent {
|
callback(Event::WindowEvent {
|
||||||
window_id,
|
window_id,
|
||||||
event: Focused(true),
|
event: Focused(true),
|
||||||
|
@ -1002,6 +1006,10 @@ impl<T: 'static> EventProcessor<T> {
|
||||||
event: WindowEvent::ModifiersChanged(ModifiersState::empty()),
|
event: WindowEvent::ModifiersChanged(ModifiersState::empty()),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if let Some(window) = self.with_window(xev.event, Arc::clone) {
|
||||||
|
window.shared_state_lock().has_focus = false;
|
||||||
|
}
|
||||||
|
|
||||||
callback(Event::WindowEvent {
|
callback(Event::WindowEvent {
|
||||||
window_id,
|
window_id,
|
||||||
event: Focused(false),
|
event: Focused(false),
|
||||||
|
|
|
@ -55,6 +55,7 @@ pub struct SharedState {
|
||||||
pub resize_increments: Option<Size>,
|
pub resize_increments: Option<Size>,
|
||||||
pub base_size: Option<Size>,
|
pub base_size: Option<Size>,
|
||||||
pub visibility: Visibility,
|
pub visibility: Visibility,
|
||||||
|
pub has_focus: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||||
|
@ -94,6 +95,7 @@ impl SharedState {
|
||||||
max_inner_size: None,
|
max_inner_size: None,
|
||||||
resize_increments: None,
|
resize_increments: None,
|
||||||
base_size: None,
|
base_size: None,
|
||||||
|
has_focus: true,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1602,6 +1604,10 @@ impl UnownedWindow {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
pub fn has_focus(&self) -> bool {
|
||||||
|
self.shared_state_lock().has_focus
|
||||||
|
}
|
||||||
|
|
||||||
pub fn title(&self) -> String {
|
pub fn title(&self) -> String {
|
||||||
String::new()
|
String::new()
|
||||||
}
|
}
|
||||||
|
|
|
@ -192,6 +192,9 @@ extern_methods!(
|
||||||
#[sel(isVisible)]
|
#[sel(isVisible)]
|
||||||
pub fn isVisible(&self) -> bool;
|
pub fn isVisible(&self) -> bool;
|
||||||
|
|
||||||
|
#[sel(isKeyWindow)]
|
||||||
|
pub fn isKeyWindow(&self) -> bool;
|
||||||
|
|
||||||
#[sel(isZoomed)]
|
#[sel(isZoomed)]
|
||||||
pub fn isZoomed(&self) -> bool;
|
pub fn isZoomed(&self) -> bool;
|
||||||
|
|
||||||
|
|
|
@ -1215,6 +1215,10 @@ impl WinitWindow {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
pub fn has_focus(&self) -> bool {
|
||||||
|
self.isKeyWindow()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn set_theme(&self, theme: Option<Theme>) {
|
pub fn set_theme(&self, theme: Option<Theme>) {
|
||||||
set_ns_theme(theme);
|
set_ns_theme(theme);
|
||||||
self.lock_shared_state("set_theme").current_theme = theme.or_else(|| Some(get_ns_theme()));
|
self.lock_shared_state("set_theme").current_theme = theme.or_else(|| Some(get_ns_theme()));
|
||||||
|
|
|
@ -393,6 +393,11 @@ impl Window {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn has_focus(&self) -> bool {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn set_theme(&self, _theme: Option<window::Theme>) {}
|
pub fn set_theme(&self, _theme: Option<window::Theme>) {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,6 +56,7 @@ impl<T> EventLoopWindowTarget<T> {
|
||||||
canvas: &Rc<RefCell<backend::Canvas>>,
|
canvas: &Rc<RefCell<backend::Canvas>>,
|
||||||
id: WindowId,
|
id: WindowId,
|
||||||
prevent_default: bool,
|
prevent_default: bool,
|
||||||
|
has_focus: Rc<RefCell<bool>>,
|
||||||
) {
|
) {
|
||||||
self.runner.add_canvas(RootWindowId(id), canvas);
|
self.runner.add_canvas(RootWindowId(id), canvas);
|
||||||
let mut canvas = canvas.borrow_mut();
|
let mut canvas = canvas.borrow_mut();
|
||||||
|
@ -65,7 +66,9 @@ impl<T> EventLoopWindowTarget<T> {
|
||||||
canvas.on_touch_end(prevent_default);
|
canvas.on_touch_end(prevent_default);
|
||||||
|
|
||||||
let runner = self.runner.clone();
|
let runner = self.runner.clone();
|
||||||
|
let has_focus_clone = has_focus.clone();
|
||||||
canvas.on_blur(move || {
|
canvas.on_blur(move || {
|
||||||
|
*has_focus_clone.borrow_mut() = false;
|
||||||
runner.send_event(Event::WindowEvent {
|
runner.send_event(Event::WindowEvent {
|
||||||
window_id: RootWindowId(id),
|
window_id: RootWindowId(id),
|
||||||
event: WindowEvent::Focused(false),
|
event: WindowEvent::Focused(false),
|
||||||
|
@ -73,7 +76,9 @@ impl<T> EventLoopWindowTarget<T> {
|
||||||
});
|
});
|
||||||
|
|
||||||
let runner = self.runner.clone();
|
let runner = self.runner.clone();
|
||||||
|
let has_focus_clone = has_focus.clone();
|
||||||
canvas.on_focus(move || {
|
canvas.on_focus(move || {
|
||||||
|
*has_focus_clone.borrow_mut() = true;
|
||||||
runner.send_event(Event::WindowEvent {
|
runner.send_event(Event::WindowEvent {
|
||||||
window_id: RootWindowId(id),
|
window_id: RootWindowId(id),
|
||||||
event: WindowEvent::Focused(true),
|
event: WindowEvent::Focused(true),
|
||||||
|
@ -191,6 +196,8 @@ impl<T> EventLoopWindowTarget<T> {
|
||||||
let runner_touch = self.runner.clone();
|
let runner_touch = self.runner.clone();
|
||||||
canvas.on_mouse_press(
|
canvas.on_mouse_press(
|
||||||
move |pointer_id, position, button, modifiers| {
|
move |pointer_id, position, button, modifiers| {
|
||||||
|
*has_focus.borrow_mut() = true;
|
||||||
|
|
||||||
// A mouse down event may come in without any prior CursorMoved events,
|
// A mouse down event may come in without any prior CursorMoved events,
|
||||||
// therefore we should send a CursorMoved event to make sure that the
|
// therefore we should send a CursorMoved event to make sure that the
|
||||||
// user code has the correct cursor position.
|
// user code has the correct cursor position.
|
||||||
|
|
|
@ -23,6 +23,7 @@ pub struct Window {
|
||||||
register_redraw_request: Box<dyn Fn()>,
|
register_redraw_request: Box<dyn Fn()>,
|
||||||
resize_notify_fn: Box<dyn Fn(PhysicalSize<u32>)>,
|
resize_notify_fn: Box<dyn Fn(PhysicalSize<u32>)>,
|
||||||
destroy_fn: Option<Box<dyn FnOnce()>>,
|
destroy_fn: Option<Box<dyn FnOnce()>>,
|
||||||
|
has_focus: Rc<RefCell<bool>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Window {
|
impl Window {
|
||||||
|
@ -42,7 +43,8 @@ impl Window {
|
||||||
|
|
||||||
let register_redraw_request = Box::new(move || runner.request_redraw(RootWI(id)));
|
let register_redraw_request = Box::new(move || runner.request_redraw(RootWI(id)));
|
||||||
|
|
||||||
target.register(&canvas, id, prevent_default);
|
let has_focus = Rc::new(RefCell::new(false));
|
||||||
|
target.register(&canvas, id, prevent_default, has_focus.clone());
|
||||||
|
|
||||||
let runner = target.runner.clone();
|
let runner = target.runner.clone();
|
||||||
let resize_notify_fn = Box::new(move |new_size| {
|
let resize_notify_fn = Box::new(move |new_size| {
|
||||||
|
@ -62,6 +64,7 @@ impl Window {
|
||||||
register_redraw_request,
|
register_redraw_request,
|
||||||
resize_notify_fn,
|
resize_notify_fn,
|
||||||
destroy_fn: Some(destroy_fn),
|
destroy_fn: Some(destroy_fn),
|
||||||
|
has_focus,
|
||||||
};
|
};
|
||||||
|
|
||||||
backend::set_canvas_size(
|
backend::set_canvas_size(
|
||||||
|
@ -399,6 +402,10 @@ impl Window {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
pub fn has_focus(&self) -> bool {
|
||||||
|
*self.has_focus.borrow()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn title(&self) -> String {
|
pub fn title(&self) -> String {
|
||||||
String::new()
|
String::new()
|
||||||
}
|
}
|
||||||
|
|
|
@ -773,6 +773,11 @@ impl Window {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
pub fn has_focus(&self) -> bool {
|
||||||
|
let window_state = self.window_state.lock().unwrap();
|
||||||
|
window_state.has_active_focus()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn title(&self) -> String {
|
pub fn title(&self) -> String {
|
||||||
let len = unsafe { GetWindowTextLengthW(self.window.0) } + 1;
|
let len = unsafe { GetWindowTextLengthW(self.window.0) } + 1;
|
||||||
let mut buf = vec![0; len as usize];
|
let mut buf = vec![0; len as usize];
|
||||||
|
|
|
@ -1022,6 +1022,16 @@ impl Window {
|
||||||
self.window.focus_window()
|
self.window.focus_window()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Gets whether the window has keyboard focus.
|
||||||
|
///
|
||||||
|
/// This queries the same state information as [`WindowEvent::Focused`].
|
||||||
|
///
|
||||||
|
/// [`WindowEvent::Focused`]: crate::event::WindowEvent::Focused
|
||||||
|
#[inline]
|
||||||
|
pub fn has_focus(&self) -> bool {
|
||||||
|
self.window.has_focus()
|
||||||
|
}
|
||||||
|
|
||||||
/// 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