I searched the forum, but couldn’t find a discussion of modal windows for Cocoa targets. It’s my understanding that background windows receive mouse clicks even if they’re behind a modal window (which Carbon didn’t do). My question is how do I prevent this? I have a modal window that opens on top of my applications main window and I don’t want the user to interact with the main window while the modal one is up. As of right now, the user can move the window around and I don’t want this to happen.
I made the mistake of opening the modal window with regular .Show, be sure you’re using .ShowModal.
A modal window should prevent the user from entering data or interacting with the background window, but I believe the user can always drag it around. You know, in case it’s in the way of something more important behind it.
As a side note, in most cases a sheet is preferred to a separate modal window on Mac. ShowModalWithin will make it a sheet on Mac, and a modal window on Windows.
On Mac OS X, you should use .ShowModalWithin if the dialog is specific to that window and .ShowModal if the dialog is for the whole application…
.ShowModalWith would be used for a save dialog when closing a document window
.ShowModal would be used for a confirmation dialog when confirming the user wants to quit your application
Thanks for your response. I’m certainly guilty of using the .show method in the past, but that isn’t the case here. I can switch it over to a sheet window if that’s the only way. I’m just surprised that the behavior can’t be interrupted somehow.
I searched the forum, but couldn’t find a discussion of modal windows for Cocoa targets. It’s my understanding that background windows receive mouse clicks even if they’re behind a modal window (which Carbon didn’t do). My question is how do I prevent this? I have a modal window that opens on top of my applications main window and I don’t want the user to interact with the main window while the modal one is up. As of right now, the user can move the window around and I don’t want this to happen.[/quote]
You may want to remove the window bar, which makes the window plain box and therefore unmovable.
[code] Window1.Show
dim newStyle As UInt32 = 0 //no titlebar, not resizeable
'if Window1.Resizeable then
newStyle = 8 //no titlebar and resizeable
soft declare sub setStyleMask lib “Cocoa.framework” selector “setStyleMask:” (id As Ptr, mask As UInt32)
setStyleMask(Ptr(Window1.Handle), newStyle)
soft declare sub setLevel lib “Cocoa.framework” selector “setLevel:” (id As Ptr, windowLevel As Int32)
setLevel(Ptr(Window1.Handle), 5) //make it float[/code]
For some reason the same code in the open event of the window removes the shadow, so it is better in the event that shows it.
The window type is simply modal as I don’t want that window to be movable either. It is, in essence, a sheet window. I remember changing it from a sheet window in the past, but I can’t really remember why (I think it had something to do with the Windows version). I think the best bet is to make it a sheet window and troubleshoot the Windows side of things.
Apple dev library does not give any information about the value of constants. I did not have time to build a Swift project to get these values. But you are right, of course.
Yeah, the constants are fine if you’re using Objective-C or Swift, it only becomes an issue when you’re not!
Now with style masks, Apple give you a bread crumb…
NSTexturedBackgroundWindowMask = 1 << 8
If you use the Apple calculator, cmd-3 to get the programmers version and there is a button labeled “X<<Y”, enter in “1”, click the button and enter in “8”, press “=” and you’ll get “256” - There’s your constant.
NSTexturedBackgroundWindowMask = 256
Now someone smarter can make me look like a fool, by explaining that what this function means is that you’re shifting 1 bit by 8 places to 256.
Some of Apple’s other constants can be discovered by using some code Joe posted a while ago…
[code]Function frameworkConstant(frameworkName as string, constantName as string) As Ptr #if TargetCocoa then
Declare Function dlopen Lib “System” ( path As CString, mode As Integer ) As ptr
Declare Function dlsym Lib “System” ( handle As PTr, name As CString ) As ptr
Const RTLD_LAZY = 1
Const RTLD_GLOBAL = 8
Dim libPtr As ptr = dlopen( "/System/Library/Frameworks/" + frameWorkName + ".framework/" + frameworkName, RTLD_LAZY Or RTLD_GLOBAL )
If libPtr = Nil Then return nil
return dlsym( libPtr, constantName )
#endif
End Function
[/code]
You need to pass in the framework and the constant name, I seem to recall that there is a different method used in the MacOSLib. Once you get a return value, you’ll need to interrogate it to figure out what the data type is.
I misread your original post, Eric. Being able to move the window under the modal window appears to be standard Cocoa behavior. Michel and Sam’s thoughts on how you may be able to work around it are probably your best bet, but it doesn’t seem like this is something Apple really supports.
Of course, a Sheet window also allows the window to be moved while the sheet is displayed. On Windows, Sheet windows are displayed as movable modal.
[quote=161361:@Paul Lefebvre]I misread your original post, Eric. Being able to move the window under the modal window appears to be standard Cocoa behavior. Michel and Sam’s thoughts on how you may be able to work around it are probably your best bet, but it doesn’t seem like this is something Apple really supports.
Of course, a Sheet window also allows the window to be moved while the sheet is displayed. On Windows, Sheet windows are displayed as movable modal.[/quote]
On cocoa, I found no way to make a movable modal non movable. Any other kind of window can be made non movable by declare, except it does nothing when the window is Movable Modal.
The only way of having a display where the user cannot move anything and not be able to click behind is a full screen one.
[quote=160986:@Sam Rowlands]
Now someone smarter can make me look like a fool, by explaining that what this function means is that you’re shifting 1 bit by 8 places to 256.[/quote]
Your shifting the value 1 left 8 positions
&b00000001
shift left 1 becomes &b0000000010
shift left 1 becomes &b0000000100
shift left 1 becomes &b0000001000
shift left 1 becomes &b0000010000
shift left 1 becomes &b0000100000
shift left 1 becomes &b0001000000
shift left 1 becomes &b0010000000
shift left 1 becomes &b0100000000
Thanks for re-reading this. I think that’s why I went away from the sheet window (as it becomes a movable modal on Win). I’ll just have to figure something out!
I’m not sure why your post was deleted, but that seemed to do the trick! You mentioned this:
Window1.Show // Window1 is set Movable modal in the inspector
declare sub setMovable lib "Cocoa" selector "setMovable:" (obj_id as Ptr, flag as Boolean)
setMovable Ptr(Window1.handle), false
I see that you reply that this actually doesn’t work for movable modal type windows, but the one that I want to freeze is simply a document style so it works great. Thanks!
I’m not sure why your post was deleted, but that seemed to do the trick! You mentioned this:
Window1.Show // Window1 is set Movable modal in the inspector
declare sub setMovable lib "Cocoa" selector "setMovable:" (obj_id as Ptr, flag as Boolean)
setMovable Ptr(Window1.handle), false
I see that you reply that this actually doesn’t work for movable modal type windows, but the one that I want to freeze is simply a document style so it works great. Thanks![/quote]
Glad it worked. I deleted it after finding out the move freeze did not work for a movable modal. I thought you wanted a non movable modal.