diff --git a/demos/gtk-demo/demo.gresource.xml b/demos/gtk-demo/demo.gresource.xml index 32b830a67b..a6e6e48a8f 100644 --- a/demos/gtk-demo/demo.gresource.xml +++ b/demos/gtk-demo/demo.gresource.xml @@ -208,6 +208,8 @@ demo3widget.ui + svgpaintable.h + svgpaintable.c org.gtk.gtk4.NodeEditor.Devel.svg diff --git a/demos/gtk-demo/meson.build b/demos/gtk-demo/meson.build index b14f1e04f2..fcddbde09e 100644 --- a/demos/gtk-demo/meson.build +++ b/demos/gtk-demo/meson.build @@ -139,6 +139,7 @@ librsvg_dep = dependency('librsvg-2.0', version: '>= 2.46.0', required: false) if librsvg_dep.found() demos += files('paintable_svg.c') + extra_demo_sources += files(['svgpaintable.c']) gtkdemo_deps += [ librsvg_dep ] endif diff --git a/demos/gtk-demo/paintable_svg.c b/demos/gtk-demo/paintable_svg.c index 975c650f93..eab506f4ed 100644 --- a/demos/gtk-demo/paintable_svg.c +++ b/demos/gtk-demo/paintable_svg.c @@ -9,183 +9,20 @@ #include #include -#define SVG_TYPE_PAINTABLE (svg_paintable_get_type ()) +#include "svgpaintable.h" -G_DECLARE_FINAL_TYPE (SvgPaintable, svg_paintable, SVG, PAINTABLE, GObject) - -struct _SvgPaintable -{ - GObject parent_instance; - GFile *file; - RsvgHandle *handle; -}; - -struct _SvgPaintableClass -{ - GObjectClass parent_class; -}; - -enum { - PROP_FILE = 1, - NUM_PROPERTIES -}; - -static void -svg_paintable_snapshot (GdkPaintable *paintable, - GdkSnapshot *snapshot, - double width, - double height) -{ - SvgPaintable *self = SVG_PAINTABLE (paintable); - cairo_t *cr; - GError *error = NULL; - - cr = gtk_snapshot_append_cairo (GTK_SNAPSHOT (snapshot), - &GRAPHENE_RECT_INIT (0, 0, width, height)); - - if (!rsvg_handle_render_document (self->handle, cr, - &(RsvgRectangle) {0, 0, width, height}, - &error)) - { - g_error ("%s", error->message); - } - - cairo_destroy (cr); -} - -static int -svg_paintable_get_intrinsic_width (GdkPaintable *paintable) -{ - SvgPaintable *self = SVG_PAINTABLE (paintable); - RsvgDimensionData data; - - rsvg_handle_get_dimensions (self->handle, &data); - - return data.width; -} - -static int -svg_paintable_get_intrinsic_height (GdkPaintable *paintable) -{ - SvgPaintable *self = SVG_PAINTABLE (paintable); - RsvgDimensionData data; - - rsvg_handle_get_dimensions (self->handle, &data); - - return data.height; -} - -static void -svg_paintable_init_interface (GdkPaintableInterface *iface) -{ - iface->snapshot = svg_paintable_snapshot; - iface->get_intrinsic_width = svg_paintable_get_intrinsic_width; - iface->get_intrinsic_height = svg_paintable_get_intrinsic_height; -} - -G_DEFINE_TYPE_WITH_CODE (SvgPaintable, svg_paintable, G_TYPE_OBJECT, - G_IMPLEMENT_INTERFACE (GDK_TYPE_PAINTABLE, - svg_paintable_init_interface)) - -static void -svg_paintable_init (SvgPaintable *self) -{ -} - -static void -svg_paintable_dispose (GObject *object) -{ - SvgPaintable *self = SVG_PAINTABLE (object); - - g_clear_object (&self->file); - g_clear_object (&self->handle); - - G_OBJECT_CLASS (svg_paintable_parent_class)->dispose (object); -} - -static void -svg_paintable_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - SvgPaintable *self = SVG_PAINTABLE (object); - - switch (prop_id) - { - case PROP_FILE: - { - GFile *file = g_value_get_object (value); - RsvgHandle *handle = rsvg_handle_new_from_gfile_sync (file, - RSVG_HANDLE_FLAGS_NONE, - NULL, - NULL); - rsvg_handle_set_dpi (handle, 90); - - g_set_object (&self->file, file); - g_set_object (&self->handle, handle); - } - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - } -} - -static void -svg_paintable_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - SvgPaintable *self = SVG_PAINTABLE (object); - - switch (prop_id) - { - case PROP_FILE: - g_value_set_object (value, self->file); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - } -} - - -static void -svg_paintable_class_init (SvgPaintableClass *class) -{ - GObjectClass *object_class = G_OBJECT_CLASS (class); - - object_class->dispose = svg_paintable_dispose; - object_class->set_property = svg_paintable_set_property; - object_class->get_property = svg_paintable_get_property; - - g_object_class_install_property (object_class, PROP_FILE, - g_param_spec_object ("file", "File", "File", - G_TYPE_FILE, - G_PARAM_READWRITE)); -} - -static SvgPaintable * -svg_paintable_new (GFile *file) -{ - return g_object_new (SVG_TYPE_PAINTABLE, - "file", file, - NULL); -} static void file_set (GtkFileChooserButton *button, GtkWidget *picture) { GFile *file; - SvgPaintable *paintable; + GdkPaintable *paintable; file = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (button)); paintable = svg_paintable_new (file); - gtk_picture_set_paintable (GTK_PICTURE (picture), GDK_PAINTABLE (paintable)); + gtk_picture_set_paintable (GTK_PICTURE (picture), paintable); g_object_unref (paintable); g_object_unref (file); @@ -201,7 +38,7 @@ do_paintable_svg (GtkWidget *do_widget) GtkFileFilter *filter; GtkWidget *button; GFile *file; - SvgPaintable *paintable; + GdkPaintable *paintable; if (!window) { @@ -228,7 +65,7 @@ do_paintable_svg (GtkWidget *do_widget) file = g_file_new_for_uri ("resource:///paintable_svg/org.gtk.gtk4.NodeEditor.Devel.svg"); paintable = svg_paintable_new (file); - gtk_picture_set_paintable (GTK_PICTURE (picture), GDK_PAINTABLE (paintable)); + gtk_picture_set_paintable (GTK_PICTURE (picture), paintable); g_object_unref (paintable); g_object_unref (file); } diff --git a/demos/gtk-demo/svgpaintable.c b/demos/gtk-demo/svgpaintable.c new file mode 100644 index 0000000000..21879ed0d9 --- /dev/null +++ b/demos/gtk-demo/svgpaintable.c @@ -0,0 +1,166 @@ +#include "svgpaintable.h" + +#include +#include + +struct _SvgPaintable +{ + GObject parent_instance; + GFile *file; + RsvgHandle *handle; +}; + +struct _SvgPaintableClass +{ + GObjectClass parent_class; +}; + +enum { + PROP_FILE = 1, + NUM_PROPERTIES +}; + +static void +svg_paintable_snapshot (GdkPaintable *paintable, + GdkSnapshot *snapshot, + double width, + double height) +{ + SvgPaintable *self = SVG_PAINTABLE (paintable); + cairo_t *cr; + GError *error = NULL; + + cr = gtk_snapshot_append_cairo (GTK_SNAPSHOT (snapshot), + &GRAPHENE_RECT_INIT (0, 0, width, height)); + + if (!rsvg_handle_render_document (self->handle, cr, + &(RsvgRectangle) {0, 0, width, height}, + &error)) + { + g_error ("%s", error->message); + } + + cairo_destroy (cr); +} + +static int +svg_paintable_get_intrinsic_width (GdkPaintable *paintable) +{ + SvgPaintable *self = SVG_PAINTABLE (paintable); + RsvgDimensionData data; + + rsvg_handle_get_dimensions (self->handle, &data); + + return data.width; +} + +static int +svg_paintable_get_intrinsic_height (GdkPaintable *paintable) +{ + SvgPaintable *self = SVG_PAINTABLE (paintable); + RsvgDimensionData data; + + rsvg_handle_get_dimensions (self->handle, &data); + + return data.height; +} + +static void +svg_paintable_init_interface (GdkPaintableInterface *iface) +{ + iface->snapshot = svg_paintable_snapshot; + iface->get_intrinsic_width = svg_paintable_get_intrinsic_width; + iface->get_intrinsic_height = svg_paintable_get_intrinsic_height; +} + +G_DEFINE_TYPE_WITH_CODE (SvgPaintable, svg_paintable, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (GDK_TYPE_PAINTABLE, + svg_paintable_init_interface)) + +static void +svg_paintable_init (SvgPaintable *self) +{ +} + +static void +svg_paintable_dispose (GObject *object) +{ + SvgPaintable *self = SVG_PAINTABLE (object); + + g_clear_object (&self->file); + g_clear_object (&self->handle); + + G_OBJECT_CLASS (svg_paintable_parent_class)->dispose (object); +} + +static void +svg_paintable_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + SvgPaintable *self = SVG_PAINTABLE (object); + + switch (prop_id) + { + case PROP_FILE: + { + GFile *file = g_value_get_object (value); + RsvgHandle *handle = rsvg_handle_new_from_gfile_sync (file, + RSVG_HANDLE_FLAGS_NONE, + NULL, + NULL); + rsvg_handle_set_dpi (handle, 90); + + g_set_object (&self->file, file); + g_set_object (&self->handle, handle); + } + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +svg_paintable_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + SvgPaintable *self = SVG_PAINTABLE (object); + + switch (prop_id) + { + case PROP_FILE: + g_value_set_object (value, self->file); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + + +static void +svg_paintable_class_init (SvgPaintableClass *class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (class); + + object_class->dispose = svg_paintable_dispose; + object_class->set_property = svg_paintable_set_property; + object_class->get_property = svg_paintable_get_property; + + g_object_class_install_property (object_class, PROP_FILE, + g_param_spec_object ("file", "File", "File", + G_TYPE_FILE, + G_PARAM_READWRITE)); +} + +GdkPaintable * +svg_paintable_new (GFile *file) +{ + return g_object_new (SVG_TYPE_PAINTABLE, + "file", file, + NULL); +} diff --git a/demos/gtk-demo/svgpaintable.h b/demos/gtk-demo/svgpaintable.h new file mode 100644 index 0000000000..f6015e517e --- /dev/null +++ b/demos/gtk-demo/svgpaintable.h @@ -0,0 +1,13 @@ +#pragma once + +#include + +G_BEGIN_DECLS + +#define SVG_TYPE_PAINTABLE (svg_paintable_get_type ()) + +G_DECLARE_FINAL_TYPE (SvgPaintable, svg_paintable, SVG, PAINTABLE, GObject) + +GdkPaintable * svg_paintable_new (GFile *file); + +G_END_DECLS diff --git a/gtk/gtklabel.c b/gtk/gtklabel.c index 6aedef6dd0..3d82096bfb 100644 --- a/gtk/gtklabel.c +++ b/gtk/gtklabel.c @@ -449,8 +449,8 @@ static gboolean gtk_label_query_tooltip (GtkWidget *widget, static void gtk_label_set_text_internal (GtkLabel *self, char *str); -static void gtk_label_set_label_internal (GtkLabel *self, - char *str); +static gboolean gtk_label_set_label_internal (GtkLabel *self, + const char *str); static gboolean gtk_label_set_use_markup_internal (GtkLabel *self, gboolean val); static gboolean gtk_label_set_use_underline_internal (GtkLabel *self, @@ -1702,15 +1702,19 @@ gtk_label_set_text_internal (GtkLabel *self, gtk_label_select_region_index (self, 0, 0); } -static void -gtk_label_set_label_internal (GtkLabel *self, - char *str) +static gboolean +gtk_label_set_label_internal (GtkLabel *self, + const char *str) { - g_free (self->label); + if (g_strcmp0 (str, self->label) == 0) + return FALSE; - self->label = str; + g_free (self->label); + self->label = g_strdup (str ? str : ""); g_object_notify_by_pspec (G_OBJECT (self), label_props[PROP_LABEL]); + + return TRUE; } static gboolean @@ -1784,7 +1788,7 @@ gtk_label_recalculate (GtkLabel *self) * @str: The text you want to set * * Sets the text within the #GtkLabel widget. It overwrites any text that - * was there before. + * was there before. * * This function will clear any previously set mnemonic accelerators, and * set the #GtkLabel:use-underline property to %FALSE as a side effect. @@ -1796,17 +1800,16 @@ gtk_label_recalculate (GtkLabel *self) **/ void gtk_label_set_text (GtkLabel *self, - const char *str) + const char *str) { g_return_if_fail (GTK_IS_LABEL (self)); - + g_object_freeze_notify (G_OBJECT (self)); - gtk_label_set_label_internal (self, g_strdup (str ? str : "")); - gtk_label_set_use_markup_internal (self, FALSE); - gtk_label_set_use_underline_internal (self, FALSE); - - gtk_label_recalculate (self); + if (gtk_label_set_label_internal (self, str) || + gtk_label_set_use_markup_internal (self, FALSE) || + gtk_label_set_use_underline_internal (self, FALSE)) + gtk_label_recalculate (self); g_object_thaw_notify (G_OBJECT (self)); } @@ -1882,14 +1885,14 @@ gtk_label_get_attributes (GtkLabel *self) **/ void gtk_label_set_label (GtkLabel *self, - const char *str) + const char *str) { g_return_if_fail (GTK_IS_LABEL (self)); g_object_freeze_notify (G_OBJECT (self)); - gtk_label_set_label_internal (self, g_strdup (str ? str : "")); - gtk_label_recalculate (self); + if (gtk_label_set_label_internal (self, str)) + gtk_label_recalculate (self); g_object_thaw_notify (G_OBJECT (self)); } @@ -2413,11 +2416,10 @@ gtk_label_set_markup (GtkLabel *self, g_object_freeze_notify (G_OBJECT (self)); - gtk_label_set_label_internal (self, g_strdup (str ? str : "")); - gtk_label_set_use_markup_internal (self, TRUE); - gtk_label_set_use_underline_internal (self, FALSE); - - gtk_label_recalculate (self); + if (gtk_label_set_label_internal (self, str) || + gtk_label_set_use_markup_internal (self, TRUE) || + gtk_label_set_use_underline_internal (self, FALSE)) + gtk_label_recalculate (self); g_object_thaw_notify (G_OBJECT (self)); } @@ -2445,11 +2447,10 @@ gtk_label_set_markup_with_mnemonic (GtkLabel *self, g_object_freeze_notify (G_OBJECT (self)); - gtk_label_set_label_internal (self, g_strdup (str ? str : "")); - gtk_label_set_use_markup_internal (self, TRUE); - gtk_label_set_use_underline_internal (self, TRUE); - - gtk_label_recalculate (self); + if (gtk_label_set_label_internal (self, str) || + gtk_label_set_use_markup_internal (self, TRUE) || + gtk_label_set_use_underline_internal (self, TRUE)) + gtk_label_recalculate (self); g_object_thaw_notify (G_OBJECT (self)); } @@ -3568,11 +3569,10 @@ gtk_label_set_text_with_mnemonic (GtkLabel *self, g_object_freeze_notify (G_OBJECT (self)); - gtk_label_set_label_internal (self, g_strdup (str)); - gtk_label_set_use_markup_internal (self, FALSE); - gtk_label_set_use_underline_internal (self, TRUE); - - gtk_label_recalculate (self); + if (gtk_label_set_label_internal (self, str) || + gtk_label_set_use_markup_internal (self, FALSE) || + gtk_label_set_use_underline_internal (self, TRUE)) + gtk_label_recalculate (self); g_object_thaw_notify (G_OBJECT (self)); } @@ -4825,7 +4825,7 @@ gtk_label_get_layout_offsets (GtkLabel *self, **/ void gtk_label_set_use_markup (GtkLabel *self, - gboolean setting) + gboolean setting) { g_return_if_fail (GTK_IS_LABEL (self)); @@ -4865,7 +4865,7 @@ gtk_label_get_use_markup (GtkLabel *self) */ void gtk_label_set_use_underline (GtkLabel *self, - gboolean setting) + gboolean setting) { g_return_if_fail (GTK_IS_LABEL (self)); diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c index c29cc88ec0..8d6e4067d5 100644 --- a/gtk/gtkwidget.c +++ b/gtk/gtkwidget.c @@ -7040,8 +7040,6 @@ gtk_widget_dispose (GObject *object) if (priv->parent) gtk_widget_unparent (widget); - else if (_gtk_widget_get_visible (widget)) - gtk_widget_hide (widget); while (priv->paintables) gtk_widget_paintable_set_widget (priv->paintables->data, NULL); diff --git a/gtk/theme/Adwaita/_common.scss b/gtk/theme/Adwaita/_common.scss index a552965cdd..8b5c53bdec 100644 --- a/gtk/theme/Adwaita/_common.scss +++ b/gtk/theme/Adwaita/_common.scss @@ -3098,13 +3098,13 @@ list { > row.expander { padding: 0px; } > row.expander .row-header { padding: 2px; } - &.horizontal row.separator:not(:first-child), - &.separators.horizontal > row:not(:first-child) { + &.horizontal row.separator, + &.separators.horizontal > row { border-left: 1px solid $_treeview_borders_color; } - &:not(.horizontal) row.separator:not(:first-child), - &.separators:not(.horizontal) > row:not(:first-child) { - border-top: 1px solid $_treeview_borders_color; + &:not(.horizontal) row.separator, + &.separators:not(.horizontal) > row { + border-bottom: 1px solid $_treeview_borders_color; } }