Bug 1612377 [Wayland] Update opaque region and widget scale factor when screen DPI changes, r=jhorak
authorMartin Stransky <stransky@redhat.com>
Thu, 26 Mar 2020 12:12:48 +0000
changeset 520538 b651ff8263af5acea08f8f89dd71ede756c52d22
parent 520537 22fa6cbe32988d765925d6286c4694b9968c9cb2
child 520539 a5081d4443a95fd506cbe5db2835804f3bdc9a3c
push id37253
push usernerli@mozilla.com
push dateThu, 26 Mar 2020 21:36:52 +0000
treeherdermozilla-central@c644dd16e2cc [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjhorak
bugs1612377
milestone76.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1612377 [Wayland] Update opaque region and widget scale factor when screen DPI changes, r=jhorak - Integrate scale factor setup to moz_container_get_wl_surface() and don't call it explicitly. - No need to set it explicitly at nsWindow::GetWaylandSurface(). - Update client offset when scale changes in CSD mode by UpdateClientOffsetFromCSDWindow(). - Update scale factor/opaque region on EGL immediately. Differential Revision: https://phabricator.services.mozilla.com/D68352
widget/gtk/mozcontainer.cpp
widget/gtk/mozcontainer.h
widget/gtk/nsWindow.cpp
--- a/widget/gtk/mozcontainer.cpp
+++ b/widget/gtk/mozcontainer.cpp
@@ -590,16 +590,32 @@ static void moz_container_set_opaque_reg
     wl_region_destroy(region);
   } else {
     wl_surface_set_opaque_region(container->surface, nullptr);
   }
 
   container->opaque_region_needs_update = false;
 }
 
+static int moz_gtk_widget_get_scale_factor(MozContainer* container) {
+  static auto sGtkWidgetGetScaleFactor =
+      (gint(*)(GtkWidget*))dlsym(RTLD_DEFAULT, "gtk_widget_get_scale_factor");
+  return sGtkWidgetGetScaleFactor
+             ? sGtkWidgetGetScaleFactor(GTK_WIDGET(container))
+             : 1;
+}
+
+void moz_container_set_scale_factor(MozContainer* container) {
+  if (!container->surface) {
+    return;
+  }
+  wl_surface_set_buffer_scale(container->surface,
+                              moz_gtk_widget_get_scale_factor(container));
+}
+
 struct wl_surface* moz_container_get_wl_surface(MozContainer* container) {
   LOGWAYLAND(("%s [%p] surface %p ready_to_draw %d\n", __FUNCTION__,
               (void*)container, (void*)container->surface,
               container->ready_to_draw));
 
   if (!container->surface) {
     if (!container->ready_to_draw) {
       moz_container_request_parent_frame_callback(container);
@@ -640,31 +656,32 @@ struct wl_surface* moz_container_get_wl_
   }
 
   if (container->surface_position_needs_update) {
     moz_container_move(container, container->subsurface_dx,
                        container->subsurface_dy);
   }
 
   moz_container_set_opaque_region(container);
+  moz_container_set_scale_factor(container);
+
   return container->surface;
 }
 
 struct wl_egl_window* moz_container_get_wl_egl_window(MozContainer* container,
                                                       int scale) {
   LOGWAYLAND(("%s [%p] eglwindow %p\n", __FUNCTION__, (void*)container,
               (void*)container->eglwindow));
 
   // Always call moz_container_get_wl_surface() to ensure underlying
   // container->surface has correct scale and position.
   wl_surface* surface = moz_container_get_wl_surface(container);
   if (!surface) {
     return nullptr;
   }
-  wl_surface_set_buffer_scale(surface, scale);
   if (!container->eglwindow) {
     GdkWindow* window = gtk_widget_get_window(GTK_WIDGET(container));
     container->eglwindow =
         wl_egl_window_create(surface, gdk_window_get_width(window) * scale,
                              gdk_window_get_height(window) * scale);
 
     LOGWAYLAND(("%s [%p] created eglwindow %p\n", __FUNCTION__,
                 (void*)container, (void*)container->eglwindow));
--- a/widget/gtk/mozcontainer.h
+++ b/widget/gtk/mozcontainer.h
@@ -107,18 +107,17 @@ struct wl_egl_window* moz_container_get_
                                                       int scale);
 
 gboolean moz_container_has_wl_egl_window(MozContainer* container);
 gboolean moz_container_surface_needs_clear(MozContainer* container);
 void moz_container_move_resize(MozContainer* container, int dx, int dy,
                                int width, int height);
 void moz_container_egl_window_set_size(MozContainer* container, int width,
                                        int height);
-void moz_container_scale_changed(MozContainer* container,
-                                 GtkAllocation* aAllocation);
+void moz_container_set_scale_factor(MozContainer* container);
 void moz_container_add_initial_draw_callback(
     MozContainer* container, const std::function<void(void)>& initial_draw_cb);
 wl_surface* moz_gtk_widget_get_wl_surface(GtkWidget* aWidget);
 void moz_container_update_opaque_region(MozContainer* container,
                                         bool aSubtractCorners,
                                         bool aFullScreen);
 #endif
 
--- a/widget/gtk/nsWindow.cpp
+++ b/widget/gtk/nsWindow.cpp
@@ -2708,17 +2708,17 @@ gboolean nsWindow::OnConfigureEvent(GtkW
   // the window from maximized size and then immediately maximizes again.
   if (!mBoundsAreValid) {
     GtkAllocation allocation = {-1, -1, 0, 0};
     gtk_window_get_size(GTK_WINDOW(mShell), &allocation.width,
                         &allocation.height);
     OnSizeAllocate(&allocation);
   }
 
-  // Client offset are upated by _NET_FRAME_EXTENTS on X11 when system titlebar
+  // Client offset are updated by _NET_FRAME_EXTENTS on X11 when system titlebar
   // is enabled. In ither cases (Wayland or system titlebar is off on X11)
   // we don't get _NET_FRAME_EXTENTS X11 property notification so we derive
   // it from mContainer position.
   if (mCSDSupportLevel == CSD_SUPPORT_CLIENT) {
     if (!mIsX11Display || (mIsX11Display && mDrawInTitlebar)) {
       UpdateClientOffsetFromCSDWindow();
     }
   }
@@ -3684,16 +3684,36 @@ void nsWindow::OnScaleChanged(GtkAllocat
   mWindowScaleFactorChanged = true;
 
   // This eventually propagate new scale to the PuppetWidgets
   OnDPIChanged();
 
   // configure_event is already fired before scale-factor signal,
   // but size-allocate isn't fired by changing scale
   OnSizeAllocate(aAllocation);
+
+  // Client offset are updated by _NET_FRAME_EXTENTS on X11 when system titlebar
+  // is enabled. In ither cases (Wayland or system titlebar is off on X11)
+  // we don't get _NET_FRAME_EXTENTS X11 property notification so we derive
+  // it from mContainer position.
+  if (mCSDSupportLevel == CSD_SUPPORT_CLIENT) {
+    if (!mIsX11Display || (mIsX11Display && mDrawInTitlebar)) {
+      UpdateClientOffsetFromCSDWindow();
+    }
+  }
+
+#ifdef MOZ_WAYLAND
+  // We need to update scale and opaque region when scale of egl window
+  // is changed.
+  if (mContainer && moz_container_has_wl_egl_window(mContainer)) {
+    moz_container_set_scale_factor(mContainer);
+    LayoutDeviceIntRegion tmpRegion;
+    UpdateOpaqueRegion(tmpRegion);
+  }
+#endif
 }
 
 void nsWindow::DispatchDragEvent(EventMessage aMsg,
                                  const LayoutDeviceIntPoint& aRefPoint,
                                  guint aTime) {
   WidgetDragEvent event(true, aMsg, this);
 
   InitDragEvent(event);
@@ -7613,22 +7633,17 @@ void nsWindow::GetCompositorWidgetInitDa
       mXDisplay ? nsCString(XDisplayString(mXDisplay)) : nsCString(),
       mIsTransparent && !mHasAlphaVisual && !mTransparencyBitmapForTitlebar,
       GetClientSize());
 }
 
 #ifdef MOZ_WAYLAND
 wl_surface* nsWindow::GetWaylandSurface() {
   if (mContainer) {
-    struct wl_surface* surface =
-        moz_container_get_wl_surface(MOZ_CONTAINER(mContainer));
-    if (surface != NULL) {
-      wl_surface_set_buffer_scale(surface, GdkScaleFactor());
-    }
-    return surface;
+    return moz_container_get_wl_surface(MOZ_CONTAINER(mContainer));
   }
 
   NS_WARNING(
       "nsWindow::GetWaylandSurfaces(): We don't have any mContainer for "
       "drawing!");
   return nullptr;
 }