mirror of
https://github.com/JetBrains/JetBrainsRuntime.git
synced 2025-12-06 09:29:38 +01:00
JBR-6763 Wayland: application crashes when popup closed
Certain Wayland compositors (wlroots) invalidate xdg_surface after window with popup loses focus. Subsequent attempts to
commit the popup window fail with protocol error "xdg_surface has never been configured".
Handle popup_done event by hiding the popup window. Also emit WINDOW_CLOSING event as otherwise focus remains on the popup parent.
Co-authored-by: Maxim Kartashёv <maxim@kartashev.spb.ru>
(cherry picked from commit 873a085de4)
This commit is contained in:
@@ -187,7 +187,9 @@ public class WLComponentPeer implements ComponentPeer {
|
||||
}
|
||||
|
||||
boolean isVisible() {
|
||||
return visible && hasSurface();
|
||||
synchronized (getStateLock()) {
|
||||
return visible && hasSurface();
|
||||
}
|
||||
}
|
||||
|
||||
boolean hasSurface() {
|
||||
@@ -306,7 +308,11 @@ public class WLComponentPeer implements ComponentPeer {
|
||||
}
|
||||
|
||||
protected void wlSetVisible(boolean v) {
|
||||
this.visible = v;
|
||||
synchronized (getStateLock()) {
|
||||
if (this.visible == v) return;
|
||||
|
||||
this.visible = v;
|
||||
}
|
||||
if (v) {
|
||||
String title = getTitle();
|
||||
boolean isWlPopup = targetIsWlPopup();
|
||||
@@ -1324,6 +1330,13 @@ public class WLComponentPeer implements ComponentPeer {
|
||||
checkIfOnNewScreen();
|
||||
}
|
||||
|
||||
void notifyPopupDone() {
|
||||
assert(targetIsWlPopup());
|
||||
setVisible(false);
|
||||
// TODO: may need a better way of notifying interested components about popup disappearance
|
||||
WLToolkit.postEvent(new WindowEvent((Window) target, WindowEvent.WINDOW_CLOSING));
|
||||
}
|
||||
|
||||
private WLGraphicsDevice getGraphicsDevice() {
|
||||
int scale = 0;
|
||||
WLGraphicsDevice theDevice = null;
|
||||
|
||||
@@ -44,6 +44,7 @@ static jmethodID postWindowClosingMID;
|
||||
static jmethodID notifyConfiguredMID;
|
||||
static jmethodID notifyEnteredOutputMID;
|
||||
static jmethodID notifyLeftOutputMID;
|
||||
static jmethodID notifyPopupDoneMID;
|
||||
|
||||
struct activation_token_list_item {
|
||||
struct xdg_activation_token_v1 *token;
|
||||
@@ -263,6 +264,14 @@ xdg_popup_done(void *data,
|
||||
struct xdg_popup *xdg_popup)
|
||||
{
|
||||
J2dTrace1(J2D_TRACE_INFO, "WLComponentPeer: xdg_popup_done(%p)\n", xdg_popup);
|
||||
struct WLFrame *frame = data;
|
||||
JNIEnv *env = getEnv();
|
||||
const jobject nativeFramePeer = (*env)->NewLocalRef(env, frame->nativeFramePeer);
|
||||
if (nativeFramePeer) {
|
||||
(*env)->CallVoidMethod(env, nativeFramePeer, notifyPopupDoneMID);
|
||||
(*env)->DeleteLocalRef(env, nativeFramePeer);
|
||||
JNU_CHECK_EXCEPTION(env);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -313,6 +322,9 @@ Java_sun_awt_wl_WLComponentPeer_initIDs
|
||||
CHECK_NULL_THROW_IE(env,
|
||||
notifyLeftOutputMID = (*env)->GetMethodID(env, clazz, "notifyLeftOutput", "(I)V"),
|
||||
"Failed to find method WLComponentPeer.notifyLeftOutput");
|
||||
CHECK_NULL_THROW_IE(env,
|
||||
notifyPopupDoneMID = (*env)->GetMethodID(env, clazz, "notifyPopupDone", "()V"),
|
||||
"Failed to find method WLComponentPeer.notifyPopupDone");
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
|
||||
Reference in New Issue
Block a user