Bug 1431337 Scale widget size to the current monitor, not the first one; r?stransky draft
authorJan Horak <jhorak@redhat.com>
Thu, 18 Jan 2018 11:52:59 +0100
changeset 723594 0893678e7a2a23ed7121621fba1b9d1d32af8f5f
parent 722085 43fa1ba322d73122e66632cfdfdc8edb8e53e32e
child 746905 25b442d0c8cb937d08bfde69f449dec2c9edb365
push id96480
push userbmo:jhorak@redhat.com
push dateTue, 23 Jan 2018 15:51:49 +0000
reviewersstransky
bugs1431337
milestone59.0a1
Bug 1431337 Scale widget size to the current monitor, not the first one; r?stransky We need to use scaling factor of the monitor on which application is actually positioned. Previously we used ScreenHelperGTK::GetGTKMonitorScaleFactor() which use the first monitor. This does not work on hidpi+normal dpi monitors setup. MozReview-Commit-ID: 1dVYOe48tPJ
widget/gtk/nsNativeThemeGTK.cpp
--- a/widget/gtk/nsNativeThemeGTK.cpp
+++ b/widget/gtk/nsNativeThemeGTK.cpp
@@ -54,16 +54,33 @@ using namespace mozilla;
 using namespace mozilla::gfx;
 using namespace mozilla::widget;
 
 NS_IMPL_ISUPPORTS_INHERITED(nsNativeThemeGTK, nsNativeTheme, nsITheme,
                                                              nsIObserver)
 
 static int gLastGdkError;
 
+// Return scale factor of the monitor where the window is located
+// by the most part.
+static inline double
+GetThemeDpiScaleFactor(nsIFrame* aFrame)
+{
+  nsIWidget* rootWidget = aFrame->PresContext()->GetRootWidget();
+  if (rootWidget) {
+      // We need to use GetDefaultScale() despite it return monitor scale
+      // factor multiplied by font scale factor because it is the scale which
+      // is updated in nsPuppetWidget.
+      // Since we don't want to apply font scale factor for UI elements
+      // (because GTK does not do so) we need to remove that from returned value.
+      return rootWidget->GetDefaultScale().scale / gfxPlatformGtk::GetFontScaleFactor();
+  }
+  return 1.0;
+}
+
 nsNativeThemeGTK::nsNativeThemeGTK()
 {
   if (moz_gtk_init() != MOZ_GTK_SUCCESS) {
     memset(mDisabledWidgetTypes, 0xff, sizeof(mDisabledWidgetTypes));
     return;
   }
 
   // We have to call moz_gtk_shutdown before the event loop stops running.
@@ -1040,17 +1057,17 @@ nsNativeThemeGTK::GetExtraSizeForWidget(
       } else {
         aExtra->bottom = extra;
       }
       return false;
     }
   default:
     return false;
   }
-  gint scale = ScreenHelperGTK::GetGTKMonitorScaleFactor();
+  gint scale = GetThemeDpiScaleFactor(aFrame);
   aExtra->top *= scale;
   aExtra->right *= scale;
   aExtra->bottom *= scale;
   aExtra->left *= scale;
   return true;
 }
 
 NS_IMETHODIMP
@@ -1068,17 +1085,17 @@ nsNativeThemeGTK::DrawWidgetBackground(g
                             &flags))
     return NS_OK;
 
   gfxContext* ctx = aContext;
   nsPresContext *presContext = aFrame->PresContext();
 
   gfxRect rect = presContext->AppUnitsToGfxUnits(aRect);
   gfxRect dirtyRect = presContext->AppUnitsToGfxUnits(aDirtyRect);
-  gint scaleFactor = ScreenHelperGTK::GetGTKMonitorScaleFactor();
+  gint scaleFactor = GetThemeDpiScaleFactor(aFrame);
 
   // Align to device pixels where sensible
   // to provide crisper and faster drawing.
   // Don't snap if it's a non-unit scale factor. We're going to have to take
   // slow paths then in any case.
   bool snapped = ctx->UserToDevicePixelSnapped(rect);
   if (snapped) {
     // Leave rect in device coords but make dirtyRect consistent.
@@ -1287,17 +1304,17 @@ nsNativeThemeGTK::GetWidgetBorder(nsDevi
       break;
     MOZ_FALLTHROUGH;
   default:
     {
       GetCachedWidgetBorder(aFrame, aWidgetType, direction, aResult);
     }
   }
 
-  gint scale = ScreenHelperGTK::GetGTKMonitorScaleFactor();
+  gint scale = GetThemeDpiScaleFactor(aFrame);
   aResult->top *= scale;
   aResult->right *= scale;
   aResult->bottom *= scale;
   aResult->left *= scale;
   return NS_OK;
 }
 
 bool
@@ -1345,17 +1362,17 @@ nsNativeThemeGTK::GetWidgetPadding(nsDev
         if (aWidgetType == NS_THEME_MENUITEM)
           moz_gtk_menuitem_get_horizontal_padding(&horizontal_padding);
         else
           moz_gtk_checkmenuitem_get_horizontal_padding(&horizontal_padding);
 
         aResult->left += horizontal_padding;
         aResult->right += horizontal_padding;
 
-        gint scale = ScreenHelperGTK::GetGTKMonitorScaleFactor();
+        gint scale = GetThemeDpiScaleFactor(aFrame);
         aResult->top *= scale;
         aResult->right *= scale;
         aResult->bottom *= scale;
         aResult->left *= scale;
 
         return true;
       }
   }
@@ -1619,17 +1636,17 @@ nsNativeThemeGTK::GetMinimumWidgetSize(n
 
       moz_gtk_get_treeview_expander_size(&expander_size);
       aResult->width = aResult->height = expander_size;
       *aIsOverridable = false;
     }
     break;
   }
 
-  *aResult = *aResult * ScreenHelperGTK::GetGTKMonitorScaleFactor();
+  *aResult = *aResult * GetThemeDpiScaleFactor(aFrame);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsNativeThemeGTK::WidgetStateChanged(nsIFrame* aFrame, uint8_t aWidgetType,
                                      nsAtom* aAttribute, bool* aShouldRepaint,
                                      const nsAttrValue* aOldValue)