Add screen absolute mouse position for resizing window.#211
Add screen absolute mouse position for resizing window.#211Cmdv wants to merge 1 commit intoRustAudio:masterfrom
Conversation
|
For nih-plug with egui, or specifically egui_baseview, this fixes problem where the mouse slips out of the window during resize drag and it interrupts resizing. For reference, PR for egui-baseview that can be merged once this is merged: BillyDM/egui-baseview#24 |
| use cocoa::base::id; | ||
| use objc::{class, msg_send, sel, sel_impl}; | ||
|
|
||
| pub fn mouse_cursor_to_nscursor(cursor: MouseCursor) -> id { |
There was a problem hiding this comment.
Please move these mouse cursor changes into a separate PR.
| /// The logical coordinates of the mouse position in screen space (absolute) | ||
| /// This remains constant even when the window resizes, making it suitable | ||
| /// for drag operations that resize the window. | ||
| screen_position: Point, |
There was a problem hiding this comment.
Rather than adding monitor-relative coordinates to every event with a cursor position, I think it would be better to provide an explicit way to use the Window struct to convert between window-relative and monitor-relative coordinates (probably by just providing a method to get the current window location).
| // NSEvent::mouseLocation returns screen coordinates with Y=0 at BOTTOM | ||
| // We need to flip Y-axis to match Windows/X11 convention (Y=0 at TOP) | ||
| let screen_point: NSPoint = unsafe { | ||
| NSEvent::mouseLocation(event) |
There was a problem hiding this comment.
This is not the correct method to use. The locationInWindow method gets the location associated with a particular event, whereas mouseLocation is a static method that simply gets the current global mouse location without reference to any particular event:
This method is similar to the mouseLocationOutsideOfEventStream method of NSWindow. It returns the location regardless of the current event or pending events.
The fact that the NSEvent::mouseLocation method in the cocoa crate takes an NSEvent argument is misleading, as the argument is just ignored: https://github.com/servo/core-foundation-rs/blob/6f844cf1a1a18e25b70fcdf1bcdc458555bd2eff/cocoa/src/appkit.rs#L3129-L3131
Add screen-absolute mouse position and cursor setting support
Motivation
I understand this might not be accepted due to breaking changes but as it worked so well locally I thought I'd pass it upstream just incase 😄
When implementing custom window resize handles (or any drag operations that modify window geometry), window-relative mouse coordinates become unreliable. As the window resizes, the cursor position relative to the window constantly changes even when the mouse hasn't moved, making smooth drag calculations difficult or impossible.
Changes
Mouse Events - Screen Position Support:
Added
screen_position: Pointfield to:MouseEvent::CursorMovedMouseEvent::DragEnteredMouseEvent::DragMovedMouseEvent::DragDroppedmacOS Cursor Support:
set_mouse_cursor()for macOS (was previouslytodo!())macos/cursor.rsmodule with cursor conversionsMouseCursorvariants including resize cursors using privateNSCursorAPIsImplementation Details
macOS:
NSEvent::mouseLocation()for screen coordinatesNSView::convertPoint(window-relative) and global mouse locationWindows:
GetCursorPos()for screen-absolute coordinatesWM_MOUSEMOVEand drag eventsX11:
root_x/root_yfrom X11 events (already in screen space)Breaking Changes
This is a breaking API change. The following enum variants now have an additional
screen_positionfield:MouseEvent::CursorMoved { position, screen_position, modifiers }MouseEvent::DragEntered { position, screen_position, modifiers, data }MouseEvent::DragMoved { position, screen_position, modifiers, data }MouseEvent::DragDropped { position, screen_position, modifiers, data }Users will need to update pattern matches, either by:
MouseEvent::CursorMoved { position, screen_position, modifiers }MouseEvent::CursorMoved { position, modifiers, .. }