Tuesday, 20 January 2015

HsQML released: Control those Contexts

Happy New Year! Another year and another new release of HsQML is out, the Haskell binding to the Qt Quick framework that's kind to your skin. As usual, it's available for download from Hackage and immediate use adding a graphical user-interface to your favourite Haskell program.

The major new feature in this release is the addition of the OpenGLContextControl QML item to the HsQML.Canvas module. Previously, the OpenGL canvas support introduced in left programs at the mercy of Qt to configure the context on their behalf and there was no way to influence this process. That was a problem if you want to use the latest OpenGL features because they require you to obtain a newfangled Core profile context whereas Qt appears to default to the Compatibility profile (or just plain OpenGL 2.x if that's all you have).

To use it, simply place an OpenGLContextControl item in your QML document inside the window you want to control and set the properties to the desired values. For example, the following snippet of code would request the system provide it with a context supporting at least the OpenGL 4.1 Core profile:

import HsQML.Canvas 1.0

OpenGLContextControl {
    majorVersion: 4;
    minorVersion: 1;
    contextType: OpenGLContextControl.OpenGL;
    contextProfile: OpenGLContextControl.CoreProfile;

The supported properties are all detailed in the Haddock documentation for the Canvas module. There's also a more sophisticated example in the corresponding new release of the hsqml-demo-samples package. This example, hsqml-opengl2, displays the current context settings and allows you to experiment with requesting different values.

This graphics chip-set has seen better days.

Also new in this release, i) the defSignalNamedParams function allows you to give names to your signal parameters and ii) the EngineConfig record has been extended to allow setting additional search paths for QML modules and native plugins..

The first point is an interesting one because, harking back, my old blog post on the Connections item, doesn't actually demonstrate passing parameters to the signal handler and that's because you couldn't ordinarily. You could connect a function to the signal manually using the connect() method in QML code and access arguments positionally that way, or written the handler to index into the arguments array for it's parameters if you were willing to stoop that low. Now, you can give the parameters names and they will automatically be available in the handler's scope.

Finally, the Template Haskell shims inside Setup.hs have been extended to support the latest version of the Cabal API shipping with version 1.22. The Template-free SetupNoTH.hs remains supporting 1.18 ≤ n < 1.22 will continue to do so at least until Debian upgrades their Cabal package. Setup.hs will now try to set QT_SELECT if you're running a recent enough version of GHC to support setting environment variables and this can prevent some problems with qtchooser(1).

release- - 2015.01.20

  * Added support for Cabal 1.22 API.

  * Added facility for controlling the OpenGL context.
  * Added defSignal variant with ability to set parameter names.
  * Added option for setting the module and plugin search paths.
  * Changed Setup script to set QT_SELECT (base >= 4.7).
  * Fixed crash resizing canvas in Inline mode.
  * Fixed leaking stable pointers when objects are collected.
  * Fixed Canvas delegate marshaller to fail on invalid values.
  * Fixed discrepancy between kinds of type conversion.

Thursday, 4 December 2014

HsQML released: London Edition

Last week I gave a talk to the London Haskell User Group on my GUI library HsQML. The slides are available now and a video of the talk will be posted on the group's YouTube channel in due course (I'll post again when that happens).

The most distinctive, some might say contentious, thing about HsQML compared to other Haskell GUI libraries is the split between implementing the back-end logic of an application in Haskell and describing its user interface using the QML domain specific language. This tends to frighten people off and I was at pains to stress that while QML does have inbuilt scripting capabilities, we can build real applications with just a thin layer of QML over our Haskell code.

The talk walking through the implementation of a new sample "sticky notes" application. Here, the Haskell back-end takes care of persisting the user's data in an SQLite database and exposes a data model to QML. Several alternate QML front-ends then show how the same data model can be skinned with different user interfaces.

One of the sticky notes application's front-ends uses Qt Quick Controls for a native look and feel, shown here on three platforms.

Belatedly also, I'm announcing version of HsQML which debuted on Hackage at the week-end. This minor release fixes a couple of bugs. Most notably, that fact that HsQML was leaking the QApplication object and this caused programs to occasionally crash on exit under Linux. HsQML now ships an OnExitHook() which should shutdown the Qt framework when the GHC RTS does, or alternatively you can call the new shutdownQt function to do it manually.

release- - 2014.11.29

  * Added function to shutdown the Qt framework.
  * Fixed intermittent crash on exit under Linux.
  * Fixed reanimated objects being passed to QML as undefined.
  * Fixed typo in the names of implicit property signals.

Friday, 14 November 2014

HsQML released: Enters the Third Dimension

Last night I released HsQML, the latest edition of my Haskell binding to the Qt Quick GUI library. As usual, it's available for download from Hackage.

HsQML allows you to bind declarative user interfaces written in QML against a Haskell back-end, but sometimes you can't just let QML hog all the graphical fun to itself. This latest release allows you incorporate 3D (OpenGL) graphics rendered from Haskell into your QML scenes using the new Canvas module.

The screenshot below shows off the OpenGL demo in the samples package. The colourful triangle is rendered using the regular Haskell Platform's OpenGL bindings, but HsQML sets up the environment so that it renders into a special HaskellCanvas element inside the QML scene. If you run the actual program you can see it being animated too, moving around and changing colour.

This release also adds the Objects.Weak module which allows you to hold weak references to QML objects and keep track of their life cycles using finalisers. The new FactoryPool abstraction uses these primitives to help you efficiently keep track of instances you've created, especially for when you need to fire change signals on them for data-binding.

London Haskell User Group

I've been fortunate enough to get a speaking slot at the London Haskell User Group and will be giving a talk on Building Pragmatic User Interfaces in Haskell with HsQML on the 26th of November. Please feel free to come along and watch. You can RSPV on the group's meet-up page.

The talk should be videoed and materials will be available online afterwards.

release- - 2014.11.13

  * Added OpenGL canvas support.
  * Added weak references and object finalisers.
  * Added FactoryPool abstraction.
  * Added To-only custom marshallers.
  * Added Ignored type.
  * Relaxed Cabal dependency constraint on 'text'.

Saturday, 2 August 2014

HsQML released: One Thousand Downloads

A few days ago I released HsQML, a bug fix to my Haskell binding to the Qt Quick GUI library. You can download the latest release from Hackage as usual.

The primary purpose of this release was to fix issue 20. HsQML has code which monitors variant values created using the Qt library in order to prevent objects which are referenced by a variant from being garbage collected. A flaw in this code caused it to examine the data held inside variants even when it wasn't valid, causing a crash in certain circumstances.

release- - 2014.07.31

  * Fixed crash when storing Haskell objects in QML variants.
  * Fixed corrupted logging output caused by threading.

In related news, HsQML has now reached over 1000 downloads from Hackage since Hackage 2 started collecting download statistics late last year. See the bar chart below:-

The spike in May was owed to the transition to Qt 5 brought about by the release of Hopefully, the graph will climb to new heights with the release of more features in the future!

My target for the next release is to support rendering OpenGL graphics directly from Haskell code and into the QML scene, to better support applications with sophisticated requirements for custom drawing. This is tracked by issue 10.

Friday, 4 July 2014

Scaling content in QML

A HsQML user e-mailed me to ask me how they could get a QML Item to fill the parent Window and I thought it would make an interesting blog post. The easy answer to that question is to use anchors to snap the boundaries of the Item to its parent's as follows:

Item {
    anchors.fill: parent;

However, in a sense, that only defers the layout problem to the Item's children. They still need to position themselves in the variable amount of space offered by their parent, either using anchors again, one of the special layout elements such as Grid or GridLayout, or by property binding each child's positioning properties (x, y, etc.) to a custom layout calculation.

Qt Quick has a number of facilities to help you to lay out your Items, but there's one particular problem that it takes a few stabs at but still doesn't make especially easy. If you have an Item which has a particular aspect ratio, how do you scale it to fill the available space while still retaining the correct aspect?

The Image element solves this problem for itself with the fillMode property, which among other things allows you to preserve the source image aspect via either fitting or cropping. However, this property is specific to images and it doesn't affect any child elements you might want to position relative to the image. It does exposes the results of its calculations via the paintedWidth and paintedHeight properties so you could use this to help you place them manually, but it would still require a little work.

On the other hand, the QQuickView C++ class offers a solution at the top-level by extending the view to support scaling QML content automatically. If HsQML used this convenience class to display its QML documents that don't have explicit Windows, it could be set to always resize the content to fit the window via the setResizeMode() method. However, this would only help to resize whole documents and then only when explicit windows weren't used.

Fortunately, it's not too difficult to build an implementation of scale-to-fit using transforms and property binding. This involves specifying both a scaling transform on the content Item to size it to fit its parent and a translating transform to centre the content if the parent has a different aspect. Any children of content Item will be positioned according to the coordinate system specified by the content Item's fixed dimensions and will be transformed along with the Item to the desired size.

The scale factor and offsets can be calculated by expressions which make use of the parent Item or Window's width and height properties. QML's property binding facility means that whenever the width or height changes, the expressions which use those values will be re-evaluated and hence the layout updated. The following example demonstrates implementing this with an explicit Window element in order to make its properties accessible for binding:

import QtQuick 2.0
import QtQuick.Window 2.0

Window {
    id: win; width: 200; height: 200;

    Rectangle {
        id: rect; width: 100; height: 100; color: 'blue';

        transform: [
            Scale {
                id: scale; xScale: yScale;
                yScale: Math.min(
            Translate {
                x: (win.width-rect.width*scale.xScale)/2;
                y: (win.height-rect.height*scale.yScale)/2;}]

        Rectangle {
            x: 0; y: 0; width: 50; height: 50; color: 'red';

This can also be made to work when you don't have an explicit Window by accessing its properties via the parent property of the root Item. The important thing to note here is that the root's parent will be initially be null when the document loads. It's only when HsQML notices that the root element isn't a Window that it will create the implicit Window for you, so a little care has to be taken to ensure that the parent's properties aren't accessed until the parent has actually been set. I took the opportunity to implement this in the Morris demo application which didn't previously handle scaling correctly, or you can look at the example code below:

Rectangle {
    id: rect; width: 100; height: 100; color: 'blue';

    property real pw : parent!=null?parent.width:width;
    property real ph : parent!=null?parent.height:height;

    transform: [
        Scale {
            id: scale; xScale: yScale;
            yScale: Math.min(
        Translate {
            x: (rect.pw-board.width*scale.xScale)/2;
            y: (rect.ph-board.height*scale.yScale)/2;}]

N.B. Nothing in this post is really specific to HsQML and you can equally try out these examples with the qmlscene tool.

Sunday, 22 June 2014

Windows Qt binaries for the Haskell Platform (HsQML)

Since upgrading to Qt 5, the installation procedure for HsQML, my Qt Quick binding for Haskell, has been been less than ideal on Windows. This is because the official Qt SDK for Windows now uses a much newer version of MinGW than ships with GHC or the Haskell Platform and the two are no longer binary compatible. Binaries compiled by GHC using these Qt libraries simply crash on start-up.

It has always been possible to work around this problem by modifying GHC's configuration files to use the C compiler from Qt's MinGW rather than its own. However, this is a rather awkward thing to have to do and, regrettably, the instructions on my web-site for doing it weren't terribly clear.

I have now produced a special build of Qt 5.3.0 using GHC's MinGW which should work out of the box. The download and updated instructions are available from the Windows section on the HsQML web-site. Hopefully this will make getting HsQML running on Windows much simpler.

Longer term, GHC ticket #9218 tracks updating the version of MinGW which ships with GHC to something more recent.

Technical Details

I began by making a straightforward build of ICU 53.1, which is a Qt dependency, and then configured the Qt source tree to make a release build using the desktop OpenGL graphics stack as follows:

configure -opensource -release -opengl desktop -no-angle -skip qtwinextras -prefix C:\qt530-hp

The one oversight here was not using the -no-sseX flags to limit the use of instructions set extensions. I presume therefore that build targeted the host machine and may not work on processors which don't support SSE 4.1 or later. The QtWinExtras module relied to too heavily on functionality missing from the older MinGW headers and so I had to disable it.

Once the build was under way I ran into a few minor tool-chain issues which I resolved as follows:-
  • Remove some flags which are unsupported by the older compiler. Namely -fno-keep-inline-dllexport in qtbase/mkspecs/win32-g++/qmake.conf and -Wno-error=unused-but-set-variable in qtwebkit/Source/ThirdParty/leveldb/Target.pri.
  • Redirect required symbols missing from MinGW to suitable alternatives. Namely YieldProcessor to _mm_pause, MemoryBarrier to _mm_mfence, strcasecmp to _stricmp, strncasecmp to _strnicmp, strdup to _strdup, _exit to _Exit, and _MAX_PATH to MAX_PATH.
  • Change the name of the GUID member of the VMRGUID structure in MinGW's strmif.h so that it doesn't have the same name as its type.
  • Add the missing header file delayimp.h by copying it from a newer version of MinGW.
When I repeat this process for the next release of Qt 5, I will prepare a proper diff against the MinGW headers to make this set up more easily reproducible.

Finally, when testing the resulting binaries, I found a MinGW-specific bug which had been introduced in the Qt 5.3 release and causes it to intermittently crash. This has been filed as QTBUG-39793 and the patch attached to that bug was applied to this build.

Wednesday, 11 June 2014

HsQML released

I've just released HsQML which, as usual, is available for download from Hackage. This release fixes several stability issues and also introduces a facility for defining properties with the CONST attribute.

If you use a property defined on one of your Haskell objects in a QML expression and that property doesn't have an associated signal, then Qt will print the following warning:

Expression depends on non-NOTIFYable properties

For mutable objects, the accurately informs us that QML has no way of knowing if the value of that property changes. However, when using Haskell, we often prefer to work with immutable values and there was previously no way of informing Qt that the value would never change. Previously, the only course of action was to specify a dummy signal or to use nullary methods instead of properties. You can now use the new defPropertyConst function instead of defPropertyRO to specify that an associated signal is unnecessary and suppress this warning.

As an aside, Christopher Reichert has just written a blog post about using HsQML which is well worth the read.

release- - 2014.06.11

  * Added properties with constant annotation.
  * Added runtime warning for users of the non-threaded RTS.
  * Added non-TH version of Setup.hs.
  * Relaxed Cabal dependency constraint on 'transformers'.
  * Fixed premature garbage collection of QML objects.
  * Fixed intermittent crash on exit when firing signals.
  * Fixed crash when using Cmd-Q to exit on MacOS.