Blob Blame History Raw
diff -up mozilla-release/widget/gtk/nsNativeThemeGTK.cpp.1144745-1 mozilla-release/widget/gtk/nsNativeThemeGTK.cpp
--- mozilla-release/widget/gtk/nsNativeThemeGTK.cpp.1144745-1	2015-05-13 10:25:28.638492635 +0200
+++ mozilla-release/widget/gtk/nsNativeThemeGTK.cpp	2015-05-13 10:28:41.438095846 +0200
@@ -32,6 +32,7 @@
 #include "gfxPlatformGtk.h"
 #include "gfxGdkNativeRenderer.h"
 #include <algorithm>
+#include <dlfcn.h>
 
 using namespace mozilla;
 using namespace mozilla::gfx;
@@ -88,6 +89,24 @@ nsNativeThemeGTK::RefreshWidgetWindow(ns
   vm->InvalidateAllViews();
 }
 
+gint
+nsNativeThemeGTK::GdkScaleFactor()
+{
+#if (MOZ_WIDGET_GTK >= 3)
+  // Since GDK 3.10
+  static auto sGdkScreenGetMonitorScaleFactorPtr = (gint (*)(GdkScreen*, gint))
+      dlsym(RTLD_DEFAULT, "gdk_screen_get_monitor_scale_factor");
+  if (sGdkScreenGetMonitorScaleFactorPtr) {
+      // FIXME: In the future, we'll want to fix this for GTK on Wayland which
+      // supports a variable scale factor per display.
+      GdkScreen *screen = gdk_screen_get_default();
+      return sGdkScreenGetMonitorScaleFactorPtr(screen, 0);
+  }
+#endif
+    return 1;
+}
+
+
 static bool IsFrameContentNodeInNamespace(nsIFrame *aFrame, uint32_t aNamespace)
 {
   nsIContent *content = aFrame ? aFrame->GetContent() : nullptr;
@@ -711,10 +730,10 @@ nsNativeThemeGTK::GetExtraSizeForWidget(
   switch (aWidgetType) {
   case NS_THEME_SCROLLBAR_THUMB_VERTICAL:
     aExtra->top = aExtra->bottom = 1;
-    return true;
+    break;
   case NS_THEME_SCROLLBAR_THUMB_HORIZONTAL:
     aExtra->left = aExtra->right = 1;
-    return true;
+    break;
 
   // Include the indicator spacing (the padding around the control).
   case NS_THEME_CHECKBOX:
@@ -732,7 +751,7 @@ nsNativeThemeGTK::GetExtraSizeForWidget(
       aExtra->right = indicator_spacing;
       aExtra->bottom = indicator_spacing;
       aExtra->left = indicator_spacing;
-      return true;
+      break;
     }
   case NS_THEME_BUTTON :
     {
@@ -745,7 +764,7 @@ nsNativeThemeGTK::GetExtraSizeForWidget(
         aExtra->right = right;
         aExtra->bottom = bottom;
         aExtra->left = left;
-        return true;
+        break;
       }
     }
   case NS_THEME_FOCUS_OUTLINE:
@@ -753,7 +772,7 @@ nsNativeThemeGTK::GetExtraSizeForWidget(
       moz_gtk_get_focus_outline_size(&aExtra->left, &aExtra->top);
       aExtra->right = aExtra->left;
       aExtra->bottom = aExtra->top;
-      return true;
+      break;
     }
   case NS_THEME_TAB :
     {
@@ -777,6 +796,11 @@ nsNativeThemeGTK::GetExtraSizeForWidget(
   default:
     return false;
   }
+  aExtra->top *= GdkScaleFactor();
+  aExtra->right *= GdkScaleFactor();
+  aExtra->bottom *= GdkScaleFactor();
+  aExtra->left *= GdkScaleFactor();
+  return true;
 }
 
 NS_IMETHODIMP
@@ -803,6 +827,7 @@ nsNativeThemeGTK::DrawWidgetBackground(n
 
   gfxRect rect = presContext->AppUnitsToGfxUnits(aRect);
   gfxRect dirtyRect = presContext->AppUnitsToGfxUnits(aDirtyRect);
+  gint scaleFactor = GdkScaleFactor();
 
   // Align to device pixels where sensible
   // to provide crisper and faster drawing.
@@ -840,8 +865,10 @@ nsNativeThemeGTK::DrawWidgetBackground(n
 
   // gdk rectangles are wrt the drawing rect.
 
-  GdkRectangle gdk_rect = {-drawingRect.x, -drawingRect.y,
-                           widgetRect.width, widgetRect.height};
+  GdkRectangle gdk_rect = {-drawingRect.x/scaleFactor,
+                           -drawingRect.y/scaleFactor,
+                           widgetRect.width/scaleFactor,
+                           widgetRect.height/scaleFactor};
 
   // translate everything so (0,0) is the top left of the drawingRect
   gfxContextAutoSaveRestore autoSR(ctx);
@@ -850,6 +877,7 @@ nsNativeThemeGTK::DrawWidgetBackground(n
     tm = ctx->CurrentMatrix();
   }
   tm.Translate(rect.TopLeft() + gfxPoint(drawingRect.x, drawingRect.y));
+  tm.Scale(scaleFactor, scaleFactor); // Draw in GDK coords
   ctx->SetMatrix(tm);
 
   NS_ASSERTION(!IsWidgetTypeDisabled(mDisabledWidgetTypes, aWidgetType),
@@ -1038,6 +1066,11 @@ nsNativeThemeGTK::GetWidgetPadding(nsDev
         aResult->left += horizontal_padding;
         aResult->right += horizontal_padding;
 
+        aResult->top *= GdkScaleFactor();
+        aResult->right *= GdkScaleFactor();
+        aResult->bottom *= GdkScaleFactor();
+        aResult->left *= GdkScaleFactor();
+
         return true;
       }
   }
@@ -1298,6 +1331,9 @@ nsNativeThemeGTK::GetMinimumWidgetSize(n
     }
     break;
   }
+
+  *aResult = *aResult * GdkScaleFactor();
+
   return NS_OK;
 }
 
diff -up mozilla-release/widget/gtk/nsNativeThemeGTK.h.1144745-1 mozilla-release/widget/gtk/nsNativeThemeGTK.h
--- mozilla-release/widget/gtk/nsNativeThemeGTK.h.1144745-1	2015-05-08 18:55:27.000000000 +0200
+++ mozilla-release/widget/gtk/nsNativeThemeGTK.h	2015-05-13 10:25:28.642492647 +0200
@@ -81,6 +81,7 @@ private:
                                nsIntMargin* aExtra);
 
   void RefreshWidgetWindow(nsIFrame* aFrame);
+  gint GdkScaleFactor();
 
   uint8_t mDisabledWidgetTypes[32];
   uint8_t mSafeWidgetStates[1024];    // 256 widgets * 32 bits per widget