From 2088ddc3969ad3c3e130b2b438306cd58f2bb2ef Mon Sep 17 00:00:00 2001 From: Dionysis Athinaios Date: Tue, 19 Mar 2024 15:42:50 +0000 Subject: [PATCH 1/8] Implement input focus for Mac --- src/macos/window.rs | 25 ++++++++++++++++++++++++- src/window.rs | 8 ++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/src/macos/window.rs b/src/macos/window.rs index c0412525..2d8eecd7 100644 --- a/src/macos/window.rs +++ b/src/macos/window.rs @@ -7,7 +7,7 @@ use cocoa::appkit::{ NSApp, NSApplication, NSApplicationActivationPolicyRegular, NSBackingStoreBuffered, NSPasteboard, NSView, NSWindow, NSWindowStyleMask, }; -use cocoa::base::{id, nil, NO, YES}; +use cocoa::base::{id, nil, BOOL, NO, YES}; use cocoa::foundation::{NSAutoreleasePool, NSPoint, NSRect, NSSize, NSString}; use core_foundation::runloop::{ CFRunLoop, CFRunLoopTimer, CFRunLoopTimerContext, __CFRunLoopTimer, kCFRunLoopDefaultMode, @@ -44,6 +44,7 @@ impl WindowHandle { pub fn is_open(&self) -> bool { self.state.window_inner.open.get() } + } unsafe impl HasRawWindowHandle for WindowHandle { @@ -280,6 +281,28 @@ impl<'a> Window<'a> { self.inner.close(); } + pub fn has_input_focus(&mut self) -> bool { + unsafe { + let view = self.inner.ns_view.as_mut().unwrap(); + let window: id = msg_send![view, window]; + if window == nil { return false; }; + let first_responder: id = msg_send![window, firstResponder]; + let is_focused: BOOL = msg_send![view, isEqual: first_responder]; + is_focused == YES + } + } + + pub fn set_input_focus(&mut self) { + unsafe { + let view = self.inner.ns_view.as_mut().unwrap(); + let window: id = msg_send![view, window]; + if window != nil { + let _: () = msg_send![window, makeKeyWindow]; + msg_send![window, makeFirstResponder:view] + } + } + } + pub fn resize(&mut self, size: Size) { if self.inner.open.get() { // NOTE: macOS gives you a personal rave if you pass in fractional pixels here. Even diff --git a/src/window.rs b/src/window.rs index 63e3f49a..1c449529 100644 --- a/src/window.rs +++ b/src/window.rs @@ -102,6 +102,14 @@ impl<'a> Window<'a> { self.window.set_mouse_cursor(cursor); } + pub fn has_input_focus(&mut self) -> bool { + self.window.has_input_focus() + } + + pub fn set_input_focus(&mut self) { + self.window.set_input_focus() + } + /// If provided, then an OpenGL context will be created for this window. You'll be able to /// access this context through [crate::Window::gl_context]. #[cfg(feature = "opengl")] From e59a630f184d75859ff666c2288bc72a52b5e2a8 Mon Sep 17 00:00:00 2001 From: Dionysis Athinaios Date: Tue, 19 Mar 2024 19:05:52 +0000 Subject: [PATCH 2/8] Add stubs for Windows and Linux --- src/win/window.rs | 8 ++++++++ src/x11/window.rs | 8 ++++++++ 2 files changed, 16 insertions(+) diff --git a/src/win/window.rs b/src/win/window.rs index ca8ec4cb..89431401 100644 --- a/src/win/window.rs +++ b/src/win/window.rs @@ -770,6 +770,14 @@ impl Window<'_> { } } + pub fn has_input_focus(&mut self) -> bool { + unimplemented!() + } + + pub fn set_input_focus(&mut self) { + unimplemented!() + } + pub fn resize(&mut self, size: Size) { // To avoid reentrant event handler calls we'll defer the actual resizing until after the // event has been handled diff --git a/src/x11/window.rs b/src/x11/window.rs index 90ec281f..adf012e4 100644 --- a/src/x11/window.rs +++ b/src/x11/window.rs @@ -370,6 +370,14 @@ impl<'a> Window<'a> { self.inner.close_requested = true; } + pub fn has_input_focus(&mut self) -> bool { + unimplemented!() + } + + pub fn set_input_focus(&mut self) { + unimplemented!() + } + pub fn resize(&mut self, size: Size) { let scaling = self.inner.window_info.scale(); let new_window_info = WindowInfo::from_logical_size(size, scaling); From be6c7e9cd56d82813122a7ecae0d51a5907ec59d Mon Sep 17 00:00:00 2001 From: Dionysis Athinaios Date: Tue, 19 Mar 2024 19:17:47 +0000 Subject: [PATCH 3/8] Remove unnecessary call to window --- src/macos/window.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/macos/window.rs b/src/macos/window.rs index 2d8eecd7..e12ce985 100644 --- a/src/macos/window.rs +++ b/src/macos/window.rs @@ -297,7 +297,6 @@ impl<'a> Window<'a> { let view = self.inner.ns_view.as_mut().unwrap(); let window: id = msg_send![view, window]; if window != nil { - let _: () = msg_send![window, makeKeyWindow]; msg_send![window, makeFirstResponder:view] } } From f2286a5f2e0b65c58f5e59f1eba6d8e3166a3962 Mon Sep 17 00:00:00 2001 From: Dionysis Athinaios Date: Thu, 21 Mar 2024 16:48:57 +0000 Subject: [PATCH 4/8] Implement input focus for Windows --- src/win/window.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/win/window.rs b/src/win/window.rs index 89431401..8362933a 100644 --- a/src/win/window.rs +++ b/src/win/window.rs @@ -8,7 +8,7 @@ use winapi::um::winuser::{ AdjustWindowRectEx, CreateWindowExW, DefWindowProcW, DestroyWindow, DispatchMessageW, GetDpiForWindow, GetMessageW, GetWindowLongPtrW, LoadCursorW, PostMessageW, RegisterClassW, ReleaseCapture, SetCapture, SetProcessDpiAwarenessContext, SetTimer, SetWindowLongPtrW, - SetWindowPos, TrackMouseEvent, TranslateMessage, UnregisterClassW, CS_OWNDC, + SetWindowPos, SetFocus, GetForegroundWindow, TrackMouseEvent, TranslateMessage, UnregisterClassW, CS_OWNDC, GET_XBUTTON_WPARAM, GWLP_USERDATA, IDC_ARROW, MSG, SWP_NOMOVE, SWP_NOZORDER, TRACKMOUSEEVENT, WHEEL_DELTA, WM_CHAR, WM_CLOSE, WM_CREATE, WM_DPICHANGED, WM_INPUTLANGCHANGE, WM_KEYDOWN, WM_KEYUP, WM_LBUTTONDOWN, WM_LBUTTONUP, WM_MBUTTONDOWN, WM_MBUTTONUP, WM_MOUSEHWHEEL, @@ -771,11 +771,14 @@ impl Window<'_> { } pub fn has_input_focus(&mut self) -> bool { - unimplemented!() + let foreground_window = unsafe { GetForegroundWindow() }; + foreground_window == self.state.hwnd } pub fn set_input_focus(&mut self) { - unimplemented!() + unsafe { + SetFocus(self.state.hwnd); + } } pub fn resize(&mut self, size: Size) { From 9f23fcf5d450755cb7a0997920e0694ff23fd378 Mon Sep 17 00:00:00 2001 From: Dionysis Athinaios Date: Sat, 23 Mar 2024 14:14:13 +0000 Subject: [PATCH 5/8] Add check for key window status --- src/macos/window.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/macos/window.rs b/src/macos/window.rs index e12ce985..805136f7 100644 --- a/src/macos/window.rs +++ b/src/macos/window.rs @@ -287,8 +287,9 @@ impl<'a> Window<'a> { let window: id = msg_send![view, window]; if window == nil { return false; }; let first_responder: id = msg_send![window, firstResponder]; + let is_key_window: BOOL = msg_send![window, isKeyWindow]; let is_focused: BOOL = msg_send![view, isEqual: first_responder]; - is_focused == YES + is_key_window == YES && is_focused == YES } } From a12c9c1c65415959f6460e519f72d5490058e2b9 Mon Sep 17 00:00:00 2001 From: Dionysis Athinaios Date: Mon, 25 Mar 2024 10:22:02 +0000 Subject: [PATCH 6/8] Rename to `has_focus` & `focus` --- src/macos/window.rs | 4 ++-- src/win/window.rs | 4 ++-- src/window.rs | 8 ++++---- src/x11/window.rs | 4 ++-- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/macos/window.rs b/src/macos/window.rs index 805136f7..2181760c 100644 --- a/src/macos/window.rs +++ b/src/macos/window.rs @@ -281,7 +281,7 @@ impl<'a> Window<'a> { self.inner.close(); } - pub fn has_input_focus(&mut self) -> bool { + pub fn has_focus(&mut self) -> bool { unsafe { let view = self.inner.ns_view.as_mut().unwrap(); let window: id = msg_send![view, window]; @@ -293,7 +293,7 @@ impl<'a> Window<'a> { } } - pub fn set_input_focus(&mut self) { + pub fn focus(&mut self) { unsafe { let view = self.inner.ns_view.as_mut().unwrap(); let window: id = msg_send![view, window]; diff --git a/src/win/window.rs b/src/win/window.rs index 8362933a..125b8b9a 100644 --- a/src/win/window.rs +++ b/src/win/window.rs @@ -770,12 +770,12 @@ impl Window<'_> { } } - pub fn has_input_focus(&mut self) -> bool { + pub fn has_focus(&mut self) -> bool { let foreground_window = unsafe { GetForegroundWindow() }; foreground_window == self.state.hwnd } - pub fn set_input_focus(&mut self) { + pub fn focus(&mut self) { unsafe { SetFocus(self.state.hwnd); } diff --git a/src/window.rs b/src/window.rs index 1c449529..0008b7ce 100644 --- a/src/window.rs +++ b/src/window.rs @@ -102,12 +102,12 @@ impl<'a> Window<'a> { self.window.set_mouse_cursor(cursor); } - pub fn has_input_focus(&mut self) -> bool { - self.window.has_input_focus() + pub fn has_focus(&mut self) -> bool { + self.window.has_focus() } - pub fn set_input_focus(&mut self) { - self.window.set_input_focus() + pub fn focus(&mut self) { + self.window.focus() } /// If provided, then an OpenGL context will be created for this window. You'll be able to diff --git a/src/x11/window.rs b/src/x11/window.rs index adf012e4..e0b29d57 100644 --- a/src/x11/window.rs +++ b/src/x11/window.rs @@ -370,11 +370,11 @@ impl<'a> Window<'a> { self.inner.close_requested = true; } - pub fn has_input_focus(&mut self) -> bool { + pub fn has_focus(&mut self) -> bool { unimplemented!() } - pub fn set_input_focus(&mut self) { + pub fn focus(&mut self) { unimplemented!() } From 8017059e30475148602e0ceafeefc2dee36d797b Mon Sep 17 00:00:00 2001 From: Dionysis Athinaios Date: Mon, 25 Mar 2024 10:43:28 +0000 Subject: [PATCH 7/8] Use GetFocus --- src/win/window.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/win/window.rs b/src/win/window.rs index 125b8b9a..bb62da96 100644 --- a/src/win/window.rs +++ b/src/win/window.rs @@ -8,7 +8,7 @@ use winapi::um::winuser::{ AdjustWindowRectEx, CreateWindowExW, DefWindowProcW, DestroyWindow, DispatchMessageW, GetDpiForWindow, GetMessageW, GetWindowLongPtrW, LoadCursorW, PostMessageW, RegisterClassW, ReleaseCapture, SetCapture, SetProcessDpiAwarenessContext, SetTimer, SetWindowLongPtrW, - SetWindowPos, SetFocus, GetForegroundWindow, TrackMouseEvent, TranslateMessage, UnregisterClassW, CS_OWNDC, + SetWindowPos, SetFocus, GetFocus, TrackMouseEvent, TranslateMessage, UnregisterClassW, CS_OWNDC, GET_XBUTTON_WPARAM, GWLP_USERDATA, IDC_ARROW, MSG, SWP_NOMOVE, SWP_NOZORDER, TRACKMOUSEEVENT, WHEEL_DELTA, WM_CHAR, WM_CLOSE, WM_CREATE, WM_DPICHANGED, WM_INPUTLANGCHANGE, WM_KEYDOWN, WM_KEYUP, WM_LBUTTONDOWN, WM_LBUTTONUP, WM_MBUTTONDOWN, WM_MBUTTONUP, WM_MOUSEHWHEEL, @@ -771,7 +771,7 @@ impl Window<'_> { } pub fn has_focus(&mut self) -> bool { - let foreground_window = unsafe { GetForegroundWindow() }; + let foreground_window = unsafe { GetFocus() }; foreground_window == self.state.hwnd } From 3e3a1ebdc59a7bff872682e0a3e634caffc2152d Mon Sep 17 00:00:00 2001 From: Dionysis Athinaios Date: Mon, 25 Mar 2024 21:43:13 +0000 Subject: [PATCH 8/8] Fix incorrectly named var --- src/win/window.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/win/window.rs b/src/win/window.rs index bb62da96..b0b72cbd 100644 --- a/src/win/window.rs +++ b/src/win/window.rs @@ -771,8 +771,8 @@ impl Window<'_> { } pub fn has_focus(&mut self) -> bool { - let foreground_window = unsafe { GetFocus() }; - foreground_window == self.state.hwnd + let focused_window = unsafe { GetFocus() }; + focused_window == self.state.hwnd } pub fn focus(&mut self) {