From 8dc066fc00332ac2e8352768f624bd6226a811b0 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Tue, 26 Jan 2016 16:48:25 -0800 Subject: [PATCH 1/8] Fix the recursive launching of load script from URL --- interface/resources/qml/desktop/Desktop.qml | 2 +- .../resources/qml/dialogs/RunningScripts.qml | 21 ++++++++++++++++++- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/interface/resources/qml/desktop/Desktop.qml b/interface/resources/qml/desktop/Desktop.qml index 96c84b49c0..f246f79be9 100644 --- a/interface/resources/qml/desktop/Desktop.qml +++ b/interface/resources/qml/desktop/Desktop.qml @@ -167,7 +167,7 @@ FocusScope { } if (setFocus) { - focus = true; + targetWindow.focus = true; } reposition(targetWindow); diff --git a/interface/resources/qml/dialogs/RunningScripts.qml b/interface/resources/qml/dialogs/RunningScripts.qml index 059c765f0e..eb56b59b66 100644 --- a/interface/resources/qml/dialogs/RunningScripts.qml +++ b/interface/resources/qml/dialogs/RunningScripts.qml @@ -184,9 +184,28 @@ Window { anchors.bottom: filterEdit.top anchors.bottomMargin: 8 anchors.right: parent.right + + // For some reason trigginer an API that enters + // an internal event loop directly from the button clicked + // trigger below causes the appliction to behave oddly. + // Most likely because the button onClicked handling is never + // completed until the function returns. + // FIXME find a better way of handling the input dialogs that + // doesn't trigger this. + Timer { + id: asyncAction + interval: 50 + repeat: false + running: false + onTriggered: ApplicationInterface.loadScriptURLDialog(); + } + Button { text: "from URL"; - onClicked: ApplicationInterface.loadScriptURLDialog(); + onClicked: { + focus = false; + asyncAction.running = true; + } } Button { text: "from Disk" From cea57a111bc6a5923f5250de164286fd2de96489 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Tue, 26 Jan 2016 16:56:33 -0800 Subject: [PATCH 2/8] Desktop cleanup --- interface/resources/qml/desktop/Desktop.qml | 72 ++++++++++----------- libraries/gl/src/gl/OffscreenQmlSurface.cpp | 1 + 2 files changed, 36 insertions(+), 37 deletions(-) diff --git a/interface/resources/qml/desktop/Desktop.qml b/interface/resources/qml/desktop/Desktop.qml index f246f79be9..14687f387e 100644 --- a/interface/resources/qml/desktop/Desktop.qml +++ b/interface/resources/qml/desktop/Desktop.qml @@ -13,6 +13,9 @@ FocusScope { anchors.fill: parent; objectName: "desktop" + onHeightChanged: d.repositionAll(); + onWidthChanged: d.repositionAll(); + // Allows QML/JS to find the desktop through the parent chain property bool desktopRoot: true @@ -50,10 +53,6 @@ FocusScope { return item; } - function isDesktop(item) { - return item.desktopRoot; - } - function isTopLevelWindow(item) { return item.topLevelWindow; } @@ -147,6 +146,31 @@ FocusScope { var windows = getTopLevelWindows(predicate); fixupZOrder(windows, zBasis, targetWindow); } + + Component.onCompleted: { + offscreenWindow.activeFocusItemChanged.connect(onWindowFocusChanged); + focusHack.start(); + } + + function onWindowFocusChanged() { + console.log("Focus item is " + offscreenWindow.activeFocusItem); +// var focusedItem = offscreenWindow.activeFocusItem ; +// if (DebugQML && focusedItem) { +// var rect = desktop.mapFromItem(focusedItem, 0, 0, focusedItem.width, focusedItem.height); +// focusDebugger.x = rect.x; +// focusDebugger.y = rect.y; +// focusDebugger.width = rect.width +// focusDebugger.height = rect.height +// } + } + + + function repositionAll() { + var windows = d.getTopLevelWindows(); + for (var i = 0; i < windows.length; ++i) { + reposition(windows[i]); + } + } } function raise(item) { @@ -190,24 +214,16 @@ FocusScope { var newPosition; if (targetWindow.x === -1 && targetWindow.y === -1) { // Set initial window position - newPosition = Utils.randomPosition(minPosition, maxPosition); - } else { - newPosition = Utils.clampVector(Qt.vector2d(targetWindow.x, targetWindow.y), minPosition, maxPosition); + // newPosition = Utils.randomPosition(minPosition, maxPosition); + newPosition = Qt.vector2d(desktop.width / 2 - windowRect.width / 2, + desktop.height / 2 - windowRect.height / 2); } + + newPosition = Utils.clampVector(Qt.vector2d(targetWindow.x, targetWindow.y), minPosition, maxPosition); targetWindow.x = newPosition.x; targetWindow.y = newPosition.y; } - function repositionAll() { - var windows = d.getTopLevelWindows(); - for (var i = 0; i < windows.length; ++i) { - reposition(windows[i]); - } - } - - onHeightChanged: repositionAll(); - onWidthChanged: repositionAll(); - Component { id: messageDialogBuilder; MessageDialog { } } function messageBox(properties) { return messageDialogBuilder.createObject(desktop, properties); @@ -252,39 +268,21 @@ FocusScope { desktop.focus = true; } - // Debugging help for figuring out focus issues - property var offscreenWindow; - onOffscreenWindowChanged: { - offscreenWindow.activeFocusItemChanged.connect(onWindowFocusChanged); - focusHack.start(); - } - FocusHack { id: focusHack; } - function onWindowFocusChanged() { - console.log("Focus item is " + offscreenWindow.activeFocusItem); - var focusedItem = offscreenWindow.activeFocusItem ; - if (DebugQML && focusedItem) { - var rect = desktop.mapFromItem(focusedItem, 0, 0, focusedItem.width, focusedItem.height); - 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 } } - + Action { text: "Toggle Focus Debugger" shortcut: "Ctrl+Shift+F" enabled: DebugQML onTriggered: focusDebugger.visible = !focusDebugger.visible } + } diff --git a/libraries/gl/src/gl/OffscreenQmlSurface.cpp b/libraries/gl/src/gl/OffscreenQmlSurface.cpp index 813386132c..3a72d98402 100644 --- a/libraries/gl/src/gl/OffscreenQmlSurface.cpp +++ b/libraries/gl/src/gl/OffscreenQmlSurface.cpp @@ -338,6 +338,7 @@ void OffscreenQmlSurface::create(QOpenGLContext* shareContext) { _updateTimer.start(); _qmlComponent = new QQmlComponent(_qmlEngine); + _qmlEngine->rootContext()->setContextProperty("offscreenWindow", QVariant::fromValue(getWindow())); } void OffscreenQmlSurface::resize(const QSize& newSize_) { From 5f38c5265c5dfb226b270884bc936fc9b8309ecc Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Tue, 26 Jan 2016 16:58:32 -0800 Subject: [PATCH 3/8] Fixing potential crash in dialog popups --- libraries/ui/src/OffscreenUi.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/libraries/ui/src/OffscreenUi.cpp b/libraries/ui/src/OffscreenUi.cpp index 8790c07f62..d7d28bef84 100644 --- a/libraries/ui/src/OffscreenUi.cpp +++ b/libraries/ui/src/OffscreenUi.cpp @@ -150,7 +150,9 @@ protected: } ~ModalDialogListener() { - disconnect(_dialog); + if (_dialog) { + disconnect(_dialog); + } } virtual QVariant waitForResult() { @@ -164,10 +166,11 @@ protected slots: void onDestroyed() { _finished = true; disconnect(_dialog); + _dialog = nullptr; } protected: - QQuickItem* const _dialog; + QQuickItem* _dialog; bool _finished { false }; QVariant _result; }; @@ -372,6 +375,7 @@ void OffscreenUi::createDesktop(const QUrl& url) { qDebug() << "Desktop already created"; return; } + #ifdef DEBUG getRootContext()->setContextProperty("DebugQML", QVariant(true)); #else @@ -382,9 +386,6 @@ void OffscreenUi::createDesktop(const QUrl& url) { Q_ASSERT(_desktop); getRootContext()->setContextProperty("desktop", _desktop); - // Enable focus debugging - _desktop->setProperty("offscreenWindow", QVariant::fromValue(getWindow())); - _toolWindow = _desktop->findChild("ToolWindow"); new VrMenu(this); From 940b0950139ecfe8cb34d0aa0c0fc57e86d582e7 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Tue, 26 Jan 2016 16:59:37 -0800 Subject: [PATCH 4/8] Removing menu logspam --- libraries/ui/src/VrMenu.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/libraries/ui/src/VrMenu.cpp b/libraries/ui/src/VrMenu.cpp index 103eb7660e..2006b22860 100644 --- a/libraries/ui/src/VrMenu.cpp +++ b/libraries/ui/src/VrMenu.cpp @@ -142,7 +142,6 @@ void VrMenu::addAction(QMenu* menu, QAction* action) { Q_ASSERT(menuQml); QQuickMenuItem* returnedValue { nullptr }; - qDebug() << menuQml; bool invokeResult = QMetaObject::invokeMethod(menuQml, "addItem", Qt::DirectConnection, Q_RETURN_ARG(QQuickMenuItem*, returnedValue), Q_ARG(QString, action->text())); From fee920723a04e675e91dca4a098f56b78f41da93 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Tue, 26 Jan 2016 17:25:20 -0800 Subject: [PATCH 5/8] Cleaning up test project --- tests/ui/qml/UI.js | 45 --------------- tests/ui/qmlscratch.pro | 122 +++++++--------------------------------- 2 files changed, 19 insertions(+), 148 deletions(-) delete mode 100644 tests/ui/qml/UI.js diff --git a/tests/ui/qml/UI.js b/tests/ui/qml/UI.js deleted file mode 100644 index 0286ac56a6..0000000000 --- a/tests/ui/qml/UI.js +++ /dev/null @@ -1,45 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the Qt Quick Controls module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names -** of its contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -.pragma library - -var margin = 2 -var tabPosition = Qt.TopEdge -var label = "" diff --git a/tests/ui/qmlscratch.pro b/tests/ui/qmlscratch.pro index b3c8be0f22..7a1b5ab652 100644 --- a/tests/ui/qmlscratch.pro +++ b/tests/ui/qmlscratch.pro @@ -7,108 +7,24 @@ CONFIG += c++11 SOURCES += src/main.cpp \ ../../libraries/ui/src/FileDialogHelper.cpp -# Additional import path used to resolve QML modules in Qt Creator's code model -QML_IMPORT_PATH = - -DISTFILES += \ - qml/UI.js \ - qml/main.qml \ - qml/Palettes.qml \ - qml/StubMenu.qml \ - qml/Stubs.qml \ - qml/TestControllers.qml \ - qml/TestDialog.qml \ - qml/TestMenu.qml \ - qml/TestRoot.qml \ - qml/controlDemo/ButtonPage.qml \ - qml/controlDemo/InputPage.qml \ - qml/controlDemo/main.qml \ - qml/controlDemo/ProgressPage.qml \ - ../../interface/resources/qml/controller/hydra/HydraButtons.qml \ - ../../interface/resources/qml/controller/hydra/HydraStick.qml \ - ../../interface/resources/qml/controller/xbox/DPad.qml \ - ../../interface/resources/qml/controller/xbox/LeftAnalogStick.qml \ - ../../interface/resources/qml/controller/xbox/RightAnalogStick.qml \ - ../../interface/resources/qml/controller/xbox/XboxButtons.qml \ - ../../interface/resources/qml/controller/AnalogButton.qml \ - ../../interface/resources/qml/controller/AnalogStick.qml \ - ../../interface/resources/qml/controller/Hydra.qml \ - ../../interface/resources/qml/controller/Standard.qml \ - ../../interface/resources/qml/controller/ToggleButton.qml \ - ../../interface/resources/qml/controller/Xbox.qml \ - ../../interface/resources/qml/controls/Button.qml \ - ../../interface/resources/qml/controls/ButtonAwesome.qml \ - ../../interface/resources/qml/controls/CheckBox.qml \ - ../../interface/resources/qml/controls/FontAwesome.qml \ - ../../interface/resources/qml/controls/Player.qml \ - ../../interface/resources/qml/controls/Slider.qml \ - ../../interface/resources/qml/controls/Spacer.qml \ - ../../interface/resources/qml/controls/SpinBox.qml \ - ../../interface/resources/qml/controls/Text.qml \ - ../../interface/resources/qml/controls/TextAndSlider.qml \ - ../../interface/resources/qml/controls/TextAndSpinBox.qml \ - ../../interface/resources/qml/controls/TextArea.qml \ - ../../interface/resources/qml/controls/TextEdit.qml \ - ../../interface/resources/qml/controls/TextHeader.qml \ - ../../interface/resources/qml/controls/TextInput.qml \ - ../../interface/resources/qml/controls/TextInputAndButton.qml \ - ../../interface/resources/qml/controls/WebView.qml \ - ../../interface/resources/qml/dialogs/FileDialog.qml \ - ../../interface/resources/qml/dialogs/MessageDialog.qml \ - ../../interface/resources/qml/dialogs/RunningScripts.qml \ - ../../interface/resources/qml/hifi/MenuOption.qml \ - ../../interface/resources/qml/styles/Border.qml \ - ../../interface/resources/qml/styles/HifiConstants.qml \ - ../../interface/resources/qml/windows/DefaultFrame.qml \ - ../../interface/resources/qml/windows/Fadable.qml \ - ../../interface/resources/qml/windows/Frame.qml \ - ../../interface/resources/qml/windows/ModalFrame.qml \ - ../../interface/resources/qml/windows/Window.qml \ - ../../interface/resources/qml/AddressBarDialog.qml \ - ../../interface/resources/qml/AvatarInputs.qml \ - ../../interface/resources/qml/Browser.qml \ - ../../interface/resources/qml/InfoView.qml \ - ../../interface/resources/qml/LoginDialog.qml \ - ../../interface/resources/qml/QmlWebWindow.qml \ - ../../interface/resources/qml/QmlWindow.qml \ - ../../interface/resources/qml/Root.qml \ - ../../interface/resources/qml/ScrollingGraph.qml \ - ../../interface/resources/qml/Stats.qml \ - ../../interface/resources/qml/TextOverlayElement.qml \ - ../../interface/resources/qml/Tooltip.qml \ - ../../interface/resources/qml/ToolWindow.qml \ - ../../interface/resources/qml/UpdateDialog.qml \ - ../../interface/resources/qml/VrMenu.qml \ - ../../interface/resources/qml/VrMenuItem.qml \ - ../../interface/resources/qml/VrMenuView.qml \ - ../../interface/resources/qml/WebEntity.qml \ - ../../interface/resources/qml/desktop/Desktop.qml \ - ../../interface/resources/qml/hifi/Desktop.qml \ - ../../interface/resources/qml/menus/MenuMouseHandler.qml \ - ../../interface/resources/qml/menus/VrMenuItem.qml \ - ../../interface/resources/qml/menus/VrMenuView.qml \ - ../../interface/resources/qml/windows/ModalWindow.qml \ - ../../interface/resources/qml/desktop/FocusHack.qml \ - ../../interface/resources/qml/hifi/dialogs/PreferencesDialog.qml \ - ../../interface/resources/qml/hifi/dialogs/Section.qml \ - ../../interface/resources/qml/hifi/dialogs/preferences/Browsable.qml \ - ../../interface/resources/qml/hifi/dialogs/preferences/Section.qml \ - ../../interface/resources/qml/hifi/dialogs/preferences/Editable.qml \ - ../../interface/resources/qml/hifi/dialogs/preferences/Slider.qml \ - ../../interface/resources/qml/hifi/dialogs/preferences/Preference.qml \ - ../../interface/resources/qml/hifi/dialogs/preferences/CheckBox.qml \ - ../../interface/resources/qml/dialogs/fileDialog/FileTableView.qml \ - ../../interface/resources/qml/hifi/dialogs/preferences/Avatar.qml \ - ../../interface/resources/qml/hifi/dialogs/preferences/AvatarBrowser.qml \ - ../../interface/resources/qml/dialogs/QueryDialog.qml \ - ../../interface/resources/qml/hifi/dialogs/preferences/Button.qml \ - ../../interface/resources/qml/hifi/dialogs/preferences/AvatarPreference.qml \ - ../../interface/resources/qml/hifi/dialogs/preferences/BrowsablePreference.qml \ - ../../interface/resources/qml/hifi/dialogs/preferences/ButtonPreference.qml \ - ../../interface/resources/qml/hifi/dialogs/preferences/CheckBoxPreference.qml \ - ../../interface/resources/qml/hifi/dialogs/preferences/EditablePreference.qml \ - ../../interface/resources/qml/hifi/dialogs/preferences/SliderPreference.qml \ - ../../interface/resources/qml/hifi/dialogs/preferences/SpinBoxPreference.qml - HEADERS += \ ../../libraries/ui/src/FileDialogHelper.h + +# Additional import path used to resolve QML modules in Qt Creator's code model +QML_IMPORT_PATH = ../../interface/resources/qml + + +DISTFILES += \ + qml/*.qml \ + ../../interface/resources/qml/*.qml \ + ../../interface/resources/qml/controls/*.qml \ + ../../interface/resources/qml/dialogs/*.qml \ + ../../interface/resources/qml/dialogs/fileDialog/*.qml \ + ../../interface/resources/qml/desktop/*.qml \ + ../../interface/resources/qml/menus/*.qml \ + ../../interface/resources/qml/styles/*.qml \ + ../../interface/resources/qml/windows/*.qml \ + ../../interface/resources/qml/hifi/*.qml \ + ../../interface/resources/qml/hifi/dialogs/*.qml \ + ../../interface/resources/qml/hifi/dialogs/preferences/*.qml + From 9a8d56da77ea79a232f16017cfa75d4301c03068 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Tue, 26 Jan 2016 17:25:36 -0800 Subject: [PATCH 6/8] Center new windows without a defined position --- interface/resources/qml/desktop/Desktop.qml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/interface/resources/qml/desktop/Desktop.qml b/interface/resources/qml/desktop/Desktop.qml index 14687f387e..e87862aa56 100644 --- a/interface/resources/qml/desktop/Desktop.qml +++ b/interface/resources/qml/desktop/Desktop.qml @@ -211,15 +211,16 @@ FocusScope { var windowRect = targetWindow.framedRect(); var minPosition = Qt.vector2d(-windowRect.x, -windowRect.y); var maxPosition = Qt.vector2d(desktop.width - windowRect.width, desktop.height - windowRect.height); - var newPosition; - if (targetWindow.x === -1 && targetWindow.y === -1) { + var newPosition = Qt.vector2d(targetWindow.x, targetWindow.y); + if (newPosition.x === -1 && newPosition.y === -1) { // Set initial window position // newPosition = Utils.randomPosition(minPosition, maxPosition); + console.log("Target has no defined position, putting in center of the screen") newPosition = Qt.vector2d(desktop.width / 2 - windowRect.width / 2, desktop.height / 2 - windowRect.height / 2); } - newPosition = Utils.clampVector(Qt.vector2d(targetWindow.x, targetWindow.y), minPosition, maxPosition); + newPosition = Utils.clampVector(newPosition, minPosition, maxPosition); targetWindow.x = newPosition.x; targetWindow.y = newPosition.y; } From fbee221966a7dd2dc7f21dd558cc161a33d8ad59 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Tue, 26 Jan 2016 18:15:41 -0800 Subject: [PATCH 7/8] Fix tool window breaking when visible while edit.js reloads --- interface/resources/qml/ToolWindow.qml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/interface/resources/qml/ToolWindow.qml b/interface/resources/qml/ToolWindow.qml index 8e42f67ebc..9aad639ff3 100644 --- a/interface/resources/qml/ToolWindow.qml +++ b/interface/resources/qml/ToolWindow.qml @@ -103,6 +103,8 @@ Windows.Window { if (index < 0) { return; } + var tab = tabView.getTab(index); + tab.enabledChanged.disconnect(updateVisiblity); tabView.removeTab(index); console.log("Updating visibility based on child tab removed"); updateVisiblity(); @@ -137,10 +139,7 @@ Windows.Window { } console.log("Updating visibility based on child tab added"); - newTab.enabledChanged.connect(function() { - console.log("Updating visibility based on child tab enabled change"); - updateVisiblity(); - }) + newTab.enabledChanged.connect(updateVisiblity) updateVisiblity(); return newTab } From 0a6be80578a1abd00ec23eac423443baab2061e1 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Tue, 26 Jan 2016 18:50:55 -0800 Subject: [PATCH 8/8] Added some disabled modal focus protection code --- interface/resources/qml/desktop/Desktop.qml | 22 +++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/interface/resources/qml/desktop/Desktop.qml b/interface/resources/qml/desktop/Desktop.qml index e87862aa56..8c4f73c200 100644 --- a/interface/resources/qml/desktop/Desktop.qml +++ b/interface/resources/qml/desktop/Desktop.qml @@ -154,6 +154,28 @@ FocusScope { function onWindowFocusChanged() { console.log("Focus item is " + offscreenWindow.activeFocusItem); + + // FIXME this needs more testing before it can go into production + // and I already cant produce any way to have a modal dialog lose focus + // to a non-modal one. + /* + var focusedWindow = getDesktopWindow(offscreenWindow.activeFocusItem); + + if (isModalWindow(focusedWindow)) { + return; + } + + // new focused window is not modal... check if there are any modal windows + var windows = getTopLevelWindows(isModalWindow); + if (0 === windows.length) { + return; + } + + // There are modal windows present, force focus back to the top-most modal window + windows.sort(function(a, b){ return a.z - b.z; }); + windows[windows.length - 1].focus = true; + */ + // var focusedItem = offscreenWindow.activeFocusItem ; // if (DebugQML && focusedItem) { // var rect = desktop.mapFromItem(focusedItem, 0, 0, focusedItem.width, focusedItem.height);