diff --git a/python/GafferUITest/ContextTrackerTest.py b/python/GafferUITest/ContextTrackerTest.py index 2b13e308f1..37e3009964 100644 --- a/python/GafferUITest/ContextTrackerTest.py +++ b/python/GafferUITest/ContextTrackerTest.py @@ -711,6 +711,7 @@ def testAcquireForFocus( self ) : self.assertTrue( tracker.isActive( script["add2" ] ) ) script.setFocus( None ) + self.waitForIdle() self.assertFalse( tracker.isActive( script["add1" ] ) ) self.assertFalse( tracker.isActive( script["add2" ] ) ) diff --git a/src/GafferUI/ContextTracker.cpp b/src/GafferUI/ContextTracker.cpp index 86319c7701..e695584427 100644 --- a/src/GafferUI/ContextTracker.cpp +++ b/src/GafferUI/ContextTracker.cpp @@ -214,17 +214,6 @@ void ContextTracker::scheduleUpdate() // Cancel old update. m_updateTask.reset(); - if( !m_node || !m_node->scriptNode() ) - { - // Don't need or can't use a BackgroundTask (the latter case being when - // a ScriptNode is being destroyed). Just do the update directly on the - // UI thread. - m_nodeContexts.clear(); - m_plugContexts.clear(); - changedSignal()( *this ); - return; - } - // Arrange to do the update on the next idle event. This allows us to avoid // redundant restarts when `plugDirtied()` or `contextChanged()` is called // multiple times in quick succession. @@ -255,10 +244,21 @@ void ContextTracker::updateInBackground() } } + if( toVisit.empty() || !m_node->scriptNode() ) + { + // Don't need or can't use a BackgroundTask (the latter case being when + // a ScriptNode is being destroyed). Just do the update directly on the + // UI thread. + m_nodeContexts.clear(); + m_plugContexts.clear(); + changedSignal()( *this ); + return; + } + Context::Scope scopedContext( contextCopy.get() ); m_updateTask = ParallelAlgo::callOnBackgroundThread( - /* subject = */ toVisit.empty() ? nullptr : toVisit.back().first, + /* subject = */ toVisit.back().first, // OK to capture `this` without incrementing reference count, because // ~UpstreamContext cancels background task and waits for it to