├── debian ├── compat ├── source │ └── format ├── libqtmozembed.install ├── libqtmozembed-dev.install ├── changelog ├── README.Debian ├── README.Fremantle ├── control └── rules ├── tests ├── auto │ ├── mer-qt5 │ ├── shared │ │ ├── downloadmgr │ │ │ └── tt.bin │ │ ├── newviewrequest │ │ │ └── newwin.html │ │ ├── ViewComponent.qml │ │ ├── ViewComponentQt5.qml │ │ ├── promptbasic │ │ │ └── prompt.html │ │ ├── searchengine │ │ │ └── test.xml │ │ ├── passwordmgr │ │ │ └── subtst_notifications_1.html │ │ ├── favicons │ │ │ └── favicon.html │ │ ├── multitouch │ │ │ └── touch.html │ │ └── componentCreation.js │ ├── run-tests.sh │ ├── mer-qt4 │ │ ├── basicview │ │ │ └── tst_basicview.qml │ │ ├── view │ │ │ └── tst_viewtest.qml │ │ ├── context │ │ │ └── tst_basicmozcontext.qml │ │ ├── favicons │ │ │ └── tst_favicon.qml │ │ ├── newviewrequest │ │ │ └── tst_newviewrequest.qml │ │ ├── selection │ │ │ └── tst_selection.qml │ │ ├── basicscroll │ │ │ └── tst_scrolltest.qml │ │ ├── passwordmgr │ │ │ └── tst_passwordmgr.qml │ │ ├── multitouch │ │ │ └── tst_multitouch.qml │ │ ├── downloadmgr │ │ │ └── tst_downloadmgr.qml │ │ ├── searchengine │ │ │ └── tst_searchengine.qml │ │ ├── basicinput │ │ │ └── tst_inputtest.qml │ │ └── promptbasic │ │ │ └── tst_prompt.qml │ └── desktop-qt5 │ │ ├── basicview │ │ └── tst_basicview.qml │ │ ├── view │ │ └── tst_viewtest.qml │ │ ├── context │ │ └── tst_basicmozcontext.qml │ │ ├── viewbasicapi │ │ └── tst_viewbasicapi.qml │ │ ├── favicons │ │ └── tst_favicon.qml │ │ ├── newviewrequest │ │ └── tst_newviewrequest.qml │ │ ├── selection │ │ └── tst_selection.qml │ │ ├── basicscroll │ │ └── tst_scrolltest.qml │ │ ├── linksactivation │ │ └── tst_activatelinks.qml │ │ ├── passwordmgr │ │ └── tst_passwordmgr.qml │ │ ├── multitouch │ │ └── tst_multitouch.qml │ │ ├── downloadmgr │ │ └── tst_downloadmgr.qml │ │ ├── searchengine │ │ └── tst_searchengine.qml │ │ ├── basicinput │ │ └── tst_inputtest.qml │ │ └── promptbasic │ │ └── tst_prompt.qml ├── components │ ├── TestHelpers.manifest │ └── tests │ │ └── content │ │ └── testHelper.js ├── tests.pro ├── qmlmoztestrunner │ ├── qmlmoztestrunner.pro │ ├── testviewcreator.h │ ├── testviewcreator.cpp │ ├── qtestrunner.h │ ├── qtestrunner.cpp │ └── main.cpp ├── test-definition │ └── tests.xml └── test-definition-qt5 │ └── tests.xml ├── qmlplugin5 ├── qmldir ├── qmlmozcontext.h ├── qmlmozcontext.cpp ├── qmlplugin5.pro └── main.cpp ├── qtmozembed.pro ├── relative-objdir.pri ├── .gitignore ├── src ├── geckoworker.cpp ├── qmozviewcreator.h ├── geckoworker.h ├── qmozembedlog.h ├── EmbedQtKeyUtils.h ├── qmozextmaterialnode.h ├── qmozscrolldecorator.h ├── qmozgrabresult.h ├── qmoztexturenode.h ├── qmozscrolldecorator.cpp ├── qmozwindow.h ├── qmozwindow_p.h ├── qmoztexturenode.cpp ├── qmozembed.pri ├── qmessagepump.h ├── src.pro ├── qmozcontext.h ├── qmozwindow.cpp ├── qmessagepump.cpp ├── qopenglwebpage.h ├── qmozwindow_p.cpp ├── quickmozview.h ├── qmozextmaterialnode.cpp ├── qmozview_templated_wrapper.h ├── qmozview_p.h ├── qmozgrabresult.cpp ├── qmozview_defined_wrapper.h ├── EmbedQtKeyUtils.cpp └── qmozcontext.cpp ├── link_to_system.sh └── rpm └── qtmozembed-qt5.spec /debian/compat: -------------------------------------------------------------------------------- 1 | 5 2 | -------------------------------------------------------------------------------- /tests/auto/mer-qt5: -------------------------------------------------------------------------------- 1 | desktop-qt5 -------------------------------------------------------------------------------- /debian/source/format: -------------------------------------------------------------------------------- 1 | 3.0 (native) 2 | -------------------------------------------------------------------------------- /debian/libqtmozembed.install: -------------------------------------------------------------------------------- 1 | usr/lib/lib*.so.* 2 | -------------------------------------------------------------------------------- /tests/auto/shared/downloadmgr/tt.bin: -------------------------------------------------------------------------------- 1 | ELF 2 | -------------------------------------------------------------------------------- /qmlplugin5/qmldir: -------------------------------------------------------------------------------- 1 | module Qt5Mozilla 2 | plugin qmlmozembedpluginqt5 3 | -------------------------------------------------------------------------------- /tests/components/TestHelpers.manifest: -------------------------------------------------------------------------------- 1 | content tests tests/content/tests 2 | -------------------------------------------------------------------------------- /debian/libqtmozembed-dev.install: -------------------------------------------------------------------------------- 1 | usr/include/q*.h 2 | usr/lib/lib*.so 3 | usr/lib/pkgconfig/* 4 | -------------------------------------------------------------------------------- /debian/changelog: -------------------------------------------------------------------------------- 1 | qtmozembed (0.1) unstable; urgency=low 2 | 3 | * Initial Release. 4 | 5 | -- unknown Mon, 04 Feb 2013 07:56:28 -0800 6 | -------------------------------------------------------------------------------- /qtmozembed.pro: -------------------------------------------------------------------------------- 1 | TEMPLATE = subdirs 2 | CONFIG += ordered 3 | SUBDIRS = src 4 | SUBDIRS += qmlplugin5 5 | qmlplugin5.depends = src 6 | 7 | isEmpty(NO_TESTS) { 8 | SUBDIRS += tests 9 | } 10 | -------------------------------------------------------------------------------- /debian/README.Debian: -------------------------------------------------------------------------------- 1 | qtmozembed for Debian 2 | ------------------------------- 3 | 4 | 5 | 6 | -- unknown Mon, 04 Feb 2013 07:56:28 -0800 7 | -------------------------------------------------------------------------------- /debian/README.Fremantle: -------------------------------------------------------------------------------- 1 | embedlite-components for Fremantle 2 | ------------------------------- 3 | 4 | You need to install maemo-optify and maemo-sdk-dev, although not mentioned in debian/control. 5 | 6 | -- Marcin Mielniczuk Fri, 22 Nov 2013 19:12:30 +0100 7 | 8 | -------------------------------------------------------------------------------- /relative-objdir.pri: -------------------------------------------------------------------------------- 1 | OBJECTS_DIR = $$RELATIVE_PATH/$$OBJ_BUILD_PATH/$$VDEPTH_PATH 2 | DESTDIR = $$RELATIVE_PATH/$$OBJ_BUILD_PATH/$$VDEPTH_PATH 3 | MOC_DIR = $$RELATIVE_PATH/$$OBJ_BUILD_PATH/$$VDEPTH_PATH/moc/release_static 4 | RCC_DIR = $$RELATIVE_PATH/$$OBJ_BUILD_PATH/$$VDEPTH_PATH/rcc/release_static 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | Makefile 2 | build-stamp 3 | configure-stamp 4 | debian/files 5 | debian/libqtmozembed-dbg/ 6 | debian/libqtmozembed-dev/ 7 | debian/libqtmozembed.postinst.debhelper 8 | debian/libqtmozembed.postrm.debhelper 9 | debian/libqtmozembed.substvars 10 | debian/libqtmozembed/ 11 | debian/tmp/ 12 | objdir-*/ 13 | -------------------------------------------------------------------------------- /tests/auto/shared/newviewrequest/newwin.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | NewWinExample 4 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /tests/auto/shared/ViewComponent.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 1.0 2 | import QtMozilla 1.0 3 | 4 | QmlMozView { 5 | id: webViewport 6 | parentid: appWindow.createParentID ? appWindow.createParentID : 0 7 | visible: true 8 | focus: true 9 | anchors.fill: parent 10 | Connections { 11 | target: webViewport.child 12 | onViewInitialized: { 13 | appWindow.mozViewInitialized = true 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/tests.pro: -------------------------------------------------------------------------------- 1 | TEMPLATE = subdirs 2 | 3 | SUBDIRS = qmlmoztestrunner 4 | 5 | OTHER_FILES += auto/* auto/scripts/* 6 | 7 | auto.files = auto/* 8 | auto.path = /opt/tests/qtmozembed/auto 9 | 10 | components.files = components/* 11 | components.path = /opt/tests/qtmozembed/components 12 | 13 | definition.files = test-definition-qt5/tests.xml 14 | definition.path = /opt/tests/qtmozembed/test-definition 15 | 16 | INSTALLS += auto definition components 17 | -------------------------------------------------------------------------------- /tests/auto/shared/ViewComponentQt5.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | import Qt5Mozilla 1.0 3 | 4 | QmlMozView { 5 | id: webViewport 6 | parentid: appWindow.createParentID ? appWindow.createParentID : 0 7 | clip: false 8 | visible: true 9 | focus: true 10 | anchors.fill: parent 11 | Connections { 12 | target: webViewport.child 13 | onViewInitialized: { 14 | appWindow.mozViewInitialized = true 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /tests/auto/shared/promptbasic/prompt.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 15 | 16 | 17 |
18 | 19 | 20 | -------------------------------------------------------------------------------- /tests/auto/shared/searchengine/test.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | QMOZTest 7 | Qt Moz Embed search 8 | UTF-8 9 | 10 | https://webhook/ 11 | 12 | -------------------------------------------------------------------------------- /qmlplugin5/qmlmozcontext.h: -------------------------------------------------------------------------------- 1 | #ifndef QMLMOZCONTEXT_H 2 | #define QMLMOZCONTEXT_H 3 | 4 | #include 5 | #include "qmozcontext.h" 6 | 7 | /*! 8 | * Declarative wrapper for singleton. 9 | */ 10 | class QmlMozContext : public QQuickItem 11 | { 12 | Q_OBJECT 13 | Q_PROPERTY(QObject* instance READ instance CONSTANT) 14 | 15 | public: 16 | QObject* instance() const; 17 | Q_INVOKABLE QString getenv(const QString envVarName) const; // Within this function I call the system getenv() function. 18 | public Q_SLOTS: 19 | void waitLoop(bool mayWait = true, int aTimeout = -1); 20 | void dumpTS(const QString& msg); 21 | }; 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /tests/auto/shared/passwordmgr/subtst_notifications_1.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Subtest for Login Manager notifications 4 | 5 | 6 |

Subtest 1

7 |
8 | 9 | 10 | 11 |
12 | 13 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /tests/qmlmoztestrunner/qmlmoztestrunner.pro: -------------------------------------------------------------------------------- 1 | TEMPLATE = app 2 | TARGET = qmlmoztestrunner 3 | CONFIG += warn_on link_pkgconfig 4 | SOURCES += main.cpp qtestrunner.cpp testviewcreator.cpp 5 | HEADERS += qtestrunner.h testviewcreator.h 6 | 7 | RELATIVE_PATH=../.. 8 | VDEPTH_PATH=tests/qmlmoztestrunner 9 | include($$RELATIVE_PATH/relative-objdir.pri) 10 | 11 | INCLUDEPATH+=$$RELATIVE_PATH/src 12 | LIBS+= -L$$RELATIVE_PATH/$$OBJ_BUILD_PATH/src -lqt5embedwidget 13 | 14 | isEmpty(DEFAULT_COMPONENT_PATH) { 15 | DEFINES += DEFAULT_COMPONENTS_PATH=\"\\\"/usr/lib/mozembedlite/\\\"\" 16 | } else { 17 | DEFINES += DEFAULT_COMPONENTS_PATH=\"\\\"$$DEFAULT_COMPONENT_PATH\\\"\" 18 | } 19 | 20 | PKGCONFIG += Qt5QuickTest 21 | QT += qml quick 22 | 23 | target.path = $$[QT_INSTALL_BINS] 24 | INSTALLS += target 25 | -------------------------------------------------------------------------------- /src/geckoworker.cpp: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-*/ 2 | /* vim: set ts=4 sw=4 et tw=79: */ 3 | /* This Source Code Form is subject to the terms of the Mozilla Public 4 | * License, v. 2.0. If a copy of the MPL was not distributed with this file, 5 | * You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 | 7 | #include "geckoworker.h" 8 | #include "nsDebug.h" 9 | #include "mozilla/embedlite/EmbedLiteApp.h" 10 | 11 | using namespace mozilla::embedlite; 12 | 13 | GeckoWorker::GeckoWorker(EmbedLiteApp* aApp, QObject* parent) 14 | : QObject(parent), 15 | mApp(aApp) 16 | { 17 | } 18 | 19 | void GeckoWorker::doWork() 20 | { 21 | mApp->StartChildThread(); 22 | } 23 | 24 | void GeckoWorker::quit() 25 | { 26 | printf("Call EmbedLiteApp::StopChildThread()\n"); 27 | mApp->StopChildThread(); 28 | deleteLater(); 29 | } 30 | -------------------------------------------------------------------------------- /src/qmozviewcreator.h: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-*/ 2 | /* This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this file, 4 | * You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 | 6 | #ifndef qmozviewcreator_h 7 | #define qmozviewcreator_h 8 | 9 | #include 10 | #include 11 | 12 | /* 13 | * QMozViewCreator abstract class defines interface for a view creator implemented in UI code. 14 | */ 15 | class QMozViewCreator : public QObject 16 | { 17 | Q_OBJECT 18 | 19 | public: 20 | explicit QMozViewCreator(QObject* parent = 0) : QObject(parent) {}; 21 | virtual ~QMozViewCreator() {}; 22 | 23 | /* 24 | * @returns ID of created web view 25 | */ 26 | virtual quint32 createView(const QString &url, const quint32 &parentId) = 0; 27 | }; 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /tests/auto/run-tests.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Create a temporary DBus session to isolate us from the normal environment. 4 | export `dbus-launch` 5 | if [ "$QTMOZEMBEDOBJDIR" != "" ]; then 6 | QMLMOZTESTRUNNER=$QTMOZEMBEDOBJDIR/tests/qmlmoztestrunner/qmlmoztestrunner 7 | export QML2_IMPORT_PATH=$QTMOZEMBEDOBJDIR/qmlplugin5 8 | else 9 | QMLMOZTESTRUNNER=/usr/lib/qt$QTVER/bin/qmlmoztestrunner 10 | export QML_IMPORT_PATH=/opt/tests/qtmozembed/imports 11 | fi 12 | CURDIR=$PWD 13 | export QTTESTSROOT=${QTTESTSROOT:-"/opt/tests/qtmozembed"} 14 | if [ "$QTTESTSLOCATION" != "" ]; then 15 | cd $QTTESTSLOCATION 16 | fi 17 | export QTTESTSLOCATION=${QTTESTSLOCATION:-"/opt/tests/qtmozembed/auto/mer-qt$QTVER"} 18 | 19 | #export NSPR_LOG_MODULES=EmbedLiteTrace:5,EmbedNonImpl:5,EmbedLiteApp:5,EmbedLiteView:5,EmbedLiteViewThreadParent:5 20 | 21 | $QMLMOZTESTRUNNER -opengl $@ 22 | exit_code=$? 23 | cd $CURDIR 24 | kill $DBUS_SESSION_BUS_PID 25 | 26 | exit $exit_code 27 | -------------------------------------------------------------------------------- /src/geckoworker.h: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-*/ 2 | /* vim: set ts=4 sw=4 et tw=79: */ 3 | /* This Source Code Form is subject to the terms of the Mozilla Public 4 | * License, v. 2.0. If a copy of the MPL was not distributed with this file, 5 | * You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 | 7 | #ifndef GECKOWORKER_H 8 | #define GECKOWORKER_H 9 | 10 | #include 11 | 12 | namespace mozilla { 13 | namespace embedlite { 14 | class EmbedLiteApp; 15 | }} 16 | 17 | /*! 18 | * An instance of this class runs in its own thread/event loop and is used to 19 | * host EmbedLiteApp's event loop. 20 | */ 21 | class GeckoWorker : public QObject 22 | { 23 | Q_OBJECT 24 | 25 | public: 26 | explicit GeckoWorker(mozilla::embedlite::EmbedLiteApp* aApp, QObject* parent = 0); 27 | 28 | public Q_SLOTS: 29 | void doWork(); 30 | void quit(); 31 | 32 | private: 33 | mozilla::embedlite::EmbedLiteApp* mApp; 34 | }; 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /src/qmozembedlog.h: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 2 | /* This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 | 6 | #ifndef QMOZ_EMBED_LOG_H 7 | #define QMOZ_EMBED_LOG_H 8 | 9 | #include 10 | #include 11 | 12 | #ifdef Q_DEBUG_LOG 13 | 14 | #ifdef LOG_COMPONENT 15 | #define LOGT(FMT, ...) fprintf(stderr, \ 16 | "EmbedLiteExt %s:%s:%d: " FMT "\n", LOG_COMPONENT, __FUNCTION__, __LINE__, ##__VA_ARGS__) 17 | #else // LOG_COMPONENT 18 | #define LOGT(FMT, ...) fprintf(stderr, \ 19 | "EmbedLiteExt %s:%d: " FMT "\n", __FUNCTION__, __LINE__, ##__VA_ARGS__) 20 | #endif // LOG_COMPONENT 21 | 22 | #else // Q_DEBUG_LOG 23 | 24 | #define LOGT(...) do {} while (0) 25 | 26 | #endif // Q_DEBUG_LOG 27 | 28 | #endif // QMOZ_EMBED_LOG_H 29 | -------------------------------------------------------------------------------- /src/EmbedQtKeyUtils.h: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 2 | /* vim:expandtab:shiftwidth=4:tabstop=4: 3 | */ 4 | /* This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 7 | 8 | #ifndef __EmbedQtKeyUtils_h__ 9 | #define __EmbedQtKeyUtils_h__ 10 | 11 | #include "nscore.h" 12 | #include 13 | 14 | class MozKey 15 | { 16 | public: 17 | static int QtModifierToDOMModifier(int aModifiers); 18 | static int QtKeyCodeToDOMKeyCode(int aKeysym, int aModifiers = 0); 19 | static int DOMKeyCodeToQtKeyCode(int aKeysym); 20 | 21 | static uint32_t* GetFlagWord32(uint32_t aKeyCode, uint32_t* aMask); 22 | static bool IsKeyDown(uint32_t aKeyCode); 23 | static void SetKeyDownFlag(uint32_t aKeyCode); 24 | static void ClearKeyDownFlag(uint32_t aKeyCode); 25 | }; 26 | 27 | #endif /* __EmbedQtKeyUtils_h__ */ 28 | -------------------------------------------------------------------------------- /debian/control: -------------------------------------------------------------------------------- 1 | Source: qtmozembed 2 | Section: libs 3 | Priority: extra 4 | Maintainer: unknown 5 | Build-Depends: debhelper, libqt4-dev | libqt4-opengl-dev | libqtbase5-dev, libqjson-dev, xulrunner-dev 6 | Standards-Version: 3.8.4 7 | Homepage: 8 | 9 | Package: libqtmozembed 10 | Architecture: any 11 | Depends: ${shlibs:Depends}, ${misc:Depends}, xulrunner 12 | Description: 13 | 14 | 15 | Package: libqtmozembed-dev 16 | Architecture: any 17 | Depends: ${shlibs:Depends}, ${misc:Depends}, libqtmozembed (= ${Source-Version}) 18 | Description: 19 | 20 | 21 | Package: libqtmozembed-dbg 22 | Architecture: any 23 | Depends: ${shlibs:Depends}, ${misc:Depends}, libqtmozembed (= ${Source-Version}) 24 | Description: 25 | 26 | -------------------------------------------------------------------------------- /tests/qmlmoztestrunner/testviewcreator.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | ** 3 | ** Copyright (C) 2014 Jolla Ltd. 4 | ** Contact: Dmitry Rozhkov 5 | ** 6 | ****************************************************************************/ 7 | 8 | /* This Source Code Form is subject to the terms of the Mozilla Public 9 | * License, v. 2.0. If a copy of the MPL was not distributed with this file, 10 | * You can obtain one at http://mozilla.org/MPL/2.0/. */ 11 | 12 | #ifndef testviewcreator_h 13 | #define testviewcreator_h 14 | 15 | #include "qmozviewcreator.h" 16 | 17 | class TestViewCreator : public QMozViewCreator 18 | { 19 | Q_OBJECT 20 | 21 | public: 22 | explicit TestViewCreator(QObject* parent = 0); 23 | ~TestViewCreator() {} 24 | 25 | virtual quint32 createView(const QString &url, const quint32 &parentId); 26 | 27 | signals: 28 | void newWindowRequested(const QString &url, const quint32 &parentId); 29 | }; 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /tests/qmlmoztestrunner/testviewcreator.cpp: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | ** 3 | ** Copyright (C) 2014 Jolla Ltd. 4 | ** Contact: Dmitry Rozhkov 5 | ** 6 | ****************************************************************************/ 7 | 8 | /* This Source Code Form is subject to the terms of the Mozilla Public 9 | * License, v. 2.0. If a copy of the MPL was not distributed with this file, 10 | * You can obtain one at http://mozilla.org/MPL/2.0/. */ 11 | 12 | #include "qmozcontext.h" 13 | #include "testviewcreator.h" 14 | 15 | TestViewCreator::TestViewCreator(QObject* parent) 16 | : QMozViewCreator(parent) 17 | { 18 | QMozContext::GetInstance()->setViewCreator(this); 19 | }; 20 | 21 | quint32 TestViewCreator::createView(const QString &url, const quint32 &parentId) 22 | { 23 | emit newWindowRequested(url, parentId); 24 | // NB: actual new ID is supposed to be set synchronously in the slot handling newWindowRequested signal 25 | return 2; 26 | }; 27 | -------------------------------------------------------------------------------- /link_to_system.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | TARGET_DIR=$1 4 | if [ "$TARGET_DIR" = "" ]; then 5 | echo "TARGET_DIR ex: /usr" 6 | TARGET_DIR=/usr 7 | fi 8 | 9 | OBJPREFIX=$2 10 | if [ "$OBJPREFIX" = "" ]; then 11 | BARCH=`uname -m` 12 | OBJPREFIX=objdir-$BARCH 13 | fi 14 | 15 | PREFIX=$TARGET_DIR/lib 16 | mkdir -p $PREFIX 17 | 18 | FILES_LIST=" 19 | $OBJPREFIX/src/libqtembedwidget.so 20 | $OBJPREFIX/src/libqtembedwidget.so.1 21 | $OBJPREFIX/src/libqtembedwidget.so.1.0 22 | $OBJPREFIX/src/libqtembedwidget.so.1.0.0 23 | " 24 | 25 | for str in $FILES_LIST; do 26 | fname="${str##*/}" 27 | rm -f $PREFIX/$fname; 28 | ln -s $(pwd)/$str $PREFIX/$fname; 29 | done 30 | 31 | rm -f $PREFIX/pkgconfig/qtembedwidget.pc; 32 | ln -s $(pwd)/$OBJPREFIX/pkgconfig/qtembedwidget.pc $PREFIX/pkgconfig/qtembedwidget.pc 33 | 34 | PREFIX=$TARGET_DIR/include 35 | mkdir -p $PREFIX 36 | 37 | FILES_LIST=" 38 | src/EmbedQtKeyUtils.h 39 | src/qdeclarativemozview.h 40 | src/qgraphicsmozview.h 41 | src/qmozcontext.h 42 | " 43 | 44 | for str in $FILES_LIST; do 45 | fname="${str##*/}" 46 | rm -f $PREFIX/$fname; 47 | ln -s $(pwd)/$str $PREFIX/$fname; 48 | done 49 | -------------------------------------------------------------------------------- /src/qmozextmaterialnode.h: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 2 | /* This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 | 6 | #ifndef qMozExtMaterialNode_h 7 | #define qMozExtMaterialNode_h 8 | 9 | #include 10 | #include 11 | 12 | class MozExtMaterialNode : public QObject, public QSGGeometryNode 13 | { 14 | Q_OBJECT 15 | public: 16 | MozExtMaterialNode(); 17 | 18 | ~MozExtMaterialNode() {} 19 | 20 | void update(); 21 | 22 | public Q_SLOTS: 23 | 24 | // This function gets called on the FBO rendering thread and will store the 25 | // texture id and size and schedule an update on the window. 26 | void newTexture(int id, const QSize &size); 27 | 28 | // Before the scene graph starts to render, we update to the pending texture 29 | void prepareNode(); 30 | 31 | private: 32 | void updateGeometry(const QSize &size); 33 | 34 | int m_id; 35 | QSize m_size; 36 | }; 37 | 38 | #endif /* qMozExtMaterialNode_h */ 39 | -------------------------------------------------------------------------------- /qmlplugin5/qmlmozcontext.cpp: -------------------------------------------------------------------------------- 1 | #include "qmlmozcontext.h" 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | QObject* QmlMozContext::instance() const 10 | { 11 | return QMozContext::GetInstance(); 12 | } 13 | 14 | void 15 | QmlMozContext::waitLoop(bool mayWait, int aTimeout) 16 | { 17 | QEventLoop::ProcessEventsFlags flags = QEventLoop::AllEvents; 18 | 19 | if (mayWait) 20 | flags |= QEventLoop::WaitForMoreEvents; 21 | 22 | QAbstractEventDispatcher *dispatcher = QAbstractEventDispatcher::instance(QThread::currentThread()); 23 | if (!dispatcher) { 24 | return; 25 | } 26 | 27 | if (aTimeout > -1) { 28 | QCoreApplication::processEvents(flags, aTimeout); 29 | } 30 | dispatcher->processEvents(flags); 31 | } 32 | 33 | void 34 | QmlMozContext::dumpTS(const QString& msg) 35 | { 36 | printf("TimeStamp: msg:\"%s\", Ts: %llu\n", msg.toUtf8().data(), QDateTime::currentMSecsSinceEpoch() / 1000); 37 | } 38 | 39 | QString 40 | QmlMozContext::getenv(const QString envVarName) const 41 | { 42 | return QString(::getenv(envVarName.toUtf8().constData())); 43 | } 44 | -------------------------------------------------------------------------------- /src/qmozscrolldecorator.h: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 2 | /* This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 | 6 | #ifndef QMOZSCROLLDECORATOR_H 7 | #define QMOZSCROLLDECORATOR_H 8 | 9 | #include 10 | 11 | class QMozScrollDecorator : public QObject 12 | { 13 | Q_OBJECT 14 | Q_PROPERTY(int position READ position NOTIFY positionChanged FINAL) 15 | Q_PROPERTY(int size READ size NOTIFY sizeChanged FINAL) 16 | Q_PROPERTY(bool moving READ moving NOTIFY movingChanged FINAL) 17 | 18 | public: 19 | QMozScrollDecorator(QObject *parent = 0); 20 | virtual ~QMozScrollDecorator(); 21 | 22 | int position() const; 23 | void setPosition(qreal pos); 24 | 25 | int size() const; 26 | void setSize(qreal size); 27 | 28 | bool moving() const; 29 | void setMoving(bool moving); 30 | 31 | Q_SIGNALS: 32 | void positionChanged(); 33 | void sizeChanged(); 34 | void movingChanged(); 35 | 36 | private: 37 | int mPos; 38 | int mSize; 39 | bool mMoving; 40 | }; 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /src/qmozgrabresult.h: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 2 | /* This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 | 6 | #ifndef QMOZGRABRESULT_H 7 | #define QMOZGRABRESULT_H 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | class QOpenGLWebPage; 14 | class QMozGrabResultPrivate; 15 | 16 | class QMozGrabResult : public QObject 17 | { 18 | Q_OBJECT 19 | Q_DECLARE_PRIVATE(QMozGrabResult) 20 | 21 | Q_PROPERTY(QImage image READ image CONSTANT) 22 | public: 23 | ~QMozGrabResult(); 24 | 25 | QImage image() const; 26 | bool isReady() const; 27 | 28 | Q_INVOKABLE bool saveToFile(const QString &fileName); 29 | 30 | protected: 31 | bool event(QEvent *e); 32 | 33 | Q_SIGNALS: 34 | void ready(); 35 | 36 | private: 37 | friend class QOpenGLWebPage; 38 | 39 | QMozGrabResult(QObject *parent = 0); 40 | void captureImage(const QRect &rect); 41 | 42 | QMozGrabResultPrivate *d_ptr; 43 | 44 | Q_DISABLE_COPY(QMozGrabResult) 45 | }; 46 | 47 | QT_END_NAMESPACE 48 | 49 | #endif 50 | -------------------------------------------------------------------------------- /qmlplugin5/qmlplugin5.pro: -------------------------------------------------------------------------------- 1 | MODULENAME = Qt5Mozilla 2 | TARGET = qmlmozembedpluginqt5 3 | 4 | TEMPLATE = lib 5 | CONFIG += qt plugin c++11 6 | QT += qml quick 7 | 8 | SOURCES += main.cpp qmlmozcontext.cpp 9 | HEADERS += qmlmozcontext.h 10 | 11 | RELATIVE_PATH=.. 12 | VDEPTH_PATH=qmlplugin5 13 | include($$RELATIVE_PATH/relative-objdir.pri) 14 | 15 | LIBS+= -L$$RELATIVE_PATH/$$OBJ_BUILD_PATH/src -lqt5embedwidget 16 | QTMOZEMBED_SOURCE_PATH = $$PWD/$$RELATIVE_PATH/src 17 | INCLUDEPATH += $$QTMOZEMBED_SOURCE_PATH 18 | 19 | isEmpty(DEFAULT_COMPONENT_PATH) { 20 | DEFINES += DEFAULT_COMPONENTS_PATH=\"\\\"/usr/lib/mozembedlite/\\\"\" 21 | } else { 22 | DEFINES += DEFAULT_COMPONENTS_PATH=\"\\\"$$DEFAULT_COMPONENT_PATH\\\"\" 23 | } 24 | 25 | TARGET = $$qtLibraryTarget($$TARGET) 26 | TARGETPATH = /usr/lib/qt5/qml/$$MODULENAME 27 | 28 | target.path = $$TARGETPATH 29 | INSTALLS += target 30 | 31 | import.files = qmldir 32 | import.path = $$TARGETPATH 33 | INSTALLS += import 34 | 35 | !isEmpty(OBJ_BUILD_PATH) { 36 | QMAKE_POST_LINK = rm -f $$OBJECTS_DIR/qmldir 37 | QMAKE_POST_LINK += && rm -f $$OBJECTS_DIR/Qt5Mozilla 38 | QMAKE_POST_LINK += && ln -s $$RELATIVE_PATH/$$RELATIVE_PATH/qmlplugin5/qmldir $$OBJECTS_DIR/qmldir 39 | QMAKE_POST_LINK += && ln -s . $$OBJECTS_DIR/Qt5Mozilla 40 | } 41 | -------------------------------------------------------------------------------- /qmlplugin5/main.cpp: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- 2 | * 3 | * This Source Code Form is subject to the terms of the Mozilla Public 4 | * License, v. 2.0. If a copy of the MPL was not distributed with this 5 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 | 7 | #include 8 | #include 9 | #include "quickmozview.h" 10 | #include "qmozcontext.h" 11 | #include "qmozscrolldecorator.h" 12 | #include "qmlmozcontext.h" 13 | 14 | class QtMozEmbedPlugin : public QQmlExtensionPlugin 15 | { 16 | Q_OBJECT 17 | Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface") 18 | 19 | public: 20 | void registerTypes(const char *uri) 21 | { 22 | Q_ASSERT(uri == QLatin1String("Qt5Mozilla")); 23 | qmlRegisterType("Qt5Mozilla", 1, 0, "QmlMozView"); 24 | qmlRegisterType("Qt5Mozilla", 1, 0, "QmlMozContext"); 25 | qmlRegisterUncreatableType("Qt5Mozilla", 1, 0, "QmlMozScrollDecorator", ""); 26 | qmlRegisterUncreatableType("Qt5Mozilla", 1, 0, "QMozReturnValue", ""); 27 | setenv("EMBED_COMPONENTS_PATH", DEFAULT_COMPONENTS_PATH, 1); 28 | } 29 | }; 30 | 31 | #include "main.moc" 32 | -------------------------------------------------------------------------------- /src/qmoztexturenode.h: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 2 | /* This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 | 6 | #ifndef qmoztexturenode_h 7 | #define qmoztexturenode_h 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | class QuickMozView; 14 | 15 | class MozTextureNode : public QObject, public QSGSimpleTextureNode 16 | { 17 | Q_OBJECT 18 | public: 19 | MozTextureNode(QuickMozView* aView); 20 | 21 | ~MozTextureNode() 22 | { 23 | delete m_texture; 24 | } 25 | 26 | Q_SIGNALS: 27 | void pendingNewTexture(); 28 | 29 | public Q_SLOTS: 30 | 31 | // This function gets called on the FBO rendering thread and will store the 32 | // texture id and size and schedule an update on the window. 33 | void newTexture(int id, const QSize &size); 34 | 35 | // Before the scene graph starts to render, we update to the pending texture 36 | void prepareNode(); 37 | 38 | void update(); 39 | 40 | private: 41 | 42 | int m_id; 43 | QSize m_size; 44 | QMutex m_mutex; 45 | QSGTexture *m_texture; 46 | QuickMozView *m_view; 47 | }; 48 | 49 | #endif /* qmoztexturenode_h */ 50 | -------------------------------------------------------------------------------- /src/qmozscrolldecorator.cpp: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 2 | /* This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 | 6 | #include 7 | #include "qmozscrolldecorator.h" 8 | 9 | QMozScrollDecorator::QMozScrollDecorator(QObject *parent) 10 | : QObject(parent) 11 | , mPos(0) 12 | , mSize(0) 13 | , mMoving(false) 14 | { 15 | } 16 | 17 | QMozScrollDecorator::~QMozScrollDecorator() 18 | { 19 | } 20 | 21 | int QMozScrollDecorator::position() const 22 | { 23 | return mPos; 24 | } 25 | 26 | void QMozScrollDecorator::setPosition(qreal pos) 27 | { 28 | if (mPos != pos) { 29 | mPos = pos; 30 | Q_EMIT positionChanged(); 31 | } 32 | } 33 | 34 | int QMozScrollDecorator::size() const 35 | { 36 | return mSize; 37 | } 38 | 39 | void QMozScrollDecorator::setSize(qreal size) 40 | { 41 | if (qIsNull(size)) 42 | return; 43 | 44 | if (mSize != size) { 45 | mSize = size; 46 | Q_EMIT sizeChanged(); 47 | } 48 | } 49 | 50 | bool QMozScrollDecorator::moving() const 51 | { 52 | return mMoving; 53 | } 54 | 55 | void QMozScrollDecorator::setMoving(bool moving) 56 | { 57 | if (mMoving != moving) { 58 | mMoving = moving; 59 | Q_EMIT movingChanged(); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /tests/auto/mer-qt4/basicview/tst_basicview.qml: -------------------------------------------------------------------------------- 1 | import QtQuickTest 1.0 2 | import QtQuick 1.0 3 | import Sailfish.Silica 1.0 4 | import QtMozilla 1.0 5 | import "../../shared/componentCreation.js" as MyScript 6 | import "../../shared/sharedTests.js" as SharedTests 7 | 8 | ApplicationWindow { 9 | id: appWindow 10 | 11 | property bool mozViewInitialized : false 12 | property variant mozView : null 13 | property variant createParentID : 0 14 | 15 | QmlMozContext { 16 | id: mozContext 17 | } 18 | Connections { 19 | target: mozContext.instance 20 | onOnInitialized: { 21 | // Gecko does not switch to SW mode if gl context failed to init 22 | // and qmlmoztestrunner does not build in GL mode 23 | // Let's put it here for now in SW mode always 24 | mozContext.instance.setIsAccelerated(true); 25 | } 26 | } 27 | 28 | resources: TestCase { 29 | id: testcaseid 30 | name: "mozContextPage" 31 | when: windowShown 32 | 33 | function cleanup() { 34 | mozContext.dumpTS("tst_basicview cleanup") 35 | } 36 | 37 | function test_1contextPrepareViewContext() 38 | { 39 | SharedTests.shared_1contextPrepareViewContext() 40 | } 41 | function test_2viewInit() 42 | { 43 | SharedTests.shared_2viewInit(false) 44 | } 45 | function test_3viewLoadURL() 46 | { 47 | SharedTests.shared_3viewLoadURL() 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /tests/auto/desktop-qt5/basicview/tst_basicview.qml: -------------------------------------------------------------------------------- 1 | import QtTest 1.0 2 | import QtQuick 2.0 3 | import Qt5Mozilla 1.0 4 | import "../../shared/componentCreation.js" as MyScript 5 | import "../../shared/sharedTests.js" as SharedTests 6 | 7 | Item { 8 | id: appWindow 9 | width: 480 10 | height: 800 11 | 12 | property bool mozViewInitialized : false 13 | property variant mozView : null 14 | property variant createParentID : 0 15 | 16 | QmlMozContext { 17 | id: mozContext 18 | } 19 | Connections { 20 | target: mozContext.instance 21 | onOnInitialized: { 22 | // Gecko does not switch to SW mode if gl context failed to init 23 | // and qmlmoztestrunner does not build in GL mode 24 | // Let's put it here for now in SW mode always 25 | mozContext.instance.setIsAccelerated(true); 26 | } 27 | } 28 | 29 | resources: TestCase { 30 | id: testcaseid 31 | name: "mozContextPage" 32 | when: windowShown 33 | parent: appWindow 34 | 35 | function cleanup() { 36 | mozContext.dumpTS("tst_basicview cleanup") 37 | } 38 | 39 | function test_1contextPrepareViewContext() 40 | { 41 | SharedTests.shared_1contextPrepareViewContext() 42 | } 43 | function test_2viewInit() 44 | { 45 | SharedTests.shared_2viewInit(true) 46 | } 47 | function test_3viewLoadURL() 48 | { 49 | SharedTests.shared_3viewLoadURL() 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/qmozwindow.h: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 2 | /* This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 | 6 | #ifndef QMOZWINDOW_H 7 | #define QMOZWINDOW_H 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | class QMozWindowPrivate; 16 | 17 | class QMozWindow: public QObject 18 | { 19 | Q_OBJECT 20 | 21 | public: 22 | explicit QMozWindow(QObject* parent = nullptr); 23 | ~QMozWindow(); 24 | 25 | void setSize(QSize); 26 | QSize size() const { return mSize; } 27 | void setContentOrientation(Qt::ScreenOrientation); 28 | Qt::ScreenOrientation contentOrientation() const; 29 | void* getPlatformImage(int* width, int* height); 30 | void suspendRendering(); 31 | void resumeRendering(); 32 | void scheduleUpdate(); 33 | bool setReadyToPaint(bool ready); 34 | bool readyToPaint() const; 35 | 36 | Q_SIGNALS: 37 | void requestGLContext(); 38 | void initialized(); 39 | void drawOverlay(QRect); 40 | void drawUnderlay(); 41 | void compositorCreated(); 42 | void compositingFinished(); 43 | 44 | private: 45 | friend class QOpenGLWebPage; 46 | friend class QuickMozView; 47 | friend class QMozWindowPrivate; 48 | 49 | QScopedPointer d; 50 | 51 | QSize mSize; 52 | Qt::ScreenOrientation mOrientation; 53 | 54 | Q_DISABLE_COPY(QMozWindow) 55 | }; 56 | 57 | #endif // QMOZWINDOW_H 58 | -------------------------------------------------------------------------------- /src/qmozwindow_p.h: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 2 | /* This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 | 6 | #ifndef QMOZWINDOW_PRIVATE_H 7 | #define QMOZWINDOW_PRIVATE_H 8 | 9 | #include 10 | #include 11 | 12 | #include "mozilla/embedlite/EmbedLiteWindow.h" 13 | 14 | class QMozWindow; 15 | 16 | class QMozWindowPrivate : public mozilla::embedlite::EmbedLiteWindowListener 17 | { 18 | public: 19 | QMozWindowPrivate(QMozWindow&); 20 | virtual ~QMozWindowPrivate(); 21 | 22 | protected: 23 | // EmbedLiteWindowListener: 24 | bool RequestGLContext(void*& context, void*& surface) override; 25 | void WindowInitialized() override; 26 | void DrawUnderlay() override; 27 | void DrawOverlay(const nsIntRect& aRect) override; 28 | bool PreRender() override; 29 | void CompositorCreated() override; 30 | void CompositingFinished() override; 31 | 32 | private: 33 | friend class QMozWindow; 34 | friend class QOpenGLWebPage; 35 | friend class QuickMozView; 36 | 37 | void getEGLContext(void*& context, void*& surface); 38 | #if defined(ENABLE_GLX) 39 | void getGLXContext(void*& context, void*& surface); 40 | #endif 41 | bool setReadyToPaint(bool ready); 42 | 43 | QMozWindow& q; 44 | mozilla::embedlite::EmbedLiteWindow* mWindow; 45 | QMutex mReadyToPaintMutex; 46 | bool mReadyToPaint; 47 | 48 | Q_DISABLE_COPY(QMozWindowPrivate) 49 | }; 50 | 51 | #endif // QMOZWINDOW_PRIVATE_H 52 | 53 | -------------------------------------------------------------------------------- /tests/auto/mer-qt4/view/tst_viewtest.qml: -------------------------------------------------------------------------------- 1 | import QtQuickTest 1.0 2 | import QtQuick 1.0 3 | import Sailfish.Silica 1.0 4 | import QtMozilla 1.0 5 | import "../../shared/componentCreation.js" as MyScript 6 | import "../../shared/sharedTests.js" as SharedTests 7 | 8 | ApplicationWindow { 9 | id: appWindow 10 | 11 | property bool mozViewInitialized : false 12 | 13 | QmlMozContext { 14 | id: mozContext 15 | } 16 | Connections { 17 | target: mozContext.instance 18 | onOnInitialized: { 19 | // Gecko does not switch to SW mode if gl context failed to init 20 | // and qmlmoztestrunner does not build in GL mode 21 | // Let's put it here for now in SW mode always 22 | mozContext.instance.setIsAccelerated(true); 23 | } 24 | } 25 | 26 | QmlMozView { 27 | id: webViewport 28 | visible: true 29 | focus: true 30 | anchors.fill: parent 31 | Connections { 32 | target: webViewport.child 33 | onViewInitialized: { 34 | appWindow.mozViewInitialized = true 35 | } 36 | } 37 | } 38 | 39 | resources: TestCase { 40 | id: testcaseid 41 | name: "mozContextPage" 42 | when: windowShown 43 | 44 | function cleanup() { 45 | mozContext.dumpTS("tst_viewtest cleanup") 46 | } 47 | 48 | function test_Test1LoadSimpleBlank() 49 | { 50 | SharedTests.shared_Test1LoadSimpleBlank() 51 | } 52 | function test_Test2LoadAboutMozillaCheckTitle() 53 | { 54 | SharedTests.shared_Test2LoadAboutMozillaCheckTitle() 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /tests/auto/desktop-qt5/view/tst_viewtest.qml: -------------------------------------------------------------------------------- 1 | import QtTest 1.0 2 | import QtQuick 2.0 3 | import Qt5Mozilla 1.0 4 | import "../../shared/componentCreation.js" as MyScript 5 | import "../../shared/sharedTests.js" as SharedTests 6 | 7 | Item { 8 | id: appWindow 9 | width: 480 10 | height: 800 11 | 12 | property bool mozViewInitialized : false 13 | 14 | QmlMozContext { 15 | id: mozContext 16 | } 17 | Connections { 18 | target: mozContext.instance 19 | onOnInitialized: { 20 | // Gecko does not switch to SW mode if gl context failed to init 21 | // and qmlmoztestrunner does not build in GL mode 22 | // Let's put it here for now in SW mode always 23 | mozContext.instance.setIsAccelerated(true); 24 | } 25 | } 26 | 27 | QmlMozView { 28 | id: webViewport 29 | visible: true 30 | focus: true 31 | active: true 32 | anchors.fill: parent 33 | Connections { 34 | target: webViewport.child 35 | onViewInitialized: { 36 | appWindow.mozViewInitialized = true 37 | } 38 | } 39 | } 40 | 41 | resources: TestCase { 42 | id: testcaseid 43 | name: "mozContextPage" 44 | when: windowShown 45 | parent: appWindow 46 | 47 | function cleanup() { 48 | mozContext.dumpTS("tst_viewtest cleanup") 49 | } 50 | 51 | function test_Test1LoadSimpleBlank() 52 | { 53 | SharedTests.shared_Test1LoadSimpleBlank() 54 | } 55 | function test_Test2LoadAboutMozillaCheckTitle() 56 | { 57 | SharedTests.shared_Test2LoadAboutMozillaCheckTitle() 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/qmoztexturenode.cpp: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 2 | /* This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 | 6 | #include "qmoztexturenode.h" 7 | #include "quickmozview.h" 8 | #include 9 | #include 10 | 11 | MozTextureNode::MozTextureNode(QuickMozView* aView) 12 | : m_id(0) 13 | , m_size(0, 0) 14 | , m_texture(0) 15 | , m_view(aView) 16 | { 17 | // Our texture node must have a texture, so use the default 0 texture. 18 | m_texture = m_view->window()->createTextureFromId(0, QSize(1, 1)); 19 | setTexture(m_texture); 20 | setFiltering(QSGTexture::Linear); 21 | } 22 | 23 | void 24 | MozTextureNode::newTexture(int id, const QSize &size) 25 | { 26 | m_mutex.lock(); 27 | m_id = id; 28 | m_size = size; 29 | m_mutex.unlock(); 30 | 31 | // We cannot call QQuickWindow::update directly here, as this is only allowed 32 | // from the rendering thread or GUI thread. 33 | Q_EMIT pendingNewTexture(); 34 | } 35 | 36 | // Before the scene graph starts to render, we update to the pending texture 37 | void 38 | MozTextureNode::prepareNode() 39 | { 40 | m_mutex.lock(); 41 | int newId = m_id; 42 | QSize size = m_size; 43 | m_id = 0; 44 | m_mutex.unlock(); 45 | if (newId) { 46 | delete m_texture; 47 | m_texture = m_view->window()->createTextureFromId(newId, size); 48 | setTexture(m_texture); 49 | } 50 | } 51 | 52 | void MozTextureNode::update() 53 | { 54 | setRect(QRectF(0, 0, m_size.width(), m_size.height())); 55 | markDirty(QSGNode::DirtyMaterial); 56 | } 57 | -------------------------------------------------------------------------------- /tests/auto/mer-qt4/context/tst_basicmozcontext.qml: -------------------------------------------------------------------------------- 1 | import QtQuickTest 1.0 2 | import QtQuick 1.0 3 | import Sailfish.Silica 1.0 4 | import QtMozilla 1.0 5 | import "../../shared/componentCreation.js" as MyScript 6 | import "../../shared/sharedTests.js" as SharedTests 7 | 8 | ApplicationWindow { 9 | id: appWindow 10 | 11 | property bool mozViewInitialized : false 12 | property variant mozView : null 13 | property variant lastObserveMessage 14 | 15 | QmlMozContext { 16 | id: mozContext 17 | } 18 | Connections { 19 | target: mozContext.instance 20 | onOnInitialized: { 21 | // Gecko does not switch to SW mode if gl context failed to init 22 | // and qmlmoztestrunner does not build in GL mode 23 | // Let's put it here for now in SW mode always 24 | mozContext.instance.setIsAccelerated(true); 25 | } 26 | onRecvObserve: { 27 | lastObserveMessage = { msg: message, data: data } 28 | } 29 | } 30 | 31 | resources: TestCase { 32 | id: testcaseid 33 | name: "mozContextPage" 34 | when: windowShown 35 | 36 | function cleanup() 37 | { 38 | mozContext.dumpTS("tst_basicmozcontext cleanup") 39 | } 40 | function test_context1Init() 41 | { 42 | SharedTests.shared_context1Init() 43 | } 44 | function test_context2AcceleratedAPI() 45 | { 46 | SharedTests.shared_context2AcceleratedAPI() 47 | } 48 | function test_context3PrefAPI() 49 | { 50 | SharedTests.shared_context3PrefAPI() 51 | } 52 | function test_context4ObserveAPI() 53 | { 54 | SharedTests.shared_context4ObserveAPI() 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /tests/auto/desktop-qt5/context/tst_basicmozcontext.qml: -------------------------------------------------------------------------------- 1 | import QtTest 1.0 2 | import QtQuick 2.0 3 | import Qt5Mozilla 1.0 4 | import "../../shared/componentCreation.js" as MyScript 5 | import "../../shared/sharedTests.js" as SharedTests 6 | 7 | Item { 8 | id: appWindow 9 | width: 480 10 | height: 800 11 | 12 | property bool mozViewInitialized : false 13 | property variant mozView : null 14 | property variant lastObserveMessage 15 | 16 | QmlMozContext { 17 | id: mozContext 18 | } 19 | Connections { 20 | target: mozContext.instance 21 | onOnInitialized: { 22 | // Gecko does not switch to SW mode if gl context failed to init 23 | // and qmlmoztestrunner does not build in GL mode 24 | // Let's put it here for now in SW mode always 25 | mozContext.instance.setIsAccelerated(true); 26 | } 27 | onRecvObserve: { 28 | lastObserveMessage = { msg: message, data: data } 29 | } 30 | } 31 | 32 | resources: TestCase { 33 | id: testcaseid 34 | name: "mozContextPage" 35 | when: windowShown 36 | parent: appWindow 37 | 38 | function cleanup() 39 | { 40 | mozContext.dumpTS("tst_basicmozcontext cleanup") 41 | } 42 | function test_context1Init() 43 | { 44 | SharedTests.shared_context1Init() 45 | } 46 | function test_context2AcceleratedAPI() 47 | { 48 | SharedTests.shared_context2AcceleratedAPI() 49 | } 50 | function test_context3PrefAPI() 51 | { 52 | SharedTests.shared_context3PrefAPI() 53 | } 54 | function test_context4ObserveAPI() 55 | { 56 | SharedTests.shared_context4ObserveAPI() 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /tests/auto/desktop-qt5/viewbasicapi/tst_viewbasicapi.qml: -------------------------------------------------------------------------------- 1 | import QtTest 1.0 2 | import QtQuick 2.0 3 | import Qt5Mozilla 1.0 4 | import "../../shared/componentCreation.js" as MyScript 5 | import "../../shared/sharedTests.js" as SharedTests 6 | 7 | Item { 8 | id: appWindow 9 | width: 480 10 | height: 800 11 | 12 | property bool mozViewInitialized : false 13 | property variant mozView : null 14 | 15 | QmlMozContext { 16 | id: mozContext 17 | } 18 | Connections { 19 | target: mozContext.instance 20 | onOnInitialized: { 21 | // Gecko does not switch to SW mode if gl context failed to init 22 | // and qmlmoztestrunner does not build in GL mode 23 | // Let's put it here for now in SW mode always 24 | mozContext.instance.setIsAccelerated(true); 25 | } 26 | } 27 | 28 | resources: TestCase { 29 | id: testcaseid 30 | name: "mozContextPage" 31 | when: windowShown 32 | parent: appWindow 33 | 34 | function cleanup() { 35 | mozContext.dumpTS("tst_viewbasicapi cleanup") 36 | } 37 | 38 | function test_1contextPrepareViewContext() 39 | { 40 | SharedTests.shared_1contextPrepareViewContext() 41 | } 42 | function test_2viewInit() 43 | { 44 | mozContext.dumpTS("test_2viewInitBasic start") 45 | testcaseid.verify(mozContext.instance.initialized()) 46 | MyScript.createSpriteObjectsQt5(); 47 | while (mozView == null) { 48 | testcaseid.wait(500) 49 | } 50 | mozContext.dumpTS("test_2viewInitBasic start1") 51 | testcaseid.verify(MyScript.waitMozView()) 52 | testcaseid.verify(mozView.uniqueID() > 0) 53 | testcaseid.verify(mozView.child) 54 | mozView = null 55 | mozContext.dumpTS("test_2viewInitBasic end") 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/qmozembed.pri: -------------------------------------------------------------------------------- 1 | QMAKE_CXXFLAGS += -include mozilla-config.h 2 | unix:QMAKE_CXXFLAGS += -fno-short-wchar -std=c++0x -fPIC 3 | DEFINES += XPCOM_GLUE=1 XPCOM_GLUE_USE_NSPR=1 MOZ_GLUE_IN_PROGRAM=1 4 | 5 | isEmpty(OBJ_PATH) { 6 | message(OBJ_PATH not defined) 7 | CONFIG += link_pkgconfig 8 | SDK_HOME=$$system(pkg-config --variable=sdkdir libxul-embedding) 9 | GECKO_LIB_DIR = $$SDK_HOME/lib 10 | GECKO_INCLUDE_DIR = $$SDK_HOME/include 11 | BIN_DIR=$$replace(SDK_HOME, -devel-, -) 12 | message($$BIN_DIR - binary dir) 13 | } else { 14 | CONFIG += link_pkgconfig 15 | message(OBJ_PATH defined $$OBJ_PATH) 16 | GECKO_LIB_DIR = $$OBJ_PATH/dist/sdk/lib 17 | GECKO_INCLUDE_DIR = $$OBJ_PATH/dist/include 18 | BIN_DIR=$$OBJ_PATH/dist/bin 19 | message($$BIN_DIR - binary dir) 20 | } 21 | 22 | !isEmpty(ENABLE_GLX) { 23 | DEFINES += ENABLE_GLX 24 | } 25 | 26 | INCLUDEPATH += $$GECKO_INCLUDE_DIR $$GECKO_INCLUDE_DIR/nspr /usr/include/nspr4 27 | LIBS += -L$$GECKO_LIB_DIR -lxpcomglue -Wl,--whole-archive -lmozglue -lmemory 28 | LIBS += -Wl,--no-whole-archive -rdynamic -ldl 29 | 30 | DEFINES += BUILD_GRE_HOME=\"\\\"$$BIN_DIR\\\"\" 31 | 32 | # Copy default mozilla flags to avoid some gcc warnings 33 | *-g++*: QMAKE_CXXFLAGS += -Wno-attributes 34 | *-g++*: QMAKE_CXXFLAGS += -Wno-ignored-qualifiers 35 | *-g++*: QMAKE_CXXFLAGS += -pedantic 36 | *-g++*: QMAKE_CXXFLAGS += -Wall 37 | *-g++*: QMAKE_CXXFLAGS += -Wno-unused-parameter 38 | *-g++*: QMAKE_CXXFLAGS += -Wpointer-arith 39 | *-g++*: QMAKE_CXXFLAGS += -Woverloaded-virtual 40 | *-g++*: QMAKE_CXXFLAGS += -Werror=return-type 41 | *-g++*: QMAKE_CXXFLAGS += -Wtype-limits 42 | *-g++*: QMAKE_CXXFLAGS += -Wempty-body 43 | *-g++*: QMAKE_CXXFLAGS += -Wno-ctor-dtor-privacy 44 | *-g++*: QMAKE_CXXFLAGS += -Wno-format 45 | *-g++*: QMAKE_CXXFLAGS += -Wno-overlength-strings 46 | *-g++*: QMAKE_CXXFLAGS += -Wno-invalid-offsetof 47 | *-g++*: QMAKE_CXXFLAGS += -Wno-variadic-macros 48 | *-g++*: QMAKE_CXXFLAGS += -Wno-long-long 49 | *-g++*: QMAKE_CXXFLAGS += -Wno-psabi 50 | -------------------------------------------------------------------------------- /tests/qmlmoztestrunner/qtestrunner.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | ** 3 | ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). 4 | ** All rights reserved. 5 | ** Contact: Nokia Corporation (qt-info@nokia.com) 6 | ** 7 | ** This file is part of the test suite of the Qt Toolkit. 8 | ** 9 | ** $QT_BEGIN_LICENSE:LGPL$ 10 | ** No Commercial Usage 11 | ** This file contains pre-release code and may not be distributed. 12 | ** You may use this file in accordance with the terms and conditions 13 | ** contained in the Technology Preview License Agreement accompanying 14 | ** this package. 15 | ** 16 | ** GNU Lesser General Public License Usage 17 | ** Alternatively, this file may be used under the terms of the GNU Lesser 18 | ** General Public License version 2.1 as published by the Free Software 19 | ** Foundation and appearing in the file LICENSE.LGPL included in the 20 | ** packaging of this file. Please review the following information to 21 | ** ensure the GNU Lesser General Public License version 2.1 requirements 22 | ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 23 | ** 24 | ** In addition, as a special exception, Nokia gives you certain additional 25 | ** rights. These rights are described in the Nokia Qt LGPL Exception 26 | ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 | ** 28 | ** If you have questions regarding the use of this file, please contact 29 | ** Nokia at qt-info@nokia.com. 30 | ** 31 | ** 32 | ** $QT_END_LICENSE$ 33 | ** 34 | ****************************************************************************/ 35 | 36 | #include 37 | 38 | class QTestRunner : public QObject 39 | { 40 | Q_OBJECT 41 | public: 42 | QTestRunner(bool isOpenGL, int agargc, char **agargv); 43 | ~QTestRunner() {} 44 | int GetResult() const; 45 | public Q_SLOTS: 46 | void DropInStartup(); 47 | private: 48 | int RunMainTest(); 49 | bool mIsOpenGL; 50 | int mResult; 51 | }; 52 | -------------------------------------------------------------------------------- /src/qmessagepump.h: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-*/ 2 | /* vim: set ts=2 sw=2 et tw=79: */ 3 | /* This Source Code Form is subject to the terms of the Mozilla Public 4 | * License, v. 2.0. If a copy of the MPL was not distributed with this file, 5 | * You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 | 7 | #ifndef qmessagepump_h 8 | #define qmessagepump_h 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include "mozilla/embedlite/EmbedLiteMessagePump.h" 15 | 16 | namespace mozilla { 17 | namespace embedlite { 18 | class EmbedLiteApp; 19 | }} 20 | 21 | class MessagePumpQt : public QObject, public mozilla::embedlite::EmbedLiteMessagePumpListener 22 | { 23 | Q_OBJECT 24 | 25 | public: 26 | MessagePumpQt(mozilla::embedlite::EmbedLiteApp* aApp); 27 | ~MessagePumpQt(); 28 | 29 | virtual bool event(QEvent* e); 30 | void scheduleDelayedIfNeeded(); 31 | void HandleDispatch(); 32 | void ScheduleWork(); 33 | 34 | virtual void Run(void* aDelegate); 35 | virtual void Quit(); 36 | virtual void ScheduleWorkLocal(); 37 | virtual void ScheduleDelayedWork(const int aDelay); 38 | 39 | mozilla::embedlite::EmbedLiteMessagePump* EmbedLoop() { return mEventLoopPrivate; } 40 | 41 | public Q_SLOTS: 42 | void dispatchDelayed(); 43 | 44 | private: 45 | // We may make recursive calls to Run, so we save state that needs to be 46 | // separate between them in this structure type. 47 | struct RunState { 48 | void* delegate; 49 | // Used to flag that the current Run() invocation should return ASAP. 50 | bool should_quit; 51 | // Used to count how many Run() invocations are on the stack. 52 | int run_depth; 53 | }; 54 | 55 | mozilla::embedlite::EmbedLiteApp* mApp; 56 | mozilla::embedlite::EmbedLiteMessagePump* mEventLoopPrivate; 57 | QTimer* mTimer; 58 | RunState* state_; 59 | int mLastDelayedWorkTime; 60 | bool mStarted; 61 | }; 62 | 63 | #endif /* qmessagepump_h */ 64 | -------------------------------------------------------------------------------- /tests/auto/shared/favicons/favicon.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Page with Favicon 7 | 8 | 9 | -------------------------------------------------------------------------------- /tests/auto/mer-qt4/favicons/tst_favicon.qml: -------------------------------------------------------------------------------- 1 | import QtQuickTest 1.0 2 | import QtQuick 1.0 3 | import Sailfish.Silica 1.0 4 | import QtMozilla 1.0 5 | import "../../shared/componentCreation.js" as MyScript 6 | import "../../shared/sharedTests.js" as SharedTests 7 | 8 | ApplicationWindow { 9 | id: appWindow 10 | 11 | property bool mozViewInitialized : false 12 | property variant favicon : null 13 | 14 | QmlMozContext { 15 | id: mozContext 16 | } 17 | Connections { 18 | target: mozContext.instance 19 | onOnInitialized: { 20 | // Gecko does not switch to SW mode if gl context failed to init 21 | // and qmlmoztestrunner does not build in GL mode 22 | // Let's put it here for now in SW mode always 23 | mozContext.instance.setIsAccelerated(true); 24 | mozContext.instance.addComponentManifest(mozContext.getenv("QTTESTSROOT") + "/components/TestHelpers.manifest"); 25 | } 26 | } 27 | 28 | QmlMozView { 29 | id: webViewport 30 | visible: true 31 | focus: true 32 | anchors.fill: parent 33 | Connections { 34 | target: webViewport.child 35 | onViewInitialized: { 36 | appWindow.mozViewInitialized = true 37 | webViewport.child.addMessageListener("chrome:linkadded"); 38 | } 39 | onRecvAsyncMessage: { 40 | print("onRecvAsyncMessage:" + message + ", data:" + data) 41 | if (message == "chrome:linkadded" && data.get == "image/x-icon") { 42 | appWindow.favicon = data.href; 43 | } 44 | } 45 | } 46 | } 47 | 48 | resources: TestCase { 49 | id: testcaseid 50 | name: "mozContextPage" 51 | when: windowShown 52 | 53 | function cleanup() { 54 | mozContext.dumpTS("tst_multitouch cleanup") 55 | } 56 | 57 | function test_TestFaviconPage() 58 | { 59 | SharedTests.shared_TestFaviconPage() 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /rpm/qtmozembed-qt5.spec: -------------------------------------------------------------------------------- 1 | %global min_xulrunner_version 38.0.5.3 2 | 3 | Name: qtmozembed-qt5 4 | Summary: Qt embeddings for Gecko 5 | Version: 1.13.2 6 | Release: 1 7 | Group: Applications/Internet 8 | License: Mozilla License 9 | URL: https://github.com/tmeshkova/qtmozembed.git 10 | Source0: %{name}-%{version}.tar.bz2 11 | BuildRequires: pkgconfig(Qt5Core) 12 | BuildRequires: pkgconfig(Qt5Gui) 13 | BuildRequires: pkgconfig(Qt5Network) 14 | BuildRequires: pkgconfig(Qt5OpenGL) 15 | BuildRequires: pkgconfig(Qt5Widgets) 16 | BuildRequires: pkgconfig(Qt5Quick) 17 | BuildRequires: pkgconfig(Qt5QuickTest) 18 | BuildRequires: pkgconfig(nspr) 19 | BuildRequires: xulrunner-qt5-devel >= %{min_xulrunner_version} 20 | BuildRequires: qt5-default 21 | BuildRequires: qt5-qttools 22 | Requires: xulrunner-qt5 >= %{min_xulrunner_version} 23 | 24 | %description 25 | Qt embeddings for Gecko browser engine 26 | 27 | %package devel 28 | Group: Applications/Internet 29 | Requires: %{name} = %{version}-%{release} 30 | Summary: Headers for qtmozembed 31 | 32 | %description devel 33 | Development files for qtmozembed. 34 | 35 | %package tests 36 | Summary: Unit tests for QtMozEmbed tests 37 | Group: Applications/Internet 38 | Requires: %{name} = %{version}-%{release} 39 | Requires: embedlite-components-qt5 >= 1.0.0 40 | Requires: qt5-qtdeclarative-import-qttest 41 | Requires: mce-tools 42 | 43 | %description tests 44 | This package contains QML unit tests for QtMozEmbed library 45 | 46 | %prep 47 | %setup -q -n %{name}-%{version} 48 | 49 | %build 50 | %qmake5 VERSION=%{version} 51 | %{__make} %{?jobs:MOZ_MAKE_FLAGS="-j%jobs"} 52 | 53 | %install 54 | %qmake5_install 55 | %post -p /sbin/ldconfig 56 | %postun -p /sbin/ldconfig 57 | 58 | %files 59 | %defattr(-,root,root,-) 60 | %{_libdir}/*.so.* 61 | %{_libdir}/qt5/qml/Qt5Mozilla/* 62 | 63 | %files devel 64 | %defattr(-,root,root,-) 65 | %{_libdir}/*.so 66 | %{_libdir}/pkgconfig 67 | %{_includedir}/* 68 | 69 | %files tests 70 | %defattr(-,root,root,-) 71 | # >> files tests 72 | /opt/tests/qtmozembed/* 73 | %{_libdir}/qt5/bin/* 74 | # << files tests 75 | -------------------------------------------------------------------------------- /tests/auto/desktop-qt5/favicons/tst_favicon.qml: -------------------------------------------------------------------------------- 1 | import QtTest 1.0 2 | import QtQuick 2.0 3 | import Qt5Mozilla 1.0 4 | import "../../shared/componentCreation.js" as MyScript 5 | import "../../shared/sharedTests.js" as SharedTests 6 | 7 | Item { 8 | id: appWindow 9 | width: 480 10 | height: 800 11 | 12 | property bool mozViewInitialized : false 13 | property variant favicon : null 14 | 15 | QmlMozContext { 16 | id: mozContext 17 | } 18 | Connections { 19 | target: mozContext.instance 20 | onOnInitialized: { 21 | // Gecko does not switch to SW mode if gl context failed to init 22 | // and qmlmoztestrunner does not build in GL mode 23 | // Let's put it here for now in SW mode always 24 | mozContext.instance.setIsAccelerated(true); 25 | mozContext.instance.addComponentManifest(mozContext.getenv("QTTESTSROOT") + "/components/TestHelpers.manifest"); 26 | } 27 | } 28 | 29 | QmlMozView { 30 | id: webViewport 31 | visible: true 32 | focus: true 33 | active: true 34 | anchors.fill: parent 35 | Connections { 36 | target: webViewport.child 37 | onViewInitialized: { 38 | appWindow.mozViewInitialized = true 39 | webViewport.child.addMessageListener("chrome:linkadded"); 40 | } 41 | onRecvAsyncMessage: { 42 | print("onRecvAsyncMessage:" + message + ", data:" + data) 43 | if (message == "chrome:linkadded" && data.get == "image/x-icon") { 44 | appWindow.favicon = data.href; 45 | } 46 | } 47 | } 48 | } 49 | 50 | resources: TestCase { 51 | id: testcaseid 52 | name: "mozContextPage" 53 | when: windowShown 54 | parent: appWindow 55 | 56 | function cleanup() { 57 | mozContext.dumpTS("tst_multitouch cleanup") 58 | } 59 | 60 | function test_TestFaviconPage() 61 | { 62 | SharedTests.shared_TestFaviconPage() 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /tests/auto/mer-qt4/newviewrequest/tst_newviewrequest.qml: -------------------------------------------------------------------------------- 1 | import QtQuickTest 1.0 2 | import QtQuick 1.0 3 | import Sailfish.Silica 1.0 4 | import QtMozilla 1.0 5 | import "../../shared/componentCreation.js" as MyScript 6 | import "../../shared/sharedTests.js" as SharedTests 7 | 8 | ApplicationWindow { 9 | id: appWindow 10 | 11 | property bool mozViewInitialized : false 12 | property variant mozView : null 13 | property variant oldMozView : null 14 | property variant createParentID : 0 15 | 16 | QmlMozContext { 17 | id: mozContext 18 | } 19 | Connections { 20 | target: mozContext.instance 21 | onOnInitialized: { 22 | // Gecko does not switch to SW mode if gl context failed to init 23 | // and qmlmoztestrunner does not build in GL mode 24 | // Let's put it here for now in SW mode always 25 | mozContext.instance.setIsAccelerated(true); 26 | } 27 | onNewWindowRequested: { 28 | print("New Window Requested: url: ", url, ", parentID:", parentId); 29 | appWindow.oldMozView = appWindow.mozView; 30 | appWindow.mozView = null; 31 | appWindow.createParentID = parentId; 32 | MyScript.createSpriteObjects(); 33 | while (appWindow.mozView === null) { 34 | testcaseid.wait() 35 | } 36 | testcaseid.verify(mozView.uniqueID() > 0) 37 | newWinResponse.windowID = mozView.uniqueID(); 38 | } 39 | } 40 | 41 | resources: TestCase { 42 | id: testcaseid 43 | name: "mozContextPage" 44 | when: windowShown 45 | 46 | function cleanup() { 47 | mozContext.dumpTS("tst_newviewrequest cleanup") 48 | } 49 | 50 | function test_1newcontextPrepareViewContext() 51 | { 52 | SharedTests.shared_1newcontextPrepareViewContext() 53 | } 54 | function test_2newviewInit() 55 | { 56 | SharedTests.shared_2newviewInit(false) 57 | } 58 | function test_viewTestNewWindowAPI() 59 | { 60 | SharedTests.shared_viewTestNewWindowAPI() 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /tests/auto/mer-qt4/selection/tst_selection.qml: -------------------------------------------------------------------------------- 1 | import QtQuickTest 1.0 2 | import QtQuick 1.0 3 | import Sailfish.Silica 1.0 4 | import QtMozilla 1.0 5 | import "../../shared/componentCreation.js" as MyScript 6 | import "../../shared/sharedTests.js" as SharedTests 7 | 8 | ApplicationWindow { 9 | id: appWindow 10 | 11 | property bool mozViewInitialized : false 12 | property string selectedContent : "" 13 | 14 | QmlMozContext { 15 | id: mozContext 16 | } 17 | Connections { 18 | target: mozContext.instance 19 | onOnInitialized: { 20 | // Gecko does not switch to SW mode if gl context failed to init 21 | // and qmlmoztestrunner does not build in GL mode 22 | // Let's put it here for now in SW mode always 23 | mozContext.instance.setIsAccelerated(true); 24 | } 25 | onRecvObserve: { 26 | print("onRecvObserve: msg:", message, ", data:", data.data); 27 | appWindow.selectedContent = data.data 28 | } 29 | } 30 | 31 | QmlMozView { 32 | id: webViewport 33 | visible: true 34 | focus: true 35 | anchors.fill: parent 36 | Connections { 37 | target: webViewport.child 38 | onViewInitialized: { 39 | webViewport.child.loadFrameScript("chrome://embedlite/content/embedhelper.js"); 40 | webViewport.child.loadFrameScript("chrome://embedlite/content/SelectHelper.js"); 41 | appWindow.mozViewInitialized = true 42 | webViewport.child.addMessageListeners([ "Content:ContextMenu", "Content:SelectionRange", "Content:SelectionCopied" ]) 43 | } 44 | onRecvAsyncMessage: { 45 | // print("onRecvAsyncMessage:" + message + ", data:" + data) 46 | } 47 | } 48 | } 49 | 50 | resources: TestCase { 51 | id: testcaseid 52 | name: "mozContextPage" 53 | when: windowShown 54 | 55 | function cleanup() { 56 | mozContext.dumpTS("tst_inputtest cleanup") 57 | } 58 | 59 | function test_SelectionInit() 60 | { 61 | SharedTests.shared_SelectionInit() 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /tests/auto/desktop-qt5/newviewrequest/tst_newviewrequest.qml: -------------------------------------------------------------------------------- 1 | import QtTest 1.0 2 | import QtQuick 2.0 3 | import Qt5Mozilla 1.0 4 | import qtmozembed.tests 1.0 5 | import "../../shared/componentCreation.js" as MyScript 6 | import "../../shared/sharedTests.js" as SharedTests 7 | 8 | Item { 9 | id: appWindow 10 | width: 480 11 | height: 800 12 | 13 | property bool mozViewInitialized : false 14 | property variant mozView : null 15 | property variant oldMozView : null 16 | property variant createParentID : 0 17 | 18 | QmlMozContext { 19 | id: mozContext 20 | } 21 | 22 | WebViewCreator { 23 | onNewWindowRequested: { 24 | print("New Window Requested: url: ", url, ", parentID:", parentId); 25 | appWindow.oldMozView = appWindow.mozView; 26 | appWindow.mozView = null; 27 | appWindow.createParentID = parentId; 28 | MyScript.createSpriteObjectsQt5(); 29 | while (appWindow.mozView === null) { 30 | testcaseid.wait() 31 | } 32 | testcaseid.verify(mozView.uniqueID() > 0) 33 | } 34 | } 35 | 36 | Connections { 37 | target: mozContext.instance 38 | onOnInitialized: { 39 | // Gecko does not switch to SW mode if gl context failed to init 40 | // and qmlmoztestrunner does not build in GL mode 41 | // Let's put it here for now in SW mode always 42 | mozContext.instance.setIsAccelerated(true); 43 | } 44 | } 45 | 46 | resources: TestCase { 47 | id: testcaseid 48 | name: "mozContextPage" 49 | when: windowShown 50 | parent: appWindow 51 | 52 | function cleanup() { 53 | mozContext.dumpTS("tst_newviewrequest cleanup") 54 | } 55 | 56 | function test_1newcontextPrepareViewContext() 57 | { 58 | SharedTests.shared_1newcontextPrepareViewContext() 59 | } 60 | function test_2newviewInit() 61 | { 62 | SharedTests.shared_2newviewInit(true) 63 | } 64 | function test_viewTestNewWindowAPI() 65 | { 66 | SharedTests.shared_viewTestNewWindowAPI() 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /tests/auto/desktop-qt5/selection/tst_selection.qml: -------------------------------------------------------------------------------- 1 | import QtTest 1.0 2 | import QtQuick 2.0 3 | import Qt5Mozilla 1.0 4 | import "../../shared/componentCreation.js" as MyScript 5 | import "../../shared/sharedTests.js" as SharedTests 6 | 7 | Item { 8 | id: appWindow 9 | width: 480 10 | height: 800 11 | 12 | property bool mozViewInitialized : false 13 | property string selectedContent : "" 14 | 15 | QmlMozContext { 16 | id: mozContext 17 | } 18 | Connections { 19 | target: mozContext.instance 20 | onOnInitialized: { 21 | // Gecko does not switch to SW mode if gl context failed to init 22 | // and qmlmoztestrunner does not build in GL mode 23 | // Let's put it here for now in SW mode always 24 | mozContext.instance.setIsAccelerated(true); 25 | } 26 | onRecvObserve: { 27 | print("onRecvObserve: msg:", message, ", data:", data.data); 28 | appWindow.selectedContent = data.data 29 | } 30 | } 31 | 32 | QmlMozView { 33 | id: webViewport 34 | visible: true 35 | focus: true 36 | active: true 37 | anchors.fill: parent 38 | Connections { 39 | target: webViewport.child 40 | onViewInitialized: { 41 | webViewport.child.loadFrameScript("chrome://embedlite/content/embedhelper.js"); 42 | webViewport.child.loadFrameScript("chrome://embedlite/content/SelectHelper.js"); 43 | appWindow.mozViewInitialized = true 44 | webViewport.child.addMessageListeners([ "Content:ContextMenu", "Content:SelectionRange", "Content:SelectionCopied" ]) 45 | } 46 | onRecvAsyncMessage: { 47 | print("onRecvAsyncMessage:" + message + ", data:" + data) 48 | } 49 | } 50 | } 51 | 52 | resources: TestCase { 53 | id: testcaseid 54 | name: "mozContextPage" 55 | when: windowShown 56 | parent: appWindow 57 | 58 | function cleanup() { 59 | mozContext.dumpTS("tst_inputtest cleanup") 60 | } 61 | 62 | function test_SelectionInit() 63 | { 64 | SharedTests.shared_SelectionInit() 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /tests/auto/mer-qt4/basicscroll/tst_scrolltest.qml: -------------------------------------------------------------------------------- 1 | import QtQuickTest 1.0 2 | import QtQuick 1.0 3 | import Sailfish.Silica 1.0 4 | import QtMozilla 1.0 5 | import "../../shared/componentCreation.js" as MyScript 6 | import "../../shared/sharedTests.js" as SharedTests 7 | 8 | ApplicationWindow { 9 | id: appWindow 10 | 11 | property bool mozViewInitialized : false 12 | property int scrollX : 0 13 | property int scrollY : 0 14 | property int clickX : 0 15 | property int clickY : 0 16 | 17 | QmlMozContext { 18 | id: mozContext 19 | } 20 | Connections { 21 | target: mozContext.instance 22 | onOnInitialized: { 23 | // Gecko does not switch to SW mode if gl context failed to init 24 | // and qmlmoztestrunner does not build in GL mode 25 | // Let's put it here for now in SW mode always 26 | mozContext.instance.setIsAccelerated(true); 27 | mozContext.instance.addComponentManifest(mozContext.getenv("QTTESTSROOT") + "/components/TestHelpers.manifest"); 28 | } 29 | } 30 | 31 | QmlMozView { 32 | id: webViewport 33 | visible: true 34 | focus: true 35 | anchors.fill: parent 36 | Connections { 37 | target: webViewport.child 38 | onViewInitialized: { 39 | appWindow.mozViewInitialized = true 40 | } 41 | onHandleSingleTap: { 42 | appWindow.clickX = point.x 43 | appWindow.clickY = point.y 44 | } 45 | onViewAreaChanged: { 46 | print("onViewAreaChanged: ", webViewport.child.scrollableOffset.x, webViewport.child.scrollableOffset.y); 47 | var offset = webViewport.child.scrollableOffset 48 | appWindow.scrollX = offset.x 49 | appWindow.scrollY = offset.y 50 | } 51 | } 52 | } 53 | 54 | resources: TestCase { 55 | id: testcaseid 56 | name: "mozContextPage" 57 | when: windowShown 58 | 59 | function cleanup() { 60 | mozContext.dumpTS("tst_scrolltest cleanup") 61 | } 62 | 63 | function test_TestScrollPaintOperations() 64 | { 65 | SharedTests.shared_TestScrollPaintOperations() 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /tests/auto/desktop-qt5/basicscroll/tst_scrolltest.qml: -------------------------------------------------------------------------------- 1 | import QtTest 1.0 2 | import QtQuick 2.0 3 | import Qt5Mozilla 1.0 4 | import "../../shared/componentCreation.js" as MyScript 5 | import "../../shared/sharedTests.js" as SharedTests 6 | 7 | Item { 8 | id: appWindow 9 | width: 480 10 | height: 800 11 | focus: true 12 | 13 | property bool mozViewInitialized : false 14 | property int scrollX : 0 15 | property int scrollY : 0 16 | property int clickX : 0 17 | property int clickY : 0 18 | 19 | QmlMozContext { 20 | id: mozContext 21 | } 22 | Connections { 23 | target: mozContext.instance 24 | onOnInitialized: { 25 | // Gecko does not switch to SW mode if gl context failed to init 26 | // and qmlmoztestrunner does not build in GL mode 27 | // Let's put it here for now in SW mode always 28 | mozContext.instance.setIsAccelerated(true); 29 | mozContext.instance.addComponentManifest(mozContext.getenv("QTTESTSROOT") + "/components/TestHelpers.manifest"); 30 | } 31 | } 32 | 33 | QmlMozView { 34 | id: webViewport 35 | visible: true 36 | focus: true 37 | active: true 38 | anchors.fill: parent 39 | 40 | Connections { 41 | target: webViewport.child 42 | onViewInitialized: { 43 | appWindow.mozViewInitialized = true 44 | } 45 | onHandleSingleTap: { 46 | appWindow.clickX = point.x 47 | appWindow.clickY = point.y 48 | } 49 | onViewAreaChanged: { 50 | print("onViewAreaChanged: ", webViewport.child.scrollableOffset.x, webViewport.child.scrollableOffset.y); 51 | var offset = webViewport.child.scrollableOffset 52 | appWindow.scrollX = offset.x 53 | appWindow.scrollY = offset.y 54 | } 55 | } 56 | } 57 | 58 | resources: TestCase { 59 | id: testcaseid 60 | name: "mozContextPage" 61 | when: windowShown 62 | parent: appWindow 63 | 64 | function cleanup() { 65 | mozContext.dumpTS("tst_scrolltest cleanup") 66 | } 67 | 68 | function test_TestScrollPaintOperations() 69 | { 70 | SharedTests.shared_TestScrollPaintOperations() 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /tests/qmlmoztestrunner/qtestrunner.cpp: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | ** 3 | ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). 4 | ** All rights reserved. 5 | ** Contact: Nokia Corporation (qt-info@nokia.com) 6 | ** 7 | ** This file is part of the test suite of the Qt Toolkit. 8 | ** 9 | ** $QT_BEGIN_LICENSE:LGPL$ 10 | ** No Commercial Usage 11 | ** This file contains pre-release code and may not be distributed. 12 | ** You may use this file in accordance with the terms and conditions 13 | ** contained in the Technology Preview License Agreement accompanying 14 | ** this package. 15 | ** 16 | ** GNU Lesser General Public License Usage 17 | ** Alternatively, this file may be used under the terms of the GNU Lesser 18 | ** General Public License version 2.1 as published by the Free Software 19 | ** Foundation and appearing in the file LICENSE.LGPL included in the 20 | ** packaging of this file. Please review the following information to 21 | ** ensure the GNU Lesser General Public License version 2.1 requirements 22 | ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 23 | ** 24 | ** In addition, as a special exception, Nokia gives you certain additional 25 | ** rights. These rights are described in the Nokia Qt LGPL Exception 26 | ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 | ** 28 | ** If you have questions regarding the use of this file, please contact 29 | ** Nokia at qt-info@nokia.com. 30 | ** 31 | ** $QT_END_LICENSE$ 32 | ** 33 | ****************************************************************************/ 34 | 35 | #include "qmozcontext.h" 36 | #include "qtestrunner.h" 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | 43 | static int gargc; 44 | static char **gargv; 45 | 46 | QTestRunner::QTestRunner(bool isOpenGL, int agargc, char **agargv) 47 | : QObject(0), mIsOpenGL(isOpenGL), mResult(0) 48 | { 49 | gargv = agargv; 50 | gargc = agargc; 51 | } 52 | 53 | int QTestRunner::GetResult() const 54 | { 55 | return mResult; 56 | } 57 | 58 | void QTestRunner::DropInStartup() 59 | { 60 | mResult = RunMainTest(); 61 | QMozContext::GetInstance()->stopEmbedding(); 62 | } 63 | 64 | int QTestRunner::RunMainTest() 65 | { 66 | return quick_test_main(gargc, gargv, "qmlmoztestrunner", 0); 67 | }; 68 | -------------------------------------------------------------------------------- /tests/auto/desktop-qt5/linksactivation/tst_activatelinks.qml: -------------------------------------------------------------------------------- 1 | import QtTest 1.0 2 | import QtQuick 2.0 3 | import Qt5Mozilla 1.0 4 | import "../../shared/componentCreation.js" as MyScript 5 | import "../../shared/sharedTests.js" as SharedTests 6 | 7 | Item { 8 | id: appWindow 9 | width: 480 10 | height: 800 11 | 12 | property bool mozViewInitialized : false 13 | 14 | QmlMozContext { 15 | id: mozContext 16 | } 17 | Connections { 18 | target: mozContext.instance 19 | onOnInitialized: { 20 | // Gecko does not switch to SW mode if gl context failed to init 21 | // and qmlmoztestrunner does not build in GL mode 22 | // Let's put it here for now in SW mode always 23 | mozContext.instance.setIsAccelerated(true); 24 | } 25 | onRecvObserve: { 26 | print("onRecvObserve: msg:", message, ", data:", data.data); 27 | } 28 | } 29 | 30 | QmlMozView { 31 | id: webViewport 32 | visible: true 33 | focus: true 34 | active: true 35 | anchors.fill: parent 36 | Connections { 37 | target: webViewport.child 38 | onViewInitialized: { 39 | webViewport.child.loadFrameScript("chrome://embedlite/content/embedhelper.js"); 40 | webViewport.child.loadFrameScript("chrome://embedlite/content/SelectHelper.js"); 41 | webViewport.child.useQmlMouse = true; 42 | appWindow.mozViewInitialized = true 43 | } 44 | } 45 | } 46 | 47 | MouseArea { 48 | id: viewportMouse 49 | anchors.fill: parent 50 | onPressed: { 51 | webViewport.child.recvMousePress(mouseX, mouseY) 52 | } 53 | onReleased: { 54 | webViewport.child.recvMouseRelease(mouseX, mouseY) 55 | } 56 | onPositionChanged: { 57 | webViewport.child.recvMouseMove(mouseX, mouseY) 58 | } 59 | } 60 | 61 | resources: TestCase { 62 | id: testcaseid 63 | name: "mozContextPage" 64 | when: windowShown 65 | parent: appWindow 66 | 67 | function cleanup() { 68 | mozContext.dumpTS("tst_inputtest cleanup") 69 | } 70 | 71 | function test_ActiveHyperLink() 72 | { 73 | SharedTests.shared_ActiveHyperLink(); 74 | webViewport.child.useQmlMouse = false; 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /src/src.pro: -------------------------------------------------------------------------------- 1 | CONFIG += qt thread debug ordered create_pc create_prl no_install_prl c++11 2 | QT += openglextensions 3 | TARGET = qt5embedwidget 4 | TEMPLATE = lib 5 | 6 | isEmpty(VERSION) { 7 | GIT_TAG = $$system(git describe --tags --abbrev=0) 8 | GIT_VERSION = $$system(echo $$GIT_TAG | sed 's/nemo[/]//') 9 | isEmpty(GIT_VERSION) { 10 | # if you're trying to build this from a tarball, I'm sorry. but being 11 | # able to specify the version in just one place (git tags) is a lot less 12 | # error-prone and easy. 13 | warning("Can't find a valid git tag version, got: $$GIT_TAG") 14 | GIT_VERSION = 0.0.0 15 | } 16 | !isEmpty(GIT_VERSION): VERSION = $$GIT_VERSION 17 | } 18 | 19 | SOURCES += qmozcontext.cpp \ 20 | qmozgrabresult.cpp \ 21 | qmozscrolldecorator.cpp \ 22 | qmessagepump.cpp \ 23 | EmbedQtKeyUtils.cpp \ 24 | qmozview_p.cpp \ 25 | geckoworker.cpp \ 26 | qopenglwebpage.cpp \ 27 | qmozwindow.cpp \ 28 | qmozwindow_p.cpp 29 | 30 | HEADERS += qmozcontext.h \ 31 | qmozgrabresult.h \ 32 | qmozviewcreator.h \ 33 | qmozscrolldecorator.h \ 34 | qmessagepump.h \ 35 | EmbedQtKeyUtils.h \ 36 | qmozview_p.h \ 37 | geckoworker.h \ 38 | qmozview_defined_wrapper.h \ 39 | qmozview_templated_wrapper.h \ 40 | qopenglwebpage.h \ 41 | qmozwindow.h \ 42 | qmozwindow_p.h 43 | 44 | SOURCES += quickmozview.cpp qmoztexturenode.cpp qmozextmaterialnode.cpp 45 | HEADERS += quickmozview.h qmoztexturenode.h qmozextmaterialnode.h 46 | 47 | include(qmozembed.pri) 48 | 49 | RELATIVE_PATH=.. 50 | VDEPTH_PATH=src 51 | include($$RELATIVE_PATH/relative-objdir.pri) 52 | 53 | PREFIX = /usr 54 | 55 | QT += quick qml 56 | 57 | !isEmpty(BUILD_QT5QUICK1) { 58 | QT += declarative widgets opengl 59 | } 60 | 61 | #DEFINES += Q_DEBUG_LOG 62 | 63 | target.path = $$PREFIX/lib 64 | 65 | QMAKE_PKGCONFIG_NAME = qt5embedwidget 66 | QMAKE_PKGCONFIG_DESCRIPTION = Model that emits process info 67 | QMAKE_PKGCONFIG_LIBDIR = $$target.path 68 | QMAKE_PKGCONFIG_INCDIR = $$target.path 69 | QMAKE_PKGCONFIG_DESTDIR = pkgconfig 70 | 71 | # install forwarding headers 72 | # match only the camel case forwarding headers here 73 | FORWARDING_HEADERS = $$system( find q*.h ) 74 | 75 | forwarding_headers.path = $$PREFIX/include 76 | forwarding_headers.files = $$FORWARDING_HEADERS 77 | INSTALLS += forwarding_headers target 78 | -------------------------------------------------------------------------------- /tests/auto/shared/multitouch/touch.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 72 | 73 | 74 |
75 |
76 | Test Div 77 |
78 | 79 | 80 | -------------------------------------------------------------------------------- /tests/auto/mer-qt4/passwordmgr/tst_passwordmgr.qml: -------------------------------------------------------------------------------- 1 | import QtQuickTest 1.0 2 | import QtQuick 1.0 3 | import Sailfish.Silica 1.0 4 | import QtMozilla 1.0 5 | import "../../shared/componentCreation.js" as MyScript 6 | import "../../shared/sharedTests.js" as SharedTests 7 | 8 | ApplicationWindow { 9 | id: appWindow 10 | 11 | property bool mozViewInitialized : false 12 | property variant promptReceived : null 13 | 14 | QmlMozContext { 15 | id: mozContext 16 | } 17 | Connections { 18 | target: mozContext.instance 19 | onOnInitialized: { 20 | // Gecko does not switch to SW mode if gl context failed to init 21 | // and qmlmoztestrunner does not build in GL mode 22 | // Let's put it here for now in SW mode always 23 | mozContext.instance.setIsAccelerated(true); 24 | mozContext.instance.addComponentManifest(mozContext.getenv("QTTESTSROOT") + "/components/TestHelpers.manifest"); 25 | } 26 | } 27 | 28 | QmlMozView { 29 | id: webViewport 30 | visible: true 31 | focus: true 32 | anchors.fill: parent 33 | Connections { 34 | target: webViewport.child 35 | onViewInitialized: { 36 | webViewport.child.loadFrameScript("chrome://tests/content/testHelper.js"); 37 | webViewport.child.loadFrameScript("chrome://embedlite/content/embedhelper.js"); 38 | appWindow.mozViewInitialized = true 39 | webViewport.child.addMessageListener("embed:login"); 40 | } 41 | onRecvAsyncMessage: { 42 | // print("onRecvAsyncMessage:" + message + ", data:" + data) 43 | if (message == "embed:login") { 44 | webViewport.child.sendAsyncMessage("embedui:login", { 45 | buttonidx: 1, 46 | id: data.id 47 | }) 48 | appWindow.promptReceived = true; 49 | } 50 | } 51 | } 52 | } 53 | 54 | resources: TestCase { 55 | id: testcaseid 56 | name: "mozContextPage" 57 | when: windowShown 58 | 59 | function cleanup() { 60 | mozContext.dumpTS("tst_passwordmgr cleanup") 61 | } 62 | 63 | function test_TestLoginMgrPage() 64 | { 65 | SharedTests.shared_TestLoginMgrPage() 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /tests/auto/mer-qt4/multitouch/tst_multitouch.qml: -------------------------------------------------------------------------------- 1 | import QtQuickTest 1.0 2 | import QtQuick 1.0 3 | import Sailfish.Silica 1.0 4 | import QtMozilla 1.0 5 | import "../../shared/componentCreation.js" as MyScript 6 | import "../../shared/sharedTests.js" as SharedTests 7 | 8 | ApplicationWindow { 9 | id: appWindow 10 | 11 | property bool mozViewInitialized : false 12 | property string testResult : "" 13 | 14 | QmlMozContext { 15 | id: mozContext 16 | } 17 | Connections { 18 | target: mozContext.instance 19 | onOnInitialized: { 20 | // Gecko does not switch to SW mode if gl context failed to init 21 | // and qmlmoztestrunner does not build in GL mode 22 | // Let's put it here for now in SW mode always 23 | mozContext.instance.setIsAccelerated(true); 24 | mozContext.instance.addComponentManifest(mozContext.getenv("QTTESTSROOT") + "/components/TestHelpers.manifest"); 25 | } 26 | } 27 | 28 | QmlMozView { 29 | id: webViewport 30 | visible: true 31 | focus: true 32 | anchors.fill: parent 33 | Connections { 34 | target: webViewport.child 35 | onViewInitialized: { 36 | webViewport.child.loadFrameScript("chrome://tests/content/testHelper.js"); 37 | appWindow.mozViewInitialized = true 38 | webViewport.child.addMessageListener("testembed:elementinnervalue"); 39 | } 40 | onHandleSingleTap: { 41 | print("HandleSingleTap: [",point.x,",",point.y,"]"); 42 | } 43 | onRecvAsyncMessage: { 44 | // print("onRecvAsyncMessage:" + message + ", data:" + data) 45 | switch (message) { 46 | case "testembed:elementinnervalue": { 47 | // print("testembed:elementpropvalue value:" + data.value); 48 | appWindow.testResult = data.value; 49 | break; 50 | } 51 | default: 52 | break; 53 | } 54 | 55 | } 56 | } 57 | } 58 | 59 | resources: TestCase { 60 | id: testcaseid 61 | name: "mozContextPage" 62 | when: windowShown 63 | 64 | function cleanup() { 65 | mozContext.dumpTS("tst_multitouch cleanup") 66 | } 67 | 68 | function test_Test1MultiTouchPage() 69 | { 70 | SharedTests.shared_Test1MultiTouchPage() 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /tests/auto/desktop-qt5/passwordmgr/tst_passwordmgr.qml: -------------------------------------------------------------------------------- 1 | import QtTest 1.0 2 | import QtQuick 2.0 3 | import Qt5Mozilla 1.0 4 | import "../../shared/componentCreation.js" as MyScript 5 | import "../../shared/sharedTests.js" as SharedTests 6 | 7 | Item { 8 | id: appWindow 9 | width: 480 10 | height: 800 11 | 12 | property bool mozViewInitialized : false 13 | property variant promptReceived : null 14 | 15 | QmlMozContext { 16 | id: mozContext 17 | } 18 | Connections { 19 | target: mozContext.instance 20 | onOnInitialized: { 21 | // Gecko does not switch to SW mode if gl context failed to init 22 | // and qmlmoztestrunner does not build in GL mode 23 | // Let's put it here for now in SW mode always 24 | mozContext.instance.setIsAccelerated(true); 25 | mozContext.instance.addComponentManifest(mozContext.getenv("QTTESTSROOT") + "/components/TestHelpers.manifest"); 26 | } 27 | } 28 | 29 | QmlMozView { 30 | id: webViewport 31 | visible: true 32 | focus: true 33 | active: true 34 | anchors.fill: parent 35 | Connections { 36 | target: webViewport.child 37 | onViewInitialized: { 38 | webViewport.child.loadFrameScript("chrome://tests/content/testHelper.js"); 39 | webViewport.child.loadFrameScript("chrome://embedlite/content/embedhelper.js"); 40 | appWindow.mozViewInitialized = true 41 | webViewport.child.addMessageListener("embed:login"); 42 | } 43 | onRecvAsyncMessage: { 44 | print("onRecvAsyncMessage:" + message + ", data:" + data) 45 | if (message == "embed:login") { 46 | webViewport.child.sendAsyncMessage("embedui:login", { 47 | buttonidx: 1, 48 | id: data.id 49 | }) 50 | appWindow.promptReceived = true; 51 | } 52 | } 53 | } 54 | } 55 | 56 | resources: TestCase { 57 | id: testcaseid 58 | name: "mozContextPage" 59 | when: windowShown 60 | parent: appWindow 61 | 62 | function cleanup() { 63 | mozContext.dumpTS("tst_passwordmgr cleanup") 64 | } 65 | 66 | function test_TestLoginMgrPage() 67 | { 68 | SharedTests.shared_TestLoginMgrPage() 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/qmozcontext.h: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-*/ 2 | /* vim: set ts=2 sw=2 et tw=79: */ 3 | /* This Source Code Form is subject to the terms of the Mozilla Public 4 | * License, v. 2.0. If a copy of the MPL was not distributed with this file, 5 | * You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 | 7 | #ifndef qmozcontext_h 8 | #define qmozcontext_h 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | class QMozContextPrivate; 15 | 16 | namespace mozilla { 17 | namespace embedlite { 18 | class EmbedLiteApp; 19 | }} 20 | class QMozViewCreator; 21 | 22 | class QMozContext : public QObject 23 | { 24 | Q_OBJECT 25 | public: 26 | typedef void (*TaskCallback)(void* data); 27 | typedef void* TaskHandle; 28 | 29 | virtual ~QMozContext(); 30 | 31 | mozilla::embedlite::EmbedLiteApp* GetApp(); 32 | void setPixelRatio(float ratio); 33 | float pixelRatio() const; 34 | Q_INVOKABLE bool initialized() const; 35 | Q_INVOKABLE bool isAccelerated() const; 36 | 37 | static QMozContext* GetInstance(); 38 | 39 | TaskHandle PostUITask(TaskCallback, void* data, int timeout = 0); 40 | TaskHandle PostCompositorTask(TaskCallback, void* data, int timeout = 0); 41 | void CancelTask(TaskHandle); 42 | 43 | Q_SIGNALS: 44 | void onInitialized(); 45 | void destroyed(); 46 | void lastViewDestroyed(); 47 | void lastWindowDestroyed(); 48 | void recvObserve(const QString message, const QVariant data); 49 | 50 | public Q_SLOTS: 51 | void setIsAccelerated(bool aIsAccelerated); 52 | void addComponentManifest(const QString& manifestPath); 53 | void addObserver(const QString& aTopic); 54 | void sendObserve(const QString& aTopic, const QString& string); 55 | void sendObserve(const QString& aTopic, const QVariant& variant); 56 | // running this without delay specified will execute Gecko/Qt nested main loop 57 | // and block this call until stopEmbedding called 58 | void runEmbedding(int aDelay = -1); 59 | void stopEmbedding(); 60 | void setPref(const QString& aName, const QVariant& aPref); 61 | void notifyFirstUIInitialized(); 62 | void setProfile(const QString); 63 | void addObservers(const QStringList& aObserversList); 64 | void setViewCreator(QMozViewCreator* viewCreator); 65 | quint32 createView(const QString& url, const quint32& parentId = 0); 66 | 67 | private: 68 | QMozContext(QObject* parent = 0); 69 | 70 | QMozContextPrivate* d; 71 | friend class QMozContextPrivate; 72 | }; 73 | 74 | #endif /* qmozcontext_h */ 75 | -------------------------------------------------------------------------------- /tests/auto/desktop-qt5/multitouch/tst_multitouch.qml: -------------------------------------------------------------------------------- 1 | import QtTest 1.0 2 | import QtQuick 2.0 3 | import Qt5Mozilla 1.0 4 | import "../../shared/componentCreation.js" as MyScript 5 | import "../../shared/sharedTests.js" as SharedTests 6 | 7 | Item { 8 | id: appWindow 9 | width: 480 10 | height: 800 11 | 12 | property bool mozViewInitialized : false 13 | property string testResult : "" 14 | 15 | QmlMozContext { 16 | id: mozContext 17 | } 18 | Connections { 19 | target: mozContext.instance 20 | onOnInitialized: { 21 | // Gecko does not switch to SW mode if gl context failed to init 22 | // and qmlmoztestrunner does not build in GL mode 23 | // Let's put it here for now in SW mode always 24 | mozContext.instance.setIsAccelerated(true); 25 | mozContext.instance.addComponentManifest(mozContext.getenv("QTTESTSROOT") + "/components/TestHelpers.manifest"); 26 | } 27 | } 28 | 29 | QmlMozView { 30 | id: webViewport 31 | visible: true 32 | focus: true 33 | active: true 34 | anchors.fill: parent 35 | Connections { 36 | target: webViewport.child 37 | onViewInitialized: { 38 | webViewport.child.loadFrameScript("chrome://tests/content/testHelper.js"); 39 | appWindow.mozViewInitialized = true 40 | webViewport.child.addMessageListener("testembed:elementinnervalue"); 41 | } 42 | onHandleSingleTap: { 43 | print("HandleSingleTap: [",point.x,",",point.y,"]"); 44 | } 45 | onRecvAsyncMessage: { 46 | // print("onRecvAsyncMessage:" + message + ", data:" + data) 47 | switch (message) { 48 | case "testembed:elementinnervalue": { 49 | // print("testembed:elementpropvalue value:" + data.value); 50 | appWindow.testResult = data.value; 51 | break; 52 | } 53 | default: 54 | break; 55 | } 56 | 57 | } 58 | } 59 | } 60 | 61 | resources: TestCase { 62 | id: testcaseid 63 | name: "mozContextPage" 64 | when: windowShown 65 | parent: appWindow 66 | 67 | function cleanup() { 68 | mozContext.dumpTS("tst_multitouch cleanup") 69 | } 70 | 71 | function test_Test1MultiTouchPage() 72 | { 73 | SharedTests.shared_Test1MultiTouchPage() 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /tests/auto/mer-qt4/downloadmgr/tst_downloadmgr.qml: -------------------------------------------------------------------------------- 1 | import QtQuickTest 1.0 2 | import QtQuick 1.0 3 | import Sailfish.Silica 1.0 4 | import QtMozilla 1.0 5 | import "../../shared/componentCreation.js" as MyScript 6 | import "../../shared/sharedTests.js" as SharedTests 7 | 8 | ApplicationWindow { 9 | id: appWindow 10 | 11 | property bool mozViewInitialized : false 12 | property variant promptReceived : null 13 | 14 | QmlMozContext { 15 | id: mozContext 16 | } 17 | Connections { 18 | target: mozContext.instance 19 | onOnInitialized: { 20 | // Gecko does not switch to SW mode if gl context failed to init 21 | // and qmlmoztestrunner does not build in GL mode 22 | // Let's put it here for now in SW mode always 23 | mozContext.instance.setIsAccelerated(true); 24 | mozContext.instance.addComponentManifest(mozContext.getenv("QTTESTSROOT") + "/components/TestHelpers.manifest"); 25 | } 26 | onRecvObserve: { 27 | if (message == "embed:download") { 28 | // print("onRecvObserve: msg:" + message + ", dmsg:" + data.msg); 29 | if (data.msg == "dl-done") { 30 | appWindow.promptReceived = true; 31 | } 32 | } 33 | } 34 | } 35 | 36 | QmlMozView { 37 | id: webViewport 38 | visible: true 39 | focus: true 40 | anchors.fill: parent 41 | Connections { 42 | target: webViewport.child 43 | onViewInitialized: { 44 | webViewport.child.addMessageListener("embed:filepicker"); 45 | appWindow.mozViewInitialized = true 46 | } 47 | onRecvAsyncMessage: { 48 | // print("onRecvAsyncMessage:" + message + ", data:" + data) 49 | if (message == "embed:filepicker") { 50 | webViewport.child.sendAsyncMessage("filepickerresponse", { 51 | winid: data.winid, 52 | accepted: true, 53 | items: ["/tmp/tt.bin"] 54 | }) 55 | } 56 | } 57 | } 58 | } 59 | 60 | resources: TestCase { 61 | id: testcaseid 62 | name: "mozContextPage" 63 | when: windowShown 64 | 65 | function cleanup() { 66 | mozContext.dumpTS("tst_downloadmgr cleanup") 67 | } 68 | 69 | function test_TestDownloadMgrPage() 70 | { 71 | SharedTests.shared_TestDownloadMgrPage() 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /tests/auto/desktop-qt5/downloadmgr/tst_downloadmgr.qml: -------------------------------------------------------------------------------- 1 | import QtTest 1.0 2 | import QtQuick 2.0 3 | import Qt5Mozilla 1.0 4 | import "../../shared/componentCreation.js" as MyScript 5 | import "../../shared/sharedTests.js" as SharedTests 6 | 7 | Item { 8 | id: appWindow 9 | width: 480 10 | height: 800 11 | 12 | property bool mozViewInitialized : false 13 | property variant promptReceived : null 14 | 15 | QmlMozContext { 16 | id: mozContext 17 | } 18 | Connections { 19 | target: mozContext.instance 20 | onOnInitialized: { 21 | // Gecko does not switch to SW mode if gl context failed to init 22 | // and qmlmoztestrunner does not build in GL mode 23 | // Let's put it here for now in SW mode always 24 | mozContext.instance.setIsAccelerated(true); 25 | mozContext.instance.addComponentManifest(mozContext.getenv("QTTESTSROOT") + "/components/TestHelpers.manifest"); 26 | } 27 | onRecvObserve: { 28 | if (message == "embed:download") { 29 | // print("onRecvObserve: msg:" + message + ", dmsg:" + data.msg); 30 | if (data.msg == "dl-done") { 31 | appWindow.promptReceived = true; 32 | } 33 | } 34 | } 35 | } 36 | 37 | QmlMozView { 38 | id: webViewport 39 | visible: true 40 | focus: true 41 | active: true 42 | anchors.fill: parent 43 | Connections { 44 | target: webViewport.child 45 | onViewInitialized: { 46 | webViewport.child.addMessageListener("embed:filepicker"); 47 | appWindow.mozViewInitialized = true 48 | } 49 | onRecvAsyncMessage: { 50 | // print("onRecvAsyncMessage:" + message + ", data:" + data) 51 | if (message == "embed:filepicker") { 52 | webViewport.child.sendAsyncMessage("filepickerresponse", { 53 | winid: data.winid, 54 | accepted: true, 55 | items: ["/tmp/tt.bin"] 56 | }) 57 | } 58 | } 59 | } 60 | } 61 | 62 | resources: TestCase { 63 | id: testcaseid 64 | name: "mozContextPage" 65 | when: windowShown 66 | parent: appWindow 67 | 68 | function cleanup() { 69 | mozContext.dumpTS("tst_downloadmgr cleanup") 70 | } 71 | 72 | function test_TestDownloadMgrPage() 73 | { 74 | SharedTests.shared_TestDownloadMgrPage() 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /debian/rules: -------------------------------------------------------------------------------- 1 | #!/usr/bin/make -f 2 | # -*- makefile -*- 3 | 4 | # Uncomment this to turn on verbose mode. 5 | #export DH_VERBOSE=1 6 | export DEB_DH_MAKESHLIBS_ARG=--ignore-missing-info 7 | package=libqtmozembed 8 | 9 | # These are used for cross-compiling and for saving the configure script 10 | # from having to guess our platform (since we know it already) 11 | DEB_HOST_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE) 12 | DEB_BUILD_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE) 13 | 14 | 15 | CFLAGS = -Wall -g 16 | configopts = 17 | 18 | ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS))) 19 | CFLAGS += -O0 20 | else 21 | CFLAGS += -O2 22 | endif 23 | 24 | ifeq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS))) 25 | INSTALL_PROGRAM += -s 26 | endif 27 | 28 | ifneq (,$(findstring parallel,$(DEB_BUILD_OPTIONS))) 29 | PARALLEL_JOBS := $(shell echo $(DEB_BUILD_OPTIONS) | \ 30 | sed -e 's/.*parallel=\([0-9]\+\).*/\1/') 31 | ifeq ($(DEB_BUILD_OPTIONS),$(PARALLEL_JOBS)) 32 | PARALLEL_JOBS := $(shell if [ -f /proc/cpuinfo ]; \ 33 | then echo `cat /proc/cpuinfo | grep 'processor' | wc -l`; \ 34 | else echo 1; fi) 35 | endif 36 | NJOBS := -j$(PARALLEL_JOBS) 37 | endif 38 | 39 | MAKEFLAGS += $(NJOBS) 40 | DEST_OBJ_DIR=objdir-$(DEB_HOST_ARCH) 41 | 42 | configure: configure-stamp 43 | configure-stamp: 44 | dh_testdir 45 | qmake OBJ_BUILD_PATH=$(DEST_OBJ_DIR) NO_TESTS=1 46 | 47 | touch configure-stamp 48 | 49 | build: build-stamp 50 | build-stamp: configure-stamp 51 | dh_testdir 52 | $(MAKE) 53 | 54 | touch build-stamp 55 | 56 | clean: 57 | dh_testdir 58 | dh_testroot 59 | -rm -f $(CURDIR)/build-stamp 60 | -rm -rf $(CURDIR)/pkgconfig 61 | -rm -f $(CURDIR)/configure-stamp 62 | -rm -rf $(DEST_OBJ_DIR) 63 | [ ! -f Makefile ] || $(MAKE) distclean 64 | rm -f Makefile 65 | dh_clean 66 | 67 | install: build 68 | dh_testdir 69 | dh_testroot 70 | dh_clean -k 71 | dh_installdirs -s 72 | 73 | # Add here commands to install the package into debian/tmp 74 | $(MAKE) install INSTALL_ROOT=$(CURDIR)/debian/tmp 75 | 76 | dh_install --sourcedir=debian/tmp 77 | 78 | 79 | 80 | # Build architecture-independent files here. 81 | binary-indep: build install 82 | # We have nothing to do by default. 83 | 84 | # Build architecture-dependent files here. 85 | binary-arch: build install 86 | dh_testdir 87 | dh_testroot 88 | dh_link 89 | dh_compress 90 | dh_fixperms 91 | dh_strip --dbg-package=$(package)-dbg 92 | dh_makeshlibs 93 | dh_installdeb 94 | dh_shlibdeps 95 | dh_gencontrol 96 | dh_md5sums 97 | ifneq (,$(findstring Maemo 5,$(shell cat /etc/issue))) 98 | maemo-optify 99 | endif 100 | dh_builddeb 101 | 102 | binary: binary-indep binary-arch 103 | .PHONY: build clean binary-indep binary-arch binary install 104 | -------------------------------------------------------------------------------- /tests/components/tests/content/testHelper.js: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 2 | /* This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 | "use strict"; 6 | 7 | let { classes: Cc, interfaces: Ci, results: Cr, utils: Cu } = Components; 8 | Cu.import("resource://gre/modules/XPCOMUtils.jsm"); 9 | Cu.import("resource://gre/modules/Services.jsm"); 10 | Cu.import("resource://gre/modules/Geometry.jsm"); 11 | Cu.import("resource://gre/modules/AddonManager.jsm"); 12 | Cu.import("resource://gre/modules/FileUtils.jsm"); 13 | 14 | let HTMLSelectElement = Ci.nsIDOMHTMLSelectElement; 15 | let HTMLLabelElement = Ci.nsIDOMHTMLLabelElement; 16 | let HTMLIFrameElement = Ci.nsIDOMHTMLIFrameElement; 17 | let HTMLFrameElement = Ci.nsIDOMHTMLFrameElement; 18 | 19 | XPCOMUtils.defineLazyServiceGetter(this, "DOMUtils", 20 | "@mozilla.org/inspector/dom-utils;1", "inIDOMUtils"); 21 | 22 | XPCOMUtils.defineLazyServiceGetter(Services, "embedlite", 23 | "@mozilla.org/embedlite-app-service;1", 24 | "nsIEmbedAppService"); 25 | 26 | const kStateActive = 0x00000001; // :active pseudoclass for elements 27 | 28 | dump("###################################### TestHelper.js loaded\n"); 29 | 30 | var globalObject = null; 31 | 32 | function TestHelper() { 33 | this._init(); 34 | } 35 | 36 | TestHelper.prototype = { 37 | QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver, 38 | Ci.nsISupportsWeakReference]), 39 | 40 | _fastFind: null, 41 | _init: function() 42 | { 43 | dump("Init Called:" + this + "\n"); 44 | // addEventListener("touchend", this, false); 45 | // Services.obs.addObserver(this, "before-first-paint", true); 46 | addMessageListener("embedtest:getelementprop", this); 47 | addMessageListener("embedtest:getelementinner", this); 48 | }, 49 | 50 | observe: function(aSubject, aTopic, data) { 51 | // Ignore notifications not about our document. 52 | dump("observe topic:" + aTopic + "\n"); 53 | }, 54 | 55 | receiveMessage: function receiveMessage(aMessage) { 56 | switch (aMessage.name) { 57 | case "embedtest:getelementprop": { 58 | let element = content.document.getElementById(aMessage.json.name); 59 | sendAsyncMessage("testembed:elementpropvalue", {value: element.value}); 60 | break; 61 | } 62 | case "embedtest:getelementinner": { 63 | let element = content.document.getElementById(aMessage.json.name); 64 | sendAsyncMessage("testembed:elementinnervalue", {value: element.innerHTML}); 65 | break; 66 | } 67 | default: { 68 | break; 69 | } 70 | } 71 | }, 72 | }; 73 | 74 | globalObject = new TestHelper(); 75 | 76 | -------------------------------------------------------------------------------- /src/qmozwindow.cpp: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 2 | /* This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 | 6 | #include "qmozwindow.h" 7 | 8 | #include "qmozcontext.h" 9 | #include "qmozwindow_p.h" 10 | 11 | #include "mozilla/embedlite/EmbedLiteApp.h" 12 | #include "mozilla/embedlite/EmbedLiteWindow.h" 13 | 14 | #include 15 | 16 | using namespace mozilla::embedlite; 17 | 18 | namespace { 19 | 20 | mozilla::ScreenRotation QtToMozillaRotation(Qt::ScreenOrientation orientation) 21 | { 22 | switch (orientation) { 23 | case Qt::PrimaryOrientation: 24 | case Qt::PortraitOrientation: 25 | return mozilla::ROTATION_0; 26 | case Qt::LandscapeOrientation: 27 | return mozilla::ROTATION_90; 28 | case Qt::InvertedLandscapeOrientation: 29 | return mozilla::ROTATION_270; 30 | case Qt::InvertedPortraitOrientation: 31 | return mozilla::ROTATION_180; 32 | default: 33 | Q_UNREACHABLE(); 34 | return mozilla::ROTATION_0; 35 | } 36 | } 37 | 38 | } // namespace 39 | 40 | QMozWindow::QMozWindow(QObject* parent) 41 | : QObject(parent) 42 | , d(new QMozWindowPrivate(*this)) 43 | , mOrientation(Qt::PrimaryOrientation) 44 | { 45 | d->mWindow = QMozContext::GetInstance()->GetApp()->CreateWindow(); 46 | d->mWindow->SetListener(d.data()); 47 | } 48 | 49 | QMozWindow::~QMozWindow() 50 | { 51 | d->mWindow->SetListener(nullptr); 52 | QMozContext::GetInstance()->GetApp()->DestroyWindow(d->mWindow); 53 | d->mWindow = nullptr; 54 | } 55 | 56 | void QMozWindow::setSize(QSize size) 57 | { 58 | if (size != mSize) { 59 | mSize = size; 60 | d->mWindow->SetSize(size.width(), size.height()); 61 | } 62 | } 63 | 64 | void QMozWindow::setContentOrientation(Qt::ScreenOrientation orientation) 65 | { 66 | if (orientation != mOrientation) { 67 | mOrientation = orientation; 68 | d->mWindow->SetContentOrientation(QtToMozillaRotation(orientation)); 69 | } 70 | } 71 | 72 | Qt::ScreenOrientation QMozWindow::contentOrientation() const 73 | { 74 | return mOrientation; 75 | } 76 | 77 | void* QMozWindow::getPlatformImage(int* width, int* height) 78 | { 79 | return d->mWindow->GetPlatformImage(width, height); 80 | } 81 | 82 | void QMozWindow::suspendRendering() 83 | { 84 | d->mWindow->SuspendRendering(); 85 | } 86 | 87 | void QMozWindow::resumeRendering() 88 | { 89 | d->mWindow->ResumeRendering(); 90 | } 91 | 92 | void QMozWindow::scheduleUpdate() 93 | { 94 | d->mWindow->ScheduleUpdate(); 95 | } 96 | 97 | bool QMozWindow::setReadyToPaint(bool ready) 98 | { 99 | return d->setReadyToPaint(ready); 100 | } 101 | 102 | bool QMozWindow::readyToPaint() const 103 | { 104 | return d->PreRender(); 105 | } 106 | -------------------------------------------------------------------------------- /tests/auto/mer-qt4/searchengine/tst_searchengine.qml: -------------------------------------------------------------------------------- 1 | import QtQuickTest 1.0 2 | import QtQuick 1.0 3 | import Sailfish.Silica 1.0 4 | import QtMozilla 1.0 5 | import "../../shared/componentCreation.js" as MyScript 6 | import "../../shared/sharedTests.js" as SharedTests 7 | 8 | ApplicationWindow { 9 | id: appWindow 10 | 11 | property bool mozViewInitialized : false 12 | property variant testResult : null 13 | 14 | QmlMozContext { 15 | id: mozContext 16 | } 17 | Connections { 18 | target: mozContext.instance 19 | onOnInitialized: { 20 | // Gecko does not switch to SW mode if gl context failed to init 21 | // and qmlmoztestrunner does not build in GL mode 22 | // Let's put it here for now in SW mode always 23 | mozContext.instance.setIsAccelerated(true); 24 | mozContext.instance.addComponentManifest(mozContext.getenv("QTTESTSROOT") + "/components/TestHelpers.manifest"); 25 | mozContext.instance.setPref("browser.search.log", true); 26 | mozContext.instance.addObserver("browser-search-engine-modified"); 27 | mozContext.instance.addObserver("embed:search"); 28 | mozContext.instance.setPref("keyword.enabled", true); 29 | } 30 | onRecvObserve: { 31 | if (message == "embed:search") { 32 | switch (data.msg) { 33 | case "init": { 34 | print("Received: search:" + message, ", msg: ", data.msg, data.defaultEngine); 35 | } 36 | case "pluginslist": { 37 | print("Received: search:" + message, ", msg: ", data.msg, data.list[0].name, data.list[0].isDefault, data.list[0].isCurrent); 38 | appWindow.testResult = data.list[0].name; 39 | } 40 | } 41 | } else if (message == "browser-search-engine-modified") { 42 | if (data == "engine-loaded") { 43 | appWindow.testResult = "loaded"; 44 | } 45 | print("Received: search mod:", data); 46 | } 47 | } 48 | } 49 | 50 | QmlMozView { 51 | id: webViewport 52 | visible: true 53 | focus: true 54 | anchors.fill: parent 55 | Connections { 56 | target: webViewport.child 57 | onViewInitialized: { 58 | appWindow.mozViewInitialized = true 59 | } 60 | onRecvAsyncMessage: { 61 | print("onRecvAsyncMessage:" + message + ", data:" + data) 62 | } 63 | } 64 | } 65 | 66 | resources: TestCase { 67 | id: testcaseid 68 | name: "mozContextPage" 69 | when: windowShown 70 | 71 | function cleanup() { 72 | mozContext.dumpTS("tst_searchengine cleanup") 73 | } 74 | 75 | function test_TestCheckDefaultSearch() 76 | { 77 | SharedTests.shared_TestCheckDefaultSearch() 78 | } 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /tests/auto/desktop-qt5/searchengine/tst_searchengine.qml: -------------------------------------------------------------------------------- 1 | import QtTest 1.0 2 | import QtQuick 2.0 3 | import Qt5Mozilla 1.0 4 | import "../../shared/componentCreation.js" as MyScript 5 | import "../../shared/sharedTests.js" as SharedTests 6 | 7 | Item { 8 | id: appWindow 9 | width: 480 10 | height: 800 11 | 12 | property bool mozViewInitialized : false 13 | property variant testResult : null 14 | 15 | QmlMozContext { 16 | id: mozContext 17 | } 18 | Connections { 19 | target: mozContext.instance 20 | onOnInitialized: { 21 | // Gecko does not switch to SW mode if gl context failed to init 22 | // and qmlmoztestrunner does not build in GL mode 23 | // Let's put it here for now in SW mode always 24 | mozContext.instance.setIsAccelerated(true); 25 | mozContext.instance.addComponentManifest(mozContext.getenv("QTTESTSROOT") + "/components/TestHelpers.manifest"); 26 | mozContext.instance.setPref("browser.search.log", true); 27 | mozContext.instance.addObserver("browser-search-engine-modified"); 28 | mozContext.instance.addObserver("embed:search"); 29 | mozContext.instance.setPref("keyword.enabled", true); 30 | } 31 | onRecvObserve: { 32 | if (message == "embed:search") { 33 | switch (data.msg) { 34 | case "init": { 35 | print("Received: search:" + message, ", msg: ", data.msg, data.defaultEngine); 36 | break; 37 | } 38 | case "pluginslist": { 39 | print("Received: search:" + message, ", msg: ", data.msg, data.list[0].name, data.list[0].isDefault, data.list[0].isCurrent); 40 | appWindow.testResult = data.list; 41 | break; 42 | } 43 | } 44 | } else if (message == "browser-search-engine-modified") { 45 | if (data == "engine-loaded") { 46 | appWindow.testResult = "loaded"; 47 | } 48 | print("Received: search mod:", data); 49 | } 50 | } 51 | } 52 | 53 | QmlMozView { 54 | id: webViewport 55 | visible: true 56 | focus: true 57 | active: true 58 | anchors.fill: parent 59 | Connections { 60 | target: webViewport.child 61 | onViewInitialized: { 62 | appWindow.mozViewInitialized = true 63 | } 64 | onRecvAsyncMessage: { 65 | print("onRecvAsyncMessage:" + message + ", data:" + data) 66 | } 67 | } 68 | } 69 | 70 | resources: TestCase { 71 | id: testcaseid 72 | name: "mozContextPage" 73 | when: windowShown 74 | parent: appWindow 75 | 76 | function cleanup() { 77 | mozContext.dumpTS("tst_searchengine cleanup") 78 | } 79 | 80 | function test_TestCheckDefaultSearch() 81 | { 82 | SharedTests.shared_TestCheckDefaultSearch() 83 | } 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /tests/test-definition/tests.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | QtMozEmbed Application automatic tests 5 | 6 | QML component unit tests 7 | 8 | cd /opt/tests/qtmozembed/auto/mer-qt4/context &&DISPLAY=:0 QTVER=4 ../../run-tests.sh 9 | 10 | 11 | cd /opt/tests/qtmozembed/auto/mer-qt4/basicview &&DISPLAY=:0 QTVER=4 ../../run-tests.sh 12 | 13 | 14 | cd /opt/tests/qtmozembed/auto/mer-qt4/view &&DISPLAY=:0 QTVER=4 ../../run-tests.sh 15 | 16 | 17 | cd /opt/tests/qtmozembed/auto/mer-qt4/basicinput &&DISPLAY=:0 QTVER=4 ../../run-tests.sh 18 | 19 | 20 | cd /opt/tests/qtmozembed/auto/mer-qt4/basicscroll &&DISPLAY=:0 QTVER=4 ../../run-tests.sh 21 | 22 | 23 | cd /opt/tests/qtmozembed/auto/mer-qt4/multitouch &&DISPLAY=:0 QTVER=4 ../../run-tests.sh 24 | 25 | 26 | cd /opt/tests/qtmozembed/auto/mer-qt4/favicons &&DISPLAY=:0 QTVER=4 ../../run-tests.sh 27 | 28 | 29 | cd /opt/tests/qtmozembed/auto/mer-qt4/promptbasic &&DISPLAY=:0 QTVER=4 ../../run-tests.sh 30 | 31 | 32 | cd /opt/tests/qtmozembed/auto/mer-qt4/searchengine &&DISPLAY=:0 QTVER=4 ../../run-tests.sh 33 | 34 | 35 | cd /opt/tests/qtmozembed/auto/mer-qt4/passwordmgr &&DISPLAY=:0 QTVER=4 ../../run-tests.sh 36 | 37 | 38 | cd /opt/tests/qtmozembed/auto/mer-qt4/downloadmgr &&DISPLAY=:0 QTVER=4 ../../run-tests.sh 39 | 40 | 41 | cd /opt/tests/qtmozembed/auto/mer-qt4/newviewrequest &&DISPLAY=:0 QTVER=4 ../../run-tests.sh 42 | 43 | 44 | cd /opt/tests/qtmozembed/auto/mer-qt4/selection &&DISPLAY=:0 QTVER=4 ../../run-tests.sh 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /tests/qmlmoztestrunner/main.cpp: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | ** 3 | ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). 4 | ** All rights reserved. 5 | ** Contact: Nokia Corporation (qt-info@nokia.com) 6 | ** 7 | ** This file is part of the test suite of the Qt Toolkit. 8 | ** 9 | ** $QT_BEGIN_LICENSE:LGPL$ 10 | ** No Commercial Usage 11 | ** This file contains pre-release code and may not be distributed. 12 | ** You may use this file in accordance with the terms and conditions 13 | ** contained in the Technology Preview License Agreement accompanying 14 | ** this package. 15 | ** 16 | ** GNU Lesser General Public License Usage 17 | ** Alternatively, this file may be used under the terms of the GNU Lesser 18 | ** General Public License version 2.1 as published by the Free Software 19 | ** Foundation and appearing in the file LICENSE.LGPL included in the 20 | ** packaging of this file. Please review the following information to 21 | ** ensure the GNU Lesser General Public License version 2.1 requirements 22 | ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 23 | ** 24 | ** In addition, as a special exception, Nokia gives you certain additional 25 | ** rights. These rights are described in the Nokia Qt LGPL Exception 26 | ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 | ** 28 | ** If you have questions regarding the use of this file, please contact 29 | ** Nokia at qt-info@nokia.com. 30 | ** 31 | ** $QT_END_LICENSE$ 32 | ** 33 | ****************************************************************************/ 34 | 35 | #include "qmozcontext.h" 36 | #include "testviewcreator.h" 37 | #include "qtestrunner.h" 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | 45 | int main(int argc, char **argv) 46 | { 47 | int retv = 0; 48 | { 49 | QGuiApplication app(argc, argv); 50 | { 51 | bool isOpenGL = false; 52 | for (int index = 1; index < argc; ++index) { 53 | if (strcmp(argv[index], "-opengl") == 0) { 54 | isOpenGL = true; 55 | break; 56 | } 57 | } 58 | 59 | qmlRegisterType("qtmozembed.tests", 1, 0, "WebViewCreator"); 60 | 61 | QTestRunner runn(isOpenGL, argc, argv); 62 | QTimer::singleShot(0, &runn, SLOT(DropInStartup())); 63 | // These components must be loaded before app start 64 | QString componentPath(DEFAULT_COMPONENTS_PATH); 65 | QMozContext::GetInstance()->addComponentManifest(componentPath + QString("/components") + QString("/EmbedLiteBinComponents.manifest")); 66 | QMozContext::GetInstance()->addComponentManifest(componentPath + QString("/chrome") + QString("/EmbedLiteJSScripts.manifest")); 67 | QMozContext::GetInstance()->addComponentManifest(componentPath + QString("/chrome") + QString("/EmbedLiteOverrides.manifest")); 68 | QMozContext::GetInstance()->addComponentManifest(componentPath + QString("/components") + QString("/EmbedLiteJSComponents.manifest")); 69 | QMozContext::GetInstance()->runEmbedding(); 70 | 71 | retv = runn.GetResult(); 72 | } 73 | app.quit(); 74 | } 75 | return retv; 76 | } 77 | -------------------------------------------------------------------------------- /tests/auto/shared/componentCreation.js: -------------------------------------------------------------------------------- 1 | var component; 2 | var sprite; 3 | var context_view_wait_timeout = 1000; 4 | var load_finish_wait_timeout = 10000; 5 | 6 | function createSpriteObjects() { 7 | component = Qt.createComponent(mozContext.getenv("QTTESTSROOT") + "/auto/shared/ViewComponent.qml"); 8 | if (component.status == Component.Ready) { 9 | finishCreation(); 10 | } 11 | else { 12 | component.statusChanged.connect(finishCreation); 13 | } 14 | } 15 | 16 | function createSpriteObjectsQt5() { 17 | component = Qt.createComponent(mozContext.getenv("QTTESTSROOT") + "/auto/shared/ViewComponentQt5.qml"); 18 | if (component.status == Component.Ready) { 19 | finishCreation(); 20 | } 21 | else { 22 | component.statusChanged.connect(finishCreation); 23 | } 24 | } 25 | 26 | function finishCreation() { 27 | if (component.status == Component.Ready) { 28 | appWindow.mozView = component.createObject(appWindow, {"x": 0, "y": 0, "active": true}); 29 | if (appWindow.mozView == null) { 30 | // Error Handling 31 | console.log("Error creating object"); 32 | } 33 | } else if (component.status == Component.Error) { 34 | // Error Handling 35 | console.log("Error loading component:", component.errorString()); 36 | } 37 | } 38 | 39 | function waitMozContext() { 40 | if (mozContext.instance === undefined) { 41 | return false; 42 | } 43 | if (mozContext.instance.initialized()) { 44 | return true; 45 | } 46 | var ticks = 0; 47 | while (!mozContext.instance.initialized() && ticks++ < context_view_wait_timeout) { 48 | testcaseid.wait(); 49 | } 50 | return ticks < context_view_wait_timeout; 51 | } 52 | 53 | function waitMozView() { 54 | if (appWindow.mozViewInitialized) { 55 | return true; 56 | } 57 | var ticks = 0; 58 | while (!appWindow.mozViewInitialized && ticks++ < context_view_wait_timeout) { 59 | testcaseid.wait(); 60 | } 61 | return ticks < context_view_wait_timeout; 62 | } 63 | 64 | function waitLoadFinished(view) { 65 | if (!view.child.loading && view.child.loadProgress !== 0) { 66 | return true; 67 | } 68 | var ticks = 0; 69 | while ((view.child.loading || view.child.loadProgress === 0) && ticks++ < load_finish_wait_timeout) { 70 | testcaseid.wait(); 71 | } 72 | return ticks < load_finish_wait_timeout; 73 | } 74 | 75 | function dumpTs(message) { 76 | print("TimeStamp:" + message + ", " + Qt.formatTime(new Date(), "hh:mm:ss::ms") + "\n"); 77 | } 78 | 79 | function scrollBy(startX, startY, dx, dy, timeMs, isKinetic) 80 | { 81 | var frameMs = 16; 82 | var timeMsStep = timeMs / frameMs; 83 | var stepRX = dx / timeMsStep; 84 | var stepRY = dy / timeMsStep; 85 | var curRX = startX; 86 | var curRY = startY; 87 | var endRX = curRX + dx; 88 | var endRY = curRY + dy; 89 | testcaseid.mousePress(webViewport, curRX, curRY, 1); 90 | while (curRX != endRX || curRY != endRY) { 91 | curRX = stepRX > 0 ? Math.min(curRX + stepRX, endRX) : Math.max(curRX + stepRX, endRX); 92 | curRY = stepRY > 0 ? Math.min(curRY + stepRY, endRY) : Math.max(curRY + stepRY, endRY); 93 | testcaseid.mouseMove(webViewport, curRX, curRY, -1, 1); 94 | } 95 | testcaseid.mouseRelease(webViewport, curRX, curRY, 1); 96 | testcaseid.mousePress(webViewport, curRX, curRY, 1); 97 | testcaseid.mouseRelease(webViewport, curRX, curRY, 1); 98 | } 99 | -------------------------------------------------------------------------------- /tests/auto/mer-qt4/basicinput/tst_inputtest.qml: -------------------------------------------------------------------------------- 1 | import QtQuickTest 1.0 2 | import QtQuick 1.0 3 | import Sailfish.Silica 1.0 4 | import QtMozilla 1.0 5 | import "../../shared/componentCreation.js" as MyScript 6 | import "../../shared/sharedTests.js" as SharedTests 7 | 8 | ApplicationWindow { 9 | id: appWindow 10 | 11 | property bool mozViewInitialized : false 12 | property string inputContent : "" 13 | property int inputState : -1 14 | property bool changed : false 15 | property int focusChange : -1 16 | property int cause : -1 17 | property string inputType : "" 18 | 19 | function isState(state, focus, cause) 20 | { 21 | return appWindow.changed === true && appWindow.inputState === state && appWindow.focusChange === focus && appWindow.cause === cause; 22 | } 23 | 24 | QmlMozContext { 25 | id: mozContext 26 | } 27 | Connections { 28 | target: mozContext.instance 29 | onOnInitialized: { 30 | // Gecko does not switch to SW mode if gl context failed to init 31 | // and qmlmoztestrunner does not build in GL mode 32 | // Let's put it here for now in SW mode always 33 | mozContext.instance.setIsAccelerated(true); 34 | mozContext.instance.addComponentManifest(mozContext.getenv("QTTESTSROOT") + "/components/TestHelpers.manifest"); 35 | } 36 | } 37 | 38 | QmlMozView { 39 | id: webViewport 40 | visible: true 41 | focus: true 42 | anchors.fill: parent 43 | Connections { 44 | target: webViewport.child 45 | onViewInitialized: { 46 | webViewport.child.loadFrameScript("chrome://tests/content/testHelper.js"); 47 | appWindow.mozViewInitialized = true 48 | webViewport.child.addMessageListener("testembed:elementpropvalue"); 49 | } 50 | onHandleSingleTap: { 51 | print("HandleSingleTap: [",point.x,",",point.y,"]"); 52 | } 53 | onRecvAsyncMessage: { 54 | // print("onRecvAsyncMessage:" + message + ", data:" + data) 55 | switch (message) { 56 | case "testembed:elementpropvalue": { 57 | // print("testembed:elementpropvalue value:" + data.value); 58 | appWindow.inputContent = data.value; 59 | break; 60 | } 61 | default: 62 | break; 63 | } 64 | } 65 | onImeNotification: { 66 | print("onImeNotification: state:" + state + ", open:" + open + ", cause:" + cause + ", focChange:" + focusChange + ", type:" + type) 67 | appWindow.changed = true 68 | appWindow.inputState = state 69 | appWindow.cause = cause 70 | appWindow.focusChange = focusChange 71 | appWindow.inputType = type 72 | } 73 | } 74 | } 75 | 76 | resources: TestCase { 77 | id: testcaseid 78 | name: "mozContextPage" 79 | when: windowShown 80 | 81 | function cleanup() { 82 | mozContext.dumpTS("tst_inputtest cleanup") 83 | } 84 | 85 | function test_Test1LoadInputPage() 86 | { 87 | SharedTests.shared_Test1LoadInputPage() 88 | } 89 | 90 | function test_Test1LoadInputURLPage() 91 | { 92 | SharedTests.shared_Test1LoadInputURLPage() 93 | } 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /src/qmessagepump.cpp: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-*/ 2 | /* vim: set ts=2 sw=2 et tw=79: */ 3 | /* This Source Code Form is subject to the terms of the Mozilla Public 4 | * License, v. 2.0. If a copy of the MPL was not distributed with this file, 5 | * You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 | 7 | #define LOG_COMPONENT "MessagePumpQt" 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #include "qmessagepump.h" 16 | 17 | #include "mozilla/embedlite/EmbedLiteMessagePump.h" 18 | #include "mozilla/embedlite/EmbedLiteApp.h" 19 | 20 | using namespace mozilla::embedlite; 21 | 22 | namespace { 23 | // Cached QEvent user type, registered for our event system 24 | static int sPokeEvent; 25 | } // namespace 26 | 27 | MessagePumpQt::MessagePumpQt(EmbedLiteApp* aApp) 28 | : mApp(aApp), mTimer(new QTimer(this)), state_(0), mLastDelayedWorkTime(-1) 29 | { 30 | mEventLoopPrivate = mApp->CreateEmbedLiteMessagePump(this); 31 | // Register our custom event type, to use in qApp event loop 32 | sPokeEvent = QEvent::registerEventType(); 33 | connect(mTimer, SIGNAL(timeout()), this, SLOT(dispatchDelayed())); 34 | mTimer->setSingleShot(true); 35 | } 36 | 37 | MessagePumpQt::~MessagePumpQt() 38 | { 39 | mTimer->stop(); 40 | delete mTimer; 41 | delete state_; 42 | delete mEventLoopPrivate; 43 | } 44 | 45 | bool 46 | MessagePumpQt::event(QEvent *e) 47 | { 48 | if (e->type() == sPokeEvent) { 49 | HandleDispatch(); 50 | return true; 51 | } 52 | return QObject::event(e); 53 | } 54 | 55 | void MessagePumpQt::HandleDispatch() 56 | { 57 | if (state_->should_quit) { 58 | return; 59 | } 60 | 61 | if (mEventLoopPrivate->DoWork(state_->delegate)) { 62 | // there might be more, see more_work_is_plausible 63 | // variable above, that's why we ScheduleWork() to keep going. 64 | ScheduleWorkLocal(); 65 | } 66 | 67 | if (state_->should_quit) { 68 | return; 69 | } 70 | 71 | bool doIdleWork = !mEventLoopPrivate->DoDelayedWork(state_->delegate); 72 | scheduleDelayedIfNeeded(); 73 | 74 | if (doIdleWork) { 75 | if (mEventLoopPrivate->DoIdleWork(state_->delegate)) { 76 | ScheduleWorkLocal(); 77 | } 78 | } 79 | } 80 | 81 | void MessagePumpQt::ScheduleWorkLocal() 82 | { 83 | QCoreApplication::postEvent(this, 84 | new QEvent((QEvent::Type)sPokeEvent)); 85 | } 86 | 87 | void 88 | MessagePumpQt::scheduleDelayedIfNeeded() 89 | { 90 | if (mLastDelayedWorkTime == -1) { 91 | return; 92 | } 93 | 94 | if (mTimer->isActive()) { 95 | mTimer->stop(); 96 | } 97 | 98 | mTimer->start(mLastDelayedWorkTime >= 0 ? mLastDelayedWorkTime : 0); 99 | } 100 | 101 | void 102 | MessagePumpQt::dispatchDelayed() 103 | { 104 | HandleDispatch(); 105 | } 106 | 107 | void MessagePumpQt::Run(void* delegate) 108 | { 109 | RunState* state = new RunState(); 110 | state->delegate = delegate; 111 | state->should_quit = false; 112 | state->run_depth = state_ ? state_->run_depth + 1 : 1; 113 | state_ = state; 114 | HandleDispatch(); 115 | } 116 | 117 | void MessagePumpQt::Quit() 118 | { 119 | if (state_) { 120 | state_->should_quit = true; 121 | state_->delegate = NULL; 122 | } 123 | } 124 | 125 | void MessagePumpQt::ScheduleWork() 126 | { 127 | ScheduleWorkLocal(); 128 | } 129 | 130 | void MessagePumpQt::ScheduleDelayedWork(const int aDelay) 131 | { 132 | mLastDelayedWorkTime = aDelay; 133 | scheduleDelayedIfNeeded(); 134 | } 135 | -------------------------------------------------------------------------------- /tests/auto/desktop-qt5/basicinput/tst_inputtest.qml: -------------------------------------------------------------------------------- 1 | import QtTest 1.0 2 | import QtQuick 2.0 3 | import Qt5Mozilla 1.0 4 | import "../../shared/componentCreation.js" as MyScript 5 | import "../../shared/sharedTests.js" as SharedTests 6 | 7 | Item { 8 | id: appWindow 9 | width: 480 10 | height: 800 11 | 12 | property bool mozViewInitialized : false 13 | property string inputContent : "" 14 | property int inputState : -1 15 | property bool changed : false 16 | property int focusChange : -1 17 | property int cause : -1 18 | property string inputType : "" 19 | 20 | function isState(state, focus, cause) 21 | { 22 | return appWindow.changed === true && appWindow.inputState === state && appWindow.focusChange === focus && appWindow.cause === cause; 23 | } 24 | 25 | QmlMozContext { 26 | id: mozContext 27 | } 28 | Connections { 29 | target: mozContext.instance 30 | onOnInitialized: { 31 | // Gecko does not switch to SW mode if gl context failed to init 32 | // and qmlmoztestrunner does not build in GL mode 33 | // Let's put it here for now in SW mode always 34 | mozContext.instance.setIsAccelerated(true); 35 | mozContext.instance.addComponentManifest(mozContext.getenv("QTTESTSROOT") + "/components/TestHelpers.manifest"); 36 | } 37 | } 38 | 39 | QmlMozView { 40 | id: webViewport 41 | clip: false 42 | visible: true 43 | focus: true 44 | active: true 45 | 46 | anchors.fill: parent 47 | Connections { 48 | target: webViewport.child 49 | onViewInitialized: { 50 | webViewport.child.loadFrameScript("chrome://tests/content/testHelper.js"); 51 | appWindow.mozViewInitialized = true 52 | webViewport.child.addMessageListener("testembed:elementpropvalue"); 53 | } 54 | onHandleSingleTap: { 55 | print("HandleSingleTap: [",point.x,",",point.y,"]"); 56 | } 57 | onRecvAsyncMessage: { 58 | // print("onRecvAsyncMessage:" + message + ", data:" + data) 59 | switch (message) { 60 | case "testembed:elementpropvalue": { 61 | // print("testembed:elementpropvalue value:" + data.value); 62 | appWindow.inputContent = data.value; 63 | break; 64 | } 65 | default: 66 | break; 67 | } 68 | } 69 | onImeNotification: { 70 | print("onImeNotification: state:" + state + ", open:" + open + ", cause:" + cause + ", focChange:" + focusChange + ", type:" + type) 71 | appWindow.changed = true 72 | appWindow.inputState = state 73 | appWindow.cause = cause 74 | appWindow.focusChange = focusChange 75 | appWindow.inputType = type 76 | } 77 | } 78 | } 79 | 80 | resources: TestCase { 81 | id: testcaseid 82 | name: "mozContextPage" 83 | when: windowShown 84 | parent: appWindow 85 | 86 | function cleanup() { 87 | mozContext.dumpTS("tst_inputtest cleanup") 88 | } 89 | 90 | function test_Test1LoadInputPage() 91 | { 92 | SharedTests.shared_Test1LoadInputPage() 93 | } 94 | 95 | function test_Test1LoadInputURLPage() 96 | { 97 | SharedTests.shared_Test1LoadInputURLPage() 98 | } 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /tests/auto/mer-qt4/promptbasic/tst_prompt.qml: -------------------------------------------------------------------------------- 1 | import QtQuickTest 1.0 2 | import QtQuick 1.0 3 | import Sailfish.Silica 1.0 4 | import QtMozilla 1.0 5 | import "../../shared/componentCreation.js" as MyScript 6 | import "../../shared/sharedTests.js" as SharedTests 7 | 8 | ApplicationWindow { 9 | id: appWindow 10 | 11 | property bool mozViewInitialized : false 12 | property variant promptReceived : null 13 | property variant testResult : null 14 | property variant testCaseNum : 0 15 | 16 | QmlMozContext { 17 | id: mozContext 18 | } 19 | Connections { 20 | target: mozContext.instance 21 | onOnInitialized: { 22 | // Gecko does not switch to SW mode if gl context failed to init 23 | // and qmlmoztestrunner does not build in GL mode 24 | // Let's put it here for now in SW mode always 25 | mozContext.instance.setIsAccelerated(true); 26 | mozContext.instance.addComponentManifest(mozContext.getenv("QTTESTSROOT") + "/components/TestHelpers.manifest"); 27 | } 28 | } 29 | 30 | QmlMozView { 31 | id: webViewport 32 | visible: true 33 | focus: true 34 | anchors.fill: parent 35 | Connections { 36 | target: webViewport.child 37 | onViewInitialized: { 38 | webViewport.child.loadFrameScript("chrome://tests/content/testHelper.js"); 39 | appWindow.mozViewInitialized = true 40 | webViewport.child.addMessageListener("testembed:elementinnervalue"); 41 | webViewport.child.addMessageListener("embed:prompt"); 42 | } 43 | onRecvAsyncMessage: { 44 | // print("onRecvAsyncMessage:" + message + ", data:" + data) 45 | if (message == "embed:prompt") { 46 | testcaseid.compare(data.defaultValue, "Your name"); 47 | testcaseid.compare(data.text, "Please enter your name:"); 48 | var responsePrompt = null; 49 | switch(appWindow.testCaseNum) { 50 | case 0: 51 | responsePrompt="expectedPromptResult"; 52 | break; 53 | case 1: 54 | responsePrompt="unexpectedPromptResult"; 55 | break; 56 | } 57 | if (responsePrompt) { 58 | webViewport.child.sendAsyncMessage("promptresponse", { 59 | winid: data.winid, 60 | checkval: true, 61 | accepted: true, 62 | promptvalue: responsePrompt 63 | }) 64 | } 65 | appWindow.promptReceived = true; 66 | } else if (message == "testembed:elementinnervalue") { 67 | appWindow.testResult = data.value; 68 | } 69 | } 70 | } 71 | } 72 | 73 | resources: TestCase { 74 | id: testcaseid 75 | name: "mozContextPage" 76 | when: windowShown 77 | 78 | function cleanup() { 79 | mozContext.dumpTS("tst_multitouch cleanup") 80 | } 81 | 82 | function test_TestPromptPage() 83 | { 84 | SharedTests.shared_TestPromptPage() 85 | } 86 | 87 | function test_TestPromptWithBadResponse() 88 | { 89 | SharedTests.shared_TestPromptWithBadResponse() 90 | } 91 | 92 | function test_TestPromptWithoutResponse() 93 | { 94 | SharedTests.shared_TestPromptWithoutResponse() 95 | } 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /tests/test-definition-qt5/tests.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | QtMozEmbed Application automatic tests 5 | 6 | QML component unit tests 7 | 8 | /usr/sbin/mcetool --set-demo-mode=on 9 | 10 | 11 | /usr/sbin/mcetool --set-demo-mode=off 12 | 13 | 14 | cd /opt/tests/qtmozembed/auto/desktop-qt5/context &&DISPLAY=:0 QTVER=5 ../../run-tests.sh 15 | 16 | 17 | cd /opt/tests/qtmozembed/auto/desktop-qt5/basicview &&DISPLAY=:0 QTVER=5 ../../run-tests.sh 18 | 19 | 20 | cd /opt/tests/qtmozembed/auto/desktop-qt5/view &&DISPLAY=:0 QTVER=5 ../../run-tests.sh 21 | 22 | 23 | cd /opt/tests/qtmozembed/auto/desktop-qt5/basicinput &&DISPLAY=:0 QTVER=5 ../../run-tests.sh 24 | 25 | 26 | cd /opt/tests/qtmozembed/auto/desktop-qt5/basicscroll &&DISPLAY=:0 QTVER=5 ../../run-tests.sh 27 | 28 | 29 | cd /opt/tests/qtmozembed/auto/desktop-qt5/multitouch &&DISPLAY=:0 QTVER=5 ../../run-tests.sh 30 | 31 | 32 | cd /opt/tests/qtmozembed/auto/desktop-qt5/favicons &&DISPLAY=:0 QTVER=5 ../../run-tests.sh 33 | 34 | 35 | cd /opt/tests/qtmozembed/auto/desktop-qt5/promptbasic &&DISPLAY=:0 QTVER=5 ../../run-tests.sh 36 | 37 | 38 | cd /opt/tests/qtmozembed/auto/desktop-qt5/searchengine &&DISPLAY=:0 QTVER=5 ../../run-tests.sh 39 | 40 | 41 | cd /opt/tests/qtmozembed/auto/desktop-qt5/passwordmgr &&DISPLAY=:0 QTVER=5 ../../run-tests.sh 42 | 43 | 44 | cd /opt/tests/qtmozembed/auto/desktop-qt5/downloadmgr &&DISPLAY=:0 QTVER=5 ../../run-tests.sh 45 | 46 | 47 | cd /opt/tests/qtmozembed/auto/desktop-qt5/newviewrequest &&DISPLAY=:0 QTVER=5 ../../run-tests.sh 48 | 49 | 50 | cd /opt/tests/qtmozembed/auto/desktop-qt5/selection &&DISPLAY=:0 QTVER=5 ../../run-tests.sh 51 | 52 | 53 | cd /opt/tests/qtmozembed/auto/desktop-qt5/linksactivation &&DISPLAY=:0 QTVER=5 ../../run-tests.sh 54 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /tests/auto/desktop-qt5/promptbasic/tst_prompt.qml: -------------------------------------------------------------------------------- 1 | import QtTest 1.0 2 | import QtQuick 2.0 3 | import Qt5Mozilla 1.0 4 | import "../../shared/componentCreation.js" as MyScript 5 | import "../../shared/sharedTests.js" as SharedTests 6 | 7 | Item { 8 | id: appWindow 9 | width: 480 10 | height: 800 11 | 12 | property bool mozViewInitialized : false 13 | property variant promptReceived : null 14 | property variant testResult : null 15 | property variant testCaseNum : 0 16 | 17 | QmlMozContext { 18 | id: mozContext 19 | } 20 | Connections { 21 | target: mozContext.instance 22 | onOnInitialized: { 23 | // Gecko does not switch to SW mode if gl context failed to init 24 | // and qmlmoztestrunner does not build in GL mode 25 | // Let's put it here for now in SW mode always 26 | mozContext.instance.setIsAccelerated(true); 27 | mozContext.instance.addComponentManifest(mozContext.getenv("QTTESTSROOT") + "/components/TestHelpers.manifest"); 28 | } 29 | } 30 | 31 | QmlMozView { 32 | id: webViewport 33 | visible: true 34 | focus: true 35 | active: true 36 | anchors.fill: parent 37 | Connections { 38 | target: webViewport.child 39 | onViewInitialized: { 40 | webViewport.child.loadFrameScript("chrome://tests/content/testHelper.js"); 41 | appWindow.mozViewInitialized = true 42 | webViewport.child.addMessageListener("testembed:elementinnervalue"); 43 | webViewport.child.addMessageListener("embed:prompt"); 44 | } 45 | onRecvAsyncMessage: { 46 | // print("onRecvAsyncMessage:" + message + ", data:" + data) 47 | if (message == "embed:prompt") { 48 | testcaseid.compare(data.defaultValue, "Your name"); 49 | testcaseid.compare(data.text, "Please enter your name:"); 50 | var responsePrompt = null; 51 | switch(appWindow.testCaseNum) { 52 | case 0: 53 | responsePrompt="expectedPromptResult"; 54 | break; 55 | case 1: 56 | responsePrompt="unexpectedPromptResult"; 57 | break; 58 | } 59 | if (responsePrompt) { 60 | webViewport.child.sendAsyncMessage("promptresponse", { 61 | winid: data.winid, 62 | checkval: true, 63 | accepted: true, 64 | promptvalue: responsePrompt 65 | }) 66 | } 67 | appWindow.promptReceived = true; 68 | } else if (message == "testembed:elementinnervalue") { 69 | appWindow.testResult = data.value; 70 | } 71 | } 72 | } 73 | } 74 | 75 | resources: TestCase { 76 | id: testcaseid 77 | name: "mozContextPage" 78 | when: windowShown 79 | parent: appWindow 80 | 81 | function cleanup() { 82 | mozContext.dumpTS("tst_multitouch cleanup") 83 | } 84 | 85 | function test_TestPromptPage() 86 | { 87 | SharedTests.shared_TestPromptPage() 88 | } 89 | 90 | function test_TestPromptWithBadResponse() 91 | { 92 | SharedTests.shared_TestPromptWithBadResponse() 93 | } 94 | 95 | function test_TestPromptWithoutResponse() 96 | { 97 | SharedTests.shared_TestPromptWithoutResponse() 98 | } 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /src/qopenglwebpage.h: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 2 | /* This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 | 6 | #ifndef QOPENGLWEBPAGE_H 7 | #define QOPENGLWEBPAGE_H 8 | 9 | #include 10 | #include 11 | 12 | // Needed events, all of these renders to qevent.h includes. 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | #include "qmozview_defined_wrapper.h" 22 | 23 | class QMozViewPrivate; 24 | class QMozGrabResult; 25 | class QMozWindow; 26 | 27 | class QOpenGLWebPage : public QObject 28 | { 29 | Q_OBJECT 30 | Q_PROPERTY(int parentId READ parentId WRITE setParentID NOTIFY parentIdChanged FINAL) 31 | Q_PROPERTY(bool privateMode READ privateMode WRITE setPrivateMode NOTIFY privateModeChanged FINAL) 32 | Q_PROPERTY(bool completed READ completed NOTIFY completedChanged FINAL) 33 | Q_PROPERTY(bool enabled READ enabled WRITE setEnabled NOTIFY enabledChanged FINAL) 34 | Q_PROPERTY(bool active READ active WRITE setActive NOTIFY activeChanged FINAL) 35 | Q_PROPERTY(bool loaded READ loaded NOTIFY loadedChanged FINAL) 36 | Q_PROPERTY(bool throttlePainting READ throttlePainting WRITE setThrottlePainting NOTIFY throttlePaintingChanged FINAL) 37 | 38 | Q_MOZ_VIEW_PRORERTIES 39 | 40 | public: 41 | explicit QOpenGLWebPage(QObject *parent = nullptr); 42 | ~QOpenGLWebPage(); 43 | 44 | Q_MOZ_VIEW_PUBLIC_METHODS 45 | int parentId() const; 46 | 47 | bool privateMode() const; 48 | void setPrivateMode(bool privateMode); 49 | 50 | bool completed() const; 51 | 52 | bool enabled() const; 53 | void setEnabled(bool enabled); 54 | 55 | bool active() const; 56 | void setActive(bool active); 57 | 58 | bool loaded() const; 59 | 60 | QMozWindow *mozWindow() const; 61 | void setMozWindow(QMozWindow *window); 62 | 63 | bool throttlePainting() const; 64 | void setThrottlePainting(bool); 65 | 66 | void initialize(); 67 | 68 | bool event(QEvent *event); 69 | QVariant inputMethodQuery(Qt::InputMethodQuery property) const; 70 | void inputMethodEvent(QInputMethodEvent* event); 71 | void keyPressEvent(QKeyEvent*); 72 | void keyReleaseEvent(QKeyEvent*); 73 | void focusInEvent(QFocusEvent*); 74 | void focusOutEvent(QFocusEvent*); 75 | void touchEvent(QTouchEvent*); 76 | void timerEvent(QTimerEvent*); 77 | 78 | QSharedPointer grabToImage(const QSize &targetSize = QSize()); 79 | 80 | public Q_SLOTS: 81 | Q_MOZ_VIEW_PUBLIC_SLOTS 82 | void update(); 83 | void forceActiveFocus(); 84 | void setInputMethodHints(Qt::InputMethodHints hints); 85 | 86 | Q_SIGNALS: 87 | void parentIdChanged(); 88 | void privateModeChanged(); 89 | void completedChanged(); 90 | void enabledChanged(); 91 | void activeChanged(); 92 | void widthChanged(); 93 | void heightChanged(); 94 | void loadedChanged(); 95 | void throttlePaintingChanged(); 96 | void afterRendering(); 97 | 98 | Q_MOZ_VIEW_SIGNALS 99 | 100 | private Q_SLOTS: 101 | void processViewInitialization(); 102 | void updateLoaded(); 103 | void createView(); 104 | void onDrawOverlay(const QRect &rect); 105 | 106 | private: 107 | QMozViewPrivate* d; 108 | friend class QMozViewPrivate; 109 | 110 | unsigned mParentID; 111 | bool mPrivateMode; 112 | bool mActive; 113 | bool mLoaded; 114 | bool mCompleted; 115 | QList > mGrabResultList; 116 | QMutex mGrabResultListLock; 117 | bool mSizeUpdateScheduled; 118 | bool mThrottlePainting; 119 | 120 | Q_DISABLE_COPY(QOpenGLWebPage) 121 | }; 122 | 123 | QML_DECLARE_TYPE(QOpenGLWebPage) 124 | 125 | #endif // QOPENGLWEBPAGE_H 126 | -------------------------------------------------------------------------------- /src/qmozwindow_p.cpp: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 2 | /* This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 | 6 | #include "qmozwindow_p.h" 7 | 8 | #include "qmozwindow.h" 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #if defined(ENABLE_GLX) 15 | #include 16 | #endif 17 | 18 | EGLContext (EGLAPIENTRY * _eglGetCurrentContext)(void) = nullptr; 19 | EGLSurface (EGLAPIENTRY * _eglGetCurrentSurface)(EGLint readdraw) = nullptr; 20 | #if defined(ENABLE_GLX) 21 | GLXContext (*_glxGetCurrentContext)(void) = nullptr; 22 | GLXDrawable (*_glxGetCurrentDrawable)(void) = nullptr; 23 | #endif 24 | 25 | QMozWindowPrivate::QMozWindowPrivate(QMozWindow& window) 26 | : q(window) 27 | , mWindow(nullptr) 28 | , mReadyToPaint(true) 29 | { 30 | } 31 | 32 | QMozWindowPrivate::~QMozWindowPrivate() 33 | { 34 | } 35 | 36 | bool QMozWindowPrivate::RequestGLContext(void*& context, void*& surface) 37 | { 38 | q.requestGLContext(); 39 | 40 | QString platform = qApp->platformName().toLower(); 41 | 42 | if (platform == "wayland" || platform == "wayland-egl") { 43 | getEGLContext(context, surface); 44 | return true; 45 | } 46 | #if defined(ENABLE_GLX) 47 | if (platform == "xcb") { 48 | getGLXContext(context, surface); 49 | return true; 50 | } 51 | #endif 52 | 53 | qCritical() << "Unsupported QPA platform type:" << platform; 54 | return false; 55 | } 56 | 57 | void QMozWindowPrivate::getEGLContext(void*& context, void*& surface) 58 | { 59 | if (!_eglGetCurrentContext || !_eglGetCurrentSurface) { 60 | void* handle = dlopen("libEGL.so.1", RTLD_LAZY); 61 | if (!handle) 62 | return; 63 | 64 | *(void **)(&_eglGetCurrentContext) = dlsym(handle, "eglGetCurrentContext"); 65 | *(void **)(&_eglGetCurrentSurface) = dlsym(handle, "eglGetCurrentSurface"); 66 | 67 | Q_ASSERT(_eglGetCurrentContext && _eglGetCurrentSurface); 68 | 69 | dlclose(handle); 70 | } 71 | 72 | surface = _eglGetCurrentSurface(EGL_DRAW); 73 | context = _eglGetCurrentContext(); 74 | } 75 | 76 | #if defined(ENABLE_GLX) 77 | void QMozWindowPrivate::getGLXContext(void*& context, void*& surface) 78 | { 79 | if (!_glxGetCurrentContext || !_glxGetCurrentDrawable) { 80 | void* handle = dlopen("libGL.so.1", RTLD_LAZY); 81 | if (!handle) 82 | return; 83 | 84 | *(void **)(&_glxGetCurrentContext) = dlsym(handle, "glXGetCurrentContext"); 85 | *(void **)(&_glxGetCurrentDrawable) = dlsym(handle, "glXGetCurrentDrawable"); 86 | 87 | Q_ASSERT(_glxGetCurrentContext && _glxGetCurrentDrawable); 88 | 89 | dlclose(handle); 90 | } 91 | 92 | surface = reinterpret_cast(_glxGetCurrentDrawable()); 93 | context = _glxGetCurrentContext(); 94 | } 95 | #endif 96 | 97 | bool QMozWindowPrivate::setReadyToPaint(bool ready) 98 | { 99 | QMutexLocker lock(&mReadyToPaintMutex); 100 | if (mReadyToPaint != ready) { 101 | mReadyToPaint = ready; 102 | return true; 103 | } 104 | return false; 105 | } 106 | 107 | void QMozWindowPrivate::WindowInitialized() 108 | { 109 | q.initialized(); 110 | } 111 | 112 | void QMozWindowPrivate::DrawUnderlay() 113 | { 114 | q.drawUnderlay(); 115 | } 116 | 117 | void QMozWindowPrivate::DrawOverlay(const nsIntRect& aRect) 118 | { 119 | q.drawOverlay(QRect(aRect.x, aRect.y, aRect.width, aRect.height)); 120 | } 121 | 122 | void QMozWindowPrivate::CompositorCreated() 123 | { 124 | q.compositorCreated(); 125 | } 126 | 127 | void QMozWindowPrivate::CompositingFinished() 128 | { 129 | q.compositingFinished(); 130 | } 131 | 132 | bool QMozWindowPrivate::PreRender() 133 | { 134 | QMutexLocker lock(&mReadyToPaintMutex); 135 | return mReadyToPaint; 136 | } 137 | -------------------------------------------------------------------------------- /src/quickmozview.h: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 2 | /* This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 | 6 | #ifndef QuickMozView_H 7 | #define QuickMozView_H 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include "qmozview_defined_wrapper.h" 14 | 15 | class QMozViewPrivate; 16 | class QMozWindow; 17 | 18 | class QuickMozView : public QQuickItem 19 | { 20 | Q_OBJECT 21 | Q_PROPERTY(int parentId READ parentId WRITE setParentID NOTIFY parentIdChanged FINAL) 22 | Q_PROPERTY(bool privateMode READ privateMode WRITE setPrivateMode NOTIFY privateModeChanged FINAL) 23 | Q_PROPERTY(bool active READ active WRITE setActive NOTIFY activeChanged FINAL) 24 | Q_PROPERTY(bool background READ background NOTIFY backgroundChanged FINAL) 25 | Q_PROPERTY(bool loaded READ loaded NOTIFY loadedChanged FINAL) 26 | Q_PROPERTY(QObject* child READ getChild NOTIFY childChanged) 27 | 28 | Q_MOZ_VIEW_PRORERTIES 29 | 30 | public: 31 | QuickMozView(QQuickItem *parent = 0); 32 | ~QuickMozView(); 33 | 34 | Q_MOZ_VIEW_PUBLIC_METHODS 35 | void RenderToCurrentContext(); 36 | 37 | int parentId() const; 38 | bool privateMode() const; 39 | 40 | bool active() const; 41 | void setActive(bool active); 42 | void setPrivateMode(bool); 43 | 44 | bool background() const; 45 | bool loaded() const; 46 | 47 | private: 48 | QObject* getChild() { return this; } 49 | void updateGLContextInfo(); 50 | 51 | public Q_SLOTS: 52 | Q_MOZ_VIEW_PUBLIC_SLOTS 53 | 54 | Q_SIGNALS: 55 | void childChanged(); 56 | void setIsActive(bool); 57 | void dispatchItemUpdate(); 58 | void textureReady(int id, const QSize &size); 59 | void parentIdChanged(); 60 | void privateModeChanged(); 61 | void activeChanged(); 62 | void backgroundChanged(); 63 | void loadedChanged(); 64 | void updateViewSize(); 65 | 66 | Q_MOZ_VIEW_SIGNALS 67 | 68 | private Q_SLOTS: 69 | void processViewInitialization(); 70 | void SetIsActive(bool aIsActive); 71 | void updateLoaded(); 72 | void resumeRendering(); 73 | void compositingFinished(); 74 | 75 | // INTERNAL 76 | protected: 77 | void itemChange(ItemChange change, const ItemChangeData &) override; 78 | void geometryChanged(const QRectF & newGeometry, const QRectF & oldGeometry) override; 79 | QSGNode* updatePaintNode(QSGNode* node, UpdatePaintNodeData* data) override; 80 | void mouseMoveEvent(QMouseEvent* event) override; 81 | void mousePressEvent(QMouseEvent* event) override; 82 | void mouseReleaseEvent(QMouseEvent* event) override; 83 | QVariant inputMethodQuery(Qt::InputMethodQuery property) const override; 84 | void inputMethodEvent(QInputMethodEvent* event) override; 85 | void keyPressEvent(QKeyEvent*) override; 86 | void keyReleaseEvent(QKeyEvent*) override; 87 | void focusInEvent(QFocusEvent*) override; 88 | void focusOutEvent(QFocusEvent*) override; 89 | void touchEvent(QTouchEvent*) override; 90 | void timerEvent(QTimerEvent*) override; 91 | void componentComplete() override; 92 | 93 | public Q_SLOTS: 94 | void setInputMethodHints(Qt::InputMethodHints hints); 95 | void updateGLContextInfo(QOpenGLContext*); 96 | 97 | private Q_SLOTS: 98 | void createThreadRenderObject(); 99 | void clearThreadRenderObject(); 100 | void contextInitialized(); 101 | void updateEnabled(); 102 | void refreshNodeTexture(); 103 | void windowVisibleChanged(bool visible); 104 | 105 | private: 106 | void createView(); 107 | 108 | QMozViewPrivate* d; 109 | friend class QMozViewPrivate; 110 | unsigned mParentID; 111 | bool mPrivateMode; 112 | bool mUseQmlMouse; 113 | bool mActive; 114 | bool mBackground; 115 | bool mLoaded; 116 | GLuint mConsTex; 117 | QMutex mRenderMutex; 118 | }; 119 | 120 | #endif // QuickMozView_H 121 | -------------------------------------------------------------------------------- /src/qmozextmaterialnode.cpp: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 2 | /* This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 | 6 | #include "qmozextmaterialnode.h" 7 | #include 8 | #include 9 | 10 | #include 11 | 12 | #define LOCAL_GL_TEXTURE_EXTERNAL 0x8D65 13 | 14 | struct MozExternalTexture 15 | { 16 | GLuint id; 17 | }; 18 | 19 | class MozTextureShader : public QSGSimpleMaterialShader 20 | { 21 | QSG_DECLARE_SIMPLE_SHADER(MozTextureShader, MozExternalTexture) 22 | 23 | public: 24 | 25 | const char *vertexShader() const 26 | { 27 | return "attribute highp vec4 aVertex; \n" 28 | "attribute highp vec2 aTexCoord; \n" 29 | "uniform highp mat4 qt_Matrix; \n" 30 | "varying highp vec2 vTexCoord; \n" 31 | "void main() { \n" 32 | " gl_Position = qt_Matrix * aVertex; \n" 33 | " vTexCoord = aTexCoord; \n" 34 | "}"; 35 | } 36 | 37 | const char *fragmentShader() const 38 | { 39 | return "#extension GL_OES_EGL_image_external : require \n" 40 | "uniform lowp float qt_Opacity; \n" 41 | "uniform lowp samplerExternalOES texture; \n" 42 | "varying highp vec2 vTexCoord; \n" 43 | "void main() { \n" 44 | " gl_FragColor = qt_Opacity * texture2D(texture, vTexCoord); \n" 45 | "}"; 46 | } 47 | 48 | QList attributes() const override 49 | { 50 | return QList() << "aVertex" << "aTexCoord"; 51 | } 52 | 53 | void updateState(const MozExternalTexture *texture, const MozExternalTexture *) override 54 | { 55 | glBindTexture(LOCAL_GL_TEXTURE_EXTERNAL, texture->id); 56 | } 57 | 58 | void deactivate() 59 | { 60 | glBindTexture(LOCAL_GL_TEXTURE_EXTERNAL, 0); 61 | } 62 | 63 | }; 64 | 65 | void MozExtMaterialNode::update() 66 | { 67 | updateGeometry(m_size); 68 | } 69 | 70 | void MozExtMaterialNode::updateGeometry(const QSize &size) 71 | { 72 | QRectF rect(0, 0, size.width(), size.height()); 73 | QSGGeometry::updateTexturedRectGeometry(geometry(), rect, QRectF(0, 1, 1, -1)); 74 | markDirty(QSGNode::DirtyGeometry); 75 | } 76 | 77 | MozExtMaterialNode::MozExtMaterialNode() 78 | : m_id(0) 79 | { 80 | setGeometry(new QSGGeometry(QSGGeometry::defaultAttributes_TexturedPoint2D(), 4)); 81 | 82 | QSGSimpleMaterial *material = MozTextureShader::createMaterial(); 83 | material->setFlag(QSGMaterial::Blending, false); 84 | material->state()->id = 0; 85 | setMaterial(material); 86 | 87 | setFlags(OwnsMaterial | OwnsGeometry); 88 | } 89 | 90 | void 91 | MozExtMaterialNode::newTexture(int id, const QSize &size) 92 | { 93 | m_id = id; 94 | 95 | // It might happen that after orientation change when compositing is done 96 | // QuickMozView::updatePaintNode() gets called before a new texture with new 97 | // geometry has been created. In this case it's safer to reset node's 98 | // geometry again. 99 | if (m_size != size && m_size.width() > 0 && m_size.height() > 0) { 100 | updateGeometry(size); 101 | } 102 | 103 | m_size = size; 104 | } 105 | 106 | // Before the scene graph starts to render, we update to the pending texture 107 | void 108 | MozExtMaterialNode::prepareNode() 109 | { 110 | if (m_id) { 111 | MozExternalTexture *texture = static_cast *>(material())->state(); 112 | texture->id = m_id; 113 | m_id = 0; 114 | markDirty(QSGNode::DirtyMaterial); 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /src/qmozview_templated_wrapper.h: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-*/ 2 | /* vim: set ts=2 sw=2 et tw=79: */ 3 | /* This Source Code Form is subject to the terms of the Mozilla Public 4 | * License, v. 2.0. If a copy of the MPL was not distributed with this file, 5 | * You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 | 7 | #ifndef qmozview_templated_wrapper_h 8 | #define qmozview_templated_wrapper_h 9 | 10 | class QPoint; 11 | class QString; 12 | class QRect; 13 | class QMozReturnValue; 14 | class IMozQViewIface 15 | { 16 | public: 17 | virtual ~IMozQViewIface() {} 18 | // Methods 19 | virtual void setInputMethodHints(Qt::InputMethodHints hints) = 0; 20 | virtual void forceViewActiveFocus() = 0; 21 | 22 | // Signals 23 | virtual void viewInitialized() = 0; 24 | virtual void urlChanged() = 0; 25 | virtual void titleChanged() = 0; 26 | virtual void loadProgressChanged() = 0; 27 | virtual void canGoBackChanged() = 0; 28 | virtual void canGoForwardChanged() = 0; 29 | virtual void loadingChanged() = 0; 30 | virtual void viewDestroyed() = 0; 31 | virtual void windowCloseRequested() = 0; 32 | virtual void recvAsyncMessage(const QString message, const QVariant data) = 0; 33 | virtual bool recvSyncMessage(const QString message, const QVariant data, QMozReturnValue* response) = 0; 34 | virtual void loadRedirect() = 0; 35 | virtual void securityChanged(QString status, uint state) = 0; 36 | virtual void firstPaint(int offx, int offy) = 0; 37 | virtual void contentLoaded(QString docuri) = 0; 38 | virtual void contentWidthChanged() = 0; 39 | virtual void contentHeightChanged() = 0; 40 | virtual void viewAreaChanged() = 0; 41 | virtual void scrollableOffsetChanged() = 0; 42 | virtual void chromeChanged() = 0; 43 | virtual void handleLongTap(QPoint point, QMozReturnValue* retval) = 0; 44 | virtual void handleSingleTap(QPoint point, QMozReturnValue* retval) = 0; 45 | virtual void handleDoubleTap(QPoint point, QMozReturnValue* retval) = 0; 46 | virtual void imeNotification(int state, bool open, int cause, int focusChange, const QString& type) = 0; 47 | virtual void bgColorChanged() = 0; 48 | virtual void useQmlMouse(bool value) = 0; 49 | virtual void draggingChanged() = 0; 50 | virtual void movingChanged() = 0; 51 | virtual void pinchingChanged() = 0; 52 | virtual void marginsChanged() = 0; 53 | }; 54 | 55 | template 56 | class IMozQView : public IMozQViewIface 57 | { 58 | public: 59 | IMozQView(TMozQView& aView) : view(aView) {} 60 | 61 | void setInputMethodHints(Qt::InputMethodHints hints) 62 | { 63 | view.setInputMethodHints(hints); 64 | } 65 | 66 | void forceViewActiveFocus() 67 | { 68 | view.forceViewActiveFocus(); 69 | } 70 | void viewInitialized() 71 | { 72 | Q_EMIT view.viewInitialized(); 73 | } 74 | void urlChanged() 75 | { 76 | Q_EMIT view.urlChanged(); 77 | } 78 | void titleChanged() 79 | { 80 | Q_EMIT view.titleChanged(); 81 | } 82 | void loadProgressChanged() 83 | { 84 | Q_EMIT view.loadProgressChanged(); 85 | } 86 | void canGoBackChanged() 87 | { 88 | Q_EMIT view.canGoBackChanged(); 89 | } 90 | void canGoForwardChanged() 91 | { 92 | Q_EMIT view.canGoForwardChanged(); 93 | } 94 | void loadingChanged() 95 | { 96 | Q_EMIT view.loadingChanged(); 97 | } 98 | void viewDestroyed() 99 | { 100 | Q_EMIT view.viewDestroyed(); 101 | } 102 | void windowCloseRequested() 103 | { 104 | Q_EMIT view.windowCloseRequested(); 105 | } 106 | void recvAsyncMessage(const QString message, const QVariant data) 107 | { 108 | Q_EMIT view.recvAsyncMessage(message, data); 109 | } 110 | bool recvSyncMessage(const QString message, const QVariant data, QMozReturnValue* response) 111 | { 112 | return Q_EMIT view.recvSyncMessage(message, data, response); 113 | } 114 | void loadRedirect() 115 | { 116 | Q_EMIT view.loadRedirect(); 117 | } 118 | void securityChanged(QString status, uint state) 119 | { 120 | Q_EMIT view.securityChanged(status, state); 121 | } 122 | void firstPaint(int offx, int offy) 123 | { 124 | Q_EMIT view.firstPaint(offx, offy); 125 | } 126 | void contentLoaded(QString docuri) 127 | { 128 | Q_EMIT view.contentLoaded(docuri); 129 | } 130 | void viewAreaChanged() 131 | { 132 | Q_EMIT view.viewAreaChanged(); 133 | } 134 | void scrollableOffsetChanged() 135 | { 136 | Q_EMIT view.scrollableOffsetChanged(); 137 | } 138 | void chromeChanged() 139 | { 140 | Q_EMIT view.chromeChanged(); 141 | } 142 | void handleLongTap(QPoint point, QMozReturnValue* retval) 143 | { 144 | Q_EMIT view.handleLongTap(point, retval); 145 | } 146 | void handleSingleTap(QPoint point, QMozReturnValue* retval) 147 | { 148 | Q_EMIT view.handleSingleTap(point, retval); 149 | } 150 | void handleDoubleTap(QPoint point, QMozReturnValue* retval) 151 | { 152 | Q_EMIT view.handleDoubleTap(point, retval); 153 | } 154 | void imeNotification(int state, bool open, int cause, int focusChange, const QString& type) 155 | { 156 | Q_EMIT view.imeNotification(state, open, cause, focusChange, type); 157 | } 158 | void bgColorChanged() 159 | { 160 | Q_EMIT view.bgColorChanged(); 161 | } 162 | 163 | void useQmlMouse(bool value) 164 | { 165 | Q_EMIT view.useQmlMouse(value); 166 | } 167 | 168 | void draggingChanged() 169 | { 170 | Q_EMIT view.draggingChanged(); 171 | } 172 | 173 | void movingChanged() 174 | { 175 | Q_EMIT view.movingChanged(); 176 | } 177 | 178 | void pinchingChanged() 179 | { 180 | Q_EMIT view.pinchingChanged(); 181 | } 182 | 183 | void marginsChanged() 184 | { 185 | Q_EMIT view.marginsChanged(); 186 | } 187 | 188 | void contentWidthChanged() 189 | { 190 | Q_EMIT view.contentWidthChanged(); 191 | } 192 | 193 | void contentHeightChanged() 194 | { 195 | Q_EMIT view.contentHeightChanged(); 196 | } 197 | 198 | TMozQView& view; 199 | }; 200 | 201 | #endif /* qmozview_templated_wrapper_h */ 202 | -------------------------------------------------------------------------------- /src/qmozview_p.h: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-*/ 2 | /* vim: set ts=2 sw=2 et tw=79: */ 3 | /* This Source Code Form is subject to the terms of the Mozilla Public 4 | * License, v. 2.0. If a copy of the MPL was not distributed with this file, 5 | * You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 | 7 | #ifndef qmozview_p_h 8 | #define qmozview_p_h 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include "qmozwindow.h" 22 | #include "qmozscrolldecorator.h" 23 | #include "mozilla/embedlite/EmbedLiteView.h" 24 | #include "qmozview_templated_wrapper.h" 25 | #include "qmozview_defined_wrapper.h" 26 | 27 | class QTouchEvent; 28 | class QMozContext; 29 | class QMozWindow; 30 | 31 | class QMozViewPrivate : public QObject, 32 | public mozilla::embedlite::EmbedLiteViewListener 33 | { 34 | Q_OBJECT 35 | public: 36 | QMozViewPrivate(IMozQViewIface* aViewIface, QObject* publicPtr); 37 | virtual ~QMozViewPrivate(); 38 | 39 | // EmbedLiteViewListener implementation: 40 | void ViewInitialized() override; 41 | void ViewDestroyed() override; 42 | void SetBackgroundColor(uint8_t r, uint8_t g, uint8_t b, uint8_t a) override; 43 | void OnLocationChanged(const char* aLocation, bool aCanGoBack, bool aCanGoForward) override; 44 | void OnLoadProgress(int32_t aProgress, int32_t aCurTotal, int32_t aMaxTotal) override; 45 | void OnLoadStarted(const char* aLocation) override; 46 | void OnLoadFinished(void) override; 47 | void OnWindowCloseRequested() override; 48 | void RecvAsyncMessage(const char16_t* aMessage, const char16_t* aData) override; 49 | char* RecvSyncMessage(const char16_t* aMessage, const char16_t* aData) override; 50 | void OnLoadRedirect(void) override; 51 | void OnSecurityChanged(const char* aStatus, unsigned int aState) override; 52 | void OnFirstPaint(int32_t aX, int32_t aY) override; 53 | void GetIMEStatus(int32_t* aIMEEnabled, int32_t* aIMEOpen, intptr_t* aNativeIMEContext) override; 54 | void IMENotification(int aIstate, bool aOpen, int aCause, int aFocusChange, 55 | const char16_t* inputType, const char16_t* inputMode) override; 56 | void OnTitleChanged(const char16_t* aTitle) override; 57 | bool HandleLongTap(const nsIntPoint& aPoint) override; 58 | bool HandleSingleTap(const nsIntPoint& aPoint) override; 59 | bool HandleDoubleTap(const nsIntPoint& aPoint) override; 60 | bool SendAsyncScrollDOMEvent(const gfxRect& aContentRect, const gfxSize& aScrollableSize) override; 61 | 62 | void SetMargins(const QMargins& margins); 63 | QColor GetBackgroundColor() const; 64 | void SetIsFocused(bool aIsFocused); 65 | void SetThrottlePainting(bool aThrottle); 66 | void UpdateScrollArea(unsigned int aWidth, unsigned int aHeight, float aPosX, float aPosY); 67 | void TestFlickingMode(QTouchEvent *event); 68 | void HandleTouchEnd(bool& draggingChanged, bool& pinchingChanged); 69 | void ResetState(); 70 | void UpdateMoving(bool moving); 71 | void ResetPainted(); 72 | void UpdateViewSize(); 73 | void ReceiveInputEvent(const mozilla::InputData& event); 74 | 75 | void load(const QString &url); 76 | void loadFrameScript(const QString &frameScript); 77 | void addMessageListener(const QString &name); 78 | void addMessageListeners(const QStringList &messageNamesList); 79 | 80 | void startMoveMonitor(); 81 | void timerEvent(QTimerEvent *event); 82 | QVariant inputMethodQuery(Qt::InputMethodQuery property) const; 83 | void inputMethodEvent(QInputMethodEvent *event); 84 | void keyPressEvent(QKeyEvent *event); 85 | void keyReleaseEvent(QKeyEvent *event); 86 | void touchEvent(QTouchEvent* event); 87 | 88 | void sendAsyncMessage(const QString& name, const QVariant& variant); 89 | void setMozWindow(QMozWindow*); 90 | 91 | public Q_SLOTS: 92 | void onCompositorCreated(); 93 | 94 | protected: 95 | friend class QOpenGLWebPage; 96 | friend class QuickMozView; 97 | 98 | void synthTouchBegin(const QVariant& touches); 99 | void synthTouchMove(const QVariant& touches); 100 | void synthTouchEnd(const QVariant& touches); 101 | void recvMouseMove(int posX, int posY); 102 | void recvMousePress(int posX, int posY); 103 | void recvMouseRelease(int posX, int posY); 104 | 105 | IMozQViewIface* mViewIface; 106 | QPointer q; 107 | QPointer mMozWindow; 108 | QMozContext* mContext; 109 | mozilla::embedlite::EmbedLiteView* mView; 110 | bool mViewInitialized; 111 | QColor mBgColor; 112 | QMargins mMargins; 113 | mutable QMutex mBgColorMutex; 114 | QImage mTempBufferImage; 115 | QSGTexture* mTempTexture; 116 | bool mEnabled; 117 | bool mChromeGestureEnabled; 118 | qreal mChromeGestureThreshold; 119 | bool mChrome; 120 | qreal mMoveDelta; 121 | qreal mDragStartY; 122 | bool mMoving; 123 | bool mPinching; 124 | QSizeF mSize; 125 | qint64 mLastTimestamp; 126 | qint64 mLastStationaryTimestamp; 127 | QPointF mLastPos; 128 | QPointF mLastStationaryPos; 129 | QMap mActiveTouchPoints; 130 | bool mCanFlick; 131 | bool mPendingTouchEvent; 132 | QString mLocation; 133 | QString mTitle; 134 | int mProgress; 135 | bool mCanGoBack; 136 | bool mCanGoForward; 137 | bool mIsLoading; 138 | bool mLastIsGoodRotation; 139 | bool mIsPasswordField; 140 | bool mGraphicsViewAssigned; 141 | QRectF mContentRect; 142 | QSizeF mScrollableSize; 143 | QPointF mScrollableOffset; 144 | // Non visual 145 | QMozScrollDecorator mVerticalScrollDecorator; 146 | QMozScrollDecorator mHorizontalScrollDecorator; 147 | float mContentResolution; 148 | bool mIsPainted; 149 | Qt::InputMethodHints mInputMethodHints; 150 | bool mIsInputFieldFocused; 151 | bool mPreedit; 152 | bool mViewIsFocused; 153 | bool mHasContext; 154 | Qt::ScreenOrientation mOrientation; 155 | bool mOrientationDirty; 156 | bool mPressed; 157 | bool mDragging; 158 | bool mFlicking; 159 | // Moving monitoring 160 | int mMovingTimerId; 161 | qreal mOffsetX; 162 | qreal mOffsetY; 163 | bool mHasCompositor; 164 | 165 | QString mPendingUrl; 166 | QStringList mPendingMessageListeners; 167 | QStringList mPendingFrameScripts; 168 | }; 169 | 170 | qint64 current_timestamp(QTouchEvent*); 171 | 172 | #endif /* qmozview_p_h */ 173 | -------------------------------------------------------------------------------- /src/qmozgrabresult.cpp: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 2 | /* This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 | 6 | #include "qopenglwebpage.h" 7 | #include "qmozgrabresult.h" 8 | #include "qmozwindow.h" 9 | 10 | #include 11 | #include 12 | #if defined(QT_OPENGL_ES_2) 13 | #include 14 | #else 15 | #include 16 | #endif 17 | #include 18 | #include 19 | #include 20 | 21 | // Handle web page grab readiness through event loop so that connection type to the ready signal doesn't matter. 22 | const QEvent::Type Event_WebPageGrab_Completed = static_cast(QEvent::registerEventType()); 23 | 24 | QImage gl_read_framebuffer(const QRect &rect) { 25 | QSize size = rect.size(); 26 | int x = rect.x(); 27 | int y = rect.y(); 28 | 29 | while (glGetError()); 30 | 31 | QImage img(size, QImage::Format_RGB32); 32 | GLint fmt = GL_BGRA_EXT; 33 | glReadPixels(x, y, size.width(), size.height(), fmt, GL_UNSIGNED_BYTE, img.bits()); 34 | if (!glGetError()) 35 | return img.mirrored(); 36 | 37 | QImage rgbaImage(size, QImage::Format_RGBX8888); 38 | glReadPixels(x, y, size.width(), size.height(), GL_RGBA, GL_UNSIGNED_BYTE, rgbaImage.bits()); 39 | return rgbaImage.mirrored(); 40 | } 41 | 42 | class QMozGrabResultPrivate 43 | { 44 | public: 45 | QMozGrabResultPrivate(QMozGrabResult *q) 46 | : q_ptr(q) 47 | , ready(false) 48 | { 49 | } 50 | 51 | static QMozGrabResult *create(QOpenGLWebPage *webPage, const QSize &targetSize); 52 | 53 | QMozGrabResult *q_ptr; 54 | QPointer webPage; 55 | QSize textureSize; 56 | QImage image; 57 | Qt::ScreenOrientation orientation; 58 | bool ready; 59 | }; 60 | 61 | QMozGrabResult::~QMozGrabResult() 62 | { 63 | if (d_ptr) { 64 | delete d_ptr; 65 | d_ptr = 0; 66 | } 67 | } 68 | 69 | /*! 70 | * \qmlproperty variant QMozGrabResult::image 71 | * 72 | * This property holds the pixel results from a grab in the 73 | * form of a QImage. 74 | */ 75 | QImage QMozGrabResult::image() const 76 | { 77 | Q_D(const QMozGrabResult); 78 | return d->image; 79 | } 80 | 81 | bool QMozGrabResult::isReady() const 82 | { 83 | Q_D(const QMozGrabResult); 84 | return d->ready; 85 | } 86 | 87 | bool QMozGrabResult::saveToFile(const QString &fileName) 88 | { 89 | Q_D(QMozGrabResult); 90 | return d->image.save(fileName); 91 | } 92 | 93 | bool QMozGrabResult::event(QEvent *e) 94 | { 95 | Q_D(QMozGrabResult); 96 | if (e->type() == Event_WebPageGrab_Completed) { 97 | d->ready = true; 98 | Q_EMIT ready(); 99 | return true; 100 | } 101 | return QObject::event(e); 102 | } 103 | 104 | void QMozGrabResult::captureImage(const QRect &rect) 105 | { 106 | Q_D(QMozGrabResult); 107 | int w = d->textureSize.width(); 108 | int h = d->textureSize.height(); 109 | 110 | if (d->orientation == Qt::LandscapeOrientation || d->orientation == Qt::InvertedLandscapeOrientation) { 111 | qSwap(w, h); 112 | } 113 | 114 | int x = d->orientation == Qt::LandscapeOrientation ? rect.width() - w : 0; 115 | int y = (d->orientation == Qt::PortraitOrientation || d->orientation == Qt::LandscapeOrientation) ? rect.height() - h : 0; 116 | 117 | QRect targetRect(x, y, w, h); 118 | QImage image = gl_read_framebuffer(targetRect); 119 | if (d->orientation != Qt::PortraitOrientation && d->orientation != Qt::PrimaryOrientation) { 120 | QMatrix rotationMatrix; 121 | switch (d->orientation) { 122 | case Qt::LandscapeOrientation: 123 | rotationMatrix.rotate(270); 124 | break; 125 | case Qt::InvertedLandscapeOrientation: 126 | rotationMatrix.rotate(90); 127 | break; 128 | case Qt::InvertedPortraitOrientation: 129 | rotationMatrix.rotate(180); 130 | default: 131 | break; 132 | } 133 | image = image.transformed(rotationMatrix); 134 | } 135 | 136 | d->image = image; 137 | QCoreApplication::postEvent(this, new QEvent(Event_WebPageGrab_Completed)); 138 | } 139 | 140 | QMozGrabResult::QMozGrabResult(QObject *parent) 141 | : QObject(parent) 142 | , d_ptr(new QMozGrabResultPrivate(this)) 143 | { 144 | } 145 | 146 | QMozGrabResult *QMozGrabResultPrivate::create(QOpenGLWebPage *webPage, const QSize &targetSize) 147 | { 148 | Q_ASSERT(webPage); 149 | 150 | QSize size = targetSize; 151 | if (size.isEmpty()) { 152 | size = webPage->mozWindow()->size(); 153 | } 154 | 155 | if (!size.isValid()) { 156 | qWarning() << "OpenGLWebPage::grabToImage web page has invalid dimensions"; 157 | return 0; 158 | } 159 | 160 | if (!webPage->mozWindow()) { 161 | qWarning() << "OpenGLWebPage::grabToImage web page is not attached to a window"; 162 | return 0; 163 | } 164 | 165 | if (!webPage->completed()) { 166 | qWarning() << "OpenGLWebPage::grabToImage web page is not yet completed. Implies that view is not created."; 167 | return 0; 168 | } 169 | 170 | if (!webPage->active()) { 171 | qWarning() << "OpenGLWebPage::grabToImage only active web page can be grabbed"; 172 | return 0; 173 | } 174 | 175 | QMozGrabResult *result = new QMozGrabResult(); 176 | QMozGrabResultPrivate *d = result->d_func(); 177 | d->textureSize = size; 178 | d->webPage = webPage; 179 | d->orientation = webPage->mozWindow()->contentOrientation(); 180 | 181 | return result; 182 | } 183 | 184 | /*! 185 | * Grabs the web page into an in-memory image. 186 | * 187 | * The grab happens asynchronously and the signal QMozGrabResult::ready() is emitted 188 | * when the grab has been completed. 189 | * 190 | * The \a targetSize can be used to specify the size of the target image. By default, the 191 | * result will have the same size as the web page. 192 | * 193 | * \note This function copies surface from the GPU's memory into CPU's memory, which can 194 | * be quite costly operation. Smaller the \a targetSize better the performance. 195 | */ 196 | QSharedPointer QOpenGLWebPage::grabToImage(const QSize &targetSize) 197 | { 198 | QSharedPointer result(QMozGrabResultPrivate::create(this, targetSize)); 199 | if (result) { 200 | QMutexLocker lock(&mGrabResultListLock); 201 | mGrabResultList.append(result.toWeakRef()); 202 | update(); 203 | } 204 | return result; 205 | } 206 | 207 | -------------------------------------------------------------------------------- /src/qmozview_defined_wrapper.h: -------------------------------------------------------------------------------- 1 | #ifndef qmozview_defined_wrapper_h 2 | #define qmozview_defined_wrapper_h 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | class QMozScrollDecorator; 16 | 17 | class QMozReturnValue : public QObject 18 | { 19 | Q_OBJECT 20 | Q_PROPERTY(QVariant message READ getMessage WRITE setMessage FINAL) 21 | 22 | public: 23 | QMozReturnValue(QObject* parent = 0) : QObject(parent) {} 24 | QMozReturnValue(const QMozReturnValue& aMsg) : QObject(NULL) { mMessage = aMsg.mMessage; } 25 | virtual ~QMozReturnValue() {} 26 | 27 | QVariant getMessage() const { return mMessage; } 28 | void setMessage(const QVariant& msg) { mMessage = msg; } 29 | 30 | private: 31 | QVariant mMessage; 32 | }; 33 | 34 | Q_DECLARE_METATYPE(QMozReturnValue) 35 | 36 | #define Q_MOZ_RETURN_VALUE \ 37 | class QMozReturnValue : public QObject \ 38 | { \ 39 | Q_OBJECT \ 40 | Q_PROPERTY(QVariant message READ getMessage WRITE setMessage FINAL) \ 41 | public: \ 42 | QMozReturnValue(QObject* parent = 0) : QObject(parent) {} \ 43 | QMozReturnValue(const QMozReturnValue& aMsg) : QObject(NULL) { mMessage = aMsg.mMessage; } \ 44 | virtual ~QMozReturnValue() {} \ 45 | QVariant getMessage() const { return mMessage; } \ 46 | void setMessage(const QVariant& msg) { mMessage = msg; } \ 47 | private: \ 48 | QVariant mMessage; \ 49 | }; \ 50 | Q_DECLARE_METATYPE(QMozReturnValue) \ 51 | 52 | #define Q_MOZ_VIEW_PRORERTIES \ 53 | Q_PROPERTY(QUrl url READ url WRITE setUrl NOTIFY urlChanged) \ 54 | Q_PROPERTY(QString title READ title NOTIFY titleChanged) \ 55 | Q_PROPERTY(bool canGoBack READ canGoBack NOTIFY canGoBackChanged FINAL) \ 56 | Q_PROPERTY(bool canGoForward READ canGoForward NOTIFY canGoForwardChanged FINAL) \ 57 | Q_PROPERTY(int loadProgress READ loadProgress NOTIFY loadProgressChanged) \ 58 | Q_PROPERTY(bool loading READ loading NOTIFY loadingChanged FINAL) \ 59 | Q_PROPERTY(QRectF contentRect READ contentRect NOTIFY viewAreaChanged FINAL) \ 60 | Q_PROPERTY(qreal contentWidth READ contentWidth NOTIFY contentWidthChanged FINAL) \ 61 | Q_PROPERTY(qreal contentHeight READ contentHeight NOTIFY contentHeightChanged FINAL) \ 62 | Q_PROPERTY(QSizeF scrollableSize READ scrollableSize FINAL) \ 63 | Q_PROPERTY(QPointF scrollableOffset READ scrollableOffset NOTIFY scrollableOffsetChanged FINAL) \ 64 | Q_PROPERTY(float resolution READ resolution) \ 65 | Q_PROPERTY(bool painted READ isPainted NOTIFY firstPaint FINAL) \ 66 | Q_PROPERTY(QColor bgcolor READ bgcolor NOTIFY bgColorChanged FINAL) \ 67 | Q_PROPERTY(bool useQmlMouse READ getUseQmlMouse WRITE setUseQmlMouse) \ 68 | Q_PROPERTY(bool dragging READ dragging NOTIFY draggingChanged FINAL) \ 69 | Q_PROPERTY(bool moving READ moving NOTIFY movingChanged FINAL) \ 70 | Q_PROPERTY(bool pinching READ pinching NOTIFY pinchingChanged FINAL) \ 71 | Q_PROPERTY(QMozScrollDecorator* verticalScrollDecorator READ verticalScrollDecorator NOTIFY verticalScrollDecoratorChanged FINAL) \ 72 | Q_PROPERTY(QMozScrollDecorator* horizontalScrollDecorator READ horizontalScrollDecorator NOTIFY horizontalScrollDecoratorChanged FINAL) \ 73 | Q_PROPERTY(bool chrome READ chrome WRITE setChrome NOTIFY chromeChanged FINAL) \ 74 | Q_PROPERTY(bool chromeGestureEnabled READ chromeGestureEnabled WRITE setChromeGestureEnabled NOTIFY chromeGestureEnabledChanged FINAL) \ 75 | Q_PROPERTY(qreal chromeGestureThreshold READ chromeGestureThreshold WRITE setChromeGestureThreshold NOTIFY chromeGestureThresholdChanged FINAL) \ 76 | Q_PROPERTY(QMargins margins READ margins WRITE setMargins NOTIFY marginsChanged) 77 | 78 | #define Q_MOZ_VIEW_PUBLIC_METHODS \ 79 | QUrl url() const; \ 80 | void setUrl(const QUrl&); \ 81 | QString title() const; \ 82 | int loadProgress() const; \ 83 | bool canGoBack() const; \ 84 | bool canGoForward() const; \ 85 | bool loading() const; \ 86 | QRectF contentRect() const; \ 87 | qreal contentWidth() const; \ 88 | qreal contentHeight() const; \ 89 | QSizeF scrollableSize() const; \ 90 | QPointF scrollableOffset() const; \ 91 | float resolution() const; \ 92 | bool isPainted() const; \ 93 | QColor bgcolor() const; \ 94 | bool getUseQmlMouse(); \ 95 | void setUseQmlMouse(bool value); \ 96 | void forceViewActiveFocus(); \ 97 | bool dragging() const; \ 98 | bool moving() const; \ 99 | bool pinching() const; \ 100 | QMozScrollDecorator* verticalScrollDecorator() const; \ 101 | QMozScrollDecorator* horizontalScrollDecorator() const; \ 102 | bool chromeGestureEnabled() const; \ 103 | void setChromeGestureEnabled(bool value); \ 104 | bool chrome() const; \ 105 | void setChrome(bool value); \ 106 | qreal chromeGestureThreshold() const; \ 107 | void setChromeGestureThreshold(qreal value); \ 108 | QMargins margins() const; \ 109 | void setMargins(QMargins); 110 | 111 | #define Q_MOZ_VIEW_PUBLIC_SLOTS \ 112 | void loadHtml(const QString& html, const QUrl& baseUrl = QUrl()); \ 113 | void goBack(); \ 114 | void goForward(); \ 115 | void stop(); \ 116 | void reload(); \ 117 | void load(const QString&); \ 118 | void sendAsyncMessage(const QString& name, const QVariant& variant); \ 119 | void addMessageListener(const QString& name); \ 120 | void addMessageListeners(const QStringList& messageNamesList); \ 121 | void loadFrameScript(const QString& name); \ 122 | void newWindow(const QString& url = "about:blank"); \ 123 | quint32 uniqueID() const; \ 124 | void setParentID(unsigned aParentID); \ 125 | void synthTouchBegin(const QVariant& touches); \ 126 | void synthTouchMove(const QVariant& touches); \ 127 | void synthTouchEnd(const QVariant& touches); \ 128 | void suspendView(); \ 129 | void resumeView(); \ 130 | void recvMouseMove(int posX, int posY); \ 131 | void recvMousePress(int posX, int posY); \ 132 | void recvMouseRelease(int posX, int posY); \ 133 | 134 | #define Q_MOZ_VIEW_SIGNALS \ 135 | void viewInitialized(); \ 136 | void urlChanged(); \ 137 | void titleChanged(); \ 138 | void loadProgressChanged(); \ 139 | void canGoBackChanged(); \ 140 | void canGoForwardChanged(); \ 141 | void loadingChanged(); \ 142 | void viewDestroyed(); \ 143 | void windowCloseRequested(); \ 144 | void recvAsyncMessage(const QString message, const QVariant data); \ 145 | bool recvSyncMessage(const QString message, const QVariant data, QMozReturnValue* response); \ 146 | void loadRedirect(); \ 147 | void securityChanged(QString status, uint state); \ 148 | void firstPaint(int offx, int offy); \ 149 | void contentLoaded(QString docuri); \ 150 | void viewAreaChanged(); \ 151 | void scrollableOffsetChanged(); \ 152 | void handleLongTap(QPoint point, QMozReturnValue* retval); \ 153 | void handleSingleTap(QPoint point, QMozReturnValue* retval); \ 154 | void handleDoubleTap(QPoint point, QMozReturnValue* retval); \ 155 | void imeNotification(int state, bool open, int cause, int focusChange, const QString& type); \ 156 | void bgColorChanged(); \ 157 | void useQmlMouse(bool value); \ 158 | void draggingChanged(); \ 159 | void movingChanged(); \ 160 | void pinchingChanged(); \ 161 | void contentWidthChanged(); \ 162 | void contentHeightChanged(); \ 163 | void verticalScrollDecoratorChanged(); \ 164 | void horizontalScrollDecoratorChanged(); \ 165 | void chromeGestureEnabledChanged(); \ 166 | void chromeChanged(); \ 167 | void chromeGestureThresholdChanged(); \ 168 | void marginsChanged(); 169 | 170 | #endif /* qmozview_defined_wrapper_h */ 171 | -------------------------------------------------------------------------------- /src/EmbedQtKeyUtils.cpp: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- 2 | * 3 | * This Source Code Form is subject to the terms of the Mozilla Public 4 | * License, v. 2.0. If a copy of the MPL was not distributed with this 5 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 | 7 | #include 8 | 9 | #include "EmbedQtKeyUtils.h" 10 | 11 | #include "nsIDOMKeyEvent.h" 12 | #include "nsIDOMWindowUtils.h" 13 | 14 | using namespace mozilla; 15 | 16 | struct nsKeyConverter 17 | { 18 | int vkCode; // Platform independent key code 19 | int keysym; // Qt key code 20 | }; 21 | 22 | static struct nsKeyConverter nsKeycodes[] = 23 | { 24 | // { nsIDOMKeyEvent::DOM_VK_CANCEL, Qt::Key_Cancel }, 25 | { nsIDOMKeyEvent::DOM_VK_BACK_SPACE, Qt::Key_Backspace }, 26 | { nsIDOMKeyEvent::DOM_VK_TAB, Qt::Key_Tab }, 27 | { nsIDOMKeyEvent::DOM_VK_TAB, Qt::Key_Backtab }, 28 | // { nsIDOMKeyEvent::DOM_VK_CLEAR, Qt::Key_Clear }, 29 | { nsIDOMKeyEvent::DOM_VK_RETURN, Qt::Key_Return }, 30 | { nsIDOMKeyEvent::DOM_VK_RETURN, Qt::Key_Enter }, 31 | { nsIDOMKeyEvent::DOM_VK_SHIFT, Qt::Key_Shift }, 32 | { nsIDOMKeyEvent::DOM_VK_CONTROL, Qt::Key_Control }, 33 | { nsIDOMKeyEvent::DOM_VK_ALT, Qt::Key_Alt }, 34 | { nsIDOMKeyEvent::DOM_VK_PAUSE, Qt::Key_Pause }, 35 | { nsIDOMKeyEvent::DOM_VK_CAPS_LOCK, Qt::Key_CapsLock }, 36 | { nsIDOMKeyEvent::DOM_VK_ESCAPE, Qt::Key_Escape }, 37 | { nsIDOMKeyEvent::DOM_VK_SPACE, Qt::Key_Space }, 38 | { nsIDOMKeyEvent::DOM_VK_PAGE_UP, Qt::Key_PageUp }, 39 | { nsIDOMKeyEvent::DOM_VK_PAGE_DOWN, Qt::Key_PageDown }, 40 | { nsIDOMKeyEvent::DOM_VK_END, Qt::Key_End }, 41 | { nsIDOMKeyEvent::DOM_VK_HOME, Qt::Key_Home }, 42 | { nsIDOMKeyEvent::DOM_VK_LEFT, Qt::Key_Left }, 43 | { nsIDOMKeyEvent::DOM_VK_UP, Qt::Key_Up }, 44 | { nsIDOMKeyEvent::DOM_VK_RIGHT, Qt::Key_Right }, 45 | { nsIDOMKeyEvent::DOM_VK_DOWN, Qt::Key_Down }, 46 | { nsIDOMKeyEvent::DOM_VK_PRINTSCREEN, Qt::Key_Print }, 47 | { nsIDOMKeyEvent::DOM_VK_INSERT, Qt::Key_Insert }, 48 | { nsIDOMKeyEvent::DOM_VK_DELETE, Qt::Key_Delete }, 49 | { nsIDOMKeyEvent::DOM_VK_HELP, Qt::Key_Help }, 50 | 51 | { nsIDOMKeyEvent::DOM_VK_0, Qt::Key_0 }, 52 | { nsIDOMKeyEvent::DOM_VK_1, Qt::Key_1 }, 53 | { nsIDOMKeyEvent::DOM_VK_2, Qt::Key_2 }, 54 | { nsIDOMKeyEvent::DOM_VK_3, Qt::Key_3 }, 55 | { nsIDOMKeyEvent::DOM_VK_4, Qt::Key_4 }, 56 | { nsIDOMKeyEvent::DOM_VK_5, Qt::Key_5 }, 57 | { nsIDOMKeyEvent::DOM_VK_6, Qt::Key_6 }, 58 | { nsIDOMKeyEvent::DOM_VK_7, Qt::Key_7 }, 59 | { nsIDOMKeyEvent::DOM_VK_8, Qt::Key_8 }, 60 | { nsIDOMKeyEvent::DOM_VK_9, Qt::Key_9 }, 61 | 62 | { nsIDOMKeyEvent::DOM_VK_SEMICOLON, Qt::Key_Semicolon }, 63 | { nsIDOMKeyEvent::DOM_VK_EQUALS, Qt::Key_Equal }, 64 | 65 | { nsIDOMKeyEvent::DOM_VK_A, Qt::Key_A }, 66 | { nsIDOMKeyEvent::DOM_VK_B, Qt::Key_B }, 67 | { nsIDOMKeyEvent::DOM_VK_C, Qt::Key_C }, 68 | { nsIDOMKeyEvent::DOM_VK_D, Qt::Key_D }, 69 | { nsIDOMKeyEvent::DOM_VK_E, Qt::Key_E }, 70 | { nsIDOMKeyEvent::DOM_VK_F, Qt::Key_F }, 71 | { nsIDOMKeyEvent::DOM_VK_G, Qt::Key_G }, 72 | { nsIDOMKeyEvent::DOM_VK_H, Qt::Key_H }, 73 | { nsIDOMKeyEvent::DOM_VK_I, Qt::Key_I }, 74 | { nsIDOMKeyEvent::DOM_VK_J, Qt::Key_J }, 75 | { nsIDOMKeyEvent::DOM_VK_K, Qt::Key_K }, 76 | { nsIDOMKeyEvent::DOM_VK_L, Qt::Key_L }, 77 | { nsIDOMKeyEvent::DOM_VK_M, Qt::Key_M }, 78 | { nsIDOMKeyEvent::DOM_VK_N, Qt::Key_N }, 79 | { nsIDOMKeyEvent::DOM_VK_O, Qt::Key_O }, 80 | { nsIDOMKeyEvent::DOM_VK_P, Qt::Key_P }, 81 | { nsIDOMKeyEvent::DOM_VK_Q, Qt::Key_Q }, 82 | { nsIDOMKeyEvent::DOM_VK_R, Qt::Key_R }, 83 | { nsIDOMKeyEvent::DOM_VK_S, Qt::Key_S }, 84 | { nsIDOMKeyEvent::DOM_VK_T, Qt::Key_T }, 85 | { nsIDOMKeyEvent::DOM_VK_U, Qt::Key_U }, 86 | { nsIDOMKeyEvent::DOM_VK_V, Qt::Key_V }, 87 | { nsIDOMKeyEvent::DOM_VK_W, Qt::Key_W }, 88 | { nsIDOMKeyEvent::DOM_VK_X, Qt::Key_X }, 89 | { nsIDOMKeyEvent::DOM_VK_Y, Qt::Key_Y }, 90 | { nsIDOMKeyEvent::DOM_VK_Z, Qt::Key_Z }, 91 | 92 | { nsIDOMKeyEvent::DOM_VK_NUMPAD0, Qt::Key_0 }, 93 | { nsIDOMKeyEvent::DOM_VK_NUMPAD1, Qt::Key_1 }, 94 | { nsIDOMKeyEvent::DOM_VK_NUMPAD2, Qt::Key_2 }, 95 | { nsIDOMKeyEvent::DOM_VK_NUMPAD3, Qt::Key_3 }, 96 | { nsIDOMKeyEvent::DOM_VK_NUMPAD4, Qt::Key_4 }, 97 | { nsIDOMKeyEvent::DOM_VK_NUMPAD5, Qt::Key_5 }, 98 | { nsIDOMKeyEvent::DOM_VK_NUMPAD6, Qt::Key_6 }, 99 | { nsIDOMKeyEvent::DOM_VK_NUMPAD7, Qt::Key_7 }, 100 | { nsIDOMKeyEvent::DOM_VK_NUMPAD8, Qt::Key_8 }, 101 | { nsIDOMKeyEvent::DOM_VK_NUMPAD9, Qt::Key_9 }, 102 | { nsIDOMKeyEvent::DOM_VK_MULTIPLY, Qt::Key_Asterisk }, 103 | { nsIDOMKeyEvent::DOM_VK_ADD, Qt::Key_Plus }, 104 | // { nsIDOMKeyEvent::DOM_VK_SEPARATOR, Qt::Key_Separator }, 105 | { nsIDOMKeyEvent::DOM_VK_SUBTRACT, Qt::Key_Minus }, 106 | { nsIDOMKeyEvent::DOM_VK_DECIMAL, Qt::Key_Period }, 107 | { nsIDOMKeyEvent::DOM_VK_DIVIDE, Qt::Key_Slash }, 108 | { nsIDOMKeyEvent::DOM_VK_F1, Qt::Key_F1 }, 109 | { nsIDOMKeyEvent::DOM_VK_F2, Qt::Key_F2 }, 110 | { nsIDOMKeyEvent::DOM_VK_F3, Qt::Key_F3 }, 111 | { nsIDOMKeyEvent::DOM_VK_F4, Qt::Key_F4 }, 112 | { nsIDOMKeyEvent::DOM_VK_F5, Qt::Key_F5 }, 113 | { nsIDOMKeyEvent::DOM_VK_F6, Qt::Key_F6 }, 114 | { nsIDOMKeyEvent::DOM_VK_F7, Qt::Key_F7 }, 115 | { nsIDOMKeyEvent::DOM_VK_F8, Qt::Key_F8 }, 116 | { nsIDOMKeyEvent::DOM_VK_F9, Qt::Key_F9 }, 117 | { nsIDOMKeyEvent::DOM_VK_F10, Qt::Key_F10 }, 118 | { nsIDOMKeyEvent::DOM_VK_F11, Qt::Key_F11 }, 119 | { nsIDOMKeyEvent::DOM_VK_F12, Qt::Key_F12 }, 120 | { nsIDOMKeyEvent::DOM_VK_F13, Qt::Key_F13 }, 121 | { nsIDOMKeyEvent::DOM_VK_F14, Qt::Key_F14 }, 122 | { nsIDOMKeyEvent::DOM_VK_F15, Qt::Key_F15 }, 123 | { nsIDOMKeyEvent::DOM_VK_F16, Qt::Key_F16 }, 124 | { nsIDOMKeyEvent::DOM_VK_F17, Qt::Key_F17 }, 125 | { nsIDOMKeyEvent::DOM_VK_F18, Qt::Key_F18 }, 126 | { nsIDOMKeyEvent::DOM_VK_F19, Qt::Key_F19 }, 127 | { nsIDOMKeyEvent::DOM_VK_F20, Qt::Key_F20 }, 128 | { nsIDOMKeyEvent::DOM_VK_F21, Qt::Key_F21 }, 129 | { nsIDOMKeyEvent::DOM_VK_F22, Qt::Key_F22 }, 130 | { nsIDOMKeyEvent::DOM_VK_F23, Qt::Key_F23 }, 131 | { nsIDOMKeyEvent::DOM_VK_F24, Qt::Key_F24 }, 132 | 133 | { nsIDOMKeyEvent::DOM_VK_NUM_LOCK, Qt::Key_NumLock }, 134 | { nsIDOMKeyEvent::DOM_VK_SCROLL_LOCK, Qt::Key_ScrollLock }, 135 | 136 | { nsIDOMKeyEvent::DOM_VK_COMMA, Qt::Key_Comma }, 137 | { nsIDOMKeyEvent::DOM_VK_PERIOD, Qt::Key_Period }, 138 | { nsIDOMKeyEvent::DOM_VK_SLASH, Qt::Key_Slash }, 139 | { nsIDOMKeyEvent::DOM_VK_BACK_QUOTE, Qt::Key_QuoteLeft }, 140 | { nsIDOMKeyEvent::DOM_VK_OPEN_BRACKET, Qt::Key_ParenLeft }, 141 | { nsIDOMKeyEvent::DOM_VK_CLOSE_BRACKET, Qt::Key_ParenRight }, 142 | { nsIDOMKeyEvent::DOM_VK_QUOTE, Qt::Key_QuoteDbl }, 143 | 144 | { nsIDOMKeyEvent::DOM_VK_META, Qt::Key_Meta } 145 | }; 146 | 147 | int 148 | MozKey::QtKeyCodeToDOMKeyCode(int aKeysym, int aModifier) 149 | { 150 | unsigned int i; 151 | 152 | // First, try to handle alphanumeric input, not listed in nsKeycodes: 153 | // most likely, more letters will be getting typed in than things in 154 | // the key list, so we will look through these first. 155 | 156 | // since X has different key symbols for upper and lowercase letters and 157 | // mozilla does not, convert gdk's to mozilla's 158 | if (aKeysym >= Qt::Key_A && aKeysym <= Qt::Key_Z) 159 | return aKeysym - Qt::Key_A + nsIDOMKeyEvent::DOM_VK_A; 160 | 161 | // numbers 162 | if (aKeysym >= Qt::Key_0 && aKeysym <= Qt::Key_9) 163 | return aKeysym - Qt::Key_0 + nsIDOMKeyEvent::DOM_VK_0; 164 | 165 | // keypad numbers 166 | if (aKeysym >= Qt::Key_0 && aKeysym <= Qt::Key_9 && aModifier & Qt::KeypadModifier) 167 | return aKeysym - Qt::Key_0 + nsIDOMKeyEvent::DOM_VK_NUMPAD0; 168 | 169 | // misc other things 170 | for (i = 0; i < ArrayLength(nsKeycodes); i++) { 171 | if (nsKeycodes[i].keysym == aKeysym) 172 | return(nsKeycodes[i].vkCode); 173 | } 174 | 175 | // function keys 176 | if (aKeysym >= Qt::Key_F1 && aKeysym <= Qt::Key_F24) 177 | return aKeysym - Qt::Key_F1 + nsIDOMKeyEvent::DOM_VK_F1; 178 | 179 | return((int)0); 180 | } 181 | 182 | int 183 | MozKey::DOMKeyCodeToQtKeyCode(int aKeysym) 184 | { 185 | unsigned int i; 186 | 187 | // First, try to handle alphanumeric input, not listed in nsKeycodes: 188 | // most likely, more letters will be getting typed in than things in 189 | // the key list, so we will look through these first. 190 | 191 | if (aKeysym >= nsIDOMKeyEvent::DOM_VK_A && aKeysym <= nsIDOMKeyEvent::DOM_VK_Z) 192 | // gdk and DOM both use the ASCII codes for these keys. 193 | return aKeysym; 194 | 195 | // numbers 196 | if (aKeysym >= nsIDOMKeyEvent::DOM_VK_0 && aKeysym <= nsIDOMKeyEvent::DOM_VK_9) 197 | // gdk and DOM both use the ASCII codes for these keys. 198 | return aKeysym - Qt::Key_0 + nsIDOMKeyEvent::DOM_VK_0; 199 | 200 | // keypad numbers 201 | if (aKeysym >= nsIDOMKeyEvent::DOM_VK_NUMPAD0 && aKeysym <= nsIDOMKeyEvent::DOM_VK_NUMPAD9) { 202 | NS_ERROR("keypad numbers conversion not implemented"); 203 | //return aKeysym - nsIDOMKeyEvent::DOM_VK_NUMPAD0 + Qt::Key_KP_0; 204 | return 0; 205 | } 206 | 207 | // misc other things 208 | for (i = 0; i < ArrayLength(nsKeycodes); ++i) { 209 | if (nsKeycodes[i].vkCode == aKeysym) { 210 | return nsKeycodes[i].keysym; 211 | } 212 | } 213 | 214 | // function keys 215 | if (aKeysym >= nsIDOMKeyEvent::DOM_VK_F1 && aKeysym <= nsIDOMKeyEvent::DOM_VK_F9) 216 | return aKeysym - nsIDOMKeyEvent::DOM_VK_F1 + Qt::Key_F1; 217 | 218 | return 0; 219 | } 220 | 221 | uint32_t* 222 | MozKey::GetFlagWord32(uint32_t aKeyCode, uint32_t* aMask) 223 | { 224 | /* Mozilla DOM Virtual Key Code is from 0 to 224. */ 225 | // NS_ASSERTION((aKeyCode <= 0xFF), "Invalid DOM Key Code"); 226 | static uint32_t mKeyDownFlags[8]; 227 | memset(mKeyDownFlags, 0, sizeof(mKeyDownFlags)); 228 | aKeyCode &= 0xFF; 229 | 230 | /* 32 = 2^5 = 0x20 */ 231 | *aMask = uint32_t(1) << (aKeyCode & 0x1F); 232 | return &mKeyDownFlags[(aKeyCode >> 5)]; 233 | } 234 | 235 | bool 236 | MozKey::IsKeyDown(uint32_t aKeyCode) 237 | { 238 | uint32_t mask; 239 | uint32_t* flag = GetFlagWord32(aKeyCode, &mask); 240 | return ((*flag) & mask) != 0; 241 | } 242 | 243 | void 244 | MozKey::SetKeyDownFlag(uint32_t aKeyCode) 245 | { 246 | uint32_t mask; 247 | uint32_t* flag = GetFlagWord32(aKeyCode, &mask); 248 | *flag |= mask; 249 | } 250 | 251 | void 252 | MozKey::ClearKeyDownFlag(uint32_t aKeyCode) 253 | { 254 | uint32_t mask; 255 | uint32_t* flag = GetFlagWord32(aKeyCode, &mask); 256 | *flag &= ~mask; 257 | } 258 | 259 | int 260 | MozKey::QtModifierToDOMModifier(int aModifiers) 261 | { 262 | int32_t modifiers = 0; 263 | if (aModifiers & Qt::ControlModifier) { 264 | modifiers |= nsIDOMWindowUtils::MODIFIER_CONTROL; 265 | } 266 | if (aModifiers & Qt::AltModifier) { 267 | modifiers |= nsIDOMWindowUtils::MODIFIER_ALT; 268 | } 269 | if (aModifiers & Qt::ShiftModifier) { 270 | modifiers |= nsIDOMWindowUtils::MODIFIER_SHIFT; 271 | } 272 | if (aModifiers & Qt::MetaModifier) { 273 | modifiers |= nsIDOMWindowUtils::MODIFIER_META; 274 | } 275 | return modifiers; 276 | } 277 | -------------------------------------------------------------------------------- /src/qmozcontext.cpp: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-*/ 2 | /* vim: set ts=2 sw=2 et tw=79: */ 3 | /* This Source Code Form is subject to the terms of the Mozilla Public 4 | * License, v. 2.0. If a copy of the MPL was not distributed with this file, 5 | * You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 | 7 | #define LOG_COMPONENT "QMozContext" 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | #include "qmozembedlog.h" 17 | #include "qmozcontext.h" 18 | #include "geckoworker.h" 19 | #include "qmessagepump.h" 20 | #include "qmozviewcreator.h" 21 | 22 | #include "nsDebug.h" 23 | #include "mozilla/embedlite/EmbedLiteMessagePump.h" 24 | #include "mozilla/embedlite/EmbedLiteApp.h" 25 | #include "mozilla/embedlite/EmbedInitGlue.h" 26 | #include "mozilla/embedlite/EmbedLiteView.h" 27 | 28 | using namespace mozilla::embedlite; 29 | 30 | static QMozContext* protectSingleton = nullptr; 31 | 32 | class QMozContextPrivate : public EmbedLiteAppListener { 33 | public: 34 | QMozContextPrivate(QMozContext* qq) 35 | : q(qq) 36 | , mApp(NULL) 37 | , mInitialized(false) 38 | , mPixelRatio(1.0) 39 | , mThread(new QThread()) 40 | , mEmbedStarted(false) 41 | , mQtPump(NULL) 42 | , mAsyncContext(getenv("USE_ASYNC")) 43 | , mViewCreator(NULL) 44 | { 45 | LOGT("Create new Context: %p, parent:%p", (void*)this, (void*)qq); 46 | setenv("BUILD_GRE_HOME", BUILD_GRE_HOME, 1); 47 | LoadEmbedLite(); 48 | mApp = XRE_GetEmbedLite(); 49 | mApp->SetListener(this); 50 | if (mAsyncContext) { 51 | mQtPump = new MessagePumpQt(mApp); 52 | } 53 | } 54 | 55 | virtual ~QMozContextPrivate() { 56 | // deleting a running thread may result in a crash 57 | if (!mThread->isFinished()) { 58 | mThread->exit(0); 59 | mThread->wait(); 60 | } 61 | delete mThread; 62 | } 63 | 64 | virtual bool ExecuteChildThread() override { 65 | if (!getenv("GECKO_THREAD")) { 66 | LOGT("Execute in child Native thread: %p", (void*)mThread); 67 | GeckoWorker *worker = new GeckoWorker(mApp); 68 | 69 | QObject::connect(mThread, SIGNAL(started()), worker, SLOT(doWork())); 70 | QObject::connect(mThread, SIGNAL(finished()), worker, SLOT(quit())); 71 | worker->moveToThread(mThread); 72 | 73 | mThread->setObjectName("GeckoWorkerThread"); 74 | mThread->start(QThread::LowPriority); 75 | return true; 76 | } 77 | return false; 78 | } 79 | // Native thread must be stopped here 80 | virtual bool StopChildThread() override { 81 | if (mThread) { 82 | LOGT("Stop Native thread: %p", (void*)mThread); 83 | mThread->exit(0); 84 | mThread->wait(); 85 | return true; 86 | } 87 | return false; 88 | } 89 | // App Initialized and ready to API call 90 | virtual void Initialized() override { 91 | mInitialized = true; 92 | #if defined(GL_PROVIDER_EGL) || defined(GL_PROVIDER_GLX) 93 | if (mApp->GetRenderType() == EmbedLiteApp::RENDER_AUTO) { 94 | mApp->SetIsAccelerated(true); 95 | } 96 | #endif 97 | if (mPixelRatio != 1.0) { 98 | q->setPixelRatio(mPixelRatio); 99 | } 100 | 101 | setDefaultPrefs(); 102 | mApp->LoadGlobalStyleSheet("chrome://global/content/embedScrollStyles.css", true); 103 | Q_EMIT q->onInitialized(); 104 | QListIterator i(mObserversList); 105 | while (i.hasNext()) { 106 | const QString& str = i.next(); 107 | mApp->AddObserver(str.toUtf8().data()); 108 | } 109 | mObserversList.clear(); 110 | } 111 | // App Destroyed, and ready to delete and program exit 112 | virtual void Destroyed() override { 113 | LOGT(""); 114 | q->destroyed(); 115 | if (mAsyncContext) { 116 | mQtPump->deleteLater(); 117 | } 118 | } 119 | virtual void OnObserve(const char* aTopic, const char16_t* aData) override { 120 | // LOGT("aTopic: %s, data: %s", aTopic, NS_ConvertUTF16toUTF8(aData).get()); 121 | QString data((QChar*)aData); 122 | if (!data.startsWith('{') && !data.startsWith('[') && !data.startsWith('"')) { 123 | QVariant vdata = QVariant::fromValue(data); 124 | Q_EMIT q->recvObserve(aTopic, vdata); 125 | return; 126 | } 127 | bool ok = true; 128 | QJsonParseError error; 129 | QJsonDocument doc = QJsonDocument::fromJson(data.toUtf8(), &error); 130 | ok = error.error == QJsonParseError::NoError; 131 | QVariant vdata = doc.toVariant(); 132 | if (ok) { 133 | // LOGT("mesg:%s, data:%s", aTopic, data.toUtf8().data()); 134 | Q_EMIT q->recvObserve(aTopic, vdata); 135 | } else { 136 | LOGT("parse: s:'%s', err:%s, errLine:%i", data.toUtf8().data(), error.errorString().toUtf8().data(), error.offset); 137 | } 138 | } 139 | virtual void LastViewDestroyed() override { 140 | Q_EMIT q->lastViewDestroyed(); 141 | } 142 | virtual void LastWindowDestroyed() override { 143 | Q_EMIT q->lastWindowDestroyed(); 144 | } 145 | void setDefaultPrefs() 146 | { 147 | if (getenv("DS_UA")) { 148 | mApp->SetCharPref("general.useragent.override", "Mozilla/5.0 (X11; Linux x86_64; rv:20.0) Gecko/20130124 Firefox/20.0"); 149 | } else if (getenv("MT_UA")) { 150 | mApp->SetCharPref("general.useragent.override", "Mozilla/5.0 (Android; Tablet; rv:20.0) Gecko/20.0 Firefox/20.0"); 151 | } else if (getenv("MP_UA")) { 152 | mApp->SetCharPref("general.useragent.override", "Mozilla/5.0 (Android; Mobile; rv:20.0) Gecko/20.0 Firefox/20.0"); 153 | } else if (getenv("CT_UA")) { 154 | mApp->SetCharPref("general.useragent.override", "Mozilla/5.0 (Linux; Android 4.0.3; Transformer Prime TF201 Build/IML74K) AppleWebKit/535.19 (KHTML, like Gecko) Tablet Chrome/18.0.1025.166 Safari/535.19"); 155 | } else if (getenv("GB_UA")) { 156 | mApp->SetCharPref("general.useragent.override", "Mozilla/5.0 (Meego; NokiaN9) AppleWebKit/534.13 (KHTML, like Gecko) NokiaBrowser/8.5.0 Mobile Safari/534.13"); 157 | } else { 158 | const char* customUA = getenv("CUSTOM_UA"); 159 | if (customUA) { 160 | mApp->SetCharPref("general.useragent.override", customUA); 161 | } 162 | } 163 | } 164 | bool IsInitialized() { return mApp && mInitialized; } 165 | 166 | virtual uint32_t CreateNewWindowRequested(const uint32_t& chromeFlags, const char* uri, const uint32_t& contextFlags, EmbedLiteView* aParentView) override 167 | { 168 | LOGT("QtMozEmbedContext new Window requested: parent:%p", (void*)aParentView); 169 | uint32_t viewId = QMozContext::GetInstance()->createView(QString(uri), aParentView ? aParentView->GetUniqueID() : 0); 170 | return viewId; 171 | } 172 | 173 | EmbedLiteMessagePump* EmbedLoop() { return mQtPump->EmbedLoop(); } 174 | 175 | QList mObserversList; 176 | private: 177 | QMozContext* q; 178 | EmbedLiteApp* mApp; 179 | bool mInitialized; 180 | float mPixelRatio; 181 | friend class QMozContext; 182 | QThread* mThread; 183 | bool mEmbedStarted; 184 | EmbedLiteMessagePump* mEventLoopPrivate; 185 | MessagePumpQt* mQtPump; 186 | bool mAsyncContext; 187 | QMozViewCreator *mViewCreator; 188 | }; 189 | 190 | QMozContext::QMozContext(QObject* parent) 191 | : QObject(parent) 192 | , d(new QMozContextPrivate(this)) 193 | { 194 | Q_ASSERT(protectSingleton == nullptr); 195 | protectSingleton = this; 196 | } 197 | 198 | void QMozContext::setProfile(const QString profilePath) 199 | { 200 | d->mApp->SetProfilePath(!profilePath.isEmpty() ? profilePath.toUtf8().data() : NULL); 201 | } 202 | 203 | QMozContext::~QMozContext() 204 | { 205 | protectSingleton = nullptr; 206 | if (d->mApp) { 207 | d->mApp->SetListener(NULL); 208 | } 209 | delete d; 210 | } 211 | 212 | void 213 | QMozContext::sendObserve(const QString& aTopic, const QVariant& variant) 214 | { 215 | if (!d->mApp) 216 | return; 217 | 218 | QJsonDocument doc = QJsonDocument::fromVariant(variant); 219 | QByteArray array = doc.toJson(); 220 | 221 | d->mApp->SendObserve(aTopic.toUtf8().data(), (const char16_t*)QString(array).constData()); 222 | } 223 | 224 | void 225 | QMozContext::sendObserve(const QString& aTopic, const QString& string) 226 | { 227 | if (!d->mApp) 228 | return; 229 | 230 | d->mApp->SendObserve(aTopic.toUtf8().data(), (const char16_t*)string.constData()); 231 | } 232 | 233 | void 234 | QMozContext::addComponentManifest(const QString& manifestPath) 235 | { 236 | if (!d->mApp) 237 | return; 238 | d->mApp->AddManifestLocation(manifestPath.toUtf8().data()); 239 | } 240 | 241 | void 242 | QMozContext::addObserver(const QString& aTopic) 243 | { 244 | if (!d->IsInitialized()) { 245 | d->mObserversList.append(aTopic); 246 | return; 247 | } 248 | 249 | d->mApp->AddObserver(aTopic.toUtf8().data()); 250 | } 251 | 252 | void QMozContext::addObservers(const QStringList& aObserversList) 253 | { 254 | if (!d->mApp) 255 | return; 256 | 257 | nsTArray observersList; 258 | for (int i = 0; i < aObserversList.size(); i++) { 259 | observersList.AppendElement(aObserversList.at(i).toUtf8().data()); 260 | } 261 | d->mApp->AddObservers(observersList); 262 | } 263 | 264 | QMozContext* 265 | QMozContext::GetInstance() 266 | { 267 | static QMozContext* lsSingleton = nullptr; 268 | if (!lsSingleton) { 269 | lsSingleton = new QMozContext(0); 270 | NS_ASSERTION(lsSingleton, "not initialized"); 271 | } 272 | return lsSingleton; 273 | } 274 | 275 | QMozContext::TaskHandle QMozContext::PostUITask(QMozContext::TaskCallback cb, void* data, int timeout) 276 | { 277 | if (!d->mApp) 278 | return nullptr; 279 | return d->mApp->PostTask(cb, data, timeout); 280 | } 281 | 282 | QMozContext::TaskHandle QMozContext::PostCompositorTask(QMozContext::TaskCallback cb, void* data, int timeout) 283 | { 284 | if (!d->mApp) 285 | return nullptr; 286 | return d->mApp->PostCompositorTask(cb, data, timeout); 287 | } 288 | 289 | void QMozContext::CancelTask(QMozContext::TaskHandle handle) 290 | { 291 | if (!d->mApp) 292 | return; 293 | d->mApp->CancelTask(handle); 294 | } 295 | 296 | void QMozContext::runEmbedding(int aDelay) 297 | { 298 | if (!d->mEmbedStarted) { 299 | d->mEmbedStarted = true; 300 | if (d->mAsyncContext) { 301 | d->mApp->StartWithCustomPump(EmbedLiteApp::EMBED_THREAD, d->EmbedLoop()); 302 | } else { 303 | d->mApp->Start(EmbedLiteApp::EMBED_THREAD); 304 | d->mEmbedStarted = false; 305 | } 306 | } 307 | } 308 | 309 | bool 310 | QMozContext::initialized() const 311 | { 312 | return d->mInitialized; 313 | } 314 | 315 | EmbedLiteApp* 316 | QMozContext::GetApp() 317 | { 318 | return d->mApp; 319 | } 320 | 321 | void QMozContext::setPixelRatio(float ratio) 322 | { 323 | d->mPixelRatio = ratio; 324 | setPref(QString("layout.css.devPixelsPerPx"), QString("%1").arg(ratio)); 325 | } 326 | 327 | float QMozContext::pixelRatio() const 328 | { 329 | return d->mPixelRatio; 330 | } 331 | 332 | void QMozContext::stopEmbedding() 333 | { 334 | GetApp()->Stop(); 335 | } 336 | 337 | quint32 338 | QMozContext::createView(const QString& url, const quint32& parentId) 339 | { 340 | return d->mViewCreator ? d->mViewCreator->createView(url, parentId) : 0; 341 | } 342 | 343 | void 344 | QMozContext::setIsAccelerated(bool aIsAccelerated) 345 | { 346 | if (!d->mApp) 347 | return; 348 | 349 | d->mApp->SetIsAccelerated(aIsAccelerated); 350 | } 351 | 352 | bool 353 | QMozContext::isAccelerated() const 354 | { 355 | if (!d->mApp) 356 | return false; 357 | return d->mApp->IsAccelerated(); 358 | } 359 | 360 | void 361 | QMozContext::setPref(const QString& aName, const QVariant& aPref) 362 | { 363 | LOGT("name:%s, type:%i", aName.toUtf8().data(), aPref.type()); 364 | if (!d->mInitialized) { 365 | LOGT("Error: context not yet initialized"); 366 | return; 367 | } 368 | switch (aPref.type()) { 369 | case QVariant::String: 370 | d->mApp->SetCharPref(aName.toUtf8().data(), aPref.toString().toUtf8().data()); 371 | break; 372 | case QVariant::Int: 373 | case QVariant::UInt: 374 | case QVariant::LongLong: 375 | case QVariant::ULongLong: 376 | d->mApp->SetIntPref(aName.toUtf8().data(), aPref.toInt()); 377 | break; 378 | case QVariant::Bool: 379 | d->mApp->SetBoolPref(aName.toUtf8().data(), aPref.toBool()); 380 | break; 381 | case QMetaType::Float: 382 | case QMetaType::Double: 383 | if (aPref.canConvert()) { 384 | d->mApp->SetIntPref(aName.toUtf8().data(), aPref.toInt()); 385 | } else { 386 | d->mApp->SetCharPref(aName.toUtf8().data(), aPref.toString().toUtf8().data()); 387 | } 388 | break; 389 | default: 390 | LOGT("Unknown pref type: %i", aPref.type()); 391 | } 392 | } 393 | 394 | void 395 | QMozContext::notifyFirstUIInitialized() 396 | { 397 | static bool sCalledOnce = false; 398 | if (!sCalledOnce) { 399 | d->mApp->SendObserve("final-ui-startup", NULL); 400 | sCalledOnce = true; 401 | } 402 | } 403 | 404 | void QMozContext::setViewCreator(QMozViewCreator* viewCreator) 405 | { 406 | d->mViewCreator = viewCreator; 407 | } 408 | --------------------------------------------------------------------------------