Add option to launch/wait for debugger on python contexts

This commit is contained in:
baldurk
2026-08-13 17:46:40 +01:00
parent 3dfd829331
commit 3ff393c91f
13 changed files with 315 additions and 12 deletions
@@ -29,6 +29,7 @@
#include <QRegularExpression>
#include "Code/Interface/QRDInterface.h"
#include "Code/Resources.h"
#include "Code/pyrenderdoc/PythonContext.h"
#include "Widgets/Extended/RDHeaderView.h"
#include "Windows/MainWindow.h"
#include "ui_ExtensionManager.h"
@@ -54,6 +55,7 @@ ExtensionManager::ExtensionManager(ICaptureContext &ctx)
ui->author->setText(lit("---"));
ui->URL->setText(lit("---"));
ui->reload->setEnabled(false);
ui->debug->setEnabled(false);
ui->alwaysLoad->setEnabled(false);
QObject::connect(ui->buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept);
@@ -128,6 +130,38 @@ void ExtensionManager::on_reload_clicked()
}
}
void ExtensionManager::on_debug_clicked()
{
if(m_Extensions.empty())
return;
RDTreeWidgetItem *item = ui->extensions->currentItem();
if(!item)
return;
int idx = ui->extensions->indexOfTopLevelItem(item);
if(idx >= 0 && idx < m_Extensions.count())
{
const ExtensionMetadata &e = m_Extensions[idx];
if(!e.name.isEmpty())
{
PythonContext::PrepareDebuggerWait();
LambdaThread *thread = new LambdaThread([this]() {
PythonContext::WaitForDebugger();
GUIInvoke::call(this, [this]() { on_reload_clicked(); });
});
thread->selfDelete(true);
thread->start();
PythonContext::LaunchDebugger(this, m_Ctx.Config(), QFileInfo(e.filePath).absoluteFilePath());
}
}
}
void ExtensionManager::on_openLocation_clicked()
{
if(m_Extensions.empty())
@@ -239,6 +273,7 @@ void ExtensionManager::update_currentItem(RDTreeWidgetItem *item)
bool loaded = item->checkState(2) == Qt::Checked;
ui->reload->setEnabled(true);
ui->debug->setEnabled(true);
ui->reload->setText(loaded ? tr("Reload") : tr("Load"));
ui->alwaysLoad->setEnabled(loaded);
@@ -49,6 +49,7 @@ public:
private slots:
// automatic slots
void on_reload_clicked();
void on_debug_clicked();
void on_openLocation_clicked();
void on_alwaysLoad_toggled(bool checked);
void on_extensions_currentItemChanged(RDTreeWidgetItem *item, RDTreeWidgetItem *);
+22 -2
View File
@@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>556</width>
<height>544</height>
<height>572</height>
</rect>
</property>
<property name="minimumSize">
@@ -191,10 +191,23 @@
</spacer>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_2">
<layout class="QHBoxLayout" name="extensionButtonsLayout">
<property name="leftMargin">
<number>0</number>
</property>
<item>
<spacer name="horizontalSpacer2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="openLocation">
<property name="text">
@@ -209,6 +222,13 @@
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="debug">
<property name="text">
<string>Debug</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="alwaysLoad">
<property name="text">
@@ -308,6 +308,7 @@ SettingsDialog::SettingsDialog(ICaptureContext &ctx, QWidget *parent)
ui->EventBrowser_ColorEventRow->setChecked(m_Ctx.Config().EventBrowser_ColorEventRow);
ui->Python_DebugEnabled->setChecked(m_Ctx.Config().Python_DebugEnabled);
ui->Python_LaunchVSCode->setChecked(m_Ctx.Config().Python_LaunchVSCode);
ui->Python_DebugPyDir->setText(m_Ctx.Config().Python_DebugPyDir);
@@ -878,6 +879,13 @@ void SettingsDialog::on_Python_DebugEnabled_toggled(bool checked)
m_Ctx.Config().Save();
}
void SettingsDialog::on_Python_LaunchVSCode_toggled(bool checked)
{
m_Ctx.Config().Python_LaunchVSCode = ui->Python_LaunchVSCode->isChecked();
m_Ctx.Config().Save();
}
// texture viewer
void SettingsDialog::on_TextureViewer_PerTexSettings_toggled(bool checked)
{
@@ -86,6 +86,7 @@ private slots:
void on_Python_DebugPyDirBrowse_clicked();
void on_Python_DebugPyDir_textEdited(const QString &dir);
void on_Python_DebugEnabled_toggled(bool checked);
void on_Python_LaunchVSCode_toggled(bool checked);
// texture viewer
void on_TextureViewer_PerTexSettings_toggled(bool checked);
+20 -1
View File
@@ -751,7 +751,26 @@ After interop is enabled you will need to reload any capture.</string>
</property>
</widget>
</item>
<item row="4" column="0" colspan="2">
<item row="4" column="0">
<widget class="QLabel" name="Python_LaunchVSCodeLabel">
<property name="text">
<string>Launch VS Code for debugging</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QCheckBox" name="Python_LaunchVSCode">
<property name="toolTip">
<string>When debugging a python script or UI extension, launch new instance of VS Code.
If disabled, debugging will do nothing and wait for a debugger connection.</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="5" column="0" colspan="2">
<spacer name="verticalSpacer_9">
<property name="orientation">
<enum>Qt::Vertical</enum>
+20 -3
View File
@@ -1059,7 +1059,7 @@ rdcstr PythonShell::GetScriptText()
return scriptEditor->getText(scriptEditor->textLength() + 1).data();
}
void PythonShell::RunScript()
void PythonShell::runScript(bool debugging)
{
PythonContext *context = newContext();
@@ -1073,11 +1073,14 @@ void PythonShell::RunScript()
enableButtons(false);
LambdaThread *thread = new LambdaThread([this, script, context]() {
if(debugging)
PythonContext::PrepareDebuggerWait();
LambdaThread *thread = new LambdaThread([this, debugging, script, context]() {
PythonContext::AddDebuggableThread();
scriptContext = context;
context->executeString(lit("script.py"), script);
context->executeString(lit("script.py"), script, debugging);
scriptContext = NULL;
GUIInvoke::call(this, [this, context]() {
@@ -1091,6 +1094,9 @@ void PythonShell::RunScript()
thread->setName(lit("Python script"));
thread->selfDelete(true);
thread->start();
if(debugging)
PythonContext::LaunchDebugger(this, m_Ctx.Config(), QString());
}
void PythonShell::on_execute_clicked()
@@ -1200,6 +1206,11 @@ void PythonShell::on_runScript_clicked()
RunScript();
}
void PythonShell::on_debugScript_clicked()
{
DebugScript();
}
void PythonShell::on_abortRun_clicked()
{
if(scriptContext)
@@ -1528,6 +1539,12 @@ void PythonShell::enableButtons(bool enable)
ui->saveScript->setEnabled(enable);
ui->runScript->setEnabled(enable);
ui->abortRun->setEnabled(!enable);
ui->debugScript->setEnabled(enable);
if(enable && !m_Ctx.Config().Python_DebugEnabled)
{
ui->debugScript->setEnabled(false);
}
}
void PythonShell::startAutocomplete()
+5 -1
View File
@@ -55,7 +55,8 @@ public:
void SetScriptText(rdcstr script) override;
bool LoadScriptFromFilename(rdcstr filename) override;
rdcstr GetScriptText() override;
void RunScript() override;
void RunScript() override { runScript(false); }
void DebugScript() override { runScript(true); }
private slots:
// automatic slots
void on_execute_clicked();
@@ -64,6 +65,7 @@ private slots:
void on_openScript_clicked();
void on_saveScript_clicked();
void on_runScript_clicked();
void on_debugScript_clicked();
void on_abortRun_clicked();
// manual slots
@@ -96,6 +98,8 @@ private:
PythonContext *newImportedDummyContext();
void setGlobals(PythonContext *ret);
void runScript(bool debugging);
void startAutocomplete();
void selectedHelp(QString word);
void refreshCurrentHelp();
+20
View File
@@ -236,6 +236,26 @@
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="debugScript">
<property name="toolTip">
<string>Begin running the script in python</string>
</property>
<property name="text">
<string>Debug</string>
</property>
<property name="icon">
<iconset resource="../Resources/resources.qrc">
<normaloff>:/wrench.png</normaloff>:/wrench.png</iconset>
</property>
<property name="toolButtonStyle">
<enum>Qt::ToolButtonTextBesideIcon</enum>
</property>
<property name="autoRaise">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="abortRun">
<property name="toolTip">