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) {