Blob Blame History Raw
diff --git a/widget/gtk/nsWindow.h b/widget/gtk/nsWindow.h
--- a/widget/gtk/nsWindow.h
+++ b/widget/gtk/nsWindow.h
@@ -487,6 +487,7 @@
   GtkWidget* mShell;
   MozContainer* mContainer;
   GdkWindow* mGdkWindow;
+  GtkWindow* mToplevelParentWindow;
   bool mWindowShouldStartDragging = false;
   PlatformCompositorWidgetDelegate* mCompositorWidgetDelegate;
 
diff --git a/widget/gtk/nsWindow.cpp b/widget/gtk/nsWindow.cpp
--- a/widget/gtk/nsWindow.cpp
+++ b/widget/gtk/nsWindow.cpp
@@ -401,6 +401,7 @@
   mContainer = nullptr;
   mGdkWindow = nullptr;
   mShell = nullptr;
+  mToplevelParentWindow = nullptr;
   mCompositorWidgetDelegate = nullptr;
   mHasMappedToplevel = false;
   mIsFullyObscured = false;
@@ -1144,6 +1145,8 @@
     nsWindow* window =
         static_cast<nsWindow*>(gVisibleWaylandPopupWindows->data);
     if (window->mPopupType != ePopupTypeTooltip) break;
+    LOG(("nsWindow::HideWaylandTooltips [%p] hidding tooltip [%p].\n",
+         (void*)this, window));
     window->HideWaylandWindow();
     gVisibleWaylandPopupWindows = g_list_delete_link(
         gVisibleWaylandPopupWindows, gVisibleWaylandPopupWindows);
@@ -1172,9 +1175,12 @@
 // before we open another one on that level. It means that every open
 // popup needs to have an unique parent.
 GtkWidget* nsWindow::ConfigureWaylandPopupWindows() {
+  LOG(("nsWindow::ConfigureWaylandPopupWindows [%p]\n", (void*)this));
+
   // Check if we're already configured.
   if (gVisibleWaylandPopupWindows &&
       g_list_find(gVisibleWaylandPopupWindows, this)) {
+    LOG(("...[%p] is already configured.\n", (void*)this));
     return GTK_WIDGET(gtk_window_get_transient_for(GTK_WINDOW(mShell)));
   }
 
@@ -1182,9 +1188,15 @@
   // as it's short lived temporary window.
   HideWaylandTooltips();
 
-  GtkWindow* parentWidget = nullptr;
+  GtkWindow* parentWidget = mToplevelParentWindow;
   if (gVisibleWaylandPopupWindows) {
+    LOG(("... there's visible active popup [%p]\n",
+         gVisibleWaylandPopupWindows->data));
+
     if (mPopupType == ePopupTypeTooltip) {
+      LOG(("...[%p] is tooltip, parent [%p]\n", (void*)this,
+           gVisibleWaylandPopupWindows->data));
+
       // Attach tooltip window to the latest popup window
       // to have both visible.
       nsWindow* window =
@@ -1200,12 +1212,19 @@
       // nsWindow::Create()) or we're toplevel popup without parent.
       // In both cases just use parent which was passed to nsWindow::Create().
       if (!menuPopupFrame) {
-        return GTK_WIDGET(gtk_window_get_transient_for(GTK_WINDOW(mShell)));
+        LOG(("...[%p] menuPopupFrame = null, using given parent widget [%p]\n",
+             (void*)this, parentWidget));
+        return GTK_WIDGET(parentWidget);
       }
 
       nsWindow* parentWindow =
           static_cast<nsWindow*>(menuPopupFrame->GetParentMenuWidget());
+      LOG(("...[%p] GetParentMenuWidget() = %p\n", (void*)this, parentWindow));
+
       if (!parentWindow) {
+        LOG(("...[%p] using active/visible popups as a parent [%p]\n",
+             (void*)this, gVisibleWaylandPopupWindows->data));
+
         // We're toplevel popup menu attached to another menu. Just use our
         // latest popup as a parent.
         parentWindow =
@@ -1234,10 +1253,10 @@
     }
   }
 
+  MOZ_ASSERT(parentWidget, "Missing parent widget for wayland popup!");
   if (parentWidget) {
+    LOG(("...[%p] set parent widget [%p]\n", (void*)this, parentWidget));
     gtk_window_set_transient_for(GTK_WINDOW(mShell), parentWidget);
-  } else {
-    parentWidget = gtk_window_get_transient_for(GTK_WINDOW(mShell));
   }
   gVisibleWaylandPopupWindows =
       g_list_prepend(gVisibleWaylandPopupWindows, this);
@@ -1248,9 +1267,11 @@
 static void NativeMoveResizeWaylandPopupCallback(
     GdkWindow* window, const GdkRectangle* flipped_rect,
     const GdkRectangle* final_rect, gboolean flipped_x, gboolean flipped_y,
-    void* unused) {
-  LOG(("%s flipped %d %d\n", __FUNCTION__, flipped_rect->x, flipped_rect->y));
-  LOG(("%s final %d %d\n", __FUNCTION__, final_rect->x, final_rect->y));
+    void* aWindow) {
+  LOG(("%s [%p] flipped %d %d\n", __FUNCTION__, aWindow, flipped_rect->x,
+       flipped_rect->y));
+  LOG(("%s [%p] final %d %d\n", __FUNCTION__, aWindow, final_rect->x,
+       final_rect->y));
 }
 #endif
 
@@ -1264,6 +1285,8 @@
   // Compositor may be confused by windows with width/height = 0
   // and positioning such windows leads to Bug 1555866.
   if (!AreBoundsSane()) {
+    LOG(("nsWindow::NativeMoveResizeWaylandPopup [%p] Bounds are not sane\n",
+         (void*)this));
     return;
   }
 
@@ -1277,6 +1300,8 @@
   // - gdk_window_move_to_rect() is not available
   // - the widget doesn't have a valid GdkWindow
   if (!sGdkWindowMoveToRect || !gdkWindow) {
+    LOG(("nsWindow::NativeMoveResizeWaylandPopup [%p] use gtk_window_move()\n",
+         (void*)this));
     gtk_window_move(GTK_WINDOW(mShell), aPosition->x, aPosition->y);
     return;
   }
@@ -1302,8 +1327,12 @@
   }
   LOG(("  request result %d %d\n", rect.x, rect.y));
 #ifdef DEBUG
-  g_signal_connect(gdkWindow, "moved-to-rect",
-                   G_CALLBACK(NativeMoveResizeWaylandPopupCallback), this);
+  if (!g_signal_handler_find(
+          gdkWindow, G_SIGNAL_MATCH_FUNC, 0, 0, nullptr,
+          FuncToGpointer(NativeMoveResizeWaylandPopupCallback), this)) {
+    g_signal_connect(gdkWindow, "moved-to-rect",
+                     G_CALLBACK(NativeMoveResizeWaylandPopupCallback), this);
+  }
 #endif
 
   GdkGravity rectAnchor = GDK_GRAVITY_NORTH_WEST;
@@ -3508,7 +3537,6 @@
   GtkWidget* parentMozContainer = nullptr;
   GtkContainer* parentGtkContainer = nullptr;
   GdkWindow* parentGdkWindow = nullptr;
-  GtkWindow* topLevelParent = nullptr;
   nsWindow* parentnsWindow = nullptr;
   GtkWidget* eventWidget = nullptr;
   bool drawToContainer = false;
@@ -3534,7 +3562,8 @@
 
     // get the toplevel window just in case someone needs to use it
     // for setting transients or whatever.
-    topLevelParent = GTK_WINDOW(gtk_widget_get_toplevel(parentMozContainer));
+    mToplevelParentWindow =
+        GTK_WINDOW(gtk_widget_get_toplevel(parentMozContainer));
   }
 
   if (!mIsX11Display) {
@@ -3542,7 +3571,7 @@
       // eWindowType_child is not supported on Wayland. Just switch to toplevel
       // as a workaround.
       mWindowType = eWindowType_toplevel;
-    } else if (mWindowType == eWindowType_popup && !topLevelParent) {
+    } else if (mWindowType == eWindowType_popup && !mToplevelParentWindow) {
       // Workaround for Wayland where the popup windows always need to have
       // parent window. For example webrtc ui is a popup window without parent.
       mWindowType = eWindowType_toplevel;
@@ -3677,7 +3706,7 @@
                                gdk_get_program_class());
         gtk_window_set_type_hint(GTK_WINDOW(mShell),
                                  GDK_WINDOW_TYPE_HINT_DIALOG);
-        gtk_window_set_transient_for(GTK_WINDOW(mShell), topLevelParent);
+        gtk_window_set_transient_for(GTK_WINDOW(mShell), mToplevelParentWindow);
       } else if (mWindowType == eWindowType_popup) {
         gtk_window_set_wmclass(GTK_WINDOW(mShell), "Popup",
                                gdk_get_program_class());
@@ -3730,10 +3759,11 @@
         }
         gtk_window_set_type_hint(GTK_WINDOW(mShell), gtkTypeHint);
 
-        if (topLevelParent) {
+        if (mToplevelParentWindow) {
           LOG(("nsWindow::Create [%p] Set popup parent %p\n", (void*)this,
-               topLevelParent));
-          gtk_window_set_transient_for(GTK_WINDOW(mShell), topLevelParent);
+               mToplevelParentWindow));
+          gtk_window_set_transient_for(GTK_WINDOW(mShell),
+                                       mToplevelParentWindow);
         }
 
         // We need realized mShell at NativeMove().
@@ -4011,7 +4041,8 @@
 #endif
   }
 
-  LOG(("nsWindow [%p]\n", (void*)this));
+  LOG(("nsWindow [%p] %s\n", (void*)this,
+       mWindowType == eWindowType_toplevel ? "Toplevel" : "Popup"));
   if (mShell) {
     LOG(("\tmShell %p mContainer %p mGdkWindow %p 0x%lx\n", mShell, mContainer,
          mGdkWindow, mIsX11Display ? gdk_x11_window_get_xid(mGdkWindow) : 0));