Bug 1967139 - [x11] CSD decoration painting shouldn't honor text scale. r=stransky
Otherwise with 1.5 scale or so we draw a too big border / radius which causes the corner to be ugly. Differential Revision: https://phabricator.services.mozilla.com/D249906
This commit is contained in:
committed by
ealvarez@mozilla.com
parent
4e26479bc5
commit
437fba298d
@@ -7,10 +7,7 @@
|
||||
#define _NS_DEVICECONTEXT_H_
|
||||
|
||||
#include <stdint.h> // for uint32_t
|
||||
#include <sys/types.h> // for int32_t
|
||||
#include "gfxTypes.h" // for gfxFloat
|
||||
#include "gfxFont.h" // for gfxFont::Orientation
|
||||
#include "mozilla/Assertions.h" // for MOZ_ASSERT_HELPER2
|
||||
#include "mozilla/RefPtr.h" // for RefPtr
|
||||
#include "nsCOMPtr.h" // for nsCOMPtr
|
||||
#include "nsCoord.h" // for nscoord
|
||||
@@ -21,8 +18,7 @@
|
||||
#include "mozilla/AppUnits.h" // for AppUnits
|
||||
#include "nsFontMetrics.h" // for nsFontMetrics::Params
|
||||
#include "mozilla/gfx/Point.h" // for IntSize
|
||||
#include "mozilla/gfx/PrintTarget.h" // for PrintTarget::PageDoneCallback
|
||||
#include "mozilla/gfx/PrintPromise.h"
|
||||
#include "mozilla/gfx/PrintPromise.h" // for PrintEndDocumentPromise
|
||||
|
||||
class gfxContext;
|
||||
class gfxTextPerfMetrics;
|
||||
@@ -45,6 +41,9 @@ enum class ScreenOrientation : uint32_t;
|
||||
namespace widget {
|
||||
class Screen;
|
||||
} // namespace widget
|
||||
namespace gfx {
|
||||
class PrintTarget;
|
||||
}
|
||||
} // namespace mozilla
|
||||
|
||||
class nsDeviceContext final {
|
||||
|
||||
@@ -6,13 +6,17 @@
|
||||
#ifndef MOZILLA_GFX_PRINTPROMISE_H
|
||||
#define MOZILLA_GFX_PRINTPROMISE_H
|
||||
|
||||
#include "ErrorList.h"
|
||||
#include "mozilla/MozPromise.h"
|
||||
#include "nscore.h"
|
||||
|
||||
namespace mozilla::gfx {
|
||||
namespace mozilla {
|
||||
|
||||
template <typename ResolveValueT, typename RejectValueT, bool IsExclusive>
|
||||
class MozPromise;
|
||||
|
||||
namespace gfx {
|
||||
|
||||
using PrintEndDocumentPromise = MozPromise</* unused */ bool, nsresult, false>;
|
||||
|
||||
} // namespace mozilla::gfx
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace mozilla
|
||||
#endif
|
||||
|
||||
@@ -28,6 +28,7 @@ headers = [
|
||||
"mozilla/PresShell.h",
|
||||
"mozilla/ServoTraversalStatistics.h",
|
||||
"mozilla/SizeOfState.h",
|
||||
"nsDeviceContext.h",
|
||||
"nsCSSProps.h",
|
||||
"nsNameSpaceManager.h",
|
||||
]
|
||||
@@ -311,6 +312,7 @@ opaque-types = [
|
||||
"RefPtr_Proxy_member_function",
|
||||
"nsAutoPtr_Proxy",
|
||||
"nsAutoPtr_Proxy_member_function",
|
||||
"nsRegion_.*",
|
||||
"mozilla::detail::HashTable", # <- We should be able to remove this and
|
||||
# HashSet below once
|
||||
# https://github.com/rust-lang/rust-bindgen/pull/1515
|
||||
|
||||
@@ -142,6 +142,13 @@ macro_rules! lnf_int_variable {
|
||||
}};
|
||||
}
|
||||
|
||||
fn eval_gtk_csd_titlebar_radius(device: &Device, url_data: &UrlExtraData) -> VariableValue {
|
||||
let int_pixels = lnf_int!(TitlebarRadius);
|
||||
let unzoomed_scale =
|
||||
device.device_pixel_ratio_ignoring_full_zoom().get() / device.device_pixel_ratio().get();
|
||||
VariableValue::pixels(int_pixels as f32 * unzoomed_scale, url_data)
|
||||
}
|
||||
|
||||
static CHROME_ENVIRONMENT_VARIABLES: [EnvironmentVariable; 10] = [
|
||||
lnf_int_variable!(
|
||||
atom!("-moz-mac-titlebar-height"),
|
||||
@@ -153,10 +160,9 @@ static CHROME_ENVIRONMENT_VARIABLES: [EnvironmentVariable; 10] = [
|
||||
TitlebarButtonSpacing,
|
||||
int_pixels
|
||||
),
|
||||
lnf_int_variable!(
|
||||
make_variable!(
|
||||
atom!("-moz-gtk-csd-titlebar-radius"),
|
||||
TitlebarRadius,
|
||||
int_pixels
|
||||
eval_gtk_csd_titlebar_radius
|
||||
),
|
||||
lnf_int_variable!(
|
||||
atom!("-moz-gtk-csd-tooltip-radius"),
|
||||
|
||||
@@ -478,6 +478,20 @@ impl Device {
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns app units per pixel at 1x full-zoom.
|
||||
fn app_units_per_device_pixel_at_unit_full_zoom(&self) -> i32 {
|
||||
match self.pres_context() {
|
||||
Some(pc) => unsafe { (*pc.mDeviceContext.mRawPtr).mAppUnitsPerDevPixelAtUnitFullZoom },
|
||||
None => AU_PER_PX,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the device pixel ratio, ignoring the full zoom factor.
|
||||
pub fn device_pixel_ratio_ignoring_full_zoom(&self) -> Scale<f32, CSSPixel, DevicePixel> {
|
||||
let au_per_px = AU_PER_PX as f32;
|
||||
Scale::new(au_per_px / self.app_units_per_device_pixel_at_unit_full_zoom() as f32)
|
||||
}
|
||||
|
||||
/// Returns the device pixel ratio.
|
||||
pub fn device_pixel_ratio(&self) -> Scale<f32, CSSPixel, DevicePixel> {
|
||||
let pc = match self.pres_context() {
|
||||
|
||||
@@ -28,7 +28,6 @@ enum class CSDStyle {
|
||||
};
|
||||
|
||||
static bool gHeaderBarShouldDrawContainer = false;
|
||||
static bool gMaximizedHeaderBarShouldDrawContainer = false;
|
||||
static CSDStyle gCSDStyle = CSDStyle::Unknown;
|
||||
static GtkWidget* sWidgetStorage[MOZ_GTK_WIDGET_NODE_COUNT];
|
||||
static GtkStyleContext* sStyleStorage[MOZ_GTK_WIDGET_NODE_COUNT];
|
||||
@@ -190,24 +189,12 @@ static void CreateHeaderBarWidget(WidgetNodeType aAppearance) {
|
||||
gtk_style_context_add_class(headerBarStyle, "default-decoration");
|
||||
|
||||
sWidgetStorage[aAppearance] = headerBar;
|
||||
if (aAppearance == MOZ_GTK_HEADER_BAR_MAXIMIZED) {
|
||||
MOZ_ASSERT(!sWidgetStorage[MOZ_GTK_HEADERBAR_WINDOW_MAXIMIZED],
|
||||
"Window widget is already created!");
|
||||
MOZ_ASSERT(!sWidgetStorage[MOZ_GTK_HEADERBAR_FIXED_MAXIMIZED],
|
||||
"Fixed widget is already created!");
|
||||
|
||||
gtk_style_context_add_class(windowStyle, "maximized");
|
||||
|
||||
sWidgetStorage[MOZ_GTK_HEADERBAR_WINDOW_MAXIMIZED] = window;
|
||||
sWidgetStorage[MOZ_GTK_HEADERBAR_FIXED_MAXIMIZED] = fixed;
|
||||
} else {
|
||||
MOZ_ASSERT(!sWidgetStorage[MOZ_GTK_HEADERBAR_WINDOW],
|
||||
"Window widget is already created!");
|
||||
MOZ_ASSERT(!sWidgetStorage[MOZ_GTK_HEADERBAR_FIXED],
|
||||
"Fixed widget is already created!");
|
||||
sWidgetStorage[MOZ_GTK_HEADERBAR_WINDOW] = window;
|
||||
sWidgetStorage[MOZ_GTK_HEADERBAR_FIXED] = fixed;
|
||||
}
|
||||
MOZ_ASSERT(!sWidgetStorage[MOZ_GTK_HEADERBAR_WINDOW],
|
||||
"Window widget is already created!");
|
||||
MOZ_ASSERT(!sWidgetStorage[MOZ_GTK_HEADERBAR_FIXED],
|
||||
"Fixed widget is already created!");
|
||||
sWidgetStorage[MOZ_GTK_HEADERBAR_WINDOW] = window;
|
||||
sWidgetStorage[MOZ_GTK_HEADERBAR_FIXED] = fixed;
|
||||
|
||||
gtk_container_add(GTK_CONTAINER(window), fixed);
|
||||
gtk_container_add(GTK_CONTAINER(fixed), headerBar);
|
||||
@@ -216,10 +203,7 @@ static void CreateHeaderBarWidget(WidgetNodeType aAppearance) {
|
||||
|
||||
// Some themes like Elementary's style the container of the headerbar rather
|
||||
// than the header bar itself.
|
||||
bool& shouldDrawContainer = aAppearance == MOZ_GTK_HEADER_BAR
|
||||
? gHeaderBarShouldDrawContainer
|
||||
: gMaximizedHeaderBarShouldDrawContainer;
|
||||
shouldDrawContainer = [&] {
|
||||
gHeaderBarShouldDrawContainer = [&] {
|
||||
const bool headerBarHasBackground = HasBackground(headerBarStyle);
|
||||
if (headerBarHasBackground && GetBorderRadius(headerBarStyle)) {
|
||||
return false;
|
||||
@@ -250,7 +234,6 @@ bool IsSolidCSDStyleUsed() {
|
||||
|
||||
static void CreateHeaderBar() {
|
||||
CreateHeaderBarWidget(MOZ_GTK_HEADER_BAR);
|
||||
CreateHeaderBarWidget(MOZ_GTK_HEADER_BAR_MAXIMIZED);
|
||||
}
|
||||
|
||||
static GtkWidget* CreateWidget(WidgetNodeType aAppearance) {
|
||||
@@ -276,11 +259,8 @@ static GtkWidget* CreateWidget(WidgetNodeType aAppearance) {
|
||||
case MOZ_GTK_TREE_HEADER_CELL:
|
||||
return CreateTreeHeaderCellWidget();
|
||||
case MOZ_GTK_HEADERBAR_WINDOW:
|
||||
case MOZ_GTK_HEADERBAR_WINDOW_MAXIMIZED:
|
||||
case MOZ_GTK_HEADERBAR_FIXED:
|
||||
case MOZ_GTK_HEADERBAR_FIXED_MAXIMIZED:
|
||||
case MOZ_GTK_HEADER_BAR:
|
||||
case MOZ_GTK_HEADER_BAR_MAXIMIZED:
|
||||
/* Create header bar widgets once and fill with child elements as we need
|
||||
the header bar fully configured to get a correct style */
|
||||
CreateHeaderBar();
|
||||
@@ -536,14 +516,14 @@ static GtkStyleContext* GetCssNodeStyleInternal(WidgetNodeType aNodeType) {
|
||||
break;
|
||||
case MOZ_GTK_WINDOW_DECORATION: {
|
||||
GtkStyleContext* parentStyle =
|
||||
CreateSubStyleWithClass(MOZ_GTK_WINDOW, "csd");
|
||||
CreateSubStyleWithClass(MOZ_GTK_HEADERBAR_WINDOW, "csd");
|
||||
style = CreateCSSNode("decoration", parentStyle);
|
||||
g_object_unref(parentStyle);
|
||||
break;
|
||||
}
|
||||
case MOZ_GTK_WINDOW_DECORATION_SOLID: {
|
||||
GtkStyleContext* parentStyle =
|
||||
CreateSubStyleWithClass(MOZ_GTK_WINDOW, "solid-csd");
|
||||
CreateSubStyleWithClass(MOZ_GTK_HEADERBAR_WINDOW, "solid-csd");
|
||||
style = CreateCSSNode("decoration", parentStyle);
|
||||
g_object_unref(parentStyle);
|
||||
break;
|
||||
@@ -606,9 +586,6 @@ void ResetWidgetCache() {
|
||||
if (sWidgetStorage[MOZ_GTK_HEADERBAR_WINDOW]) {
|
||||
gtk_widget_destroy(sWidgetStorage[MOZ_GTK_HEADERBAR_WINDOW]);
|
||||
}
|
||||
if (sWidgetStorage[MOZ_GTK_HEADERBAR_WINDOW_MAXIMIZED]) {
|
||||
gtk_widget_destroy(sWidgetStorage[MOZ_GTK_HEADERBAR_WINDOW_MAXIMIZED]);
|
||||
}
|
||||
|
||||
/* Clear already freed arrays */
|
||||
mozilla::PodArrayZero(sWidgetStorage);
|
||||
@@ -688,12 +665,9 @@ void StyleContextSetScale(GtkStyleContext* style, gint aScaleFactor) {
|
||||
}
|
||||
|
||||
bool HeaderBarShouldDrawContainer(WidgetNodeType aNodeType) {
|
||||
MOZ_ASSERT(aNodeType == MOZ_GTK_HEADER_BAR ||
|
||||
aNodeType == MOZ_GTK_HEADER_BAR_MAXIMIZED);
|
||||
MOZ_ASSERT(aNodeType == MOZ_GTK_HEADER_BAR);
|
||||
mozilla::Unused << GetWidget(aNodeType);
|
||||
return aNodeType == MOZ_GTK_HEADER_BAR
|
||||
? gHeaderBarShouldDrawContainer
|
||||
: gMaximizedHeaderBarShouldDrawContainer;
|
||||
return gHeaderBarShouldDrawContainer;
|
||||
}
|
||||
|
||||
gint GetBorderRadius(GtkStyleContext* aStyle) {
|
||||
|
||||
@@ -134,20 +134,14 @@ enum WidgetNodeType : int {
|
||||
MOZ_GTK_WINDOW,
|
||||
/* Used only as a container for MOZ_GTK_HEADER_BAR. */
|
||||
MOZ_GTK_HEADERBAR_WINDOW,
|
||||
/* Used only as a container for MOZ_GTK_HEADER_BAR_MAXIMIZED. */
|
||||
MOZ_GTK_HEADERBAR_WINDOW_MAXIMIZED,
|
||||
/* Used only as a container for MOZ_GTK_HEADER_BAR. */
|
||||
MOZ_GTK_HEADERBAR_FIXED,
|
||||
/* Used only as a container for MOZ_GTK_HEADER_BAR_MAXIMIZED. */
|
||||
MOZ_GTK_HEADERBAR_FIXED_MAXIMIZED,
|
||||
/* Window container for all widgets */
|
||||
MOZ_GTK_WINDOW_CONTAINER,
|
||||
/* Used for scrolled window shell. */
|
||||
MOZ_GTK_SCROLLED_WINDOW,
|
||||
/* Paints a GtkHeaderBar */
|
||||
MOZ_GTK_HEADER_BAR,
|
||||
/* Paints a GtkHeaderBar in maximized state */
|
||||
MOZ_GTK_HEADER_BAR_MAXIMIZED,
|
||||
|
||||
/* Client-side window decoration node. Available on GTK 3.20+. */
|
||||
MOZ_GTK_WINDOW_DECORATION,
|
||||
|
||||
@@ -62,8 +62,18 @@ static int gLastGdkError;
|
||||
|
||||
// Return widget scale factor of the monitor where the window is located by the
|
||||
// most part. We intentionally honor the text scale factor here in order to
|
||||
// have consistent scaling with other UI elements.
|
||||
static inline CSSToLayoutDeviceScale GetWidgetScaleFactor(nsIFrame* aFrame) {
|
||||
// have consistent scaling with other UI elements, except for the window
|
||||
// decorations, which should use unscaled pixels.
|
||||
static inline CSSToLayoutDeviceScale GetWidgetScaleFactor(
|
||||
nsIFrame* aFrame, StyleAppearance aAppearance) {
|
||||
if (aAppearance == StyleAppearance::MozWindowDecorations) {
|
||||
// Window decorations can't honor the text scale.
|
||||
return CSSToLayoutDeviceScale{
|
||||
float(AppUnitsPerCSSPixel()) /
|
||||
float(aFrame->PresContext()
|
||||
->DeviceContext()
|
||||
->AppUnitsPerDevPixelAtUnitFullZoom())};
|
||||
}
|
||||
return aFrame->PresContext()->CSSToDevPixelScale();
|
||||
}
|
||||
|
||||
@@ -503,7 +513,7 @@ nsNativeThemeGTK::DrawWidgetBackground(gfxContext* aContext, nsIFrame* aFrame,
|
||||
Transparency transparency = GetWidgetTransparency(aFrame, aAppearance);
|
||||
|
||||
// gdk rectangles are wrt the drawing rect.
|
||||
auto scaleFactor = GetWidgetScaleFactor(aFrame);
|
||||
auto scaleFactor = GetWidgetScaleFactor(aFrame, aAppearance);
|
||||
LayoutDeviceIntRect gdkDevRect(-drawingRect.TopLeft(), widgetRect.Size());
|
||||
|
||||
auto gdkCssRect = CSSIntRect::RoundIn(gdkDevRect / scaleFactor);
|
||||
@@ -632,7 +642,8 @@ LayoutDeviceIntMargin nsNativeThemeGTK::GetWidgetBorder(
|
||||
|
||||
GtkTextDirection direction = GetTextDirection(aFrame);
|
||||
CSSIntMargin result = GetCachedWidgetBorder(aFrame, aAppearance, direction);
|
||||
return (CSSMargin(result) * GetWidgetScaleFactor(aFrame)).Rounded();
|
||||
return (CSSMargin(result) * GetWidgetScaleFactor(aFrame, aAppearance))
|
||||
.Rounded();
|
||||
}
|
||||
|
||||
bool nsNativeThemeGTK::GetWidgetPadding(nsDeviceContext* aContext,
|
||||
|
||||
Reference in New Issue
Block a user