Additional work on splash screen
Showing the changes to interface/src/Application.cpp (1 of 10 files). Show all
Unified · Split
| @@ -144,6 +144,7 @@ · 143 unmodified lines | ||
| 144 | 144 | #include <trackers/EyeTracker.h> |
| 145 | 145 | #include <avatars-renderer/ScriptAvatar.h> |
| 146 | 146 | #include <RenderableEntityItem.h> |
| 147 | +#include <procedural/ProceduralSkybox.h> | |
| 147 | 148 | |
| 148 | 149 | #include "AudioClient.h" |
| 149 | 150 | #include "audio/AudioScope.h" |
| @@ -375,7 +376,7 @@ Setting::Handle<int> maxOctreePacketsPerSecond("maxOctreePPS", DEFAULT_MAX_OCTRE · 225 unmodified lines | ||
| 375 | 376 | static const QString MARKETPLACE_CDN_HOSTNAME = "mpassets.highfidelity.com"; |
| 376 | 377 | static const int INTERVAL_TO_CHECK_HMD_WORN_STATUS = 500; // milliseconds |
| 377 | 378 | static const QString DESKTOP_DISPLAY_PLUGIN_NAME = "Desktop"; |
| 378 | − | |
| 379 | +static const QString ACTIVE_DISPLAY_PLUGIN_SETTING_NAME = "activeDisplayPlugin"; | |
| 379 | 380 | static const QString SYSTEM_TABLET = "com.highfidelity.interface.tablet.system"; |
| 380 | 381 | |
| 381 | 382 | const std::vector<std::pair<QString, Application::AcceptURLMethod>> Application::_acceptedExtensions { |
| @@ -1349,10 +1350,14 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo · 967 unmodified lines | ||
| 1349 | 1350 | QCoreApplication::processEvents(); |
| 1350 | 1351 | _glWidget->createContext(); |
| 1351 | 1352 | |
| 1352 | − // Create the main thread context, the GPU backend, and the display plugins | |
| 1353 | + // Create the main thread context, the GPU backend | |
| 1353 | 1354 | initializeGL(); |
| 1354 | − DependencyManager::get<TextureCache>()->setGPUContext(_gpuContext); | |
| 1355 | − qCDebug(interfaceapp, "Initialized Display."); | |
| 1355 | + qCDebug(interfaceapp, "Initialized GL"); | |
| 1356 | + | |
| 1357 | + // Initialize the display plugin architecture | |
| 1358 | + initializeDisplayPlugins(); | |
| 1359 | + qCDebug(interfaceapp, "Initialized Display"); | |
| 1360 | + | |
| 1356 | 1361 | // Create the rendering engine. This can be slow on some machines due to lots of |
| 1357 | 1362 | // GPU pipeline creation. |
| 1358 | 1363 | initializeRenderEngine(); |
| @@ -2372,6 +2377,10 @@ void Application::onAboutToQuit() { · 1013 unmodified lines | ||
| 2372 | 2377 | } |
| 2373 | 2378 | } |
| 2374 | 2379 | |
| 2380 | + // The active display plugin needs to be loaded before the menu system is active, | |
| 2381 | + // so its persisted explicitly here | |
| 2382 | + Setting::Handle<QString>{ ACTIVE_DISPLAY_PLUGIN_SETTING_NAME }.set(getActiveDisplayPlugin()->getName()); | |
| 2383 | + | |
| 2375 | 2384 | getActiveDisplayPlugin()->deactivate(); |
| 2376 | 2385 | if (_autoSwitchDisplayModeSupportedHMDPlugin |
| 2377 | 2386 | && _autoSwitchDisplayModeSupportedHMDPlugin->isSessionActive()) { |
| @@ -2611,10 +2620,84 @@ void Application::initializeGL() { · 233 unmodified lines | ||
| 2611 | 2620 | _glWidget->makeCurrent(); |
| 2612 | 2621 | _gpuContext = std::make_shared<gpu::Context>(); |
| 2613 | 2622 | |
| 2623 | + DependencyManager::get<TextureCache>()->setGPUContext(_gpuContext); | |
| 2624 | + | |
| 2614 | 2625 | // Restore the default main thread context |
| 2615 | 2626 | _offscreenContext->makeCurrent(); |
| 2627 | +} | |
| 2628 | + | |
| 2629 | +static const QString SPLASH_SKYBOX{ "{\"ProceduralEntity\":{ \"version\":2, \"shaderUrl\":\"qrc:///shaders/splashSkybox.frag\" } }" }; | |
| 2630 | + | |
| 2631 | +void Application::initializeDisplayPlugins() { | |
| 2632 | + auto displayPlugins = PluginManager::getInstance()->getDisplayPlugins(); | |
| 2633 | + Setting::Handle<QString> activeDisplayPluginSetting{ ACTIVE_DISPLAY_PLUGIN_SETTING_NAME, displayPlugins.at(0)->getName() }; | |
| 2634 | + auto lastActiveDisplayPluginName = activeDisplayPluginSetting.get(); | |
| 2635 | + | |
| 2636 | + auto defaultDisplayPlugin = displayPlugins.at(0); | |
| 2637 | + // Once time initialization code | |
| 2638 | + DisplayPluginPointer targetDisplayPlugin; | |
| 2639 | + foreach(auto displayPlugin, displayPlugins) { | |
| 2640 | + displayPlugin->setContext(_gpuContext); | |
| 2641 | + if (displayPlugin->getName() == lastActiveDisplayPluginName) { | |
| 2642 | + targetDisplayPlugin = displayPlugin; | |
| 2643 | + } | |
| 2644 | + QObject::connect(displayPlugin.get(), &DisplayPlugin::recommendedFramebufferSizeChanged, | |
| 2645 | + [this](const QSize& size) { resizeGL(); }); | |
| 2646 | + QObject::connect(displayPlugin.get(), &DisplayPlugin::resetSensorsRequested, this, &Application::requestReset); | |
| 2647 | + } | |
| 2648 | + | |
| 2649 | + // The default display plugin needs to be activated first, otherwise the display plugin thread | |
| 2650 | + // may be launched by an external plugin, which is bad | |
| 2651 | + setDisplayPlugin(defaultDisplayPlugin); | |
| 2652 | + | |
| 2653 | + // Now set the desired plugin if it's not the same as the default plugin | |
| 2654 | + if (targetDisplayPlugin != defaultDisplayPlugin) { | |
| 2655 | + setDisplayPlugin(targetDisplayPlugin); | |
| 2656 | + } | |
| 2657 | + | |
| 2658 | + // Submit a default frame to render until the engine starts up | |
| 2659 | + updateRenderArgs(0.0f); | |
| 2660 | + | |
| 2661 | + _offscreenContext->makeCurrent(); | |
| 2616 | 2662 | |
| 2617 | − updateDisplayMode(); | |
| 2663 | +#define ENABLE_SPLASH_FRAME 0 | |
| 2664 | +#if ENABLE_SPLASH_FRAME | |
| 2665 | + { | |
| 2666 | + QMutexLocker viewLocker(&_renderArgsMutex); | |
| 2667 | + | |
| 2668 | + if (_appRenderArgs._isStereo) { | |
| 2669 | + _gpuContext->enableStereo(true); | |
| 2670 | + _gpuContext->setStereoProjections(_appRenderArgs._eyeProjections); | |
| 2671 | + _gpuContext->setStereoViews(_appRenderArgs._eyeOffsets); | |
| 2672 | + } | |
| 2673 | + | |
| 2674 | + // Frame resources | |
| 2675 | + auto framebufferCache = DependencyManager::get<FramebufferCache>(); | |
| 2676 | + gpu::FramebufferPointer finalFramebuffer = framebufferCache->getFramebuffer(); | |
| 2677 | + std::shared_ptr<ProceduralSkybox> procedural = std::make_shared<ProceduralSkybox>(); | |
| 2678 | + procedural->parse(SPLASH_SKYBOX); | |
| 2679 | + | |
| 2680 | + _gpuContext->beginFrame(_appRenderArgs._view, _appRenderArgs._headPose); | |
| 2681 | + gpu::doInBatch("splashFrame", _gpuContext, [&](gpu::Batch& batch) { | |
| 2682 | + batch.resetStages(); | |
| 2683 | + batch.enableStereo(false); | |
| 2684 | + batch.setFramebuffer(finalFramebuffer); | |
| 2685 | + batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR0, { 0, 0, 0, 1 }); | |
| 2686 | + batch.enableSkybox(true); | |
| 2687 | + batch.enableStereo(_appRenderArgs._isStereo); | |
| 2688 | + batch.setViewportTransform({ 0, 0, finalFramebuffer->getSize() }); | |
| 2689 | + procedural->render(batch, _appRenderArgs._renderArgs.getViewFrustum()); | |
| 2690 | + }); | |
| 2691 | + auto frame = _gpuContext->endFrame(); | |
| 2692 | + frame->frameIndex = 0; | |
| 2693 | + frame->framebuffer = finalFramebuffer; | |
| 2694 | + frame->pose = _appRenderArgs._headPose; | |
| 2695 | + frame->framebufferRecycler = [framebufferCache, procedural](const gpu::FramebufferPointer& framebuffer) { | |
| 2696 | + framebufferCache->releaseFramebuffer(framebuffer); | |
| 2697 | + }; | |
| 2698 | + _displayPlugin->submitFrame(frame); | |
| 2699 | + } | |
| 2700 | +#endif | |
| 2618 | 2701 | } |
| 2619 | 2702 | |
| 2620 | 2703 | void Application::initializeRenderEngine() { |
| @@ -2638,6 +2721,7 @@ void Application::initializeRenderEngine() { · 17 unmodified lines | ||
| 2638 | 2721 | } |
| 2639 | 2722 | |
| 2640 | 2723 | extern void setupPreferences(); |
| 2724 | +static void addDisplayPluginToMenu(const DisplayPluginPointer& displayPlugin, bool active); | |
| 2641 | 2725 | |
| 2642 | 2726 | void Application::initializeUi() { |
| 2643 | 2727 | // Build a shared canvas / context for the Chromium processes |
| @@ -2779,10 +2863,25 @@ void Application::initializeUi() { · 135 unmodified lines | ||
| 2779 | 2863 | offscreenSurfaceCache->reserve(TabletScriptingInterface::QML, 1); |
| 2780 | 2864 | offscreenSurfaceCache->reserve(Web3DOverlay::QML, 2); |
| 2781 | 2865 | |
| 2782 | − // Now that the menu is instantiated, ensure the display plugin menu is properly updated | |
| 2783 | − updateDisplayMode(); | |
| 2784 | 2866 | flushMenuUpdates(); |
| 2785 | 2867 | |
| 2868 | + // Now that the menu is instantiated, ensure the display plugin menu is properly updated | |
| 2869 | + { | |
| 2870 | + auto displayPlugins = PluginManager::getInstance()->getDisplayPlugins(); | |
| 2871 | + // first sort the plugins into groupings: standard, advanced, developer | |
| 2872 | + std::stable_sort(displayPlugins.begin(), displayPlugins.end(), | |
| 2873 | + [](const DisplayPluginPointer& a, const DisplayPluginPointer& b)->bool { return a->getGrouping() < b->getGrouping(); }); | |
| 2874 | + | |
| 2875 | + // concatenate the groupings into a single list in the order: standard, advanced, developer | |
| 2876 | + for(const auto& displayPlugin : displayPlugins) { | |
| 2877 | + addDisplayPluginToMenu(displayPlugin, _displayPlugin == displayPlugin); | |
| 2878 | + } | |
| 2879 | + | |
| 2880 | + // after all plugins have been added to the menu, add a separator to the menu | |
| 2881 | + auto parent = getPrimaryMenu()->getMenu(MenuOption::OutputMenu); | |
| 2882 | + parent->addSeparator(); | |
| 2883 | + } | |
| 2884 | + | |
| 2786 | 2885 | // The display plugins are created before the menu now, so we need to do this here to hide the menu bar |
| 2787 | 2886 | // now that it exists |
| 2788 | 2887 | if (_window && _window->isFullScreen()) { |
| @@ -2933,7 +3032,7 @@ void Application::updateCamera(RenderArgs& renderArgs, float deltaTime) { · 144 unmodified lines | ||
| 2933 | 3032 | _thirdPersonHMDCameraBoomValid = false; |
| 2934 | 3033 | |
| 2935 | 3034 | _myCamera.setOrientation(myAvatar->getHead()->getOrientation()); |
| 2936 | − if (Menu::getInstance()->isOptionChecked(MenuOption::CenterPlayerInView)) { | |
| 3035 | + if (isOptionChecked(MenuOption::CenterPlayerInView)) { | |
| 2937 | 3036 | _myCamera.setPosition(myAvatar->getDefaultEyePosition() |
| 2938 | 3037 | + _myCamera.getOrientation() * boomOffset); |
| 2939 | 3038 | } |
| @@ -5735,6 +5834,32 @@ void Application::update(float deltaTime) { · 2795 unmodified lines | ||
| 5735 | 5834 | } |
| 5736 | 5835 | |
| 5737 | 5836 | |
| 5837 | + updateRenderArgs(deltaTime); | |
| 5838 | + | |
| 5839 | + // HACK | |
| 5840 | + // load the view frustum | |
| 5841 | + // FIXME: This preDisplayRender call is temporary until we create a separate render::scene for the mirror rendering. | |
| 5842 | + // Then we can move this logic into the Avatar::simulate call. | |
| 5843 | + myAvatar->preDisplaySide(&_appRenderArgs._renderArgs); | |
| 5844 | + | |
| 5845 | + | |
| 5846 | + { | |
| 5847 | + PerformanceTimer perfTimer("limitless"); | |
| 5848 | + AnimDebugDraw::getInstance().update(); | |
| 5849 | + } | |
| 5850 | + | |
| 5851 | + { | |
| 5852 | + PerformanceTimer perfTimer("limitless"); | |
| 5853 | + DependencyManager::get<LimitlessVoiceRecognitionScriptingInterface>()->update(); | |
| 5854 | + } | |
| 5855 | + | |
| 5856 | + { // Game loop is done, mark the end of the frame for the scene transactions and the render loop to take over | |
| 5857 | + PerformanceTimer perfTimer("enqueueFrame"); | |
| 5858 | + getMain3DScene()->enqueueFrame(); | |
| 5859 | + } | |
| 5860 | +} | |
| 5861 | + | |
| 5862 | +void Application::updateRenderArgs(float deltaTime) { | |
| 5738 | 5863 | editRenderArgs([this, deltaTime](AppRenderArgs& appRenderArgs) { |
| 5739 | 5864 | PerformanceTimer perfTimer("editRenderArgs"); |
| 5740 | 5865 | appRenderArgs._headPose = getHMDSensorPose(); |
| @@ -5758,9 +5883,9 @@ void Application::update(float deltaTime) { · 17 unmodified lines | ||
| 5758 | 5883 | QMutexLocker viewLocker(&_viewMutex); |
| 5759 | 5884 | // adjust near clip plane to account for sensor scaling. |
| 5760 | 5885 | auto adjustedProjection = glm::perspective(glm::radians(_fieldOfView.get()), |
| 5761 | − getActiveDisplayPlugin()->getRecommendedAspectRatio(), | |
| 5762 | − DEFAULT_NEAR_CLIP * sensorToWorldScale, | |
| 5763 | − DEFAULT_FAR_CLIP); | |
| 5886 | + getActiveDisplayPlugin()->getRecommendedAspectRatio(), | |
| 5887 | + DEFAULT_NEAR_CLIP * sensorToWorldScale, | |
| 5888 | + DEFAULT_FAR_CLIP); | |
| 5764 | 5889 | _viewFrustum.setProjection(adjustedProjection); |
| 5765 | 5890 | _viewFrustum.calculate(); |
| 5766 | 5891 | } |
| @@ -5776,8 +5901,14 @@ void Application::update(float deltaTime) { · 9 unmodified lines | ||
| 5776 | 5901 | } |
| 5777 | 5902 | { |
| 5778 | 5903 | PROFILE_RANGE(render, "/resizeGL"); |
| 5779 | − PerformanceWarning::setSuppressShortTimings(Menu::getInstance()->isOptionChecked(MenuOption::SuppressShortTimings)); | |
| 5780 | − bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings); | |
| 5904 | + bool showWarnings = false; | |
| 5905 | + bool suppressShortTimings = false; | |
| 5906 | + auto menu = Menu::getInstance(); | |
| 5907 | + if (menu) { | |
| 5908 | + suppressShortTimings = menu->isOptionChecked(MenuOption::SuppressShortTimings); | |
| 5909 | + showWarnings = menu->isOptionChecked(MenuOption::PipelineWarnings); | |
| 5910 | + } | |
| 5911 | + PerformanceWarning::setSuppressShortTimings(suppressShortTimings); | |
| 5781 | 5912 | PerformanceWarning warn(showWarnings, "Application::paintGL()"); |
| 5782 | 5913 | resizeGL(); |
| 5783 | 5914 | } |
| @@ -5833,12 +5964,6 @@ void Application::update(float deltaTime) { · 49 unmodified lines | ||
| 5833 | 5964 | } |
| 5834 | 5965 | } |
| 5835 | 5966 | |
| 5836 | − // HACK | |
| 5837 | − // load the view frustum | |
| 5838 | − // FIXME: This preDisplayRender call is temporary until we create a separate render::scene for the mirror rendering. | |
| 5839 | − // Then we can move this logic into the Avatar::simulate call. | |
| 5840 | − myAvatar->preDisplaySide(&appRenderArgs._renderArgs); | |
| 5841 | − | |
| 5842 | 5967 | { |
| 5843 | 5968 | QMutexLocker viewLocker(&_viewMutex); |
| 5844 | 5969 | _myCamera.loadViewFrustum(_displayViewFrustum); |
| @@ -5850,21 +5975,6 @@ void Application::update(float deltaTime) { · 5 unmodified lines | ||
| 5850 | 5975 | appRenderArgs._renderArgs.setViewFrustum(_displayViewFrustum); |
| 5851 | 5976 | } |
| 5852 | 5977 | }); |
| 5853 | − | |
| 5854 | − { | |
| 5855 | − PerformanceTimer perfTimer("limitless"); | |
| 5856 | − AnimDebugDraw::getInstance().update(); | |
| 5857 | − } | |
| 5858 | − | |
| 5859 | − { | |
| 5860 | − PerformanceTimer perfTimer("limitless"); | |
| 5861 | − DependencyManager::get<LimitlessVoiceRecognitionScriptingInterface>()->update(); | |
| 5862 | − } | |
| 5863 | − | |
| 5864 | − { // Game loop is done, mark the end of the frame for the scene transactions and the render loop to take over | |
| 5865 | − PerformanceTimer perfTimer("enqueueFrame"); | |
| 5866 | − getMain3DScene()->enqueueFrame(); | |
| 5867 | − } | |
| 5868 | 5978 | } |
| 5869 | 5979 | |
| 5870 | 5980 | void Application::queryAvatars() { |
| @@ -7505,15 +7615,19 @@ void Application::shareSnapshot(const QString& path, const QUrl& href) { · 1634 unmodified lines | ||
| 7505 | 7615 | } |
| 7506 | 7616 | |
| 7507 | 7617 | float Application::getRenderResolutionScale() const { |
| 7508 | − if (Menu::getInstance()->isOptionChecked(MenuOption::RenderResolutionOne)) { | |
| 7618 | + auto menu = Menu::getInstance(); | |
| 7619 | + if (!menu) { | |
| 7620 | + return 1.0f; | |
| 7621 | + } | |
| 7622 | + if (menu->isOptionChecked(MenuOption::RenderResolutionOne)) { | |
| 7509 | 7623 | return 1.0f; |
| 7510 | − } else if (Menu::getInstance()->isOptionChecked(MenuOption::RenderResolutionTwoThird)) { | |
| 7624 | + } else if (menu->isOptionChecked(MenuOption::RenderResolutionTwoThird)) { | |
| 7511 | 7625 | return 0.666f; |
| 7512 | − } else if (Menu::getInstance()->isOptionChecked(MenuOption::RenderResolutionHalf)) { | |
| 7626 | + } else if (menu->isOptionChecked(MenuOption::RenderResolutionHalf)) { | |
| 7513 | 7627 | return 0.5f; |
| 7514 | − } else if (Menu::getInstance()->isOptionChecked(MenuOption::RenderResolutionThird)) { | |
| 7628 | + } else if (menu->isOptionChecked(MenuOption::RenderResolutionThird)) { | |
| 7515 | 7629 | return 0.333f; |
| 7516 | − } else if (Menu::getInstance()->isOptionChecked(MenuOption::RenderResolutionQuarter)) { | |
| 7630 | + } else if (menu->isOptionChecked(MenuOption::RenderResolutionQuarter)) { | |
| 7517 | 7631 | return 0.25f; |
| 7518 | 7632 | } else { |
| 7519 | 7633 | return 1.0f; |
| @@ -7737,7 +7851,7 @@ DisplayPluginPointer Application::getActiveDisplayPlugin() const { · 217 unmodified lines | ||
| 7737 | 7851 | |
| 7738 | 7852 | static const char* EXCLUSION_GROUP_KEY = "exclusionGroup"; |
| 7739 | 7853 | |
| 7740 | −static void addDisplayPluginToMenu(DisplayPluginPointer displayPlugin, bool active = false) { | |
| 7854 | +static void addDisplayPluginToMenu(const DisplayPluginPointer& displayPlugin, bool active) { | |
| 7741 | 7855 | auto menu = Menu::getInstance(); |
| 7742 | 7856 | QString name = displayPlugin->getName(); |
| 7743 | 7857 | auto grouping = displayPlugin->getGrouping(); |
| @@ -7782,65 +7896,12 @@ void Application::updateDisplayMode() { · 38 unmodified lines | ||
| 7782 | 7896 | qFatal("Attempted to switch display plugins from a non-main thread"); |
| 7783 | 7897 | } |
| 7784 | 7898 | |
| 7785 | − auto displayPlugins = PluginManager::getInstance()->getDisplayPlugins(); | |
| 7786 | − | |
| 7787 | − // Once time initialization code | |
| 7788 | − static std::once_flag once; | |
| 7789 | − std::call_once(once, [&] { | |
| 7790 | − foreach(auto displayPlugin, displayPlugins) { | |
| 7791 | − displayPlugin->setContext(_gpuContext); | |
| 7792 | − QObject::connect(displayPlugin.get(), &DisplayPlugin::recommendedFramebufferSizeChanged, | |
| 7793 | − [this](const QSize& size) { resizeGL(); }); | |
| 7794 | − QObject::connect(displayPlugin.get(), &DisplayPlugin::resetSensorsRequested, this, &Application::requestReset); | |
| 7795 | − } | |
| 7796 | − }); | |
| 7797 | − | |
| 7798 | 7899 | // Once time initialization code that depends on the UI being available |
| 7799 | − auto menu = Menu::getInstance(); | |
| 7800 | − if (menu) { | |
| 7801 | − static std::once_flag onceUi; | |
| 7802 | − std::call_once(onceUi, [&] { | |
| 7803 | − bool first = true; | |
| 7804 | − | |
| 7805 | − // first sort the plugins into groupings: standard, advanced, developer | |
| 7806 | − DisplayPluginList standard; | |
| 7807 | − DisplayPluginList advanced; | |
| 7808 | − DisplayPluginList developer; | |
| 7809 | − foreach(auto displayPlugin, displayPlugins) { | |
| 7810 | − displayPlugin->setContext(_gpuContext); | |
| 7811 | − auto grouping = displayPlugin->getGrouping(); | |
| 7812 | − switch (grouping) { | |
| 7813 | − case Plugin::ADVANCED: | |
| 7814 | − advanced.push_back(displayPlugin); | |
| 7815 | − break; | |
| 7816 | − case Plugin::DEVELOPER: | |
| 7817 | − developer.push_back(displayPlugin); | |
| 7818 | − break; | |
| 7819 | − default: | |
| 7820 | − standard.push_back(displayPlugin); | |
| 7821 | − break; | |
| 7822 | − } | |
| 7823 | − } | |
| 7824 | − | |
| 7825 | − // concatenate the groupings into a single list in the order: standard, advanced, developer | |
| 7826 | − standard.insert(std::end(standard), std::begin(advanced), std::end(advanced)); | |
| 7827 | − standard.insert(std::end(standard), std::begin(developer), std::end(developer)); | |
| 7828 | − | |
| 7829 | − foreach(auto displayPlugin, standard) { | |
| 7830 | − addDisplayPluginToMenu(displayPlugin, first); | |
| 7831 | − first = false; | |
| 7832 | − } | |
| 7833 | − | |
| 7834 | − // after all plugins have been added to the menu, add a separator to the menu | |
| 7835 | − auto parent = menu->getMenu(MenuOption::OutputMenu); | |
| 7836 | − parent->addSeparator(); | |
| 7837 | − }); | |
| 7838 | − | |
| 7839 | − } | |
| 7840 | − | |
| 7900 | + auto displayPlugins = getDisplayPlugins(); | |
| 7841 | 7901 | |
| 7842 | 7902 | // Default to the first item on the list, in case none of the menu items match |
| 7843 | 7903 | DisplayPluginPointer newDisplayPlugin = displayPlugins.at(0); |
| 7904 | + auto menu = getPrimaryMenu(); | |
| 7844 | 7905 | if (menu) { |
| 7845 | 7906 | foreach(DisplayPluginPointer displayPlugin, PluginManager::getInstance()->getDisplayPlugins()) { |
| 7846 | 7907 | QString name = displayPlugin->getName(); |
| @@ -7864,6 +7925,14 @@ void Application::updateDisplayMode() { · 17 unmodified lines | ||
| 7864 | 7925 | } |
| 7865 | 7926 | |
| 7866 | 7927 | void Application::setDisplayPlugin(DisplayPluginPointer newDisplayPlugin) { |
| 7928 | + if (newDisplayPlugin == _displayPlugin) { | |
| 7929 | + return; | |
| 7930 | + } | |
| 7931 | + | |
| 7932 | + // FIXME don't have the application directly set the state of the UI, | |
| 7933 | + // instead emit a signal that the display plugin is changing and let | |
| 7934 | + // the desktop lock itself. Reduces coupling between the UI and display | |
| 7935 | + // plugins | |
| 7867 | 7936 | auto offscreenUi = DependencyManager::get<OffscreenUi>(); |
| 7868 | 7937 | auto desktop = offscreenUi->getDesktop(); |
| 7869 | 7938 | auto menu = Menu::getInstance(); |
| @@ -7874,8 +7943,8 @@ void Application::setDisplayPlugin(DisplayPluginPointer newDisplayPlugin) { · 4 unmodified lines | ||
| 7874 | 7943 | bool wasRepositionLocked = false; |
| 7875 | 7944 | if (desktop) { |
| 7876 | 7945 | // Tell the desktop to no reposition (which requires plugin info), until we have set the new plugin, below. |
| 7877 | − wasRepositionLocked = offscreenUi->getDesktop()->property("repositionLocked").toBool(); | |
| 7878 | − offscreenUi->getDesktop()->setProperty("repositionLocked", true); | |
| 7946 | + wasRepositionLocked = desktop->property("repositionLocked").toBool(); | |
| 7947 | + desktop->setProperty("repositionLocked", true); | |
| 7879 | 7948 | } |
| 7880 | 7949 | |
| 7881 | 7950 | if (_displayPlugin) { |