Bug 1745589 - Ensure we also draw headerbar parent if the headerbar has no background. r=stransky

Even if it has a radius. This can happen in older ElementaryOS themes...

Differential Revision: https://phabricator.services.mozilla.com/D133588
This commit is contained in:
Emilio Cobos Álvarez 2021-12-13 10:48:36 +00:00
Родитель b9f0306faa
Коммит 110e4553a3
4 изменённых файлов: 60 добавлений и 17 удалений

Просмотреть файл

@ -10,6 +10,7 @@
#include "gtkdrawing.h"
#include "mozilla/Assertions.h"
#include "mozilla/PodOperations.h"
#include "mozilla/ScopeExit.h"
#include "nsDebug.h"
#include "nsPrintfCString.h"
#include "nsString.h"
@ -26,6 +27,8 @@ enum class CSDStyle {
Normal,
};
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];
@ -440,6 +443,21 @@ static GtkWidget* CreateNotebookWidget() {
return widget;
}
static bool HasBackground(GtkStyleContext* aStyle) {
GdkRGBA gdkColor;
gtk_style_context_get_background_color(aStyle, GTK_STATE_FLAG_NORMAL,
&gdkColor);
if (gdkColor.alpha != 0.0) {
return true;
}
GValue value = G_VALUE_INIT;
gtk_style_context_get_property(aStyle, "background-image",
GTK_STATE_FLAG_NORMAL, &value);
auto cleanup = mozilla::MakeScopeExit([&] { g_value_unset(&value); });
return g_value_get_boxed(&value);
}
static void CreateHeaderBarWidget(WidgetNodeType aAppearance) {
GtkWidget* window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
GtkStyleContext* windowStyle = gtk_widget_get_style_context(window);
@ -489,7 +507,27 @@ static void CreateHeaderBarWidget(WidgetNodeType aAppearance) {
}
gtk_container_add(GTK_CONTAINER(window), fixed);
gtk_container_add(GTK_CONTAINER(fixed), sWidgetStorage[aAppearance]);
gtk_container_add(GTK_CONTAINER(fixed), headerBar);
gtk_style_context_invalidate(headerBarStyle);
gtk_style_context_invalidate(fixedStyle);
// 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 = [&] {
const bool headerBarHasBackground = HasBackground(headerBarStyle);
if (headerBarHasBackground && GetBorderRadius(headerBarStyle)) {
return false;
}
if (HasBackground(fixedStyle) &&
(GetBorderRadius(fixedStyle) || !headerBarHasBackground)) {
return true;
}
return false;
}();
}
#define ICON_SCALE_VARIANTS 2
@ -554,7 +592,7 @@ static void CreateHeaderBarButton(GtkWidget* aParentWidget,
// We bypass GetWidget() here because we create all titlebar
// buttons at once when a first one is requested.
NS_ASSERTION(sWidgetStorage[aAppearance] == nullptr,
NS_ASSERTION(!sWidgetStorage[aAppearance],
"Titlebar button is already created!");
sWidgetStorage[aAppearance] = widget;
@ -754,6 +792,8 @@ static GtkWidget* CreateWidget(WidgetNodeType aAppearance) {
return CreateComboBoxEntryArrowWidget();
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:
case MOZ_GTK_HEADER_BAR_BUTTON_CLOSE:
@ -1461,6 +1501,15 @@ void StyleContextSetScale(GtkStyleContext* style, gint aScaleFactor) {
}
}
bool HeaderBarShouldDrawContainer(WidgetNodeType aNodeType) {
MOZ_ASSERT(aNodeType == MOZ_GTK_HEADER_BAR ||
aNodeType == MOZ_GTK_HEADER_BAR_MAXIMIZED);
mozilla::Unused << GetWidget(aNodeType);
return aNodeType == MOZ_GTK_HEADER_BAR
? gHeaderBarShouldDrawContainer
: gMaximizedHeaderBarShouldDrawContainer;
}
gint GetBorderRadius(GtkStyleContext* aStyle) {
GValue value = G_VALUE_INIT;
// NOTE(emilio): In an ideal world, we'd query the two longhands

Просмотреть файл

@ -58,4 +58,6 @@ void StyleContextSetScale(GtkStyleContext* style, gint aScaleFactor);
gint GetBorderRadius(GtkStyleContext* aStyle);
bool HeaderBarShouldDrawContainer(WidgetNodeType);
#endif // WidgetStyleCache_h

Просмотреть файл

@ -2177,15 +2177,12 @@ static gint moz_gtk_header_bar_paint(WidgetNodeType widgetType, cairo_t* cr,
// Some themes like Elementary's style the container of the headerbar rather
// than the header bar itself.
if (!GetBorderRadius(style)) {
if (HeaderBarShouldDrawContainer(widgetType)) {
auto containerType = widgetType == MOZ_GTK_HEADER_BAR
? MOZ_GTK_HEADERBAR_FIXED
: MOZ_GTK_HEADERBAR_FIXED_MAXIMIZED;
GtkStyleContext* containerStyle = GetStyleContext(
style = GetStyleContext(
containerType, state->scale, GTK_TEXT_DIR_NONE, state_flags);
if (GetBorderRadius(containerStyle)) {
style = containerStyle;
}
}
// Some themes (Adwaita for instance) draws bold dark line at

Просмотреть файл

@ -1549,7 +1549,10 @@ void nsLookAndFeel::PerThemeData::Init() {
g_object_unref(accelStyle);
}
style = GetStyleContext(MOZ_GTK_HEADER_BAR);
const auto effectiveHeaderBarStyle =
HeaderBarShouldDrawContainer(MOZ_GTK_HEADER_BAR) ? MOZ_GTK_HEADERBAR_FIXED
: MOZ_GTK_HEADER_BAR;
style = GetStyleContext(effectiveHeaderBarStyle);
{
gtk_style_context_get_color(style, GTK_STATE_FLAG_NORMAL, &color);
mTitlebarText = GDK_RGBA_TO_NS_RGBA(color);
@ -1559,15 +1562,7 @@ void nsLookAndFeel::PerThemeData::Init() {
mTitlebarInactiveText = GDK_RGBA_TO_NS_RGBA(color);
mTitlebarInactiveBackground =
GetBackgroundColor(style, mTitlebarText, GTK_STATE_FLAG_BACKDROP);
mTitlebarRadius = 0;
if (!IsSolidCSDStyleUsed()) {
mTitlebarRadius = GetBorderRadius(style);
if (!mTitlebarRadius) {
// Some themes like ElementaryOS set the radius on the headerbar parent.
style = GetStyleContext(MOZ_GTK_HEADERBAR_FIXED);
mTitlebarRadius = GetBorderRadius(style);
}
}
mTitlebarRadius = IsSolidCSDStyleUsed() ? 0 : GetBorderRadius(style);
}
style = GetStyleContext(MOZ_GTK_MENUPOPUP);