How to customize "Notification Web API" in Qt?

3

I'm creating a simple browser using QtWebkit and added it the "support" for Notification Web API using QWebPage::setFeaturePermission .

An example:

function notifyMe() {
    if (Notification.permission === "granted") {
        var notification = new Notification("Hi there!");
    } else if (Notification.permission !== "denied") {
        Notification.requestPermission(function(permission) {
            if (permission === "granted") {
                var notification = new Notification("Hi there!");
            }
        });
    }
}

<button onclick="notifyMe();">Notify me</button>

Code:

QObject::connect(page,
    SIGNAL(featurePermissionRequested(QWebFrame*, QWebPage::Feature)), this,
    SLOT(featurePermissionRequested(QWebFrame*,QWebPage::Feature))
);

...

void Form::featurePermissionRequested(QWebFrame* frame, QWebPage::Feature feature) {
    switch (feature) {
        case QWebPage::Notifications:
            qDebug() << "Notification";
            page->setFeaturePermission(frame, feature, QWebPage::PermissionGrantedByUser);
        break;
        case QWebPage::Geolocation:
            qDebug() << "GEO";
        break;
        default:
            qDebug() << "Unknown feature";
    }
}

Whenever I click the "Notify me" button the following message will appear on the Desktop:

Inotherwords,itworksperfectly,butIwonderifitispossibleto"customize" the "notifications" in Qt?

In other words, I'd like them to be similar to GoogleChrome or Firefox, something like this:

    
asked by anonymous 03.03.2015 / 18:46

1 answer

1

In order to customize Notifications Web API in QtWebkit you will need to use "Webkit plugins", that is, create a plugin and put it in the qtdir/plugins/webkit directory.

  

Note: To create the plugins you will need to use the "header" <QtWebKit/QWebKitPlatformPlugin>

Creating a Webkit plugin:

  • Create a project in QtCreator
  • In the file .pro (example src.pro ) add this:

    TARGET = $$qtLibraryTarget(meupluginwebkit)
    TEMPLATE = lib
    CONFIG += plugin
    
    HEADERS += $$[QT_INSTALL_HEADERS]/QtWebKit/qwebkitplatformplugin.h \
        meupluginwebkit.h
    
    SOURCES += \
        meupluginwebkit.cpp
    
    DESTDIR = $$PWD/bin-plugin
    OBJECTS_DIR = $$PWD/build-plugin
    MOC_DIR = $$PWD/build-plugin
    RCC_DIR = $$PWD/build-plugin
    UI_DIR = $$PWD/build-plugin
    
  • Create the mypluginwebkit.h file in the project folder

    #ifndef MEUPLUGINWEBKIT_H
    #define MEUPLUGINWEBKIT_H
    
    #include <QtWebKit/QWebKitPlatformPlugin>
    
    class meupluginwebkit : public QObject, public QWebKitPlatformPlugin
    {
        Q_OBJECT
        Q_INTERFACES(QWebKitPlatformPlugin)
    
    #if QT_VERSION >= 0x050000
        Q_PLUGIN_METADATA(IID "org.qtwebkit.QtWebKit.QtWebPlugin")
    #endif
    
    public:
        explicit meupluginwebkit();
        ~meupluginwebkit();
    
        bool supportsExtension(Extension ext) const;
        QObject* createExtension(Extension ext) const;
    };
    
    #endif // MEUPLUGINWEBKIT_H
    
  • Create the mypluginwebkit.cpp file in the project folder

    #include "meupluginwebkit.h"
    #include "notification/notification.h"
    
    meupluginwebkit::meupluginwebkit()
    {
    }
    
    meupluginwebkit::~meupluginwebkit()
    {
    }
    
    bool meupluginwebkit::supportsExtension(Extension ext) const
    {
        return ext == Notifications;
    }
    
    QObject* meupluginwebkit::createExtension(Extension ext) const
    {
        switch (ext) {
            case Notifications:
                return new Notification();
    
            default:
                return 0;
        }
    }
    
    //Para QT-4.8
    #if QT_VERSION < 0x050000
    Q_EXPORT_PLUGIN2(webkitplugin, meupluginwebkit);
    #endif
    
  • Create a folder named notification

    in the project folder
  • In the notification folder add the following files:

    notification.h

    #ifndef NOTIFICATION_H
    #define NOTIFICATION_H
    
    #include <QtWebKit/QWebKitPlatformPlugin>
    
    class Notification : public QWebNotificationPresenter
    {
        Q_OBJECT
    
    public:
        explicit Notification();
        ~Notification();
    
        void showNotification(const QWebNotificationData* data);
    
    signals:
        void notificationClosed();
        void notificationClicked();
    };
    
    #endif // NOTIFICATION_H
    

    notification.cpp

    #include "notification.h"
    #include <QDebug>
    
    Notification::Notification() : QWebNotificationPresenter()
    {
        qDebug() << "Create: Notification";
    }
    
    Notification::~Notification()
    {
        qDebug() << "Delete: this (Notification)";
    }
    
    void Notification::showNotification(const QWebNotificationData* data)
    {
        qDebug() << "titulo:" << data->title();
        qDebug() << "icone:" << data->iconUrl();
        qDebug() << "mensagem:" << data->message();
        qDebug() << "pagina que chamou a notificação:" << data->openerPageUrl();
    }
    

In the example I used qDebug just to understand how to capture the data, to create your custom notification, you will probably have to use QWidget

  • Create the notification.pri file in the notification folder:

    QT += network
    
    HEADERS += \
        $$PWD/notification.h
    
    SOURCES += \
        $$PWD/notification.cpp
    
  • Include notification.pri in src.pro :

    include($$PWD/notification/notification.pri)
    

Compiling the src.pro :

  • Open the src.pro project in QtCreator (if it is not already open)
  • Click the " Build " button (the drawing of the hammer, or use Ctrl + B) - Note: Do not click the "Run" li>
  • Close the src.pro
  • Open the folder where the file src.pro
  • Open the bin-plugin
  • Copy the file meupluginwebkit.dll to QtDir/plugins/webkit/meupluginwebkit.dll (exexample with mingw: C:/qt/qt5.4/mingw/plugin/webkit/meupluginwebkit.dll )
  • If the webkit folder does not exist, then create it.
  • Open your project that is using QWebView and test JavaScript using Notification Web API .

When you run the project using QWebView , it will automatically load dll from the webkit folder, so no other configuration type is required and this will replace the default QtWebkit notification system ( which in the case in Windows uses SystemTrayIcon ) for its custom widget .

    
14.03.2015 / 19:42