diff --git a/java/java-structure-view/BUILD.bazel b/java/java-structure-view/BUILD.bazel
index a8b99f528af8..d5e8f7e2e4d5 100644
--- a/java/java-structure-view/BUILD.bazel
+++ b/java/java-structure-view/BUILD.bazel
@@ -20,6 +20,7 @@ jvm_library(
"//java/java-psi-impl:psi-impl",
"//platform/util:util-ui",
"//java/java-analysis-impl:analysis-impl",
+ "//platform/platform-api:ide",
]
)
### auto-generated section `build intellij.java.structureView` end
\ No newline at end of file
diff --git a/java/java-structure-view/intellij.java.structureView.iml b/java/java-structure-view/intellij.java.structureView.iml
index f19071ca71fa..3353118bae26 100644
--- a/java/java-structure-view/intellij.java.structureView.iml
+++ b/java/java-structure-view/intellij.java.structureView.iml
@@ -14,5 +14,6 @@
+
\ No newline at end of file
diff --git a/platform/core-api/api-dump-experimental.txt b/platform/core-api/api-dump-experimental.txt
index d88409132255..84b8bcd550c2 100644
--- a/platform/core-api/api-dump-experimental.txt
+++ b/platform/core-api/api-dump-experimental.txt
@@ -224,17 +224,6 @@ a:com.intellij.openapi.application.ReadAction
- *s:computeThrowable(com.intellij.openapi.util.ThrowableComputable):java.lang.Object
- *s:run(java.lang.Runnable):V
- *s:runThrowable(com.intellij.util.ThrowableRunnable):V
-*f:com.intellij.openapi.client.ClientSystemInfo
-- *sf:Companion:com.intellij.openapi.client.ClientSystemInfo$Companion
-- f:getMacClient():java.lang.Boolean
-- f:getWindowsClient():java.lang.Boolean
-- sf:isMac():Z
-- sf:isWindows():Z
-- f:setMacClient(java.lang.Boolean):V
-- f:setWindowsClient(java.lang.Boolean):V
-*f:com.intellij.openapi.client.ClientSystemInfo$Companion
-- f:isMac():Z
-- f:isWindows():Z
a:com.intellij.openapi.command.CommandProcessor
- *a:allowMergeGlobalCommands(java.lang.Runnable):V
- *a:executeCommand(com.intellij.openapi.project.Project,java.lang.Runnable,java.lang.String,java.lang.Object,com.intellij.openapi.command.UndoConfirmationPolicy,Z,com.intellij.openapi.editor.Document):V
diff --git a/platform/platform-api/api-dump-experimental.txt b/platform/platform-api/api-dump-experimental.txt
index 6c9e54d0bdc4..7f524013ff69 100644
--- a/platform/platform-api/api-dump-experimental.txt
+++ b/platform/platform-api/api-dump-experimental.txt
@@ -79,6 +79,15 @@ c:com.intellij.openapi.actionSystem.ex.ComboBoxAction$ComboBoxButton
- *p:doShiftClick():V
f:com.intellij.openapi.actionSystem.remoting.PermissionsKt
- *sf:getOwner():com.intellij.platform.ide.core.permissions.Permission
+*f:com.intellij.openapi.client.ClientSystemInfo
+- *sf:Companion:com.intellij.openapi.client.ClientSystemInfo$Companion
+- sf:isMac():Z
+- sf:isWaylandToolkit():Z
+- sf:isWindows():Z
+*f:com.intellij.openapi.client.ClientSystemInfo$Companion
+- f:isMac():Z
+- f:isWaylandToolkit():Z
+- f:isWindows():Z
com.intellij.openapi.fileEditor.AsyncFileEditorProvider
- com.intellij.openapi.fileEditor.FileEditorProvider
- com.intellij.openapi.project.DumbAware
diff --git a/platform/core-api/src/com/intellij/openapi/client/ClientSystemInfo.kt b/platform/platform-api/src/com/intellij/openapi/client/ClientSystemInfo.kt
similarity index 69%
rename from platform/core-api/src/com/intellij/openapi/client/ClientSystemInfo.kt
rename to platform/platform-api/src/com/intellij/openapi/client/ClientSystemInfo.kt
index aa47c3e1f134..692dcdcefbeb 100644
--- a/platform/core-api/src/com/intellij/openapi/client/ClientSystemInfo.kt
+++ b/platform/platform-api/src/com/intellij/openapi/client/ClientSystemInfo.kt
@@ -1,13 +1,15 @@
-// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
+// Copyright 2000-2026 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.openapi.client
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.util.KeyWithDefaultValue
import com.intellij.openapi.util.SystemInfo
+import com.intellij.util.ui.StartupUiUtil
import org.jetbrains.annotations.ApiStatus
/**
- * Provides information about operating system, just like [SystemInfo], but for the current client (in terms of [ClientId.current])
+ * Provides information about operating system, just like [SystemInfo], but for the current client (in terms of
+ * [com.intellij.codeWithMe.ClientId.current])
*/
@ApiStatus.Experimental
class ClientSystemInfo private constructor() {
@@ -22,6 +24,11 @@ class ClientSystemInfo private constructor() {
return getInstance()?.windowsClient ?: SystemInfo.isWindows
}
+ @JvmStatic
+ fun isWaylandToolkit(): Boolean {
+ return getInstance()?.waylandToolkitClient ?: StartupUiUtil.isWaylandToolkit()
+ }
+
@ApiStatus.Internal
fun getInstance(): ClientSystemInfo? {
return ApplicationManager.getApplication()?.currentSessionOrNull?.takeIf { it.isRemote }?.getUserData(CLIENT_INFO_KEY)
@@ -30,6 +37,12 @@ class ClientSystemInfo private constructor() {
private val CLIENT_INFO_KEY = KeyWithDefaultValue.create("ClientSystemInfo") { ClientSystemInfo() }
}
+ @ApiStatus.Internal
var macClient: Boolean? = null
+
+ @ApiStatus.Internal
var windowsClient: Boolean? = null
+
+ @ApiStatus.Internal
+ var waylandToolkitClient: Boolean? = null
}
\ No newline at end of file
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 270feee73b2a..6bbbc08b29ba 100644
--- a/platform/platform-api/src/com/intellij/openapi/ui/JBPopupMenu.java
+++ b/platform/platform-api/src/com/intellij/openapi/ui/JBPopupMenu.java
@@ -5,6 +5,7 @@ import com.intellij.icons.AllIcons;
import com.intellij.openapi.actionSystem.ActionGroup;
import com.intellij.openapi.actionSystem.ActionManager;
import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.client.ClientSystemInfo;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Editor;
import com.intellij.ui.ColorUtil;
@@ -15,7 +16,6 @@ import com.intellij.ui.ScreenUtil;
import com.intellij.ui.awt.RelativePoint;
import com.intellij.ui.wayland.WaylandUtilKt;
import com.intellij.util.ui.GraphicsUtil;
-import com.intellij.util.ui.StartupUiUtil;
import com.intellij.util.ui.TimerUtil;
import com.intellij.util.ui.update.UiNotifyConnector;
import org.jetbrains.annotations.NonNls;
@@ -382,7 +382,7 @@ public class JBPopupMenu extends JPopupMenu {
}
if (configuration == null) return Short.MAX_VALUE;
Rectangle screenRectangle = ScreenUtil.getScreenRectangle(configuration);
- if (StartupUiUtil.isWaylandToolkit()) {
+ if (ClientSystemInfo.isWaylandToolkit()) {
var screenHeight = WaylandUtilKt.getFakeScreenHeight(invoker);
if (screenHeight != null) {
screenRectangle.height = screenHeight;
diff --git a/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionMenu.kt b/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionMenu.kt
index 7c737d59df0e..cddf2836e598 100644
--- a/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionMenu.kt
+++ b/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionMenu.kt
@@ -21,6 +21,7 @@ import com.intellij.openapi.actionSystem.ex.MainMenuPresentationAware
import com.intellij.openapi.actionSystem.impl.ActionPresentationDecorator.decorateTextIfNeeded
import com.intellij.openapi.actionSystem.impl.actionholder.createActionRef
import com.intellij.openapi.application.EDT
+import com.intellij.openapi.client.ClientSystemInfo
import com.intellij.openapi.ui.JBPopupMenu
import com.intellij.openapi.util.Disposer
import com.intellij.openapi.util.IconLoader.getDarkIcon
@@ -47,7 +48,6 @@ import com.intellij.util.cancelOnDispose
import com.intellij.util.concurrency.EdtScheduler
import com.intellij.util.concurrency.annotations.RequiresEdt
import com.intellij.util.ui.JBUI
-import com.intellij.util.ui.StartupUiUtil
import com.intellij.util.ui.launchOnShow
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.FlowPreview
@@ -397,7 +397,7 @@ class ActionMenu constructor(
override fun getPopupMenuOrigin(): Point {
val result = super.getPopupMenuOrigin()
- if (!StartupUiUtil.isWaylandToolkit() || parent !is JPopupMenu) return result
+ if (!ClientSystemInfo.isWaylandToolkit() || parent !is JPopupMenu) return result
correctPopupMenuPositionForWayland(result)
return result
}
diff --git a/platform/platform-impl/src/com/intellij/ui/popup/AbstractPopup.java b/platform/platform-impl/src/com/intellij/ui/popup/AbstractPopup.java
index f2eb8dfab0c7..f1863da9d1ab 100644
--- a/platform/platform-impl/src/com/intellij/ui/popup/AbstractPopup.java
+++ b/platform/platform-impl/src/com/intellij/ui/popup/AbstractPopup.java
@@ -38,6 +38,7 @@ import com.intellij.openapi.application.AccessToken;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.WriteIntentReadAction;
import com.intellij.openapi.application.impl.LaterInvocator;
+import com.intellij.openapi.client.ClientSystemInfo;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.ex.EditorEx;
@@ -470,7 +471,7 @@ public class AbstractPopup implements JBPopup, ScreenAreaConsumer, AlignedPopup,
myCancelKeyEnabled = cancelKeyEnabled;
myLocateByContent = locateByContent;
- myLocateWithinScreen = placeWithinScreenBounds && !StartupUiUtil.isWaylandToolkit();
+ myLocateWithinScreen = placeWithinScreenBounds && !ClientSystemInfo.isWaylandToolkit();
myAlpha = alpha;
myMaskProvider = maskProvider;
myInStack = inStack;
@@ -1377,7 +1378,7 @@ public class AbstractPopup implements JBPopup, ScreenAreaConsumer, AlignedPopup,
LOG.warn(sb.toString());
}
Rectangle original = new Rectangle(targetBounds);
- if (StartupUiUtil.isWaylandToolkit()) {
+ if (ClientSystemInfo.isWaylandToolkit()) {
var hadToFit = fitSizeToScreen(targetBounds, screen);
if (hadToFit && LOG.isDebugEnabled()) {
LOG.debug("Target bounds after resizing to fit the screen: " + targetBounds);
@@ -1427,7 +1428,7 @@ public class AbstractPopup implements JBPopup, ScreenAreaConsumer, AlignedPopup,
popupOwner = root.getRootPane();
LOG.debug("popup owner fixed for JDK cache");
}
- if (StartupUiUtil.isWaylandToolkit()) {
+ if (ClientSystemInfo.isWaylandToolkit()) {
// In Wayland, popup's owner must be a toplevel, i.e., a window or another popup that is also a window:
popupOwner = SwingUtilities.getRoot(popupOwner);
targetBounds.setLocation(getLocationRelativeToParent(targetBounds, (Window) popupOwner));
@@ -1573,7 +1574,7 @@ public class AbstractPopup implements JBPopup, ScreenAreaConsumer, AlignedPopup,
PopupLocationTracker.register(this);
- if (StartupUiUtil.isWaylandToolkit()) {
+ if (ClientSystemInfo.isWaylandToolkit()) {
var hadToFit = fitSizeToScreen(bounds, screen);
if (hadToFit && LOG.isDebugEnabled()) {
LOG.debug("Popup shown larger than the screen, adjusted: " + targetBounds);
@@ -1835,7 +1836,7 @@ public class AbstractPopup implements JBPopup, ScreenAreaConsumer, AlignedPopup,
}
private static void fitToVisibleArea(Rectangle targetBounds) {
- if (StartupUiUtil.isWaylandToolkit()) return; // Wrt screen edges, only the Wayland server can reliably position popups
+ if (ClientSystemInfo.isWaylandToolkit()) return; // Wrt screen edges, only the Wayland server can reliably position popups
Point topLeft = new Point(targetBounds.x, targetBounds.y);
Point bottomRight = new Point((int)targetBounds.getMaxX(), (int)targetBounds.getMaxY());
@@ -2105,7 +2106,7 @@ public class AbstractPopup implements JBPopup, ScreenAreaConsumer, AlignedPopup,
final Window wnd = popup.getWindow();
assert wnd != null;
- if (StartupUiUtil.isWaylandToolkit() && wnd.getType() == Window.Type.POPUP && myOwner != null) {
+ if (ClientSystemInfo.isWaylandToolkit() && wnd.getType() == Window.Type.POPUP && myOwner != null) {
Rectangle newBounds = wnd.getBounds();
newBounds.setLocation(p.getScreenPoint());
Component parent = SwingUtilities.getRoot(myOwner);
@@ -2580,7 +2581,7 @@ public class AbstractPopup implements JBPopup, ScreenAreaConsumer, AlignedPopup,
size = window.getPreferredSize();
}
- if (StartupUiUtil.isWaylandToolkit() && useScreenLocation
+ if (ClientSystemInfo.isWaylandToolkit() && useScreenLocation
&& myPopup.getWindow().getType() == Window.Type.POPUP
&& myOwner != null) {
// The location is in the screen coordinates, but popups need to be positioned relative to their parent
@@ -3125,7 +3126,7 @@ public class AbstractPopup implements JBPopup, ScreenAreaConsumer, AlignedPopup,
}
private static boolean shouldUseTrueWaylandPopups() {
- return StartupUiUtil.isWaylandToolkit() && Registry.is("wayland.true.popups", false);
+ return ClientSystemInfo.isWaylandToolkit() && Registry.is("wayland.true.popups", false);
}
@Override
diff --git a/platform/platform-impl/src/com/intellij/ui/popup/WizardPopup.java b/platform/platform-impl/src/com/intellij/ui/popup/WizardPopup.java
index 06f810361efa..a005d151ee91 100644
--- a/platform/platform-impl/src/com/intellij/ui/popup/WizardPopup.java
+++ b/platform/platform-impl/src/com/intellij/ui/popup/WizardPopup.java
@@ -6,6 +6,7 @@ import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.ShortcutProvider;
import com.intellij.openapi.actionSystem.ShortcutSet;
import com.intellij.openapi.application.WriteIntentReadAction;
+import com.intellij.openapi.client.ClientSystemInfo;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.DumbAwareAction;
import com.intellij.openapi.project.Project;
@@ -31,7 +32,6 @@ import com.intellij.ui.speedSearch.ElementFilter;
import com.intellij.ui.speedSearch.SpeedSearch;
import com.intellij.ui.wayland.WaylandUtilKt;
import com.intellij.util.ui.JBUI;
-import com.intellij.util.ui.StartupUiUtil;
import com.intellij.util.ui.TimerUtil;
import org.intellij.lang.annotations.JdkConstants;
import org.jetbrains.annotations.ApiStatus;
@@ -396,7 +396,7 @@ public abstract class WizardPopup extends AbstractPopup implements ActionListene
private static @Nullable Integer computeNotBiggerHeight(@NotNull Dimension ofContent, @Nullable Component focusOwner) {
@Nullable Integer screenHeight = null;
- if (StartupUiUtil.isWaylandToolkit()) {
+ if (ClientSystemInfo.isWaylandToolkit()) {
screenHeight = WaylandUtilKt.getFakeScreenHeight(focusOwner);
}
else {
diff --git a/platform/platform-impl/src/com/intellij/ui/popup/list/ListPopupImpl.java b/platform/platform-impl/src/com/intellij/ui/popup/list/ListPopupImpl.java
index 9ee9e42af667..371f2df9a135 100644
--- a/platform/platform-impl/src/com/intellij/ui/popup/list/ListPopupImpl.java
+++ b/platform/platform-impl/src/com/intellij/ui/popup/list/ListPopupImpl.java
@@ -52,7 +52,6 @@ import com.intellij.util.ObjectUtils;
import com.intellij.util.SlowOperations;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.ui.JBInsets;
-import com.intellij.util.ui.StartupUiUtil;
import com.intellij.util.ui.UIUtil;
import com.intellij.util.ui.accessibility.ScreenReader;
import kotlin.Unit;
@@ -670,7 +669,7 @@ public class ListPopupImpl extends WizardPopup implements ListPopup, NextStepHan
if (!UiInterceptors.tryIntercept(myChild)) {
// Intercept child popup in tests because it is impossible to calculate location on screen there
var childLocation = new Point(container.getLocationOnScreen().x + container.getWidth() - STEP_X_PADDING, y);
- if (StartupUiUtil.isWaylandToolkit()) {
+ if (ClientSystemInfo.isWaylandToolkit()) {
SwingUtilities.convertPointFromScreen(childLocation, container);
var childBounds = new Rectangle(childLocation, myChild.getPreferredContentSize());
WaylandUtilKt.moveToFitChildPopupX(childBounds, container);