firefox/mozilla-1444437.patch

184 lines
6.6 KiB
Diff

# 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;
};