mirror of
https://github.com/JetBrains/JetBrainsRuntime.git
synced 2025-12-06 09:29:38 +01:00
JBR-2698 setAutoRequestFocus(false) breaks focus logic under i3 window manager on Linux
(cherry picked from commit ebcdeb7d80)
This commit is contained in:
@@ -77,7 +77,6 @@ public class XBaseWindow {
|
||||
|
||||
private static XAtom wm_client_leader;
|
||||
|
||||
private long userTime;
|
||||
private static long globalUserTime;
|
||||
|
||||
static enum InitialiseState {
|
||||
@@ -654,7 +653,7 @@ public class XBaseWindow {
|
||||
try {
|
||||
this.visible = visible;
|
||||
if (visible) {
|
||||
setUserTimeFromGlobal();
|
||||
setUserTimeBeforeShowing();
|
||||
XlibWrapper.XMapWindow(XToolkit.getDisplay(), getWindow());
|
||||
}
|
||||
else {
|
||||
@@ -1014,7 +1013,7 @@ public class XBaseWindow {
|
||||
public void handleVisibilityEvent(XEvent xev) {
|
||||
}
|
||||
public void handleKeyPress(XEvent xev) {
|
||||
setUserTime(xev.get_xkey().get_time());
|
||||
setUserTime(xev.get_xkey().get_time(), true);
|
||||
}
|
||||
public void handleKeyRelease(XEvent xev) {
|
||||
}
|
||||
@@ -1047,7 +1046,7 @@ public class XBaseWindow {
|
||||
if (!isWheel) {
|
||||
switch (xev.get_type()) {
|
||||
case XConstants.ButtonPress:
|
||||
setUserTime(xbe.get_time());
|
||||
setUserTime(xbe.get_time(), true);
|
||||
if (buttonState == 0) {
|
||||
XWindowPeer parent = getToplevelXWindow();
|
||||
// See 6385277, 6981400.
|
||||
@@ -1265,15 +1264,12 @@ public class XBaseWindow {
|
||||
return x >= getAbsoluteX() && y >= getAbsoluteY() && x < (getAbsoluteX()+getWidth()) && y < (getAbsoluteY()+getHeight());
|
||||
}
|
||||
|
||||
void setUserTimeFromGlobal() {
|
||||
setUserTime(globalUserTime);
|
||||
void setUserTimeBeforeShowing() {
|
||||
if (globalUserTime != 0) setUserTime(globalUserTime, false);
|
||||
}
|
||||
|
||||
protected void setUserTime(long time) {
|
||||
if (time == userTime) return;
|
||||
|
||||
userTime = time;
|
||||
if ((int)time - (int)globalUserTime > 0 /* accounting for wrap-around */) {
|
||||
protected void setUserTime(long time, boolean updateGlobalTime) {
|
||||
if (updateGlobalTime && (int)time - (int)globalUserTime > 0 /* accounting for wrap-around */) {
|
||||
globalUserTime = time;
|
||||
}
|
||||
XNETProtocol netProtocol = XWM.getWM().getNETProtocol();
|
||||
|
||||
@@ -1093,7 +1093,7 @@ abstract class XDecoratedPeer extends XWindowPeer {
|
||||
}
|
||||
// we should treat WM_TAKE_FOCUS message as user interaction, as it can originate e.g. from user clicking
|
||||
// on window title bar (there will be no ButtonPress/ButtonRelease events in this case)
|
||||
setUserTime(requestTimeStamp);
|
||||
setUserTime(requestTimeStamp, true);
|
||||
|
||||
if (XWM.getWMID() == XWM.UNITY_COMPIZ_WM) {
|
||||
// JDK-8159460
|
||||
|
||||
@@ -110,7 +110,8 @@ final class XWM
|
||||
MUTTER_WM = 15,
|
||||
UNITY_COMPIZ_WM = 16,
|
||||
XMONAD_WM = 17,
|
||||
AWESOME_WM = 18;
|
||||
AWESOME_WM = 18,
|
||||
I3_WM = 19;
|
||||
|
||||
public String toString() {
|
||||
switch (WMID) {
|
||||
@@ -621,6 +622,10 @@ final class XWM
|
||||
return isNetWMName("awesome");
|
||||
}
|
||||
|
||||
static boolean isI3() {
|
||||
return isNetWMName("i3");
|
||||
}
|
||||
|
||||
static int awtWMNonReparenting = -1;
|
||||
static boolean isNonReparentingWM() {
|
||||
if (awtWMNonReparenting == -1) {
|
||||
@@ -824,6 +829,8 @@ final class XWM
|
||||
awt_wmgr = XWM.XMONAD_WM;
|
||||
} else if (isAwesome()) {
|
||||
awt_wmgr = XWM.AWESOME_WM;
|
||||
} else if (isI3()) {
|
||||
awt_wmgr = XWM.I3_WM;
|
||||
}
|
||||
/*
|
||||
* We don't check for legacy WM when we already know that WM
|
||||
|
||||
@@ -1105,7 +1105,7 @@ class XWindowPeer extends XPanelPeer implements WindowPeer,
|
||||
if (!isVisible() && vis) {
|
||||
isBeforeFirstMapNotify = true;
|
||||
winAttr.initialFocus = isAutoRequestFocus();
|
||||
if (!winAttr.initialFocus) {
|
||||
if (!winAttr.initialFocus && XWM.getWMID() != XWM.I3_WM) {
|
||||
/*
|
||||
* It's easier and safer to temporary suppress WM_TAKE_FOCUS
|
||||
* protocol itself than to ignore WM_TAKE_FOCUS client message.
|
||||
@@ -1113,6 +1113,13 @@ class XWindowPeer extends XPanelPeer implements WindowPeer,
|
||||
* the message come after showing and the message come after
|
||||
* activation. Also, on Metacity, for some reason, we have _two_
|
||||
* WM_TAKE_FOCUS client messages when showing a frame/dialog.
|
||||
*
|
||||
* i3 window manager doesn't track updates to WM_TAKE_FOCUS
|
||||
* property, so this approach won't work for it, breaking
|
||||
* focus behaviour completely. So another way is used to
|
||||
* suppress focus take over - via setting _NET_WM_USER_TIME
|
||||
* to 0, as specified in EWMH spec (see
|
||||
* 'setUserTimeBeforeShowing' method).
|
||||
*/
|
||||
suppressWmTakeFocus(true);
|
||||
}
|
||||
@@ -1177,6 +1184,16 @@ class XWindowPeer extends XPanelPeer implements WindowPeer,
|
||||
protected void suppressWmTakeFocus(boolean doSuppress) {
|
||||
}
|
||||
|
||||
@Override
|
||||
void setUserTimeBeforeShowing() {
|
||||
if (winAttr.initialFocus || XWM.getWMID() != XWM.I3_WM) {
|
||||
super.setUserTimeBeforeShowing();
|
||||
}
|
||||
else {
|
||||
setUserTime(0, false);
|
||||
}
|
||||
}
|
||||
|
||||
final boolean isSimpleWindow() {
|
||||
return !(target instanceof Frame || target instanceof Dialog);
|
||||
}
|
||||
@@ -1399,7 +1416,7 @@ class XWindowPeer extends XPanelPeer implements WindowPeer,
|
||||
isUnhiding |= isWMStateNetHidden();
|
||||
|
||||
super.handleMapNotifyEvent(xev);
|
||||
if (!winAttr.initialFocus) {
|
||||
if (!winAttr.initialFocus && XWM.getWMID() != XWM.I3_WM) {
|
||||
suppressWmTakeFocus(false); // restore the protocol.
|
||||
/*
|
||||
* For some reason, on Metacity, a frame/dialog being shown
|
||||
@@ -2015,7 +2032,7 @@ class XWindowPeer extends XPanelPeer implements WindowPeer,
|
||||
this.visible = visible;
|
||||
if (visible) {
|
||||
applyWindowType();
|
||||
setUserTimeFromGlobal();
|
||||
setUserTimeBeforeShowing();
|
||||
XlibWrapper.XMapRaised(XToolkit.getDisplay(), getWindow());
|
||||
} else {
|
||||
XlibWrapper.XUnmapWindow(XToolkit.getDisplay(), getWindow());
|
||||
|
||||
Reference in New Issue
Block a user