Bug 1427999 - Implement GetToolbarButtonMetrics() to get titlebar button size and border, r?jhorak
Titlebar button on Gtk+ >= 3.20 can have defined its size as min-width and min-height
and can leave CSS styles border/padding empty. To render the button icon at center we need to
calculate button widget border from gap between icon and button.
This is done by GetToolbarButtonMetrics() which also stores final values to
ToolbarButtonGTKMetrics cache.
MozReview-Commit-ID: 5sMJATWHUNX
--- a/widget/gtk/gtk3drawing.cpp
+++ b/widget/gtk/gtk3drawing.cpp
@@ -20,16 +20,17 @@
#include <math.h>
static gboolean checkbox_check_state;
static gboolean notebook_has_tab_gap;
static ScrollbarGTKMetrics sScrollbarMetrics[2];
static ToggleGTKMetrics sCheckboxMetrics;
static ToggleGTKMetrics sRadioMetrics;
+static ToolbarButtonGTKMetrics sToolbarButtonMetrics;
#define ARROW_UP 0
#define ARROW_DOWN G_PI
#define ARROW_RIGHT G_PI_2
#define ARROW_LEFT (G_PI+G_PI_2)
#if !GTK_CHECK_VERSION(3,14,0)
#define GTK_STATE_FLAG_CHECKED (1 << 11)
@@ -174,16 +175,17 @@ moz_gtk_refresh()
else {
notebook_has_tab_gap = true;
}
sScrollbarMetrics[GTK_ORIENTATION_HORIZONTAL].initialized = false;
sScrollbarMetrics[GTK_ORIENTATION_VERTICAL].initialized = false;
sCheckboxMetrics.initialized = false;
sRadioMetrics.initialized = false;
+ sToolbarButtonMetrics.initialized = false;
}
gint
moz_gtk_checkbox_get_metrics(gint* indicator_size, gint* indicator_spacing)
{
gtk_widget_style_get(GetWidget(MOZ_GTK_CHECKBUTTON_CONTAINER),
"indicator_size", indicator_size,
"indicator_spacing", indicator_spacing,
@@ -297,16 +299,63 @@ moz_gtk_splitter_get_metrics(gint orient
style = GetStyleContext(MOZ_GTK_SPLITTER_HORIZONTAL);
} else {
style = GetStyleContext(MOZ_GTK_SPLITTER_VERTICAL);
}
gtk_style_context_get_style(style, "handle_size", size, NULL);
return MOZ_GTK_SUCCESS;
}
+const ToolbarButtonGTKMetrics*
+GetToolbarButtonMetrics()
+{
+ if (!sToolbarButtonMetrics.initialized) {
+ GtkStyleContext* style = GetStyleContext(MOZ_GTK_HEADER_BAR_BUTTON_CLOSE);
+
+ gint iconWidth, iconHeight;
+ if (!gtk_icon_size_lookup(GTK_ICON_SIZE_MENU, &iconWidth, &iconHeight)) {
+ NS_WARNING("Failed to get Gtk+ icon size for titlebar button!");
+
+ // Use some reasonable fallback size
+ iconWidth = 16;
+ iconHeight = 16;
+ }
+
+ gint width = 0, height = 0;
+ if (gtk_check_version(3, 20, 0) == nullptr) {
+ gtk_style_context_get(style, gtk_style_context_get_state(style),
+ "min-width", &width,
+ "min-height", &height, NULL);
+ }
+
+ // Cover cases when min-width/min-height is not set, it's invalid
+ // or we're running on Gtk+ < 3.20.
+ if (width < iconWidth)
+ width = iconWidth;
+ if (height < iconHeight)
+ height = iconHeight;
+
+ gint left = 0, top = 0, right = 0, bottom = 0;
+ moz_gtk_add_margin_border_padding(style, &left, &top, &right, &bottom);
+
+ width += left + right;
+ height += top + bottom;
+ sToolbarButtonMetrics.minSizeWithBorderMargin.width = width;
+ sToolbarButtonMetrics.minSizeWithBorderMargin.height = height;
+
+ // Get border size from gap between icon and button sizes.
+ // Buton size is calculated as min-width/height + border/padding.
+ sToolbarButtonMetrics.iconXPosition = (width - iconWidth) / 2;
+ sToolbarButtonMetrics.iconYPosition = (height - iconHeight) / 2;
+ sToolbarButtonMetrics.initialized = true;
+ }
+
+ return &sToolbarButtonMetrics;
+}
+
static gint
moz_gtk_window_paint(cairo_t *cr, GdkRectangle* rect,
GtkTextDirection direction)
{
GtkStyleContext* style = GetStyleContext(MOZ_GTK_WINDOW, direction);
gtk_style_context_save(style);
gtk_style_context_add_class(style, GTK_STYLE_CLASS_BACKGROUND);
--- a/widget/gtk/gtkdrawing.h
+++ b/widget/gtk/gtkdrawing.h
@@ -79,16 +79,23 @@ typedef struct {
} ScrollbarGTKMetrics;
typedef struct {
bool initialized;
MozGtkSize minSizeWithBorder;
GtkBorder borderAndPadding;
} ToggleGTKMetrics;
+typedef struct {
+ bool initialized;
+ MozGtkSize minSizeWithBorderMargin;
+ gint iconXPosition;
+ gint iconYPosition;
+} ToolbarButtonGTKMetrics;
+
typedef enum {
MOZ_GTK_STEPPER_DOWN = 1 << 0,
MOZ_GTK_STEPPER_BOTTOM = 1 << 1,
MOZ_GTK_STEPPER_VERTICAL = 1 << 2
} GtkScrollbarButtonFlags;
typedef enum {
MOZ_GTK_TRACK_OPAQUE = 1 << 0
@@ -547,9 +554,15 @@ gint moz_gtk_get_menu_separator_height(g
gint moz_gtk_splitter_get_metrics(gint orientation, gint* size);
/**
* Get the YTHICKNESS of a tab (notebook extension).
*/
gint
moz_gtk_get_tab_thickness(WidgetNodeType aNodeType);
+
+/**
+ * Get ToolbarButtonGTKMetrics for recent theme.
+ */
+const ToolbarButtonGTKMetrics* GetToolbarButtonMetrics();
+
#endif