diff --git a/platform/platform-api/src/com/intellij/openapi/ui/JBPopupMenu.java b/platform/platform-api/src/com/intellij/openapi/ui/JBPopupMenu.java index 057305e81bdb..d73446e5edb3 100644 --- a/platform/platform-api/src/com/intellij/openapi/ui/JBPopupMenu.java +++ b/platform/platform-api/src/com/intellij/openapi/ui/JBPopupMenu.java @@ -11,6 +11,7 @@ import com.intellij.ui.*; import com.intellij.ui.awt.RelativePoint; import com.intellij.util.ui.GraphicsUtil; import com.intellij.util.ui.TimerUtil; +import com.intellij.util.ui.WaylandUtilKt; import com.intellij.util.ui.update.UiNotifyConnector; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -349,6 +350,7 @@ public class JBPopupMenu extends JPopupMenu { } if (configuration == null) return Short.MAX_VALUE; Rectangle screenRectangle = ScreenUtil.getScreenRectangle(configuration); + WaylandUtilKt.addFakeScreenInsets(screenRectangle); if (invoker != null && invoker.getParent() instanceof JMenuBar) { var menuItemHeight = invoker.getSize().height; diff --git a/platform/platform-resources/src/META-INF/PlatformExtensions.xml b/platform/platform-resources/src/META-INF/PlatformExtensions.xml index af3591c96f8d..4d298d99a01f 100644 --- a/platform/platform-resources/src/META-INF/PlatformExtensions.xml +++ b/platform/platform-resources/src/META-INF/PlatformExtensions.xml @@ -1836,6 +1836,7 @@ key="settings.name" bundle="messages.MinimapBundle"/> + diff --git a/platform/util/ui/src/com/intellij/util/ui/WaylandUtil.kt b/platform/util/ui/src/com/intellij/util/ui/WaylandUtil.kt index c5649a255fd1..80dd132cce77 100644 --- a/platform/util/ui/src/com/intellij/util/ui/WaylandUtil.kt +++ b/platform/util/ui/src/com/intellij/util/ui/WaylandUtil.kt @@ -3,6 +3,7 @@ package com.intellij.util.ui import com.intellij.openapi.diagnostic.debug import com.intellij.openapi.diagnostic.fileLogger +import com.intellij.openapi.util.registry.Registry import com.intellij.ui.ComponentUtil import org.jetbrains.annotations.ApiStatus import java.awt.Component @@ -103,6 +104,26 @@ fun getNearestTopLevelAncestor(component: Component): Component? { } } +/** + * Slightly decreases the screen height on Wayland. + * + * Because Wayland doesn't report the actual screen insets, + * for some use cases, like trying to determine the maximum height of some menu or popup, + * the maximum size can be larger than the actual available screen space. + * This function applies a workaround for this problem by subtracting some fixed + * amount of space from the screen height. + * + * Does nothing if not running under the native Wayland toolkit. + */ +@ApiStatus.Internal +fun addFakeScreenInsets(rectangle: Rectangle) { + if (!StartupUiUtil.isWaylandToolkit()) return + val total = JBUI.scale(Registry.intValue("wayland.screen.vInsets", defaultValue = 50, minValue = 0, maxValue = 300)) + val top = total / 2 + rectangle.y += top + rectangle.height -= total +} + private fun fitValue(location: Int, width: Int, start1: Int, end1: Int, start2: Int, end2: Int, preferLess: Boolean): Int { LOG.debug { "The available intervals are $start1..$end1 and $start2..$end2, the popup size is $width" } if (location >= start1 && location + width < end1) {