Added popup-fixing patches, fixed api key paths

This commit is contained in:
Jan Horak 2020-02-11 10:45:39 +01:00
parent 158b963518
commit 422073de22
5 changed files with 373 additions and 3 deletions

View File

@ -10,9 +10,9 @@ ac_add_options --disable-updater
ac_add_options --enable-chrome-format=omni
ac_add_options --enable-pulseaudio
ac_add_options --without-system-icu
ac_add_options --with-mozilla-api-keyfile=../mozilla-api-key
ac_add_options --with-google-location-service-api-keyfile=../google-api-key
ac_add_options --with-google-safebrowsing-api-keyfile=../google-api-key
ac_add_options --with-mozilla-api-keyfile=../../mozilla-api-key
ac_add_options --with-google-location-service-api-keyfile=../../google-api-key
ac_add_options --with-google-safebrowsing-api-keyfile=../../google-api-key
ac_add_options --enable-release
ac_add_options --update-channel=release
ac_add_options --disable-system-sqlite

View File

@ -163,6 +163,9 @@ Patch415: Bug-1238661---fix-mozillaSignalTrampoline-to-work-.patch
Patch417: bug1375074-save-restore-x28.patch
Patch422: mozilla-1580174-webrtc-popup.patch
Patch427: mozilla-1607404-fix-remote-offset.patch
Patch428: mozilla-1609732-no-full-hide.patch
Patch429: mozilla-1609732-pause-renderer.patch
Patch430: mozilla-1605795-popup-parent-fix.patch
# Wayland specific upstream patches
Patch574: firefox-pipewire.patch
@ -362,6 +365,9 @@ This package contains results of tests executed during build.
# dropdown missing on multimonitor
# fix for wrong intl.accept_lang when using non en-us langpack
%patch427 -p1 -b .1607404-fix-remote-offset
%patch428 -p1 -b .1609732-no-full-hide
%patch429 -p1 -b .1609732-pause-renderer
%patch430 -p1 -b .1605795-popup-parent-fix
# Wayland specific upstream patches
%patch574 -p1 -b .firefox-pipewire

View File

@ -0,0 +1,231 @@
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);
}

View File

@ -0,0 +1,60 @@
diff --git a/widget/gtk/WindowSurfaceWayland.cpp b/widget/gtk/WindowSurfaceWayland.cpp
--- a/widget/gtk/WindowSurfaceWayland.cpp
+++ b/widget/gtk/WindowSurfaceWayland.cpp
@@ -805,6 +805,10 @@
mBufferCommitAllowed = false;
LayoutDeviceIntRect lockedScreenRect = mWindow->GetBounds();
+ // The window bounds of popup windows contains relative position to
+ // the transient window. We need to remove that effect because by changing
+ // position of the popup window the buffer has not changed its size.
+ lockedScreenRect.x = lockedScreenRect.y = 0;
gfx::IntRect lockSize = aRegion.GetBounds().ToUnknownRect();
bool isTransparentPopup =
diff --git a/widget/gtk/nsWindow.cpp b/widget/gtk/nsWindow.cpp
--- a/widget/gtk/nsWindow.cpp
+++ b/widget/gtk/nsWindow.cpp
@@ -1324,6 +1324,7 @@
// 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 =
@@ -1355,7 +1356,7 @@
mBounds.width, mBounds.height));
GtkWindow* parentGtkWindow = gtk_window_get_transient_for(GTK_WINDOW(mShell));
- if (!parentGtkWindow) {
+ if (!parentGtkWindow || !GTK_IS_WIDGET(parentGtkWindow)) {
NS_WARNING("Popup has no parent!");
return;
}
@@ -1431,8 +1432,13 @@
parentWindow));
int x_parent, y_parent;
- gdk_window_get_origin(gtk_widget_get_window(GTK_WIDGET(parentWindow)),
- &x_parent, &y_parent);
+ if (parentWindow) {
+ gdk_window_get_origin(gtk_widget_get_window(GTK_WIDGET(parentWindow)),
+ &x_parent, &y_parent);
+ } else {
+ NS_WARNING(("no parent window, this should not happen for popup!"));
+ x_parent = y_parent = 0;
+ }
GdkRectangle rect = {aPosition->x - x_parent, aPosition->y - y_parent, 1, 1};
if (aSize) {
@@ -1470,7 +1476,7 @@
bool isWidgetVisible =
(sGtkWidgetIsVisible != nullptr) && sGtkWidgetIsVisible(mShell);
if (isWidgetVisible) {
- HideWaylandWindow();
+ gtk_widget_hide(mShell);
}
LOG((" requested rect: x: %d y: %d width: %d height: %d\n", rect.x, rect.y,

View File

@ -0,0 +1,73 @@
diff --git a/widget/gtk/nsWindow.h b/widget/gtk/nsWindow.h
--- a/widget/gtk/nsWindow.h
+++ b/widget/gtk/nsWindow.h
@@ -681,6 +681,7 @@
bool IsMainMenuWindow();
GtkWidget* ConfigureWaylandPopupWindows();
+ void PauseRemoteRenderer();
void HideWaylandWindow();
void HideWaylandTooltips();
void HideWaylandPopupAndAllChildren();
diff --git a/widget/gtk/nsWindow.cpp b/widget/gtk/nsWindow.cpp
--- a/widget/gtk/nsWindow.cpp
+++ b/widget/gtk/nsWindow.cpp
@@ -1386,10 +1386,10 @@
}
if (needsPositionUpdate && needsSizeUpdate) {
- Resize(newBounds.x, newBounds.y, newBounds.width, newBounds.height, true);
+ mBounds = newBounds;
NotifyWindowMoved(newBounds.x, newBounds.y);
} else if (needsPositionUpdate) {
- Move(newBounds.x, newBounds.y);
+ mBounds = newBounds;
NotifyWindowMoved(newBounds.x, newBounds.y);
} else {
Resize(newBounds.width, newBounds.height, true);
@@ -1476,6 +1476,7 @@
bool isWidgetVisible =
(sGtkWidgetIsVisible != nullptr) && sGtkWidgetIsVisible(mShell);
if (isWidgetVisible) {
+ PauseRemoteRenderer();
gtk_widget_hide(mShell);
}
@@ -4497,16 +4498,8 @@
}
}
-void nsWindow::HideWaylandWindow() {
+void nsWindow::PauseRemoteRenderer() {
#ifdef MOZ_WAYLAND
- if (mWindowType == eWindowType_popup) {
- LOG(("nsWindow::HideWaylandWindow: popup [%p]\n", this));
- GList* foundWindow = g_list_find(gVisibleWaylandPopupWindows, this);
- if (foundWindow) {
- gVisibleWaylandPopupWindows =
- g_list_delete_link(gVisibleWaylandPopupWindows, foundWindow);
- }
- }
if (!mIsDestroyed) {
if (mContainer && moz_container_has_wl_egl_window(mContainer)) {
// Because wl_egl_window is destroyed on moz_container_unmap(),
@@ -4529,6 +4522,18 @@
}
}
#endif
+}
+
+void nsWindow::HideWaylandWindow() {
+ if (mWindowType == eWindowType_popup) {
+ LOG(("nsWindow::HideWaylandWindow: popup [%p]\n", this));
+ GList* foundWindow = g_list_find(gVisibleWaylandPopupWindows, this);
+ if (foundWindow) {
+ gVisibleWaylandPopupWindows =
+ g_list_delete_link(gVisibleWaylandPopupWindows, foundWindow);
+ }
+ }
+ PauseRemoteRenderer();
gtk_widget_hide(mShell);
}