mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-339714 Wayland: some popup-like windows disappear immediately
GitOrigin-RevId: bec8c2d404cd8615c73eb311335d3c3d1d5c5f91
This commit is contained in:
committed by
intellij-monorepo-bot
parent
43f454ee2d
commit
b1814d0a22
@@ -10,6 +10,7 @@ import com.intellij.openapi.util.registry.Registry;
|
||||
import com.intellij.openapi.wm.IdeFrame;
|
||||
import com.intellij.ui.jcef.JBCefBrowserBase;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.ui.StartupUiUtil;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -46,6 +47,20 @@ public final class IdePopupManager implements IdeEventQueue.EventDispatcher {
|
||||
LOG.warn("Skipped " + e);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (StartupUiUtil.isWaylandToolkit()) {
|
||||
// Reasons for skipping 'focus lost'-like events on Wayland:
|
||||
// - When a new popup window appears, the main frame looses focus, but the "opposite window"
|
||||
// for that event is null (because Wayland); this can be solved by waiting a bit
|
||||
// (several hundreds ms) for
|
||||
// KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusedWindow()
|
||||
// to become non-null.
|
||||
// - When a (popup) window is dragged, it also looses focus (because Wayland); this one is
|
||||
// not solvable because there's no guarantee that the focus will get back, nor is there
|
||||
// a notification that the drag is actually happening.
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!isPopupActive()) return false;
|
||||
|
||||
Window sourceWindow = ((WindowEvent)e).getWindow();
|
||||
@@ -57,36 +72,9 @@ public final class IdePopupManager implements IdeEventQueue.EventDispatcher {
|
||||
return false;
|
||||
}
|
||||
|
||||
Window focused = ((WindowEvent)e).getOppositeWindow();
|
||||
if (focused == null) {
|
||||
focused = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusedWindow();
|
||||
if (focused == null) {
|
||||
// Check if any browser is in focus (java focus can be in the process of transfer).
|
||||
JBCefBrowserBase browser = JBCefBrowserBase.getFocusedBrowser();
|
||||
if (browser != null && browser.getComponent() != null) {
|
||||
focused = SwingUtilities.getWindowAncestor(browser.getComponent());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component ultimateParentForFocusedComponent = UIUtil.findUltimateParent(focused);
|
||||
Component ultimateParentForEventWindow = UIUtil.findUltimateParent(sourceWindow);
|
||||
|
||||
boolean shouldCloseAllPopup = false;
|
||||
if (ultimateParentForEventWindow == null || ultimateParentForFocusedComponent == null) {
|
||||
shouldCloseAllPopup = true;
|
||||
}
|
||||
|
||||
if (!shouldCloseAllPopup && ultimateParentForEventWindow instanceof IdeFrame ultimateParentWindowForEvent) {
|
||||
if (ultimateParentWindowForEvent.isInFullScreen()
|
||||
&& !ultimateParentForFocusedComponent.equals(ultimateParentForEventWindow)) {
|
||||
shouldCloseAllPopup = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (shouldCloseAllPopup) {
|
||||
closeAllPopups();
|
||||
}
|
||||
Window focusedWindow = ((WindowEvent)e).getOppositeWindow();
|
||||
maybeCloseAllPopups(focusedWindow, sourceWindow);
|
||||
return false;
|
||||
}
|
||||
else if (e instanceof KeyEvent keyEvent) {
|
||||
// the following is copied from IdeKeyEventDispatcher
|
||||
@@ -116,6 +104,38 @@ public final class IdePopupManager implements IdeEventQueue.EventDispatcher {
|
||||
return false;
|
||||
}
|
||||
|
||||
private void maybeCloseAllPopups(Window focused, Window sourceWindow) {
|
||||
if (focused == null) {
|
||||
focused = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusedWindow();
|
||||
if (focused == null) {
|
||||
// Check if any browser is in focus (java focus can be in the process of transfer).
|
||||
JBCefBrowserBase browser = JBCefBrowserBase.getFocusedBrowser();
|
||||
if (browser != null && browser.getComponent() != null) {
|
||||
focused = SwingUtilities.getWindowAncestor(browser.getComponent());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component ultimateParentForFocusedComponent = UIUtil.findUltimateParent(focused);
|
||||
Component ultimateParentForEventWindow = UIUtil.findUltimateParent(sourceWindow);
|
||||
|
||||
boolean shouldCloseAllPopup = false;
|
||||
if (ultimateParentForEventWindow == null || ultimateParentForFocusedComponent == null) {
|
||||
shouldCloseAllPopup = true;
|
||||
}
|
||||
|
||||
if (!shouldCloseAllPopup && ultimateParentForEventWindow instanceof IdeFrame ultimateParentWindowForEvent) {
|
||||
if (ultimateParentWindowForEvent.isInFullScreen()
|
||||
&& !ultimateParentForFocusedComponent.equals(ultimateParentForEventWindow)) {
|
||||
shouldCloseAllPopup = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (shouldCloseAllPopup) {
|
||||
closeAllPopups();
|
||||
}
|
||||
}
|
||||
|
||||
public void push(IdePopupEventDispatcher dispatcher) {
|
||||
myDispatchStack.remove(dispatcher);
|
||||
myDispatchStack.add(dispatcher);
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
package com.intellij.ui;
|
||||
|
||||
import com.intellij.util.ui.StartupUiUtil;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import com.jetbrains.JBR;
|
||||
import org.intellij.lang.annotations.JdkConstants;
|
||||
@@ -210,8 +211,12 @@ abstract class WindowMouseListener extends MouseAdapter implements MouseInputLis
|
||||
protected void notifyResized() {}
|
||||
|
||||
private static boolean jbrMoveSupported(Component component) {
|
||||
// The JBR team states that isWindowMoveSupported works only for Frame/Dialog
|
||||
return (component instanceof Frame || component instanceof Dialog)
|
||||
&& JBR.isWindowMoveSupported();
|
||||
if (StartupUiUtil.isWaylandToolkit()) {
|
||||
return (component instanceof Window window) && window.getType() != Window.Type.POPUP;
|
||||
} else {
|
||||
// The JBR team states that isWindowMoveSupported works only for Frame/Dialog
|
||||
return (component instanceof Frame || component instanceof Dialog)
|
||||
&& JBR.isWindowMoveSupported();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user