Bug 1512589 - [Wayland] Map mozcontainer from map-event signal. r=jhorak, a=RyanVM
authorMartin Stransky <stransky@redhat.com>
Mon, 10 Dec 2018 10:06:27 +0000
changeset 509082 37e58b34932fe6e1d5246412c94e31af2c3a41e6
parent 509081 f0978d33730c3a9b4b99ed623f25e352beb3ee5b
child 509083 49a93d8ec9f9a1e9d4b3322bfbb77d86be5d71a8
push id1905
push userffxbld-merge
push dateMon, 21 Jan 2019 12:33:13 +0000
treeherdermozilla-release@c2fca1944d8c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjhorak, RyanVM
bugs1512589
milestone65.0
Bug 1512589 - [Wayland] Map mozcontainer from map-event signal. r=jhorak, a=RyanVM It's not quaranteed that we have a valid wl_surface at GtkWidget::map event. In that case create it at GtkWidget::map-event handler which is called after widget show. Differential Revision: https://phabricator.services.mozilla.com/D13979
widget/gtk/mozcontainer.cpp
--- a/widget/gtk/mozcontainer.cpp
+++ b/widget/gtk/mozcontainer.cpp
@@ -26,16 +26,19 @@ using namespace mozilla::widget;
 #endif
 
 /* init methods */
 static void moz_container_class_init(MozContainerClass *klass);
 static void moz_container_init(MozContainer *container);
 
 /* widget class methods */
 static void moz_container_map(GtkWidget *widget);
+#if defined(MOZ_WAYLAND)
+static gboolean moz_container_map_wayland(GtkWidget *widget, GdkEventAny *event);
+#endif
 static void moz_container_unmap(GtkWidget *widget);
 static void moz_container_realize(GtkWidget *widget);
 static void moz_container_size_allocate(GtkWidget *widget,
                                         GtkAllocation *allocation);
 
 /* container class methods */
 static void moz_container_remove(GtkContainer *container,
                                  GtkWidget *child_widget);
@@ -124,16 +127,21 @@ void moz_container_put(MozContainer *con
 
 void moz_container_class_init(MozContainerClass *klass) {
   /*GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
     GtkObjectClass *object_class = GTK_OBJECT_CLASS (klass); */
   GtkContainerClass *container_class = GTK_CONTAINER_CLASS(klass);
   GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass);
 
   widget_class->map = moz_container_map;
+#if defined(MOZ_WAYLAND)
+    if (!GDK_IS_X11_DISPLAY(gdk_display_get_default())) {
+      widget_class->map_event = moz_container_map_wayland;
+    }
+#endif
   widget_class->unmap = moz_container_unmap;
   widget_class->realize = moz_container_realize;
   widget_class->size_allocate = moz_container_size_allocate;
 
   container_class->remove = moz_container_remove;
   container_class->forall = moz_container_forall;
   container_class->add = moz_container_add;
 }
@@ -169,33 +177,42 @@ static void frame_callback_handler(void 
   MozContainer *container = MOZ_CONTAINER(data);
   g_clear_pointer(&container->frame_callback_handler, wl_callback_destroy);
   container->ready_to_draw = true;
 }
 
 static const struct wl_callback_listener frame_listener = {
     frame_callback_handler};
 
-static void moz_container_map_wayland(MozContainer *container) {
-  container->surface_needs_clear = true;
-  container->ready_to_draw = false;
+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;
+  }
 
   wl_surface *gtk_container_surface =
       moz_container_get_gtk_container_surface(container);
-  container->frame_callback_handler = wl_surface_frame(gtk_container_surface);
-  wl_callback_add_listener(container->frame_callback_handler, &frame_listener,
-                           container);
+
+  if (gtk_container_surface) {
+    container->frame_callback_handler = wl_surface_frame(gtk_container_surface);
+    wl_callback_add_listener(container->frame_callback_handler, &frame_listener,
+                             container);
+  }
+
+  return FALSE;
 }
 
 static void moz_container_unmap_wayland(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);
   g_clear_pointer(&container->frame_callback_handler, wl_callback_destroy);
 
+  container->surface_needs_clear = true;
   container->ready_to_draw = false;
 }
 
 static gint moz_container_get_scale(MozContainer *container) {
     static auto sGdkWindowGetScaleFactorPtr = (gint(*)(GdkWindow *))dlsym(
         RTLD_DEFAULT, "gdk_window_get_scale_factor");
 
     if (sGdkWindowGetScaleFactorPtr) {
@@ -226,17 +243,17 @@ void moz_container_map(GtkWidget *widget
     }
     tmp_list = tmp_list->next;
   }
 
   if (gtk_widget_get_has_window(widget)) {
     gdk_window_show(gtk_widget_get_window(widget));
 #if defined(MOZ_WAYLAND)
     if (!GDK_IS_X11_DISPLAY(gdk_display_get_default())) {
-      moz_container_map_wayland(MOZ_CONTAINER(widget));
+      moz_container_map_wayland(widget, nullptr);
     }
 #endif
   }
 }
 
 void moz_container_unmap(GtkWidget *widget) {
   g_return_if_fail(IS_MOZ_CONTAINER(widget));