Commit 172f7f75 authored by Ahmed Ashour's avatar Ahmed Ashour Committed by skylot

fix(gui): preserve main window maximized state (PR #626)

parent 05e5c82c
...@@ -2,7 +2,6 @@ package jadx.core.dex.attributes; ...@@ -2,7 +2,6 @@ package jadx.core.dex.attributes;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator;
import java.util.EnumSet; import java.util.EnumSet;
import java.util.IdentityHashMap; import java.util.IdentityHashMap;
import java.util.List; import java.util.List;
......
...@@ -32,7 +32,6 @@ import jadx.core.dex.nodes.parser.AnnotationsParser; ...@@ -32,7 +32,6 @@ import jadx.core.dex.nodes.parser.AnnotationsParser;
import jadx.core.dex.nodes.parser.FieldInitAttr; import jadx.core.dex.nodes.parser.FieldInitAttr;
import jadx.core.dex.nodes.parser.SignatureParser; import jadx.core.dex.nodes.parser.SignatureParser;
import jadx.core.dex.nodes.parser.StaticValuesParser; import jadx.core.dex.nodes.parser.StaticValuesParser;
import jadx.core.utils.RegionUtils;
import jadx.core.utils.exceptions.DecodeException; import jadx.core.utils.exceptions.DecodeException;
import jadx.core.utils.exceptions.JadxRuntimeException; import jadx.core.utils.exceptions.JadxRuntimeException;
......
package jadx.core.dex.visitors.regions.variables; package jadx.core.dex.visitors.regions.variables;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
......
...@@ -2,7 +2,6 @@ package jadx.tests.integration.inner; ...@@ -2,7 +2,6 @@ package jadx.tests.integration.inner;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import jadx.NotYetImplemented;
import jadx.core.dex.nodes.ClassNode; import jadx.core.dex.nodes.ClassNode;
import jadx.tests.api.IntegrationTest; import jadx.tests.api.IntegrationTest;
......
package jadx.gui.settings; 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.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.util.ArrayList; import java.util.ArrayList;
...@@ -12,6 +15,8 @@ import java.util.Map; ...@@ -12,6 +15,8 @@ import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.function.Consumer; import java.util.function.Consumer;
import javax.swing.JFrame;
import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea; import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger; import org.slf4j.Logger;
...@@ -19,6 +24,7 @@ import org.slf4j.LoggerFactory; ...@@ -19,6 +24,7 @@ import org.slf4j.LoggerFactory;
import jadx.api.JadxArgs; import jadx.api.JadxArgs;
import jadx.cli.JadxCLIArgs; import jadx.cli.JadxCLIArgs;
import jadx.gui.ui.MainWindow;
import jadx.gui.ui.codearea.EditorTheme; import jadx.gui.ui.codearea.EditorTheme;
import jadx.gui.utils.FontUtils; import jadx.gui.utils.FontUtils;
import jadx.gui.utils.LangLocale; import jadx.gui.utils.LangLocale;
...@@ -51,9 +57,10 @@ public class JadxSettings extends JadxCLIArgs { ...@@ -51,9 +57,10 @@ public class JadxSettings extends JadxCLIArgs {
private boolean showHeapUsageBar = true; private boolean showHeapUsageBar = true;
private int settingsVersion = 0;
private Map<String, WindowLocation> windowPos = new HashMap<>(); private Map<String, WindowLocation> windowPos = new HashMap<>();
private int mainWindowExtendedState = JFrame.NORMAL;
private int settingsVersion = 0;
public static JadxSettings makeDefault() { public static JadxSettings makeDefault() {
JadxSettings jadxSettings = new JadxSettings(); JadxSettings jadxSettings = new JadxSettings();
...@@ -92,7 +99,7 @@ public class JadxSettings extends JadxCLIArgs { ...@@ -92,7 +99,7 @@ public class JadxSettings extends JadxCLIArgs {
public void setLastOpenFilePath(Path lastOpenFilePath) { public void setLastOpenFilePath(Path lastOpenFilePath) {
this.lastOpenFilePath = lastOpenFilePath; this.lastOpenFilePath = lastOpenFilePath;
partialSync(settings -> settings.lastOpenFilePath = JadxSettings.this.lastOpenFilePath); partialSync(settings -> settings.lastOpenFilePath = lastOpenFilePath);
} }
public Path getLastSaveProjectPath() { public Path getLastSaveProjectPath() {
...@@ -105,12 +112,12 @@ public class JadxSettings extends JadxCLIArgs { ...@@ -105,12 +112,12 @@ public class JadxSettings extends JadxCLIArgs {
public void setLastSaveProjectPath(Path lastSaveProjectPath) { public void setLastSaveProjectPath(Path lastSaveProjectPath) {
this.lastSaveProjectPath = lastSaveProjectPath; this.lastSaveProjectPath = lastSaveProjectPath;
partialSync(settings -> settings.lastSaveProjectPath = JadxSettings.this.lastSaveProjectPath); partialSync(settings -> settings.lastSaveProjectPath = lastSaveProjectPath);
} }
public void setLastSaveFilePath(Path lastSaveFilePath) { public void setLastSaveFilePath(Path lastSaveFilePath) {
this.lastSaveFilePath = lastSaveFilePath; this.lastSaveFilePath = lastSaveFilePath;
partialSync(settings -> settings.lastSaveFilePath = JadxSettings.this.lastSaveFilePath); partialSync(settings -> settings.lastSaveFilePath = lastSaveFilePath);
} }
public boolean isFlattenPackage() { public boolean isFlattenPackage() {
...@@ -119,7 +126,7 @@ public class JadxSettings extends JadxCLIArgs { ...@@ -119,7 +126,7 @@ public class JadxSettings extends JadxCLIArgs {
public void setFlattenPackage(boolean flattenPackage) { public void setFlattenPackage(boolean flattenPackage) {
this.flattenPackage = flattenPackage; this.flattenPackage = flattenPackage;
partialSync(settings -> settings.flattenPackage = JadxSettings.this.flattenPackage); partialSync(settings -> settings.flattenPackage = flattenPackage);
} }
public boolean isCheckForUpdates() { public boolean isCheckForUpdates() {
...@@ -146,29 +153,35 @@ public class JadxSettings extends JadxCLIArgs { ...@@ -146,29 +153,35 @@ public class JadxSettings extends JadxCLIArgs {
} }
public void saveWindowPos(Window window) { public void saveWindowPos(Window window) {
WindowLocation pos = new WindowLocation(window.getClass().getSimpleName(), WindowLocation pos = new WindowLocation(window.getClass().getSimpleName(), window.getBounds());
window.getX(), window.getY(),
window.getWidth(), window.getHeight()
);
windowPos.put(pos.getWindowId(), pos); windowPos.put(pos.getWindowId(), pos);
partialSync(settings -> settings.windowPos = windowPos); partialSync(settings -> settings.windowPos = windowPos);
} }
public boolean loadWindowPos(Window window) { public boolean loadWindowPos(Window window) {
WindowLocation pos = windowPos.get(window.getClass().getSimpleName()); WindowLocation pos = windowPos.get(window.getClass().getSimpleName());
if (pos == null || !isContainedInAnyScreen(pos)) { if (pos == null || pos.getBounds() == null) {
return false; return false;
} }
if (window instanceof MainWindow) {
int extendedState = getMainWindowExtendedState();
if (extendedState != JFrame.NORMAL) {
((JFrame) window).setExtendedState(extendedState);
return true;
}
}
window.setLocation(pos.getX(), pos.getY()); if (!isContainedInAnyScreen(pos)) {
window.setSize(pos.getWidth(), pos.getHeight()); return false;
}
window.setBounds(pos.getBounds());
return true; return true;
} }
private static boolean isContainedInAnyScreen(WindowLocation pos) { private static boolean isContainedInAnyScreen(WindowLocation pos) {
for (GraphicsDevice gd : GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices()) { for (GraphicsDevice gd : GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices()) {
if (gd.getDefaultConfiguration().getBounds().contains( if (gd.getDefaultConfiguration().getBounds().contains(pos.getBounds())) {
pos.getX(), pos.getY(), pos.getWidth(), pos.getHeight())) {
return true; return true;
} }
} }
...@@ -317,6 +330,15 @@ public class JadxSettings extends JadxCLIArgs { ...@@ -317,6 +330,15 @@ public class JadxSettings extends JadxCLIArgs {
this.editorThemePath = editorThemePath; 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) { private void upgradeSettings(int fromVersion) {
LOG.debug("upgrade settings from version: {} to {}", fromVersion, CURRENT_SETTINGS_VERSION); LOG.debug("upgrade settings from version: {} to {}", fromVersion, CURRENT_SETTINGS_VERSION);
if (fromVersion == 0) { if (fromVersion == 0) {
......
package jadx.gui.settings; package jadx.gui.settings;
import java.awt.Rectangle;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.prefs.Preferences; import java.util.prefs.Preferences;
...@@ -15,6 +16,7 @@ import com.google.gson.InstanceCreator; ...@@ -15,6 +16,7 @@ import com.google.gson.InstanceCreator;
import jadx.gui.JadxGUI; import jadx.gui.JadxGUI;
import jadx.gui.utils.PathTypeAdapter; import jadx.gui.utils.PathTypeAdapter;
import jadx.gui.utils.RectangleTypeAdapter;
public class JadxSettingsAdapter { public class JadxSettingsAdapter {
...@@ -40,6 +42,7 @@ public class JadxSettingsAdapter { ...@@ -40,6 +42,7 @@ public class JadxSettingsAdapter {
private static final GsonBuilder GSON_BUILDER = new GsonBuilder() private static final GsonBuilder GSON_BUILDER = new GsonBuilder()
.setExclusionStrategies(EXCLUDE_FIELDS) .setExclusionStrategies(EXCLUDE_FIELDS)
.registerTypeHierarchyAdapter(Path.class, PathTypeAdapter.singleton()) .registerTypeHierarchyAdapter(Path.class, PathTypeAdapter.singleton())
.registerTypeHierarchyAdapter(Rectangle.class, RectangleTypeAdapter.singleton())
; ;
private static final Gson GSON = GSON_BUILDER.create(); private static final Gson GSON = GSON_BUILDER.create();
......
...@@ -17,7 +17,6 @@ import jadx.gui.ui.codearea.EditorTheme; ...@@ -17,7 +17,6 @@ import jadx.gui.ui.codearea.EditorTheme;
import jadx.gui.utils.FontUtils; import jadx.gui.utils.FontUtils;
import jadx.gui.utils.LangLocale; import jadx.gui.utils.LangLocale;
import jadx.gui.utils.NLS; import jadx.gui.utils.NLS;
import jadx.gui.utils.Utils;
public class JadxSettingsWindow extends JDialog { public class JadxSettingsWindow extends JDialog {
private static final long serialVersionUID = -1804570470377354148L; private static final long serialVersionUID = -1804570470377354148L;
......
package jadx.gui.settings; package jadx.gui.settings;
import java.awt.Rectangle;
public class WindowLocation { public class WindowLocation {
private final String windowId; private final String windowId;
private final int x; private final Rectangle bounds;
private final int y;
private final int width;
private final int height;
public WindowLocation(String windowId, int x, int y, int width, int height) { public WindowLocation(String windowId, Rectangle bounds) {
this.windowId = windowId; this.windowId = windowId;
this.x = x; this.bounds = bounds;
this.y = y;
this.width = width;
this.height = height;
} }
public String getWindowId() { public String getWindowId() {
return windowId; return windowId;
} }
public int getX() { public Rectangle getBounds() {
return x; return bounds;
}
public int getY() {
return y;
}
public int getWidth() {
return width;
}
public int getHeight() {
return height;
} }
@Override @Override
public String toString() { public String toString() {
return "WindowLocation{" + return "WindowLocation{" +
"id='" + windowId + '\'' + "id='" + windowId + '\'' +
", x=" + x + ", x=" + bounds.getX() +
", y=" + y + ", y=" + bounds.getY() +
", width=" + width + ", width=" + bounds.getWidth() +
", height=" + height + ", height=" + bounds.getHeight() +
'}'; '}';
} }
} }
...@@ -8,12 +8,10 @@ import java.awt.DisplayMode; ...@@ -8,12 +8,10 @@ import java.awt.DisplayMode;
import java.awt.Font; import java.awt.Font;
import java.awt.GraphicsDevice; import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment; import java.awt.GraphicsEnvironment;
import java.awt.Toolkit;
import java.awt.dnd.DnDConstants; import java.awt.dnd.DnDConstants;
import java.awt.dnd.DropTarget; import java.awt.dnd.DropTarget;
import java.awt.event.ActionEvent; import java.awt.event.ActionEvent;
import java.awt.event.ActionListener; import java.awt.event.ActionListener;
import java.awt.event.InputEvent;
import java.awt.event.KeyAdapter; import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent; import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter; import java.awt.event.MouseAdapter;
...@@ -169,7 +167,6 @@ public class MainWindow extends JFrame { ...@@ -169,7 +167,6 @@ public class MainWindow extends JFrame {
setLocationAndPosition(); setLocationAndPosition();
heapUsageBar.setVisible(settings.isShowHeapUsageBar()); heapUsageBar.setVisible(settings.isShowHeapUsageBar());
setVisible(true); setVisible(true);
setLocationRelativeTo(null);
setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
addWindowListener(new WindowAdapter() { addWindowListener(new WindowAdapter() {
@Override @Override
...@@ -921,15 +918,16 @@ public class MainWindow extends JFrame { ...@@ -921,15 +918,16 @@ public class MainWindow extends JFrame {
} }
public void setLocationAndPosition() { public void setLocationAndPosition() {
if (this.settings.loadWindowPos(this)) { if (settings.loadWindowPos(this)) {
return; return;
} }
GraphicsDevice gd = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice(); GraphicsDevice gd = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
DisplayMode mode = gd.getDisplayMode(); DisplayMode mode = gd.getDisplayMode();
int w = mode.getWidth(); int w = mode.getWidth();
int h = mode.getHeight(); int h = mode.getHeight();
setLocation((int) (w * BORDER_RATIO), (int) (h * BORDER_RATIO)); setBounds((int) (w * BORDER_RATIO), (int) (h * BORDER_RATIO),
setSize((int) (w * WINDOW_RATIO), (int) (h * WINDOW_RATIO)); (int) (w * WINDOW_RATIO), (int) (h * WINDOW_RATIO));
setLocationRelativeTo(null);
} }
private void setEditorTheme(String editorThemePath) { private void setEditorTheme(String editorThemePath) {
...@@ -966,6 +964,7 @@ public class MainWindow extends JFrame { ...@@ -966,6 +964,7 @@ public class MainWindow extends JFrame {
return; return;
} }
settings.saveWindowPos(this); settings.saveWindowPos(this);
settings.setMainWindowExtendedState(getExtendedState());
cancelBackgroundJobs(); cancelBackgroundJobs();
dispose(); dispose();
} }
......
...@@ -3,7 +3,6 @@ package jadx.gui.ui.codearea; ...@@ -3,7 +3,6 @@ package jadx.gui.ui.codearea;
import javax.swing.*; import javax.swing.*;
import java.awt.*; import java.awt.*;
import java.awt.event.ActionEvent; import java.awt.event.ActionEvent;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent; import java.awt.event.KeyEvent;
import jadx.gui.treemodel.JClass; import jadx.gui.treemodel.JClass;
......
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; ...@@ -6,7 +6,6 @@ import javax.swing.undo.UndoManager;
import java.awt.*; import java.awt.*;
import java.awt.datatransfer.DataFlavor; import java.awt.datatransfer.DataFlavor;
import java.awt.event.ActionEvent; import java.awt.event.ActionEvent;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent; import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter; import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent; import java.awt.event.MouseEvent;
......
...@@ -6,13 +6,10 @@ import java.awt.datatransfer.Clipboard; ...@@ -6,13 +6,10 @@ import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.StringSelection; import java.awt.datatransfer.StringSelection;
import java.awt.datatransfer.Transferable; import java.awt.datatransfer.Transferable;
import java.awt.event.InputEvent; import java.awt.event.InputEvent;
import java.io.InputStream;
import java.net.URL; import java.net.URL;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment