Back to Blog home

Popups are a can of worms

Published on Wednesday December 19, 2007 by Andreas Aardal Hanssen in Labs Qt Graphics View KDE | Comments

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.

Subscribe to Our Blog

Stay up to date with the latest marketing, sales and service tips and news.

The blog comment system has been migrated to a new platform. If you face any issues, please let us know via feedback@qt.io.