Changed the presenter to only send 'set_cursor_style' on the topmost window
co-authored-by: Antonio <antonio@zed.dev>
This commit is contained in:
parent
27a80a1c94
commit
45e4e3354e
7 changed files with 54 additions and 65 deletions
|
@ -866,10 +866,12 @@ impl MutableAppContext {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn screen_position(&self, window_id: usize, view_position: &Vector2F) -> Option<Vector2F> {
|
pub fn is_topmost_window_for_position(&self, window_id: usize, position: Vector2F) -> bool {
|
||||||
self.presenters_and_platform_windows
|
self.presenters_and_platform_windows
|
||||||
.get(&window_id)
|
.get(&window_id)
|
||||||
.map(|(_, window)| window.screen_position(view_position))
|
.map_or(false, |(_, window)| {
|
||||||
|
window.is_topmost_for_position(position)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn window_ids(&self) -> impl Iterator<Item = usize> + '_ {
|
pub fn window_ids(&self) -> impl Iterator<Item = usize> + '_ {
|
||||||
|
|
|
@ -64,7 +64,7 @@ pub trait Platform: Send + Sync {
|
||||||
fn read_credentials(&self, url: &str) -> Result<Option<(String, Vec<u8>)>>;
|
fn read_credentials(&self, url: &str) -> Result<Option<(String, Vec<u8>)>>;
|
||||||
fn delete_credentials(&self, url: &str) -> Result<()>;
|
fn delete_credentials(&self, url: &str) -> Result<()>;
|
||||||
|
|
||||||
fn set_cursor_style(&self, style: CursorStyle, window_id: usize, screen_position: &Vector2F);
|
fn set_cursor_style(&self, style: CursorStyle);
|
||||||
fn should_auto_hide_scrollbars(&self) -> bool;
|
fn should_auto_hide_scrollbars(&self) -> bool;
|
||||||
|
|
||||||
fn local_timezone(&self) -> UtcOffset;
|
fn local_timezone(&self) -> UtcOffset;
|
||||||
|
@ -145,7 +145,7 @@ pub trait Window {
|
||||||
fn present_scene(&mut self, scene: Scene);
|
fn present_scene(&mut self, scene: Scene);
|
||||||
fn appearance(&self) -> Appearance;
|
fn appearance(&self) -> Appearance;
|
||||||
fn on_appearance_changed(&mut self, callback: Box<dyn FnMut()>);
|
fn on_appearance_changed(&mut self, callback: Box<dyn FnMut()>);
|
||||||
fn screen_position(&self, view_position: &Vector2F) -> Vector2F;
|
fn is_topmost_for_position(&self, position: Vector2F) -> bool;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
|
|
@ -37,7 +37,6 @@ use objc::{
|
||||||
runtime::{Class, Object, Sel},
|
runtime::{Class, Object, Sel},
|
||||||
sel, sel_impl,
|
sel, sel_impl,
|
||||||
};
|
};
|
||||||
use pathfinder_geometry::vector::Vector2F;
|
|
||||||
use postage::oneshot;
|
use postage::oneshot;
|
||||||
use ptr::null_mut;
|
use ptr::null_mut;
|
||||||
use std::{
|
use std::{
|
||||||
|
@ -696,21 +695,18 @@ impl platform::Platform for MacPlatform {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_cursor_style(&self, style: CursorStyle, window_id: usize, screen_position: &Vector2F) {
|
fn set_cursor_style(&self, style: CursorStyle) {
|
||||||
if Some(window_id) == Window::window_id_under(screen_position) {
|
unsafe {
|
||||||
dbg!(screen_position, style);
|
let cursor: id = match style {
|
||||||
unsafe {
|
CursorStyle::Arrow => msg_send![class!(NSCursor), arrowCursor],
|
||||||
let cursor: id = match style {
|
CursorStyle::ResizeLeftRight => {
|
||||||
CursorStyle::Arrow => msg_send![class!(NSCursor), arrowCursor],
|
msg_send![class!(NSCursor), resizeLeftRightCursor]
|
||||||
CursorStyle::ResizeLeftRight => {
|
}
|
||||||
msg_send![class!(NSCursor), resizeLeftRightCursor]
|
CursorStyle::ResizeUpDown => msg_send![class!(NSCursor), resizeUpDownCursor],
|
||||||
}
|
CursorStyle::PointingHand => msg_send![class!(NSCursor), pointingHandCursor],
|
||||||
CursorStyle::ResizeUpDown => msg_send![class!(NSCursor), resizeUpDownCursor],
|
CursorStyle::IBeam => msg_send![class!(NSCursor), IBeamCursor],
|
||||||
CursorStyle::PointingHand => msg_send![class!(NSCursor), pointingHandCursor],
|
};
|
||||||
CursorStyle::IBeam => msg_send![class!(NSCursor), IBeamCursor],
|
let _: () = msg_send![cursor, set];
|
||||||
};
|
|
||||||
let _: () = msg_send![cursor, set];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -259,8 +259,8 @@ impl platform::Window for StatusItem {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn screen_position(&self, _view_position: &Vector2F) -> Vector2F {
|
fn is_topmost_for_position(&self, _: Vector2F) -> bool {
|
||||||
unimplemented!()
|
true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,9 +17,9 @@ use crate::{
|
||||||
use block::ConcreteBlock;
|
use block::ConcreteBlock;
|
||||||
use cocoa::{
|
use cocoa::{
|
||||||
appkit::{
|
appkit::{
|
||||||
CGPoint, NSApplication, NSBackingStoreBuffered, NSScreen, NSView, NSViewHeightSizable,
|
CGFloat, CGPoint, NSApplication, NSBackingStoreBuffered, NSScreen, NSView,
|
||||||
NSViewWidthSizable, NSWindow, NSWindowButton, NSWindowCollectionBehavior,
|
NSViewHeightSizable, NSViewWidthSizable, NSWindow, NSWindowButton,
|
||||||
NSWindowStyleMask,
|
NSWindowCollectionBehavior, NSWindowStyleMask,
|
||||||
},
|
},
|
||||||
base::{id, nil},
|
base::{id, nil},
|
||||||
foundation::{
|
foundation::{
|
||||||
|
@ -52,8 +52,6 @@ use std::{
|
||||||
time::Duration,
|
time::Duration,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::geometry::Vector2FExt;
|
|
||||||
|
|
||||||
const WINDOW_STATE_IVAR: &str = "windowState";
|
const WINDOW_STATE_IVAR: &str = "windowState";
|
||||||
|
|
||||||
static mut WINDOW_CLASS: *const Class = ptr::null();
|
static mut WINDOW_CLASS: *const Class = ptr::null();
|
||||||
|
@ -561,28 +559,6 @@ impl Window {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn window_id_under(screen_position: &Vector2F) -> Option<usize> {
|
|
||||||
unsafe {
|
|
||||||
let app = NSApplication::sharedApplication(nil);
|
|
||||||
|
|
||||||
let point = screen_position.to_ns_point();
|
|
||||||
let window_number: NSInteger = msg_send![class!(NSWindow), windowNumberAtPoint:point belowWindowWithWindowNumber:0];
|
|
||||||
|
|
||||||
// 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 {
|
impl Drop for Window {
|
||||||
|
@ -780,13 +756,34 @@ impl platform::Window for Window {
|
||||||
self.0.borrow_mut().appearance_changed_callback = Some(callback);
|
self.0.borrow_mut().appearance_changed_callback = Some(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn screen_position(&self, view_position: &Vector2F) -> Vector2F {
|
fn is_topmost_for_position(&self, position: Vector2F) -> bool {
|
||||||
let self_borrow = self.0.borrow_mut();
|
let window_bounds = self.bounds();
|
||||||
|
let self_borrow = self.0.borrow();
|
||||||
|
let self_id = self_borrow.id;
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
let point = view_position.to_ns_point();
|
let app = NSApplication::sharedApplication(nil);
|
||||||
|
|
||||||
|
// Convert back to bottom-left coordinates
|
||||||
|
let point = NSPoint::new(
|
||||||
|
position.x() as CGFloat,
|
||||||
|
(window_bounds.height() - position.y()) as CGFloat,
|
||||||
|
);
|
||||||
|
|
||||||
let screen_point: NSPoint =
|
let screen_point: NSPoint =
|
||||||
msg_send![self_borrow.native_window, convertPointToScreen: point];
|
msg_send![self_borrow.native_window, convertPointToScreen: point];
|
||||||
vec2f(screen_point.x as f32, screen_point.y as f32)
|
let window_number: NSInteger = msg_send![class!(NSWindow), windowNumberAtPoint:screen_point belowWindowWithWindowNumber:0];
|
||||||
|
let top_most_window: id = msg_send![app, windowWithWindowNumber: window_number];
|
||||||
|
|
||||||
|
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 topmost_window_id = get_window_state(&*top_most_window).borrow().id;
|
||||||
|
topmost_window_id == self_id
|
||||||
|
} else {
|
||||||
|
// Someone else's window is on top
|
||||||
|
false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -178,7 +178,7 @@ impl super::Platform for Platform {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_cursor_style(&self, style: CursorStyle, _window_id: usize, _position: &Vector2F) {
|
fn set_cursor_style(&self, style: CursorStyle) {
|
||||||
*self.cursor.lock() = style;
|
*self.cursor.lock() = style;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -333,8 +333,8 @@ impl super::Window for Window {
|
||||||
|
|
||||||
fn on_appearance_changed(&mut self, _: Box<dyn FnMut()>) {}
|
fn on_appearance_changed(&mut self, _: Box<dyn FnMut()>) {}
|
||||||
|
|
||||||
fn screen_position(&self, view_position: &Vector2F) -> Vector2F {
|
fn is_topmost_for_position(&self, _position: Vector2F) -> bool {
|
||||||
view_position.clone()
|
true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,7 @@ use std::{
|
||||||
ops::{Deref, DerefMut, Range},
|
ops::{Deref, DerefMut, Range},
|
||||||
sync::Arc,
|
sync::Arc,
|
||||||
};
|
};
|
||||||
|
use time::Instant;
|
||||||
|
|
||||||
pub struct Presenter {
|
pub struct Presenter {
|
||||||
window_id: usize,
|
window_id: usize,
|
||||||
|
@ -317,15 +318,8 @@ impl Presenter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dbg!("*******");
|
if cx.is_topmost_window_for_position(self.window_id, *position) {
|
||||||
dbg!(position);
|
cx.platform().set_cursor_style(style_to_assign);
|
||||||
dbg!(event_reused);
|
|
||||||
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 !event_reused {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue