IDEA-192055 Focus goes nowhere after breakpoint popup

This commit is contained in:
Denis Fokin
2018-05-28 16:42:54 +03:00
parent 92d42621b7
commit 5ad3469deb
3 changed files with 83 additions and 4 deletions
@@ -0,0 +1,53 @@
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.openapi.wm;
import com.intellij.util.containers.WeakList;
import javax.swing.*;
import java.awt.*;
import java.awt.event.AWTEventListener;
import java.awt.event.FocusEvent;
import java.util.List;
public class WeakFocusStackManager {
private final WeakList <Component> focusOwners = new WeakList<>();
private static final WeakFocusStackManager instance = new WeakFocusStackManager();
public Component getLastFocusedOutside(Container container) {
Component[] components = focusOwners.toStrongList().toArray(new Component[0]);
for (int i = components.length - 1; i >= 0; i--) {
if (!SwingUtilities.isDescendingFrom(components[i], container)) {
return components[i];
}
}
return null;
}
public static WeakFocusStackManager getInstance() {
return instance;
}
private WeakFocusStackManager () {
Toolkit.getDefaultToolkit().addAWTEventListener(new AWTEventListener() {
@Override
public void eventDispatched(AWTEvent event) {
// We are interested only in FOCUS_GAINED events
if (event.getID() == FocusEvent.FOCUS_GAINED) {
focusOwners.add((Component)event.getSource());
}
}
}, AWTEvent.FOCUS_EVENT_MASK);
}
public Component getLastFocusedComponent() {
List<Component> strongList = focusOwners.toStrongList();
return strongList.isEmpty() ? null : strongList.get(strongList.size() - 1);
}
public Component getLastButOneFocusedComponent() {
List<Component> strongList = focusOwners.toStrongList();
return strongList.size() < 2 ? null : strongList.get(strongList.size() - 2);
}
}
@@ -22,6 +22,7 @@ import com.intellij.openapi.util.ActionCallback;
import com.intellij.openapi.util.ExpirableRunnable;
import com.intellij.openapi.wm.IdeFocusManager;
import com.intellij.openapi.wm.IdeFrame;
import com.intellij.openapi.wm.WeakFocusStackManager;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -33,6 +34,7 @@ public class IdeFocusManagerImpl extends IdeFocusManager {
public IdeFocusManagerImpl(ToolWindowManagerImpl twManager) {
myToolWindowManager = twManager;
WeakFocusStackManager.getInstance();
}
@Override
@@ -18,10 +18,7 @@ import com.intellij.openapi.ui.popup.JBPopupListener;
import com.intellij.openapi.ui.popup.LightweightWindowEvent;
import com.intellij.openapi.util.*;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.wm.FocusRequestor;
import com.intellij.openapi.wm.IdeFocusManager;
import com.intellij.openapi.wm.IdeGlassPane;
import com.intellij.openapi.wm.IdeGlassPaneUtil;
import com.intellij.openapi.wm.*;
import com.intellij.openapi.wm.impl.IdeGlassPaneEx;
import com.intellij.ui.awt.RelativePoint;
import com.intellij.ui.components.panels.NonOpaquePanel;
@@ -1626,6 +1623,33 @@ public class BalloonImpl implements Balloon, IdeTooltip.Ui {
myContent.setOpaque(false);
add(myContent);
setFocusTraversalPolicyProvider(true);
setFocusTraversalPolicy(new FocusTraversalPolicy() {
@Override
public Component getComponentAfter(Container aContainer, Component aComponent) {
return WeakFocusStackManager.getInstance().getLastFocusedOutside(MyComponent.this);
}
@Override
public Component getComponentBefore(Container aContainer, Component aComponent) {
return WeakFocusStackManager.getInstance().getLastFocusedOutside(MyComponent.this);
}
@Override
public Component getFirstComponent(Container aContainer) {
return WeakFocusStackManager.getInstance().getLastFocusedOutside(MyComponent.this);
}
@Override
public Component getLastComponent(Container aContainer) {
return WeakFocusStackManager.getInstance().getLastFocusedOutside(MyComponent.this);
}
@Override
public Component getDefaultComponent(Container aContainer) {
return WeakFocusStackManager.getInstance().getLastFocusedOutside(MyComponent.this);
}
});
}
public Rectangle getContentBounds() {