Window full screen issue

I have made a unified Cocoa window in Xojo. To allow movement by dragging anywhere on the metal background, I use the MacWindowDragger module. The problem with this is that it has no window bounds checking, so you can drag the title bar of the window through and above the menubar at the top of the screen.

The solution I came up was to create a windows class in which the Moved event checks for the top of the window, like this:

i = GlobalStuff.WhichScreenIsWindowOn(self)

if < screen(i).top + 44 and i = 0 then //using MacWindowDragger you can drag the window throught the roof. Don’t! = screen(i).top + 44
elseif < screen(i).top + 22 and i > 0 then //on a secondary screen with no menubar = screen(i).top + 22
end if

That works well unless you invoke the full screen window. In full screen mode the is 0, and this code forces it down to 44

My kludgey solution is to use this line

if < screen(i).top + 44 and i = 0 and <> 0 then //using MacWindowDragger you can drag the window throught the roof. Don’t!

– note, I’ve added the caveat that if = 0, don’t adjust it

It works, but is inelegant and conceivably could break if the user really jammed the window upward quickly and managed to get the .top = 0.

I know I’m not the only one creating unified windows and useing MacWIndowDragger. Has anyone come up with a better solution?

So, you are letting the user drag the window around while in full screen mode? Is that correct?

What is the problem that you need help with? I don’t think I clearly understood it from reading your post… :frowning:

On a side note, I would like to know how you know what screen the window is on? I want to know!

At the WWDC keynote, Apple announced support for each monitor having its own menubar and Dock. This code would fail to function in that case. Offhand, I don’t have a solution for you that will work with 2013r1 or 2013r2.

What is MacWindowDragger? Google has no help.

In FullScreen mode you should filter out your window from even getting a Moved event. Maybe that’s what MacWindowDragger is doing. A workaround could be, in your Moved event code…

i = GlobalStuff.WhichScreenIsWindowOn(self) if thisWindowIsFullScreen then //set fullscreen coordinates always elseif < screen(i).top + 44 and i = 0 then .....

@Tristan Bellman-Greenwood

The drag of the window is not when in full screen mode (you can’t). It’s during normal operation.

I have a function that returns the screen the window is on (I don’t recall if I wrote this or someone else posted it).

Dim x As Integer
// Track the possible screens
Dim theScreen As Integer

For x = ScreenCount -1 DownTo 0
// Line split because of the list line wrap :-{ …
If w.Left >= Screen(x).Left And _
w.Left < (Screen(x).Left + Screen(x).Width) And _
w.Top >= Screen(x).Top And _
w.Top < (Screen(x).Top + Screen(x).Height) Then
theScreen = x
End If

Return theScreen


MacWindowDragger is a module that was posted to beta testers prior to Xojo release. I believe it was from one of the Xojo engineers (sorry, I forget whom – but thanks!).

Wish I could see that. Thought betas was just bugs n’ stuff. I’m not interested in testing the bleeding edge so it’d be disingenuous for me to join but I am tempted.

I checked a couple of my apps that do this sort of window dragging and it’s very simple using only MouseDown and MouseDrag. But I found it only works in Carbon apps, in Cocoa the window wiggles around. So anyways, there’s a setting on NSWindow just for this. Call it in the Open event and the whole window is draggable and respects the top region automatically. I don’t have a secondary monitor to test how that behaves and I don’t know how you’re doing fullscreen (Xojo method or declares). Either way I think just toggle this draggablility when you toggle fullscreen.

[code]soft declare sub setMovable lib “Cocoa.framework” selector “setMovableByWindowBackground:” (id As Ptr, doMove As Boolean)

setMovable(Ptr(self.Handle), True)[/code]

Spoke too soon. MacWindowDragger is in in feedback 18670.

Looks like it’s a workaround to setMovableByWindowBackground failing on certain window setups. Not sure though, it’s been marked fixed and metal windows drag fine for me with that single declare. Is the module still necessary?

[quote=20730:@doofus]Spoke too soon. MacWindowDragger is in in feedback 18670.

Looks like it’s a workaround to setMovableByWindowBackground failing on certain window setups. Not sure though, it’s been marked fixed and metal windows drag fine for me with that single declare. Is the module still necessary?[/quote]

If I recall correctly, setMovableByWindowBackground: treats Canvases as draggable, regardless of your intent.

You recall correctly : )

That project doesn’t actually use the dragging feature though. In Window1.MouseDown the test for ShouldDragWindow( self ) always returns false because isMovableByWindowBackground is never turned on. But turning it on then negates the effects of DragWindow( self ). I got it to work by commenting out the ShouldDrag test and then it drags as expected (but not on Canvases).

Another option is to just use setMovableByWindowBackground and in each Canvas toggle it Off in MouseEnter, On in MouseExit. This keeps the window out from under the menubar, allows dragging to other Spaces and Canvases are useable. Of course have it always off in fullscreen (but with the fullscreen declare example it doesn’t seem to matter).

This has all been very helpful, and it’s solved a problem I had trying to make a floating palette use the metal background (another thread in this forum).

I figure out how to do that, but as noted clicking on a splitter canvas dragged the window. Calling setMovableByWindowBackground with false and true on canvas enter/exit did that trick.

Thanks everyone.

I just discovered that Enter/Exit isn’t sufficient. If the mouse is down while moving in or out of a Canvas those events don’t fire and can leave the window in the opposite state you want. For a splitter control they should work ok but there’s still an unlikely case of dragging from outside the window onto the splitter then letting up and trying to drag, the window will move.

Not sure of a perfect solution yet. I wonder why Canvases are singled out as not respecting this setting?

There’s no idea of user intent. Some canvases are decorative and some have actual function.

I mean why does a Canvas act different than other controls in regards to this dragging… It’s because other controls return False for “mouseDownCanMoveWindow” and a Canvas returns True.

I don’t know if it’s possible to dynamically override this in a Canvas but you can dynamically make an NSView subclass that returns False and add that as the Canvas’ SubView. This blocks window dragging over a Canvas but clicks still fall to it’s normal mouse events.

Yes, this is what it boils down to. Picking one behavior breaks MouseDown/Drag/Up events, picking the other ends up with what we have today.

Dynamically subclassing one of these falls under the “don’t try this at home” and “warranty void if attempted” categories. You will have problems (if you get it to work at all).

Really? I do this in a couple of my apps and haven’t had any problems. I learned how to do it from NSImageView in MacOSLib where an NSView subclass is implemented with Xojo Shared methods then an instance made and added as the subview. I assumed anything in MacOSLib is kosher.

I meant trying to dynamically subclass the view returned from the Handle property (ie call objc_setClass) or perform swizzling of its methods.

There may be another way :: I was looking at the NS documentation last night (as I’m faced with a similar situation, although not in full screen)… I’ll try out my idea this morning (if I have time) and let you know.

Thanks Joe. Swizzling is what I was thinking of, won’t bother now.

Here’s a class for making a window background-draggable while blocking select controls from window dragging like so…

//window event Sub Open() FullDrag.applyToWindow(self, Canvas1, Canvas2) End Sub
minimal error checking of declares, cocoa only

Curious to see Sam’s idea.

it was a flop :frowning: