my KDExperiments

Programming, KDE and more

Putting KGameCanvas to sleep. Forever. July 31, 2007

Filed under: Uncategorized — Devil's Advocate @ 1:48 pm

KGameCanvas is a small and lightweight canvas that i had written in Qt 4.0/4.1 times, when QGV was not yet available or still very buggy, because we needed a very simple canvas to use in KBoard (now Tagua), and we did not need complex optizations for handling milions of items that actually resulted in a noticeable slowdown in many games and game-like tests. Something very much like the canvas in Qt 3, even if i’d say probably somewhat better. That said, KGC would never deserve to exist in a perfect world, and even in our unperfect world looks like that QGV finally catched up what was missing and is now working very well in small games with many animated items, outperforming KGC because it can avoid clipping the painter (and this can be a quite expensive operation if the region is complex). A small test program writtem by Paolo Capriotti can be found in the git repository at http://repo.or.cz/w/kgcqgv.git, a flag in CMakeLists.txt can be set to chose between KGC and QGV, just run and click to add a new item.

I feel very happy that we are now ready to get rid of KGC, in the unix philosophy there should generally be only one tool to do one job, and that tool will do its job well (even if i’d say that Qt is not following this philosophy very much because they are reinventing the wheel in many places, but well, they are just doing their best for something that is being sold and this can sometimes be the best choice to avoid complex dependencies). And it will probably be nice using a few of QGV’s advanced features in Tagua, such as event handling, transformations, etc. The only thing that i may want to complain is that i’ll now have to do some work to port the exisiting code😀

 

Trying to solve compositing problems of Qt widgets as X11 windows July 21, 2007

Filed under: qt,x11 — Devil's Advocate @ 4:57 am

Since Qt 4 all widgets are double-buffered, and every widget is drawn over the parent widget, for instance allowing it to be transparent. But problems come if you are trying to move your semi-transparent widgets around, or you create/destroy them, because Qt will create an X window for each widget, and X is not really designed to do such things (EDIT: ok, X is designed to do this, but is not interacting well with Qt behaviour). The result is that X will copy the content of the widget when the widget is moved (and this is wrong, because it is semi-transparent!), and erase the parent window when it is destroyed (this can be avoided setting a flag for the parent, but this is not done by most Qt widgets). Then, Qt will paint the correct content, but the result is that your app will flicker as hell.

widgets1.png

Namely, what Qt does is creating a unique double buffer for each toplevel window, compose all widgets on it, and then copy from the buffer to each X11 window. In the image above, suppose that the triangular region needs to be redrawn. Qt will draw in its internal buffer (that is an image as big as the widget A) part of the widget A, and over it the correct parts of widgets B and C, in order to completely update the triangle. Then blue, red and green regions will be copied onto the X windows that represent widgets A, B and C.

widgets2.png

Here instead I show what happens when a X window with Qt-emulated transparency is moved. Not really nice. In the end the correct content will appear, but what X did was not really helpful.

I have been trying to solve this problem for a while because i wanted to enable a few new graphical effects for Tagua, and yesterday i also wrote a crude hack trying to solve it by placing a completely transparent widget in front of everything that would track all mouse events and dispatch all received events to the underlaying widgets. Well, i was able to get no flicker, but a lot of complex code had to be written to send move/enter/leave mouse events to the correct widget, and many cases where left unhandled (such as drag/drop events, focus, etc). Replicating a big part of Qt/X11 event management just to get rid of flickering is not the right thing to do (and almost impossible to do in the right way), so this is surely not how this problem will be solved.

A true solution would require some support in the X server. This could be solved temporarily in Qt at the price of creating only one toplevel X window that would contain all child widgets and track all mouse events, but this is surely not optimal because most widgets (such as buttons) do not require all mouse events but just enter/leave notifications, and, since applications comunicate with X through a socket, receiving all mouse events would wast resources. What is required is a flag to prevent X from copying the content of a window being moved, and some support in Qt for such flag. Or a way to tell X to just create input contexts in place of windows, in this case all painting operations would be done onto the toplevel window, and probably it would also be easer to handle for the toolkit and a bit faster (because an invalidated region that spans through many widgets could be updated all at once).

I’d like to know if some work is being done by some graphics-ninja to solve this problem🙂

 

Why git rules! July 11, 2007

Filed under: git,kboard,kde,vcs — Devil's Advocate @ 2:34 pm

During past days, under suggestion of Paolo Capriotti, we’ve been using git for the development of our project KBoard, trying to understand how decentralized development model works and what are its strengths and weaknesses. If you don’t know what git is, why it is promotes a completely different development model than cvs/svn and why it is worth considering, i highly recommend you to give a look at this talk from Linus Torvalds himself, where he explains why he decided to write it and what he wants a vcs to be able to do.

One of the issues with cvs/svn is that, since everythig goes in a central repository, nobody is allowed to commit changes that do not compile or break completely the code. The result of this is that most developers instead of committing their changes in a regular an logical way will keep modified files in their machine waiting for that particular feature X to be ready to go mainline. A commit “Implemented huge feature X” means that something is not working properly, this should not happen where a revision control system does what it is supposed to do.

One way around this is creating a branch for each new feature, but you won’t create a new branch in the main repository for each new feature that you are going to implement, would you? Much better would be if you could have your own repository where you will create a new branch for each new feature, and from which the mantainer of the project will be able to get your changes as soon as you tell him “Feature X is ready“.

This works very well in real life because people tend to create trust networks. For instance the toplevel mantainer of a project (Linus for the kernel) only trusts a few people, he cannot trust everyone. Each one of his friend will also trust another bunch of people, and so on. That is, once you have a patch for a feature X, you will just have to notify the mantainer of upper level that such feature is ready in order to propagate it up to the toplevel.

Another very important side effect of this new model is that it is exactly in the spirit of Mark Shuttleworth‘s talk at the aKademy: a sort of rithm, regular schedules and releases are required for an opensource project to proceed. But most kde developers are just doing it for pleasure, it is not fair forcing them to spend two months just fixing bugs because the release date is approaching. But in a decentralized development model each developer can just say to the release manager “features X,Y are ready, feature W requires testing, don’t include feature Z because it is not ready“, and the release will just slip out without pain.

 

 
Follow

Get every new post delivered to your Inbox.