Toggle global window Mac

I’ve searched the forum, Googled, and even ChatGPT’d.

I was hoping to be able to add an option to toggle the main window between global floating and document (or any other that would work), but no luck so far. I see other programs like VLC can do it.

I had high hopes when ChatGPT hallucinated this solution:

MainWindow.Type = DesktopWindow.Types.GlobalFloating

Sadly, it appears to be a read-only attribute.

I’m running on an M1 Mac.

Do I have to create two windows of each type (global and document) and then only show one or the other? That seems like a lot of work for something that seems should be as simple as OpenAIs hallucinated solution.

Thanks.

You could do this with Declares. Here’s the NSWindow attribute:

Thank you Eric.

I’m encouraged that there appears to be a more accessible solution. Sadly, I failed to mention that I am not a professional programmer by any stretch. I would classify myself as an intermediate hobbyist at best. About half the time, I rely on ChatGPT to request code and then use that as a learning opportunity. It’s a challenging approach, as ChatGPT seems to be a little confused about Xojo and the various code updates over the past couple of years.

I will take your message as yet another opportunity to research and learn. However, if you’re feeling gracious and would care to take pity on a train wreck like myself, I would greatly appreciate any guidance regarding the Xojo code to achieve this. My preliminary attempts have fallen short.

Many thanks.

Oh! Hey! I got it. Thanks for the nudge in the right direction. This was my first declare and use of the Cocoa API. Bumpy ride, but I finally got there.

Thanks again!

1 Like

You’re welcome! Glad that was enough of a hint, because now you’ve picked up a new skill. :trophy:

My goal exactly.

FYI, in the end, I was unable to figure out the NSWindow.Level command directly, but with your guidance regarding the proper approach and verbiage, I was able to refine my searches and ran across a similar Xojo Forum entry that led me to this solution:

soft declare sub setLevel lib "Cocoa" selector "setLevel:" (id As Ptr, windowLevel As Int32)
setLevel(Ptr(MainWindow.Handle), 5) //make it float

I couldn’t find any documentation on the “setLevel:” command as opposed to “NSWindow.Level”, but I’m so green at this point, they might be the same thing and I just don’t get the connection. Regardless, it’s simple, it works, and now I have a whole bunch of new stuff to try to learn with Cocoa.

-Scott

Here’s the Apple documentation for NSWindow.level

If I may share some advice from someone who’s spent a LOT of time working with macOS declares and API.

  1. Use a module and external methods, these not only allow for the declares to be reused, but also help keep maintenance to a minimum.

  2. Future self will appreciate you giving yourself hints to which specific API you’re using. Many of Apple’s API share the same name, but work on different classes and or take different parameters. I settled on className_functionName “NSWindow_setLevel”. If Xojo ever decides to support typeAliases, this can be gratefully simplified, but so far they keep refusing to do so.

  3. There is a slight performance penalty for using “Cocoa” as this is an umbrella framework, instead try to use the actual framework name. In this case you’re calling the “AppKit” framework.

  4. AFAIK, Xojo is using Objective-C messaging to communicate with system frameworks, this is why you need to add “set” to the name, if you want to match the documentation, you can set the name of the external method to be “NSWindow_level”, while keeping the selector “setLevel:”, you can even use the extends keyword before passing in the NSWindowLevel so it can operate more like it does in Obj-C or Swift.

  5. Use constants for the values, these can be hard to track down, you may have to read .h files for the framework, or with some more declares you can ask the OS what some constants actually are. kCGUtilityWindowLevelKey is going to help you more in the future than the number 5 will, especially as constant values can and do change over time, and across CPUs. A prime example is alignment.center has different values on Intel and Apple Silicon.

  6. There is a field with external methods, Description, include the version compatibility information in that field, do it now. Apple’s APIs change rapidly, so you need to know which ones are supported on which version of the OS. Using the wrong API will no longer crash your application, it sends your application into limp mode, its still running, but things just stop working. There’s some declares I’ve shared in this forum which can re-activate crash on NSException.

  7. Read the API changes from WWDC events from now on to find out which APIs have been deprecated, and what the replacements are. Move away from deprecated API as soon as feasible, often Apple lets them rot before removing, i.e. they stop working correctly, you waste a ton of time trying to figure out why…

  8. Once you get deep into it, you might expect to be able to access all of Apple’s frameworks. Some will need to be loaded first (like using the actual video player instead of Xojo’s custom one), and AFAIK some are Swift only. I think @Greg_O has done something with accessing Swift objects with Xojo.

  9. Swizzling is cool! Once you learn how to do this, you can actually override some of the Xojo framework and bend it to your will. I always imagine being scolded by a Xojo engineer for this, but you know what, at least that part of my app is now consistent with Apple’s Mac apps.

  10. Watch out for PRIVATE & Deprecated API, at some point you’re going to start translating shared Objective-C or Swift code over to Xojo declares, double check each API you convert, because you don’t want to waste time with a deprecated API or a PRIVATE API. PRIVATE APIs will get you into trouble with the App Store and once you start using 'em, it’s hard to stop, especially when the public API is pure garbage :wink:

  11. Declares are a great feature of Xojo and what allowed me to continue using it for as long as I did, but for the most part you’re on your own and Xojo lacks many features that could really help. Learning Declares and Apple’s API will benefit the transition to Swift or Objective-C as you’re now learning the same frameworks that you’ll be using when you move up to these languages.

2 Likes

I forgot… If you’d like to see an example of just how much you can “power up” your Xojo made applications with Declares, check out the demo app from App Kit 2021 - Building Better Mac Applications

All good advice. I will also drop in here that the nascent macOSLib project is an excellent resource for this stuff. It’s a large, structured collection of macOS Declares that give you access to a lot of functionality missing from Xojo. It’s a little out of date in some areas, and thus some stuff doesn’t always work, but if you stick to the fundamentals you’ll be very pleasantly surprised. Your window level Declare is already in there, for example, right next to a long list of other goodies.

That said, because it is a moribund project and rather large, it may be a lot to take on all at once especially if you are new to Declares, as you will be constantly referring to Apple’s documentation and occasionally troubleshooting out-of-date code. Bookmark it for later!

Had to look that word up!

Not unlike a Declare when you need functionality that isn’t in your language. :wink:

1 Like

Wow! This list goes to 11! Thank you very much. (I hope the reference to This is Spinal Tap isn’t lost on you.)

Great advice. I have copied every word into my programming journal. I’m sure I’ll refer to it often.

1 Like

Thank you. I had not seen this resource before. Looks intriguing.

1 Like

Excellent. Thanks again!

(It also appears I need to learn better forum etiquette and limit my replies to a single response with quotes from previous posts. I’ll try to do better in the future.)

1 Like