Andreas
Qt
KDE
Graphics View
Posted by Andreas
 in Qt, KDE, Graphics View
 on Friday, May 30, 2008 @ 13:57

I’m studying how we can add light and shadow to widgets and items. I want to hear what you think :-). So I’ll just throw out my ideas and see what happens.

Light and shadow are special effects that follow and decorate items, and affect how they are rendered, at the same time as they’re a bit different from regular items / subitems, or subwidgets. For both light and shadow effects, there’s sometimes a need to render outside the item’s boundaries and blend into surroundings. For widgets, we then need to do something to break out of the box model… to make that happen. For inside-widget light effects, we’re limited to what we can do inside paintEvent() or inside the paint() function. I don’t know about you, but I think both light and shadow effects should be primary citizens of the scene graph, which essentially means they are also items. Stack-above / always-on-top (overlays) or stack-below / always-below items (underlays?).

Here’s a flash video showing a sample of what I’m working on. This is based on Graphics View.

The scene consists of 150 elliptoid items with shadows, and one light source that’s flying over it. It’s a bit psychedelic; anyone who loves colliding mice will love this. ;-) Haha.

Let’s start with shadows. In 2D, shadows can be pretty simple. Shadows can be thought of as transformed filled outlines of an object with a dark semitransparent fill and possibly fuzzy/blurred edges, stacked below the object itself. It has an offset, and/or an angle. The offset can be fixed for all items, or relative to one or more light sources. Ideally two shadows on top of each other don’t make a darker shadow, rather they blend with each other along the edges. Exact shadows are expensive to do accurately, and in many cases they’re completely pointless because they’re hard to see in the first place; at least the types of shadows we foresee being used in 2D / 2.5D UIs… Extreme shadows are cool but useless, subtle shadows, however, to me, are/can be beautiful. There seems to be a “market” for simple stupid fast shadows (e.g., bounding rect / bounding region based), pretty good medium-speed shadows (e.g., shape based), and custom shadows. And possibly perfect shadows (e.g., based on paint()) but I don’t really think that market is very big :-)).

As for how shadows are stacked, the easiest way is to just say that an item with a shadow always renders the shadow before itself. This works fine for most cases. But as soon as sibling items come close, and one’s shadow renders on top of the other, it starts looking wrong.

Sibling Shadows 1 Sibling Shadows 2
Take 1: Sibling shadow overlaps Take 2: Sibling shadows behind both

It would be nice if I could set a shadow on our favorite “Drag And Drop Robot” without having lower leg shadows cast on the upper legs, or a shadow from the left leg draw on top of the right leg. I can see the need for both, but what would the API look like? And how would the items be stacked? My solution right now is to add a special flag to QGraphicsItem called QGraphicsItem::ItemStacksBehindParent (the child and its children are behind the parent), which is certainly one step on the way.

The other thing is how the shadow is placed. I don’t know about you, but I hate it how some presentation tools rotate the shadow relative to the item when you rotate and item that has a shadow on it. A picture says more than a thousand words:

Shadow follows item transform Shadow transform relative to scene
No :-( Shadow follows item. Yes! Shadow follows scene :-)).

It’s a bit complicated though because you want the shadow to follow the item, but you wants its offset to be done scene-relative. Turns out it’s just that the item’s local transform is prepended to instead of appended to the parent item’s scene transform. So I added a flag for that: QGraphicsItem::ItemBeforeSceneTransform. Btw this is just research, it’s not in Qt snapshots or anything.

Now light effects come in many different shapes and colors. Light can affect shadows, or it can just add a glow to an item. Light is typically represented by an abstract member of the scene, to which you can calculate distance and angle and apply a suitable effect to your item, or the background, and so on. In styling, we usually fake light big-time by just applying light and dark effects to our button bevels, or use pixmaps that look shiny and sparkly. Which, of course, is in many cases much faster than doing “correct lighting”. I recall once Zack Rusin and I were talking crap, I don’t know who brought it up but if the whole UI was a complex detailed 3D scene graph, lighting could come by itself (I think the discussion started with why buttons in RTL mode don’t have shadows cast as if the sun shine from the upper right).

For blend effects it’s also necessary to apply aftereffects that combine the source and destination. That can be done in two ways - either just via an offscreen buffer, or directly onto the destination device / framebuffer / or so. If we want blend effects I think we need some type of shader integration. Let’s not digress though.

So, ball in your court. What are your thoughts about light and shadow?

Thiago Macieira
Qt
KDE
News
Posted by Thiago Macieira
 in Qt, KDE, News
 on Wednesday, May 28, 2008 @ 15:51

Earlier this month, we released the single, largest release of Qt since the 4.0.0 release two years ago. Qt 4.4.0 is the result of 10 months of hard work by the Trolls, including numerous distractions. And while it’s being digested by our clients and users, we’re working on Qt 4.4.1, which will include fixes for bugs that were already known at the time of the 4.4.0 release, as well as some that people have reported.

In the meantime, we take two steps back, to the 4.3.x series, and then one step forward: we’re releasing today Qt version 4.3.5. This release is meant for those who cannot upgrade to Qt 4.4.0 yet, but need fixes for some important issues. All of the changes done for 4.3.5 will be present in 4.4.1 and some are even part of 4.4.0 already.

This is the first time ever we’re doing a public release of the previous minor series. In the past, we’ve always stopped development of the previous minor series when the next one came out. Sure, we’ve done security fixes when needed and Trolltech Support continued to support clients using them, but we’ve never made a public release. So this is news for us too. :-)

One of the main reasons that made us decide to release 4.3.5 was the sheer size of the 4.4.0 upgrade. Many customers are scared to take the leap. Not that 4.4.0 is a bad release — no, far from it, all indications so far are that it is a great release. (At least, the Trolltech head of Support hasn’t tried to kill me yet for it!) But nonetheless, we decided we would reassert our commitment to all clients and users despite all distractions, by providing them with one more 4.3 release.

If this proves to be a good thing, we may repeat it for the 4.4.x branch when Qt 4.5.0 is released, although we’re not expecting anything as groundbreaking for that release as 4.4.0 was. We also have two or three bugfixes up our sleeves in the 4.3 branch, which may lead to a 4.3.6 release if necessary.

Including the pictures of the Qt developer team again, since a few more people have been patched in.

Oslo team Berlin team
Oslo team Berlin team
Andreas
Qt
Graphics View
Posted by Andreas
 in Qt, Graphics View
 on Friday, May 23, 2008 @ 07:47

Here’s another brain dump… I’m working on adding opacity support to QGraphicsItem and possibly QWidget, and have run into a common inside pattern, with a common problem to solve. Figured I’d share it with those interested.

Many of Qt’s properties propagate, some do in different ways, but the general pattern is that you set or modify a property on a widget or an item, and that property has some effect up and/or down its hierarchy. This is a good API pattern. Propagation is most often what you want, and you’re often surprised when a certain property doesn’t propagate (like QWidget::style).

  • Q{Graphics,}Widget::visible - if you explicitly show a widget, its implicitly hidden descendants are shown, explicitly hide a widget, and visible children are all implicitly hidden
  • Q{Graphics,}Widget::enabled - if you explicitly enable a widget, its implicitly disabled descendants are enabled, explicitly disable a widget, and its enabled descendants are implicitly disabled
  • Q{Graphics,}Widget::palette - you set a mask [*] of modified palette entries, the palette is resolved against its ancestors, and propagates to children
  • Q{Graphics,}Widget::font - you set a mask of modified font entries, the font (or rather -request) is resolved against the widget’s ancestors, and also propagates to children
  • Q{Graphics,}Widget::pos - if you move a widget, its children move with it
  • QGraphicsItem::transform - if you transform an item, its children transform

There are plenty of other properties that propagate. How does this actually work on the inside? Let’s take a look at visibility, as an example. QWidget::visible’s setter, QWidget::setVisible() (which is called by show() and hide()), sets local state only, and doesn’t touch other parts of the hierarchy - so the setter is “cheap”. Checking isVisible() is also cheap, but what you get from isVisible() is local state only; determining whether the widget will actually be visible to you when its window is shown, requires some more work. It’s relatively expensive to resolve “true” or “effective” visibility for a widget (compared to the setter anyway). Luckily though, QWidget’s visibility property is cleverly designed so you very seldom need to call show() or hide() at all, and I don’t know of any case where I’ve ever had to check my widget’s “effective” visibility. This is all done inside Qt. And that’s good, since we can do clever stuff to avoid the resolving expense. Because visibility rarely changes, we could even cache it.

For the record, if you want to know your widget’s effective visibility, there’s a handy QWidget::isVisibleTo() [**] that you can use:

if (widget->isVisible()) {
    // Whether this widget's local state is visible. But if the
    // parent is hidden, this widget is also effectively hidden.
}
QWidget *window = widget->window();
if (window->isVisible() && widget->isVisibleTo(window)) {
   // Yup, unless the window is outside your desktop, and unless
   // you've turned off your monitor, or perhaps you don't even
   // have a monitor at all, it should be visible. ;-)
}

OK, so let’s give an example of the opposite, a propagating property with a cheap effective getter and an expensive setter: QWidget::palette. When you set a palette, this palette is first resolved against the parent palette, and then explicitly propagated to all descendants. This operation can be expensive, depending on how deep your descendant hierarchy is. Why is the setter expensive? Because unlike QWidget::visible, which changes quite frequently during the runtime of an application (think how many times you open and close menus, dialogs, switch tabs, show and hide docks, minimize and maximize windows), palettes are very rarely changed at all, and mostly assigned once only, right before the widget is shown for the first time. So every time the widget is drawn and you need to access the palette, it’s very cheap and easy to access.

Expensive assignment, cheap resolve

If you think your property will be assigned only once-ish, and you need it to propagate, you go for the cheap resolve and expensive assignment. Typically this involves storing local state in every single child, so it’s also a memory vs. speed trade-off. This implicitly makes the individual child widget’s resolve step (”effective property resolve”) cheap. Using the example above, when you set a palette with a blue color entry for QPalette::Link, QWidget::setPalette will immediately walk the child tree and resolve all child widgets’ palettes against this new entry. So if the deepest descendant needs to redraw itself (or paint using QWidget::render), it has a fully resolved copy of the palette in its private section.

Laziness can help a lot here; you can speed up the expensive assignment by setting a dirty state on all non-dirty descendants - now the resolve is will only happen on access. The setter is the same order of complexity though, it’s still expensive. There’s still room to be clever :-).

Expensive resolve, cheap assignment

If you think your property will be assigned several times, and relatively rarely used, you go for the cheap assignment and expensive resolve. QWidget::pos, for example. Changing the position of a widget is something you might not do very many times yourself, but you can be sure that the layout system does this very many times for many different widgets in the same form (although only once per widget). Making the setter propagate its state immediately, like QWidget::palette, would mean form resizing would become a quadratic operation (for each widget, set the position and adjust all descendants’ positions). So instead, you set local state only. Now, when the widget is rerendered, Qt walks the tree to calculate each widget’s effective position, but it only needs to do this only once per paint event.

Caching can help here, tremendously in fact. When you resolve the state of a leaf node, you cache all resolved states for its parents all the way up to the ancestor. Now, if you need to resolve another leaf, there’s a fair chance you’ll hit a node that already has a resolved state for you. The complexity is still O(N lg N), but the cut-off makes the common case O(N).

So the question is - which approach to choose for widget opacity? :-)

— Andreas

[*] From the outside, QFont and QPalette look like actual value classes, but a little-known secret is that they actually represent a request set. When you assign a palette or a font to a widget, you’re not actually overriding any other entries than the ones you explicitly set, and even those might be modified to match what’s available. This is why neither QWidget::font nor QWidget::palette have symmetric setters and getters (the getters return the resolved palette).

[**] Qt 3 has QWidget::isVisibleToTLW(), which is obsolete (but present) in Qt 4. This does the same as widget->isVisibleTo(widget->window()) < = which is much clearer and doesn't use ugly abbreviations. :-)

lorn
Qt
Qtopia
KDE
Posted by lorn
 in Qt, Qtopia, KDE
 on Tuesday, May 20, 2008 @ 20:00

It’s been a long time since I have blogged anything. Been busy finding a new house to live in, then moving house, then holiday/being sick at Waikiki in Hawaii. Waikiki is much like the Gold Coast here in Queensland, except people there wear shoes, and tops. Australia is much more baby/family friendly, although. My 2 years old son finally conquered his fear of ocean waves, and was happily swimming in the ocean. Now we just need to wait for summer here so we can go swimming at the beach.

Been working on Qtopia integrations on the ficgta02 and n810 and readying for the upcoming Qtopia 4.4 release.

In particular dynamic rotation. Still small things to be fixed up for Qtopia 4, as a late addition to the Qtopia 4 game. We used to have it way back in Qtopia 1 and 2, but for Qtopia 4 it was never ported or really thought about, as most devices we were developing for did not need it, or didn’t really seem sensible to have it. But the Neo and n800/n810 are different. In particular, the Neo, has no buttons, so it can be oriented in any direction.

Qtopia 4 is much more complicated than Qtopia 2, with theming, styling and all that jazz.

Qtopia on the Openmoko Neo (ficgta01 and ficgta02) is mostly working. The Openmoko folks have picked up on Qtopia on X11 porting/demo code we had done, and started working more extensively on it for the Neo phones. They plan on trying to meld Qtopia with Enlightenment stuff. Or at least make them work together. Who says Qt and Gtk can’t live together?

Qtopia on n800/n810 is coming along nicely as well. We made the n810 rotate whenever the keyboard is slid in or out. Being in portrait mode when in and using the few buttons it has that way. Probably the most difficult thing for the n810 so far was the keyboard driver, going back to the days of the Sharp Zaurus qwerty keyboard.

Other projects going on I cannot speak of, but they generally benefit Qtopia.

Thomas Zander
KDE
News
Posted by Thomas Zander
 in KDE, News
 on Friday, May 16, 2008 @ 18:48

Its been a while since I introduced ‘Vng’. Vng is still under production and innovation is happening :)

As a quick intro can be read here, which will tell you that vng is a version control system made to be usable by humans.

So, what has happened since my last blog. Well, I’ve been polishing a lot. This means that I have added various options to the major commands. Like adding all files in a dir recursively to the repository. Which you really miss if you need it.
Another thing I added was a matcher. The most obvious place where this is visible is in watching past changes. The changes command will naturally list things like commit-message, author etc. Using the various matchers it becomes trivial to do some more intelligent interrogation of your repository.
vng changes --match zander #show all the records which ‘zander’ made.
vng changes --last 10 #show 10 records
vng changes --from-match 'fix assert' #Find the record with ‘fix assert’ in the message and start showing changes from there.
vng changes --to-patch 'Add.*Command' # show only changes until one that matches the regular expression.
Naturally you can combine all those without problems.

Most of these things you probable just have to try out to see how it works for you. I’m someone that really cares about the tiny details so you’ll find things like showing when you changed whitespace at the end of the line with a colored marker, or being able to type ‘vng what’ instead of the full command ‘vng whatsnew’ since, well, vng knows you must have meant the full one, naturally.

Back to the “what happened” point. I always get a bit excited when I have a tool that is just smart in visualization etc. But I actually started writing this blog for a reason;
The main complaint I have heard from people trying git on the Qt repository (specifically on Windows) is that its slow. Now, we know that git has some scalability problems on Windows, and the git people are working on that. But in my interviews with various perforce users that actually made the above claim I noticed a very different problem.
The way that perforce works is that your checkout has all files checked out as read-only. Whenever you want to edit a file you have to tell perforce. Which tells the server you are editing this file.
The effect of this is that doing a ‘p4 diff’ will first ask the server which files you have opened and then do a compare of only those files with your local copy. This is substantially different from git or darcs or many others which all use the file-date to check if you have edited a file. Using a filedate has the big disadvantage that for a repository the size of Qt (or KDE) you have to stat 30000 files if you ask your app to give you a diff. This is disk-access and thus slow.

So, no matter how much the file-access is optimized and duplicate statting is reduced, the concept of making the user keep track of which files to diff will always be faster then letting the tool auto-detect this.

This conclusion then lead me to investigate in what manner it would be practical to re-use this concept for the people that now have very good reason to complain about slowness. I mean; instantaneous diff, or waiting 30 seconds on cold caches to do a diff of Qt…
I have used my creative-Friday today to work on this in vng and have for the most part finished the implementation. I have added ‘vng edit’ and ‘vng opened’. Edit will ask the user if he wants to switch to the way of working that he has to mark files for editing. After which any whatsnew / record etc will only happen on the files that are being edited. The biggest change, naturally, is the speedup. The results will be on screen instantaneously since we already know which files are changed and we avoid any file listing or statting.
Next step is to make the perforce integration that virtually all tools have work for vng. This integration is in most editors, in diff and various other tools already. They will detect a file that is read-only and will call p4 edit on the file prior to writing out your changes. If we can fool those tools into doing the same but then call vng edit instead we get a huge speedup virtually for free.

Are you interrested in trying out vng; see vng.googlecode.com or just download the sources from repo.or.cz/w/vng.git. Note that the speedups are not in the downloadable executable posted on the projectpage. I’ll have to rebuild that one soon.

Have a good weekend!

Simon
Qt
Qtopia
Posted by Simon
 in Qt, Qtopia
 on Wednesday, May 14, 2008 @ 14:57

Today we’re proud to announce the winners of the Trolltech Open Source Development Award!

A while ago Espen announced the finalists for the award. The vote is over now and the ballots were counted (electronically).

The third place goes straight to the editor of choice: VIM. Much of Qt’s source code and documentation was loaded, edited, syntax highlighted and saved by Vim, without using the CTRL or X key at all. :wq!

Once platform dependent code is written it may be necessary to implement similar functionality on the remaining platforms. This pattern is typical for Trolltech engineers and therefore the choice of Synergy for the second place comes natural. The lines between different operating systems blur when we use the same keyboard and mouse on Mac OS X, Windows or Linux. That’s very much in the spirit of Qt. As a bonus we have less keyboards and mice to clean from dust and coffee stains.

Once the code is written we submit it and move on to the next task. Unless the unthinkable happens and a bug slipped in. In the hypothetical case of a dangling pointer or memory corruption we might require our winning tool, Valgrind. We don’t need to sprinkle printf() statements into the code anymore, we don’t even need to recompile. We just run the program under Valgrind and it points straight to yoursomeone else’s source code. Hurray!

Here are the reactions from some Trolltech engineers on the results:



Jens
Uncategorized
Qt
Labs
Styles
Posted by Jens
 in Uncategorized, Qt, Labs, Styles
 on Tuesday, May 13, 2008 @ 20:28

textedit with gtkstyle

Now that 4.4 is out, I finally found the time to kick off some new development and one of my pet projects these days is QGtkStyle. We already have QCleanlooks, icon themes, standard shortcuts and dialog buttons to integrate with GNOME, but to achieve true perfection we need to use the Gtk theme engine directly just like we do on Mac and Windows. QGtkStyle does exactly this, and in addition extends and surpasses QCleanlooks in a lot of other areas as well. All group boxes are now flat style to blend better with GNOME dialogs. Icon theme support has improved, scrollbar buttons are disabled at edges and item view branches now support hover.

spreadsheet example

The style is already available right now as a Qt 4.4 plugin on Labs and given that you can accept the normal disclaimers about using unreleased and experimental code, you can start playing with it immediately.

This is how the Arora browser looks:

clearlooks style

All the above shots were taken using the “Clearlooks” engine. Here are a few alternatives:

Ubuntu Human:
mediaplayer

Mythbuntu:
mediaplayer

And of course the unforgettable Raleigh engine:
mediaplayer

Tor Arne Vestbø
Qt
WebKit
Internet
 in Qt, WebKit, Internet
 on Tuesday, May 13, 2008 @ 13:31

So, after Simon snitched on me and leaked highly sensitive information about my top-secret project, I guess it’s finally time to spill the beans.

Yes, it is true. For the past few months I have been semi-secretly working on taking over the world implementing support for the HTML5 video and audio elements in the Qt port of WebKit, using Phonon as the media backend. This adds QtWebKit to the list of cool browsers that support this feature.

The introduction of a special purpose media element in the HTML5 draft allows embedding of audio and video content into web pages without resorting to using the generic object tag with some random plugin-based player. It’s as easy as this:

<video src="foobar.ogg">Fallback content here.</video>

The media element also comes with a scripting API, making it easy to roll your own player interface if you want to (or use the default one provided by the user agent by adding the controls attribute).

Employing Phonon to implement the playback started out as my “hey-welcome-to-Trolltech-here-is-a-fun-task-for-you”-project, but turned out to also be a good test-case for the implementation of the various Phonon backends we are doing here at Trolltech. The project was momentarily put on ice while we were busy stabilizing the 4.4 release, but now that 4.4 is out the door it’s time to get back in the saddle.

Some of the tasks currently in the pipeline are Win and Mac support (which is still largely untested), full screen support using overlays (for speed), routing the data through an IODevice rather than just passing a URL (which will help buffering and let us ensure that per-site credentials will work), plus implementing more of the default UI controls.

Initial support is already in WebKit trunk for those of you who want to try it out, and the finished result will be in Qt 4.5. Here’s a screenshot, for you pixel peepers out there:

Andreas
Qt
KDE
Labs
Graphics View
Painting
Posted by Andreas
 in Qt, KDE, Labs, Graphics View, Painting
 on Monday, May 12, 2008 @ 21:44

I’ve always had a dream that Qt’s widget system would be based on a powerful 2D, or possibly even 3D, graphics engine, reaping all the benefits and optimizations that make games run fast. The reason is, coming from a 3D graphics background originally (alright, I was 16 at the time), I’ve always been puzzled by how poor application UIs perform, and how constrained they are, compared to the most basic 2D and 3D graphics engines out there. I think there are many reason for why graphics toolkits provide limited capabilities, and performance, and I’ve been studying this, hoping to help find ways for Qt to be better than the rest. If you ask me why oh why, be warned, I will talk all night. ;-)

I think I could get shot for saying this, but IMO widgets are monolithic beasts. Input, painting, clipping, geometry, events and all are almost always packed into just one class. And that class plugs into a framework that works in only one way. It’s hard to change the way a widget clips without introducing rendering artifacts (draw outside and try to update with the rendered region - oops, the dirty region is autoclipped to the widget rect). It’s impossible to know what a widget looks like without calling paintEvent(), which is a virtual function that might do something different every time it’s called. Multithreaded painting is extremely hard. It’s hard to make the widget paint outside paintEvent() in general. Couldn’t the widget just say what it looks like instead?

The main reason it’s like this, I think, is that UI toolkits’ graphics capabilities are just a hurdle in the path to the ultimate goal, which is to pull together UIs with a nice tool, perhaps targeting your favorite language, and with a cool style and the perfect widget ;-). IOW modeled vertically, after the concrete problem to be solved (which is generally speaking a good approach), and perhaps constrained by the capabilities of the primary target platform. I still think we can learn a lot from looking at UIs as a specialization of a 2D graphics scene API, rather than 2D graphics being an extension to a UI toolkit. We need to model our graphics the way that graphics works (both software and hardware), and not cling so much to a particular problem space. Make sense?

Qt provides both a high-level widget API, a low-level graphics API, and a “mid-level” canvas API called Graphics View. Graphics View is an example of loosening up the constraints of the high-level API, without exposing too many low-level problems such as geometry and dirty region handling. In a way it’s more a 2D graphics engine than anything else. It manages surfaces in 2D (or 2.5D, quasi-3D) space. Originally, we meant for it to be different from QWidget. Obviously, it’s a framework that’s meant for something completely different than widgets (vector graphics, charts, maps, IC design, large scrollable scenes, and so on). What we’ve learned, however, is that the two aren’t really that different. Why can’t I have 1000 widgets in a QScrollArea, for example.

So looking back a few years, you’ll see that we’ve made changes to improve QWidget. Without breaking compatibility of course (which is amazing in itself, shows how Qt’s architecture allows for significant internal changes).

Before Graphics View came out, in Qt 4.1, we loosened up one constraint in QWidget by enabling automatic background propagation. Now, widgets no longer had any default background (remember this change? how about QWidget::autoFillBackground oh, OK now you remember ;-)), and we were one step out of the box-model that widgets traditionally represent (btw when I use the term “box-model” I refer to a widget representing an independent rectangular region of actual screen real estate). Then, in Qt 4.2, we introduced delayed widget creation (DWC), which allows a widget to be constructed without an actual window handle. As part of the DWC work Paul, Matthias and a few others did for 4.2, they had to ensure that widgets had enough local state to independently represent what it otherwise had with a window handle, as without. Well, this had a ripple-effect. During the Qt 4.2 and 4.3 maintenance cycles, we discussed the fact that the only widget that really needs a window handle, is the top-level. With Qt 4.4, Bjørn Erik did some tough refactoring work (which some of us, me included, thought wouldn’t really be feasible), and gave birth to what we call Alien Widgets, the invisible behind-the-scenes beauty. Because of this, in Qt 4.4, a window and a widget are different, despite being the same class, in that the window signs a “contract” with the windowing system to register some screen real estate. This is the same now on all platforms.

Still, after this, you could see some strings that pull QWidget down. Painting outside paint event - using QWidget for screen shot captures, for example, required painter redirection. Each widget still constructed its own QPainter inside paintEvent(), and with it a separate paint engine, despite how all painting ended up in the same paint device: the QPixmap backingstore, which was associated with the same top-level window. Now in Qt 4.4, QWidget has a render-function, much like QGraphicsItem has a paint-function, and the window is, for a subtree of QWidgets, essentially the same as a QGraphicsView is for a scene. Puh.

Background propagation. DWC. Alien Widgets. Shared Painter. You see what’s happening? We’re on a mission. :-) We’re closing the gap between QWidget and Graphics View. And we’re not done, there’s still more to come. :-) There are some things that we cannot easily change, like QWidget’s clipping model for one (it’s opposite from Graphics View) [*]. And that Graphics View can’t make windows like QWidget (arguably, this is solvable though). Plus all our widgets are QWidget-based. Embedding the QWidget-based widgets into Graphics View using WoC is cool, but it’s just not good enough for full-blown exploitation…

Feature by feature, I must say the situation today looks surprisingly good. I’m looking forward to the day when I can simply assign a QGLWidget viewport as QWidget’s window. Or when I can load UIs from Qt Designer into Graphics View. Or in Qt 5, maybe the two are the same thing (the latter is usually only mentioned between some specially interested devs in Trolltech social events after consuming large amounts of beer).

That’s enough blabber for one blog post. I just felt like sharing what’s on my mind these days. This is btw all part of the research we’re doing in Development / Trolltech to support next generation UIs.

[*] QWidget is by default clipped to the intersect of its rect() and the localized exposed region before paintEvent() is called. QScrollArea has no explicit clipping features. Because most widgets don’t draw outside their bounds, item-imposed clipping should have been off by default (obviously expose-clipping is unavoidable for viewports that allow partial updates). And scroll areas should instead explicitly clip the widgets that intersect its edges (widgets outside shouldn’t be drawn, you don’t need clipping for that) (most 2D and 3D graphics APIs use subdivision instead, essentially real-time retesselation of the intersecting primitives to avoid clipping altogether). It’s extremely hard to change this in QWidget today without breaking compatibility. QGraphicsItem has the preferred model in place. But all our standard widgets are written using QWidget, not QGraphicsItem/QGraphicsWidget.

Simon
Qt
KDE
WebKit
Posted by Simon
 in Qt, KDE, WebKit
 on Friday, May 09, 2008 @ 13:44

As part of Qt 4.4 we have now made our very first release! :-D

Shortly before the release we finished merging all our changes back to the Subversion trunk branch, where we are working directly now. We will continue to maintain and bugfix the code in the Qt 4.4.x release series, but we try to make the changes in trunk first and then backport changes as they fit.

Our current goal is to catch up with the architectural changes that happened in trunk and maintain the layout tests. Holger for example fixed the HTML Canvas after some internal API changes. Ariya started working on Netscape plugins for Windows and Tor Arne I heard is polishing a secret feature he’s been semi-secretly working on for a while now in not-so-secret trunk. I heard rumors that he’s going to secretly blog about the secret feature soon, so stay tuned.

Big props also to Marc and the guys at Collabora for landing the initial support for Netscape plugins for the X11 Qt and Gtk ports in WebKit trunk! Great job!

On the application side Urs Wolfer’s Google Summer of Code project for integrating QtWebKit into KDE has been accepted. Congrats Urs! Feel free to stop by in #webkit and bug us if you have questions :)