fix(gui): preserve main window maximized state (PR #626)
This commit is contained in:
@@ -2,7 +2,6 @@ package jadx.core.dex.attributes;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.EnumSet;
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.List;
|
||||
|
||||
@@ -32,7 +32,6 @@ import jadx.core.dex.nodes.parser.AnnotationsParser;
|
||||
import jadx.core.dex.nodes.parser.FieldInitAttr;
|
||||
import jadx.core.dex.nodes.parser.SignatureParser;
|
||||
import jadx.core.dex.nodes.parser.StaticValuesParser;
|
||||
import jadx.core.utils.RegionUtils;
|
||||
import jadx.core.utils.exceptions.DecodeException;
|
||||
import jadx.core.utils.exceptions.JadxRuntimeException;
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package jadx.core.dex.visitors.regions.variables;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
|
||||
@@ -2,7 +2,6 @@ package jadx.tests.integration.inner;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import jadx.NotYetImplemented;
|
||||
import jadx.core.dex.nodes.ClassNode;
|
||||
import jadx.tests.api.IntegrationTest;
|
||||
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
package jadx.gui.settings;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.Font;
|
||||
import java.awt.GraphicsDevice;
|
||||
import java.awt.GraphicsEnvironment;
|
||||
import java.awt.Window;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
@@ -12,6 +15,8 @@ import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import javax.swing.JFrame;
|
||||
|
||||
import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.slf4j.Logger;
|
||||
@@ -19,6 +24,7 @@ import org.slf4j.LoggerFactory;
|
||||
|
||||
import jadx.api.JadxArgs;
|
||||
import jadx.cli.JadxCLIArgs;
|
||||
import jadx.gui.ui.MainWindow;
|
||||
import jadx.gui.ui.codearea.EditorTheme;
|
||||
import jadx.gui.utils.FontUtils;
|
||||
import jadx.gui.utils.LangLocale;
|
||||
@@ -51,9 +57,10 @@ public class JadxSettings extends JadxCLIArgs {
|
||||
|
||||
private boolean showHeapUsageBar = true;
|
||||
|
||||
private int settingsVersion = 0;
|
||||
|
||||
private Map<String, WindowLocation> windowPos = new HashMap<>();
|
||||
private int mainWindowExtendedState = JFrame.NORMAL;
|
||||
|
||||
private int settingsVersion = 0;
|
||||
|
||||
public static JadxSettings makeDefault() {
|
||||
JadxSettings jadxSettings = new JadxSettings();
|
||||
@@ -92,7 +99,7 @@ public class JadxSettings extends JadxCLIArgs {
|
||||
|
||||
public void setLastOpenFilePath(Path lastOpenFilePath) {
|
||||
this.lastOpenFilePath = lastOpenFilePath;
|
||||
partialSync(settings -> settings.lastOpenFilePath = JadxSettings.this.lastOpenFilePath);
|
||||
partialSync(settings -> settings.lastOpenFilePath = lastOpenFilePath);
|
||||
}
|
||||
|
||||
public Path getLastSaveProjectPath() {
|
||||
@@ -105,12 +112,12 @@ public class JadxSettings extends JadxCLIArgs {
|
||||
|
||||
public void setLastSaveProjectPath(Path lastSaveProjectPath) {
|
||||
this.lastSaveProjectPath = lastSaveProjectPath;
|
||||
partialSync(settings -> settings.lastSaveProjectPath = JadxSettings.this.lastSaveProjectPath);
|
||||
partialSync(settings -> settings.lastSaveProjectPath = lastSaveProjectPath);
|
||||
}
|
||||
|
||||
public void setLastSaveFilePath(Path lastSaveFilePath) {
|
||||
this.lastSaveFilePath = lastSaveFilePath;
|
||||
partialSync(settings -> settings.lastSaveFilePath = JadxSettings.this.lastSaveFilePath);
|
||||
partialSync(settings -> settings.lastSaveFilePath = lastSaveFilePath);
|
||||
}
|
||||
|
||||
public boolean isFlattenPackage() {
|
||||
@@ -119,7 +126,7 @@ public class JadxSettings extends JadxCLIArgs {
|
||||
|
||||
public void setFlattenPackage(boolean flattenPackage) {
|
||||
this.flattenPackage = flattenPackage;
|
||||
partialSync(settings -> settings.flattenPackage = JadxSettings.this.flattenPackage);
|
||||
partialSync(settings -> settings.flattenPackage = flattenPackage);
|
||||
}
|
||||
|
||||
public boolean isCheckForUpdates() {
|
||||
@@ -146,29 +153,35 @@ public class JadxSettings extends JadxCLIArgs {
|
||||
}
|
||||
|
||||
public void saveWindowPos(Window window) {
|
||||
WindowLocation pos = new WindowLocation(window.getClass().getSimpleName(),
|
||||
window.getX(), window.getY(),
|
||||
window.getWidth(), window.getHeight()
|
||||
);
|
||||
WindowLocation pos = new WindowLocation(window.getClass().getSimpleName(), window.getBounds());
|
||||
windowPos.put(pos.getWindowId(), pos);
|
||||
partialSync(settings -> settings.windowPos = windowPos);
|
||||
}
|
||||
|
||||
public boolean loadWindowPos(Window window) {
|
||||
WindowLocation pos = windowPos.get(window.getClass().getSimpleName());
|
||||
if (pos == null || !isContainedInAnyScreen(pos)) {
|
||||
if (pos == null || pos.getBounds() == null) {
|
||||
return false;
|
||||
}
|
||||
if (window instanceof MainWindow) {
|
||||
int extendedState = getMainWindowExtendedState();
|
||||
if (extendedState != JFrame.NORMAL) {
|
||||
((JFrame) window).setExtendedState(extendedState);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!isContainedInAnyScreen(pos)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
window.setLocation(pos.getX(), pos.getY());
|
||||
window.setSize(pos.getWidth(), pos.getHeight());
|
||||
window.setBounds(pos.getBounds());
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean isContainedInAnyScreen(WindowLocation pos) {
|
||||
for (GraphicsDevice gd : GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices()) {
|
||||
if (gd.getDefaultConfiguration().getBounds().contains(
|
||||
pos.getX(), pos.getY(), pos.getWidth(), pos.getHeight())) {
|
||||
if (gd.getDefaultConfiguration().getBounds().contains(pos.getBounds())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -317,6 +330,15 @@ public class JadxSettings extends JadxCLIArgs {
|
||||
this.editorThemePath = editorThemePath;
|
||||
}
|
||||
|
||||
public int getMainWindowExtendedState() {
|
||||
return mainWindowExtendedState;
|
||||
}
|
||||
|
||||
public void setMainWindowExtendedState(int mainWindowExtendedState) {
|
||||
this.mainWindowExtendedState = mainWindowExtendedState;
|
||||
partialSync(settings -> settings.mainWindowExtendedState = mainWindowExtendedState);
|
||||
}
|
||||
|
||||
private void upgradeSettings(int fromVersion) {
|
||||
LOG.debug("upgrade settings from version: {} to {}", fromVersion, CURRENT_SETTINGS_VERSION);
|
||||
if (fromVersion == 0) {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package jadx.gui.settings;
|
||||
|
||||
import java.awt.Rectangle;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.nio.file.Path;
|
||||
import java.util.prefs.Preferences;
|
||||
@@ -15,6 +16,7 @@ import com.google.gson.InstanceCreator;
|
||||
|
||||
import jadx.gui.JadxGUI;
|
||||
import jadx.gui.utils.PathTypeAdapter;
|
||||
import jadx.gui.utils.RectangleTypeAdapter;
|
||||
|
||||
public class JadxSettingsAdapter {
|
||||
|
||||
@@ -40,6 +42,7 @@ public class JadxSettingsAdapter {
|
||||
private static final GsonBuilder GSON_BUILDER = new GsonBuilder()
|
||||
.setExclusionStrategies(EXCLUDE_FIELDS)
|
||||
.registerTypeHierarchyAdapter(Path.class, PathTypeAdapter.singleton())
|
||||
.registerTypeHierarchyAdapter(Rectangle.class, RectangleTypeAdapter.singleton())
|
||||
;
|
||||
private static final Gson GSON = GSON_BUILDER.create();
|
||||
|
||||
|
||||
@@ -17,7 +17,6 @@ import jadx.gui.ui.codearea.EditorTheme;
|
||||
import jadx.gui.utils.FontUtils;
|
||||
import jadx.gui.utils.LangLocale;
|
||||
import jadx.gui.utils.NLS;
|
||||
import jadx.gui.utils.Utils;
|
||||
|
||||
public class JadxSettingsWindow extends JDialog {
|
||||
private static final long serialVersionUID = -1804570470377354148L;
|
||||
|
||||
@@ -1,50 +1,34 @@
|
||||
package jadx.gui.settings;
|
||||
|
||||
import java.awt.Rectangle;
|
||||
|
||||
public class WindowLocation {
|
||||
|
||||
private final String windowId;
|
||||
|
||||
private final int x;
|
||||
private final int y;
|
||||
private final int width;
|
||||
private final int height;
|
||||
private final Rectangle bounds;
|
||||
|
||||
public WindowLocation(String windowId, int x, int y, int width, int height) {
|
||||
public WindowLocation(String windowId, Rectangle bounds) {
|
||||
this.windowId = windowId;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
this.bounds = bounds;
|
||||
}
|
||||
|
||||
public String getWindowId() {
|
||||
return windowId;
|
||||
}
|
||||
|
||||
public int getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
public int getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
public int getWidth() {
|
||||
return width;
|
||||
}
|
||||
|
||||
public int getHeight() {
|
||||
return height;
|
||||
public Rectangle getBounds() {
|
||||
return bounds;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "WindowLocation{" +
|
||||
"id='" + windowId + '\'' +
|
||||
", x=" + x +
|
||||
", y=" + y +
|
||||
", width=" + width +
|
||||
", height=" + height +
|
||||
", x=" + bounds.getX() +
|
||||
", y=" + bounds.getY() +
|
||||
", width=" + bounds.getWidth() +
|
||||
", height=" + bounds.getHeight() +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,12 +8,10 @@ import java.awt.DisplayMode;
|
||||
import java.awt.Font;
|
||||
import java.awt.GraphicsDevice;
|
||||
import java.awt.GraphicsEnvironment;
|
||||
import java.awt.Toolkit;
|
||||
import java.awt.dnd.DnDConstants;
|
||||
import java.awt.dnd.DropTarget;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.InputEvent;
|
||||
import java.awt.event.KeyAdapter;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.event.MouseAdapter;
|
||||
@@ -169,7 +167,6 @@ public class MainWindow extends JFrame {
|
||||
setLocationAndPosition();
|
||||
heapUsageBar.setVisible(settings.isShowHeapUsageBar());
|
||||
setVisible(true);
|
||||
setLocationRelativeTo(null);
|
||||
setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
|
||||
addWindowListener(new WindowAdapter() {
|
||||
@Override
|
||||
@@ -921,15 +918,16 @@ public class MainWindow extends JFrame {
|
||||
}
|
||||
|
||||
public void setLocationAndPosition() {
|
||||
if (this.settings.loadWindowPos(this)) {
|
||||
if (settings.loadWindowPos(this)) {
|
||||
return;
|
||||
}
|
||||
GraphicsDevice gd = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
|
||||
DisplayMode mode = gd.getDisplayMode();
|
||||
int w = mode.getWidth();
|
||||
int h = mode.getHeight();
|
||||
setLocation((int) (w * BORDER_RATIO), (int) (h * BORDER_RATIO));
|
||||
setSize((int) (w * WINDOW_RATIO), (int) (h * WINDOW_RATIO));
|
||||
setBounds((int) (w * BORDER_RATIO), (int) (h * BORDER_RATIO),
|
||||
(int) (w * WINDOW_RATIO), (int) (h * WINDOW_RATIO));
|
||||
setLocationRelativeTo(null);
|
||||
}
|
||||
|
||||
private void setEditorTheme(String editorThemePath) {
|
||||
@@ -966,6 +964,7 @@ public class MainWindow extends JFrame {
|
||||
return;
|
||||
}
|
||||
settings.saveWindowPos(this);
|
||||
settings.setMainWindowExtendedState(getExtendedState());
|
||||
cancelBackgroundJobs();
|
||||
dispose();
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@ package jadx.gui.ui.codearea;
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.InputEvent;
|
||||
import java.awt.event.KeyEvent;
|
||||
|
||||
import jadx.gui.treemodel.JClass;
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
package jadx.gui.utils;
|
||||
|
||||
import java.awt.Rectangle;
|
||||
import java.io.IOException;
|
||||
import com.google.gson.TypeAdapter;
|
||||
import com.google.gson.stream.JsonReader;
|
||||
import com.google.gson.stream.JsonToken;
|
||||
import com.google.gson.stream.JsonWriter;
|
||||
|
||||
public class RectangleTypeAdapter {
|
||||
|
||||
private static TypeAdapter<Rectangle> SINGLETON;
|
||||
|
||||
public static TypeAdapter<Rectangle> singleton() {
|
||||
if (SINGLETON == null) {
|
||||
SINGLETON = new TypeAdapter<Rectangle>() {
|
||||
|
||||
@Override
|
||||
public void write(JsonWriter out, Rectangle value) throws IOException {
|
||||
if (value == null) {
|
||||
out.nullValue();
|
||||
} else {
|
||||
out.beginObject();
|
||||
out.name("x").value(value.getX());
|
||||
out.name("y").value(value.getY());
|
||||
out.name("width").value(value.getWidth());
|
||||
out.name("height").value(value.getHeight());
|
||||
out.endObject();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Rectangle read(JsonReader in) throws IOException {
|
||||
if (in.peek() == JsonToken.NULL) {
|
||||
in.nextNull();
|
||||
return null;
|
||||
}
|
||||
in.beginObject();
|
||||
Rectangle rectangle = new Rectangle();
|
||||
while (in.hasNext()) {
|
||||
String name = in.nextName();
|
||||
switch(name) {
|
||||
case "x":
|
||||
rectangle.x = in.nextInt();
|
||||
break;
|
||||
case "y":
|
||||
rectangle.y = in.nextInt();
|
||||
break;
|
||||
case "width":
|
||||
rectangle.width = in.nextInt();
|
||||
break;
|
||||
case "height":
|
||||
rectangle.height = in.nextInt();
|
||||
break;
|
||||
}
|
||||
}
|
||||
in.endObject();
|
||||
return rectangle;
|
||||
}
|
||||
};
|
||||
}
|
||||
return SINGLETON;
|
||||
}
|
||||
|
||||
private RectangleTypeAdapter() {
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,6 @@ import javax.swing.undo.UndoManager;
|
||||
import java.awt.*;
|
||||
import java.awt.datatransfer.DataFlavor;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.InputEvent;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
|
||||
@@ -6,13 +6,10 @@ import java.awt.datatransfer.Clipboard;
|
||||
import java.awt.datatransfer.StringSelection;
|
||||
import java.awt.datatransfer.Transferable;
|
||||
import java.awt.event.InputEvent;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user