diff --git a/qrenderdoc/Code/CaptureContext.cpp b/qrenderdoc/Code/CaptureContext.cpp index b9f8b22c4..0149532be 100644 --- a/qrenderdoc/Code/CaptureContext.cpp +++ b/qrenderdoc/Code/CaptureContext.cpp @@ -1763,6 +1763,11 @@ void CaptureContext::RefreshUIStatus(const rdcarray &exclude, } } +void CaptureContext::InvokeOntoUIThread(std::function callback) +{ + GUIInvoke::call(GetMainWindow()->Widget(), callback); +} + void CaptureContext::AddMessages(const rdcarray &msgs) { m_UnreadMessageCount += msgs.count(); diff --git a/qrenderdoc/Code/CaptureContext.h b/qrenderdoc/Code/CaptureContext.h index 41e4a529e..8424dbe37 100644 --- a/qrenderdoc/Code/CaptureContext.h +++ b/qrenderdoc/Code/CaptureContext.h @@ -147,6 +147,8 @@ public: ////////////////////////////////////////////////////////////////////////////// // Accessors + void InvokeOntoUIThread(std::function callback) override; + IReplayManager &Replay() override { return m_Replay; } IExtensionManager &Extensions() override { return *this; } bool IsCaptureLoaded() override { return m_CaptureLoaded; } diff --git a/qrenderdoc/Code/Interface/QRDInterface.h b/qrenderdoc/Code/Interface/QRDInterface.h index f536ac27a..b68263098 100644 --- a/qrenderdoc/Code/Interface/QRDInterface.h +++ b/qrenderdoc/Code/Interface/QRDInterface.h @@ -2885,6 +2885,21 @@ by calling :meth:`EmbedDependentFiles`. )"); virtual void RemoveDependentFiles() = 0; + DOCUMENT(R"(Invoke a callback on the UI thread. All widget accesses must come from the UI thread, +so if work has been done on the render thread then this function can be used to asynchronously and +safely go back to the UI thread. + +This function is safe to call on the UI thread, but it will synchronously call the callback +immediately before returning. + +.. note:: + No parameters are provided to the callback, it is assumed that the callback will maintain its own + context as needed. + +:param Callable[[], None] callback: The callback to invoke on the UI thread. +)"); + virtual void InvokeOntoUIThread(std::function callback) = 0; + DOCUMENT(R"(Registers a delayed callback to be called after a certain number of milliseconds on the UI thread. diff --git a/qrenderdoc/Code/pyrenderdoc/PythonInvokers.cpp b/qrenderdoc/Code/pyrenderdoc/PythonInvokers.cpp index 9b4e3a985..3ca1d4f33 100644 --- a/qrenderdoc/Code/pyrenderdoc/PythonInvokers.cpp +++ b/qrenderdoc/Code/pyrenderdoc/PythonInvokers.cpp @@ -1340,6 +1340,10 @@ struct CaptureContextInvoker : UIThreadInvoker // pass-through functions that don't need the UI thread /////////////////////////////////////////////////////////////////////// // + virtual void InvokeOntoUIThread(std::function callback) override + { + return m_Obj.InvokeOntoUIThread(callback); + } virtual rdcstr TempCaptureFilename(const rdcstr &appname) override { return m_Obj.TempCaptureFilename(appname);