mirror of
https://github.com/brl/mutter.git
synced 2024-11-21 15:40:41 -05:00
Allow a theme to specify ellipsize width for a title
It's nice to indicate when a title is truncated with an ellipsis. Because themes may draw a title multiple times to draw a shadow, or may include the window icon within the title area, we can't determine the proper ellipsization width automatically, so add an optional attribute to the <title/> element "ellipsize_width" which, if set, is the width to ellipsize at. This is only enabled if a theme version of 3.1 is required. When it's not set, we keep the old behavior of just letting the title be clipped with a hard edge. https://bugzilla.gnome.org/show_bug.cgi?id=591842
This commit is contained in:
parent
e8e78ebfdd
commit
1d7476a725
@ -32,6 +32,10 @@ Additional predefined variables are added for positioning expressions:
|
|||||||
frame_y_center: the Y center of the entire frame, with respect to the
|
frame_y_center: the Y center of the entire frame, with respect to the
|
||||||
piece currently being drawn.
|
piece currently being drawn.
|
||||||
|
|
||||||
|
The <title/> element now supports an "ellipsize_width" attribute. When
|
||||||
|
specified, this gives a width at which to ellipsize the title. If not
|
||||||
|
specified, the title will simply be clipped to the title area.
|
||||||
|
|
||||||
New Features in Theme Format Version 3
|
New Features in Theme Format Version 3
|
||||||
======================================
|
======================================
|
||||||
|
|
||||||
|
@ -501,6 +501,7 @@ meta_frames_ensure_layout (MetaFrames *frames,
|
|||||||
|
|
||||||
frame->layout = gtk_widget_create_pango_layout (widget, frame->title);
|
frame->layout = gtk_widget_create_pango_layout (widget, frame->title);
|
||||||
|
|
||||||
|
pango_layout_set_ellipsize (frame->layout, PANGO_ELLIPSIZE_END);
|
||||||
pango_layout_set_auto_dir (frame->layout, FALSE);
|
pango_layout_set_auto_dir (frame->layout, FALSE);
|
||||||
|
|
||||||
font_desc = meta_gtk_widget_get_font_desc (widget, scale,
|
font_desc = meta_gtk_widget_get_font_desc (widget, scale,
|
||||||
|
@ -2584,12 +2584,14 @@ parse_draw_op_element (GMarkupParseContext *context,
|
|||||||
const char *color;
|
const char *color;
|
||||||
const char *x;
|
const char *x;
|
||||||
const char *y;
|
const char *y;
|
||||||
|
const char *ellipsize_width;
|
||||||
MetaColorSpec *color_spec;
|
MetaColorSpec *color_spec;
|
||||||
|
|
||||||
if (!locate_attributes (context, element_name, attribute_names, attribute_values,
|
if (!locate_attributes (context, element_name, attribute_names, attribute_values,
|
||||||
error,
|
error,
|
||||||
"!color", &color,
|
"!color", &color,
|
||||||
"!x", &x, "!y", &y,
|
"!x", &x, "!y", &y,
|
||||||
|
"ellipsize_width", &ellipsize_width,
|
||||||
NULL))
|
NULL))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -2599,8 +2601,18 @@ parse_draw_op_element (GMarkupParseContext *context,
|
|||||||
|
|
||||||
if (!check_expression (y, FALSE, info->theme, context, error))
|
if (!check_expression (y, FALSE, info->theme, context, error))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (!check_expression (ellipsize_width, FALSE, info->theme, context, error))
|
||||||
|
return;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (ellipsize_width && peek_required_version (info) < 3001)
|
||||||
|
{
|
||||||
|
set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
|
||||||
|
ATTRIBUTE_NOT_FOUND, "ellipsize_width", element_name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* Check last so we don't have to free it when other
|
/* Check last so we don't have to free it when other
|
||||||
* stuff fails
|
* stuff fails
|
||||||
*/
|
*/
|
||||||
@ -2617,6 +2629,8 @@ parse_draw_op_element (GMarkupParseContext *context,
|
|||||||
|
|
||||||
op->data.title.x = meta_draw_spec_new (info->theme, x, NULL);
|
op->data.title.x = meta_draw_spec_new (info->theme, x, NULL);
|
||||||
op->data.title.y = meta_draw_spec_new (info->theme, y, NULL);
|
op->data.title.y = meta_draw_spec_new (info->theme, y, NULL);
|
||||||
|
if (ellipsize_width)
|
||||||
|
op->data.title.ellipsize_width = meta_draw_spec_new (info->theme, ellipsize_width, NULL);
|
||||||
|
|
||||||
g_assert (info->op_list);
|
g_assert (info->op_list);
|
||||||
|
|
||||||
|
@ -2884,6 +2884,8 @@ meta_draw_op_free (MetaDrawOp *op)
|
|||||||
|
|
||||||
meta_draw_spec_free (op->data.title.x);
|
meta_draw_spec_free (op->data.title.x);
|
||||||
meta_draw_spec_free (op->data.title.y);
|
meta_draw_spec_free (op->data.title.y);
|
||||||
|
if (op->data.title.ellipsize_width)
|
||||||
|
meta_draw_spec_free (op->data.title.ellipsize_width);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case META_DRAW_OP_LIST:
|
case META_DRAW_OP_LIST:
|
||||||
@ -3756,6 +3758,7 @@ meta_draw_op_draw_with_env (const MetaDrawOp *op,
|
|||||||
if (info->title_layout)
|
if (info->title_layout)
|
||||||
{
|
{
|
||||||
int rx, ry;
|
int rx, ry;
|
||||||
|
PangoRectangle ink_rect, logical_rect;
|
||||||
|
|
||||||
gc = get_gc_for_primitive (widget, drawable,
|
gc = get_gc_for_primitive (widget, drawable,
|
||||||
op->data.title.color_spec,
|
op->data.title.color_spec,
|
||||||
@ -3764,10 +3767,47 @@ meta_draw_op_draw_with_env (const MetaDrawOp *op,
|
|||||||
rx = parse_x_position_unchecked (op->data.title.x, env);
|
rx = parse_x_position_unchecked (op->data.title.x, env);
|
||||||
ry = parse_y_position_unchecked (op->data.title.y, env);
|
ry = parse_y_position_unchecked (op->data.title.y, env);
|
||||||
|
|
||||||
|
if (op->data.title.ellipsize_width)
|
||||||
|
{
|
||||||
|
int ellipsize_width;
|
||||||
|
int right_bearing;
|
||||||
|
|
||||||
|
ellipsize_width = parse_x_position_unchecked (op->data.title.ellipsize_width, env);
|
||||||
|
/* HACK: parse_x_position_unchecked adds in env->rect.x, subtract out again */
|
||||||
|
ellipsize_width -= env->rect.x;
|
||||||
|
|
||||||
|
pango_layout_set_width (info->title_layout, -1);
|
||||||
|
pango_layout_get_pixel_extents (info->title_layout,
|
||||||
|
&ink_rect, &logical_rect);
|
||||||
|
|
||||||
|
/* Pango's idea of ellipsization is with respect to the logical rect.
|
||||||
|
* correct for this, by reducing the ellipsization width by the overflow
|
||||||
|
* of the un-ellipsized text on the right... it's always the visual
|
||||||
|
* right we want regardless of bidi, since since the X we pass in to
|
||||||
|
* gdk_draw_layout() is always the left edge of the line.
|
||||||
|
*/
|
||||||
|
right_bearing = (ink_rect.x + ink_rect.width) - (logical_rect.x + logical_rect.width);
|
||||||
|
right_bearing = MAX (right_bearing, 0);
|
||||||
|
|
||||||
|
ellipsize_width -= right_bearing;
|
||||||
|
ellipsize_width = MAX (ellipsize_width, 0);
|
||||||
|
|
||||||
|
/* Only ellipsizing when necessary is a performance optimization -
|
||||||
|
* pango_layout_set_width() will force a relayout if it isn't the
|
||||||
|
* same as the current width of -1.
|
||||||
|
*/
|
||||||
|
if (ellipsize_width < logical_rect.width)
|
||||||
|
pango_layout_set_width (info->title_layout, PANGO_SCALE * ellipsize_width);
|
||||||
|
}
|
||||||
|
|
||||||
gdk_draw_layout (drawable, gc,
|
gdk_draw_layout (drawable, gc,
|
||||||
rx, ry,
|
rx, ry,
|
||||||
info->title_layout);
|
info->title_layout);
|
||||||
|
|
||||||
|
/* Remove any ellipsization we might have set; will short-circuit
|
||||||
|
* if the width is already -1 */
|
||||||
|
pango_layout_set_width (info->title_layout, -1);
|
||||||
|
|
||||||
g_object_unref (G_OBJECT (gc));
|
g_object_unref (G_OBJECT (gc));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -4326,7 +4366,7 @@ meta_frame_style_draw_with_style (MetaFrameStyle *style,
|
|||||||
GdkRectangle bottom_titlebar_edge;
|
GdkRectangle bottom_titlebar_edge;
|
||||||
GdkRectangle top_titlebar_edge;
|
GdkRectangle top_titlebar_edge;
|
||||||
GdkRectangle left_edge, right_edge, bottom_edge;
|
GdkRectangle left_edge, right_edge, bottom_edge;
|
||||||
PangoRectangle extents;
|
PangoRectangle logical_rect;
|
||||||
MetaDrawInfo draw_info;
|
MetaDrawInfo draw_info;
|
||||||
|
|
||||||
g_return_if_fail (style_gtk->colormap == gdk_drawable_get_colormap (drawable));
|
g_return_if_fail (style_gtk->colormap == gdk_drawable_get_colormap (drawable));
|
||||||
@ -4373,13 +4413,13 @@ meta_frame_style_draw_with_style (MetaFrameStyle *style,
|
|||||||
|
|
||||||
if (title_layout)
|
if (title_layout)
|
||||||
pango_layout_get_pixel_extents (title_layout,
|
pango_layout_get_pixel_extents (title_layout,
|
||||||
NULL, &extents);
|
NULL, &logical_rect);
|
||||||
|
|
||||||
draw_info.mini_icon = mini_icon;
|
draw_info.mini_icon = mini_icon;
|
||||||
draw_info.icon = icon;
|
draw_info.icon = icon;
|
||||||
draw_info.title_layout = title_layout;
|
draw_info.title_layout = title_layout;
|
||||||
draw_info.title_layout_width = title_layout ? extents.width : 0;
|
draw_info.title_layout_width = title_layout ? logical_rect.width : 0;
|
||||||
draw_info.title_layout_height = title_layout ? extents.height : 0;
|
draw_info.title_layout_height = title_layout ? logical_rect.height : 0;
|
||||||
draw_info.fgeom = fgeom;
|
draw_info.fgeom = fgeom;
|
||||||
|
|
||||||
/* The enum is in the order the pieces should be rendered. */
|
/* The enum is in the order the pieces should be rendered. */
|
||||||
|
@ -534,6 +534,7 @@ struct _MetaDrawOp
|
|||||||
MetaColorSpec *color_spec;
|
MetaColorSpec *color_spec;
|
||||||
MetaDrawSpec *x;
|
MetaDrawSpec *x;
|
||||||
MetaDrawSpec *y;
|
MetaDrawSpec *y;
|
||||||
|
MetaDrawSpec *ellipsize_width;
|
||||||
} title;
|
} title;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
|
Loading…
Reference in New Issue
Block a user