mirror of
https://github.com/zed-industries/zed.git
synced 2024-11-08 07:35:01 +03:00
Merge pull request #2054 from zed-industries/notification-mouse-events
Notification mouse events
This commit is contained in:
commit
94b2f8e07f
@ -178,6 +178,21 @@ impl MouseMovedEvent {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Default)]
|
||||
pub struct MouseExitedEvent {
|
||||
pub position: Vector2F,
|
||||
pub pressed_button: Option<MouseButton>,
|
||||
pub modifiers: Modifiers,
|
||||
}
|
||||
|
||||
impl Deref for MouseExitedEvent {
|
||||
type Target = Modifiers;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.modifiers
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum Event {
|
||||
KeyDown(KeyDownEvent),
|
||||
@ -186,6 +201,7 @@ pub enum Event {
|
||||
MouseDown(MouseButtonEvent),
|
||||
MouseUp(MouseButtonEvent),
|
||||
MouseMoved(MouseMovedEvent),
|
||||
MouseExited(MouseExitedEvent),
|
||||
ScrollWheel(ScrollWheelEvent),
|
||||
}
|
||||
|
||||
@ -197,6 +213,7 @@ impl Event {
|
||||
Event::ModifiersChanged { .. } => None,
|
||||
Event::MouseDown(event) | Event::MouseUp(event) => Some(event.position),
|
||||
Event::MouseMoved(event) => Some(event.position),
|
||||
Event::MouseExited(event) => Some(event.position),
|
||||
Event::ScrollWheel(event) => Some(event.position),
|
||||
}
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ use crate::{
|
||||
keymap_matcher::Keystroke,
|
||||
platform::{Event, NavigationDirection},
|
||||
KeyDownEvent, KeyUpEvent, Modifiers, ModifiersChangedEvent, MouseButton, MouseButtonEvent,
|
||||
MouseMovedEvent, ScrollDelta, ScrollWheelEvent, TouchPhase,
|
||||
MouseExitedEvent, MouseMovedEvent, ScrollDelta, ScrollWheelEvent, TouchPhase,
|
||||
};
|
||||
use cocoa::{
|
||||
appkit::{NSEvent, NSEventModifierFlags, NSEventPhase, NSEventType},
|
||||
@ -221,6 +221,16 @@ impl Event {
|
||||
modifiers: read_modifiers(native_event),
|
||||
})
|
||||
}),
|
||||
NSEventType::NSMouseExited => window_height.map(|window_height| {
|
||||
Self::MouseExited(MouseExitedEvent {
|
||||
position: vec2f(
|
||||
native_event.locationInWindow().x as f32,
|
||||
window_height - native_event.locationInWindow().y as f32,
|
||||
),
|
||||
pressed_button: None,
|
||||
modifiers: read_modifiers(native_event),
|
||||
})
|
||||
}),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
@ -66,6 +66,14 @@ const NSNormalWindowLevel: NSInteger = 0;
|
||||
#[allow(non_upper_case_globals)]
|
||||
const NSPopUpWindowLevel: NSInteger = 101;
|
||||
#[allow(non_upper_case_globals)]
|
||||
const NSTrackingMouseEnteredAndExited: NSUInteger = 0x01;
|
||||
#[allow(non_upper_case_globals)]
|
||||
const NSTrackingMouseMoved: NSUInteger = 0x02;
|
||||
#[allow(non_upper_case_globals)]
|
||||
const NSTrackingActiveAlways: NSUInteger = 0x80;
|
||||
#[allow(non_upper_case_globals)]
|
||||
const NSTrackingInVisibleRect: NSUInteger = 0x200;
|
||||
#[allow(non_upper_case_globals)]
|
||||
const NSWindowAnimationBehaviorUtilityWindow: NSInteger = 4;
|
||||
|
||||
#[repr(C)]
|
||||
@ -164,6 +172,10 @@ unsafe fn build_classes() {
|
||||
sel!(mouseMoved:),
|
||||
handle_view_event as extern "C" fn(&Object, Sel, id),
|
||||
);
|
||||
decl.add_method(
|
||||
sel!(mouseExited:),
|
||||
handle_view_event as extern "C" fn(&Object, Sel, id),
|
||||
);
|
||||
decl.add_method(
|
||||
sel!(mouseDragged:),
|
||||
handle_view_event as extern "C" fn(&Object, Sel, id),
|
||||
@ -316,6 +328,7 @@ enum ImeState {
|
||||
struct WindowState {
|
||||
id: usize,
|
||||
native_window: id,
|
||||
kind: WindowKind,
|
||||
event_callback: Option<Box<dyn FnMut(Event) -> bool>>,
|
||||
activate_callback: Option<Box<dyn FnMut(bool)>>,
|
||||
resize_callback: Option<Box<dyn FnMut()>>,
|
||||
@ -337,7 +350,6 @@ struct WindowState {
|
||||
ime_state: ImeState,
|
||||
//Retains the last IME Text
|
||||
ime_text: Option<String>,
|
||||
accepts_first_mouse: bool,
|
||||
}
|
||||
|
||||
struct InsertText {
|
||||
@ -422,6 +434,7 @@ impl Window {
|
||||
let window = Self(Rc::new(RefCell::new(WindowState {
|
||||
id,
|
||||
native_window,
|
||||
kind: options.kind,
|
||||
event_callback: None,
|
||||
resize_callback: None,
|
||||
should_close_callback: None,
|
||||
@ -437,7 +450,6 @@ impl Window {
|
||||
scene_to_render: Default::default(),
|
||||
renderer: Renderer::new(true, fonts),
|
||||
last_fresh_keydown: None,
|
||||
accepts_first_mouse: options.kind == WindowKind::PopUp,
|
||||
traffic_light_position: options
|
||||
.titlebar
|
||||
.as_ref()
|
||||
@ -470,8 +482,6 @@ impl Window {
|
||||
native_window.setTitlebarAppearsTransparent_(YES);
|
||||
}
|
||||
|
||||
native_window.setAcceptsMouseMovedEvents_(YES);
|
||||
|
||||
native_view.setAutoresizingMask_(NSViewWidthSizable | NSViewHeightSizable);
|
||||
native_view.setWantsBestResolutionOpenGLSurface_(YES);
|
||||
|
||||
@ -494,8 +504,25 @@ impl Window {
|
||||
}
|
||||
|
||||
match options.kind {
|
||||
WindowKind::Normal => native_window.setLevel_(NSNormalWindowLevel),
|
||||
WindowKind::Normal => {
|
||||
native_window.setLevel_(NSNormalWindowLevel);
|
||||
native_window.setAcceptsMouseMovedEvents_(YES);
|
||||
}
|
||||
WindowKind::PopUp => {
|
||||
// Use a tracking area to allow receiving MouseMoved events even when
|
||||
// the window or application aren't active, which is often the case
|
||||
// e.g. for notification windows.
|
||||
let tracking_area: id = msg_send![class!(NSTrackingArea), alloc];
|
||||
let _: () = msg_send![
|
||||
tracking_area,
|
||||
initWithRect: NSRect::new(NSPoint::new(0., 0.), NSSize::new(0., 0.))
|
||||
options: NSTrackingMouseEnteredAndExited | NSTrackingMouseMoved | NSTrackingActiveAlways | NSTrackingInVisibleRect
|
||||
owner: native_view
|
||||
userInfo: nil
|
||||
];
|
||||
let _: () =
|
||||
msg_send![native_view, addTrackingArea: tracking_area.autorelease()];
|
||||
|
||||
native_window.setLevel_(NSPopUpWindowLevel);
|
||||
let _: () = msg_send![
|
||||
native_window,
|
||||
@ -965,7 +992,6 @@ extern "C" fn handle_view_event(this: &Object, _: Sel, native_event: id) {
|
||||
|
||||
let window_height = window_state_borrow.content_size().y();
|
||||
let event = unsafe { Event::from_native(native_event, Some(window_height)) };
|
||||
|
||||
if let Some(event) = event {
|
||||
match &event {
|
||||
Event::MouseMoved(
|
||||
@ -985,7 +1011,11 @@ extern "C" fn handle_view_event(this: &Object, _: Sel, native_event: id) {
|
||||
.detach();
|
||||
}
|
||||
|
||||
Event::MouseMoved(_) if !is_active => return,
|
||||
Event::MouseMoved(_)
|
||||
if !(is_active || window_state_borrow.kind == WindowKind::PopUp) =>
|
||||
{
|
||||
return
|
||||
}
|
||||
|
||||
Event::MouseUp(MouseButtonEvent {
|
||||
button: MouseButton::Left,
|
||||
@ -1408,7 +1438,7 @@ extern "C" fn accepts_first_mouse(this: &Object, _: Sel, _: id) -> BOOL {
|
||||
unsafe {
|
||||
let state = get_window_state(this);
|
||||
let state_borrow = state.as_ref().borrow();
|
||||
return state_borrow.accepts_first_mouse as BOOL;
|
||||
return state_borrow.kind == WindowKind::PopUp;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -360,6 +360,21 @@ impl Presenter {
|
||||
self.last_mouse_moved_event = Some(event.clone());
|
||||
}
|
||||
|
||||
Event::MouseExited(event) => {
|
||||
// When the platform sends a MouseExited event, synthesize
|
||||
// a MouseMoved event whose position is outside the window's
|
||||
// bounds so that hover and cursor state can be updated.
|
||||
return self.dispatch_event(
|
||||
Event::MouseMoved(MouseMovedEvent {
|
||||
position: event.position,
|
||||
pressed_button: event.pressed_button,
|
||||
modifiers: event.modifiers,
|
||||
}),
|
||||
event_reused,
|
||||
cx,
|
||||
);
|
||||
}
|
||||
|
||||
Event::ScrollWheel(e) => mouse_events.push(MouseEvent::ScrollWheel(MouseScrollWheel {
|
||||
region: Default::default(),
|
||||
platform_event: e.clone(),
|
||||
|
Loading…
Reference in New Issue
Block a user