diff --git a/qrenderdoc/Code/Interface/QRDInterface.h b/qrenderdoc/Code/Interface/QRDInterface.h index 8810d6298..0b1869c6f 100644 --- a/qrenderdoc/Code/Interface/QRDInterface.h +++ b/qrenderdoc/Code/Interface/QRDInterface.h @@ -125,11 +125,23 @@ will be invoked, if it exists. :param QWidget widget: A handle to the widget to use as the context for this shortcut, or ``None`` for a global shortcut. Note that if an existing global shortcut exists the new one will not be registered. -:rtype: ``str`` )"); virtual void RegisterShortcut(const QString &shortcut, QWidget *widget, ShortcutCallback callback) = 0; + DOCUMENT(R"(Unregister a callback for a particular key shortcut, made in a previous call to +:meth:`RegisterShortcut`. + +See the documentation for :meth:`RegisterShortcut` for what these shortcuts are for. + +:param str shortcut: The text string representing the shortcut, e.g. 'Ctrl+S'. To unregister all + shortcuts for a particular widget, you can pass an empty string here. In this case, + :param:`widget` must not be ``None``. +:param QWidget widget: A handle to the widget used as the context for the shortcut, or ``None`` + if referring to a global shortcut. +)"); + virtual void UnregisterShortcut(const QString &shortcut, QWidget *widget) = 0; + protected: IMainWindow() = default; ~IMainWindow() = default; diff --git a/qrenderdoc/Windows/EventBrowser.cpp b/qrenderdoc/Windows/EventBrowser.cpp index fca27b095..f295fb5ec 100644 --- a/qrenderdoc/Windows/EventBrowser.cpp +++ b/qrenderdoc/Windows/EventBrowser.cpp @@ -165,6 +165,26 @@ EventBrowser::EventBrowser(ICaptureContext &ctx, QWidget *parent) EventBrowser::~EventBrowser() { + // unregister any shortcuts we registered + Qt::Key keys[] = { + Qt::Key_1, Qt::Key_2, Qt::Key_3, Qt::Key_4, Qt::Key_5, + Qt::Key_6, Qt::Key_7, Qt::Key_8, Qt::Key_9, Qt::Key_0, + }; + for(int i = 0; i < 10; i++) + { + m_Ctx.GetMainWindow()->UnregisterShortcut( + QKeySequence(keys[i] | Qt::ControlModifier).toString(), NULL); + } + + m_Ctx.GetMainWindow()->UnregisterShortcut( + QKeySequence(Qt::Key_Left | Qt::ControlModifier).toString(), NULL); + + m_Ctx.GetMainWindow()->UnregisterShortcut( + QKeySequence(Qt::Key_Right | Qt::ControlModifier).toString(), NULL); + + m_Ctx.GetMainWindow()->UnregisterShortcut(QString(), ui->findStrip); + m_Ctx.GetMainWindow()->UnregisterShortcut(QString(), ui->jumpStrip); + m_Ctx.BuiltinWindowClosed(this); m_Ctx.RemoveCaptureViewer(this); delete ui; diff --git a/qrenderdoc/Windows/MainWindow.cpp b/qrenderdoc/Windows/MainWindow.cpp index 5bbc1eef7..dc9686509 100644 --- a/qrenderdoc/Windows/MainWindow.cpp +++ b/qrenderdoc/Windows/MainWindow.cpp @@ -249,6 +249,12 @@ MainWindow::MainWindow(ICaptureContext &ctx) : QMainWindow(NULL), ui(new Ui::Mai MainWindow::~MainWindow() { + // explicitly delete our children here, so that the MainWindow is still alive while they are + // closing. + + setUpdatesEnabled(false); + qDeleteAll(findChildren(QString(), Qt::FindDirectChildrenOnly)); + m_RemoteProbeSemaphore.acquire(); m_RemoteProbe->wait(); m_RemoteProbe->deleteLater(); @@ -1376,6 +1382,31 @@ void MainWindow::RegisterShortcut(const QString &shortcut, QWidget *widget, Shor } } +void MainWindow::UnregisterShortcut(const QString &shortcut, QWidget *widget) +{ + if(widget) + { + if(shortcut.isEmpty()) + { + // if no shortcut is specified, remove all shortcuts for this widget + for(QMap &sh : m_WidgetShortcutCallbacks) + sh.remove(widget); + } + else + { + QKeySequence ks = QKeySequence::fromString(shortcut); + + m_WidgetShortcutCallbacks[ks].remove(widget); + } + } + else + { + QKeySequence ks = QKeySequence::fromString(shortcut); + + m_GlobalShortcutCallbacks.remove(ks); + } +} + bool MainWindow::eventFilter(QObject *watched, QEvent *event) { if(event->type() == QEvent::ShortcutOverride) diff --git a/qrenderdoc/Windows/MainWindow.h b/qrenderdoc/Windows/MainWindow.h index 03c8f8394..6e1e65f43 100644 --- a/qrenderdoc/Windows/MainWindow.h +++ b/qrenderdoc/Windows/MainWindow.h @@ -53,6 +53,7 @@ public: // IMainWindow QWidget *Widget() override { return this; } void RegisterShortcut(const QString &shortcut, QWidget *widget, ShortcutCallback callback) override; + void UnregisterShortcut(const QString &shortcut, QWidget *widget) override; // ICaptureViewer void OnCaptureLoaded() override; void OnCaptureClosed() override; diff --git a/qrenderdoc/Windows/ShaderViewer.cpp b/qrenderdoc/Windows/ShaderViewer.cpp index 7d6f854ad..937525cde 100644 --- a/qrenderdoc/Windows/ShaderViewer.cpp +++ b/qrenderdoc/Windows/ShaderViewer.cpp @@ -585,6 +585,9 @@ ShaderViewer::~ShaderViewer() // don't want to async invoke while using 'this', so save the trace separately ShaderDebugTrace *trace = m_Trace; + // unregister any shortcuts on this window + m_Ctx.GetMainWindow()->UnregisterShortcut(QString(), this); + m_Ctx.Replay().AsyncInvoke([trace](IReplayController *r) { r->FreeTrace(trace); }); if(m_CloseCallback)