From a6a766785226c1330e87ac4eebb6bf945c535083 Mon Sep 17 00:00:00 2001 From: Lucas Hosseini Date: Fri, 12 May 2023 23:57:35 +0200 Subject: [PATCH] Keep scroll history in decompiler widget. (#3177) * Keep scroll history in decompiler widget. This commit adds a `scrollHistory` on top of the rizin-managed history, that keeps track of the scroll position within decompiled functions. * Fix clearing history upon init. --- src/widgets/DecompilerWidget.cpp | 35 +++++++++++++++++++------------- src/widgets/DecompilerWidget.h | 6 +++--- 2 files changed, 24 insertions(+), 17 deletions(-) diff --git a/src/widgets/DecompilerWidget.cpp b/src/widgets/DecompilerWidget.cpp index 9414f118..60586192 100644 --- a/src/widgets/DecompilerWidget.cpp +++ b/src/widgets/DecompilerWidget.cpp @@ -26,8 +26,7 @@ DecompilerWidget::DecompilerWidget(MainWindow *main) ui(new Ui::DecompilerWidget), decompilerBusy(false), seekFromCursor(false), - scrollerHorizontal(0), - scrollerVertical(0), + historyPos(0), previousFunctionAddr(RVA_INVALID), decompiledFunctionAddr(RVA_INVALID), code(Decompiler::makeWarning(tr("Choose an offset and refresh to get decompiled code")), @@ -311,13 +310,6 @@ QTextCursor DecompilerWidget::getCursorForAddress(RVA addr) void DecompilerWidget::decompilationFinished(RzAnnotatedCode *codeDecompiled) { - bool isDisplayReset = false; - if (previousFunctionAddr == decompiledFunctionAddr) { - scrollerHorizontal = ui->textEdit->horizontalScrollBar()->sliderPosition(); - scrollerVertical = ui->textEdit->verticalScrollBar()->sliderPosition(); - isDisplayReset = true; - } - ui->progressLabel->setVisible(false); ui->decompilerComboBox->setEnabled(decompilerSelectionEnabled); @@ -354,10 +346,8 @@ void DecompilerWidget::decompilationFinished(RzAnnotatedCode *codeDecompiled) } } - if (isDisplayReset) { - ui->textEdit->horizontalScrollBar()->setSliderPosition(scrollerHorizontal); - ui->textEdit->verticalScrollBar()->setSliderPosition(scrollerVertical); - } + ui->textEdit->horizontalScrollBar()->setSliderPosition(scrollHistory[historyPos].first); + ui->textEdit->verticalScrollBar()->setSliderPosition(scrollHistory[historyPos].second); } void DecompilerWidget::setAnnotationsAtCursor(size_t pos) @@ -416,11 +406,28 @@ void DecompilerWidget::cursorPositionChanged() updateSelection(); } -void DecompilerWidget::seekChanged() +void DecompilerWidget::seekChanged(RVA /* addr */, CutterCore::SeekHistoryType type) { if (seekFromCursor) { return; } + + if (!scrollHistory.empty()) { // History is empty upon init. + scrollHistory[historyPos] = { ui->textEdit->horizontalScrollBar()->sliderPosition(), + ui->textEdit->verticalScrollBar()->sliderPosition() }; + } + if (type == CutterCore::SeekHistoryType::New) { + // Erase previous history past this point. + if (scrollHistory.size() > historyPos + 1) { + scrollHistory.erase(scrollHistory.begin() + historyPos + 1, scrollHistory.end()); + } + scrollHistory.push_back({ 0, 0 }); + historyPos = scrollHistory.size() - 1; + } else if (type == CutterCore::SeekHistoryType::Undo) { + --historyPos; + } else if (type == CutterCore::SeekHistoryType::Redo) { + ++historyPos; + } RVA fcnAddr = Core()->getFunctionStart(seekable->getOffset()); if (fcnAddr == RVA_INVALID || fcnAddr != decompiledFunctionAddr) { doRefresh(); diff --git a/src/widgets/DecompilerWidget.h b/src/widgets/DecompilerWidget.h index 015525af..ed5c7f0c 100644 --- a/src/widgets/DecompilerWidget.h +++ b/src/widgets/DecompilerWidget.h @@ -53,7 +53,7 @@ private slots: * - Seek changed to an offset contained in the decompiled function. * - Auto-refresh is disabled. */ - void seekChanged(); + void seekChanged(RVA /* addr */, CutterCore::SeekHistoryType type); void decompilationFinished(RzAnnotatedCode *code); private: @@ -72,8 +72,8 @@ private: bool decompilerBusy; bool seekFromCursor; - int scrollerHorizontal; - int scrollerVertical; + int historyPos; + QVector> scrollHistory; RVA previousFunctionAddr; RVA decompiledFunctionAddr; std::unique_ptr code;