diff --git a/interface/resources/qml/Root.qml b/interface/resources/qml/Root.qml index b503e2e1a6..e1431de967 100644 --- a/interface/resources/qml/Root.qml +++ b/interface/resources/qml/Root.qml @@ -6,14 +6,31 @@ import "dialogs" // This is our primary 'desktop' object to which all VR dialogs and // windows will be childed. -Item { +FocusScope { id: desktop anchors.fill: parent; // Debugging help for figuring out focus issues property var offscreenWindow; onOffscreenWindowChanged: offscreenWindow.activeFocusItemChanged.connect(onWindowFocusChanged); - function onWindowFocusChanged() { console.log("Focus item is " + offscreenWindow.activeFocusItem); } + function onWindowFocusChanged() { + console.log("Focus item is " + offscreenWindow.activeFocusItem); + var focusedItem = offscreenWindow.activeFocusItem ; + if (DebugQML && focusedItem) { + var rect = desktop.mapToItem(desktop, focusedItem.x, focusedItem.y, focusedItem.width, focusedItem.height); + focusDebugger.visible = true + focusDebugger.x = rect.x; + focusDebugger.y = rect.y; + focusDebugger.width = rect.width + focusDebugger.height = rect.height + } + } + + Rectangle { + id: focusDebugger; + z: 9999; visible: false; color: "red" + ColorAnimation on color { from: "#7fffff00"; to: "#7f0000ff"; duration: 1000; loops: 9999 } + } // Allows QML/JS to find the desktop through the parent chain property bool desktopRoot: true @@ -184,76 +201,14 @@ Item { var windows = getTopLevelWindows(predicate); fixupZOrder(windows, zBasis, targetWindow); } + } - - - //function findMenuChild(menu, childName) { - // if (!menu) { - // return null; - // } - - // if (menu.type !== 2) { - // console.warn("Tried to find child of a non-menu"); - // return null; - // } - - // var items = menu.items; - // var count = items.length; - // for (var i = 0; i < count; ++i) { - // var child = items[i]; - // var name; - // switch (child.type) { - // case 2: - // name = child.title; - // break; - // case 1: - // name = child.text; - // break; - // default: - // break; - // } - - // if (name && name === childName) { - // return child; - // } - // } - //} - - //function findMenu(rootMenu, path) { - // if ('string' === typeof(path)) { - // path = [ path ] - // } - - // var currentMenu = rootMenu; - // for (var i = 0; currentMenu && i < path.length; ++i) { - // currentMenu = findMenuChild(currentMenu, path[i]); - // } - - // return currentMenu; - //} - - //function findInRootMenu(item, path) { - // return findMenu(findRootMenu(item), path); - //} - - //function menuItemsToListModel(parent, items) { - // var newListModel = Qt.createQmlObject('import QtQuick 2.5; ListModel {}', parent); - // for (var i = 0; i < items.length; ++i) { - // var item = items[i]; - // switch (item.type) { - // case 2: - // newListModel.append({"type":item.type, "name": item.title, "item": item}) - // break; - // case 1: - // newListModel.append({"type":item.type, "name": item.text, "item": item}) - // break; - // case 0: - // newListModel.append({"type":item.type, "name": "-----", "item": item}) - // break; - // } - // } - // return newListModel; - //} + function unfocusWindows() { + var windows = d.getTopLevelWindows(); + for (var i = 0; i < windows.length; ++i) { + windows[i].focus = false; + } + desktop.focus = true; } } diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index cc175e3fae..55619ec87a 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2191,6 +2191,11 @@ void Application::mousePressEvent(QMouseEvent* event, unsigned int deviceID) { _altPressed = false; auto offscreenUi = DependencyManager::get(); + // If we get a mouse press event it means it wasn't consumed by the offscreen UI, + // hence, we should defocus all of the offscreen UI windows, in order to allow + // keyboard shortcuts not to be swallowed by them. In particular, WebEngineViews + // will consume all keyboard events. + offscreenUi->unfocusWindows(); QPointF transformedPos = offscreenUi->mapToVirtualScreen(event->localPos(), _glWidget); QMouseEvent mappedEvent(event->type(), transformedPos, diff --git a/libraries/ui/src/OffscreenUi.cpp b/libraries/ui/src/OffscreenUi.cpp index 36905797d6..e215fcc067 100644 --- a/libraries/ui/src/OffscreenUi.cpp +++ b/libraries/ui/src/OffscreenUi.cpp @@ -279,5 +279,10 @@ QVariant OffscreenUi::returnFromUiThread(std::function function) { return function(); } +void OffscreenUi::unfocusWindows() { + bool invokeResult = QMetaObject::invokeMethod(_desktop, "unfocusWindows"); + Q_ASSERT(invokeResult); +} + #include "OffscreenUi.moc" diff --git a/libraries/ui/src/OffscreenUi.h b/libraries/ui/src/OffscreenUi.h index b42fe50a92..fa4d7aaeaf 100644 --- a/libraries/ui/src/OffscreenUi.h +++ b/libraries/ui/src/OffscreenUi.h @@ -33,7 +33,7 @@ public: bool shouldSwallowShortcut(QEvent* event); bool navigationFocused(); void setNavigationFocused(bool focused); - + void unfocusWindows(); QQuickItem* getDesktop(); QQuickItem* getToolWindow(); diff --git a/tests/ui/qml/main.qml b/tests/ui/qml/main.qml index c1f1831275..0acb88c36d 100644 --- a/tests/ui/qml/main.qml +++ b/tests/ui/qml/main.qml @@ -39,8 +39,8 @@ ApplicationWindow { Root { id: desktop anchors.fill: parent - StubMenu { id: stubMenu } + Component.onCompleted: offscreenWindow = appWindow Row { id: testButtons