Qt does not support for XInput 2.2’s multitouch protocol.[1] So instead of whining, I approached it as an opportunity to learn XInput2 and possibly give a more awesome MT experience in Composite. Qt allows you to catch and handle raw X11 events using QApplication::x11EventFilter().

As a starting project, I took the Qt fingerpaint demo to make it work with XInput2. With Ubuntu 12.04:

$ sudo apt-get install xinput libxi-dev qt4-demos

N.B. I already have Qt4 tool and -dev packages and a bunch of stuff installed, so YMMV.

Next, using my Lenovo Ideapad, let’s confirm that fingerpaint is broken:

$ /usr/lib/qt4/examples/touch/fingerpaint/fingerpaint

And contrary to what I expected… multitouch works!! However, sometimes it works and sometimes it doesn’t.[2] Usually if you wait until “Fingerpaint” appears in the title bar you’re good to go.

As it happens, Ubuntu 12.04 has a patch that enables Qt’s multitouch. 🙂

So next, I compiled the Ivory application that I did for MeeGo. And:

Got touch without getting TouchBegin for id 58
Got touch without getting TouchBegin for id 58
Got touch without getting TouchBegin for id 58
Got touch without getting TouchBegin for id 58
Got touch without getting TouchBegin for id 58
Got touch without getting TouchBegin for id 58

Turns out that this is Ubuntu bug #1007847 and is easily fixed like this:

diff --git a/src/Application.cpp b/src/Application.cpp
index 05e1a92..4fc590b 100644
--- a/src/Application.cpp
+++ b/src/Application.cpp
@@ -59,7 +59,7 @@ namespace Ivory

-        setViewport(new QGLWidget);
+        setViewport(new QWidget);

         QStringList ports;

…and it works!

This isn’t the blog I expected to write — so it’s been a pleasant surprise.  However, I am still interested in doing raw XInput processing… so I’ll still explore that in the next blog.

[1] – …as far as I know. Last I heard the status was that there was no support (nor plans to support) XInput 2.2 or anything else new in X11.  (…but patches welcome.)

[2] – I think I have an idea why it sometimes doesn’t work. More on that next time.


[cross roads]This series has been fun and frustrating, but leaves me a bit worried about using QtQuick/QML for the UI of Composite.  While a lack of personal free time was one reason for the 4-month delay between posts… other things bothered me:

  1. I didn’t expect that I would have to roll my own QML version of QTableView.
  2. The way data is passed between C++ and QML is still fuzzy to me.
  3. Internet literature on QML is heavily slanted towards Javascript implementations rather than C++.
  4. Searching for “qml sucks” lands a lot of people to this blog. (I’m the #1 hit! …ironic, since that article speaks well of QML.)
  5. In Qt5, QtQuick sees the most changes and I wonder what porting C++ components will be like.
  6. I don’t really like GUI coding, and am inclined to stick with what I know (things like QWidget).

But these things make me want to keep on with QML:

  1. I’m going to need lots of custom widgets.  With Qt5 I want to be able to port the drawing logic as fast as possible.  It looks like the QML-written parts should port quickly.
  2. I like the prospect of benefiting from QtQuick’s new SceneGraph implementation.
  3. QML makes it easier for users to re-skin the UI without serious coding-fu (a big deal for hipster musicians)
  4. My 2nd choice is QGraphicsView — and I’m not sure my troubles will be much easier there.

Anyway… it’s time for Composite to start moving again, and currently this (in)decision is the major showstopper.

What’s your opinion? What would you do?

QtQuick: Why bother with QML?

December 21, 2011

This post is an introduction to the next several posts. If you’re bored with QtQuick introductions (since there are many)… then there’s probably nothing to see here.

Composite (and its ancestor Hydrogen) has always had a Qt UI. And when it comes to GUI, Qt is the toolkit that I prefer to use. Why Because I really don’t like UI development. I like to work on models, business logic, complex calculations, etc. I really get bored with sizing widgets and trying to figure out how to convince the font system to give you the real, actual, true bounding rectangle (and not the one that’s better for typesetting).

And then there’s the code. The options have always been something like:

  • Use a C API like GTK+ and write gobs of code and manually
    type all the gtk_widget_* namespaces for every class method.
  • Use a C++ API wripper like gtkmm (which never really gets
    rid of the smell of the C API).
  • Write gobs of Qt code to express your UI. Which means that
    small changes (like moving a widget from here to there) often
    require a lot of code changes.
  • Use a UI designer to create XML files that get processed into
    code. (I.e. Qt Designer or Glade.) While it’s easy, these
    files often have compatibility issues even across minor
    releases. They also are not very diff friendly (which is
    important to a backend-loving code monkey like me).
  • Write your UI in a scripting language like Tcl/Tk or Python
    (e.g. the PySide bindings). Here you trade-off flexibility
    for simplicity a lot of the time. (Think: custom widgets.)

These options all have one thing in common: they suck.

Along comes QtQuick, with the idea of expressing your UI in a scripting language called QML. QML is:

  • Like javascript and CSS: so it looks like code, and diff’s like code.
  • Declarative/Interpretive: so small changes just require that I refresh the QML file in question… not recompile (or even restart) my whole application.
  • Designer-friendly: if your project has an artist, they probably aren’t very good at C++. QML isn’t too difficult to parse… which makes them more productive.
  • Developer-friendly: as a C++ lover I’m not crazy about the syntax of QML… but I love that I can throw up a UI pretty quick. While the UI’s that I design look like butt… I don’t feel like I have invested a lot of code into something that needs to change (and change a lot) later in the project.
  • Architecture-friendly: It more or less enforces that you use a model/view architecture in your application. When the UI was code, it’s very tempting to pragmatically break the rules.
  • Prototype-friendly: You can add some logic into the QML via JavaScript, which means you can prototype the UI’s behavior without having to invest any C++ code.
  • Promising: The Qt framework is reorganizing itself around QML. It’s pretty fast now, but it promises to be blazing fast in Qt 5. (Even faster than using native widgets or QGraphicsView… and that’s an impressive accomplishment.)

However, it does come with a few drawbacks:

  • It’s oriented to embedded devices that have a fixed-size, full-screen “app” paradigm. Therefore, you’ll find that lots of sizes and relationships are set in fixed-size pixels. It’s not quite as nice as QLayout in C++. This means it’s still a little… primative in a desktop context.
  • The scripting language is kind of… strange. It is very weakly typed (e.g. inspecting the code you can’t be sure if a symbol is a property or a method or a signal or an element or a reference to a C++ class). This is really, really confusing.
  • The language uses a sort of “inner class” idiom like in Java.
  • It’s interpreted, so typos likemy_symbol/mySymbol will not be detected until run-time. (In fact, this is a drawback of Qt signals/slots as a whole.)
  • Concepts like QAction and QMenu are missing, and will probably never be added. They’ve been branded as obsolete, old thinking with respect to UI design. While I don’t necessarily disagree… the loss of them takes some getting used to.
  • It’s new, and the documentation is still developing. For example, none of the examples that I could find show any sort of in-depth C++/QML interaction. Most of the examples use JavaScript to implement the application logic.

All in all, I think that the good out-weighs the bad.

Since I don’t know how to use QML effectively, the following few blogs will share my journey and what I’ve learned. I’ll do so by writing a very simple calculator application.

That’s also the caveat: I’m writing this as I go… so I probably just said something dumb. 🙂