Compare commits

...

15 Commits

Author SHA1 Message Date
Matthias Clasen
d47392487f textview fixes 2021-08-06 16:41:16 -04:00
Matthias Clasen
1394f73ce2 label fixes 2021-08-06 16:41:04 -04:00
Matthias Clasen
4a5025eca1 css fixes 2021-08-06 16:40:54 -04:00
Matthias Clasen
be8cbb2adb textview: Use line-height from css
Pass the line height from the style on to the
text attributes.
2021-08-06 14:35:48 -04:00
Matthias Clasen
3c9edc1afa textview: Add line-spacing plumbing
This adds a line-spacing property to GtkTextAttributes
and GtkTextTag.
2021-08-06 14:35:43 -04:00
Matthias Clasen
630bbf8d9b label: Use line-height from css 2021-08-06 14:20:10 -04:00
Matthias Clasen
8eb82da896 css: Add line-height property
This adds the plumbing to parse the line-height
property from CSS. Widgets are not picking it
up yet.
2021-08-06 14:19:34 -04:00
Matthias Clasen
a457a81fd9 Merge branch 'matthiasc/for-master' into 'master'
text: Move setup code out of a loop

See merge request GNOME/gtk!3826
2021-08-05 18:45:39 +00:00
Matthias Clasen
e5e7f5dd88 ci: Disable treeview-headers-hidden reftest
Somebody needs to figure out why it fails in ci so
frequently.
2021-08-05 12:41:04 -04:00
Matthias Clasen
916886312a Merge branch 'wip/exalm/shadow-extents' into 'master'
Shrink shadow extents

See merge request GNOME/gtk!3825
2021-08-05 16:39:52 +00:00
Matthias Clasen
8ff94ea1f2 text: Move setup code out of a loop
Just a cleanup, no functional change.
2021-08-05 12:31:18 -04:00
Matthias Clasen
053bd0cd31 Merge branch 'fix-tab-not-captured-in-popover' into 'master'
popovermenu: Cycle around focus also with (Shift+)Tab

Closes #3915

See merge request GNOME/gtk!3732
2021-08-05 02:07:43 +00:00
vanadiae
a3ce574193 popover: Cycle around focus with (Shift+)Tab
Same thing as the previous popovermenu commit, except for the base popover
because the popovermenu needs special behaviour with e.g. sides arrow so
we need to have the "cycle around" for regular popovers here too.
2021-08-04 12:11:44 +02:00
vanadiae
ef92adc87d popovermenu: Cycle around focus also with (Shift+)Tab
Currently when moving the focus with (Shift+)Tab, it also traverses the window's
widgets, although it would be expected that the focus stays within the popover,
as it's (almost) like it's a separate window. This would be consistent with
the behaviour of the Up/down arrows, which do cycle around the focus once it
reaches the end.

So this commit makes the popovermenu cycle around focus in any direction, apart
from left/right because they are used to open and close submenus and it wouldn't
make sense anyway to cycle horizontally as there's usually only one widget per
line.
2021-08-04 12:11:44 +02:00
Alexander Mikhaylenko
46a9538b6a Shrink shadow extents
Long time ago, Cairo shadows in both GTK3 and 4 were drawn at a size about
twice their radius. Eventually this was fixed but the shadow extents are
still calculated for the previous size and appear unreasonably large: for
example, 141px for a 50px radius shadow. This can get very noticeable in
places such as invisible window frame which gets included into screenshots.

https://gitlab.gnome.org/GNOME/gtk/-/merge_requests/3419 just divides the
radius by 2 when drawing a shadow with Cairo, do the same when calculating
extents.

See https://gitlab.gnome.org/GNOME/gtk/-/issues/3841
2021-08-04 14:47:17 +05:00
22 changed files with 242 additions and 45 deletions

View File

@@ -2146,7 +2146,7 @@ gsk_outset_shadow_get_extents (GskOutsetShadowNode *self,
{
float clip_radius;
clip_radius = gsk_cairo_blur_compute_pixels (self->blur_radius);
clip_radius = gsk_cairo_blur_compute_pixels (self->blur_radius / 2.0);
*top = MAX (0, clip_radius + self->spread - self->dy);
*right = MAX (0, ceil (clip_radius + self->spread + self->dx));
*bottom = MAX (0, ceil (clip_radius + self->spread + self->dy));
@@ -3852,7 +3852,7 @@ gsk_shadow_node_diff (GskRenderNode *node1,
return;
}
clip_radius = gsk_cairo_blur_compute_pixels (shadow1->radius);
clip_radius = gsk_cairo_blur_compute_pixels (shadow1->radius / 2.0);
top = MAX (top, ceil (clip_radius - shadow1->dy));
right = MAX (right, ceil (clip_radius + shadow1->dx));
bottom = MAX (bottom, ceil (clip_radius + shadow1->dy));
@@ -3886,7 +3886,7 @@ gsk_shadow_node_get_bounds (GskShadowNode *self,
for (i = 0; i < self->n_shadows; i++)
{
float clip_radius = gsk_cairo_blur_compute_pixels (self->shadows[i].radius);
float clip_radius = gsk_cairo_blur_compute_pixels (self->shadows[i].radius / 2.0);
top = MAX (top, clip_radius - self->shadows[i].dy);
right = MAX (right, clip_radius + self->shadows[i].dx);
bottom = MAX (bottom, clip_radius + self->shadows[i].dy);
@@ -4866,7 +4866,7 @@ gsk_blur_node_diff (GskRenderNode *node1,
cairo_region_t *sub;
int i, n, clip_radius;
clip_radius = ceil (gsk_cairo_blur_compute_pixels (self1->radius));
clip_radius = ceil (gsk_cairo_blur_compute_pixels (self1->radius / 2.0));
sub = cairo_region_create ();
gsk_render_node_diff (self1->child, self2->child, sub);
@@ -4913,7 +4913,7 @@ gsk_blur_node_new (GskRenderNode *child,
self->child = gsk_render_node_ref (child);
self->radius = radius;
clip_radius = gsk_cairo_blur_compute_pixels (radius);
clip_radius = gsk_cairo_blur_compute_pixels (radius / 2.0);
graphene_rect_init_from_rect (&node->bounds, &child->bounds);
graphene_rect_inset (&self->render_node.bounds,

View File

@@ -204,6 +204,10 @@ gtk_css_animated_style_set_animated_value (GtkCssAnimatedStyle *animated,
unshare_font (animated);
gtk_css_take_value (&style->font->letter_spacing, value);
break;
case GTK_CSS_PROPERTY_LINE_HEIGHT:
unshare_font (animated);
gtk_css_take_value (&style->font->line_height, value);
break;
case GTK_CSS_PROPERTY_TEXT_DECORATION_LINE:
unshare_font_variant (animated);
gtk_css_take_value (&style->font_variant->text_decoration_line, value);

View File

@@ -542,8 +542,8 @@ gtk_css_shadow_value_get_extents (const GtkCssValue *value,
spread = _gtk_css_number_value_get (shadow->spread, 0);
radius = _gtk_css_number_value_get (shadow->radius, 0);
if (value->is_filter)
radius = radius * 2;
if (!value->is_filter)
radius = radius / 2.0;
clip_radius = gsk_cairo_blur_compute_pixels (radius);
hoffset = _gtk_css_number_value_get (shadow->hoffset, 0);
voffset = _gtk_css_number_value_get (shadow->voffset, 0);

View File

@@ -107,11 +107,12 @@ static const int font_props[] = {
GTK_CSS_PROPERTY_FONT_WEIGHT,
GTK_CSS_PROPERTY_FONT_STRETCH,
GTK_CSS_PROPERTY_LETTER_SPACING,
GTK_CSS_PROPERTY_TEXT_SHADOW,
GTK_CSS_PROPERTY_TEXT_SHADOW,
GTK_CSS_PROPERTY_CARET_COLOR,
GTK_CSS_PROPERTY_SECONDARY_CARET_COLOR,
GTK_CSS_PROPERTY_FONT_FEATURE_SETTINGS,
GTK_CSS_PROPERTY_FONT_VARIATION_SETTINGS,
GTK_CSS_PROPERTY_LINE_HEIGHT,
};
static const int font_variant_props[] = {
GTK_CSS_PROPERTY_TEXT_DECORATION_LINE,
@@ -417,6 +418,9 @@ gtk_css_static_style_set_value (GtkCssStaticStyle *sstyle,
case GTK_CSS_PROPERTY_LETTER_SPACING:
gtk_css_take_value (&style->font->letter_spacing, value);
break;
case GTK_CSS_PROPERTY_LINE_HEIGHT:
gtk_css_take_value (&style->font->line_height, value);
break;
case GTK_CSS_PROPERTY_TEXT_DECORATION_LINE:
gtk_css_take_value (&style->font_variant->text_decoration_line, value);
break;

View File

@@ -226,3 +226,13 @@ _gtk_css_ident_value_get (const GtkCssValue *value)
return value->string;
}
GtkCssValue *
gtk_css_line_height_value_get_default (void)
{
static GtkCssValue *normal_line_height;
if (normal_line_height == NULL)
normal_line_height = _gtk_css_ident_value_new_take ("normal");
return normal_line_height;
}

View File

@@ -40,6 +40,7 @@ GtkCssValue * _gtk_css_string_value_parse (GtkCssParser *par
const char * _gtk_css_string_value_get (const GtkCssValue *string);
GtkCssValue * gtk_css_line_height_value_get_default (void);
G_END_DECLS

View File

@@ -117,6 +117,8 @@ gtk_css_style_get_value (GtkCssStyle *style,
return style->font->font_stretch;
case GTK_CSS_PROPERTY_LETTER_SPACING:
return style->font->letter_spacing;
case GTK_CSS_PROPERTY_LINE_HEIGHT:
return style->font->line_height;
case GTK_CSS_PROPERTY_TEXT_DECORATION_LINE:
return style->font_variant->text_decoration_line;
case GTK_CSS_PROPERTY_TEXT_DECORATION_COLOR:

0
gtk/gtkcssstyle.h Normal file
View File

View File

@@ -151,6 +151,7 @@ struct _GtkCssFontValues {
GtkCssValue *secondary_caret_color; // NULL if currentColor
GtkCssValue *font_feature_settings;
GtkCssValue *font_variation_settings;
GtkCssValue *line_height;
};
struct _GtkCssFontVariantValues {

View File

@@ -812,6 +812,25 @@ transform_origin_parse (GtkCssStyleProperty *property,
return _gtk_css_position_value_parse (parser);
}
static GtkCssValue *
parse_line_height (GtkCssStyleProperty *property,
GtkCssParser *parser)
{
GtkCssValue *value = NULL;
if (gtk_css_parser_try_ident (parser, "normal"))
value = _gtk_css_ident_value_new ("normal");
else
value = _gtk_css_number_value_parse (parser, GTK_CSS_PARSE_NUMBER |
GTK_CSS_PARSE_PERCENT |
GTK_CSS_POSITIVE_ONLY);
if (value == NULL)
gtk_css_parser_error_syntax (parser, "Not a valid line-height value");
return value;
}
/*** REGISTRATION ***/
G_STATIC_ASSERT (GTK_CSS_PROPERTY_COLOR == 0);
@@ -1401,4 +1420,10 @@ _gtk_css_style_property_init_properties (void)
GTK_CSS_AFFECTS_TEXT_ATTRS | GTK_CSS_AFFECTS_TEXT_SIZE,
parse_font_variation_settings,
gtk_css_font_variations_value_new_default ());
gtk_css_style_property_register ("line-height",
GTK_CSS_PROPERTY_LINE_HEIGHT,
GTK_STYLE_PROPERTY_INHERIT | GTK_STYLE_PROPERTY_ANIMATED,
GTK_CSS_AFFECTS_TEXT_SIZE,
parse_line_height,
_gtk_css_value_ref (gtk_css_line_height_value_get_default ()));
}

View File

@@ -275,6 +275,7 @@ enum { /*< skip >*/
GTK_CSS_PROPERTY_SECONDARY_CARET_COLOR,
GTK_CSS_PROPERTY_FONT_FEATURE_SETTINGS,
GTK_CSS_PROPERTY_FONT_VARIATION_SETTINGS,
GTK_CSS_PROPERTY_LINE_HEIGHT,
/* add more */
GTK_CSS_PROPERTY_N_PROPERTIES
};

View File

@@ -53,6 +53,8 @@
#include "gtkdragicon.h"
#include "gtkcsscolorvalueprivate.h"
#include "gtkjoinedmenuprivate.h"
#include "gtkcssstylepropertyprivate.h"
#include "gtkcssnumbervalueprivate.h"
#include <math.h>
#include <string.h>
@@ -841,6 +843,26 @@ gtk_label_update_layout_attributes (GtkLabel *self,
pango_attr_list_unref (attrs);
}
static void
gtk_label_update_layout (GtkLabel *self)
{
GtkCssStyle *style;
GtkCssStyleProperty *prop;
float line_spacing;
if (self->layout == NULL)
return;
style = gtk_css_node_get_style (gtk_widget_get_css_node (GTK_WIDGET (self)));
if (_gtk_css_value_equal (style->font->line_height, gtk_css_line_height_value_get_default ()))
line_spacing = 0.0;
else
line_spacing = _gtk_css_number_value_get (style->font->line_height, 1.0);
pango_layout_set_line_spacing (self->layout, line_spacing);
}
static void
gtk_label_css_changed (GtkWidget *widget,
GtkCssStyleChange *change)
@@ -851,6 +873,11 @@ gtk_label_css_changed (GtkWidget *widget,
GTK_WIDGET_CLASS (gtk_label_parent_class)->css_changed (widget, change);
if (gtk_css_style_change_affects (change, GTK_CSS_AFFECTS_TEXT_SIZE))
{
gtk_label_update_layout (self);
}
if (gtk_css_style_change_affects (change, GTK_CSS_AFFECTS_TEXT_ATTRS))
{
new_attrs = gtk_css_style_get_pango_attributes (gtk_css_style_change_get_new_style (change));
@@ -860,7 +887,7 @@ gtk_label_css_changed (GtkWidget *widget,
else
attrs_affected = FALSE;
if (change == NULL || attrs_affected || (self->select_info && self->select_info->links))
if (change == NULL || attrs_affected || (self->select_info && self->select_info->links))
{
gtk_label_update_layout_attributes (self, new_attrs);
@@ -3982,6 +4009,7 @@ gtk_label_ensure_layout (GtkLabel *self)
self->layout = gtk_widget_create_pango_layout (GTK_WIDGET (self), self->text);
gtk_label_update_layout_attributes (self, NULL);
gtk_label_update_layout (self);
switch (self->jtype)
{

View File

@@ -972,6 +972,59 @@ gtk_popover_unrealize (GtkWidget *widget)
g_clear_object (&priv->surface);
}
static gboolean
gtk_popover_focus (GtkWidget *widget,
GtkDirectionType direction)
{
if (!gtk_widget_get_visible (widget))
return FALSE;
/* This code initially comes from gtkpopovermenu.c */
if (gtk_widget_get_first_child (widget) == NULL)
{
/* Empty popover, so nothing to Tab through. */
return FALSE;
}
else
{
/* Move focus normally, but when nothing can be focused in this direction then we cycle around. */
if (gtk_widget_focus_move (widget, direction))
return TRUE;
if (gtk_popover_get_autohide (GTK_POPOVER (widget)))
{
GtkWidget *p = gtk_root_get_focus (gtk_widget_get_root (widget));
/* In the case where the popover doesn't have any focusable child (like
* the GtkTreePopover for combo boxes) then the focus will end up out of
* the popover, hence creating an infinite loop below. To avoid this, just
* say we had focus and stop here.
*/
if (!gtk_widget_is_ancestor (p, widget) && p != widget)
return TRUE;
/* Cycle around with (Shift+)Tab */
if (direction == GTK_DIR_TAB_FORWARD || direction == GTK_DIR_TAB_BACKWARD)
{
for (;
p != widget;
p = gtk_widget_get_parent (p))
{
/* Unfocus everything in the popover. */
gtk_widget_set_focus_child (p, NULL);
}
}
/* Focus again from scratch */
gtk_widget_focus_move (widget, direction);
return TRUE;
}
else
{
return FALSE;
}
}
}
static void
gtk_popover_show (GtkWidget *widget)
{
@@ -1734,6 +1787,7 @@ gtk_popover_class_init (GtkPopoverClass *klass)
widget_class->unrealize = gtk_popover_unrealize;
widget_class->map = gtk_popover_map;
widget_class->unmap = gtk_popover_unmap;
widget_class->focus = gtk_popover_focus;
widget_class->show = gtk_popover_show;
widget_class->hide = gtk_popover_hide;
widget_class->measure = gtk_popover_measure;
@@ -2175,8 +2229,8 @@ gtk_popover_get_position (GtkPopover *popover)
* Sets whether @popover is modal.
*
* A modal popover will grab the keyboard focus on it when being
* displayed. Clicking outside the popover area or pressing Esc
* will dismiss the popover.
* displayed. Focus will wrap around within the popover. Clicking
* outside the popover area or pressing Esc will dismiss the popover.
*
* Called this function on an already showing popup with a new
* autohide value different from the current one, will cause the

View File

@@ -480,12 +480,21 @@ gtk_popover_menu_focus (GtkWidget *widget,
else
return TRUE;
}
else if (direction == GTK_DIR_UP || direction == GTK_DIR_DOWN)
/* Cycle around with up/down arrows and (Shift+)Tab when modal */
else if (gtk_popover_get_autohide (GTK_POPOVER (menu)))
{
GtkWidget *p;
GtkWidget *p = gtk_root_get_focus (gtk_widget_get_root (widget));
/* In the case where the popover doesn't have any focusable child, if
* the menu doesn't have any item for example, then the focus will end
* up out of the popover, hence creating an infinite loop below. To
* avoid this, just say we had focus and stop here.
*/
if (!gtk_widget_is_ancestor (p, widget) && p != widget)
return TRUE;
/* cycle around */
for (p = gtk_root_get_focus (gtk_widget_get_root (widget));
for (;
p != widget;
p = gtk_widget_get_parent (p))
{
@@ -493,7 +502,7 @@ gtk_popover_menu_focus (GtkWidget *widget,
}
if (gtk_widget_focus_move (widget, direction))
return TRUE;
}
}
}
return FALSE;

View File

@@ -5049,39 +5049,40 @@ gtk_text_move_visually (GtkText *self,
int index;
PangoLayout *layout = gtk_text_ensure_layout (self, FALSE);
const char *text;
gboolean split_cursor;
gboolean strong;
text = pango_layout_get_text (layout);
index = g_utf8_offset_to_pointer (text, start) - text;
g_object_get (gtk_widget_get_settings (GTK_WIDGET (self)),
"gtk-split-cursor", &split_cursor,
NULL);
if (split_cursor)
strong = TRUE;
else
{
GdkDisplay *display;
GdkSeat *seat;
GdkDevice *keyboard = NULL;
PangoDirection direction = PANGO_DIRECTION_LTR;
display = gtk_widget_get_display (GTK_WIDGET (self));
seat = gdk_display_get_default_seat (display);
if (seat)
keyboard = gdk_seat_get_keyboard (seat);
if (keyboard)
direction = gdk_device_get_direction (keyboard);
strong = direction == priv->resolved_dir;
}
while (count != 0)
{
int new_index, new_trailing;
gboolean split_cursor;
gboolean strong;
g_object_get (gtk_widget_get_settings (GTK_WIDGET (self)),
"gtk-split-cursor", &split_cursor,
NULL);
if (split_cursor)
strong = TRUE;
else
{
GdkDisplay *display;
GdkSeat *seat;
GdkDevice *keyboard = NULL;
PangoDirection direction = PANGO_DIRECTION_LTR;
display = gtk_widget_get_display (GTK_WIDGET (self));
seat = gdk_display_get_default_seat (display);
if (seat)
keyboard = gdk_seat_get_keyboard (seat);
if (keyboard)
direction = gdk_device_get_direction (keyboard);
strong = direction == priv->resolved_dir;
}
if (count > 0)
{
@@ -5098,11 +5099,11 @@ gtk_text_move_visually (GtkText *self,
index = 0;
else if (new_index != G_MAXINT)
index = new_index;
while (new_trailing--)
index = g_utf8_next_char (text + index) - text;
}
return g_utf8_pointer_to_offset (text, text + index);
}

View File

@@ -387,6 +387,9 @@ _gtk_text_attributes_fill_from_tags (GtkTextAttributes *dest,
if (tag->priv->pixels_inside_wrap_set)
dest->pixels_inside_wrap = vals->pixels_inside_wrap;
if (tag->priv->line_spacing_set)
dest->line_spacing = vals->line_spacing;
if (tag->priv->tabs_set)
{
if (dest->tabs)
@@ -457,6 +460,7 @@ _gtk_text_tag_affects_size (GtkTextTag *tag)
priv->pixels_above_lines_set ||
priv->pixels_below_lines_set ||
priv->pixels_inside_wrap_set ||
priv->line_spacing_set ||
priv->tabs_set ||
priv->underline_set ||
priv->overline_set ||

View File

@@ -147,6 +147,8 @@ struct _GtkTextAttributes
int pixels_below_lines;
int pixels_inside_wrap;
float line_spacing;
int letter_spacing;
guint invisible : 1;

View File

@@ -1277,6 +1277,8 @@ set_para_values (GtkTextLayout *layout,
pango_layout_set_spacing (display->layout,
style->pixels_inside_wrap * PANGO_SCALE);
pango_layout_set_line_spacing (display->layout, style->line_spacing);
if (style->tabs)
pango_layout_set_tabs (display->layout, style->tabs);

View File

@@ -107,6 +107,7 @@ enum {
PROP_PIXELS_ABOVE_LINES,
PROP_PIXELS_BELOW_LINES,
PROP_PIXELS_INSIDE_WRAP,
PROP_LINE_SPACING,
PROP_EDITABLE,
PROP_WRAP_MODE,
PROP_JUSTIFICATION,
@@ -150,6 +151,7 @@ enum {
PROP_PIXELS_ABOVE_LINES_SET,
PROP_PIXELS_BELOW_LINES_SET,
PROP_PIXELS_INSIDE_WRAP_SET,
PROP_LINE_SPACING_SET,
PROP_EDITABLE_SET,
PROP_WRAP_MODE_SET,
PROP_JUSTIFICATION_SET,
@@ -585,6 +587,8 @@ gtk_text_tag_class_init (GtkTextTagClass *klass)
* GtkTextTag:pixels-inside-wrap:
*
* Pixels of blank space between wrapped lines in a paragraph.
*
* Ignored if line-spacing is set.
*/
g_object_class_install_property (object_class,
PROP_PIXELS_INSIDE_WRAP,
@@ -596,6 +600,21 @@ gtk_text_tag_class_init (GtkTextTagClass *klass)
0,
GTK_PARAM_READWRITE));
/**
* GtkTexTag:line-spacing:
*
* The line spacing factor that is applied between consecutive lines.
*
* Since: 4.4
*/
g_object_class_install_property (object_class,
PROP_LINE_SPACING,
g_param_spec_float ("line-spacing",
P_("Line spacing"),
P_("The factor for spacing between lines"),
0.0, 10.0, 0.0,
GTK_PARAM_READWRITE));
/**
* GtkTextTag:strikethrough:
*
@@ -936,6 +955,10 @@ gtk_text_tag_class_init (GtkTextTagClass *klass)
P_("Pixels inside wrap set"),
P_("Whether this tag affects the number of pixels between wrapped lines"));
ADD_SET_PROP ("line-spacing-set", PROP_LINE_SPACING_SET,
P_("Linespacing set"),
P_("Whether this tag affects spacing between wrapped lines"));
ADD_SET_PROP ("strikethrough-set", PROP_STRIKETHROUGH_SET,
P_("Strikethrough set"),
P_("Whether this tag affects strikethrough"));
@@ -1573,6 +1596,13 @@ gtk_text_tag_set_property (GObject *object,
size_changed = TRUE;
break;
case PROP_LINE_SPACING:
priv->line_spacing_set = TRUE;
priv->values->line_spacing = g_value_get_float (value);
g_object_notify (object, "line-spacing-set");
size_changed = TRUE;
break;
case PROP_EDITABLE:
priv->editable_set = TRUE;
priv->values->editable = g_value_get_boolean (value);
@@ -2022,6 +2052,10 @@ gtk_text_tag_get_property (GObject *object,
g_value_set_int (value, priv->values->pixels_inside_wrap);
break;
case PROP_LINE_SPACING:
g_value_set_float (value, priv->values->line_spacing);
break;
case PROP_EDITABLE:
g_value_set_boolean (value, priv->values->editable);
break;
@@ -2169,6 +2203,10 @@ gtk_text_tag_get_property (GObject *object,
g_value_set_boolean (value, priv->pixels_inside_wrap_set);
break;
case PROP_LINE_SPACING_SET:
g_value_set_boolean (value, priv->line_spacing_set);
break;
case PROP_EDITABLE_SET:
g_value_set_boolean (value, priv->editable_set);
break;

View File

@@ -71,6 +71,7 @@ struct _GtkTextTagPrivate
guint pixels_above_lines_set : 1;
guint pixels_below_lines_set : 1;
guint pixels_inside_wrap_set : 1;
guint line_spacing_set : 1;
guint tabs_set : 1;
guint underline_set : 1;
guint overline_set : 1;

View File

@@ -57,6 +57,8 @@
#include "gtknative.h"
#include "gtkwidgetprivate.h"
#include "gtkjoinedmenuprivate.h"
#include "gtkcssstylepropertyprivate.h"
#include "gtkcssstringvalueprivate.h"
/**
* GtkTextView:
@@ -7659,6 +7661,11 @@ gtk_text_view_set_attributes_from_style (GtkTextView *text_view,
pango_font_description_free (values->font);
values->font = gtk_css_style_get_pango_font (style);
if (_gtk_css_value_equal (style->font->line_height, gtk_css_line_height_value_get_default ()))
values->line_spacing = 0.0;
else
values->line_spacing = _gtk_css_number_value_get (style->font->line_height, 1.0);
}
static void

View File

@@ -441,8 +441,11 @@ testdata = [
'treeview-fixed-height.css',
'treeview-fixed-height.ref.ui',
'treeview-fixed-height.ui',
'treeview-headers-hidden.ref.ui',
'treeview-headers-hidden.ui',
# this test fails with an off-by-one in ci too frequently
# to be left enabled. Remove it until somebody figures out
# what is going on there.
#'treeview-headers-hidden.ref.ui',
#'treeview-headers-hidden.ui',
'unresolvable.css',
'unresolvable.ref.ui',
'unresolvable.ui',