Raise and lower keyboard for HTML fields in Browser window

This commit is contained in:
David Rowe 2016-09-28 16:40:38 +13:00
parent ec00129988
commit 875566d956
3 changed files with 60 additions and 20 deletions

View file

@ -1,5 +1,6 @@
import QtQuick 2.5 import QtQuick 2.5
import QtQuick.Controls 1.2 import QtQuick.Controls 1.2
import QtWebChannel 1.0
import QtWebEngine 1.2 import QtWebEngine 1.2
import "controls-uit" import "controls-uit"
@ -19,6 +20,9 @@ ScrollingWindow {
property variant permissionsBar: {'securityOrigin':'none','feature':'none'} property variant permissionsBar: {'securityOrigin':'none','feature':'none'}
property alias url: webview.url property alias url: webview.url
property alias webView: webview property alias webView: webview
property alias eventBridge: eventBridgeWrapper.eventBridge
x: 100 x: 100
y: 100 y: 100
@ -197,32 +201,60 @@ ScrollingWindow {
} }
} }
WebEngineView { WebView {
id: webview id: webview
url: "https://highfidelity.com" url: "https://highfidelity.com"
property alias eventBridgeWrapper: eventBridgeWrapper
QtObject {
id: eventBridgeWrapper
WebChannel.id: "eventBridgeWrapper"
property var eventBridge;
}
webChannel.registeredObjects: [eventBridgeWrapper]
// Create a global EventBridge object for raiseAndLowerKeyboard.
WebEngineScript {
id: createGlobalEventBridge
sourceCode: eventBridgeJavaScriptToInject
injectionPoint: WebEngineScript.DocumentCreation
worldId: WebEngineScript.MainWorld
}
// Detect when may want to raise and lower keyboard.
WebEngineScript {
id: raiseAndLowerKeyboard
injectionPoint: WebEngineScript.Deferred
sourceUrl: resourceDirectoryUrl + "/html/raiseAndLowerKeyboard.js"
worldId: WebEngineScript.MainWorld
}
userScripts: [ createGlobalEventBridge, raiseAndLowerKeyboard ]
anchors.top: buttons.bottom anchors.top: buttons.bottom
anchors.topMargin: 8 anchors.topMargin: 8
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
onFeaturePermissionRequested: { onFeaturePermissionRequested: {
permissionsBar.securityOrigin = securityOrigin; permissionsBar.securityOrigin = securityOrigin;
permissionsBar.feature = feature; permissionsBar.feature = feature;
root.showPermissionsBar(); root.showPermissionsBar();
} }
onLoadingChanged: { onLoadingChanged: {
if (loadRequest.status === WebEngineView.LoadSucceededStatus) { if (loadRequest.status === WebEngineView.LoadSucceededStatus) {
addressBar.text = loadRequest.url addressBar.text = loadRequest.url
} }
} }
onIconChanged: { onIconChanged: {
console.log("New icon: " + icon) console.log("New icon: " + icon)
} }
onNewViewRequested: {
var component = Qt.createComponent("Browser.qml");
var newWindow = component.createObject(desktop);
request.openIn(newWindow.webView)
}
onWindowCloseRequested: { onWindowCloseRequested: {
root.destroy(); root.destroy();
} }
@ -230,8 +262,6 @@ ScrollingWindow {
Component.onCompleted: { Component.onCompleted: {
desktop.initWebviewProfileHandlers(webview.profile) desktop.initWebviewProfileHandlers(webview.profile)
} }
profile: desktop.browserProfile
} }
} // item } // item

View file

@ -9,7 +9,7 @@
// //
import QtQuick 2.5 import QtQuick 2.5
import QtWebEngine 1.1 import QtWebEngine 1.2
WebEngineView { WebEngineView {
id: root id: root

View file

@ -565,6 +565,19 @@ QObject* OffscreenQmlSurface::finishQmlLoad(std::function<void(QQmlContext*, QOb
return nullptr; return nullptr;
} }
// FIXME: Refactor with similar code in RenderableWebEntityItem
QString javaScriptToInject;
QFile webChannelFile(":qtwebchannel/qwebchannel.js");
QFile createGlobalEventBridgeFile(PathUtils::resourcesPath() + "/html/createGlobalEventBridge.js");
if (webChannelFile.open(QFile::ReadOnly | QFile::Text) &&
createGlobalEventBridgeFile.open(QFile::ReadOnly | QFile::Text)) {
QString webChannelStr = QTextStream(&webChannelFile).readAll();
QString createGlobalEventBridgeStr = QTextStream(&createGlobalEventBridgeFile).readAll();
javaScriptToInject = webChannelStr + createGlobalEventBridgeStr;
} else {
qWarning() << "Unable to find qwebchannel.js or createGlobalEventBridge.js";
}
QQmlContext* newContext = new QQmlContext(_qmlEngine, qApp); QQmlContext* newContext = new QQmlContext(_qmlEngine, qApp);
QObject* newObject = _qmlComponent->beginCreate(newContext); QObject* newObject = _qmlComponent->beginCreate(newContext);
if (_qmlComponent->isError()) { if (_qmlComponent->isError()) {
@ -577,6 +590,9 @@ QObject* OffscreenQmlSurface::finishQmlLoad(std::function<void(QQmlContext*, QOb
return nullptr; return nullptr;
} }
newObject->setProperty("eventBridge", QVariant::fromValue(this));
newContext->setContextProperty("eventBridgeJavaScriptToInject", QVariant(javaScriptToInject));
f(newContext, newObject); f(newContext, newObject);
_qmlComponent->completeCreate(); _qmlComponent->completeCreate();
@ -835,6 +851,9 @@ void OffscreenQmlSurface::onFocusObjectChanged(QObject* object) {
disconnect(_currentFocusItem, &QObject::destroyed, this, 0); disconnect(_currentFocusItem, &QObject::destroyed, this, 0);
setKeyboardRaised(_currentFocusItem, false); setKeyboardRaised(_currentFocusItem, false);
} }
// Handle QML text fields' focus and unfocus - testing READ_ONLY_PROPERTY prevents action for HTML files.
// HTML text fields are handled via emitWebEvent().
const char* READ_ONLY_PROPERTY = "readOnly"; const char* READ_ONLY_PROPERTY = "readOnly";
setKeyboardRaised(item, item->hasActiveFocus() && item->property(READ_ONLY_PROPERTY) == false); setKeyboardRaised(item, item->hasActiveFocus() && item->property(READ_ONLY_PROPERTY) == false);
_currentFocusItem = item; _currentFocusItem = item;
@ -897,12 +916,6 @@ void OffscreenQmlSurface::synthesizeKeyPress(QString key) {
} }
void OffscreenQmlSurface::setKeyboardRaised(QObject* object, bool raised) { void OffscreenQmlSurface::setKeyboardRaised(QObject* object, bool raised) {
// raise the keyboard only while in HMD mode and it's being requested.
// XXX
// bool value = AbstractViewStateInterface::instance()->isHMDMode() && raised;
// getRootItem()->setProperty("keyboardRaised", QVariant(value));
if (!object) { if (!object) {
return; return;
} }
@ -931,16 +944,13 @@ void OffscreenQmlSurface::emitWebEvent(const QVariant& message) {
} else { } else {
// special case to handle raising and lowering the virtual keyboard // special case to handle raising and lowering the virtual keyboard
if (message.type() == QVariant::String && message.toString() == "_RAISE_KEYBOARD") { if (message.type() == QVariant::String && message.toString() == "_RAISE_KEYBOARD") {
setKeyboardRaised(getRootItem(), true); setKeyboardRaised(_currentFocusItem, true);
} else if (message.type() == QVariant::String && message.toString() == "_LOWER_KEYBOARD") { } else if (message.type() == QVariant::String && message.toString() == "_LOWER_KEYBOARD") {
setKeyboardRaised(getRootItem(), false); setKeyboardRaised(_currentFocusItem, false);
} else { } else {
emit webEventReceived(message); emit webEventReceived(message);
} }
} }
} }
#include "OffscreenQmlSurface.moc" #include "OffscreenQmlSurface.moc"