Skip to content

Add screen absolute mouse position for resizing window.#211

Open
Cmdv wants to merge 1 commit intoRustAudio:masterfrom
Cmdv:resize-window
Open

Add screen absolute mouse position for resizing window.#211
Cmdv wants to merge 1 commit intoRustAudio:masterfrom
Cmdv:resize-window

Conversation

@Cmdv
Copy link

@Cmdv Cmdv commented Oct 6, 2025

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: Point field to:

  • MouseEvent::CursorMoved
  • MouseEvent::DragEntered
  • MouseEvent::DragMoved
  • MouseEvent::DragDropped

macOS Cursor Support:

  • Implemented set_mouse_cursor() for macOS (was previously todo!())
  • Added new macos/cursor.rs module with cursor conversions
  • Supports all MouseCursor variants including resize cursors using private NSCursor APIs

Implementation Details

macOS:

  • Uses NSEvent::mouseLocation() for screen coordinates
  • Flips Y-axis from bottom-origin to top-origin for consistency with other platforms
  • Handles both NSView::convertPoint (window-relative) and global mouse location

Windows:

  • Uses GetCursorPos() for screen-absolute coordinates
  • Converts to logical coordinates using DPI scaling
  • Applied to both WM_MOUSEMOVE and drag events

X11:

  • Uses root_x/root_y from X11 events (already in screen space)
  • Converts to logical coordinates consistently with window-relative positions

Breaking Changes

This is a breaking API change. The following enum variants now have an additional screen_position field:

  • 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:

  • Adding the new field: MouseEvent::CursorMoved { position, screen_position, modifiers }
  • Using wildcard: MouseEvent::CursorMoved { position, modifiers, .. }

2025-10-06 14 19 01

SpruceCloud pushed a commit to SpruceCloud/egui-baseview-resizefix that referenced this pull request Feb 7, 2026
@SpruceCloud
Copy link

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 {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants