andlabs
andlabs

Reputation: 11588

How do I initiate a user mouse-driven move or resize for custom window borders on OS X 10.8+ on a borderless window when the event comes to a subview?

I have a borderless window whose sole subview, which is always the size of the window (constrained by Auto Layout), is a third party component. That component wants to be able to notify me, when a mouseDown: has occurred in certain areas that is up to its discretion, to tell the OS to initiate a user-driven move or resize of the window (as if it wasn't borderless). It also wants to decide the operation (move or resize) to use in question. This last bit is partially because on all other OSs that I have this code running on, I have to specify those operations. (If necessary, I can change the rules for when such an event can be triggered, or how; this depends on what changes are necessary.)

I know about setting the window to be moveable from the background, but I need to be in control of when the move happens. It also does not handle resizes.

I know about -[NSWindow performWindowDragWithEvent:], however there are two problems:

I can implement my own loop, but then that leads to the question of how to query Auto Layout for the window's constrained minimum and maximum size. I don't see any methods for this in NSWindow; only methods for setting your own minimum and maximum size... Plus, I would need to know how to handle certain edge cases. For instance, what happens if there are two monitors, arranged vertically, with the menubar in between, and the mouse crosses the menubar while dragging?

There is sample code on Apple about moving, but it doesn't handle resizing and it doesn't take the edge cases into consideration.

I could also look at what GTK+ or Qt do...

Or is there some other option I am missing?

Thanks.

Upvotes: 4

Views: 260

Answers (1)

Ken Thomases
Ken Thomases

Reputation: 90531

For determining the limits of the window size from auto layout, I think you can temporarily add height and width constraints to the content view. First, make the constraints try to make the view zero-sized at priority NSLayoutPriorityDragThatCanResizeWindow (510). Then, call -fittingSize on the view. Then change the constraints so they try to make the view very large and repeat. Then, remove the constraints.

I don't think the window or view will actually resize due to those constraints unless you call -layout... methods. If necessary, you may need to record the window's original frame and restore it after measuring. You can disable screen updates around the whole process to avoid any UI flashing/flickering.

For the other stuff, I think you'll just have to do it manually. Use -performWindowDragWithEvent: where you can (for moving, on 10.11+). You'll just have to experiment to determine the behavior of the edge cases and replicate it.

Upvotes: 3

Related Questions