diff options
| author | Owen W. Taylor <[email protected]> | 2014-09-27 16:47:27 +0300 | 
|---|---|---|
| committer | Victor Kareh <[email protected]> | 2018-08-28 09:38:37 -0400 | 
| commit | a47f178df47ae26bf080b5c4f34762102c58085e (patch) | |
| tree | 10de970315f7f835c2bac590c4e2a18150b24409 /src | |
| parent | 728f0022b1b5b75a289abf8f3acec43378c06d92 (diff) | |
| download | marco-a47f178df47ae26bf080b5c4f34762102c58085e.tar.bz2 marco-a47f178df47ae26bf080b5c4f34762102c58085e.tar.xz | |
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
NOTE: Patch copied from mutter and adapted for metacity.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ui/frames.c | 1 | ||||
| -rw-r--r-- | src/ui/theme-parser.c | 14 | ||||
| -rw-r--r-- | src/ui/theme.c | 43 | ||||
| -rw-r--r-- | src/ui/theme.h | 1 | 
4 files changed, 56 insertions, 3 deletions
| diff --git a/src/ui/frames.c b/src/ui/frames.c index 90e2b2d8..a8cb96fa 100644 --- a/src/ui/frames.c +++ b/src/ui/frames.c @@ -482,6 +482,7 @@ meta_frames_ensure_layout (MetaFrames  *frames,        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_single_paragraph_mode (frame->layout, TRUE); diff --git a/src/ui/theme-parser.c b/src/ui/theme-parser.c index 56ea32b5..38c1e664 100644 --- a/src/ui/theme-parser.c +++ b/src/ui/theme-parser.c @@ -2615,12 +2615,14 @@ parse_draw_op_element (GMarkupParseContext  *context,        const char *color;        const char *x;        const char *y; +      const char *ellipsize_width;        MetaColorSpec *color_spec;        if (!locate_attributes (context, element_name, attribute_names, attribute_values,                                error,                                "!color", &color,                                "!x", &x, "!y", &y, +                              "ellipsize_width", &ellipsize_width,                                NULL))          return; @@ -2630,8 +2632,18 @@ parse_draw_op_element (GMarkupParseContext  *context,        if (!check_expression (y, FALSE, info->theme, context, error))          return; + +      if (!check_expression (ellipsize_width, FALSE, info->theme, context, error)) +        return;  #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         * stuff fails         */ @@ -2648,6 +2660,8 @@ parse_draw_op_element (GMarkupParseContext  *context,        op->data.title.x = meta_draw_spec_new (info->theme, x, 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); diff --git a/src/ui/theme.c b/src/ui/theme.c index 7382883d..4385b7c6 100644 --- a/src/ui/theme.c +++ b/src/ui/theme.c @@ -3010,6 +3010,8 @@ meta_draw_op_free (MetaDrawOp *op)        meta_draw_spec_free (op->data.title.x);        meta_draw_spec_free (op->data.title.y); +      if (op->data.title.ellipsize_width) +        meta_draw_spec_free (op->data.title.ellipsize_width);        break;      case META_DRAW_OP_LIST: @@ -3875,6 +3877,7 @@ meta_draw_op_draw_with_env (const MetaDrawOp    *op,        if (info->title_layout)          {            int rx, ry; +          PangoRectangle ink_rect, logical_rect;            meta_color_spec_render (op->data.title.color_spec, style_gtk, &color);            gdk_cairo_set_source_rgba (cr, &color); @@ -3882,7 +3885,39 @@ meta_draw_op_draw_with_env (const MetaDrawOp    *op,            rx = parse_x_position_unchecked (op->data.title.x, env);            ry = parse_y_position_unchecked (op->data.title.y, env); -          if (rx - env->rect.x + env->title_width >= env->rect.width) +          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 +               * cairo_move_to() 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); +            } +          else if (rx - env->rect.x + env->title_width >= env->rect.width)            {              const double alpha_margin = 30.0;              int text_space = env->rect.x + env->rect.width - @@ -3907,12 +3942,14 @@ meta_draw_op_draw_with_env (const MetaDrawOp    *op,                                                            color.blue, 0);              cairo_set_source(cr, linpat);              cairo_pattern_destroy(linpat); -          } else { -            gdk_cairo_set_source_rgba (cr, &color);            }            cairo_move_to (cr, rx, ry);            pango_cairo_show_layout (cr, 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);          }        break; diff --git a/src/ui/theme.h b/src/ui/theme.h index a52d22e8..6d0b4d16 100644 --- a/src/ui/theme.h +++ b/src/ui/theme.h @@ -539,6 +539,7 @@ struct _MetaDrawOp        MetaColorSpec *color_spec;        MetaDrawSpec *x;        MetaDrawSpec *y; +      MetaDrawSpec *ellipsize_width;      } title;      struct { | 
