mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-10-06 06:21:16 +07:00
[UI, Wayland] IJPL-235513 Close the Show Usages popup when a usage is selected
A rather hacky way, but it should do the trick. An alternative approach: somehow track the navigation and close the popup manually when it's done. But it's riskier and would potentially affect non-Wayland environments. (cherry picked from commit 65990e6a178e81b663f3d411dd8ad7b7b2bd8063) IJ-CR-193931 GitOrigin-RevId: e2ded5b02d7cae6d88968b55ffe5748a090bf858
This commit is contained in:
committed by
intellij-monorepo-bot
parent
a248ced99f
commit
43c46ce1ec
@@ -20,6 +20,7 @@ import com.intellij.ui.ScrollingUtil;
|
||||
import com.intellij.ui.SpeedSearchBase;
|
||||
import com.intellij.ui.SpeedSearchComparator;
|
||||
import com.intellij.ui.TableUtil;
|
||||
import com.intellij.ui.popup.AbstractPopup;
|
||||
import com.intellij.ui.popup.HintUpdateSupply;
|
||||
import com.intellij.ui.table.JBTable;
|
||||
import com.intellij.usageView.UsageInfo;
|
||||
@@ -215,6 +216,10 @@ public final class ShowUsagesTable extends JBTable implements UiDataProvider {
|
||||
navigateBlocking(parameters.project, navigatable, NavigationOptions.requestFocus(), dataContext);
|
||||
}
|
||||
}
|
||||
var popup = PopupUtil.getPopupContainerFor(this);
|
||||
if (popup instanceof AbstractPopup abstractPopup) {
|
||||
abstractPopup.setForceCancelOnFocusLoss(true); // Disable the Wayland focus workaround and allow it to close.
|
||||
}
|
||||
UsageNavigation.getInstance(parameters.project).navigate(usageInfosToNavigate, true, dataContext);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -233,6 +233,7 @@ public class AbstractPopup implements JBPopup, ScreenAreaConsumer, AlignedPopup,
|
||||
private JComponent myPreferredFocusedComponent;
|
||||
private boolean myRequestFocus;
|
||||
private boolean myFocusable;
|
||||
private boolean myForceCancelOnFocusLoss;
|
||||
private boolean myForcedHeavyweight;
|
||||
private boolean myLocateWithinScreen;
|
||||
private boolean myResizable;
|
||||
@@ -2321,6 +2322,39 @@ public class AbstractPopup implements JBPopup, ScreenAreaConsumer, AlignedPopup,
|
||||
myCancelOnClickOutside = cancelOnClickOutside;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disables Wayland-specific workarounds for popup focus loss.
|
||||
* <p>
|
||||
* Normally a focusable popup is closed when another window gets focus.
|
||||
* A non-focusable popup is also closed when that window is not an ancestor of the popup.
|
||||
* </p>
|
||||
* <p>
|
||||
* However, on Wayland due to various focus quirks, this behavior is disabled by default,
|
||||
* because the owner window may get focus for no reason.
|
||||
* </p>
|
||||
* <p>
|
||||
* In most cases it isn't an issue. For example, when the user clicks outside the popup,
|
||||
* then it's closed anyway because it's the click itself that closes the popup, not the resulting focus loss.
|
||||
* In some cases, however, it might be necessary to react to focus changes.
|
||||
* One such example is the show usages popup that opens a focused editor when a usage is selected.
|
||||
* In this case, we rely on the focus change to close the popup.
|
||||
* </p>
|
||||
* <p>
|
||||
* This function should be called whenever we do something and expect a focus change as a result,
|
||||
* and that focus change should close the popup.
|
||||
* This is, of course, a hack, and therefore is generally not recommended,
|
||||
* provided there's a reliable way to just close the popup by explicitly calling {@link #cancel()} instead.
|
||||
* But it's not always an option, as the activity triggered by the popup can be asynchronous in nature and hard to track,
|
||||
* as it's the case with usage navigation.
|
||||
* </p>
|
||||
*
|
||||
* @param forceCancelOnFocusLoss pass {@code true} here to enable the normal behavior on Wayland
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
public void setForceCancelOnFocusLoss(boolean forceCancelOnFocusLoss) {
|
||||
myForceCancelOnFocusLoss = forceCancelOnFocusLoss;
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
public void setIsMovable(boolean movable) {
|
||||
myMovable = movable;
|
||||
@@ -3036,6 +3070,8 @@ public class AbstractPopup implements JBPopup, ScreenAreaConsumer, AlignedPopup,
|
||||
return false;
|
||||
}
|
||||
|
||||
if (myForceCancelOnFocusLoss) return true;
|
||||
|
||||
// On Wayland focus gets temporarily transferred to popup's owner while the popup is being
|
||||
// interactively moved.
|
||||
// This is not a reason for cancelling the popup.
|
||||
|
||||
Reference in New Issue
Block a user