From bd89209a994bd5281386a968e9bf5656b9964283 Mon Sep 17 00:00:00 2001 From: Max Weber Date: Thu, 11 Jul 2019 20:04:05 -0600 Subject: [PATCH] runelite-client: Allow partial screen containment again --- .../client/config/RuneLiteConfig.java | 9 ++-- .../java/net/runelite/client/ui/ClientUI.java | 10 ++++- .../runelite/client/ui/ContainableFrame.java | 41 +++++++++++-------- 3 files changed, 39 insertions(+), 21 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/config/RuneLiteConfig.java b/runelite-client/src/main/java/net/runelite/client/config/RuneLiteConfig.java index 13b1f5dee6..2c4cf3597a 100644 --- a/runelite-client/src/main/java/net/runelite/client/config/RuneLiteConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/config/RuneLiteConfig.java @@ -26,6 +26,7 @@ package net.runelite.client.config; import java.awt.Dimension; import net.runelite.api.Constants; +import net.runelite.client.ui.ContainableFrame; @ConfigGroup("runelite") public interface RuneLiteConfig extends Config @@ -64,14 +65,14 @@ public interface RuneLiteConfig extends Config } @ConfigItem( - keyName = "containInScreen", + keyName = "containInScreen2", name = "Contain in screen", - description = "Makes the client stay contained in the screen when attempted to move out of it.
Note: Only works if custom chrome is enabled.", + description = "Makes the client stay contained in the screen when attempted to move out of it.
Note: 'Always' only works if custom chrome is enabled.", position = 13 ) - default boolean containInScreen() + default ContainableFrame.Mode containInScreen() { - return false; + return ContainableFrame.Mode.RESIZING; } @ConfigItem( diff --git a/runelite-client/src/main/java/net/runelite/client/ui/ClientUI.java b/runelite-client/src/main/java/net/runelite/client/ui/ClientUI.java index 247e6a9dff..5a175716d4 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/ClientUI.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/ClientUI.java @@ -858,7 +858,15 @@ public class ClientUI } frame.setExpandResizeType(config.automaticResizeType()); - frame.setContainedInScreen(config.containInScreen() && withTitleBar); + + ContainableFrame.Mode containMode = config.containInScreen(); + if (containMode == ContainableFrame.Mode.ALWAYS && !withTitleBar) + { + // When native window decorations are enabled we don't have a way to receive window move events + // so we can't contain to screen always. + containMode = ContainableFrame.Mode.RESIZING; + } + frame.setContainedInScreen(containMode); if (!config.rememberScreenBounds()) { diff --git a/runelite-client/src/main/java/net/runelite/client/ui/ContainableFrame.java b/runelite-client/src/main/java/net/runelite/client/ui/ContainableFrame.java index fdfca6e89c..e65d6c9fa7 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/ContainableFrame.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/ContainableFrame.java @@ -32,18 +32,25 @@ import net.runelite.client.config.ExpandResizeType; public class ContainableFrame extends JFrame { + public enum Mode + { + ALWAYS, + RESIZING, + NEVER; + } + private static final int SCREEN_EDGE_CLOSE_DISTANCE = 40; @Setter private ExpandResizeType expandResizeType; - private boolean containedInScreen; + private Mode containedInScreen; private boolean expandedClientOppositeDirection; - public void setContainedInScreen(boolean value) + public void setContainedInScreen(Mode value) { this.containedInScreen = value; - if (value) + if (this.containedInScreen == Mode.ALWAYS) { // Reposition the frame if it is intersecting with the bounds this.setLocation(this.getX(), this.getY()); @@ -54,13 +61,13 @@ public class ContainableFrame extends JFrame @Override public void setLocation(int x, int y) { - if (containedInScreen) + if (this.containedInScreen == Mode.ALWAYS) { Rectangle bounds = this.getGraphicsConfiguration().getBounds(); - x = Math.max(x, (int)bounds.getX()); - x = Math.min(x, (int)(bounds.getX() + bounds.getWidth() - this.getWidth())); - y = Math.max(y, (int)bounds.getY()); - y = Math.min(y, (int)(bounds.getY() + bounds.getHeight() - this.getHeight())); + x = Math.max(x, (int) bounds.getX()); + x = Math.min(x, (int) (bounds.getX() + bounds.getWidth() - this.getWidth())); + y = Math.max(y, (int) bounds.getY()); + y = Math.min(y, (int) (bounds.getY() + bounds.getHeight() - this.getHeight())); } super.setLocation(x, y); @@ -69,15 +76,17 @@ public class ContainableFrame extends JFrame @Override public void setBounds(int x, int y, int width, int height) { - if (containedInScreen) + if (this.containedInScreen == Mode.ALWAYS) { + // XXX: this is wrong if setSize/resize is called because Component::resize sets private state that is read + // in Window::setBounds Rectangle bounds = this.getGraphicsConfiguration().getBounds(); - width = Math.min(width, width - (int)bounds.getX() + x); - x = Math.max(x, (int)bounds.getX()); - height = Math.min(height, height - (int)bounds.getY() + y); - y = Math.max(y, (int)bounds.getY()); - width = Math.min(width, (int)(bounds.getX() + bounds.getWidth()) - x); - height = Math.min(height, (int)(bounds.getY() + bounds.getHeight()) - y); + width = Math.min(width, width - (int) bounds.getX() + x); + x = Math.max(x, (int) bounds.getX()); + height = Math.min(height, height - (int) bounds.getY() + y); + y = Math.max(y, (int) bounds.getY()); + width = Math.min(width, (int) (bounds.getX() + bounds.getWidth()) - x); + height = Math.min(height, (int) (bounds.getY() + bounds.getHeight()) - y); } super.setBounds(x, y, width, height); @@ -115,7 +124,7 @@ public class ContainableFrame extends JFrame final int newWindowWidth = getWidth() + increment; int newWindowX = getX(); - if (containedInScreen) + if (this.containedInScreen != Mode.NEVER) { final Rectangle screenBounds = getGraphicsConfiguration().getBounds(); final boolean wouldExpandThroughEdge = getX() + newWindowWidth > screenBounds.getX() + screenBounds.getWidth();