207 lines
7.4 KiB
Diff
207 lines
7.4 KiB
Diff
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.
|
|
*
|