Showing the changes to interface/src/Application.cpp (1 of 164 files). Show all
Unified · Split
| @@ -113,7 +113,6 @@ · 112 unmodified lines | |||
| 113 | #include <plugins/SteamClientPlugin.h> | 113 | #include <plugins/SteamClientPlugin.h> |
| 114 | #include <plugins/InputConfiguration.h> | 114 | #include <plugins/InputConfiguration.h> |
| 115 | #include <RecordingScriptingInterface.h> | 115 | #include <RecordingScriptingInterface.h> |
| 116 | #include <RenderableWebEntityItem.h> | ||
| 117 | #include <UpdateSceneTask.h> | 116 | #include <UpdateSceneTask.h> |
| 118 | #include <RenderViewTask.h> | 117 | #include <RenderViewTask.h> |
| 119 | #include <SecondaryCamera.h> | 118 | #include <SecondaryCamera.h> |
| @@ -139,6 +138,7 @@ · 19 unmodified lines | |||
| 139 | #include <display-plugins/CompositorHelper.h> | 138 | #include <display-plugins/CompositorHelper.h> |
| 140 | #include <trackers/EyeTracker.h> | 139 | #include <trackers/EyeTracker.h> |
| 141 | #include <avatars-renderer/ScriptAvatar.h> | 140 | #include <avatars-renderer/ScriptAvatar.h> |
| 141 | #include <RenderableEntityItem.h> | ||
| 142 | 142 | ||
| 143 | #include "AudioClient.h" | 143 | #include "AudioClient.h" |
| 144 | #include "audio/AudioScope.h" | 144 | #include "audio/AudioScope.h" |
| @@ -184,6 +184,7 @@ · 39 unmodified lines | |||
| 184 | #include "ui/UpdateDialog.h" | 184 | #include "ui/UpdateDialog.h" |
| 185 | #include "ui/overlays/Overlays.h" | 185 | #include "ui/overlays/Overlays.h" |
| 186 | #include "ui/DomainConnectionModel.h" | 186 | #include "ui/DomainConnectionModel.h" |
| 187 | #include "ui/ImageProvider.h" | ||
| 187 | #include "Util.h" | 188 | #include "Util.h" |
| 188 | #include "InterfaceParentFinder.h" | 189 | #include "InterfaceParentFinder.h" |
| 189 | #include "ui/OctreeStatsProvider.h" | 190 | #include "ui/OctreeStatsProvider.h" |
| @@ -212,6 +213,73 @@ extern "C" { · 22 unmodified lines | |||
| 212 | } | 213 | } |
| 213 | #endif | 214 | #endif |
| 214 | 215 | ||
| 216 | enum ApplicationEvent { | ||
| 217 | // Execute a lambda function | ||
| 218 | Lambda = QEvent::User + 1, | ||
| 219 | // Trigger the next render | ||
| 220 | Render, | ||
| 221 | // Trigger the next idle | ||
| 222 | Idle, | ||
| 223 | }; | ||
| 224 | |||
| 225 | |||
| 226 | class RenderEventHandler : public QObject { | ||
| 227 | using Parent = QObject; | ||
| 228 | Q_OBJECT | ||
| 229 | public: | ||
| 230 | RenderEventHandler(QOpenGLContext* context) { | ||
| 231 | _renderContext = new OffscreenGLCanvas(); | ||
| 232 | _renderContext->setObjectName("RenderContext"); | ||
| 233 | _renderContext->create(context); | ||
| 234 | if (!_renderContext->makeCurrent()) { | ||
| 235 | qFatal("Unable to make rendering context current"); | ||
| 236 | } | ||
| 237 | _renderContext->doneCurrent(); | ||
| 238 | |||
| 239 | // Deleting the object with automatically shutdown the thread | ||
| 240 | connect(qApp, &QCoreApplication::aboutToQuit, this, &QObject::deleteLater); | ||
| 241 | |||
| 242 | // Transfer to a new thread | ||
| 243 | moveToNewNamedThread(this, "RenderThread", [this](QThread* renderThread) { | ||
| 244 | hifi::qt::addBlockingForbiddenThread("Render", renderThread); | ||
| 245 | _renderContext->moveToThreadWithContext(renderThread); | ||
| 246 | qApp->_lastTimeRendered.start(); | ||
| 247 | }, std::bind(&RenderEventHandler::initialize, this), QThread::HighestPriority); | ||
| 248 | } | ||
| 249 | |||
| 250 | private: | ||
| 251 | void initialize() { | ||
| 252 | PROFILE_SET_THREAD_NAME("Render"); | ||
| 253 | if (!_renderContext->makeCurrent()) { | ||
| 254 | qFatal("Unable to make rendering context current on render thread"); | ||
| 255 | } | ||
| 256 | } | ||
| 257 | |||
| 258 | void render() { | ||
| 259 | if (qApp->shouldPaint()) { | ||
| 260 | qApp->paintGL(); | ||
| 261 | } | ||
| 262 | } | ||
| 263 | |||
| 264 | bool event(QEvent* event) override { | ||
| 265 | switch ((int)event->type()) { | ||
| 266 | case ApplicationEvent::Render: | ||
| 267 | render(); | ||
| 268 | // Ensure we never back up the render events. Each render should be triggered only in response | ||
| 269 | // to the NEXT render event after the last render occured | ||
| 270 | QCoreApplication::removePostedEvents(this, ApplicationEvent::Render); | ||
| 271 | return true; | ||
| 272 | |||
| 273 | default: | ||
| 274 | break; | ||
| 275 | } | ||
| 276 | return Parent::event(event); | ||
| 277 | } | ||
| 278 | |||
| 279 | OffscreenGLCanvas* _renderContext { nullptr }; | ||
| 280 | }; | ||
| 281 | |||
| 282 | |||
| 215 | Q_LOGGING_CATEGORY(trace_app_input_mouse, "trace.app.input.mouse") | 283 | Q_LOGGING_CATEGORY(trace_app_input_mouse, "trace.app.input.mouse") |
| 216 | 284 | ||
| 217 | using namespace std; | 285 | using namespace std; |
| @@ -427,10 +495,10 @@ class LambdaEvent : public QEvent { · 209 unmodified lines | |||
| 427 | std::function<void()> _fun; | 495 | std::function<void()> _fun; |
| 428 | public: | 496 | public: |
| 429 | LambdaEvent(const std::function<void()> & fun) : | 497 | LambdaEvent(const std::function<void()> & fun) : |
| 430 | QEvent(static_cast<QEvent::Type>(Application::Lambda)), _fun(fun) { | 498 | QEvent(static_cast<QEvent::Type>(ApplicationEvent::Lambda)), _fun(fun) { |
| 431 | } | 499 | } |
| 432 | LambdaEvent(std::function<void()> && fun) : | 500 | LambdaEvent(std::function<void()> && fun) : |
| 433 | QEvent(static_cast<QEvent::Type>(Application::Lambda)), _fun(fun) { | 501 | QEvent(static_cast<QEvent::Type>(ApplicationEvent::Lambda)), _fun(fun) { |
| 434 | } | 502 | } |
| 435 | void call() const { _fun(); } | 503 | void call() const { _fun(); } |
| 436 | }; | 504 | }; |
| @@ -1368,8 +1436,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo · 931 unmodified lines | |||
| 1368 | auto entityScriptingInterface = DependencyManager::get<EntityScriptingInterface>(); | 1436 | auto entityScriptingInterface = DependencyManager::get<EntityScriptingInterface>(); |
| 1369 | connect(entityScriptingInterface.data(), &EntityScriptingInterface::clickDownOnEntity, | 1437 | connect(entityScriptingInterface.data(), &EntityScriptingInterface::clickDownOnEntity, |
| 1370 | [this](const EntityItemID& entityItemID, const PointerEvent& event) { | 1438 | [this](const EntityItemID& entityItemID, const PointerEvent& event) { |
| 1371 | auto entity = getEntities()->getTree()->findEntityByID(entityItemID); | 1439 | if (getEntities()->wantsKeyboardFocus(entityItemID)) { |
| 1372 | if (entity && entity->wantsKeyboardFocus()) { | ||
| 1373 | setKeyboardFocusOverlay(UNKNOWN_OVERLAY_ID); | 1440 | setKeyboardFocusOverlay(UNKNOWN_OVERLAY_ID); |
| 1374 | setKeyboardFocusEntity(entityItemID); | 1441 | setKeyboardFocusEntity(entityItemID); |
| 1375 | } else { | 1442 | } else { |
| @@ -1693,7 +1760,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo · 317 unmodified lines | |||
| 1693 | _defaultSkybox->setCubemap(_defaultSkyboxTexture); | 1760 | _defaultSkybox->setCubemap(_defaultSkyboxTexture); |
| 1694 | } | 1761 | } |
| 1695 | 1762 | ||
| 1696 | EntityItem::setEntitiesShouldFadeFunction([this]() { | 1763 | EntityTreeRenderer::setEntitiesShouldFadeFunction([this]() { |
| 1697 | SharedNodePointer entityServerNode = DependencyManager::get<NodeList>()->soloNodeOfType(NodeType::EntityServer); | 1764 | SharedNodePointer entityServerNode = DependencyManager::get<NodeList>()->soloNodeOfType(NodeType::EntityServer); |
| 1698 | return entityServerNode && !isPhysicsEnabled(); | 1765 | return entityServerNode && !isPhysicsEnabled(); |
| 1699 | }); | 1766 | }); |
| @@ -1737,6 +1804,27 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo · 37 unmodified lines | |||
| 1737 | 1804 | ||
| 1738 | connect(&_myCamera, &Camera::modeUpdated, this, &Application::cameraModeChanged); | 1805 | connect(&_myCamera, &Camera::modeUpdated, this, &Application::cameraModeChanged); |
| 1739 | 1806 | ||
| 1807 | // Setup the mouse ray pick and related operators | ||
| 1808 | DependencyManager::get<EntityTreeRenderer>()->setMouseRayPickID(_rayPickManager.createRayPick( | ||
| 1809 | RayPickFilter(DependencyManager::get<RayPickScriptingInterface>()->PICK_ENTITIES() | DependencyManager::get<RayPickScriptingInterface>()->PICK_INCLUDE_NONCOLLIDABLE()), | ||
| 1810 | 0.0f, true)); | ||
| 1811 | DependencyManager::get<EntityTreeRenderer>()->setMouseRayPickResultOperator([&](QUuid rayPickID) { | ||
| 1812 | RayToEntityIntersectionResult entityResult; | ||
| 1813 | RayPickResult result = _rayPickManager.getPrevRayPickResult(rayPickID); | ||
| 1814 | entityResult.intersects = result.type != DependencyManager::get<RayPickScriptingInterface>()->INTERSECTED_NONE(); | ||
| 1815 | if (entityResult.intersects) { | ||
| 1816 | entityResult.intersection = result.intersection; | ||
| 1817 | entityResult.distance = result.distance; | ||
| 1818 | entityResult.surfaceNormal = result.surfaceNormal; | ||
| 1819 | entityResult.entityID = result.objectID; | ||
| 1820 | entityResult.entity = DependencyManager::get<EntityTreeRenderer>()->getTree()->findEntityByID(entityResult.entityID); | ||
| 1821 | } | ||
| 1822 | return entityResult; | ||
| 1823 | }); | ||
| 1824 | DependencyManager::get<EntityTreeRenderer>()->setSetPrecisionPickingOperator([&](QUuid rayPickID, bool value) { | ||
| 1825 | _rayPickManager.setPrecisionPicking(rayPickID, value); | ||
| 1826 | }); | ||
| 1827 | |||
| 1740 | qCDebug(interfaceapp) << "Metaverse session ID is" << uuidStringWithoutCurlyBraces(accountManager->getSessionID()); | 1828 | qCDebug(interfaceapp) << "Metaverse session ID is" << uuidStringWithoutCurlyBraces(accountManager->getSessionID()); |
| 1741 | } | 1829 | } |
| 1742 | 1830 | ||
| @@ -2079,6 +2167,13 @@ void Application::initializeGL() { · 336 unmodified lines | |||
| 2079 | _renderEngine->load(); | 2167 | _renderEngine->load(); |
| 2080 | _renderEngine->registerScene(_main3DScene); | 2168 | _renderEngine->registerScene(_main3DScene); |
| 2081 | 2169 | ||
| 2170 | _offscreenContext = new OffscreenGLCanvas(); | ||
| 2171 | _offscreenContext->setObjectName("MainThreadContext"); | ||
| 2172 | _offscreenContext->create(_glWidget->qglContext()); | ||
| 2173 | if (!_offscreenContext->makeCurrent()) { | ||
| 2174 | qFatal("Unable to make offscreen context current"); | ||
| 2175 | } | ||
| 2176 | |||
| 2082 | // The UI can't be created until the primary OpenGL | 2177 | // The UI can't be created until the primary OpenGL |
| 2083 | // context is created, because it needs to share | 2178 | // context is created, because it needs to share |
| 2084 | // texture resources | 2179 | // texture resources |
| @@ -2102,14 +2197,15 @@ void Application::initializeGL() { · 17 unmodified lines | |||
| 2102 | 2197 | ||
| 2103 | _idleLoopStdev.reset(); | 2198 | _idleLoopStdev.reset(); |
| 2104 | 2199 | ||
| 2105 | _offscreenContext = new OffscreenGLCanvas(); | 2200 | _renderEventHandler = new RenderEventHandler(_glWidget->qglContext()); |
| 2106 | _offscreenContext->setObjectName("MainThreadContext"); | 2201 | |
| 2107 | _offscreenContext->create(_glWidget->qglContext()); | 2202 | // Restore the primary GL content for the main thread |
| 2108 | _offscreenContext->makeCurrent(); | 2203 | if (!_offscreenContext->makeCurrent()) { |
| 2204 | qFatal("Unable to make offscreen context current"); | ||
| 2205 | } | ||
| 2109 | 2206 | ||
| 2110 | // update before the first render | 2207 | // update before the first render |
| 2111 | update(0); | 2208 | update(0); |
| 2112 | |||
| 2113 | } | 2209 | } |
| 2114 | 2210 | ||
| 2115 | FrameTimingsScriptingInterface _frameTimingsScriptingInterface; | 2211 | FrameTimingsScriptingInterface _frameTimingsScriptingInterface; |
| @@ -2117,6 +2213,9 @@ FrameTimingsScriptingInterface _frameTimingsScriptingInterface; · 1 unmodified line | |||
| 2117 | extern void setupPreferences(); | 2213 | extern void setupPreferences(); |
| 2118 | 2214 | ||
| 2119 | void Application::initializeUi() { | 2215 | void Application::initializeUi() { |
| 2216 | // Make sure all QML surfaces share the main thread GL context | ||
| 2217 | OffscreenQmlSurface::setSharedContext(_offscreenContext->getContext()); | ||
| 2218 | |||
| 2120 | AddressBarDialog::registerType(); | 2219 | AddressBarDialog::registerType(); |
| 2121 | ErrorDialog::registerType(); | 2220 | ErrorDialog::registerType(); |
| 2122 | LoginDialog::registerType(); | 2221 | LoginDialog::registerType(); |
| @@ -2127,7 +2226,7 @@ void Application::initializeUi() { · 4 unmodified lines | |||
| 2127 | qmlRegisterType<Preference>("Hifi", 1, 0, "Preference"); | 2226 | qmlRegisterType<Preference>("Hifi", 1, 0, "Preference"); |
| 2128 | 2227 | ||
| 2129 | auto offscreenUi = DependencyManager::get<OffscreenUi>(); | 2228 | auto offscreenUi = DependencyManager::get<OffscreenUi>(); |
| 2130 | offscreenUi->create(_glWidget->qglContext()); | 2229 | offscreenUi->create(); |
| 2131 | 2230 | ||
| 2132 | auto surfaceContext = offscreenUi->getSurfaceContext(); | 2231 | auto surfaceContext = offscreenUi->getSurfaceContext(); |
| 2133 | 2232 | ||
| @@ -2146,6 +2245,9 @@ void Application::initializeUi() { · 12 unmodified lines | |||
| 2146 | qApp->quit(); | 2245 | qApp->quit(); |
| 2147 | }); | 2246 | }); |
| 2148 | 2247 | ||
| 2248 | // register the pixmap image provider (used only for security image, for now) | ||
| 2249 | engine->addImageProvider(ImageProvider::PROVIDER_NAME, new ImageProvider()); | ||
| 2250 | |||
| 2149 | setupPreferences(); | 2251 | setupPreferences(); |
| 2150 | 2252 | ||
| 2151 | // For some reason there is already an "Application" object in the QML context, | 2253 | // For some reason there is already an "Application" object in the QML context, |
| @@ -2270,14 +2372,12 @@ void Application::initializeUi() { · 118 unmodified lines | |||
| 2270 | 2372 | ||
| 2271 | void Application::paintGL() { | 2373 | void Application::paintGL() { |
| 2272 | // Some plugins process message events, allowing paintGL to be called reentrantly. | 2374 | // Some plugins process message events, allowing paintGL to be called reentrantly. |
| 2273 | if (_inPaint || _aboutToQuit || _window->isMinimized()) { | 2375 | if (_aboutToQuit || _window->isMinimized()) { |
| 2274 | return; | 2376 | return; |
| 2275 | } | 2377 | } |
| 2276 | 2378 | ||
| 2277 | _inPaint = true; | ||
| 2278 | Finally clearFlag([this] { _inPaint = false; }); | ||
| 2279 | |||
| 2280 | _frameCount++; | 2379 | _frameCount++; |
| 2380 | _lastTimeRendered.start(); | ||
| 2281 | 2381 | ||
| 2282 | auto lastPaintBegin = usecTimestampNow(); | 2382 | auto lastPaintBegin = usecTimestampNow(); |
| 2283 | PROFILE_RANGE_EX(render, __FUNCTION__, 0xff0000ff, (uint64_t)_frameCount); | 2383 | PROFILE_RANGE_EX(render, __FUNCTION__, 0xff0000ff, (uint64_t)_frameCount); |
| @@ -2293,18 +2393,11 @@ void Application::paintGL() { · 9 unmodified lines | |||
| 2293 | displayPlugin = getActiveDisplayPlugin(); | 2393 | displayPlugin = getActiveDisplayPlugin(); |
| 2294 | } | 2394 | } |
| 2295 | 2395 | ||
| 2296 | { | ||
| 2297 | PROFILE_RANGE(render, "/offscreenMakeCurrent"); | ||
| 2298 | // FIXME not needed anymore? | ||
| 2299 | _offscreenContext->makeCurrent(); | ||
| 2300 | } | ||
| 2301 | |||
| 2302 | { | 2396 | { |
| 2303 | PROFILE_RANGE(render, "/pluginBeginFrameRender"); | 2397 | PROFILE_RANGE(render, "/pluginBeginFrameRender"); |
| 2304 | // If a display plugin loses it's underlying support, it | 2398 | // If a display plugin loses it's underlying support, it |
| 2305 | // needs to be able to signal us to not use it | 2399 | // needs to be able to signal us to not use it |
| 2306 | if (!displayPlugin->beginFrameRender(_frameCount)) { | 2400 | if (!displayPlugin->beginFrameRender(_frameCount)) { |
| 2307 | _inPaint = false; | ||
| 2308 | updateDisplayMode(); | 2401 | updateDisplayMode(); |
| 2309 | return; | 2402 | return; |
| 2310 | } | 2403 | } |
| @@ -2372,12 +2465,6 @@ void Application::paintGL() { · 61 unmodified lines | |||
| 2372 | auto myAvatar = getMyAvatar(); | 2465 | auto myAvatar = getMyAvatar(); |
| 2373 | boomOffset = myAvatar->getScale() * myAvatar->getBoomLength() * -IDENTITY_FORWARD; | 2466 | boomOffset = myAvatar->getScale() * myAvatar->getBoomLength() * -IDENTITY_FORWARD; |
| 2374 | 2467 | ||
| 2375 | if (_myCamera.getMode() == CAMERA_MODE_FIRST_PERSON || _myCamera.getMode() == CAMERA_MODE_THIRD_PERSON) { | ||
| 2376 | Menu::getInstance()->setIsOptionChecked(MenuOption::FirstPerson, myAvatar->getBoomLength() <= MyAvatar::ZOOM_MIN); | ||
| 2377 | Menu::getInstance()->setIsOptionChecked(MenuOption::ThirdPerson, !(myAvatar->getBoomLength() <= MyAvatar::ZOOM_MIN)); | ||
| 2378 | cameraMenuChanged(); | ||
| 2379 | } | ||
| 2380 | |||
| 2381 | // The render mode is default or mirror if the camera is in mirror mode, assigned further below | 2468 | // The render mode is default or mirror if the camera is in mirror mode, assigned further below |
| 2382 | renderArgs._renderMode = RenderArgs::DEFAULT_RENDER_MODE; | 2469 | renderArgs._renderMode = RenderArgs::DEFAULT_RENDER_MODE; |
| 2383 | 2470 | ||
| @@ -2685,15 +2772,6 @@ void Application::resizeGL() { · 301 unmodified lines | |||
| 2685 | QMutexLocker viewLocker(&_viewMutex); | 2772 | QMutexLocker viewLocker(&_viewMutex); |
| 2686 | _myCamera.loadViewFrustum(_viewFrustum); | 2773 | _myCamera.loadViewFrustum(_viewFrustum); |
| 2687 | } | 2774 | } |
| 2688 | |||
| 2689 | auto offscreenUi = DependencyManager::get<OffscreenUi>(); | ||
| 2690 | auto uiSize = displayPlugin->getRecommendedUiSize(); | ||
| 2691 | // Bit of a hack since there's no device pixel ratio change event I can find. | ||
| 2692 | if (offscreenUi->size() != fromGlm(uiSize)) { | ||
| 2693 | qCDebug(interfaceapp) << "Device pixel ratio changed, triggering resize to " << uiSize; | ||
| 2694 | offscreenUi->resize(fromGlm(uiSize), true); | ||
| 2695 | _offscreenContext->makeCurrent(); | ||
| 2696 | } | ||
| 2697 | } | 2775 | } |
| 2698 | 2776 | ||
| 2699 | void Application::handleSandboxStatus(QNetworkReply* reply) { | 2777 | void Application::handleSandboxStatus(QNetworkReply* reply) { |
| @@ -2867,56 +2945,26 @@ bool Application::importFromZIP(const QString& filePath) { · 167 unmodified lines | |||
| 2867 | } | 2945 | } |
| 2868 | 2946 | ||
| 2869 | void Application::onPresent(quint32 frameCount) { | 2947 | void Application::onPresent(quint32 frameCount) { |
| 2870 | if (shouldPaint()) { | 2948 | postEvent(this, new QEvent((QEvent::Type)ApplicationEvent::Idle), Qt::HighEventPriority); |
| 2871 | postEvent(this, new QEvent(static_cast<QEvent::Type>(Idle)), Qt::HighEventPriority); | 2949 | if (_renderEventHandler && !isAboutToQuit()) { |
| 2872 | postEvent(this, new QEvent(static_cast<QEvent::Type>(Paint)), Qt::HighEventPriority); | 2950 | postEvent(_renderEventHandler, new QEvent((QEvent::Type)ApplicationEvent::Render)); |
| 2873 | } | 2951 | } |
| 2874 | } | 2952 | } |
| 2875 | 2953 | ||
| 2876 | bool _renderRequested { false }; | 2954 | static inline bool isKeyEvent(QEvent::Type type) { |
| 2877 | 2955 | return type == QEvent::KeyPress || type == QEvent::KeyRelease; | |
| 2878 | bool Application::event(QEvent* event) { | 2956 | } |
| 2879 | if (!Menu::getInstance()) { | ||
| 2880 | return false; | ||
| 2881 | } | ||
| 2882 | |||
| 2883 | int type = event->type(); | ||
| 2884 | switch (type) { | ||
| 2885 | case Event::Lambda: | ||
| 2886 | static_cast<LambdaEvent*>(event)->call(); | ||
| 2887 | return true; | ||
| 2888 | |||
| 2889 | // Explicit idle keeps the idle running at a lower interval, but without any rendering | ||
| 2890 | // see (windowMinimizedChanged) | ||
| 2891 | case Event::Idle: | ||
| 2892 | idle(); | ||
| 2893 | // Clear the event queue of pending idle calls | ||
| 2894 | removePostedEvents(this, Idle); | ||
| 2895 | return true; | ||
| 2896 | |||
| 2897 | case Event::Paint: | ||
| 2898 | // NOTE: This must be updated as close to painting as possible, | ||
| 2899 | // or AvatarInputs will mysteriously move to the bottom-right | ||
| 2900 | AvatarInputs::getInstance()->update(); | ||
| 2901 | paintGL(); | ||
| 2902 | // Clear the event queue of pending paint calls | ||
| 2903 | removePostedEvents(this, Paint); | ||
| 2904 | return true; | ||
| 2905 | |||
| 2906 | default: | ||
| 2907 | break; | ||
| 2908 | } | ||
| 2909 | 2957 | ||
| 2910 | { | 2958 | bool Application::handleKeyEventForFocusedEntityOrOverlay(QEvent* event) { |
| 2911 | if (!_keyboardFocusedEntity.get().isInvalidID()) { | 2959 | if (!_keyboardFocusedEntity.get().isInvalidID()) { |
| 2912 | switch (event->type()) { | 2960 | switch (event->type()) { |
| 2913 | case QEvent::KeyPress: | 2961 | case QEvent::KeyPress: |
| 2914 | case QEvent::KeyRelease: { | 2962 | case QEvent::KeyRelease: |
| 2915 | //auto entityScriptingInterface = DependencyManager::get<EntityScriptingInterface>(); | 2963 | { |
| 2916 | auto entity = getEntities()->getTree()->findEntityByID(_keyboardFocusedEntity.get()); | 2964 | auto eventHandler = getEntities()->getEventHandler(_keyboardFocusedEntity.get()); |
| 2917 | if (entity && entity->getEventHandler()) { | 2965 | if (eventHandler) { |
| 2918 | event->setAccepted(false); | 2966 | event->setAccepted(false); |
| 2919 | QCoreApplication::sendEvent(entity->getEventHandler(), event); | 2967 | QCoreApplication::sendEvent(eventHandler, event); |
| 2920 | if (event->isAccepted()) { | 2968 | if (event->isAccepted()) { |
| 2921 | _lastAcceptedKeyPress = usecTimestampNow(); | 2969 | _lastAcceptedKeyPress = usecTimestampNow(); |
| 2922 | return true; | 2970 | return true; |
| @@ -2924,20 +2972,17 @@ bool Application::event(QEvent* event) { · 1 unmodified line | |||
| 2924 | } | 2972 | } |
| 2925 | break; | 2973 | break; |
| 2926 | } | 2974 | } |
| 2927 | default: | 2975 | default: |
| 2928 | break; | 2976 | break; |
| 2929 | } | ||
| 2930 | } | 2977 | } |
| 2931 | } | 2978 | } |
| 2932 | 2979 | ||
| 2933 | { | 2980 | if (_keyboardFocusedOverlay.get() != UNKNOWN_OVERLAY_ID) { |
| 2934 | if (_keyboardFocusedOverlay.get() != UNKNOWN_OVERLAY_ID) { | 2981 | switch (event->type()) { |
| 2935 | switch (event->type()) { | 2982 | case QEvent::KeyPress: |
| 2936 | case QEvent::KeyPress: | 2983 | case QEvent::KeyRelease: { |
| 2937 | case QEvent::KeyRelease: { | ||
| 2938 | // Only Web overlays can have focus. | 2984 | // Only Web overlays can have focus. |
| 2939 | auto overlay = | 2985 | auto overlay = std::dynamic_pointer_cast<Web3DOverlay>(getOverlays().getOverlay(_keyboardFocusedOverlay.get())); |
| 2940 | std::dynamic_pointer_cast<Web3DOverlay>(getOverlays().getOverlay(_keyboardFocusedOverlay.get())); | ||
| 2941 | if (overlay && overlay->getEventHandler()) { | 2986 | if (overlay && overlay->getEventHandler()) { |
| 2942 | event->setAccepted(false); | 2987 | event->setAccepted(false); |
| 2943 | QCoreApplication::sendEvent(overlay->getEventHandler(), event); | 2988 | QCoreApplication::sendEvent(overlay->getEventHandler(), event); |
| @@ -2946,15 +2991,52 @@ bool Application::event(QEvent* event) { · 2 unmodified lines | |||
| 2946 | return true; | 2991 | return true; |
| 2947 | } | 2992 | } |
| 2948 | } | 2993 | } |
| 2949 | break; | ||
| 2950 | } | ||
| 2951 | default: | ||
| 2952 | break; | ||
| 2953 | } | 2994 | } |
| 2995 | break; | ||
| 2996 | |||
| 2997 | default: | ||
| 2998 | break; | ||
| 2954 | } | 2999 | } |
| 2955 | } | 3000 | } |
| 2956 | 3001 | ||
| 2957 | switch (event->type()) { | 3002 | return false; |
| 3003 | } | ||
| 3004 | |||
| 3005 | bool Application::handleFileOpenEvent(QFileOpenEvent* fileEvent) { | ||
| 3006 | QUrl url = fileEvent->url(); | ||
| 3007 | if (!url.isEmpty()) { | ||
| 3008 | QString urlString = url.toString(); | ||
| 3009 | if (canAcceptURL(urlString)) { | ||
| 3010 | return acceptURL(urlString); | ||
| 3011 | } | ||
| 3012 | } | ||
| 3013 | return false; | ||
| 3014 | } | ||
| 3015 | |||
| 3016 | bool Application::event(QEvent* event) { | ||
| 3017 | if (!Menu::getInstance()) { | ||
| 3018 | return false; | ||
| 3019 | } | ||
| 3020 | |||
| 3021 | // Allow focused Entities and Overlays to handle keyboard input | ||
| 3022 | if (isKeyEvent(event->type()) && handleKeyEventForFocusedEntityOrOverlay(event)) { | ||
| 3023 | return true; | ||
| 3024 | } | ||
| 3025 | |||
| 3026 | int type = event->type(); | ||
| 3027 | switch (type) { | ||
| 3028 | case ApplicationEvent::Lambda: | ||
| 3029 | static_cast<LambdaEvent*>(event)->call(); | ||
| 3030 | return true; | ||
| 3031 | |||
| 3032 | // Explicit idle keeps the idle running at a lower interval, but without any rendering | ||
| 3033 | // see (windowMinimizedChanged) | ||
| 3034 | case ApplicationEvent::Idle: | ||
| 3035 | idle(); | ||
| 3036 | // Don't process extra idle events that arrived in the event queue while we were doing this idle | ||
| 3037 | QCoreApplication::removePostedEvents(this, ApplicationEvent::Idle); | ||
| 3038 | return true; | ||
| 3039 | |||
| 2958 | case QEvent::MouseMove: | 3040 | case QEvent::MouseMove: |
| 2959 | mouseMoveEvent(static_cast<QMouseEvent*>(event)); | 3041 | mouseMoveEvent(static_cast<QMouseEvent*>(event)); |
| 2960 | return true; | 3042 | return true; |
| @@ -2995,26 +3077,15 @@ bool Application::event(QEvent* event) { · 34 unmodified lines | |||
| 2995 | case QEvent::Drop: | 3077 | case QEvent::Drop: |
| 2996 | dropEvent(static_cast<QDropEvent*>(event)); | 3078 | dropEvent(static_cast<QDropEvent*>(event)); |
| 2997 | return true; | 3079 | return true; |
| 2998 | default: | ||
| 2999 | break; | ||
| 3000 | } | ||
| 3001 | 3080 | ||
| 3002 | // handle custom URL | 3081 | case QEvent::FileOpen: |
| 3003 | if (event->type() == QEvent::FileOpen) { | 3082 | if (handleFileOpenEvent(static_cast<QFileOpenEvent*>(event))) { |
| 3004 | 3083 | return true; | |
| 3005 | QFileOpenEvent* fileEvent = static_cast<QFileOpenEvent*>(event); | ||
| 3006 | |||
| 3007 | QUrl url = fileEvent->url(); | ||
| 3008 | |||
| 3009 | if (!url.isEmpty()) { | ||
| 3010 | QString urlString = url.toString(); | ||
| 3011 | |||
| 3012 | if (canAcceptURL(urlString)) { | ||
| 3013 | |||
| 3014 | return acceptURL(urlString); | ||
| 3015 | } | 3084 | } |
| 3016 | } | 3085 | break; |
| 3017 | return false; | 3086 | |
| 3087 | default: | ||
| 3088 | break; | ||
| 3018 | } | 3089 | } |
| 3019 | 3090 | ||
| 3020 | if (HFActionEvent::types().contains(event->type())) { | 3091 | if (HFActionEvent::types().contains(event->type())) { |
| @@ -3719,11 +3790,12 @@ bool Application::acceptSnapshot(const QString& urlString) { · 698 unmodified lines | |||
| 3719 | 3790 | ||
| 3720 | static uint32_t _renderedFrameIndex { INVALID_FRAME }; | 3791 | static uint32_t _renderedFrameIndex { INVALID_FRAME }; |
| 3721 | 3792 | ||
| 3722 | bool Application::shouldPaint() { | 3793 | bool Application::shouldPaint() const { |
| 3723 | if (_aboutToQuit) { | 3794 | if (_aboutToQuit) { |
| 3724 | return false; | 3795 | return false; |
| 3725 | } | 3796 | } |
| 3726 | 3797 | ||
| 3798 | |||
| 3727 | auto displayPlugin = getActiveDisplayPlugin(); | 3799 | auto displayPlugin = getActiveDisplayPlugin(); |
| 3728 | 3800 | ||
| 3729 | #ifdef DEBUG_PAINT_DELAY | 3801 | #ifdef DEBUG_PAINT_DELAY |
| @@ -3739,15 +3811,14 @@ bool Application::shouldPaint() { · 9 unmodified lines | |||
| 3739 | (float)paintDelaySamples / paintDelayUsecs << "us"; | 3811 | (float)paintDelaySamples / paintDelayUsecs << "us"; |
| 3740 | } | 3812 | } |
| 3741 | #endif | 3813 | #endif |
| 3742 | 3814 | ||
| 3743 | // Throttle if requested | 3815 | // Throttle if requested |
| 3744 | if (displayPlugin->isThrottled() && (_lastTimeUpdated.elapsed() < THROTTLED_SIM_FRAME_PERIOD_MS)) { | 3816 | if (displayPlugin->isThrottled() && (_lastTimeRendered.elapsed() < THROTTLED_SIM_FRAME_PERIOD_MS)) { |
| 3745 | return false; | 3817 | return false; |
| 3746 | } | 3818 | } |
| 3747 | 3819 | ||
| 3748 | // Sync up the _renderedFrameIndex | 3820 | // Sync up the _renderedFrameIndex |
| 3749 | _renderedFrameIndex = displayPlugin->presentCount(); | 3821 | _renderedFrameIndex = displayPlugin->presentCount(); |
| 3750 | |||
| 3751 | return true; | 3822 | return true; |
| 3752 | } | 3823 | } |
| 3753 | 3824 | ||
| @@ -3957,7 +4028,6 @@ void setupCpuMonitorThread() { · 203 unmodified lines | |||
| 3957 | 4028 | ||
| 3958 | #endif | 4029 | #endif |
| 3959 | 4030 | ||
| 3960 | |||
| 3961 | void Application::idle() { | 4031 | void Application::idle() { |
| 3962 | PerformanceTimer perfTimer("idle"); | 4032 | PerformanceTimer perfTimer("idle"); |
| 3963 | 4033 | ||
| @@ -3988,9 +4058,17 @@ void Application::idle() { · 24 unmodified lines | |||
| 3988 | }); | 4058 | }); |
| 3989 | #endif | 4059 | #endif |
| 3990 | 4060 | ||
| 3991 | |||
| 3992 | |||
| 3993 | auto displayPlugin = getActiveDisplayPlugin(); | 4061 | auto displayPlugin = getActiveDisplayPlugin(); |
| 4062 | if (displayPlugin) { | ||
| 4063 | auto uiSize = displayPlugin->getRecommendedUiSize(); | ||
| 4064 | // Bit of a hack since there's no device pixel ratio change event I can find. | ||
| 4065 | if (offscreenUi->size() != fromGlm(uiSize)) { | ||
| 4066 | qCDebug(interfaceapp) << "Device pixel ratio changed, triggering resize to " << uiSize; | ||
| 4067 | offscreenUi->resize(fromGlm(uiSize), true); | ||
| 4068 | _offscreenContext->makeCurrent(); | ||
| 4069 | } | ||
| 4070 | } | ||
| 4071 | |||
| 3994 | if (displayPlugin) { | 4072 | if (displayPlugin) { |
| 3995 | PROFILE_COUNTER_IF_CHANGED(app, "present", float, displayPlugin->presentRate()); | 4073 | PROFILE_COUNTER_IF_CHANGED(app, "present", float, displayPlugin->presentRate()); |
| 3996 | } | 4074 | } |
| @@ -4038,6 +4116,10 @@ void Application::idle() { · 41 unmodified lines | |||
| 4038 | bool showWarnings = getLogger()->extraDebugging(); | 4116 | bool showWarnings = getLogger()->extraDebugging(); |
| 4039 | PerformanceWarning warn(showWarnings, "idle()"); | 4117 | PerformanceWarning warn(showWarnings, "idle()"); |
| 4040 | 4118 | ||
| 4119 | if (!_offscreenContext->makeCurrent()) { | ||
| 4120 | qFatal("Unable to make main thread context current"); | ||
| 4121 | } | ||
| 4122 | |||
| 4041 | { | 4123 | { |
| 4042 | PerformanceTimer perfTimer("update"); | 4124 | PerformanceTimer perfTimer("update"); |
| 4043 | PerformanceWarning warn(showWarnings, "Application::idle()... update()"); | 4125 | PerformanceWarning warn(showWarnings, "Application::idle()... update()"); |
| @@ -4100,6 +4182,13 @@ void Application::idle() { · 56 unmodified lines | |||
| 4100 | } | 4182 | } |
| 4101 | 4183 | ||
| 4102 | _overlayConductor.update(secondsSinceLastUpdate); | 4184 | _overlayConductor.update(secondsSinceLastUpdate); |
| 4185 | |||
| 4186 | auto myAvatar = getMyAvatar(); | ||
| 4187 | if (_myCamera.getMode() == CAMERA_MODE_FIRST_PERSON || _myCamera.getMode() == CAMERA_MODE_THIRD_PERSON) { | ||
| 4188 | Menu::getInstance()->setIsOptionChecked(MenuOption::FirstPerson, myAvatar->getBoomLength() <= MyAvatar::ZOOM_MIN); | ||
| 4189 | Menu::getInstance()->setIsOptionChecked(MenuOption::ThirdPerson, !(myAvatar->getBoomLength() <= MyAvatar::ZOOM_MIN)); | ||
| 4190 | cameraMenuChanged(); | ||
| 4191 | } | ||
| 4103 | } | 4192 | } |
| 4104 | 4193 | ||
| 4105 | ivec2 Application::getMouse() const { | 4194 | ivec2 Application::getMouse() const { |
| @@ -4354,7 +4443,6 @@ void Application::init() { · 248 unmodified lines | |||
| 4354 | _timerStart.start(); | 4443 | _timerStart.start(); |
| 4355 | _lastTimeUpdated.start(); | 4444 | _lastTimeUpdated.start(); |
| 4356 | 4445 | ||
| 4357 | |||
| 4358 | if (auto steamClient = PluginManager::getInstance()->getSteamClientPlugin()) { | 4446 | if (auto steamClient = PluginManager::getInstance()->getSteamClientPlugin()) { |
| 4359 | // when +connect_lobby in command line, join steam lobby | 4447 | // when +connect_lobby in command line, join steam lobby |
| 4360 | const QString STEAM_LOBBY_COMMAND_LINE_KEY = "+connect_lobby"; | 4448 | const QString STEAM_LOBBY_COMMAND_LINE_KEY = "+connect_lobby"; |
| @@ -4403,14 +4491,7 @@ void Application::init() { · 42 unmodified lines | |||
| 4403 | 4491 | ||
| 4404 | // Make sure any new sounds are loaded as soon as know about them. | 4492 | // Make sure any new sounds are loaded as soon as know about them. |
| 4405 | connect(tree.get(), &EntityTree::newCollisionSoundURL, this, [this](QUrl newURL, EntityItemID id) { | 4493 | connect(tree.get(), &EntityTree::newCollisionSoundURL, this, [this](QUrl newURL, EntityItemID id) { |
| 4406 | EntityTreePointer tree = getEntities()->getTree(); | 4494 | getEntities()->setCollisionSound(id, DependencyManager::get<SoundCache>()->getSound(newURL)); |
| 4407 | if (auto entity = tree->findEntityByEntityItemID(id)) { | ||
| 4408 | auto sound = DependencyManager::get<SoundCache>()->getSound(newURL); | ||
| 4409 | auto renderable = entity->getRenderableInterface(); | ||
| 4410 | if (renderable) { | ||
| 4411 | renderable->setCollisionSound(sound); | ||
| 4412 | } | ||
| 4413 | } | ||
| 4414 | }, Qt::QueuedConnection); | 4495 | }, Qt::QueuedConnection); |
| 4415 | connect(getMyAvatar().get(), &MyAvatar::newCollisionSoundURL, this, [this](QUrl newURL) { | 4496 | connect(getMyAvatar().get(), &MyAvatar::newCollisionSoundURL, this, [this](QUrl newURL) { |
| 4416 | if (auto avatar = getMyAvatar()) { | 4497 | if (auto avatar = getMyAvatar()) { |
| @@ -4721,9 +4802,12 @@ void Application::setKeyboardFocusEntity(EntityItemID entityItemID) { · 304 unmodified lines | |||
| 4721 | auto entityScriptingInterface = DependencyManager::get<EntityScriptingInterface>(); | 4802 | auto entityScriptingInterface = DependencyManager::get<EntityScriptingInterface>(); |
| 4722 | auto properties = entityScriptingInterface->getEntityProperties(entityItemID); | 4803 | auto properties = entityScriptingInterface->getEntityProperties(entityItemID); |
| 4723 | if (!properties.getLocked() && properties.getVisible()) { | 4804 | if (!properties.getLocked() && properties.getVisible()) { |
| 4724 | auto entity = getEntities()->getTree()->findEntityByID(entityItemID); | 4805 | |
| 4725 | if (entity && entity->wantsKeyboardFocus()) { | 4806 | auto entities = getEntities(); |
| 4726 | entity->setProxyWindow(_window->windowHandle()); | 4807 | auto entityId = _keyboardFocusedEntity.get(); |
| 4808 | if (entities->wantsKeyboardFocus(entityId)) { | ||
| 4809 | entities->setProxyWindow(entityId, _window->windowHandle()); | ||
| 4810 | auto entity = getEntities()->getEntity(entityId); | ||
| 4727 | if (_keyboardMouseDevice->isActive()) { | 4811 | if (_keyboardMouseDevice->isActive()) { |
| 4728 | _keyboardMouseDevice->pluginFocusOutEvent(); | 4812 | _keyboardMouseDevice->pluginFocusOutEvent(); |
| 4729 | } | 4813 | } |
| @@ -4999,7 +5083,7 @@ void Application::update(float deltaTime) { · 269 unmodified lines | |||
| 4999 | PerformanceTimer perfTimer("physics"); | 5083 | PerformanceTimer perfTimer("physics"); |
| 5000 | 5084 | ||
| 5001 | { | 5085 | { |
| 5002 | PROFILE_RANGE_EX(simulation_physics, "UpdateStats", 0xffffff00, (uint64_t)getActiveDisplayPlugin()->presentCount()); | 5086 | PROFILE_RANGE_EX(simulation_physics, "UpdateStates", 0xffffff00, (uint64_t)getActiveDisplayPlugin()->presentCount()); |
| 5003 | 5087 | ||
| 5004 | PerformanceTimer perfTimer("updateStates)"); | 5088 | PerformanceTimer perfTimer("updateStates)"); |
| 5005 | static VectorOfMotionStates motionStates; | 5089 | static VectorOfMotionStates motionStates; |
| @@ -5068,7 +5152,7 @@ void Application::update(float deltaTime) { · 62 unmodified lines | |||
| 5068 | 5152 | ||
| 5069 | // NOTE: the getEntities()->update() call below will wait for lock | 5153 | // NOTE: the getEntities()->update() call below will wait for lock |
| 5070 | // and will simulate entity motion (the EntityTree has been given an EntitySimulation). | 5154 | // and will simulate entity motion (the EntityTree has been given an EntitySimulation). |
| 5071 | getEntities()->update(); // update the models... | 5155 | getEntities()->update(true); // update the models... |
| 5072 | } | 5156 | } |
| 5073 | 5157 | ||
| 5074 | myAvatar->harvestResultsFromPhysicsSimulation(deltaTime); | 5158 | myAvatar->harvestResultsFromPhysicsSimulation(deltaTime); |
| @@ -5081,6 +5165,9 @@ void Application::update(float deltaTime) { · 6 unmodified lines | |||
| 5081 | _physicsEngine->dumpStatsIfNecessary(); | 5165 | _physicsEngine->dumpStatsIfNecessary(); |
| 5082 | } | 5166 | } |
| 5083 | } | 5167 | } |
| 5168 | } else { | ||
| 5169 | // update the rendering without any simulation | ||
| 5170 | getEntities()->update(false); | ||
| 5084 | } | 5171 | } |
| 5085 | 5172 | ||
| 5086 | // AvatarManager update | 5173 | // AvatarManager update |
| @@ -6256,7 +6343,11 @@ bool Application::askToReplaceDomainContent(const QString& url) { · 1169 unmodified lines | |||
| 6256 | octreeFilePacket->write(urlData); | 6343 | octreeFilePacket->write(urlData); |
| 6257 | limitedNodeList->sendPacket(std::move(octreeFilePacket), *octreeNode); | 6344 | limitedNodeList->sendPacket(std::move(octreeFilePacket), *octreeNode); |
| 6258 | }); | 6345 | }); |
| 6259 | DependencyManager::get<AddressManager>()->handleLookupString(DOMAIN_SPAWNING_POINT); | 6346 | auto addressManager = DependencyManager::get<AddressManager>(); |
| 6347 | addressManager->handleLookupString(DOMAIN_SPAWNING_POINT); | ||
| 6348 | QString newHomeAddress = addressManager->getHost() + DOMAIN_SPAWNING_POINT; | ||
| 6349 | qCDebug(interfaceapp) << "Setting new home bookmark to: " << newHomeAddress; | ||
| 6350 | DependencyManager::get<LocationBookmarks>()->setHomeLocationToAddress(newHomeAddress); | ||
| 6260 | methodDetails = "SuccessfulRequestToReplaceContent"; | 6351 | methodDetails = "SuccessfulRequestToReplaceContent"; |
| 6261 | } else { | 6352 | } else { |
| 6262 | methodDetails = "UserDeclinedToReplaceContent"; | 6353 | methodDetails = "UserDeclinedToReplaceContent"; |
| @@ -6269,7 +6360,7 @@ bool Application::askToReplaceDomainContent(const QString& url) { · 6 unmodified lines | |||
| 6269 | OffscreenUi::warning("Unable to replace content", "You do not have permissions to replace domain content", | 6360 | OffscreenUi::warning("Unable to replace content", "You do not have permissions to replace domain content", |
| 6270 | QMessageBox::Ok, QMessageBox::Ok); | 6361 | QMessageBox::Ok, QMessageBox::Ok); |
| 6271 | } | 6362 | } |
| 6272 | QJsonObject messageProperties = { | 6363 | QJsonObject messageProperties = { |
| 6273 | { "status", methodDetails }, | 6364 | { "status", methodDetails }, |
| 6274 | { "content_set_url", url } | 6365 | { "content_set_url", url } |
| 6275 | }; | 6366 | }; |
| @@ -6352,14 +6443,14 @@ void Application::showAssetServerWidget(QString filePath) { · 76 unmodified lines | |||
| 6352 | 6443 | ||
| 6353 | void Application::addAssetToWorldFromURL(QString url) { | 6444 | void Application::addAssetToWorldFromURL(QString url) { |
| 6354 | qInfo(interfaceapp) << "Download model and add to world from" << url; | 6445 | qInfo(interfaceapp) << "Download model and add to world from" << url; |
| 6355 | 6446 | ||
| 6356 | QString filename; | 6447 | QString filename; |
| 6357 | if (url.contains("filename")) { | 6448 | if (url.contains("filename")) { |
| 6358 | filename = url.section("filename=", 1, 1); // Filename is in "?filename=" parameter at end of URL. | 6449 | filename = url.section("filename=", 1, 1); // Filename is in "?filename=" parameter at end of URL. |
| 6359 | } | 6450 | } |
| 6360 | if (url.contains("vr.google.com/downloads")) { | 6451 | if (url.contains("vr.google.com/downloads")) { |
| 6361 | filename = url.section('/', -1); | 6452 | filename = url.section('/', -1); |
| 6362 | filename.remove(".zip?noDownload=false"); | 6453 | filename.remove(".zip"); |
| 6363 | } | 6454 | } |
| 6364 | 6455 | ||
| 6365 | if (!DependencyManager::get<NodeList>()->getThisNodeCanWriteAssets()) { | 6456 | if (!DependencyManager::get<NodeList>()->getThisNodeCanWriteAssets()) { |
| @@ -6389,7 +6480,7 @@ void Application::addAssetToWorldFromURLRequestFinished() { · 23 unmodified lines | |||
| 6389 | } | 6480 | } |
| 6390 | if (url.contains("vr.google.com/downloads")) { | 6481 | if (url.contains("vr.google.com/downloads")) { |
| 6391 | filename = url.section('/', -1); | 6482 | filename = url.section('/', -1); |
| 6392 | filename.remove(".zip?noDownload=false"); | 6483 | filename.remove(".zip"); |
| 6393 | isBlocks = true; | 6484 | isBlocks = true; |
| 6394 | } | 6485 | } |
| 6395 | 6486 | ||
| @@ -6406,6 +6497,7 @@ void Application::addAssetToWorldFromURLRequestFinished() { · 10 unmodified lines | |||
| 6406 | if (tempFile.open(QIODevice::WriteOnly)) { | 6497 | if (tempFile.open(QIODevice::WriteOnly)) { |
| 6407 | tempFile.write(request->getData()); | 6498 | tempFile.write(request->getData()); |
| 6408 | addAssetToWorldInfoClear(filename); // Remove message from list; next one added will have a different key. | 6499 | addAssetToWorldInfoClear(filename); // Remove message from list; next one added will have a different key. |
| 6500 | tempFile.close(); | ||
| 6409 | qApp->getFileDownloadInterface()->runUnzip(downloadPath, url, true, false, isBlocks); | 6501 | qApp->getFileDownloadInterface()->runUnzip(downloadPath, url, true, false, isBlocks); |
| 6410 | } else { | 6502 | } else { |
| 6411 | QString errorInfo = "Couldn't open temporary file for download"; | 6503 | QString errorInfo = "Couldn't open temporary file for download"; |
| @@ -7223,14 +7315,6 @@ void Application::updateDisplayMode() { · 811 unmodified lines | |||
| 7223 | qFatal("Attempted to switch display plugins from a non-main thread"); | 7315 | qFatal("Attempted to switch display plugins from a non-main thread"); |
| 7224 | } | 7316 | } |
| 7225 | 7317 | ||
| 7226 | // Some plugins *cough* Oculus *cough* process message events from inside their | ||
| 7227 | // display function, and we don't want to change the display plugin underneath | ||
| 7228 | // the paintGL call, so we need to guard against that | ||
| 7229 | // The current oculus runtime doesn't do this anymore | ||
| 7230 | if (_inPaint) { | ||
| 7231 | qFatal("Attempted to switch display plugins while in painting"); | ||
| 7232 | } | ||
| 7233 | |||
| 7234 | auto menu = Menu::getInstance(); | 7318 | auto menu = Menu::getInstance(); |
| 7235 | auto displayPlugins = PluginManager::getInstance()->getDisplayPlugins(); | 7319 | auto displayPlugins = PluginManager::getInstance()->getDisplayPlugins(); |
| 7236 | 7320 | ||
| @@ -7307,12 +7391,12 @@ void Application::updateDisplayMode() { · 70 unmodified lines | |||
| 7307 | bool wasRepositionLocked = offscreenUi->getDesktop()->property("repositionLocked").toBool(); | 7391 | bool wasRepositionLocked = offscreenUi->getDesktop()->property("repositionLocked").toBool(); |
| 7308 | offscreenUi->getDesktop()->setProperty("repositionLocked", true); | 7392 | offscreenUi->getDesktop()->setProperty("repositionLocked", true); |
| 7309 | 7393 | ||
| 7310 | auto oldDisplayPlugin = _displayPlugin; | ||
| 7311 | if (_displayPlugin) { | 7394 | if (_displayPlugin) { |
| 7312 | disconnect(_displayPluginPresentConnection); | 7395 | disconnect(_displayPlugin.get(), &DisplayPlugin::presented, this, &Application::onPresent); |
| 7313 | _displayPlugin->deactivate(); | 7396 | _displayPlugin->deactivate(); |
| 7314 | } | 7397 | } |
| 7315 | 7398 | ||
| 7399 | auto oldDisplayPlugin = _displayPlugin; | ||
| 7316 | bool active = newDisplayPlugin->activate(); | 7400 | bool active = newDisplayPlugin->activate(); |
| 7317 | 7401 | ||
| 7318 | if (!active) { | 7402 | if (!active) { |
| @@ -7350,7 +7434,7 @@ void Application::updateDisplayMode() { · 31 unmodified lines | |||
| 7350 | _offscreenContext->makeCurrent(); | 7434 | _offscreenContext->makeCurrent(); |
| 7351 | getApplicationCompositor().setDisplayPlugin(newDisplayPlugin); | 7435 | getApplicationCompositor().setDisplayPlugin(newDisplayPlugin); |
| 7352 | _displayPlugin = newDisplayPlugin; | 7436 | _displayPlugin = newDisplayPlugin; |
| 7353 | _displayPluginPresentConnection = connect(_displayPlugin.get(), &DisplayPlugin::presented, this, &Application::onPresent); | 7437 | connect(_displayPlugin.get(), &DisplayPlugin::presented, this, &Application::onPresent); |
| 7354 | offscreenUi->getDesktop()->setProperty("repositionLocked", wasRepositionLocked); | 7438 | offscreenUi->getDesktop()->setProperty("repositionLocked", wasRepositionLocked); |
| 7355 | } | 7439 | } |
| 7356 | 7440 | ||
| @@ -7602,3 +7686,5 @@ void Application::setAvatarOverrideUrl(const QUrl& url, bool save) { · 245 unmodified lines | |||
| 7602 | _avatarOverrideUrl = url; | 7686 | _avatarOverrideUrl = url; |
| 7603 | _saveAvatarOverrideUrl = save; | 7687 | _saveAvatarOverrideUrl = save; |
| 7604 | } | 7688 | } |
| 7689 | |||
| 7690 | #include "Application.moc" | ||