Skip to content

Commit bad50d8

Browse files
dathinaiosmicahrj
andauthored
Implement input focus for Mac & Windows (#170)
* Implement input focus for Mac * Add stubs for Windows and Linux * Remove unnecessary call to window * Implement input focus for Windows * Add check for key window status * Rename to `has_focus` & `focus` * Use GetFocus * Fix incorrectly named var --------- Co-authored-by: Micah Johnston <[email protected]>
1 parent 085ae2a commit bad50d8

File tree

4 files changed

+52
-2
lines changed

4 files changed

+52
-2
lines changed

src/macos/window.rs

+24-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use cocoa::appkit::{
77
NSApp, NSApplication, NSApplicationActivationPolicyRegular, NSBackingStoreBuffered,
88
NSPasteboard, NSView, NSWindow, NSWindowStyleMask,
99
};
10-
use cocoa::base::{id, nil, NO, YES};
10+
use cocoa::base::{id, nil, BOOL, NO, YES};
1111
use cocoa::foundation::{NSAutoreleasePool, NSPoint, NSRect, NSSize, NSString};
1212
use core_foundation::runloop::{
1313
CFRunLoop, CFRunLoopTimer, CFRunLoopTimerContext, __CFRunLoopTimer, kCFRunLoopDefaultMode,
@@ -43,6 +43,7 @@ impl WindowHandle {
4343
pub fn is_open(&self) -> bool {
4444
self.state.window_inner.open.get()
4545
}
46+
4647
}
4748

4849
unsafe impl HasRawWindowHandle for WindowHandle {
@@ -284,6 +285,28 @@ impl<'a> Window<'a> {
284285
self.inner.close();
285286
}
286287

288+
pub fn has_focus(&mut self) -> bool {
289+
unsafe {
290+
let view = self.inner.ns_view.as_mut().unwrap();
291+
let window: id = msg_send![view, window];
292+
if window == nil { return false; };
293+
let first_responder: id = msg_send![window, firstResponder];
294+
let is_key_window: BOOL = msg_send![window, isKeyWindow];
295+
let is_focused: BOOL = msg_send![view, isEqual: first_responder];
296+
is_key_window == YES && is_focused == YES
297+
}
298+
}
299+
300+
pub fn focus(&mut self) {
301+
unsafe {
302+
let view = self.inner.ns_view.as_mut().unwrap();
303+
let window: id = msg_send![view, window];
304+
if window != nil {
305+
msg_send![window, makeFirstResponder:view]
306+
}
307+
}
308+
}
309+
287310
pub fn resize(&mut self, size: Size) {
288311
if self.inner.open.get() {
289312
// NOTE: macOS gives you a personal rave if you pass in fractional pixels here. Even

src/win/window.rs

+12-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use winapi::um::winuser::{
88
AdjustWindowRectEx, CreateWindowExW, DefWindowProcW, DestroyWindow, DispatchMessageW,
99
GetDpiForWindow, GetMessageW, GetWindowLongPtrW, LoadCursorW, PostMessageW, RegisterClassW,
1010
ReleaseCapture, SetCapture, SetProcessDpiAwarenessContext, SetTimer, SetWindowLongPtrW,
11-
SetWindowPos, TrackMouseEvent, TranslateMessage, UnregisterClassW, CS_OWNDC,
11+
SetWindowPos, SetFocus, GetFocus, TrackMouseEvent, TranslateMessage, UnregisterClassW, CS_OWNDC,
1212
GET_XBUTTON_WPARAM, GWLP_USERDATA, IDC_ARROW, MSG, SWP_NOMOVE, SWP_NOZORDER, TRACKMOUSEEVENT,
1313
WHEEL_DELTA, WM_CHAR, WM_CLOSE, WM_CREATE, WM_DPICHANGED, WM_INPUTLANGCHANGE, WM_KEYDOWN,
1414
WM_KEYUP, WM_LBUTTONDOWN, WM_LBUTTONUP, WM_MBUTTONDOWN, WM_MBUTTONUP, WM_MOUSEHWHEEL,
@@ -770,6 +770,17 @@ impl Window<'_> {
770770
}
771771
}
772772

773+
pub fn has_focus(&mut self) -> bool {
774+
let focused_window = unsafe { GetFocus() };
775+
focused_window == self.state.hwnd
776+
}
777+
778+
pub fn focus(&mut self) {
779+
unsafe {
780+
SetFocus(self.state.hwnd);
781+
}
782+
}
783+
773784
pub fn resize(&mut self, size: Size) {
774785
// To avoid reentrant event handler calls we'll defer the actual resizing until after the
775786
// event has been handled

src/window.rs

+8
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,14 @@ impl<'a> Window<'a> {
102102
self.window.set_mouse_cursor(cursor);
103103
}
104104

105+
pub fn has_focus(&mut self) -> bool {
106+
self.window.has_focus()
107+
}
108+
109+
pub fn focus(&mut self) {
110+
self.window.focus()
111+
}
112+
105113
/// If provided, then an OpenGL context will be created for this window. You'll be able to
106114
/// access this context through [crate::Window::gl_context].
107115
#[cfg(feature = "opengl")]

src/x11/window.rs

+8
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,14 @@ impl<'a> Window<'a> {
359359
self.inner.close_requested = true;
360360
}
361361

362+
pub fn has_focus(&mut self) -> bool {
363+
unimplemented!()
364+
}
365+
366+
pub fn focus(&mut self) {
367+
unimplemented!()
368+
}
369+
362370
pub fn resize(&mut self, size: Size) {
363371
let scaling = self.inner.window_info.scale();
364372
let new_window_info = WindowInfo::from_logical_size(size, scaling);

0 commit comments

Comments
 (0)