mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[UI][IJPL-61730] Normalize window state to fit screen bounds
Normalize window position and size when restoring the state to ensure it fits within screen bounds. Adjust location to center if out of bounds. GitOrigin-RevId: 4daf53c5f4b3995a3a51cea2e9a31fd30014288a
This commit is contained in:
committed by
intellij-monorepo-bot
parent
a866ebb5ea
commit
c70fad3998
@@ -348,12 +348,53 @@ abstract class WindowStateServiceImpl extends WindowStateService implements Modi
|
||||
<T> T get(@NotNull Class<T> type, @Nullable Rectangle screen) {
|
||||
Point location = apply(Point::new, myLocation);
|
||||
Dimension size = apply(Dimension::new, mySize);
|
||||
// convert location and size according to the given screen
|
||||
if (myScreen != null && !myScreen.isEmpty() && screen != null && !screen.isEmpty()) {
|
||||
if (location != null) ScreenUtil.moveAndScale(location, myScreen, screen);
|
||||
if (size != null) ScreenUtil.moveAndScale(size, myScreen, screen);
|
||||
if (!isVisible(location, size)) return null; // adjusted state is not visible
|
||||
// convert location and size according to the given screen and normalize to fit
|
||||
if (location != null || size != null) {
|
||||
if (myScreen != null && !myScreen.isEmpty() && screen != null && !screen.isEmpty()) {
|
||||
if (location != null) ScreenUtil.moveAndScale(location, myScreen, screen);
|
||||
if (size != null) ScreenUtil.moveAndScale(size, myScreen, screen);
|
||||
|
||||
if (location != null && size != null) {
|
||||
Rectangle r = new Rectangle(location, size);
|
||||
Rectangle original = new Rectangle(r);
|
||||
ScreenUtil.moveToFit(r, screen.getBounds(), null, true);
|
||||
if (!r.equals(original)) {
|
||||
LOG.warn("Window state forced to fit screen: " + original + " -> " + r + " (screen: " + screen + ")");
|
||||
}
|
||||
location = r.getLocation();
|
||||
size = r.getSize();
|
||||
}
|
||||
else if (location != null) {
|
||||
Point original = new Point(location);
|
||||
if (location.x < screen.x || location.x >= screen.x + screen.width) {
|
||||
location.x = screen.x + screen.width / 2;
|
||||
}
|
||||
if (location.y < screen.y || location.y >= screen.y + screen.height) {
|
||||
location.y = screen.y + screen.height / 2;
|
||||
}
|
||||
if (!location.equals(original)) {
|
||||
LOG.warn("Window location forced to fit screen: " + original + " -> " + location + " (screen: " + screen + ")");
|
||||
}
|
||||
}
|
||||
else {
|
||||
location = new Point(screen.x + screen.width / 2, screen.y + screen.height / 2);
|
||||
Rectangle r = new Rectangle(location, size);
|
||||
Dimension original = new Dimension(size);
|
||||
ScreenUtil.moveToFit(r, screen.getBounds(), null, true);
|
||||
if (!size.equals(original)) {
|
||||
LOG.warn("Window size forced to fit screen: " + original + " -> " + size + " (screen: " + screen + ")");
|
||||
}
|
||||
location = r.getLocation();
|
||||
size = r.getSize();
|
||||
}
|
||||
|
||||
if (!isVisible(location, size)) {
|
||||
LOG.warn("Adjusted window state is not visible: location=" + location + ", size=" + size + " (screen: " + screen + ")");
|
||||
return null; // adjusted state is not visible
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (type == Point.class) return (T)location;
|
||||
if (type == Dimension.class) return (T)size;
|
||||
if (type == Rectangle.class) return location == null || size == null ? null : (T)new Rectangle(location, size);
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.ui;
|
||||
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.ui.scale.JBUIScale;
|
||||
import com.intellij.util.SystemProperties;
|
||||
@@ -334,13 +333,17 @@ public final class ScreenUtil {
|
||||
}
|
||||
|
||||
public static void moveRectangleToFitTheScreen(@NotNull Rectangle aRectangle) {
|
||||
moveRectangleToFitTheScreen(aRectangle, false);
|
||||
}
|
||||
|
||||
private static void moveRectangleToFitTheScreen(@NotNull Rectangle aRectangle, boolean crop) {
|
||||
if (StartupUiUtil.isWaylandToolkit()) return; // No abs coordinates in Wayland
|
||||
|
||||
int screenX = aRectangle.x + aRectangle.width / 2;
|
||||
int screenY = aRectangle.y + aRectangle.height / 2;
|
||||
Rectangle screen = getScreenRectangle(screenX, screenY);
|
||||
|
||||
moveToFit(aRectangle, screen, null);
|
||||
moveToFit(aRectangle, screen, null, crop);
|
||||
}
|
||||
|
||||
public static void moveToFit(final @NotNull Rectangle rectangle, final @NotNull Rectangle container, @Nullable Insets padding) {
|
||||
@@ -421,29 +424,7 @@ public final class ScreenUtil {
|
||||
}
|
||||
|
||||
public static void fitToScreen(@NotNull Rectangle r) {
|
||||
if (StartupUiUtil.isWaylandToolkit()) return; // No abs coordinates in Wayland
|
||||
|
||||
Rectangle screen = getScreenRectangle(r.x, r.y);
|
||||
|
||||
int xOverdraft = r.x + r.width - screen.x - screen.width;
|
||||
if (xOverdraft > 0) {
|
||||
int shift = Math.min(xOverdraft, r.x - screen.x);
|
||||
xOverdraft -= shift;
|
||||
r.x -= shift;
|
||||
if (xOverdraft > 0) {
|
||||
r.width -= xOverdraft;
|
||||
}
|
||||
}
|
||||
|
||||
int yOverdraft = r.y + r.height - screen.y - screen.height;
|
||||
if (yOverdraft > 0) {
|
||||
int shift = Math.min(yOverdraft, r.y - screen.y);
|
||||
yOverdraft -= shift;
|
||||
r.y -= shift;
|
||||
if (yOverdraft > 0) {
|
||||
r.height -= yOverdraft;
|
||||
}
|
||||
}
|
||||
moveRectangleToFitTheScreen(r, true);
|
||||
}
|
||||
|
||||
public static @NotNull Point findNearestPointOnBorder(@NotNull Rectangle rect, @NotNull Point p) {
|
||||
|
||||
Reference in New Issue
Block a user