From 65e612ed6ffa66e6f5cc7de28bbd019b5dd80391 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jindra=20Pet=C5=99=C3=ADk?= Date: Tue, 17 Oct 2023 20:43:11 +0200 Subject: [PATCH] Added [#1130], [#1220] Remembering last used screen (monitor), opening dialogs on same screen as the main window, do not restore window size to larger value that actual screen size Fixed [#1768], [#1768] Maximizing window on other than main monitor --- CHANGELOG.md | 10 ++ .../flash/configuration/Configuration.java | 24 ++++ .../decompiler/flash/gui/ErrorLogFrame.java | 2 +- .../decompiler/flash/gui/LoadingDialog.java | 2 +- src/com/jpexs/decompiler/flash/gui/Main.java | 1 + .../flash/gui/MainFrameClassic.java | 21 ++- .../decompiler/flash/gui/MainFrameRibbon.java | 45 +++++- src/com/jpexs/decompiler/flash/gui/View.java | 132 ++++++++++++++---- .../locales/AdvancedSettingsDialog.properties | 19 +++ .../AdvancedSettingsDialog_cs.properties | 20 +++ 10 files changed, 234 insertions(+), 42 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9c0f7b1f4..4248093ce 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,13 @@ All notable changes to this project will be documented in this file. ## [Unreleased] +### Added +- [#1130], [#1220] Remembering last used screen (monitor), + opening dialogs on same screen as the main window, + do not restore window size to larger value that actual screen size + +### Fixed +- [#1768], [#1768] Maximizing window on other than main monitor ## [19.1.2] - 2023-10-16 ### Fixed @@ -3182,6 +3189,9 @@ Major version of SWF to XML export changed to 2. [alpha 9]: https://github.com/jindrapetrik/jpexs-decompiler/compare/alpha8...alpha9 [alpha 8]: https://github.com/jindrapetrik/jpexs-decompiler/compare/alpha7...alpha8 [alpha 7]: https://github.com/jindrapetrik/jpexs-decompiler/releases/tag/alpha7 +[#1130]: https://www.free-decompiler.com/flash/issues/1130 +[#1220]: https://www.free-decompiler.com/flash/issues/1220 +[#1768]: https://www.free-decompiler.com/flash/issues/1768 [#2099]: https://www.free-decompiler.com/flash/issues/2099 [#2090]: https://www.free-decompiler.com/flash/issues/2090 [#2079]: https://www.free-decompiler.com/flash/issues/2079 diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/configuration/Configuration.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/configuration/Configuration.java index 9794f9a1e..977d15664 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/configuration/Configuration.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/configuration/Configuration.java @@ -936,6 +936,30 @@ public final class Configuration { @ConfigurationInternal public static ConfigurationItem guiActionDocsSplitPaneDividerLocationPercent = null; + @ConfigurationDefaultBoolean(true) + @ConfigurationCategory("ui") + public static ConfigurationItem rememberLastScreen = null; + + @ConfigurationDefaultInt(-1) + @ConfigurationInternal + public static ConfigurationItem lastMainWindowScreenIndex = null; + + @ConfigurationDefaultInt(-1) + @ConfigurationInternal + public static ConfigurationItem lastMainWindowScreenX = null; + + @ConfigurationDefaultInt(-1) + @ConfigurationInternal + public static ConfigurationItem lastMainWindowScreenY = null; + + @ConfigurationDefaultInt(-1) + @ConfigurationInternal + public static ConfigurationItem lastMainWindowScreenWidth = null; + + @ConfigurationDefaultInt(-1) + @ConfigurationInternal + public static ConfigurationItem lastMainWindowScreenHeight = null; + private enum OSId { WINDOWS, OSX, UNIX } diff --git a/src/com/jpexs/decompiler/flash/gui/ErrorLogFrame.java b/src/com/jpexs/decompiler/flash/gui/ErrorLogFrame.java index 6be0ee8bd..e60d6dd8b 100644 --- a/src/com/jpexs/decompiler/flash/gui/ErrorLogFrame.java +++ b/src/com/jpexs/decompiler/flash/gui/ErrorLogFrame.java @@ -116,7 +116,7 @@ public class ErrorLogFrame extends AppFrame { if (View.isOceanic()) { setBackground(Color.white); } - View.centerScreen(this); + View.centerScreenMain(this); View.setWindowIcon(this); setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE); Container cnt = getContentPane(); diff --git a/src/com/jpexs/decompiler/flash/gui/LoadingDialog.java b/src/com/jpexs/decompiler/flash/gui/LoadingDialog.java index fdb6d9cb9..837268ce8 100644 --- a/src/com/jpexs/decompiler/flash/gui/LoadingDialog.java +++ b/src/com/jpexs/decompiler/flash/gui/LoadingDialog.java @@ -109,7 +109,7 @@ public class LoadingDialog extends AppDialog { pack(); Dimension siz = getSize(); setSize(Math.max(300, 150 + getFontMetrics(new JLabel().getFont()).stringWidth(translate("loadingpleasewait"))), siz.height); - View.centerScreen(this); + View.centerScreenMain(this); } @Override diff --git a/src/com/jpexs/decompiler/flash/gui/Main.java b/src/com/jpexs/decompiler/flash/gui/Main.java index b9e972eb4..7af7c62c9 100644 --- a/src/com/jpexs/decompiler/flash/gui/Main.java +++ b/src/com/jpexs/decompiler/flash/gui/Main.java @@ -2935,6 +2935,7 @@ public class Main { } public static void exit() { + View.saveScreen(); if (mainFrame != null && mainFrame.getPanel() != null) { mainFrame.getPanel().scrollPosStorage.saveScrollPos(mainFrame.getPanel().getCurrentTree().getCurrentTreeItem()); mainFrame.getPanel().savePins(); diff --git a/src/com/jpexs/decompiler/flash/gui/MainFrameClassic.java b/src/com/jpexs/decompiler/flash/gui/MainFrameClassic.java index f5005b92c..8769bd04a 100644 --- a/src/com/jpexs/decompiler/flash/gui/MainFrameClassic.java +++ b/src/com/jpexs/decompiler/flash/gui/MainFrameClassic.java @@ -22,6 +22,10 @@ import com.jpexs.helpers.Helper; import java.awt.BorderLayout; import java.awt.Container; import java.awt.Dimension; +import java.awt.GraphicsDevice; +import java.awt.Insets; +import java.awt.Rectangle; +import java.awt.Toolkit; import java.awt.Window; import java.awt.event.ComponentAdapter; import java.awt.event.ComponentEvent; @@ -63,12 +67,17 @@ public final class MainFrameClassic extends AppFrame implements MainFrame { int w = Configuration.guiWindowWidth.get(); int h = Configuration.guiWindowHeight.get(); - Dimension dim = java.awt.Toolkit.getDefaultToolkit().getScreenSize(); - if (w > dim.width) { - w = dim.width; + GraphicsDevice device = View.getMainDefaultScreenDevice(); + Rectangle bounds = device.getDefaultConfiguration().getBounds(); + Insets insets = Toolkit.getDefaultToolkit().getScreenInsets(device.getDefaultConfiguration()); + int maxWidth = bounds.width - (insets.left + insets.right); + int maxHeight = bounds.height - (insets.top + insets.bottom); + + if (w > maxWidth) { + w = maxWidth; } - if (h > dim.height) { - h = dim.height; + if (h > maxHeight) { + h = maxHeight; } setSize(w, h); @@ -116,7 +125,7 @@ public final class MainFrameClassic extends AppFrame implements MainFrame { cnt.setLayout(new BorderLayout()); cnt.add(panel); - View.centerScreen(this); + View.centerScreenMain(this); } @Override diff --git a/src/com/jpexs/decompiler/flash/gui/MainFrameRibbon.java b/src/com/jpexs/decompiler/flash/gui/MainFrameRibbon.java index 5878cfb9c..016fd7db2 100644 --- a/src/com/jpexs/decompiler/flash/gui/MainFrameRibbon.java +++ b/src/com/jpexs/decompiler/flash/gui/MainFrameRibbon.java @@ -25,6 +25,12 @@ import java.awt.Color; import java.awt.Component; import java.awt.Container; import java.awt.Dimension; +import java.awt.Frame; +import java.awt.GraphicsConfiguration; +import java.awt.GraphicsDevice; +import java.awt.Insets; +import java.awt.Rectangle; +import java.awt.Toolkit; import java.awt.Window; import java.awt.event.ComponentAdapter; import java.awt.event.ComponentEvent; @@ -77,12 +83,17 @@ public final class MainFrameRibbon extends AppRibbonFrame { int w = Configuration.guiWindowWidth.get(); int h = Configuration.guiWindowHeight.get(); - Dimension dim = java.awt.Toolkit.getDefaultToolkit().getScreenSize(); - if (w > dim.width) { - w = dim.width; + GraphicsDevice device = View.getMainDefaultScreenDevice(); + Rectangle bounds = device.getDefaultConfiguration().getBounds(); + Insets insets = Toolkit.getDefaultToolkit().getScreenInsets(device.getDefaultConfiguration()); + int maxWidth = bounds.width - (insets.left + insets.right); + int maxHeight = bounds.height - (insets.top + insets.bottom); + + if (w > maxWidth) { + w = maxWidth; } - if (h > dim.height) { - h = dim.height; + if (h > maxHeight) { + h = maxHeight; } setSize(w, h); @@ -95,7 +106,7 @@ public final class MainFrameRibbon extends AppRibbonFrame { } if (maximizedVertical) { state |= JFrame.MAXIMIZED_VERT; - } + } setExtendedState(state); View.setWindowIcon(this); @@ -164,10 +175,30 @@ public final class MainFrameRibbon extends AppRibbonFrame { } }); - View.centerScreen(this); + View.centerScreenMain(this); } + @Override + public void setExtendedState(int state) { + if ((state & Frame.MAXIMIZED_BOTH) == Frame.MAXIMIZED_BOTH) { + GraphicsConfiguration gc = View.getWindowDevice(MainFrameRibbon.this.getWindow()).getDefaultConfiguration(); + + Insets screenInsets = Toolkit.getDefaultToolkit().getScreenInsets(gc); + Rectangle screenBounds = gc.getBounds(); + Rectangle maxBounds = new Rectangle( + screenBounds.x + screenInsets.left, + screenBounds.y + screenInsets.top, + screenBounds.width - (screenInsets.left + screenInsets.right), + screenBounds.height - (screenInsets.top + screenInsets.bottom) + ); + setMaximizedBounds(maxBounds); + } + super.setExtendedState(state); + } + + + private static void getApplicationMenuButtons(Component comp, List ret) { if (comp instanceof JRibbonApplicationMenuButton) { ret.add((JRibbonApplicationMenuButton) comp); diff --git a/src/com/jpexs/decompiler/flash/gui/View.java b/src/com/jpexs/decompiler/flash/gui/View.java index e79f9ac19..8a138a4dd 100644 --- a/src/com/jpexs/decompiler/flash/gui/View.java +++ b/src/com/jpexs/decompiler/flash/gui/View.java @@ -46,6 +46,7 @@ import java.net.URI; import java.net.URISyntaxException; import java.net.URL; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; @@ -339,53 +340,132 @@ public class View { } } + public static void centerScreenMain(Window f) { + centerScreen(f, true); + } + /** * Centers specified frame on the screen * * @param f Frame to center on the screen */ public static void centerScreen(Window f) { - centerScreen(f, 0); // todo, set screen to the currently active screen instead of the first screen in a multi screen setup, (maybe by using the screen where the main window is now classic or ribbon?) + centerScreen(f, false); } - - public static void centerScreen(Window f, int screen) { - - GraphicsDevice[] allDevices = getEnv().getScreenDevices(); + + public static void centerScreen(Window f, boolean mainWindow) { int topLeftX; int topLeftY; int screenX; int screenY; int windowPosX; int windowPosY; + GraphicsDevice device; - if (screen < allDevices.length && screen > -1) { - topLeftX = allDevices[screen].getDefaultConfiguration().getBounds().x; - topLeftY = allDevices[screen].getDefaultConfiguration().getBounds().y; - - screenX = allDevices[screen].getDefaultConfiguration().getBounds().width; - screenY = allDevices[screen].getDefaultConfiguration().getBounds().height; - - Insets bounds = Toolkit.getDefaultToolkit().getScreenInsets(allDevices[screen].getDefaultConfiguration()); - screenX = screenX - bounds.right; - screenY = screenY - bounds.bottom; + if (mainWindow || Main.getMainFrame() == null) { + device = getMainDefaultScreenDevice(); } else { - topLeftX = allDevices[0].getDefaultConfiguration().getBounds().x; - topLeftY = allDevices[0].getDefaultConfiguration().getBounds().y; - - screenX = allDevices[0].getDefaultConfiguration().getBounds().width; - screenY = allDevices[0].getDefaultConfiguration().getBounds().height; - - Insets bounds = Toolkit.getDefaultToolkit().getScreenInsets(allDevices[0].getDefaultConfiguration()); - screenX = screenX - bounds.right; - screenY = screenY - bounds.bottom; + device = getWindowDevice(Main.getMainFrame().getWindow()); } + topLeftX = device.getDefaultConfiguration().getBounds().x; + topLeftY = device.getDefaultConfiguration().getBounds().y; + + screenX = device.getDefaultConfiguration().getBounds().width; + screenY = device.getDefaultConfiguration().getBounds().height; + + Insets bounds = Toolkit.getDefaultToolkit().getScreenInsets(device.getDefaultConfiguration()); + screenX = screenX - bounds.right; + screenY = screenY - bounds.bottom; + windowPosX = ((screenX - f.getWidth()) / 2) + topLeftX; windowPosY = ((screenY - f.getHeight()) / 2) + topLeftY; f.setLocation(windowPosX, windowPosY); } + public static void saveScreen() { + MainFrame mainFrame = Main.getMainFrame(); + if (mainFrame == null) { + return; + } + Window w = mainFrame.getWindow(); + if (w == null) { + return; + } + GraphicsDevice device = getWindowDevice(w); + + GraphicsDevice[] allDevices = getEnv().getScreenDevices(); + int deviceIndex = -1; + for (int i = 0; i < allDevices.length; i++) { + if (allDevices[i] == device) { + deviceIndex = i; + break; + } + } + if (deviceIndex != -1) { + Configuration.lastMainWindowScreenIndex.set(deviceIndex); + Rectangle bounds = device.getDefaultConfiguration().getBounds(); + Configuration.lastMainWindowScreenX.set(bounds.x); + Configuration.lastMainWindowScreenY.set(bounds.y); + Configuration.lastMainWindowScreenWidth.set(bounds.width); + Configuration.lastMainWindowScreenHeight.set(bounds.height); + } + } + + public static GraphicsDevice getMainDefaultScreenDevice() { + if (!Configuration.rememberLastScreen.get()) { + return getEnv().getDefaultScreenDevice(); + } + + int deviceIndex = Configuration.lastMainWindowScreenIndex.get(); + GraphicsDevice[] allDevices = getEnv().getScreenDevices(); + + if (deviceIndex >= allDevices.length || deviceIndex == -1) { + return getEnv().getDefaultScreenDevice(); + } + + Rectangle expectedBounds = allDevices[deviceIndex].getDefaultConfiguration().getBounds(); + if (Configuration.lastMainWindowScreenX.get() != expectedBounds.x + || Configuration.lastMainWindowScreenY.get() != expectedBounds.y + || Configuration.lastMainWindowScreenWidth.get() != expectedBounds.width + || Configuration.lastMainWindowScreenHeight.get() != expectedBounds.height) { + return getEnv().getDefaultScreenDevice(); + } + return allDevices[deviceIndex]; + } + + public static int getWindowDeviceIndex(Window window) { + GraphicsDevice device = getWindowDevice(window); + GraphicsDevice[] allDevices = getEnv().getScreenDevices(); + for (int i = 0; i < allDevices.length; i++) { + if (allDevices[i] == device) { + return i; + } + } + return -1; + } + + public static GraphicsDevice getWindowDevice(Window window) { + Rectangle bounds = window.getBounds(); + return Arrays.asList(GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices()).stream() + // pick devices where window located + .filter(d -> d.getDefaultConfiguration().getBounds().intersects(bounds)) + // sort by biggest intersection square + .sorted((f, s) -> Long.compare(// + square(f.getDefaultConfiguration().getBounds().intersection(bounds)), + square(s.getDefaultConfiguration().getBounds().intersection(bounds)))) + // use one with the biggest part of the window + .reduce((f, s) -> s) // + + // fallback to default device + .orElse(window.getGraphicsConfiguration().getDevice()); + } + + private static long square(Rectangle rec) { + return Math.abs(rec.width * rec.height); + } + public static ImageIcon getIcon(String name, int size) { ImageIcon icon = getIcon(getPrefferedIconName(name, size)); if (icon.getIconWidth() == size && icon.getIconHeight() == size) { @@ -512,8 +592,6 @@ public class View { return expandedNodes; } - - private static TreePath expandTreeNode(JTree tree, List pathAsStringList) { TreePath tp = getTreePathByPathStrings(tree, pathAsStringList); tree.expandPath(tp); @@ -563,7 +641,7 @@ public class View { TreePath tp = new TreePath(path.toArray(new Object[path.size()])); return tp; } - + public static void expandTreeNodes(JTree tree, List> pathsToExpand) { for (List pathAsStringList : pathsToExpand) { expandTreeNode(tree, pathAsStringList); diff --git a/src/com/jpexs/decompiler/flash/gui/locales/AdvancedSettingsDialog.properties b/src/com/jpexs/decompiler/flash/gui/locales/AdvancedSettingsDialog.properties index f610bd3c3..9a2d5d57f 100644 --- a/src/com/jpexs/decompiler/flash/gui/locales/AdvancedSettingsDialog.properties +++ b/src/com/jpexs/decompiler/flash/gui/locales/AdvancedSettingsDialog.properties @@ -715,3 +715,22 @@ config.description.displayAs12PCodeDocsPanel = Show panel with documentation of config.name.gui.action.splitPane.docs.dividerLocationPercent = (Internal) AS 1/2 splitPanedocsdividerLocationPercent config.description.action.avm2.splitPane.docs.dividerLocationPercent = AS 1/2 splitPane docs divider Location Percent +#after 19.1.2 + +config.name.rememberLastScreen = Remember last used screen (on multiple monitors) +config.description.rememberLastScreen = Remember last used screen on configuration with multiple screen devices (monitors) + +config.name.lastMainWindowScreenIndex = Last main window screen index +config.description.lastMainWindowScreenIndex = Last main window screen index + +config.name.lastMainWindowScreenX = Last main window screen X +config.description.lastMainWindowScreenX = Last main window screen X coordinate + +config.name.lastMainWindowScreenY = Last main window screen Y +config.description.lastMainWindowScreenY = Last main window screen Y coordinate + +config.name.lastMainWindowScreenWidth = Last main window screen width +config.description.lastMainWindowScreenWidth = Last main window screen width + +config.name.lastMainWindowScreenHeight = Last main window screen width +config.description.lastMainWindowScreenHeight = Last main window screen width \ No newline at end of file diff --git a/src/com/jpexs/decompiler/flash/gui/locales/AdvancedSettingsDialog_cs.properties b/src/com/jpexs/decompiler/flash/gui/locales/AdvancedSettingsDialog_cs.properties index 62436add3..950619aa7 100644 --- a/src/com/jpexs/decompiler/flash/gui/locales/AdvancedSettingsDialog_cs.properties +++ b/src/com/jpexs/decompiler/flash/gui/locales/AdvancedSettingsDialog_cs.properties @@ -704,3 +704,23 @@ config.description.displayAs12PCodeDocsPanel = Zobraz\u00ed panel s dokumentac\u config.name.gui.action.splitPane.docs.dividerLocationPercent = (Internal) AS 1/2 splitPanedocsdividerLocationPercent config.description.gui.action.splitPane.docs.dividerLocationPercent = AS 1/2 pozice v procentech um\u00edst\u011bn\u00ed dokumenta\u010dn\u00edho splitPane + +#after 19.1.2 + +config.name.rememberLastScreen = Pamatovat si naposledy pou\u017eitou obrazovku (p\u0159i v\u00edce monitorech) +config.description.rememberLastScreen = Pamatovat si naposledy pou\u017eitou obrazovku na konfigurac\u00edch s v\u00edce zobrazovac\u00edmi za\u0159\u00edzen\u00edmi (monitory) + +config.name.lastMainWindowScreenIndex = Posledn\u00ed index obrazovky hlavn\u00edho okna +config.description.lastMainWindowScreenIndex = Posledn\u00ed index obrazovky hlavn\u00edho okna + +config.name.lastMainWindowScreenX = Posledn\u00ed X obrazovky hlavn\u00edho okna +config.description.lastMainWindowScreenX = Posledn\u00ed Xov\u00e1 sou\u0159adn\u00edce obrazovky hlavn\u00edho okna + +config.name.lastMainWindowScreenY = Posledn\u00ed Y obrazovky hlavn\u00edho okna +config.description.lastMainWindowScreenY = Posledn\u00ed Yov\u00e1 sou\u0159adn\u00edce obrazovky hlavn\u00edho okna + +config.name.lastMainWindowScreenWidth = Posledn\u00ed \u0161\u00ed\u0159ka obrazovky hlavn\u00edho okna +config.description.lastMainWindowScreenWidth = Posledn\u00ed \u0161\u00ed\u0159ka obrazovky hlavn\u00edho okna + +config.name.lastMainWindowScreenHeight = Posledn\u00ed v\u00fd\u0161ka obrazovky hlavn\u00edho okna +config.description.lastMainWindowScreenHeight = Posledn\u00ed v\u00fd\u0161ka obrazovky hlavn\u00edho okna \ No newline at end of file