summaryrefslogtreecommitdiff
path: root/mozilla-1539471.patch
diff options
context:
space:
mode:
Diffstat (limited to 'mozilla-1539471.patch')
-rw-r--r--mozilla-1539471.patch206
1 files changed, 206 insertions, 0 deletions
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.
+ *
bgstack15