In Norway (and I guess around the rest of the world) now is the time between Christmas and New Year’s. The Norwegians call the time romjul. Rom in Norwegian typically means rum, the distilled beverage. However, rom can also mean “room” or “space” and that’s what it means in this context, the time between Christmas and New Year’s Day. Therefore, I affectionately call this time, “Space Christmas” hoping to evoke a campy sci-fi feel for the time, usually to some Norwegians chagrin. It seems to have stuck though as I’ve heard Norwegian in the halls of Trolltech use this phrase as well.
Anyway, the point is that this is traditionally a down time when people are out doing other things. Sometimes people do check blogs during this time though, so I decided to spotlight on a couple of things in Qt/Mac that are in Qt 4.4.0. Both of these are little things that are no where near as earth-shattering as any of big features, but I think they are worth mentioning.
The first is something that I’ve sorely missed in Qt, and others have as well too I’m sure, proper support of proxy icons. A proxy icon is a nice feature of Mac OS X that allows you to put an icon in the title bar of a window to act as a “proxy” in drag operations. This turns out be extremely useful once you know about it. You can also do a Command+Click on it and it will show a pop-up menu with a path to where the item is on disk. This is very handy too when you want to make sure which file you happen to be editing. More information on proxy icons can be found at Apple’s Developer Website.
Astute readers of Qt Quarterly will remember this article where I talk about some of the events that were added in Qt 4. One was the Qt::IconDrag event, which allowed one to emulate the proxy icon. However, it was only emulation and it was a lot of work for something that I think most people wouldn’t bother doing unless they really were concerned about their Mac OS X application. I know of one person, besides me, that actually did this.
So, we needed an API that allowed you to get set the proxy icon, but also was worthwhile for people to use it in cross-platform code. It seems we found it with QWidget::windowFilePath property. This will associate a file path with a window, on all platforms it will do also set the window title of the window to the filename including the [*] token so that it behaves well with QWidget::windowModified property. If you still want control over the title bar, that’s OK, just set the QWidget::windowTitle property and it will use that. Oh yes, on Mac OS X you get the added benefit of a proxy icon if the path exists.
That means that you can take out old code like this:
QString shownName;
if (fileName.isEmpty())
shownName = "untitled.txt";
else
shownName = QFileInfo(fileName).fileName();
setWindowTitle(tr("%1[*] - %2").arg(shownName).arg(tr("Rich Text")));
setWindowModified(false);
With something like:
QString shownName = fileName;
if (fileName.isEmpty())
shownName = "untitled.txt";
setWindowFilePath(shownName);
setWindowModified(false);
Granted it may not seem like much, but if you’ve written a lot of application saving and loading code, it’s less to write and you get a real proxy icon for free (as shown below) with no code on your part.
So, that’s the first thing and anyone writing Qt code can take advantage of it. The second is very Mac OS X specific and shouldn’t affect the vast majority of users out there, but co-workers have asked about the change, so I thought I would say a few words on it here. In the course of my bug fixing, I changed Qt applications to no longer make themselves the front application anymore on start-up. For most applications that you launch via Finder, the Dock, Xcode, or Launch Services (which implies QDesktopServices) you should see no difference. If you are launching an application by executing it directly, you may need to tell it to raise if you want that application to take precedence over the current application. This is to be more in line with all the other applications on Mac OS X (feel free to experiment). The main idea is not to grab focus away from the main application, which can be annoying. If you really want to people to turn their attention to your app you can use something like QApplication::alert which will bounce the icon on the dock on Mac OS X and do similar attention grabbing tricks on other platforms. This at least allows people to finish their current thought before switching to that application.
Anyway, there’s a spotlight on some things to expect in Qt 4.4. I hope your find use for them.
Happy Space Christmas!
18 Responses to “Spotlight on Little Things”
Hi Trenton!
I really appreciate all those little details put into the Mac Version by you guys!
Thank you also for pointing them out in this blog, such things are easily overseen when reading the docs.
Nils
Thanks, Nils!
We *do* try to document such things in the changelog, but changelogs for pre-release software is always murky at best (I don’t know if one was even included in the tech preview). I thought these were nice little things that could be easily overlooked, hence the spotlight ![]()
Hi,
you seem to be a Mac expert, however I would like to ask about Windows,
where I’ve noticed something similar in Explorer folder windows… (in Windows XP)
When you right-click on the folder icon in the upper left corner, you get the popup menu
of the actual folder, not the window menu. Also the icon can be dragged, for e.g. to create
its shortcut on the Desktop.
It is probably just a hack made by responding to some non-client window messages,
I don’t recall seeing it anywhere in the API documentation. And it also doesn’t exist in Vista anymore.
However, maybe it could be possible for Qt to implement it on Windows the way Explorer does,
setting QWidget::windowFilePath would make the window icon behave like its shell object, supporting
the right-click popup menu and file drag ‘n drop operations, just like on the Mac
Milan
Thanks for that second thing! It was driving me nuts in my app as I frequently launch several apps at a time, and expect the last-launched to be frontmost. Can you convince the Perforce authors to fix P4V?
Happy New (Space) Year!
To mimak:That’s good feedback. I haven’t done any Windows coding in a long while though and there are other Trolls here that know more about Windows look and feel. My suggestion would be to file it as a suggestion at: http://trolltech.com/developer/bugreport-form with the same information, then it will get to the right people.
To Rob W: Thanks, glad you like the change
I don’t have any influence over P4V, but you could suggest to them that they can ask for the patch though (it’s a one-liner).
Great!
With the QWidget::windowFilePath property, I should be able to pull out a nice slab of code - especially given that it’s a property, as I can bind it directly to a key via my managed data / document API!
If only QSpinBox’s frame and focus looked right….
Anyway, thanks!
Hrmm, am I that one person, besides you, that you knew actually did the proxy icon?
Anyways, it seems a slew of bugs I’ve encountered in the Qt 4.3 series are all getting fixed in Qt 4.4.0. How exciting. I’ve never jumpd on the snapshot wagon before, but it seems almost certain tonight I’ll do just that and start using the snapshops. Two comments:
1) It would be great if Trolltech could include a page in the document about how to make your Qt app more XXXX like, where XXX could be OSX, Vista, whatever. Qt makes your app cross platform, but developers need to take some extra steps to make the app feels especially native, and having a document that summarizes all this in one place would be quite useful.
2) Is there a better way to running off the custom snapshots other than downloading the full tarball each time and doing a recompile? I’m thinking rsync, which I’ve never toyed with before, because downloading and doing a clean build of each Qt snapshot would be incredibly painful. I’d like to hack up a simple updateQtSnapshot type bash script…
Aidan - I couldn’t agree with you more about QSpinBox on the Mac. It’s the one supplied Qt widget that looks TERRIBLE. And here I’m hoping Trolltech starts supporting other semi standard widgets like search boxes and line edits with round corners while retaining that sunken appearance. I guess one can only dream.
Will, I understand your frustration about wanting make you Qt app more native. Ideally getting documentation is the best solution; the guidelines written for the platform is a good starting point though (that’s why I linked to proxy icons mentioned in the Apple guidelines). At least for the Mac OS X things, I try to use the same terms in the Qt documentation as well, so it’s possible to find it. It’s an ocean of stuff to be sure, but that’s what indexed searches are for. We also had some information about bring applications to Mac during devdays here: http://chaos.troll.no/~ahanssen/devdays2007/BringingYourAppToTheMac.pdf , it’s aimed at beginners, but there may be some things in there you may find useful.
Good metaphors should also get propagated up to examples as well. Ideally offering a “higher level” of an interface (e.g., a document-based interface that takes care of creating the windows and title bars for you) would insulate you more from such differences. This moves Qt more into a “framework” than a “toolkit,” but needs to be considered carefully.
As to ugly spinbox’s I’m aware of them. If you guys have specific issues (and not just “it looks” ugly), file some bugs with them and we’ll see if we can’t get something done about it for 4.4.
Thanks for the quick response Trenton. I also appreciate the link to the pdf. I read through it and I’m happy to say I’m making use of everything talked about there, except the deployqt thing which I can’t find online. I currently statically link with Qt so I guess I don’t need deployqt. To this day I’m confused why anyone would want to dynamically link against Qt (aka embed a copy of the frameworks in the bundle). My impression is that by linking statically only the parts I use are copied over. That said, I’m curious if this is adversely effectively my load times (aka the time it takes to start my app from a cold boot) and if by linking dynamically frameworks would be loaded as they are used, thus my app would feel more snappy since it would start up quicker.
I’ve already voiced my requests about more Mac like behavior/compatibility through widgets, but in case my trackers ever get lost in the ether my main widget gripes aside from the spinbox appearance and the lack of a native search line edit with rounded corners is that Qt doesn’t provide a nice purple question mark help button like those seen throughout OSX, as well as native bevel button support.
Anyways, I’ve really taken notice of your attention to Mac details and appreciate the work you’ve put into Qt/Mac. I’ve been here from the start of Qt/Mac, what was it, I think back around 2002-2003 and since then Qt has definately changed a lot from being almost a toy on the Mac to now a real professional solution for cross-platform development.
Hi Will, I’ve had an example showing how to create a native-looking main window similar to Mail sitting around for a while, and I went ahead and added it to the 4.4 branch today. You should find it in demos/macmainwindow in tonight’s snapshot. One of the things it shows is how to embed a native search line edit inside a Qt application. It still has some rough edges, feel free to nitpick
(I know for one thing that the unified tool bar needs some work, we’ll get that done for 4.4.)
Deployqt is secretly hidden away at http://labs.trolltech.com/blogs/2007/08/23/deploying-mac-applications-without-the-hassle/ . We’ll probably turn it into solution or include it in Qt at some point. I would say that the main benefits of linking dynamically are that you can load plugins (such as accessibility plugins) and that you can replace the Qt libraries without relinking the application.
Trenton & Morten: nice job! However, is there a way to do transparent windows in QT, like those in the iLife suite?
Erik, you can always set the transparency of a window with QWidget::setWindowTransparency(), but I guess you mean the “Heads Up Display” or HUD windows. These are not available at all in Carbon
You will have to write some Cocoa code to get them for the moment, but they should be able to co-exist with your Qt windows (haven’t tried it myself). When Qt will be based on Cocoa, it should be possible, but we’ll cross that bridge when we are farther along on in that process.
Yes, the HUD windows. Hmm, so apparently you cannot set the background color of a Carbon window to a color with an alpha component? I did try setWindowTransparency, but it gives a white (or white-striped) background. However, can you use Carbon/QT inside a Cocoa window? Because that’s what I’d like to do with a HUD display…
I should have said setWindowOpacity()
Shows that I should double check my comments against the Qt documentation.
This is more into technical details, but Qt puts its widgets as children of the Carbon windows content view, which as far as I know (don’t quote me on it though) is always opaque. You can set a black QPalette on your window and adjust the window opacity and you’ll get closer to the look. You cannot put a Carbon view (and therefore a Qt widget) into a Cocoa window. They will exist fine as separate windows (with its own set of caveats). If you want a pure Carbon HUD window, you’ll need to emulate it yourself I’m afraid. As I said above, hopefully when Qt sits on top of Cocoa, it should be possible to do this without emulating.
I thought I tried that, but apparently not, as it works
Last question does QWidget have something like NSPanel’s setMovableByWindowBackground? I couldn’t find it, but the window opacity shows that I sometimes overlook flags
And yes, I’m asking this because I want(ed) to use/emulate a HUD window.
Erik. Currently no. This is kind of an architectural difference between Qt and the Apple toolkits. QWidget always thinks you want the mouse, so anytime you click in the window, Carbon asks what part of the widget is clickable and we return the the entire widget. This stops the “asynchronous drag.” Of course, if you aren’t adverse to writing some Carbon code, you could handle the kEventControlGetPartRegion before Qt and return a different region for kControlClickableMetaPart. I think that’s all that is required. Of course, it might be easier to do something in the mouseMoveEvent() since you are already on the emulation route.
This is very welcome. I implemented a proxyicon with Jambi. There was a slight issue: I couldn’t get a right click to register on the icon so for now I just have left click bringing up the menu. At any rate it will be nice not to have to worry about it (assuming the new stuff becomes usable in jambi)
While I’m on the subject of OSX and jambi, it would be nice if there was a way (or the way was apparent) to use
void qt_mac_set_menubar_icons(bool enable)
in jambi.
