I am trying to develop some program in QT with QT SDK. Yesterday I was reading about Unity Launcher API on official ubuntu website. But there is example only for Vala and python. Is possible to use Unity Launcher API(quicklists, counters, and progress bars) with C++ language and if it's possible, please post an example.


Solution 1:

I'm also learning Qt and tried to find a way to use Unity API in Qt , I could only use Dbus API , but no luck with Quicklist since it needs a DbusMenu and I do not know how to implement that (still learning :) ).

This is the example I created for my self and I hope it's useful for others . Maybe Unity devs can help to correct / fix / add new code (quicklist) to it :)

/*
    Unity Launcher Dbus API exmable for Qt
    foxoman [gplus.to/foxoman][[email protected]]

    https://wiki.ubuntu.com/Unity/LauncherAPI#Low_level_DBus_API:_com.canonical.Unity.LauncherEntry

    First step : add this line to your Qt project file .pro
     QT       += dbus
*/

/* I will run this example as Qt console apps */
#include <QtCore/QCoreApplication>

/* Include Qt Dbus required */
#include <QtDBus>

// Qt Main Method
int main(int argc, char *argv[])
{


    /* Qt console Main Loop [ in GUI application the Main loop is QApplication ]
        Unity API need Main Loop to run */
    QCoreApplication a(argc, argv);


    /* Create Qt Dbus Signal to send Dbus Message to unity Dbus API
        signal com.canonical.Unity.LauncherEntry.Update (in s app_uri, in a{sv} properties)
    */
    QDBusMessage signal = QDBusMessage::createSignal(
     "/", /* Path */
     "com.canonical.Unity.LauncherEntry", /* Unity DBus Interface */
     "Update"); /* Update Signal */


    /* app_uri
       Desktop ID ex: firefox -> need to be pined in the launcher to see the effect
    */
    signal << "application://firefox.desktop";


    /* properties : A map of strings to variants with the properties to set on the launcher icon */
    QVariantMap setProperty;

    /* A number to display on the launcher icon */
    setProperty.insert("count", qint64(80));

    /* show count */
    setProperty.insert("count-visible", true);

    /* progress bar count must be float between 0 and 1 (mean from 0.00 to 0.100)*/
    setProperty.insert("progress", double(0.80));

    /* show progress bar */
    setProperty.insert("progress-visible", true);

    /* Tells the launcher to get the users attention  */
    setProperty.insert("urgent",true);

    /* Pack the properties Map to the signal */
    signal << setProperty;

    /* Send the signal */
    QDBusConnection::sessionBus().send(signal);


    return a.exec();
}

download the example here http://ubuntuone.com/1SLDPcN9OhrU6LD1wgDs3r

Solution 2:

There is not currently a specific library for accessing launcher functionality from Qt C++. There is a libunity library but this is heavily glib oriented so is relatively unsuited to Qt. As mentioned in the other answer, the most convenient way to integrate with the launcher is to use the low level dbus API.

The basic concept of how to integrate with the launcher is you send a signal to the launcher with an application ID and a set of properties. The application ID is the file name of the .desktop file, normally stored in /usr/share/applications:

//create the signal
QDBusMessage signal = QDBusMessage::createSignal("/", 
    "com.canonical.Unity.LauncherEntry", "Update");

//set the application ID
signal << "application://firefox.desktop";

//set the properties
QVariantMap properties;
    ...
signal << properties;

//send the signal
QDBusConnection::sessionBus().send(signal);

Counter

To set the counter, you will need to set the properties such that the count is visible and give it the desired integer value:

qint64 counter_value = 1;
properties["count-visible"] = true; //set the count to visible
properties["count"] = counter_value; //set the counter value

Progress Bar

To set the progress bar, you will need to set the properties such that the progress is visible and give it the desired double value:

double progress_value = 0.5;
properties["progress-visible"] = true; //set the progress bar to visible
properties["progress"] = progress_value; //set the progress value

Quicklist

The quicklist can be set by using the dbusmenu Qt library. You will need to include the header file:

#include <dbusmenuexporter.h>

The quicklist is created as a QMenu menu in Qt. This menu is 'exported' over dbusmenu using a DBusMenuExporter object. When exporting, you give this object a unique path and then reference that path to tell the launcher item which menu to display as a quicklist.

In your main window class declaration, add the following instance variables:

QMenu *quicklist;
DBusMenuExporter *quicklist_exporter;

Then, in the constructor function:

quicklist = new QMenu(this);
//exports the menu over dbus using the object: /com/me/myapp/quicklist
quicklist_exporter = new DBusMenuExporter("/com/me/myapp/quicklist", quicklist);

To add items to the menu, use the [addAction](http: //qt-project.org/doc/qt-5.0/qtwidgets/qmenu.html#addAction) method of the menu to add [QAction](http: //qt-project.org/doc/qt-5.0/qtwidgets/qaction.html) objects.

To set the quicklist of the launcher icon, set the 'quicklist' property of the signal:

properties["quicklist"] = "/com/me/myapp/quicklist";

Configuring the Project File

You will need to configure the .pro file to add dbus support: QT += dbus. In order to build with quicklist support, you will need to have the dbusmenu-qt development libraries (libdbusmenu*dev) installed. You can then add the following to the project file to include the dbusmenu library:

#import the dbusmenu-qt library for quicklists
greaterThan(QT_MAJOR_VERSION, 4) {
    INCLUDEPATH += /usr/include/dbusmenu-qt5/
    LIBS += -ldbusmenu-qt5
} else {
    INCLUDEPATH += /usr/include/dbusmenu-qt/
    LIBS += -ldbusmenu-qt
}

Example Application

To see an full example using all of the launcher functionality from Qt, look at this Github project.