Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement input focus for Mac & Windows #170

Merged
merged 9 commits into from
Mar 25, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 23 additions & 1 deletion src/macos/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -44,6 +44,7 @@ impl WindowHandle {
pub fn is_open(&self) -> bool {
self.state.window_inner.open.get()
}

}

unsafe impl HasRawWindowHandle for WindowHandle {
Expand Down Expand Up @@ -280,6 +281,27 @@ 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
dathinaios marked this conversation as resolved.
Show resolved Hide resolved
}
}

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 {
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
Expand Down
13 changes: 12 additions & 1 deletion src/win/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -770,6 +770,17 @@ impl Window<'_> {
}
}

pub fn has_input_focus(&mut self) -> bool {
let foreground_window = unsafe { GetForegroundWindow() };
dathinaios marked this conversation as resolved.
Show resolved Hide resolved
foreground_window == self.state.hwnd
}

pub fn set_input_focus(&mut self) {
unsafe {
SetFocus(self.state.hwnd);
}
}

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
Expand Down
8 changes: 8 additions & 0 deletions src/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,14 @@ impl<'a> Window<'a> {
self.window.set_mouse_cursor(cursor);
}

pub fn has_input_focus(&mut self) -> bool {
dathinaios marked this conversation as resolved.
Show resolved Hide resolved
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")]
Expand Down
8 changes: 8 additions & 0 deletions src/x11/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down