diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index a57b157e64..31e69315b4 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -142,6 +142,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : QApplication(argc, argv), _window(new MainWindow(desktop())), _glWidget(new GLCanvas()), + _toolWindow(NULL), _nodeThread(new QThread(this)), _datagramProcessor(), _undoStack(), diff --git a/interface/src/Application.h b/interface/src/Application.h index 96858a6c73..f82b14b47e 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -323,6 +323,7 @@ public: bool isHMDMode() const; QRect getDesirableApplicationGeometry(); + RunningScriptsWidget* getRunningScriptsWidget() { return _runningScriptsWidget; } signals: diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index ae12b5ff26..5e35f08e95 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -1303,6 +1303,10 @@ void Menu::bandwidthDetails() { connect(_bandwidthDialog, SIGNAL(closed()), SLOT(bandwidthDetailsClosed())); _bandwidthDialog->show(); + + if (_hmdToolsDialog) { + _hmdToolsDialog->watchWindow(_bandwidthDialog->windowHandle()); + } } _bandwidthDialog->raise(); } @@ -1384,6 +1388,9 @@ void Menu::toggleConsole() { void Menu::toggleToolWindow() { QMainWindow* toolWindow = Application::getInstance()->getToolWindow(); toolWindow->setVisible(!toolWindow->isVisible()); + if (_hmdToolsDialog) { + _hmdToolsDialog->watchWindow(toolWindow->windowHandle()); + } } void Menu::audioMuteToggled() { @@ -1406,6 +1413,9 @@ void Menu::octreeStatsDetails() { Application::getInstance()->getOcteeSceneStats()); connect(_octreeStatsDialog, SIGNAL(closed()), SLOT(octreeStatsDetailsClosed())); _octreeStatsDialog->show(); + if (_hmdToolsDialog) { + _hmdToolsDialog->watchWindow(_octreeStatsDialog->windowHandle()); + } } _octreeStatsDialog->raise(); } @@ -1586,6 +1596,9 @@ void Menu::lodTools() { _lodToolsDialog = new LodToolsDialog(Application::getInstance()->getGLWidget()); connect(_lodToolsDialog, SIGNAL(closed()), SLOT(lodToolsClosed())); _lodToolsDialog->show(); + if (_hmdToolsDialog) { + _hmdToolsDialog->watchWindow(_lodToolsDialog->windowHandle()); + } } _lodToolsDialog->raise(); } diff --git a/interface/src/ui/HMDToolsDialog.cpp b/interface/src/ui/HMDToolsDialog.cpp index 580490f83b..ab84980d80 100644 --- a/interface/src/ui/HMDToolsDialog.cpp +++ b/interface/src/ui/HMDToolsDialog.cpp @@ -67,12 +67,22 @@ HMDToolsDialog::HMDToolsDialog(QWidget* parent) : // watch for our dialog window moving screens. If it does we want to enforce our rules about // what screens we're allowed on - QWindow* dialogWindow = windowHandle(); - connect(dialogWindow, &QWindow::screenChanged, this, &HMDToolsDialog::dialogWindowScreenChanged); - connect(dialogWindow, &QWindow::xChanged, this, &HMDToolsDialog::dialogWindowGeometryChanged); - connect(dialogWindow, &QWindow::yChanged, this, &HMDToolsDialog::dialogWindowGeometryChanged); - connect(dialogWindow, &QWindow::widthChanged, this, &HMDToolsDialog::dialogWindowGeometryChanged); - connect(dialogWindow, &QWindow::heightChanged, this, &HMDToolsDialog::dialogWindowGeometryChanged); + watchWindow(windowHandle()); + if (Application::getInstance()->getRunningScriptsWidget()) { + watchWindow(Application::getInstance()->getRunningScriptsWidget()->windowHandle()); + } + if (Application::getInstance()->getToolWindow()) { + watchWindow(Application::getInstance()->getToolWindow()->windowHandle()); + } + if (Menu::getInstance()->getBandwidthDialog()) { + watchWindow(Menu::getInstance()->getBandwidthDialog()->windowHandle()); + } + if (Menu::getInstance()->getOctreeStatsDialog()) { + watchWindow(Menu::getInstance()->getOctreeStatsDialog()->windowHandle()); + } + if (Menu::getInstance()->getLodToolsDialog()) { + watchWindow(Menu::getInstance()->getLodToolsDialog()->windowHandle()); + } // when the application is about to quit, leave HDM mode connect(Application::getInstance(), SIGNAL(aboutToQuit()), this, SLOT(aboutToQuit())); @@ -82,67 +92,16 @@ HMDToolsDialog::HMDToolsDialog(QWidget* parent) : } HMDToolsDialog::~HMDToolsDialog() { + foreach(HMDWindowWatcher* watcher, _windowWatchers) { + delete watcher; + } + _windowWatchers.clear(); } void HMDToolsDialog::applicationWindowScreenChanged(QScreen* screen) { _debugDetails->setText(getDebugDetails()); } -void HMDToolsDialog::dialogWindowGeometryChanged(int arg) { - QWindow* dialogWindow = windowHandle(); - _previousDialogRect = rect(); - _previousDialogRect = QRect(dialogWindow->mapToGlobal(_previousDialogRect.topLeft()), - dialogWindow->mapToGlobal(_previousDialogRect.bottomRight())); - _previousDialogScreen = dialogWindow->screen(); -} - -void HMDToolsDialog::dialogWindowScreenChanged(QScreen* screen) { - _debugDetails->setText(getDebugDetails()); - - // if we have more than one screen, and a known hmdScreen then try to - // keep our dialog off of the hmdScreen - if (QApplication::desktop()->screenCount() > 1) { - - // we want to use a local variable here because we are not necesarily in HMD mode - int hmdScreenNumber = OculusManager::getHMDScreen(); - if (_hmdScreenNumber >= 0) { - QScreen* hmdScreen = QGuiApplication::screens()[hmdScreenNumber]; - if (screen == hmdScreen) { - qDebug() << "HMD Tools: Whoa! What are you doing? You don't want to move me to the HMD Screen!"; - QWindow* dialogWindow = windowHandle(); - - // try to pick a better screen - QScreen* betterScreen = NULL; - - QWindow* appWindow = Application::getInstance()->getWindow()->windowHandle(); - QScreen* appScreen = appWindow->screen(); - - if (_previousDialogScreen && _previousDialogScreen != hmdScreen) { - // first, if the previous dialog screen is not the HMD screen, then move it there. - betterScreen = appScreen; - } else if (appScreen != hmdScreen) { - // second, if the application screen is not the HMD screen, then move it there. - betterScreen = appScreen; - } else if (_previousScreen && _previousScreen != hmdScreen) { - // third, if the application screen is the HMD screen, we want to move it to - // the previous screen - betterScreen = _previousScreen; - } else { - // last, if we can't use the previous screen the use the primary desktop screen - int desktopPrimaryScreenNumber = QApplication::desktop()->primaryScreen(); - QScreen* desktopPrimaryScreen = QGuiApplication::screens()[desktopPrimaryScreenNumber]; - betterScreen = desktopPrimaryScreen; - } - - if (betterScreen) { - dialogWindow->setScreen(betterScreen); - dialogWindow->setGeometry(_previousDialogRect); - } - } - } - } -} - QString HMDToolsDialog::getDebugDetails() const { QString results; @@ -304,5 +263,79 @@ void HMDToolsDialog::screenCountChanged(int newCount) { _debugDetails->setText(getDebugDetails()); } +void HMDToolsDialog::watchWindow(QWindow* window) { + qDebug() << "HMDToolsDialog::watchWindow() window:" << window; + if (window && !_windowWatchers.contains(window)) { + HMDWindowWatcher* watcher = new HMDWindowWatcher(window, this); + _windowWatchers[window] = watcher; + } +} + + +HMDWindowWatcher::HMDWindowWatcher(QWindow* window, HMDToolsDialog* hmdTools) : + _window(window), + _hmdTools(hmdTools), + _previousScreen(NULL) +{ + connect(window, &QWindow::screenChanged, this, &HMDWindowWatcher::windowScreenChanged); + connect(window, &QWindow::xChanged, this, &HMDWindowWatcher::windowGeometryChanged); + connect(window, &QWindow::yChanged, this, &HMDWindowWatcher::windowGeometryChanged); + connect(window, &QWindow::widthChanged, this, &HMDWindowWatcher::windowGeometryChanged); + connect(window, &QWindow::heightChanged, this, &HMDWindowWatcher::windowGeometryChanged); +} + +HMDWindowWatcher::~HMDWindowWatcher() { +} + + +void HMDWindowWatcher::windowGeometryChanged(int arg) { + _previousRect = _window->geometry(); + _previousScreen = _window->screen(); +} + +void HMDWindowWatcher::windowScreenChanged(QScreen* screen) { + // if we have more than one screen, and a known hmdScreen then try to + // keep our dialog off of the hmdScreen + if (QApplication::desktop()->screenCount() > 1) { + + // we want to use a local variable here because we are not necesarily in HMD mode + int hmdScreenNumber = OculusManager::getHMDScreen(); + if (hmdScreenNumber >= 0) { + QScreen* hmdScreen = QGuiApplication::screens()[hmdScreenNumber]; + if (screen == hmdScreen) { + qDebug() << "HMD Tools: Whoa! What are you doing? You don't want to move me to the HMD Screen!"; + + // try to pick a better screen + QScreen* betterScreen = NULL; + + QScreen* lastApplicationScreen = _hmdTools->getLastApplicationScreen(); + QWindow* appWindow = Application::getInstance()->getWindow()->windowHandle(); + QScreen* appScreen = appWindow->screen(); + + if (_previousScreen && _previousScreen != hmdScreen) { + // first, if the previous dialog screen is not the HMD screen, then move it there. + betterScreen = _previousScreen; + } else if (appScreen != hmdScreen) { + // second, if the application screen is not the HMD screen, then move it there. + betterScreen = appScreen; + } else if (lastApplicationScreen && lastApplicationScreen != hmdScreen) { + // third, if the application screen is the HMD screen, we want to move it to + // the previous screen + betterScreen = lastApplicationScreen; + } else { + // last, if we can't use the previous screen the use the primary desktop screen + int desktopPrimaryScreenNumber = QApplication::desktop()->primaryScreen(); + QScreen* desktopPrimaryScreen = QGuiApplication::screens()[desktopPrimaryScreenNumber]; + betterScreen = desktopPrimaryScreen; + } + + if (betterScreen) { + _window->setScreen(betterScreen); + _window->setGeometry(_previousRect); + } + } + } + } +} diff --git a/interface/src/ui/HMDToolsDialog.h b/interface/src/ui/HMDToolsDialog.h index d539b58d04..10dc1c5c80 100644 --- a/interface/src/ui/HMDToolsDialog.h +++ b/interface/src/ui/HMDToolsDialog.h @@ -14,6 +14,8 @@ #include <QDialog> +class HMDWindowWatcher; + class HMDToolsDialog : public QDialog { Q_OBJECT public: @@ -23,7 +25,9 @@ public: QString getDebugDetails() const; QScreen* getHMDScreen() const { return _hmdScreen; } + QScreen* getLastApplicationScreen() const { return _previousScreen; } bool hasHMDScreen() const { return _hmdScreenNumber >= -1; } + void watchWindow(QWindow* window); signals: void closed(); @@ -34,8 +38,6 @@ public slots: void activateWindowAfterEnterMode(); void moveWindowAfterLeaveMode(); void applicationWindowScreenChanged(QScreen* screen); - void dialogWindowScreenChanged(QScreen* screen); - void dialogWindowGeometryChanged(int arg); void aboutToQuit(); void screenCountChanged(int newCount); @@ -60,6 +62,27 @@ private: QRect _previousDialogRect; QScreen* _previousDialogScreen; bool _inHDMMode; + + QHash<QWindow*, HMDWindowWatcher*> _windowWatchers; +}; + + +class HMDWindowWatcher : public QObject { + Q_OBJECT +public: + // Sets up the UI + HMDWindowWatcher(QWindow* window, HMDToolsDialog* hmdTools); + ~HMDWindowWatcher(); + +public slots: + void windowScreenChanged(QScreen* screen); + void windowGeometryChanged(int arg); + +private: + QWindow* _window; + HMDToolsDialog* _hmdTools; + QRect _previousRect; + QScreen* _previousScreen; }; #endif // hifi_HMDToolsDialog_h