How to get NSPopover to follow the mouse pointer correctly and ignore mouse events?

I would like to display an informational NSPopover that tracks a custom mouse cursor.

For this, I use NSTrackingArea to update the popover positioningRect when the mouseMoved event mouseMoved .

However, this has two drawbacks:

  • The cross follows the mouse with a slight delay. How can I reduce this delay to make the popover more glued to the mouse pointer?
  • When I move the mouse in the direction of popover, the mouseExited tracking method is mouseExited , which causes the popover to โ€œabsorbโ€ the mouse movement events, so that the mouseMoved tracking mouseMoved will no longer fires. How can I avoid popover popping up mouse events, or at least keep forwarding these events?

This question is very similar to Somehow around this NSTrackingArea quirk? , with the difference that I use NSPopover , so I have nothing to set ignoresMouseEvents on.

+5
source share
1 answer

I took a look at your problem. I could not fix the delay, but it can decrease if you set popover.animates to false .

Incorrect approach :

I was able to solve the mouseExited more popover problem by adding a new border (and shadowless) window on top of the other. trackingArea added to the transparent window, and popover is added to the original one. Depending on the transparent level windows, it is located above the popover, and therefore they cannot interfere with each other. In the gif below you can see the results of my tests:

example gif

Here is my code:

Mouse tracking:

 override func mouseMoved(with event: NSEvent) { let location = self.view.convert(event.locationInWindow, from: nil) popover.positioningRect.origin.x = location.x popover.positioningRect.origin.y = location.y } 

Custom window:

 transparentWindow.backgroundColor = NSColor.clear transparentWindow.isOpaque = false transparentWindow.styleMask = .borderless transparentWindow.makeKeyAndOrderFront(nil) 

Update 11/11/2016 :

I just read the question in the link you provided. There is a window for setting ignoresMouseEvents on. Even if NSPopover inherits from NSObject , you have a contentViewController that contains a view object that contains popovers window . (as explained here )

So just install

 popover.contentViewController?.view.window?.ignoresMouseEvents = true 

after displaying popover .

+2
source

Source: https://habr.com/ru/post/1259292/


All Articles