fontsel: defer expensive selection updates
Based on the openSUSE gtk2-bnc130159-bgo319483-async-selection-in-gtk-font-selection.diff. Coalesce font family, style and size selection updates with short timeouts to keep GtkFontSelection responsive while preserving immediate updates for internal programmatic selection changes.
This commit is contained in:
parent
0c87680876
commit
3501d8c4f5
1 changed files with 150 additions and 16 deletions
166
gtk/gtkfontsel.c
166
gtk/gtkfontsel.c
|
|
@ -585,6 +585,79 @@ gtk_font_selection_new (void)
|
|||
return GTK_WIDGET (fontsel);
|
||||
}
|
||||
|
||||
static GQuark
|
||||
font_selection_font_timeout_quark (void)
|
||||
{
|
||||
return g_quark_from_static_string ("gtk-font-selection-font-timeout");
|
||||
}
|
||||
|
||||
static GQuark
|
||||
font_selection_style_timeout_quark (void)
|
||||
{
|
||||
return g_quark_from_static_string ("gtk-font-selection-style-timeout");
|
||||
}
|
||||
|
||||
static GQuark
|
||||
font_selection_size_timeout_quark (void)
|
||||
{
|
||||
return g_quark_from_static_string ("gtk-font-selection-size-timeout");
|
||||
}
|
||||
|
||||
static GQuark
|
||||
font_selection_immediate_quark (void)
|
||||
{
|
||||
return g_quark_from_static_string ("gtk-font-selection-immediate");
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_font_selection_remove_timeout (GtkFontSelection *fontsel,
|
||||
GQuark quark)
|
||||
{
|
||||
guint timeout_id;
|
||||
|
||||
timeout_id = GPOINTER_TO_UINT (g_object_get_qdata (G_OBJECT (fontsel), quark));
|
||||
if (timeout_id)
|
||||
{
|
||||
g_source_remove (timeout_id);
|
||||
g_object_set_qdata (G_OBJECT (fontsel), quark, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_font_selection_get_immediate (GtkFontSelection *fontsel)
|
||||
{
|
||||
return GPOINTER_TO_UINT (g_object_get_qdata (G_OBJECT (fontsel),
|
||||
font_selection_immediate_quark ())) != 0;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_font_selection_set_immediate (GtkFontSelection *fontsel,
|
||||
gboolean immediate)
|
||||
{
|
||||
g_object_set_qdata (G_OBJECT (fontsel),
|
||||
font_selection_immediate_quark (),
|
||||
GUINT_TO_POINTER (immediate ? 1 : 0));
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_font_selection_schedule_selection (GtkFontSelection *fontsel,
|
||||
GQuark quark,
|
||||
GSourceFunc func)
|
||||
{
|
||||
guint timeout_id;
|
||||
|
||||
gtk_font_selection_remove_timeout (fontsel, quark);
|
||||
|
||||
if (gtk_font_selection_get_immediate (fontsel))
|
||||
{
|
||||
func (fontsel);
|
||||
return;
|
||||
}
|
||||
|
||||
timeout_id = g_timeout_add (200, func, fontsel);
|
||||
g_object_set_qdata (G_OBJECT (fontsel), quark, GUINT_TO_POINTER (timeout_id));
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_font_selection_finalize (GObject *object)
|
||||
{
|
||||
|
|
@ -594,6 +667,10 @@ gtk_font_selection_finalize (GObject *object)
|
|||
|
||||
fontsel = GTK_FONT_SELECTION (object);
|
||||
|
||||
gtk_font_selection_remove_timeout (fontsel, font_selection_font_timeout_quark ());
|
||||
gtk_font_selection_remove_timeout (fontsel, font_selection_style_timeout_quark ());
|
||||
gtk_font_selection_remove_timeout (fontsel, font_selection_size_timeout_quark ());
|
||||
|
||||
if (fontsel->font)
|
||||
gdk_font_unref (fontsel->font);
|
||||
|
||||
|
|
@ -632,6 +709,8 @@ gtk_font_selection_reload_fonts (GtkFontSelection *fontsel)
|
|||
PangoFontDescription *desc;
|
||||
desc = gtk_font_selection_get_font_description (fontsel);
|
||||
|
||||
gtk_font_selection_set_immediate (fontsel, TRUE);
|
||||
|
||||
gtk_font_selection_show_available_fonts (fontsel);
|
||||
gtk_font_selection_show_available_sizes (fontsel, TRUE);
|
||||
gtk_font_selection_show_available_styles (fontsel);
|
||||
|
|
@ -639,6 +718,8 @@ gtk_font_selection_reload_fonts (GtkFontSelection *fontsel)
|
|||
gtk_font_selection_select_font_desc (fontsel, desc, NULL, NULL);
|
||||
gtk_font_selection_scroll_to_selection (fontsel);
|
||||
|
||||
gtk_font_selection_set_immediate (fontsel, FALSE);
|
||||
|
||||
pango_font_description_free (desc);
|
||||
}
|
||||
}
|
||||
|
|
@ -715,11 +796,11 @@ gtk_font_selection_scroll_on_map (GtkWidget *widget,
|
|||
}
|
||||
|
||||
/* This is called when a family is selected in the list. */
|
||||
static void
|
||||
gtk_font_selection_select_font (GtkTreeSelection *selection,
|
||||
gpointer data)
|
||||
static gboolean
|
||||
gtk_font_selection_real_select_font (gpointer data)
|
||||
{
|
||||
GtkFontSelection *fontsel;
|
||||
GtkTreeSelection *selection;
|
||||
GtkTreeModel *model;
|
||||
GtkTreeIter iter;
|
||||
#ifdef INCLUDE_FONT_ENTRIES
|
||||
|
|
@ -727,6 +808,7 @@ gtk_font_selection_select_font (GtkTreeSelection *selection,
|
|||
#endif
|
||||
|
||||
fontsel = GTK_FONT_SELECTION (data);
|
||||
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (fontsel->family_list));
|
||||
|
||||
if (gtk_tree_selection_get_selected (selection, &model, &iter))
|
||||
{
|
||||
|
|
@ -734,20 +816,35 @@ gtk_font_selection_select_font (GtkTreeSelection *selection,
|
|||
|
||||
gtk_tree_model_get (model, &iter, FAMILY_COLUMN, &family, -1);
|
||||
if (fontsel->family != family)
|
||||
{
|
||||
gtk_font_selection_ref_family (fontsel, family);
|
||||
{
|
||||
gtk_font_selection_ref_family (fontsel, family);
|
||||
|
||||
#ifdef INCLUDE_FONT_ENTRIES
|
||||
family_name = pango_font_family_get_name (fontsel->family);
|
||||
gtk_entry_set_text (GTK_ENTRY (fontsel->font_entry), family_name);
|
||||
family_name = pango_font_family_get_name (fontsel->family);
|
||||
gtk_entry_set_text (GTK_ENTRY (fontsel->font_entry), family_name);
|
||||
#endif
|
||||
|
||||
gtk_font_selection_show_available_styles (fontsel);
|
||||
gtk_font_selection_select_best_style (fontsel, TRUE);
|
||||
}
|
||||
gtk_font_selection_show_available_styles (fontsel);
|
||||
gtk_font_selection_select_best_style (fontsel, TRUE);
|
||||
}
|
||||
|
||||
g_object_unref (family);
|
||||
}
|
||||
|
||||
g_object_set_qdata (G_OBJECT (fontsel), font_selection_font_timeout_quark (), NULL);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_font_selection_select_font (GtkTreeSelection *selection,
|
||||
gpointer data)
|
||||
{
|
||||
GtkFontSelection *fontsel = GTK_FONT_SELECTION (data);
|
||||
|
||||
gtk_font_selection_schedule_selection (fontsel,
|
||||
font_selection_font_timeout_quark (),
|
||||
gtk_font_selection_real_select_font);
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
@ -950,14 +1047,16 @@ gtk_font_selection_select_best_style (GtkFontSelection *fontsel,
|
|||
|
||||
|
||||
/* This is called when a style is selected in the list. */
|
||||
static void
|
||||
gtk_font_selection_select_style (GtkTreeSelection *selection,
|
||||
gpointer data)
|
||||
static gboolean
|
||||
gtk_font_selection_real_select_style (gpointer data)
|
||||
{
|
||||
GtkFontSelection *fontsel = GTK_FONT_SELECTION (data);
|
||||
GtkTreeSelection *selection;
|
||||
GtkTreeModel *model;
|
||||
GtkTreeIter iter;
|
||||
|
||||
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (fontsel->face_list));
|
||||
|
||||
if (gtk_tree_selection_get_selected (selection, &model, &iter))
|
||||
{
|
||||
PangoFontFace *face;
|
||||
|
|
@ -969,6 +1068,21 @@ gtk_font_selection_select_style (GtkTreeSelection *selection,
|
|||
|
||||
gtk_font_selection_show_available_sizes (fontsel, FALSE);
|
||||
gtk_font_selection_select_best_size (fontsel);
|
||||
|
||||
g_object_set_qdata (G_OBJECT (fontsel), font_selection_style_timeout_quark (), NULL);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_font_selection_select_style (GtkTreeSelection *selection,
|
||||
gpointer data)
|
||||
{
|
||||
GtkFontSelection *fontsel = GTK_FONT_SELECTION (data);
|
||||
|
||||
gtk_font_selection_schedule_selection (fontsel,
|
||||
font_selection_style_timeout_quark (),
|
||||
gtk_font_selection_real_select_style);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -1101,22 +1215,38 @@ gtk_font_selection_size_focus_out (GtkWidget *w,
|
|||
}
|
||||
|
||||
/* This is called when a size is selected in the list. */
|
||||
static void
|
||||
gtk_font_selection_select_size (GtkTreeSelection *selection,
|
||||
gpointer data)
|
||||
static gboolean
|
||||
gtk_font_selection_real_select_size (gpointer data)
|
||||
{
|
||||
GtkFontSelection *fontsel;
|
||||
GtkTreeSelection *selection;
|
||||
GtkTreeModel *model;
|
||||
GtkTreeIter iter;
|
||||
gint new_size;
|
||||
|
||||
fontsel = GTK_FONT_SELECTION (data);
|
||||
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (fontsel->size_list));
|
||||
|
||||
if (gtk_tree_selection_get_selected (selection, &model, &iter))
|
||||
{
|
||||
gtk_tree_model_get (model, &iter, SIZE_COLUMN, &new_size, -1);
|
||||
gtk_font_selection_set_size (fontsel, new_size * PANGO_SCALE);
|
||||
}
|
||||
|
||||
g_object_set_qdata (G_OBJECT (fontsel), font_selection_size_timeout_quark (), NULL);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_font_selection_select_size (GtkTreeSelection *selection,
|
||||
gpointer data)
|
||||
{
|
||||
GtkFontSelection *fontsel = GTK_FONT_SELECTION (data);
|
||||
|
||||
gtk_font_selection_schedule_selection (fontsel,
|
||||
font_selection_size_timeout_quark (),
|
||||
gtk_font_selection_real_select_size);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -1450,6 +1580,8 @@ gtk_font_selection_select_font_desc (GtkFontSelection *fontsel,
|
|||
if (!new_family)
|
||||
return FALSE;
|
||||
|
||||
gtk_font_selection_set_immediate (fontsel, TRUE);
|
||||
|
||||
if (pfamily)
|
||||
*pfamily = new_family;
|
||||
else
|
||||
|
|
@ -1500,6 +1632,8 @@ gtk_font_selection_select_font_desc (GtkFontSelection *fontsel,
|
|||
|
||||
gtk_font_selection_set_size (fontsel, pango_font_description_get_size (new_desc));
|
||||
|
||||
gtk_font_selection_set_immediate (fontsel, FALSE);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue