Skip to content

Commit

Permalink
fix(gui): save current caret position and add it to tab code jump eve…
Browse files Browse the repository at this point in the history
…nt (#2409)
  • Loading branch information
skylot committed Feb 12, 2025
1 parent bf58f03 commit 8873038
Show file tree
Hide file tree
Showing 8 changed files with 62 additions and 39 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -429,8 +429,12 @@ private void highlightAllMatches(@Nullable String str) {
SearchEngine.markAll(this, context);
}

public JumpPosition getCurrentPosition() {
return new JumpPosition(node, getCaretPosition());
public @Nullable JumpPosition getCurrentPosition() {
int pos = getCaretPosition();
if (pos == 0) {
return null;
}
return new JumpPosition(node, pos);
}

public int getLineStartFor(int pos) throws BadLocationException {
Expand Down
19 changes: 18 additions & 1 deletion jadx-gui/src/main/java/jadx/gui/ui/tab/ITabStatesListener.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,35 @@

import java.util.List;

import org.jetbrains.annotations.Nullable;

import jadx.gui.ui.codearea.EditorViewState;
import jadx.gui.utils.JumpPosition;

/**
* Tabbed pane events listener
*/
public interface ITabStatesListener {

/**
* Tab added to tabbed pane without become active (selected)
*/
default void onTabOpen(TabBlueprint blueprint) {
}

/**
* Tab become active (selected)
*/
default void onTabSelect(TabBlueprint blueprint) {
}

default void onTabCodeJump(TabBlueprint blueprint, JumpPosition position) {
/**
* Caret position changes.
*
* @param prevPos previous caret position; can be null if unknown; can be from another tab
* @param newPos new caret position, node refer to jump target node
*/
default void onTabCodeJump(TabBlueprint blueprint, @Nullable JumpPosition prevPos, JumpPosition newPos) {
}

default void onTabSmaliJump(TabBlueprint blueprint, int pos, boolean debugMode) {
Expand Down
5 changes: 3 additions & 2 deletions jadx-gui/src/main/java/jadx/gui/ui/tab/LogTabStates.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import java.util.List;

import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand All @@ -25,8 +26,8 @@ public void onTabClose(TabBlueprint blueprint) {
}

@Override
public void onTabCodeJump(TabBlueprint blueprint, JumpPosition position) {
LOG.debug("onTabCodeJump: blueprint={}, position={}", blueprint, position);
public void onTabCodeJump(TabBlueprint blueprint, @Nullable JumpPosition prevPos, JumpPosition newPos) {
LOG.debug("onTabCodeJump: blueprint={}, prevPos={}, newPos={}", blueprint, prevPos, newPos);
}

@Override
Expand Down
22 changes: 4 additions & 18 deletions jadx-gui/src/main/java/jadx/gui/ui/tab/NavigationController.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,10 @@ public NavigationController(MainWindow mainWindow) {
}

public void navBack() {
if (jumps.size() > 1) {
jumps.updateCurPosition(mainWindow.getTabbedPane().getCurrentPosition());
}
jump(jumps.getPrev());
}

public void navForward() {
if (jumps.size() > 1) {
jumps.updateCurPosition(mainWindow.getTabbedPane().getCurrentPosition());
}
jump(jumps.getNext());
}

Expand All @@ -40,28 +34,20 @@ private void jump(@Nullable JumpPosition pos) {
}

@Override
public void onTabCodeJump(TabBlueprint blueprint, JumpPosition position) {
if (position.equals(jumps.getCurrent())) {
public void onTabCodeJump(TabBlueprint blueprint, @Nullable JumpPosition prevPos, JumpPosition newPos) {
if (newPos.equals(jumps.getCurrent())) {
// ignore self-initiated jumps
return;
}
saveCurrentPosition();
jumps.addPosition(position);
jumps.addPosition(prevPos);
jumps.addPosition(newPos);
}

@Override
public void onTabSmaliJump(TabBlueprint blueprint, int pos, boolean debugMode) {
saveCurrentPosition();
// TODO: save smali jump
}

private void saveCurrentPosition() {
JumpPosition curPos = mainWindow.getTabbedPane().getCurrentPosition();
if (curPos != null) {
jumps.addPosition(curPos);
}
}

public void reset() {
jumps.reset();
}
Expand Down
6 changes: 3 additions & 3 deletions jadx-gui/src/main/java/jadx/gui/ui/tab/TabbedPane.java
Original file line number Diff line number Diff line change
Expand Up @@ -211,8 +211,8 @@ public TabsController getTabsController() {
private @Nullable ContentPanel showCode(JumpPosition jumpPos) {
ContentPanel contentPanel = getContentPanel(jumpPos.getNode());
if (contentPanel != null) {
scrollToPos(contentPanel, jumpPos.getPos());
selectTab(contentPanel);
scrollToPos(contentPanel, jumpPos.getPos());
}
return contentPanel;
}
Expand All @@ -224,8 +224,8 @@ private void scrollToPos(ContentPanel contentPanel, int pos) {
}
if (contentPanel instanceof AbstractCodeContentPanel) {
AbstractCodeArea codeArea = ((AbstractCodeContentPanel) contentPanel).getCodeArea();
codeArea.scrollToPos(pos);
codeArea.requestFocus();
codeArea.scrollToPos(pos);
}
}

Expand Down Expand Up @@ -414,7 +414,7 @@ public void onTabSelect(TabBlueprint blueprint) {
}

@Override
public void onTabCodeJump(TabBlueprint blueprint, JumpPosition position) {
public void onTabCodeJump(TabBlueprint blueprint, @Nullable JumpPosition prevPos, JumpPosition position) {
showCode(position);
}

Expand Down
8 changes: 7 additions & 1 deletion jadx-gui/src/main/java/jadx/gui/ui/tab/TabsController.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ public class TabsController {

public TabsController(MainWindow mainWindow) {
this.mainWindow = mainWindow;
// addListener(new LogTabStates());
}

public MainWindow getMainWindow() {
Expand Down Expand Up @@ -76,6 +77,10 @@ public TabBlueprint openTab(JNode node, boolean hidden) {
}

public void selectTab(JNode node) {
if (selectedTab != null && selectedTab.getNode() == node) {
// already selected
return;
}
TabBlueprint blueprint = openTab(node);
selectedTab = blueprint;
listeners.forEach(l -> l.onTabSelect(blueprint));
Expand Down Expand Up @@ -141,10 +146,11 @@ private void jumpToInnerClass(JNode node, JavaClass codeParent, JClass jumpCls)
* Prefer {@link TabsController#codeJump(JNode)} method
*/
public void codeJump(JumpPosition pos) {
JumpPosition currentPosition = mainWindow.getTabbedPane().getCurrentPosition();
if (selectedTab == null || selectedTab.getNode() != pos.getNode()) {
selectTab(pos.getNode());
}
listeners.forEach(l -> l.onTabCodeJump(selectedTab, pos));
listeners.forEach(l -> l.onTabCodeJump(selectedTab, currentPosition, pos));
}

public void smaliJump(JClass cls, int pos, boolean debugMode) {
Expand Down
31 changes: 20 additions & 11 deletions jadx-gui/src/main/java/jadx/gui/utils/JumpManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,31 +6,40 @@
import org.jetbrains.annotations.Nullable;

public class JumpManager {
/**
* Maximum number of elements to store in a jump list
*/
private static final int MAX_JUMPS = 100;

private final List<JumpPosition> list = new ArrayList<>();
/**
* This number of elements will be removed from the start if a list becomes bigger than MAX_JUMPS.
* List grow most of the time, so removing should be done in big batches to not run very often.
* Because of this, an effective jump history size will vary
* from (MAX_JUMPS - LIST_SHRINK_COUNT) to MAX_JUMPS over time.
*/
private static final int LIST_SHRINK_COUNT = 50;

private final List<JumpPosition> list = new ArrayList<>(MAX_JUMPS);
private int currentPos = 0;

public void addPosition(JumpPosition pos) {
if (ignoreJump(pos)) {
public void addPosition(@Nullable JumpPosition pos) {
if (pos == null || ignoreJump(pos)) {
return;
}
currentPos++;
if (currentPos >= list.size()) {
list.add(pos);
if (list.size() >= MAX_JUMPS) {
list.subList(0, LIST_SHRINK_COUNT).clear();
}
currentPos = list.size() - 1;
} else {
// discard forward history after navigating back and jumping to a new place
list.set(currentPos, pos);
int size = list.size();
for (int i = currentPos + 1; i < size; i++) {
list.set(i, null);
}
list.subList(currentPos + 1, list.size()).clear();
}
}

public void updateCurPosition(JumpPosition pos) {
list.set(currentPos, pos);
}

public int size() {
return list.size();
}
Expand Down
2 changes: 1 addition & 1 deletion jadx-gui/src/main/java/jadx/gui/utils/JumpPosition.java
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,6 @@ public int hashCode() {

@Override
public String toString() {
return "Jump: " + node + " : " + pos;
return "Jump{" + node + ":" + pos + '}';
}
}

0 comments on commit 8873038

Please sign in to comment.