Blob Blame History Raw
diff -up firefox-67.0/widget/gtk/mozcontainer.cpp.mozilla-1535567 firefox-67.0/widget/gtk/mozcontainer.cpp
--- firefox-67.0/widget/gtk/mozcontainer.cpp.mozilla-1535567	2019-05-14 01:08:37.000000000 +0200
+++ firefox-67.0/widget/gtk/mozcontainer.cpp	2019-05-15 15:56:19.645336209 +0200
@@ -157,6 +157,7 @@ void moz_container_init(MozContainer *co
   container->subsurface = nullptr;
   container->eglwindow = nullptr;
   container->frame_callback_handler = nullptr;
+  container->frame_callback_handler_surface_id = -1;
   // We can draw to x11 window any time.
   container->ready_to_draw = GDK_IS_X11_DISPLAY(gdk_display_get_default());
   container->surface_needs_clear = true;
@@ -165,6 +166,11 @@ void moz_container_init(MozContainer *co
 }
 
 #if defined(MOZ_WAYLAND)
+void moz_container_set_initial_draw_callback(
+    MozContainer *container, std::function<void(void)> inital_draw_cb) {
+  container->inital_draw_cb = inital_draw_cb;
+}
+
 static wl_surface *moz_container_get_gtk_container_surface(
     MozContainer *container) {
   static auto sGdkWaylandWindowGetWlSurface = (wl_surface * (*)(GdkWindow *))
@@ -178,37 +184,61 @@ static void frame_callback_handler(void
                                    uint32_t time) {
   MozContainer *container = MOZ_CONTAINER(data);
   g_clear_pointer(&container->frame_callback_handler, wl_callback_destroy);
+  container->frame_callback_handler_surface_id = -1;
   if (!container->ready_to_draw && container->inital_draw_cb) {
     container->inital_draw_cb();
   }
   container->ready_to_draw = true;
 }
 
-void moz_container_set_initial_draw_callback(
-    MozContainer *container, std::function<void(void)> inital_draw_cb) {
-  container->inital_draw_cb = inital_draw_cb;
-}
-
 static const struct wl_callback_listener frame_listener = {
     frame_callback_handler};
 
-static gboolean moz_container_map_wayland(GtkWidget *widget,
-                                          GdkEventAny *event) {
-  MozContainer *container = MOZ_CONTAINER(widget);
-
-  if (container->ready_to_draw || container->frame_callback_handler) {
-    return FALSE;
-  }
-
+static void moz_container_request_parent_frame_callback(
+    MozContainer *container) {
   wl_surface *gtk_container_surface =
       moz_container_get_gtk_container_surface(container);
+  int gtk_container_surface_id =
+      gtk_container_surface
+          ? wl_proxy_get_id((struct wl_proxy *)gtk_container_surface)
+          : -1;
+
+
+
+
+
+
+
+  if (container->frame_callback_handler &&
+      container->frame_callback_handler_surface_id ==
+          gtk_container_surface_id) {
+    return;
+  }
+
+  // If there's pending frame callback, delete it.
+  if (container->frame_callback_handler) {
+    g_clear_pointer(&container->frame_callback_handler, wl_callback_destroy);
+  }
 
   if (gtk_container_surface) {
+    container->frame_callback_handler_surface_id = gtk_container_surface_id;
     container->frame_callback_handler = wl_surface_frame(gtk_container_surface);
     wl_callback_add_listener(container->frame_callback_handler, &frame_listener,
                              container);
+  } else {
+    container->frame_callback_handler_surface_id = -1;
+  }
+}
+
+static gboolean moz_container_map_wayland(GtkWidget *widget,
+                                          GdkEventAny *event) {
+  MozContainer *container = MOZ_CONTAINER(widget);
+
+  if (container->ready_to_draw) {
+    return FALSE;
   }
 
+  moz_container_request_parent_frame_callback(MOZ_CONTAINER(widget));
   return FALSE;
 }
 
@@ -217,6 +247,7 @@ static void moz_container_unmap_wayland(
   g_clear_pointer(&container->subsurface, wl_subsurface_destroy);
   g_clear_pointer(&container->surface, wl_surface_destroy);
   g_clear_pointer(&container->frame_callback_handler, wl_callback_destroy);
+  container->frame_callback_handler_surface_id = -1;
 
   container->surface_needs_clear = true;
   container->ready_to_draw = false;
@@ -329,6 +360,10 @@ void moz_container_realize(GtkWidget *wi
             : gtk_widget_get_visual(widget);
 
     window = gdk_window_new(parent, &attributes, attributes_mask);
+
+
+
+
     gdk_window_set_user_data(window, widget);
   } else {
     window = parent;
@@ -498,6 +533,7 @@ static void moz_container_add(GtkContain
 struct wl_surface *moz_container_get_wl_surface(MozContainer *container) {
   if (!container->surface) {
     if (!container->ready_to_draw) {
+      moz_container_request_parent_frame_callback(container);
       return nullptr;
     }
     GdkDisplay *display = gtk_widget_get_display(GTK_WIDGET(container));
diff -up firefox-67.0/widget/gtk/mozcontainer.h.mozilla-1535567 firefox-67.0/widget/gtk/mozcontainer.h
--- firefox-67.0/widget/gtk/mozcontainer.h.mozilla-1535567	2019-05-14 01:08:37.000000000 +0200
+++ firefox-67.0/widget/gtk/mozcontainer.h	2019-05-15 15:50:59.440570372 +0200
@@ -77,6 +77,7 @@ struct _MozContainer {
   struct wl_subsurface *subsurface;
   struct wl_egl_window *eglwindow;
   struct wl_callback *frame_callback_handler;
+  int frame_callback_handler_surface_id;
   gboolean surface_needs_clear;
   gboolean ready_to_draw;
   std::function<void(void)> inital_draw_cb;