Popups are a can of worms

Published Wednesday December 19th, 2007
10 Comments on Popups are a can of worms
Posted in Graphics View, KDE, Labs, Qt

Hm, that title sounds funny with no associated context.

We’re implementing popup support in Graphics View. This is the result of an outstanding bug, or rather essential missing functionality, in the Widgets on Canvas project: support for embedded popups. I.e., popups that pop out of widgets that are embedded into a QGraphicsScene. Such as the QComboBox popup list, the QMenus of a QMenuBar, the context menu in QLineEdit. I could go on. Popups are everywhere! (AAaaarggh….) The bug is easy to see. Add a combobox to a scene, then click on it. As of a few days ago, the popup will show up at the right spot. But you’ll soon uncover the problem. It’s not a popup. It’s just a widget. And uh, plain widgets aren’t half way as cool at being a popup as popups are.

#include <qtgui>

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8"));

    QComboBox *box = new QComboBox;
    box->addItem("Mandag"); box->addItem("Tirsdag"); box->addItem("Onsdag");
    box->addItem("Torsdag"); box->addItem("Fredag"); box->addItem("Lørdag");
    box->addItem("Søndag");

    QGraphicsScene scene;
    scene.addWidget(box)->show();

    QGraphicsView view(&scene);
    view.show();

    return app.exec();
}

This is crazy, when you think of it. First we thought QGraphicsWidget would be fine. From a framework POV, it made perfect sense. We add support for layouts and widget-like properties, and you can write your own widgets to put inside a scene. Then some bright fellow said “what about widgets people already spent time writing, do they have to _port_ them to QGraphicsWidget?”. We all knew the answer, which was an undisputable “yes and no”. Yes, you can, and that should be quite easy, but no, you shouldn’t have to. Making basic things easy, and advanced stuff possible, is a central design philosophy that swirls around in our minds more often than what’s good for us. Then some sucker ends up saying what everyone was thinking, (but couldn’t quite grasp so they chose not to say at risk of being held responsible for some major mistake later on,) which sounded something like “….a proxy widget?”.

Embedded popups - strike 1

Why on earth does the popup show up there? Wait, windows use global coordinates… and the popup adjusts to the current screen’s available geometry….

Yeah, a proxy widget. You know, just “plug it in!”. Ehem. Everybody nods and goes “that makes perfect sense, but,…” and then you see everybody thinking like crazy, before one of our brightest people suddenly breaks and tilts his head to the side, a spring popping out of his ear. Everyone wants to say something, everyone knows a proxy is a can of worms, but some silly person goes “hey, how hard can it be?”. And you know what, we really just can’t get enough of those people. 😉 Sometimes I like to think that many of mandkind’s greatest achievements come from people with a sudden unexplained lack-of-insight, inability to foresee the future, and just plain stupid. It’s like building a house. Everyone knows building a house is crazy, it’ll take way too long, cost more than you have, mess up your relationship, but still some people go “Look sweetheart, it’s just €175000 for the house and another €150000 for the lot!”. And hey, you get a house. Which is great ;-). And have more kids, and you know.

So the project starts, and when it reaches its successful end, everyone, (including the stupid entrepreneur,) wonders how on earth this project could succeed.

Hah! Anyway. Popups! Yes.

What’s the big deal with popups? Popups imply explicit and implicit mouse grabbing, event replays, nesting popups (i.e., nesting grabs), grab-on-show, release-on-hide. Window positioning (converting QWidget global screen coordinates to QGraphicsWidget local parent coordinates). Delete/hide/remove/deactivate/unfocus/disable while grabbing? Implicitly? Explicitly? What if you grab while grabbing? Ungrab without grabbing? You grab the mouse and some other widget does the same, then the other releases the grab. Or better yet, releases _your_ grab. Should the scene propagate the grab to the view? [*] It’s one hell of a state machine! I’m losing sleep thinking about cases where somebody’d explicitly release a grab that some other widget has implicitly gained from a simple mouse press. That’s a silly reason to lose sleep ;-).

Of course, it’ll work, that’s almost the annoying part. When it’s done it’ll work just fine. No bells ‘n’ whistles, just a darn popup. It’s just such a can of worms.

Embedded popups

Now that’s more like it!

[*] No, it probably shouldn’t 😉

Update 2007-12-20: Here’s a patch that implements popup and mouse grab support. It’s a bit broken, but the basic functionality is there.

Do you like this? Share it
Share on LinkedInGoogle+Share on FacebookTweet about this on Twitter

Posted in Graphics View, KDE, Labs, Qt

10 comments

Nick says:

I have to hand it to you… That was one of the most entertaining blogs I’ve ever read!

Keep up the good work though, I mean that’s what Trolltech is all about right. Doing stupid things that should never work and somehow pulling them off brilliantly. I mean, mixing proprietary and open source development models… WTF!!! 😉

matthias says:

funny post to start the day, thanks 😉
i’m still amazed by all the blood sweat and tears you save us every day 😉 i guess the TT offices must be quite bloody sweaty wet places =)

jospoortvliet says:

Hi,

I wonder about the screenshot. The anti-aliassing looks rather funny, esp on the comboboxes. wazzup with that?

Andreas says:

jospoortvliet: Many styles render into a pixmap, then blit the pixmap to the screen. Some styles seem to have to do that (XP, Vista, Mac OS X). Others just do that because it makes pixmap caching easier. We’re fixing the ones that can be fixed as we go, to be truly resolution independent, and for those you won’t see this jagging – but for the rest you’ll see aliasing artifacts as the pixmap is transformed and drawn.

jospoortvliet says:

Andreas: tnx for the info. It is good to know this will be fixed soon. I would suggest fixing Plastique asap, as it would make the screenshots a lot better 😉

Zandru says:

this is funny 🙂 does it mean you can go fishing with popups? 8) can’t wait for 4.4!

Chani says:

wow. you guys make it look so easy…
at this rate, qt will be making my tea for me in a couple of years, won’t it? 😉

Andreas says:

Not only the contents of this entry are great, I also like the writing style. More like a good conversation than like a textbook. Keep it that way please 🙂
Aaaaand… I’d like to hear about progress on the resolution-independent UI front. I can’t remember reading much about it and it seems to be an important improvement.

Robert Knight says:

Hi Andreas,

Thanks so much for your work on this. In order to do really interesting effects on large windows at a decent speed I guess that hardware acceleration (eg. via OpenGL) will be a requirement. I tried changing the viewport for the QGraphicsView to a QGLWidget using the embeddeddialogs demo from the latest snapshot and it did speed up scrolling, but the dialogs were still quite sluggish in scaling and rotating when clicked on.

Commenting closed.

Get started today with Qt Download now