WIP - adds platform APIs for checking the top most window

This commit is contained in:
Mikayla Maki
2023-01-25 09:10:35 -08:00
parent a66a0cfd70
commit 426aeb7c5e
9 changed files with 126 additions and 5 deletions
+7
View File
@@ -21,6 +21,7 @@ use std::{
use anyhow::{anyhow, Context, Result};
use lazy_static::lazy_static;
use parking_lot::Mutex;
use pathfinder_geometry::vector::Vector2F;
use postage::oneshot;
use smallvec::SmallVec;
use smol::prelude::*;
@@ -865,6 +866,12 @@ impl MutableAppContext {
}
}
pub fn screen_position(&self, window_id: usize, view_position: &Vector2F) -> Option<Vector2F> {
self.presenters_and_platform_windows
.get(&window_id)
.map(|(_, window)| window.screen_position(view_position))
}
pub fn window_ids(&self) -> impl Iterator<Item = usize> + '_ {
self.cx.windows.keys().cloned()
}
+2 -1
View File
@@ -64,7 +64,7 @@ pub trait Platform: Send + Sync {
fn read_credentials(&self, url: &str) -> Result<Option<(String, Vec<u8>)>>;
fn delete_credentials(&self, url: &str) -> Result<()>;
fn set_cursor_style(&self, style: CursorStyle);
fn set_cursor_style(&self, style: CursorStyle, window_id: usize, screen_position: &Vector2F);
fn should_auto_hide_scrollbars(&self) -> bool;
fn local_timezone(&self) -> UtcOffset;
@@ -145,6 +145,7 @@ pub trait Window {
fn present_scene(&mut self, scene: Scene);
fn appearance(&self) -> Appearance;
fn on_appearance_changed(&mut self, callback: Box<dyn FnMut()>);
fn screen_position(&self, view_position: &Vector2F) -> Vector2F;
}
#[derive(Debug)]
+14 -1
View File
@@ -37,6 +37,7 @@ use objc::{
runtime::{Class, Object, Sel},
sel, sel_impl,
};
use pathfinder_geometry::vector::Vector2F;
use postage::oneshot;
use ptr::null_mut;
use std::{
@@ -695,7 +696,19 @@ impl platform::Platform for MacPlatform {
Ok(())
}
fn set_cursor_style(&self, style: CursorStyle) {
fn set_cursor_style(&self, style: CursorStyle, window_id: usize, screen_position: &Vector2F) {
let top_most = Window::window_id_under(screen_position);
if top_most.is_none() {
return;
}
if top_most.unwrap() != window_id {
return;
}
dbg!(top_most.unwrap(), window_id);
dbg!(style);
unsafe {
let cursor: id = match style {
CursorStyle::Arrow => msg_send![class!(NSCursor), arrowCursor],
@@ -258,6 +258,10 @@ impl platform::Window for StatusItem {
crate::Appearance::from_native(appearance)
}
}
fn screen_position(&self, _view_position: &Vector2F) -> Vector2F {
unimplemented!()
}
}
impl StatusItemState {
+30
View File
@@ -559,6 +559,26 @@ impl Window {
}
}
}
pub fn window_id_under(screen_position: &Vector2F) -> Option<usize> {
unsafe {
let app = NSApplication::sharedApplication(nil);
let point = NSPoint::new(screen_position.x() as f64, screen_position.y() as f64);
let window_number: NSInteger = msg_send![class!(NSWindow), windowNumberAtPoint:point belowWindowWithWindowNumber:0 as NSInteger];
// For some reason this API doesn't work when our two windows are on top of each other
let top_most_window: id = msg_send![app, windowWithWindowNumber: window_number];
dbg!(top_most_window);
let is_panel: BOOL = msg_send![top_most_window, isKindOfClass: PANEL_CLASS];
let is_window: BOOL = msg_send![top_most_window, isKindOfClass: WINDOW_CLASS];
if is_panel | is_window {
let id = get_window_state(&*top_most_window).borrow().id;
Some(id)
} else {
None
}
}
}
}
impl Drop for Window {
@@ -755,6 +775,16 @@ impl platform::Window for Window {
fn on_appearance_changed(&mut self, callback: Box<dyn FnMut()>) {
self.0.borrow_mut().appearance_changed_callback = Some(callback);
}
fn screen_position(&self, view_position: &Vector2F) -> Vector2F {
let self_borrow = self.0.borrow_mut();
unsafe {
let point = NSPoint::new(view_position.x() as f64, view_position.y() as f64);
let screen_point: NSPoint =
msg_send![self_borrow.native_window, convertPointToScreen: point];
vec2f(screen_point.x as f32, screen_point.y as f32)
}
}
}
impl WindowState {
+5 -1
View File
@@ -178,7 +178,7 @@ impl super::Platform for Platform {
Ok(())
}
fn set_cursor_style(&self, style: CursorStyle) {
fn set_cursor_style(&self, style: CursorStyle, _window_id: usize, _position: &Vector2F) {
*self.cursor.lock() = style;
}
@@ -332,6 +332,10 @@ impl super::Window for Window {
}
fn on_appearance_changed(&mut self, _: Box<dyn FnMut()>) {}
fn screen_position(&self, view_position: &Vector2F) -> Vector2F {
view_position.clone()
}
}
pub fn platform() -> Platform {
+8 -1
View File
@@ -316,7 +316,14 @@ impl Presenter {
break;
}
}
cx.platform().set_cursor_style(style_to_assign);
if let Some(screen_position) = cx.screen_position(self.window_id, position) {
cx.platform().set_cursor_style(
style_to_assign,
self.window_id,
&screen_position,
);
}
if !event_reused {
if pressed_button.is_some() {
@@ -209,6 +209,7 @@ impl EventDispatcher {
break;
}
}
cx.platform().set_cursor_style(style_to_assign);
if !event_reused {