summaryrefslogtreecommitdiff
path: root/mozilla-1444437.patch
diff options
context:
space:
mode:
Diffstat (limited to 'mozilla-1444437.patch')
-rw-r--r--mozilla-1444437.patch183
1 files changed, 183 insertions, 0 deletions
diff --git a/mozilla-1444437.patch b/mozilla-1444437.patch
new file mode 100644
index 0000000..79fda10
--- /dev/null
+++ b/mozilla-1444437.patch
@@ -0,0 +1,183 @@
+
+# HG changeset patch
+# User Martin Stransky <stransky@redhat.com>
+# Date 1530185851 -7200
+# Node ID 7dc09bb0f57c3397f68c424b2a4e781e89069517
+# Parent 15c95df467be553beb39f2e8102c206639e05fde
+Bug 1444437 - [Wayland] Don't map mozcontainer subsurface until parent surface is commited, r?ashie
+
+MozReview-Commit-ID: 4qoyGH8VCAU
+
+diff --git a/widget/gtk/mozcontainer.cpp b/widget/gtk/mozcontainer.cpp
+--- a/widget/gtk/mozcontainer.cpp
++++ b/widget/gtk/mozcontainer.cpp
+@@ -207,17 +207,17 @@ moz_container_init (MozContainer *contai
+ gtk_widget_set_redraw_on_allocate(GTK_WIDGET(container), FALSE);
+
+ #if defined(MOZ_WAYLAND)
+ {
+ container->subcompositor = nullptr;
+ container->surface = nullptr;
+ container->subsurface = nullptr;
+ container->eglwindow = nullptr;
+- container->committed = false;
++ container->parent_surface_committed = false;
+
+ GdkDisplay *gdk_display = gtk_widget_get_display(GTK_WIDGET(container));
+ if (GDK_IS_WAYLAND_DISPLAY (gdk_display)) {
+ // Available as of GTK 3.8+
+ static auto sGdkWaylandDisplayGetWlDisplay =
+ (wl_display *(*)(GdkDisplay *))
+ dlsym(RTLD_DEFAULT, "gdk_wayland_display_get_wl_display");
+
+@@ -228,21 +228,22 @@ moz_container_init (MozContainer *contai
+ wl_display_roundtrip(display);
+ }
+ }
+ #endif
+ }
+
+ #if defined(MOZ_WAYLAND)
+ static void
+-moz_container_after_paint(GdkFrameClock *clock, MozContainer *container)
++moz_container_commited_handler(GdkFrameClock *clock, MozContainer *container)
+ {
+- container->committed = true;
+- g_signal_handlers_disconnect_by_func(clock,
+- reinterpret_cast<gpointer>(moz_container_after_paint), container);
++ container->parent_surface_committed = true;
++ g_signal_handler_disconnect(clock,
++ container->parent_surface_committed_handler);
++ container->parent_surface_committed_handler = 0;
+ }
+
+ /* We want to draw to GdkWindow owned by mContainer from Compositor thread but
+ * Gtk+ can be used in main thread only. So we create wayland wl_surface
+ * and attach it as an overlay to GdkWindow.
+ *
+ * see gtk_clutter_embed_ensure_subsurface() at gtk-clutter-embed.c
+ * for reference.
+@@ -263,37 +264,44 @@ moz_container_map_surface(MozContainer *
+
+ GdkDisplay *display = gtk_widget_get_display(GTK_WIDGET(container));
+ if (GDK_IS_X11_DISPLAY(display))
+ return false;
+
+ if (container->subsurface && container->surface)
+ return true;
+
++ if (!container->parent_surface_committed) {
++ if (!container->parent_surface_committed_handler) {
++ GdkWindow* window = gtk_widget_get_window(GTK_WIDGET(container));
++ GdkFrameClock *clock = sGdkWindowGetFrameClock(window);
++ container->parent_surface_committed_handler =
++ g_signal_connect_after(clock, "after-paint",
++ G_CALLBACK(moz_container_commited_handler),
++ container);
++ }
++ return false;
++ }
++
+ if (!container->surface) {
+ struct wl_compositor *compositor;
+ compositor = sGdkWaylandDisplayGetWlCompositor(display);
+ container->surface = wl_compositor_create_surface(compositor);
+ }
+
+ if (!container->subsurface) {
+ GdkWindow* window = gtk_widget_get_window(GTK_WIDGET(container));
+ wl_surface* gtk_surface = sGdkWaylandWindowGetWlSurface(window);
+ if (!gtk_surface) {
+ // We requested the underlying wl_surface too early when container
+ // is not realized yet. We'll try again before first rendering
+ // to mContainer.
+ return false;
+ }
+
+- GdkFrameClock *clock = sGdkWindowGetFrameClock(window);
+- g_signal_connect_after(clock, "after-paint",
+- G_CALLBACK(moz_container_after_paint),
+- container);
+-
+ container->subsurface =
+ wl_subcompositor_get_subsurface (container->subcompositor,
+ container->surface,
+ gtk_surface);
+ gint x, y;
+ gdk_window_get_position(window, &x, &y);
+ wl_subsurface_set_position(container->subsurface, x, y);
+ wl_subsurface_set_desync(container->subsurface);
+@@ -310,17 +318,29 @@ moz_container_map_surface(MozContainer *
+ }
+
+ static void
+ moz_container_unmap_surface(MozContainer *container)
+ {
+ g_clear_pointer(&container->eglwindow, wl_egl_window_destroy);
+ g_clear_pointer(&container->subsurface, wl_subsurface_destroy);
+ g_clear_pointer(&container->surface, wl_surface_destroy);
+- container->committed = false;
++
++ if (container->parent_surface_committed_handler) {
++ static auto sGdkWindowGetFrameClock =
++ (GdkFrameClock *(*)(GdkWindow *))
++ dlsym(RTLD_DEFAULT, "gdk_window_get_frame_clock");
++ GdkWindow* window = gtk_widget_get_window(GTK_WIDGET(container));
++ GdkFrameClock *clock = sGdkWindowGetFrameClock(window);
++
++ g_signal_handler_disconnect(clock,
++ container->parent_surface_committed_handler);
++ container->parent_surface_committed_handler = 0;
++ }
++ container->parent_surface_committed = false;
+ }
+
+ #endif
+
+ void
+ moz_container_map (GtkWidget *widget)
+ {
+ MozContainer *container;
+@@ -582,17 +602,17 @@ moz_container_get_wl_surface(MozContaine
+ if (!container->subsurface || !container->surface) {
+ GdkWindow* window = gtk_widget_get_window(GTK_WIDGET(container));
+ if (!gdk_window_is_visible(window))
+ return nullptr;
+
+ moz_container_map_surface(container);
+ }
+
+- return container->committed ? container->surface : nullptr;
++ return container->surface;
+ }
+
+ struct wl_egl_window *
+ moz_container_get_wl_egl_window(MozContainer *container)
+ {
+ if (!container->eglwindow) {
+ struct wl_surface *wlsurf = moz_container_get_wl_surface(container);
+ if (!wlsurf)
+diff --git a/widget/gtk/mozcontainer.h b/widget/gtk/mozcontainer.h
+--- a/widget/gtk/mozcontainer.h
++++ b/widget/gtk/mozcontainer.h
+@@ -68,17 +68,18 @@ struct _MozContainer
+ GtkContainer container;
+ GList *children;
+
+ #ifdef MOZ_WAYLAND
+ struct wl_subcompositor *subcompositor;
+ struct wl_surface *surface;
+ struct wl_subsurface *subsurface;
+ struct wl_egl_window *eglwindow;
+- gboolean committed;
++ gboolean parent_surface_committed;
++ gulong parent_surface_committed_handler;
+ #endif
+ };
+
+ struct _MozContainerClass
+ {
+ GtkContainerClass parent_class;
+ };
+
+
bgstack15