firefox/mozilla-1539471.patch

207 lines
7.4 KiB
Diff
Raw Normal View History

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.
*