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 <micah@photophore.systems>
This commit is contained in:
parent
085ae2a27e
commit
bad50d886a
|
@ -7,7 +7,7 @@ use cocoa::appkit::{
|
||||||
NSApp, NSApplication, NSApplicationActivationPolicyRegular, NSBackingStoreBuffered,
|
NSApp, NSApplication, NSApplicationActivationPolicyRegular, NSBackingStoreBuffered,
|
||||||
NSPasteboard, NSView, NSWindow, NSWindowStyleMask,
|
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 cocoa::foundation::{NSAutoreleasePool, NSPoint, NSRect, NSSize, NSString};
|
||||||
use core_foundation::runloop::{
|
use core_foundation::runloop::{
|
||||||
CFRunLoop, CFRunLoopTimer, CFRunLoopTimerContext, __CFRunLoopTimer, kCFRunLoopDefaultMode,
|
CFRunLoop, CFRunLoopTimer, CFRunLoopTimerContext, __CFRunLoopTimer, kCFRunLoopDefaultMode,
|
||||||
|
@ -43,6 +43,7 @@ impl WindowHandle {
|
||||||
pub fn is_open(&self) -> bool {
|
pub fn is_open(&self) -> bool {
|
||||||
self.state.window_inner.open.get()
|
self.state.window_inner.open.get()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl HasRawWindowHandle for WindowHandle {
|
unsafe impl HasRawWindowHandle for WindowHandle {
|
||||||
|
@ -284,6 +285,28 @@ impl<'a> Window<'a> {
|
||||||
self.inner.close();
|
self.inner.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn has_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_key_window: BOOL = msg_send![window, isKeyWindow];
|
||||||
|
let is_focused: BOOL = msg_send![view, isEqual: first_responder];
|
||||||
|
is_key_window == YES && is_focused == YES
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn 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) {
|
pub fn resize(&mut self, size: Size) {
|
||||||
if self.inner.open.get() {
|
if self.inner.open.get() {
|
||||||
// NOTE: macOS gives you a personal rave if you pass in fractional pixels here. Even
|
// NOTE: macOS gives you a personal rave if you pass in fractional pixels here. Even
|
||||||
|
|
|
@ -8,7 +8,7 @@ use winapi::um::winuser::{
|
||||||
AdjustWindowRectEx, CreateWindowExW, DefWindowProcW, DestroyWindow, DispatchMessageW,
|
AdjustWindowRectEx, CreateWindowExW, DefWindowProcW, DestroyWindow, DispatchMessageW,
|
||||||
GetDpiForWindow, GetMessageW, GetWindowLongPtrW, LoadCursorW, PostMessageW, RegisterClassW,
|
GetDpiForWindow, GetMessageW, GetWindowLongPtrW, LoadCursorW, PostMessageW, RegisterClassW,
|
||||||
ReleaseCapture, SetCapture, SetProcessDpiAwarenessContext, SetTimer, SetWindowLongPtrW,
|
ReleaseCapture, SetCapture, SetProcessDpiAwarenessContext, SetTimer, SetWindowLongPtrW,
|
||||||
SetWindowPos, 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,
|
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,
|
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,
|
WM_KEYUP, WM_LBUTTONDOWN, WM_LBUTTONUP, WM_MBUTTONDOWN, WM_MBUTTONUP, WM_MOUSEHWHEEL,
|
||||||
|
@ -770,6 +770,17 @@ impl Window<'_> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn has_focus(&mut self) -> bool {
|
||||||
|
let focused_window = unsafe { GetFocus() };
|
||||||
|
focused_window == self.state.hwnd
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn focus(&mut self) {
|
||||||
|
unsafe {
|
||||||
|
SetFocus(self.state.hwnd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn resize(&mut self, size: Size) {
|
pub fn resize(&mut self, size: Size) {
|
||||||
// To avoid reentrant event handler calls we'll defer the actual resizing until after the
|
// To avoid reentrant event handler calls we'll defer the actual resizing until after the
|
||||||
// event has been handled
|
// event has been handled
|
||||||
|
|
|
@ -102,6 +102,14 @@ impl<'a> Window<'a> {
|
||||||
self.window.set_mouse_cursor(cursor);
|
self.window.set_mouse_cursor(cursor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn has_focus(&mut self) -> bool {
|
||||||
|
self.window.has_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
|
/// 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].
|
/// access this context through [crate::Window::gl_context].
|
||||||
#[cfg(feature = "opengl")]
|
#[cfg(feature = "opengl")]
|
||||||
|
|
|
@ -359,6 +359,14 @@ impl<'a> Window<'a> {
|
||||||
self.inner.close_requested = true;
|
self.inner.close_requested = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn has_focus(&mut self) -> bool {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn focus(&mut self) {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn resize(&mut self, size: Size) {
|
pub fn resize(&mut self, size: Size) {
|
||||||
let scaling = self.inner.window_info.scale();
|
let scaling = self.inner.window_info.scale();
|
||||||
let new_window_info = WindowInfo::from_logical_size(size, scaling);
|
let new_window_info = WindowInfo::from_logical_size(size, scaling);
|
||||||
|
|
Loading…
Reference in a new issue