diff options
Diffstat (limited to 'mozilla-1605795-popup-parent-fix.patch')
-rw-r--r-- | mozilla-1605795-popup-parent-fix.patch | 231 |
1 files changed, 0 insertions, 231 deletions
diff --git a/mozilla-1605795-popup-parent-fix.patch b/mozilla-1605795-popup-parent-fix.patch deleted file mode 100644 index d859893..0000000 --- a/mozilla-1605795-popup-parent-fix.patch +++ /dev/null @@ -1,231 +0,0 @@ -diff --git a/widget/gtk/nsWindow.h b/widget/gtk/nsWindow.h ---- a/widget/gtk/nsWindow.h -+++ b/widget/gtk/nsWindow.h -@@ -687,6 +687,9 @@ - void HideWaylandPopupAndAllChildren(); - void CleanupWaylandPopups(); - GtkWindow* GetCurrentTopmostWindow(); -+ GtkWindow* GetCurrentWindow(); -+ GtkWindow* GetTopmostWindow(); -+ bool IsWidgetOverflowWindow(); - - /** - * |mIMContext| takes all IME related stuff. -diff --git a/widget/gtk/nsWindow.cpp b/widget/gtk/nsWindow.cpp ---- a/widget/gtk/nsWindow.cpp -+++ b/widget/gtk/nsWindow.cpp -@@ -1193,20 +1193,26 @@ - while (popupList) { - LOG((" Looking for %p [nsWindow]\n", popupList->data)); - nsWindow* waylandWnd = static_cast<nsWindow*>(popupList->data); -- bool popupFound = false; -- for (unsigned long i = 0; i < widgetChain.Length(); i++) { -- if (waylandWnd == widgetChain[i]) { -- popupFound = true; -- break; -+ // Remove only menu popups or empty frames - they are most likely -+ // already rolledup popups -+ if (waylandWnd->IsMainMenuWindow() || !waylandWnd->GetFrame()) { -+ bool popupFound = false; -+ for (unsigned long i = 0; i < widgetChain.Length(); i++) { -+ if (waylandWnd == widgetChain[i]) { -+ popupFound = true; -+ break; -+ } - } -- } -- if (!popupFound) { -- LOG((" nsWindow [%p] not found in PopupManager, hiding it.\n", -- waylandWnd)); -- waylandWnd->HideWaylandWindow(); -- popupList = gVisibleWaylandPopupWindows; -+ if (!popupFound) { -+ LOG((" nsWindow [%p] not found in PopupManager, hiding it.\n", -+ waylandWnd)); -+ waylandWnd->HideWaylandWindow(); -+ popupList = gVisibleWaylandPopupWindows; -+ } else { -+ LOG((" nsWindow [%p] is still open.\n", waylandWnd)); -+ popupList = popupList->next; -+ } - } else { -- LOG((" nsWindow [%p] is still open.\n", waylandWnd)); - popupList = popupList->next; - } - } -@@ -1229,6 +1235,55 @@ - return false; - } - -+GtkWindow* nsWindow::GetTopmostWindow() { -+ nsView* view = nsView::GetViewFor(this); -+ if (view) { -+ nsView* parentView = view->GetParent(); -+ if (parentView) { -+ nsIWidget* parentWidget = parentView->GetNearestWidget(nullptr); -+ if (parentWidget) { -+ nsWindow* parentnsWindow = static_cast<nsWindow*>(parentWidget); -+ LOG((" Topmost window: %p [nsWindow]\n", parentnsWindow)); -+ return GTK_WINDOW(parentnsWindow->mShell); -+ } -+ } -+ } -+ return nullptr; -+} -+ -+GtkWindow* nsWindow::GetCurrentWindow() { -+ GtkWindow* parentGtkWindow = nullptr; -+ // get the last opened window from gVisibleWaylandPopupWindows -+ if (gVisibleWaylandPopupWindows) { -+ nsWindow* parentnsWindow = -+ static_cast<nsWindow*>(gVisibleWaylandPopupWindows->data); -+ if (parentnsWindow) { -+ LOG((" Setting parent to last opened window: %p [nsWindow]\n", -+ parentnsWindow)); -+ parentGtkWindow = GTK_WINDOW(parentnsWindow->GetGtkWidget()); -+ } -+ } -+ // get the topmost window if the last opened windows are empty -+ if (!parentGtkWindow) { -+ parentGtkWindow = GetTopmostWindow(); -+ } -+ if (parentGtkWindow && GTK_IS_WINDOW(parentGtkWindow)) { -+ return GTK_WINDOW(parentGtkWindow); -+ } else { -+ LOG((" Failed to get current window for %p: %p\n", this, parentGtkWindow)); -+ } -+ return nullptr; -+} -+ -+bool nsWindow::IsWidgetOverflowWindow() { -+ if (this->GetFrame() && this->GetFrame()->GetContent()->GetID()) { -+ nsCString nodeId; -+ this->GetFrame()->GetContent()->GetID()->ToUTF8String(nodeId); -+ return nodeId.Equals("widget-overflow"); -+ } -+ return false; -+} -+ - // Wayland keeps strong popup window hierarchy. We need to track active - // (visible) popup windows and make sure we hide popup on the same level - // before we open another one on that level. It means that every open -@@ -1247,9 +1302,18 @@ - } - #endif - -- // Check if we're already configured. -+ if (!GetFrame()) { -+ LOG((" Window without frame cannot be configured.\n")); -+ return nullptr; -+ } -+ -+ // Check if we're already configured. Popup can be reattached to various -+ // windows, so don't consider them configured. Also the widget-overflow needs -+ // special care because the opened (remote) popups has to be closed before is -+ // it shown again. - if (gVisibleWaylandPopupWindows && -- g_list_find(gVisibleWaylandPopupWindows, this)) { -+ g_list_find(gVisibleWaylandPopupWindows, this) && -+ mPopupType != ePopupTypeTooltip && !IsWidgetOverflowWindow()) { - LOG((" [%p] is already configured.\n", (void*)this)); - return GTK_WIDGET(gtk_window_get_transient_for(GTK_WINDOW(mShell))); - } -@@ -1257,80 +1321,30 @@ - // If we're opening a new window we don't want to attach it to a tooltip - // as it's short lived temporary window. - HideWaylandTooltips(); -+ // Cleanup already closed menus -+ CleanupWaylandPopups(); - - GtkWindow* parentGtkWindow = nullptr; -- -- if (IsMainMenuWindow()) { -- // Remove and hide already closed popups from the -- // 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. -- // 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() - 1; i++) { -- unsigned long parentIndex = i + 1; -- if (widgetChain.Length() > parentIndex && widgetChain[i] == this) { -- nsWindow* parentWindow = -- static_cast<nsWindow*>(widgetChain[parentIndex]); -- parentGtkWindow = GTK_WINDOW(parentWindow->GetGtkWidget()); -- LOG((" [%p] Found %p as parent in nsXULPopupManager.", this, -- parentWindow)); -- break; -- } -- } -- } 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) { -- nsWindow* parentWindow = -- static_cast<nsWindow*>(gVisibleWaylandPopupWindows->data); -- parentGtkWindow = GTK_WINDOW(parentWindow->GetGtkWidget()); -- } -- } -+ if (HasRemoteContent() || IsWidgetOverflowWindow()) { -+ LOG( -+ (" Hiding all opened popups because the window is remote content or " -+ "overflow-widget")); -+ HideWaylandOpenedPopups(); -+ } -+ -+ parentGtkWindow = GetCurrentWindow(); - if (parentGtkWindow) { - MOZ_ASSERT(parentGtkWindow != GTK_WINDOW(this->GetGtkWidget()), - "Cannot set self as parent"); - gtk_window_set_transient_for(GTK_WINDOW(mShell), - GTK_WINDOW(parentGtkWindow)); -- } else { -- // Fallback to the parent given in nsWindow::Create (most likely the -- // toplevel window). -- parentGtkWindow = gtk_window_get_transient_for(GTK_WINDOW(mShell)); -- LOG((" Setting parent from transient: %p [GtkWindow]\n", parentGtkWindow)); -- } -- // Add current window to the visible popup list -- gVisibleWaylandPopupWindows = -- g_list_prepend(gVisibleWaylandPopupWindows, this); -- -- LOG((" Parent window for %p: %p [GtkWindow]", this, parentGtkWindow)); -+ // Add current window to the visible popup list -+ gVisibleWaylandPopupWindows = -+ g_list_prepend(gVisibleWaylandPopupWindows, this); -+ LOG((" Parent window for %p: %p [GtkWindow]", this, parentGtkWindow)); -+ } -+ -+ MOZ_ASSERT(parentGtkWindow, "NO parent window for %p: expect popup glitches"); - return GTK_WIDGET(parentGtkWindow); - } - - |