From 5c50e48156c6edbc2923bb3702f60349d8184057 Mon Sep 17 00:00:00 2001 From: Emmanuele Bassi Date: Tue, 15 Jan 2019 22:16:05 +0000 Subject: [PATCH 1/2] Add fallback glyphs for GtkSwitch states Even though the IEC power glyphs are part of Unicode 9.0 (released in 2016) not all fonts have them. To avoid showing the hexbox of doom when the system font does not have the glyphs we'd like to use, add a fallback pair, using the old glyphs we suggested when the labels were translatable. --- gtk/gtkswitch.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 53 insertions(+), 2 deletions(-) diff --git a/gtk/gtkswitch.c b/gtk/gtkswitch.c index abc37ab863..cb361c1292 100644 --- a/gtk/gtkswitch.c +++ b/gtk/gtkswitch.c @@ -280,6 +280,54 @@ gtk_switch_activate (GtkSwitch *sw) gtk_switch_begin_toggle_animation (sw); } +static void +gtk_switch_update_state_labels (GtkSwitch *sw) +{ + /* Glyphs for the ON state, in descending order of preference */ + const char *on_glyphs[] = { + "⏽", /* U+23FD POWER ON SYMBOL */ + "❙", /* U+2759 MEDIUM VERTICAL BAR */ + }; + + /* Glyphs for the OFF state, in descending order of preference */ + const char *off_glyphs[] = { + "⭘", /* U+2B58 HEAVY CIRCLE */ + "○", /* U+25CB WHITE CIRCLE */ + }; + + GtkSwitchPrivate *priv = gtk_switch_get_instance_private (sw); + GtkWidget *widget = GTK_WIDGET (sw); + int i; + + for (i = 0; i < G_N_ELEMENTS (on_glyphs); i++) + { + PangoLayout *layout = gtk_widget_create_pango_layout (widget, on_glyphs[i]); + + if (pango_layout_get_unknown_glyphs_count (layout) == 0) + { + gtk_label_set_text (GTK_LABEL (priv->on_label), on_glyphs[i]); + g_object_unref (layout); + break; + } + + g_object_unref (layout); + } + + for (i = 0; i < G_N_ELEMENTS (off_glyphs); i++) + { + PangoLayout *layout = gtk_widget_create_pango_layout (widget, off_glyphs[i]); + + if (pango_layout_get_unknown_glyphs_count (layout) == 0) + { + gtk_label_set_text (GTK_LABEL (priv->off_label), off_glyphs[i]); + g_object_unref (layout); + break; + } + + g_object_unref (layout); + } +} + static void gtk_switch_measure (GtkWidget *widget, GtkOrientation orientation, @@ -639,14 +687,17 @@ gtk_switch_init (GtkSwitch *self) gtk_widget_add_controller (GTK_WIDGET (self), GTK_EVENT_CONTROLLER (gesture)); priv->pan_gesture = gesture; - priv->on_label = gtk_label_new ("⏽"); + + priv->on_label = gtk_label_new (""); gtk_widget_set_parent (priv->on_label, GTK_WIDGET (self)); - priv->off_label = gtk_label_new ("⭘"); + priv->off_label = gtk_label_new (""); gtk_widget_set_parent (priv->off_label, GTK_WIDGET (self)); priv->slider = gtk_gizmo_new ("slider", NULL, NULL, NULL); gtk_widget_set_parent (priv->slider, GTK_WIDGET (self)); + + gtk_switch_update_state_labels (self); } /** From 58d9c3d5bdab3600809f3bc8dd51e328e9755d08 Mon Sep 17 00:00:00 2001 From: Emmanuele Bassi Date: Fri, 18 Jan 2019 14:43:42 +0000 Subject: [PATCH 2/2] switch: Update state labels when needed If the text style changes, or the display settings do, we need to update the state labels to ensure that the glyphs are available in the font we're using. --- gtk/gtkswitch.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/gtk/gtkswitch.c b/gtk/gtkswitch.c index cb361c1292..8ade76acdb 100644 --- a/gtk/gtkswitch.c +++ b/gtk/gtkswitch.c @@ -65,6 +65,7 @@ #include "gtkprivate.h" #include "gtkprogresstrackerprivate.h" #include "gtksettingsprivate.h" +#include "gtkstylecontextprivate.h" #include "gtkwidgetprivate.h" #include "a11y/gtkswitchaccessible.h" @@ -399,6 +400,31 @@ gtk_switch_size_allocate (GtkWidget *widget, gtk_widget_size_allocate (priv->off_label, &child_alloc, -1); } +static void +gtk_switch_style_updated (GtkWidget *widget) +{ + GtkSwitch *self = GTK_SWITCH (widget); + GtkCssStyleChange *change; + GtkStyleContext *context; + + GTK_WIDGET_CLASS (gtk_switch_parent_class)->style_updated (widget); + + context = gtk_widget_get_style_context (widget); + change = gtk_style_context_get_change (context); + + if (change == NULL || gtk_css_style_change_affects (change, GTK_CSS_AFFECTS_TEXT)) + gtk_switch_update_state_labels (self); +} + +static void +gtk_switch_display_changed (GtkWidget *widget, + GdkDisplay *previous_display) +{ + GtkSwitch *self = GTK_SWITCH (widget); + + gtk_switch_update_state_labels (self); +} + static void gtk_switch_set_action_name (GtkActionable *actionable, const gchar *action_name) @@ -591,6 +617,8 @@ gtk_switch_class_init (GtkSwitchClass *klass) widget_class->measure = gtk_switch_measure; widget_class->size_allocate = gtk_switch_size_allocate; + widget_class->style_updated = gtk_switch_style_updated; + widget_class->display_changed = gtk_switch_display_changed; klass->activate = gtk_switch_activate; klass->state_set = state_set;