From 384fee2ff4d41260acfe81f7cf1658976e2cea9d Mon Sep 17 00:00:00 2001 From: Martin Stransky Date: Thu, 28 Mar 2019 14:23:14 +0100 Subject: [PATCH] Added fix for mozbz#1539471 - wayland popups/tooltips --- firefox.spec | 7 +- mozilla-1539471.patch | 206 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 212 insertions(+), 1 deletion(-) create mode 100644 mozilla-1539471.patch diff --git a/firefox.spec b/firefox.spec index 95965f1..eb32302 100644 --- a/firefox.spec +++ b/firefox.spec @@ -99,7 +99,7 @@ ExcludeArch: s390x Summary: Mozilla Firefox Web browser Name: firefox Version: 66.0.1 -Release: 3%{?pre_tag}%{?dist} +Release: 4%{?pre_tag}%{?dist} URL: https://www.mozilla.org/firefox/ License: MPLv1.1 or GPLv2+ or LGPLv2+ Source0: https://archive.mozilla.org/pub/firefox/releases/%{version}%{?pre_version}/source/firefox-%{version}%{?pre_version}.source.tar.xz @@ -163,6 +163,7 @@ Patch576: mozilla-1532643-popup.patch Patch577: mozilla-1535567.patch Patch578: mozilla-1431399.patch Patch579: mozilla-1468911.patch +Patch580: mozilla-1539471.patch # PGO/LTO patches Patch600: pgo.patch @@ -381,6 +382,7 @@ This package contains results of tests executed during build. %patch577 -p1 -b .mozilla-1535567 %patch578 -p1 -b .mozilla-1431399 %patch579 -p1 -b .mozilla-1468911 +%patch580 -p1 -b .mozilla-1539471 # PGO patches %patch600 -p1 -b .pgo @@ -934,6 +936,9 @@ gtk-update-icon-cache %{_datadir}/icons/hicolor &>/dev/null || : #--------------------------------------------------------------------- %changelog +* Thu Mar 28 2019 Martin Stransky - 66.0.1-4 +- Added fix for mozbz#1539471 - wayland popups/tooltips + * Wed Mar 27 2019 Martin Stransky - 66.0.1-3 - Added fix for mozbz#526293 - show remote locations at file chooser dialog diff --git a/mozilla-1539471.patch b/mozilla-1539471.patch new file mode 100644 index 0000000..1a321d2 --- /dev/null +++ b/mozilla-1539471.patch @@ -0,0 +1,206 @@ +diff -up firefox-66.0.1/widget/gtk/nsWindow.cpp.mozilla-1539471 firefox-66.0.1/widget/gtk/nsWindow.cpp +--- firefox-66.0.1/widget/gtk/nsWindow.cpp.mozilla-1539471 2019-03-28 14:08:42.351128620 +0100 ++++ firefox-66.0.1/widget/gtk/nsWindow.cpp 2019-03-28 14:20:23.282890178 +0100 +@@ -312,6 +312,9 @@ static nsWindow *gFocusWindow = nullptr; + static bool gBlockActivateEvent = false; + static bool gGlobalsInitialized = false; + static bool gRaiseWindows = true; ++#ifdef MOZ_WAYLAND ++static GList *gCurrentPopupWindows = nullptr; ++#endif + + #if GTK_CHECK_VERSION(3, 4, 0) + static uint32_t gLastTouchID = 0; +@@ -1136,8 +1139,16 @@ void nsWindow::NativeMoveResizeWaylandPo + return; + } + +- GtkWidget* parentWidget = +- GTK_WIDGET(gtk_window_get_transient_for(GTK_WINDOW(mShell))); ++ GtkWidget *parentWidget; ++ if (mPopupType == ePopupTypeTooltip && gCurrentPopupWindows) { ++ // Attach tooltip window to the latest popup window ++ // to have both visible. ++ parentWidget = GTK_WIDGET(gCurrentPopupWindows->data); ++ gtk_window_set_transient_for(GTK_WINDOW(mShell), ++ GTK_WINDOW(parentWidget)); ++ } else { ++ parentWidget = GTK_WIDGET(gtk_window_get_transient_for(GTK_WINDOW(mShell))); ++ } + + int x_parent, y_parent; + gdk_window_get_origin(gtk_widget_get_window(parentWidget), &x_parent, &y_parent); +@@ -3489,7 +3500,7 @@ nsresult nsWindow::Create(nsIWidget *aPa + gtkTypeHint = GDK_WINDOW_TYPE_HINT_DND; + mIsDragPopup = true; + } else { +- switch (aInitData->mPopupHint) { ++ switch (mPopupType) { + case ePopupTypeMenu: + gtkTypeHint = GDK_WINDOW_TYPE_HINT_POPUP_MENU; + break; +@@ -3610,6 +3621,8 @@ nsresult nsWindow::Create(nsIWidget *aPa + return NS_ERROR_FAILURE; + + case eWindowType_child: { ++ MOZ_ASSERT(mIsX11Display, ++ "eWindowType_child is not supported on Wayland!"); + if (parentMozContainer) { + mGdkWindow = CreateGdkWindow(parentGdkWindow, parentMozContainer); + mHasMappedToplevel = parentnsWindow->mHasMappedToplevel; +@@ -3979,6 +3992,49 @@ void nsWindow::NativeMoveResize() { + } + } + ++#ifdef MOZ_WAYLAND ++void nsWindow::OpenToplevelWaylandWindow() { ++ // 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 ++ // popup needs to have an unique parent. ++ if (mWindowType == eWindowType_popup) { ++ GtkWidget *parentWidget = ++ GTK_WIDGET(gtk_window_get_transient_for(GTK_WINDOW(mShell))); ++ ++ if (gCurrentPopupWindows) { ++ do { ++ GtkWidget *widget = GTK_WIDGET(gCurrentPopupWindows->data); ++ if (widget == parentWidget) { ++ break; ++ } ++ nsWindow* window = get_window_for_gtk_widget(widget); ++ NS_ASSERTION(window, "Unknown window in popup widget list!"); ++ window->CloseToplevelWaylandWindow(); ++ ++ } while (gCurrentPopupWindows != nullptr); ++ } ++ gCurrentPopupWindows = g_list_prepend(gCurrentPopupWindows, mShell); ++ } ++ ++ gtk_widget_show(mShell); ++} ++ ++void nsWindow::CloseToplevelWaylandWindow() { ++ if (mContainer && moz_container_has_wl_egl_window(mContainer)) { ++ // Because wl_egl_window is destroyed on moz_container_unmap(), ++ // the current compositor cannot use it anymore. To avoid crash, ++ // destroy the compositor & recreate a new compositor on next ++ // expose event. ++ DestroyLayerManager(); ++ } ++ if (mWindowType == eWindowType_popup) { ++ gCurrentPopupWindows = g_list_remove(gCurrentPopupWindows, mShell); ++ } ++ gtk_widget_hide(mShell); ++} ++#endif ++ + void nsWindow::NativeShow(bool aAction) { + if (aAction) { + // unset our flag now that our window has been shown +@@ -3990,51 +4046,55 @@ void nsWindow::NativeShow(bool aAction) + SetUserTimeAndStartupIDForActivatedWindow(mShell); + } + +- gtk_widget_show(mShell); ++#ifdef MOZ_WAYLAND ++ if (!mIsX11Display) { ++ OpenToplevelWaylandWindow(); ++ } else ++#endif ++ { ++ gtk_widget_show(mShell); ++ } + } else if (mContainer) { + gtk_widget_show(GTK_WIDGET(mContainer)); + } else if (mGdkWindow) { + gdk_window_show_unraised(mGdkWindow); + } + } else { +-#ifdef MOZ_WAYLAND +- if (mContainer && moz_container_has_wl_egl_window(mContainer)) { +- // Because wl_egl_window is destroyed on moz_container_unmap(), +- // the current compositor cannot use it anymore. To avoid crash, +- // destroy the compositor & recreate a new compositor on next +- // expose event. +- DestroyLayerManager(); +- } +-#endif +- + if (mIsTopLevel) { +- // Workaround window freezes on GTK versions before 3.21.2 by +- // ensuring that configure events get dispatched to windows before +- // they are unmapped. See bug 1225044. +- if (gtk_check_version(3, 21, 2) != nullptr && mPendingConfigures > 0) { +- GtkAllocation allocation; +- gtk_widget_get_allocation(GTK_WIDGET(mShell), &allocation); +- +- GdkEventConfigure event; +- PodZero(&event); +- event.type = GDK_CONFIGURE; +- event.window = mGdkWindow; +- event.send_event = TRUE; +- event.x = allocation.x; +- event.y = allocation.y; +- event.width = allocation.width; +- event.height = allocation.height; +- +- auto shellClass = GTK_WIDGET_GET_CLASS(mShell); +- for (unsigned int i = 0; i < mPendingConfigures; i++) { +- Unused << shellClass->configure_event(mShell, &event); ++#ifdef MOZ_WAYLAND ++ if (!mIsX11Display) { ++ CloseToplevelWaylandWindow(); ++ } else ++#endif ++ { ++ // Workaround window freezes on GTK versions before 3.21.2 by ++ // ensuring that configure events get dispatched to windows before ++ // they are unmapped. See bug 1225044. ++ if (gtk_check_version(3, 21, 2) != nullptr && mPendingConfigures > 0) { ++ GtkAllocation allocation; ++ gtk_widget_get_allocation(GTK_WIDGET(mShell), &allocation); ++ ++ GdkEventConfigure event; ++ PodZero(&event); ++ event.type = GDK_CONFIGURE; ++ event.window = mGdkWindow; ++ event.send_event = TRUE; ++ event.x = allocation.x; ++ event.y = allocation.y; ++ event.width = allocation.width; ++ event.height = allocation.height; ++ ++ auto shellClass = GTK_WIDGET_GET_CLASS(mShell); ++ for (unsigned int i = 0; i < mPendingConfigures; i++) { ++ Unused << shellClass->configure_event(mShell, &event); ++ } ++ mPendingConfigures = 0; + } +- mPendingConfigures = 0; +- } + +- gtk_widget_hide(mShell); ++ gtk_widget_hide(mShell); + +- ClearTransparencyBitmap(); // Release some resources ++ ClearTransparencyBitmap(); // Release some resources ++ } + } else if (mContainer) { + gtk_widget_hide(GTK_WIDGET(mContainer)); + } else if (mGdkWindow) { +diff -up firefox-66.0.1/widget/gtk/nsWindow.h.mozilla-1539471 firefox-66.0.1/widget/gtk/nsWindow.h +--- firefox-66.0.1/widget/gtk/nsWindow.h.mozilla-1539471 2019-03-28 14:08:42.345128639 +0100 ++++ firefox-66.0.1/widget/gtk/nsWindow.h 2019-03-28 14:08:42.355128607 +0100 +@@ -603,6 +603,11 @@ class nsWindow final : public nsBaseWidg + + void ForceTitlebarRedraw(); + ++#ifdef MOZ_WAYLAND ++ void OpenToplevelWaylandWindow(); ++ void CloseToplevelWaylandWindow(); ++#endif ++ + /** + * |mIMContext| takes all IME related stuff. + *