99 lines
3.9 KiB
Diff
99 lines
3.9 KiB
Diff
diff --git a/widget/gtk/nsWindow.h b/widget/gtk/nsWindow.h
|
|
--- a/widget/gtk/nsWindow.h
|
|
+++ b/widget/gtk/nsWindow.h
|
|
@@ -401,6 +401,8 @@
|
|
#ifdef MOZ_WAYLAND
|
|
virtual nsresult GetScreenRect(LayoutDeviceIntRect* aRect) override;
|
|
#endif
|
|
+ bool IsRemoteContent() { return HasRemoteContent(); }
|
|
+ static void HideWaylandOpenedPopups();
|
|
|
|
protected:
|
|
virtual ~nsWindow();
|
|
diff --git a/widget/gtk/nsWindow.cpp b/widget/gtk/nsWindow.cpp
|
|
--- a/widget/gtk/nsWindow.cpp
|
|
+++ b/widget/gtk/nsWindow.cpp
|
|
@@ -1165,6 +1165,14 @@
|
|
}
|
|
}
|
|
|
|
+void nsWindow::HideWaylandOpenedPopups() {
|
|
+ while (gVisibleWaylandPopupWindows) {
|
|
+ nsWindow* window =
|
|
+ static_cast<nsWindow*>(gVisibleWaylandPopupWindows->data);
|
|
+ window->HideWaylandWindow();
|
|
+ }
|
|
+}
|
|
+
|
|
// Hide popup nsWindows which are no longer in the nsXULPopupManager widget
|
|
// chain list.
|
|
void nsWindow::CleanupWaylandPopups() {
|
|
@@ -1218,7 +1226,10 @@
|
|
// popup needs to have an unique parent.
|
|
GtkWidget* nsWindow::ConfigureWaylandPopupWindows() {
|
|
MOZ_ASSERT(this->mWindowType == eWindowType_popup);
|
|
- LOG(("nsWindow::ConfigureWaylandPopupWindows [%p]\n", (void*)this));
|
|
+ LOG(
|
|
+ ("nsWindow::ConfigureWaylandPopupWindows [%p], frame %p hasRemoteContent "
|
|
+ "%d\n",
|
|
+ (void*)this, this->GetFrame(), this->HasRemoteContent()));
|
|
#if DEBUG
|
|
if (this->GetFrame() && this->GetFrame()->GetContent()->GetID()) {
|
|
nsCString nodeId;
|
|
@@ -1245,14 +1256,14 @@
|
|
// gVisibleWaylandPopupWindows which were not yet been hidden.
|
|
CleanupWaylandPopups();
|
|
// Since the popups are shown by unknown order it can happen that child
|
|
- // popup is shown before parent popup. The
|
|
+ // popup is shown before parent popup.
|
|
// We look for the current window parent in nsXULPopupManager since it
|
|
// always has correct popup hierarchy while gVisibleWaylandPopupWindows may
|
|
// not.
|
|
nsXULPopupManager* pm = nsXULPopupManager::GetInstance();
|
|
AutoTArray<nsIWidget*, 5> widgetChain;
|
|
pm->GetSubmenuWidgetChain(&widgetChain);
|
|
- for (unsigned long i = 0; i < widgetChain.Length(); i++) {
|
|
+ for (unsigned long i = 0; i < widgetChain.Length() - 1; i++) {
|
|
unsigned long parentIndex = i + 1;
|
|
if (widgetChain.Length() > parentIndex && widgetChain[i] == this) {
|
|
nsWindow* parentWindow =
|
|
@@ -1264,6 +1275,29 @@
|
|
}
|
|
}
|
|
} else {
|
|
+ // Panels usually ends there
|
|
+ if (gVisibleWaylandPopupWindows && HasRemoteContent()) {
|
|
+ // If the new panel is remote content, we need to close all other popups
|
|
+ // before to keep the correct hierarchy because the remote content popup
|
|
+ // can replace the overflow-widget panel.
|
|
+ HideWaylandOpenedPopups();
|
|
+ } else if (gVisibleWaylandPopupWindows) {
|
|
+ // If there is any remote content panel currently opened, close all
|
|
+ // opened popups to keep the correct hierarchy.
|
|
+ GList* popupList = gVisibleWaylandPopupWindows;
|
|
+ while (popupList) {
|
|
+ nsWindow* waylandWnd = static_cast<nsWindow*>(popupList->data);
|
|
+ LOG((" Checking [%p] IsRemoteContent %d\n", popupList->data,
|
|
+ waylandWnd->IsRemoteContent()));
|
|
+ if (waylandWnd->IsRemoteContent()) {
|
|
+ // close all popups including remote content before showing our panel
|
|
+ // Most likely returning from addon panel to overflow-widget.
|
|
+ HideWaylandOpenedPopups();
|
|
+ break;
|
|
+ }
|
|
+ popupList = popupList->next;
|
|
+ }
|
|
+ }
|
|
// For popups in panels use the last opened popup window as parent,
|
|
// panels are not stored in nsXULPopupManager.
|
|
if (gVisibleWaylandPopupWindows) {
|
|
@@ -4380,6 +4414,7 @@
|
|
void nsWindow::HideWaylandWindow() {
|
|
#ifdef MOZ_WAYLAND
|
|
if (mWindowType == eWindowType_popup) {
|
|
+ LOG(("nsWindow::HideWaylandWindow: popup [%p]\n", this));
|
|
GList* foundWindow = g_list_find(gVisibleWaylandPopupWindows, this);
|
|
if (foundWindow) {
|
|
gVisibleWaylandPopupWindows =
|
|
|