mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2025-01-12 13:30:19 +00:00
GtkLabel: better treatment for ellipsized links
When links are entirely hidden in an ellipsis, don't let them be activated by clicking and skip them when moving the focus around. This commit depends on enhancements in pango 1.36.7 which make it possible to find the ellipsed runs in a PangoLayout. With older pango, things will work the same way as before. https://bugzilla.gnome.org/show_bug.cgi?id=668258
This commit is contained in:
parent
0ff5cf7daf
commit
1cddd14ab4
111
gtk/gtklabel.c
111
gtk/gtklabel.c
@ -4561,6 +4561,53 @@ get_layout_index (GtkLabel *label,
|
||||
return inside;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
range_is_in_ellipsis (GtkLabel *label,
|
||||
gint start,
|
||||
gint end)
|
||||
{
|
||||
GtkLabelPrivate *priv = label->priv;
|
||||
PangoLayoutIter *iter;
|
||||
gboolean in_ellipsis;
|
||||
|
||||
if (!priv->ellipsize)
|
||||
return FALSE;
|
||||
|
||||
gtk_label_ensure_layout (label);
|
||||
|
||||
if (!pango_layout_is_ellipsized (priv->layout))
|
||||
return FALSE;
|
||||
|
||||
iter = pango_layout_get_iter (priv->layout);
|
||||
|
||||
in_ellipsis = FALSE;
|
||||
|
||||
do {
|
||||
PangoLayoutRun *run;
|
||||
|
||||
run = pango_layout_iter_get_run_readonly (iter);
|
||||
if (run)
|
||||
{
|
||||
PangoItem *item;
|
||||
|
||||
item = ((PangoGlyphItem*)run)->item;
|
||||
|
||||
if (item->offset <= start && end <= item->offset + item->length)
|
||||
{
|
||||
if (item->analysis.flags & PANGO_ANALYSIS_FLAG_IS_ELLIPSIS)
|
||||
in_ellipsis = TRUE;
|
||||
break;
|
||||
}
|
||||
else if (item->offset + item->length >= end)
|
||||
break;
|
||||
}
|
||||
} while (pango_layout_iter_next_run (iter));
|
||||
|
||||
pango_layout_iter_free (iter);
|
||||
|
||||
return in_ellipsis;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_label_select_word (GtkLabel *label)
|
||||
{
|
||||
@ -4588,6 +4635,7 @@ gtk_label_grab_focus (GtkWidget *widget)
|
||||
GtkLabelPrivate *priv = label->priv;
|
||||
gboolean select_on_focus;
|
||||
GtkLabelLink *link;
|
||||
GList *l;
|
||||
|
||||
if (priv->select_info == NULL)
|
||||
return;
|
||||
@ -4608,10 +4656,17 @@ gtk_label_grab_focus (GtkWidget *widget)
|
||||
{
|
||||
if (priv->select_info->links && !priv->in_click)
|
||||
{
|
||||
link = priv->select_info->links->data;
|
||||
priv->select_info->selection_anchor = link->start;
|
||||
priv->select_info->selection_end = link->start;
|
||||
_gtk_label_accessible_focus_link_changed (label);
|
||||
for (l = priv->select_info->links; l; l = l->next)
|
||||
{
|
||||
link = l->data;
|
||||
if (!range_is_in_ellipsis (label, link->start, link->end))
|
||||
{
|
||||
priv->select_info->selection_anchor = link->start;
|
||||
priv->select_info->selection_end = link->start;
|
||||
_gtk_label_accessible_focus_link_changed (label);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -4634,11 +4689,16 @@ gtk_label_focus (GtkWidget *widget,
|
||||
focus_link = gtk_label_get_focus_link (label);
|
||||
if (focus_link && direction == GTK_DIR_TAB_BACKWARD)
|
||||
{
|
||||
l = g_list_last (info->links);
|
||||
focus_link = l->data;
|
||||
info->selection_anchor = focus_link->start;
|
||||
info->selection_end = focus_link->start;
|
||||
_gtk_label_accessible_focus_link_changed (label);
|
||||
for (l = g_list_last (info->links); l; l = l->prev)
|
||||
{
|
||||
focus_link = l->data;
|
||||
if (!range_is_in_ellipsis (label, focus_link->start, focus_link->end))
|
||||
{
|
||||
info->selection_anchor = focus_link->start;
|
||||
info->selection_end = focus_link->start;
|
||||
_gtk_label_accessible_focus_link_changed (label);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -4664,9 +4724,12 @@ gtk_label_focus (GtkWidget *widget,
|
||||
|
||||
if (link->start > index)
|
||||
{
|
||||
gtk_label_select_region_index (label, link->start, link->start);
|
||||
_gtk_label_accessible_focus_link_changed (label);
|
||||
return TRUE;
|
||||
if (!range_is_in_ellipsis (label, link->start, link->end))
|
||||
{
|
||||
gtk_label_select_region_index (label, link->start, link->start);
|
||||
_gtk_label_accessible_focus_link_changed (label);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (direction == GTK_DIR_TAB_BACKWARD)
|
||||
@ -4676,9 +4739,12 @@ gtk_label_focus (GtkWidget *widget,
|
||||
|
||||
if (link->end < index)
|
||||
{
|
||||
gtk_label_select_region_index (label, link->start, link->start);
|
||||
_gtk_label_accessible_focus_link_changed (label);
|
||||
return TRUE;
|
||||
if (!range_is_in_ellipsis (label, link->start, link->end))
|
||||
{
|
||||
gtk_label_select_region_index (label, link->start, link->start);
|
||||
_gtk_label_accessible_focus_link_changed (label);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -4697,6 +4763,12 @@ gtk_label_focus (GtkWidget *widget,
|
||||
}
|
||||
else
|
||||
l = info->links;
|
||||
for (; l; l = l->next)
|
||||
{
|
||||
GtkLabelLink *link = l->data;
|
||||
if (!range_is_in_ellipsis (label, link->start, link->end))
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case GTK_DIR_TAB_BACKWARD:
|
||||
@ -4707,6 +4779,12 @@ gtk_label_focus (GtkWidget *widget,
|
||||
}
|
||||
else
|
||||
l = g_list_last (info->links);
|
||||
for (; l; l = l->prev)
|
||||
{
|
||||
GtkLabelLink *link = l->data;
|
||||
if (!range_is_in_ellipsis (label, link->start, link->end))
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -5114,7 +5192,8 @@ gtk_label_motion (GtkWidget *widget,
|
||||
link = l->data;
|
||||
if (index >= link->start && index <= link->end)
|
||||
{
|
||||
found = TRUE;
|
||||
if (!range_is_in_ellipsis (label, link->start, link->end))
|
||||
found = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user