Constraining window positions in other applications in Cocoa? - cocoa

I'm relatively new to Cocoa development. I'm developing on Snow Leopard. I have a scenario in mind and I'm curious if the API supports it. I've not been able to find anything about it, so I assume its not possible. But I'm happy to be proved wrong.
Suppose I write an application that lives at the top of the screen just below the menu bar. The window floats, so it is always on top. This can be annoying, so one thing I had in mind was constraining other windows (especially those in other applications) so that they are below my application. Is there something in the API that would allow me to do that? To specify a maximum origin for all windows (except mine)?
Thanks.

There's no real supported way to do this. You could achieve something similar using the Accessibility API. You'd have to watch for window-moved notifications and shove the window back into the visibile area.

I don't think you can do that, you see, one of the cool things of a window's based UI is that you can stack Windows on top of others, in a desktop metafore.
Now, what you can do is a always on top window, using NSScreenSaverWindowLevel as the NSWindow level. One nice trick you can do is [window setLevel: NSScreenSaverWindowLevel+1], and it set's your window above the screensaver level.

Related

Why is moving a GUI window from the code discouraged?

Well, the title almost says it all : Why should I not move a GUI (e.g. Gtk) window on screen from the code ? In Gtk 3 there was an API for moving windows on screen, but it was removed in Gtk 4, because it is not good to move a window from code; only the user should do so (don't ask me to provide sources for that, I read it somewhere but have forgotten where and cannot find it). But I cannot think of any reason why it shouldn't be good, but of several reasons why it could be good, for example to restore the position of a window between application restarts. Could you please shed some light on this ?
The major reason why is that it can't possibly work cross-platform, so it is broken API by definition. That’s also why it was removed in GTK4. For example: this is impossible to implement when running on top of a Wayland session, since the protocol doesn't allow getting/setting global coordinates. If you still want to have something similar working, you'll have to call the specific platform API (for example, X11) for those platforms that you want to support.
On the reason why it’s not supported by some display protocols: it’s bad for UX and security. In terms of UX: some compositors can have special behavior because they need to work on a small device, or because they have a kiosk mode in which everything should always run fullscreen, or they provide a tiling experience. Applications positioning their windows themselves then tend to give unexpected behaviour. In terms of security: if you allow this, it’s technically possible for an application to reposition and resize itself so that it covers your screens while making itself transparent, without it being noticeable, which means it has the possibility of scraping all input.

SetWindowPos API - Backward resizing?

I'm using Windows's SetWindowPos API to try to 'crop' a part of a window so a user will only be able to see the RIGHT part of it.
Problem is, I can only 'crop' it, starting from the top left corner, and I would rather cropping a different part of the window which does not 'contain' the top left part.
As seen on the image below, what i'm trying to do is reverse the 'resizing' mechanism in such way that the window will 'hide' the Label1, and only show the Button1.
It is possible that I am not using the correct API for the job, If so, i'd love to be pointed toward the right one.
You need to move your controls on the Form for that to work. The window has a position and a size, which is all the window manager cares about. What is visible inside is your application's responsibility.
Your screenshot looks very VB6-ish. Do note that newer technologies, e.g. Windows Forms or WPF offer better support for what you are trying to do here.
If you have a window handle for the control, then you can place it outside its parent. Pass to SetWindowPos a negative value for the X coordinate.
Of course, the fact that the control cannot be seen does not mean it cannot be interacted with. The user can reach it with the keyboard if it accepts focus. So perhaps a better idea would be to hide and/or disable it. Use ShowWindow and EnableWindow to do that.
Then again, it's quite plausible that you won't be able to get a window handle. Many frameworks use controls that are not windowed. To interact with them you would need to use an automation framework such as UI Automation. Only you can know whether or not the target application supports automation.

Minimize-in-place - Do I need a custom framework

I want to create a system wide minimize-in-place feature that occurs when double-clicking the title bar of any visible window in layer 0.
It seems that this would be a really simple feature to re-implement... When a title-bar is double-clicked, just draw the title bar only. That's it. The problem is implimenting it in all applications. I think it requires writting a custom framework to override the behavior in AppKit? Maybe NSApplication, NSWindow or NSView?
How can I recreate minimize-in-place?
Is a framework my only choice? If I create a framework, can I replace the behavior of minimize in 3rd party apps?
Which framework do I need to override in order to intercept and recreate the default behavior of the minimize button?
More about minimize-in-place:
I am familiar with WindowShade by Unsanity, this is exactly what I want to create. Supposedly unsanity is working on a Lion version, but their track record is bismal. Minimize-in-place was a system feature way back in the days of OS 7 or 8. I have tried other utilities that try to replace this feature, and there aren't any that do minimize-in-place at a core system level like it needs to be done. Please don't offer utitlity suggestions, I am going to build my own.
I have built an Application that recreates minimize-in-place, but it's not good enough.
My Application semi-successfully recreates minimize-in-place by putting "placeholder" windows (belonging to my app) in place of the 3rd party windows when they get minimized to dock. When my window (title bar only) gets double-clicked, I close my window and restore the real window from the dock.
My custom app works perfectly, but there is a lot of application switching going on. I have optimized the switching between apps to be nearly seamless, but the fact remains that there is application switching going on every time a window title bar is double-clicked. The result of application switching is that menu bars switch back and forth, pallets of 3rd party apps hide themselves when my app takes focus, and the list goes on.
So, although I've built a concept app, this method isn't going to work as I'd like it to. Minimize-in-place needs to be implemented using some other method than building an Application, and I need help understanding how to do it.
What I know think I need to do. Suggestions and assistance welcome.
I think I need to write a custom framework that replaces AppKit? This seems overwhelming even though I only need a super-tiny portion of the code to be overridden? i.e. the core _minimize function whatever that may be.
When a title-bar of 3rd party window is double-clicked, just clip to the title bar and let the rest of the system function as normal. On un-minimize (double click 2nd time), set clip back to full window.
Simple right?
Thanks for any assistance/suggestions,
Chris

Kiosk Applications - OS X programming - Multiple monitors

I've learnt Cocoa + Objective C primarily for iPhone development, and I need to utilize this skill set to build a very basic kiosk application for OS X in a couple of days. The application is basically as follows :
The setup has two touch screen monitors, the app must be running full screen mode. The monitor on the right acts as a detail view to a list of options on the left. There are 3 options on the monitor on the left. Picking one will play a movie on the right, Picking two will take you to a quiz, Picking 3 will pull up a Webview.
The user may not use any other operations on the PC. (I've started reading about OS X application development and realized Cocoa provides a kiosk mode for these types of apps)
My questions briefly are
Firstly, any help on how to get my app running in a kiosk mode is much appreciated! I'm under a bit of a time crunch (2 days to get all this done, talk about life in startups!), so completely static content is fine, I'm slightly worried about how OS X will handle full screen mode if an app has been written in a smaller window size. (Scaling etc.)
Next, assuming there are two windows, one on each screen, how do I deal with focus? If the user suddenly gets bored with content on the right and touches the window on the left, the first touch will probably act to focus the window and the second will act as a click on the button. I'd like to avoid this scenario!)
What are the navigation paradigms in OS X ? I'm guessing it's not as simple as [navigationController pushViewController]? In short, how do I display a new view over an existing view?
Thanks,
Teja
Firstly, any help on how to get my app running in a kiosk mode is much appreciated!
http://developer.apple.com/library/mac/#technotes/KioskMode/
Next, assuming there are two windows, one on each screen, how do I deal with focus? If the user suddenly gets bored with content on the right and touches the window on the left, the first touch will probably act to focus the window and the second will act as a click on the button. I'd like to avoid this scenario!)
Click-through is the default. If you have any custom views, respond to acceptsFirstMouse: with YES to support click-through in them.
What are the navigation paradigms in OS X ?
Typically either window-based or source-list-based. Your application is atypical.
I'm guessing it's not as simple as [navigationController pushViewController]?
It's simpler and more complex at the same time. There is no stack to manage; you can have multiple windows up at the same time. It gets more complex when you want everything in one window (as in your kiosk-mode app), in which case you end up using tab views (with or without tabs) to enable the user to switch from one view to another.
In short, how do I display a new view over an existing view?
You don't. Layering one view over another in the same superview is barely supported at all in AppKit, and almost always wrong.
In a normal application, you should make multiple windows. In an app like yours, you'll need to use tab views. View controllers may help you here, although NSViewControllers are very different from UIViewControllers (as I mentioned, no view stack); they're more similar to NSWindowControllers.

Window docking advice for Mac

I'm from a Windows programming background when writing tools, but have been programming using Carbon and Cocoa for the past year. I have introduced myself to Mac by, I admit it, hiding from UI programming. I've been basically wapping my OpenGL code in a view, then staying in my comfort zone using my platform agnostic OpenGL C++ code as usual.
However, now I want to start porting one of my more sophisticated applications to Mac OS.
Typically I use the standard Visual Studio dockable MDI approach, which is excellent, but very Windows-like. From using a Mac primarily now for a while, I don't tend to see this sort of method used for Mac UIs. Even Xcode doesn't support the idea of drag and drop/dockable views, unfortunately. I see docked views with splitter panels, but that's about it.
The closest thing I've seen to the Visual Studio approach is Photoshop CS4, which is pretty nice.
So what is the general consensus on this? Is there are more Mac-like way of achieving the same thing that I haven't seen? If not, I'm happy to write a window manager in Cocoa myself, so that I can finally delve in an learn what looks like an excellent API.
Note, I don't want to use QT or any other cross-platform libraries. The whole point is that I want to make a Mac app look like a Mac app, leave the Windows app looking like a Windows app. I always find the cross-platform libraries tend to lose this effect, and when I see a native Mac UI, with fancy Cocoa transitions and animations, I always smile. It's also a good excuse for me to learn Cocoa.
That being said, if there is an Open Source Cocoa library to do this, I'd love to know about it! I'd love to see how someone else achieves this, and would help smooth the Cocoa learning curve.
Cheers,
Shane
UPDATE: I forgot to mention a critical point. I support plugins, which can have their own UI to display various plugin specific information. I don't know which plugins will be loaded and I don't know where their UI will live, if I don't support docking. I'd love to hear people's thoughts on this, specifically: How do I support a plugin view architecture, if the UI can't change? Where do I put the plugin views?
Coming from a Windows background, you feel the need to have docking windows, but is it really essential to the app? Apple's philosophy (in my opinion) is that the designer knows better than the user how things should look and work. For example, iTunes is a pretty sophisticated app, but it doesn't let you change the UI around, change the skin, etc., because Apple wants to keep it consistent. They offer the full view, the mini player, and a handful of different viewing options, but they don't let you pull the source list off into a separate window, or dock it in other positions. They think it should be on the left, so there it stays...
You said you "want to make a Mac app look like a Mac app", and as you pointed out, Mac apps don't tend to have docking windows. Therefore, implementing your own docking windows is probably a step in the wrong direction ;)
+1 to Ken's answer.
From a user perspective unless its integral to the app like it is in Adobe CS or Eclipse i want everything as concise as possible and all the different options and displays out of my way so i can focus on the document.
I think you will find with mac users that those who have the "user skill" to make use of rearranging panels will in most cases opt for hot key bindings instead, and those who dont have that level of "skill" youre just going to confuse.
I would recommend keeping it as simple as possible.
One thing that's common among many Mac apps is the ability to hide all the chrome and focus on your content. That's the point behind the "tic tac" toolbar control in the top right corner of many windows. A serious weakness of many docking UIs is that they expect you to have the window take up most of the screen, because the docked panels can obscure content. Even if docked panels are collapsable, the space left by them is often just wasted and filled with white space. So, if you build a docking panel into your interface, you should expect it to be visible most of the time. For example, iTunes' source list is clearly designed to be visible all the time, but you can double-click a playlist to open it in a new window.
To get used to the range of Mac controls, I'd suggest you try doing some serious work with some apps that don't have a cross-platform UI; for example, the iWork apps, Interface Builder or Preview. Take note of where controls appear and why—in toolbars, in bottom bars, in inspectors, in source lists/sidebars, in panels such as IB's Library or the Font and Color panels, in contextual HUDs. Don't forget the menu bar either. Get an idea of the feel of controls—their responsiveness, modality, sizing, grouping and consistency. Try to develop some taste—not everything is perfect; just try iCal if you want to have something to make fun of.
Note that there's no "one size fits all" for controls, which can be an issue with docking UIs. It's important to think about workflow: how commonly used the control would be, whether you can replace it with direct manipulation, whether a visible indication of its state is necessary, whether it's operable from the keyboard and mouse where appropriate, and so forth. Figure out how the control's placement and behavior lets the user work more efficiently.
As a simple example of example of a good versus bad control placement and behavior in otherwise-decent applications, compare image masking in OmniGraffle and Keynote. In OmniGraffle, this uses the Image inspector where you have to first click on an unlabeled button ("Natural size") in order to enable the appropriate controls, then adjust size and position away in a low-fidelity fashion with an image thumbnail or by typing percentages into fields. Trying to resize the frame directly behaves in a bizarre and counterintuitive fashion.
In Keynote, masking starts with a sensibly named menu item or toolbar item, uses a HUD which pops up the instant you click on a masked image and allows for direct manipulation including a sensible display of the extent of the image you're masking. While you're dragging a masked image around, it even follows the guides. Advanced users can ignore the HUD entirely, just double-clicking the image to toggle mask editing and using the handles for sizing. It should be easy to see, with a few caveats (e.g. the state of "Edit Mask" mode should be visible in the HUD rather than just from the image; the outer border of the image you're masking should be more effectively used) Keynote is substantially better at this, in part because it doesn't use an inspector.
That said, if you do have a huge number of options and the standard tabbed inspector layout doesn't work for you, check out the Omni Group's OmniInspector framework. Try to use it for good, and hopefully you'll figure out how to obsess over UI as much as you do over graphics now :-)
(running in slow motion, reaching out in panic) Nnnnnoooooooo!!!!!
:-) Seriously, as I mentioned in reply to Ken's excellent answer, trying to force a "Windowsism" on an OS X UI is definitely a bad idea. In my opinion, the biggest problem with Windows UI is third-party developers inventing new and inconsistent ways of presenting UI, rather than being consistent and following established conventions. To a Mac user, that's the sign of a terrible application. It's that way for a reason.
I encourage you to rethink your UI app's implementation from the ground up with the Mac OS in mind. If you've done your job well, the architecture and model (sans platform-specific implementation) should clearly translate to any platform.
In terms of UI, you've been using a Mac for a year, so you should have a pretty good idea of "the norm". If you have doubts, it's best to post a question specifically detailing what you need to present and your thoughts on how you might do it (or asking how if you have no idea).
Just don't whack your app with the ugly stick by forcing it to behave as if it were running in Windows when it's clearly not. That's the kiss of death for an app to Mac users.

Resources