diff --git a/panels/background/bg-source.c b/panels/background/bg-source.c index b199257ba1f7fc4e9c3d03e6f22fdc2300f6cfef..dacf82f1048631031f03f146d36212beaf8a5762 100644 --- a/panels/background/bg-source.c +++ b/panels/background/bg-source.c @@ -23,7 +23,7 @@ #include -#define THUMBNAIL_WIDTH 154 +#define THUMBNAIL_WIDTH 144 #define THUMBNAIL_HEIGHT (THUMBNAIL_WIDTH * 3 / 4) typedef struct diff --git a/panels/background/cc-background-chooser.c b/panels/background/cc-background-chooser.c index 587bbad1f9683a4de1a9fb2fedba430e2b1553cd..43b093877678b69c187845c9640bcfdd15dc5d9d 100644 --- a/panels/background/cc-background-chooser.c +++ b/panels/background/cc-background-chooser.c @@ -28,6 +28,7 @@ #include "bg-recent-source.h" #include "bg-wallpapers-source.h" #include "cc-background-chooser.h" +#include "cc-background-paintable.h" struct _CcBackgroundChooser { @@ -84,11 +85,21 @@ on_delete_background_clicked_cb (GtkButton *button, bg_recent_source_remove_item (source, item); } +static void +direction_changed_cb (GtkWidget *widget, + GtkTextDirection *previous_direction, + GdkPaintable *paintable) +{ + g_object_set (paintable, + "text-direction", gtk_widget_get_direction (widget), + NULL); +} + static GtkWidget* create_widget_func (gpointer model_item, gpointer user_data) { - g_autoptr(GdkPixbuf) pixbuf = NULL; + g_autoptr(CcBackgroundPaintable) paintable = NULL; CcBackgroundItem *item; GtkWidget *overlay; GtkWidget *child; @@ -100,14 +111,19 @@ create_widget_func (gpointer model_item, source = BG_SOURCE (user_data); item = CC_BACKGROUND_ITEM (model_item); - pixbuf = cc_background_item_get_thumbnail (item, - bg_source_get_thumbnail_factory (source), - bg_source_get_thumbnail_width (source), - bg_source_get_thumbnail_height (source), - bg_source_get_scale_factor (source)); - picture = gtk_picture_new_for_pixbuf (pixbuf); + + paintable = cc_background_paintable_new (source, item); + + picture = gtk_picture_new_for_paintable (GDK_PAINTABLE (paintable)); gtk_picture_set_can_shrink (GTK_PICTURE (picture), FALSE); + g_object_bind_property (picture, "scale-factor", + paintable, "scale-factor", G_BINDING_SYNC_CREATE); + g_object_bind_property (picture, "text-direction", + paintable, "text-direction", G_BINDING_SYNC_CREATE); + g_signal_connect_object (picture, "direction-changed", + G_CALLBACK (direction_changed_cb), paintable, 0); + icon = gtk_image_new_from_icon_name ("slideshow-symbolic"); gtk_widget_set_halign (icon, GTK_ALIGN_START); gtk_widget_set_valign (icon, GTK_ALIGN_END); diff --git a/panels/background/cc-background-chooser.ui b/panels/background/cc-background-chooser.ui index 509ed53edb659143dcb48469fe3ae3f427b3af09..edaf1dd94d8f099cd70e7a1ace31fcb80318c225 100644 --- a/panels/background/cc-background-chooser.ui +++ b/panels/background/cc-background-chooser.ui @@ -13,6 +13,8 @@ 12 12 + 12 + 12 12 12 True @@ -41,6 +43,8 @@ 12 12 + 12 + 12 12 12 True diff --git a/panels/background/cc-background-item.c b/panels/background/cc-background-item.c index b69a9d940255565ef7a8fe0487847132f503b872..e25c8c43d73660bd2829da65b8aadf636fdfbb4c 100644 --- a/panels/background/cc-background-item.c +++ b/panels/background/cc-background-item.c @@ -32,6 +32,14 @@ #include "cc-background-item.h" #include "gdesktop-enums-types.h" +typedef struct { + int width; + int height; + int frame; + int scale_factor; + GdkPixbuf *thumbnail; +} CachedThumbnail; + struct _CcBackgroundItem { GObject parent_instance; @@ -39,6 +47,7 @@ struct _CcBackgroundItem /* properties */ char *name; char *uri; + char *uri_dark; char *size; GDesktopBackgroundStyle placement; GDesktopBackgroundShading shading; @@ -57,19 +66,17 @@ struct _CcBackgroundItem int width; int height; - struct { - int width; - int height; - int frame; - int scale_factor; - GdkPixbuf *thumbnail; - } cached_thumbnail; + GnomeBG *bg_dark; + + CachedThumbnail cached_thumbnail; + CachedThumbnail cached_thumbnail_dark; }; enum { PROP_0, PROP_NAME, PROP_URI, + PROP_URI_DARK, PROP_PLACEMENT, PROP_SHADING, PROP_PRIMARY_COLOR, @@ -102,6 +109,15 @@ set_bg_properties (CcBackgroundItem *item) gnome_bg_set_filename (item->bg, filename); } + if (item->uri_dark) { + g_autoptr(GFile) file = NULL; + g_autofree gchar *filename = NULL; + + file = g_file_new_for_commandline_arg (item->uri_dark); + filename = g_file_get_path (file); + gnome_bg_set_filename (item->bg_dark, filename); + } + if (item->primary_color != NULL) { gdk_rgba_parse (&pcolor, item->primary_color); } @@ -110,7 +126,9 @@ set_bg_properties (CcBackgroundItem *item) } gnome_bg_set_rgba (item->bg, item->shading, &pcolor, &scolor); + gnome_bg_set_rgba (item->bg_dark, item->shading, &pcolor, &scolor); gnome_bg_set_placement (item->bg, item->placement); + gnome_bg_set_placement (item->bg_dark, item->placement); } @@ -125,9 +143,20 @@ cc_background_item_changes_with_time (CcBackgroundItem *item) if (item->bg != NULL) { changes = gnome_bg_changes_with_time (item->bg); } + if (item->bg_dark != NULL) { + changes |= gnome_bg_changes_with_time (item->bg_dark); + } return changes; } +gboolean +cc_background_item_has_dark_version (CcBackgroundItem *item) +{ + g_return_val_if_fail (CC_IS_BACKGROUND_ITEM (item), FALSE); + + return item->uri && item->uri_dark; +} + static void update_size (CcBackgroundItem *item) { @@ -168,21 +197,27 @@ cc_background_item_get_frame_thumbnail (CcBackgroundItem *item, int height, int scale_factor, int frame, - gboolean force_size) + gboolean force_size, + gboolean dark) { g_autoptr(GdkPixbuf) pixbuf = NULL; g_autoptr(GdkPixbuf) retval = NULL; + CachedThumbnail *thumbnail; + GnomeBG *bg; g_return_val_if_fail (CC_IS_BACKGROUND_ITEM (item), NULL); g_return_val_if_fail (width > 0 && height > 0, NULL); + thumbnail = dark ? &item->cached_thumbnail_dark : &item->cached_thumbnail; + bg = dark ? item->bg_dark : item->bg; + /* Use the cached thumbnail if the sizes match */ - if (item->cached_thumbnail.thumbnail && - item->cached_thumbnail.width == width && - item->cached_thumbnail.height == height && - item->cached_thumbnail.scale_factor == scale_factor && - item->cached_thumbnail.frame == frame) - return g_object_ref (item->cached_thumbnail.thumbnail); + if (thumbnail->thumbnail && + thumbnail->width == width && + thumbnail->height == height && + thumbnail->scale_factor == scale_factor && + thumbnail->frame == frame) + return g_object_ref (thumbnail->thumbnail); set_bg_properties (item); @@ -194,7 +229,7 @@ cc_background_item_get_frame_thumbnail (CcBackgroundItem *item, * the slideshow frame though, so we can't do much better than this * for now. */ - pixbuf = render_at_size (item->bg, width, height); + pixbuf = render_at_size (bg, width, height); } else { g_autoptr(GdkMonitor) monitor = NULL; GdkDisplay *display; @@ -208,14 +243,14 @@ cc_background_item_get_frame_thumbnail (CcBackgroundItem *item, gdk_monitor_get_geometry (monitor, &monitor_layout); if (frame >= 0) { - pixbuf = gnome_bg_create_frame_thumbnail (item->bg, + pixbuf = gnome_bg_create_frame_thumbnail (bg, thumbs, &monitor_layout, width, height, frame); } else { - pixbuf = gnome_bg_create_thumbnail (item->bg, + pixbuf = gnome_bg_create_thumbnail (bg, thumbs, &monitor_layout, width, @@ -225,7 +260,7 @@ cc_background_item_get_frame_thumbnail (CcBackgroundItem *item, retval = g_steal_pointer (&pixbuf); - gnome_bg_get_image_size (item->bg, + gnome_bg_get_image_size (bg, thumbs, width, height, @@ -235,11 +270,11 @@ cc_background_item_get_frame_thumbnail (CcBackgroundItem *item, update_size (item); /* Cache the new thumbnail */ - g_set_object (&item->cached_thumbnail.thumbnail, retval); - item->cached_thumbnail.width = width; - item->cached_thumbnail.height = height; - item->cached_thumbnail.scale_factor = scale_factor; - item->cached_thumbnail.frame = frame; + g_set_object (&thumbnail->thumbnail, retval); + thumbnail->width = width; + thumbnail->height = height; + thumbnail->scale_factor = scale_factor; + thumbnail->frame = frame; return g_steal_pointer (&retval); } @@ -250,9 +285,10 @@ cc_background_item_get_thumbnail (CcBackgroundItem *item, GnomeDesktopThumbnailFactory *thumbs, int width, int height, - int scale_factor) + int scale_factor, + gboolean dark) { - return cc_background_item_get_frame_thumbnail (item, thumbs, width, height, scale_factor, -1, FALSE); + return cc_background_item_get_frame_thumbnail (item, thumbs, width, height, scale_factor, -1, FALSE, dark); } static void @@ -362,6 +398,21 @@ _set_uri (CcBackgroundItem *item, } } + +static void +_set_uri_dark (CcBackgroundItem *item, + const char *value) +{ + g_free (item->uri_dark); + if (value && *value == '\0') { + item->uri_dark = NULL; + } else { + if (value && strstr (value, "://") == NULL) + g_warning ("URI '%s' is invalid", value); + item->uri_dark = g_strdup (value); + } +} + const char * cc_background_item_get_uri (CcBackgroundItem *item) { @@ -370,6 +421,14 @@ cc_background_item_get_uri (CcBackgroundItem *item) return item->uri; } +const char * +cc_background_item_get_uri_dark (CcBackgroundItem *item) +{ + g_return_val_if_fail (CC_IS_BACKGROUND_ITEM (item), NULL); + + return item->uri_dark; +} + static void _set_placement (CcBackgroundItem *item, GDesktopBackgroundStyle value) @@ -541,6 +600,9 @@ cc_background_item_set_property (GObject *object, case PROP_URI: _set_uri (self, g_value_get_string (value)); break; + case PROP_URI_DARK: + _set_uri_dark (self, g_value_get_string (value)); + break; case PROP_PLACEMENT: _set_placement (self, g_value_get_enum (value)); break; @@ -591,9 +653,12 @@ cc_background_item_get_property (GObject *object, case PROP_NAME: g_value_set_string (value, self->name); break; - case PROP_URI: + case PROP_URI: g_value_set_string (value, self->uri); break; + case PROP_URI_DARK: + g_value_set_string (value, self->uri_dark); + break; case PROP_PLACEMENT: g_value_set_enum (value, self->placement); break; @@ -671,6 +736,13 @@ cc_background_item_class_init (CcBackgroundItemClass *klass) "uri", NULL, G_PARAM_READWRITE)); + g_object_class_install_property (object_class, + PROP_URI_DARK, + g_param_spec_string ("uri-dark", + "uri-dark", + "uri-dark", + NULL, + G_PARAM_READWRITE)); g_object_class_install_property (object_class, PROP_PLACEMENT, g_param_spec_enum ("placement", @@ -767,6 +839,7 @@ static void cc_background_item_init (CcBackgroundItem *item) { item->bg = gnome_bg_new (); + item->bg_dark = gnome_bg_new (); item->shading = G_DESKTOP_BACKGROUND_SHADING_SOLID; item->placement = G_DESKTOP_BACKGROUND_STYLE_SCALED; @@ -790,6 +863,7 @@ cc_background_item_finalize (GObject *object) g_return_if_fail (item != NULL); g_clear_object (&item->cached_thumbnail.thumbnail); + g_clear_object (&item->cached_thumbnail_dark.thumbnail); g_free (item->name); g_free (item->uri); g_free (item->primary_color); @@ -799,8 +873,8 @@ cc_background_item_finalize (GObject *object) g_free (item->source_url); g_free (item->source_xml); - if (item->bg != NULL) - g_object_unref (item->bg); + g_clear_object (&item->bg); + g_clear_object (&item->bg_dark); G_OBJECT_CLASS (cc_background_item_parent_class)->finalize (object); } @@ -959,6 +1033,10 @@ cc_background_item_compare (CcBackgroundItem *saved, if (files_equal (saved->uri, configured->uri) == FALSE) return FALSE; } + if (flags & CC_BACKGROUND_ITEM_HAS_URI_DARK) { + if (files_equal (saved->uri_dark, configured->uri_dark) == FALSE) + return FALSE; + } if (flags & CC_BACKGROUND_ITEM_HAS_SHADING) { if (saved->shading != configured->shading) return FALSE; diff --git a/panels/background/cc-background-item.h b/panels/background/cc-background-item.h index 9832d1e0422de150b3fce25abc8ec1bb6253e885..80fd5a2e7fb6ab2843b580fd4a8c712e461b8e35 100644 --- a/panels/background/cc-background-item.h +++ b/panels/background/cc-background-item.h @@ -35,7 +35,8 @@ typedef enum { CC_BACKGROUND_ITEM_HAS_PLACEMENT = 1 << 1, CC_BACKGROUND_ITEM_HAS_PCOLOR = 1 << 2, CC_BACKGROUND_ITEM_HAS_SCOLOR = 1 << 3, - CC_BACKGROUND_ITEM_HAS_URI = 1 << 4 + CC_BACKGROUND_ITEM_HAS_URI = 1 << 4, + CC_BACKGROUND_ITEM_HAS_URI_DARK = 1 << 5 } CcBackgroundItemFlags; #define CC_BACKGROUND_ITEM_HAS_ALL (CC_BACKGROUND_ITEM_HAS_SHADING & \ @@ -46,26 +47,30 @@ typedef enum { CcBackgroundItem * cc_background_item_new (const char *uri); CcBackgroundItem * cc_background_item_copy (CcBackgroundItem *item); -gboolean cc_background_item_load (CcBackgroundItem *item, - GFileInfo *info); +gboolean cc_background_item_load (CcBackgroundItem *item, + GFileInfo *info); gboolean cc_background_item_changes_with_time (CcBackgroundItem *item); +gboolean cc_background_item_has_dark_version (CcBackgroundItem *item); GdkPixbuf * cc_background_item_get_thumbnail (CcBackgroundItem *item, GnomeDesktopThumbnailFactory *thumbs, int width, int height, - int scale_factor); + int scale_factor, + gboolean dark); GdkPixbuf * cc_background_item_get_frame_thumbnail (CcBackgroundItem *item, GnomeDesktopThumbnailFactory *thumbs, int width, int height, int scale_factor, int frame, - gboolean force_size); + gboolean force_size, + gboolean dark); GDesktopBackgroundStyle cc_background_item_get_placement (CcBackgroundItem *item); GDesktopBackgroundShading cc_background_item_get_shading (CcBackgroundItem *item); const char * cc_background_item_get_uri (CcBackgroundItem *item); +const char * cc_background_item_get_uri_dark (CcBackgroundItem *item); const char * cc_background_item_get_source_url (CcBackgroundItem *item); const char * cc_background_item_get_source_xml (CcBackgroundItem *item); CcBackgroundItemFlags cc_background_item_get_flags (CcBackgroundItem *item); diff --git a/panels/background/cc-background-paintable.c b/panels/background/cc-background-paintable.c new file mode 100644 index 0000000000000000000000000000000000000000..763370601e76791d4a2dd7aea39542722c4b64df --- /dev/null +++ b/panels/background/cc-background-paintable.c @@ -0,0 +1,306 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2021 Alexander Mikhaylenko + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + */ + +#include + +#include "cc-background-paintable.h" + +struct _CcBackgroundPaintable +{ + GObject parent_instance; + + BgSource *source; + CcBackgroundItem *item; + int scale_factor; + GtkTextDirection text_direction; + + GdkPaintable *texture; + GdkPaintable *dark_texture; +}; + +enum +{ + PROP_0, + PROP_SOURCE, + PROP_ITEM, + PROP_SCALE_FACTOR, + PROP_TEXT_DIRECTION, + N_PROPS +}; + +static GParamSpec *properties [N_PROPS]; + +static void cc_background_paintable_paintable_init (GdkPaintableInterface *iface); + +G_DEFINE_TYPE_WITH_CODE (CcBackgroundPaintable, cc_background_paintable, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (GDK_TYPE_PAINTABLE, + cc_background_paintable_paintable_init)) + +static void +update_cache (CcBackgroundPaintable *self) +{ + g_autoptr (GdkPixbuf) pixbuf = NULL; + GnomeDesktopThumbnailFactory *factory; + int width, height; + + g_clear_object (&self->texture); + g_clear_object (&self->dark_texture); + + factory = bg_source_get_thumbnail_factory (self->source); + width = bg_source_get_thumbnail_width (self->source); + height = bg_source_get_thumbnail_height (self->source); + + pixbuf = cc_background_item_get_thumbnail (self->item, + factory, + width, + height, + self->scale_factor, + FALSE); + + self->texture = GDK_PAINTABLE (gdk_texture_new_for_pixbuf (pixbuf)); + + if (cc_background_item_has_dark_version (self->item)) + { + g_autoptr (GdkPixbuf) dark_pixbuf = NULL; + + dark_pixbuf = cc_background_item_get_thumbnail (self->item, + factory, + width, + height, + self->scale_factor, + TRUE); + self->dark_texture = GDK_PAINTABLE (gdk_texture_new_for_pixbuf (dark_pixbuf)); + } + + gdk_paintable_invalidate_size (GDK_PAINTABLE (self)); +} + +static void +cc_background_paintable_dispose (GObject *object) +{ + CcBackgroundPaintable *self = CC_BACKGROUND_PAINTABLE (object); + + g_clear_object (&self->item); + g_clear_object (&self->source); + g_clear_object (&self->texture); + g_clear_object (&self->dark_texture); + + G_OBJECT_CLASS (cc_background_paintable_parent_class)->dispose (object); +} + +static void +cc_background_paintable_constructed (GObject *object) +{ + CcBackgroundPaintable *self = CC_BACKGROUND_PAINTABLE (object); + + G_OBJECT_CLASS (cc_background_paintable_parent_class)->constructed (object); + + update_cache (self); +} + +static void +cc_background_paintable_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + CcBackgroundPaintable *self = CC_BACKGROUND_PAINTABLE (object); + + switch (prop_id) + { + case PROP_SOURCE: + g_value_set_object (value, self->source); + break; + + case PROP_ITEM: + g_value_set_object (value, self->item); + break; + + case PROP_SCALE_FACTOR: + g_value_set_int (value, self->scale_factor); + break; + + case PROP_TEXT_DIRECTION: + g_value_set_enum (value, self->text_direction); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +cc_background_paintable_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + CcBackgroundPaintable *self = CC_BACKGROUND_PAINTABLE (object); + + switch (prop_id) + { + case PROP_SOURCE: + g_set_object (&self->source, g_value_get_object (value)); + break; + + case PROP_ITEM: + g_set_object (&self->item, g_value_get_object (value)); + break; + + case PROP_SCALE_FACTOR: + self->scale_factor = g_value_get_int (value); + update_cache (self); + break; + + case PROP_TEXT_DIRECTION: + self->text_direction = g_value_get_enum (value); + gdk_paintable_invalidate_contents (GDK_PAINTABLE (self)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +cc_background_paintable_class_init (CcBackgroundPaintableClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->dispose = cc_background_paintable_dispose; + object_class->constructed = cc_background_paintable_constructed; + object_class->get_property = cc_background_paintable_get_property; + object_class->set_property = cc_background_paintable_set_property; + + properties[PROP_SOURCE] = + g_param_spec_object ("source", + "Source", + "Source", + BG_TYPE_SOURCE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS); + + properties[PROP_ITEM] = + g_param_spec_object ("item", + "Item", + "Item", + CC_TYPE_BACKGROUND_ITEM, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS); + + properties[PROP_SCALE_FACTOR] = + g_param_spec_int ("scale-factor", + "Scale Factor", + "Scale Factor", + 1, G_MAXINT, 1, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS); + + properties[PROP_TEXT_DIRECTION] = + g_param_spec_enum ("text-direction", + "Text Direction", + "Text Direction", + GTK_TYPE_TEXT_DIRECTION, + GTK_TEXT_DIR_LTR, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties (object_class, N_PROPS, properties); +} + +static void +cc_background_paintable_init (CcBackgroundPaintable *self) +{ + self->scale_factor = 1; + self->text_direction = GTK_TEXT_DIR_LTR; +} + +static void +cc_background_paintable_snapshot (GdkPaintable *paintable, + GdkSnapshot *snapshot, + double width, + double height) +{ + CcBackgroundPaintable *self = CC_BACKGROUND_PAINTABLE (paintable); + + gdk_paintable_snapshot (self->texture, snapshot, width, height); + + if (self->dark_texture) + { + gboolean is_rtl = self->text_direction == GTK_TEXT_DIR_RTL; + + gtk_snapshot_push_clip (GTK_SNAPSHOT (snapshot), + &GRAPHENE_RECT_INIT (is_rtl ? 0.0f : width / 2.0f, + 0.0f, + width / 2.0f, + height)); + + gdk_paintable_snapshot (self->dark_texture, snapshot, width, height); + + gtk_snapshot_pop (GTK_SNAPSHOT (snapshot)); + } +} + +static int +cc_background_paintable_get_intrinsic_width (GdkPaintable *paintable) +{ + CcBackgroundPaintable *self = CC_BACKGROUND_PAINTABLE (paintable); + + return gdk_paintable_get_intrinsic_width (self->texture) / self->scale_factor; +} + +static int +cc_background_paintable_get_intrinsic_height (GdkPaintable *paintable) +{ + CcBackgroundPaintable *self = CC_BACKGROUND_PAINTABLE (paintable); + + return gdk_paintable_get_intrinsic_height (self->texture) / self->scale_factor; +} + +static double +cc_background_paintable_get_intrinsic_aspect_ratio (GdkPaintable *paintable) +{ + CcBackgroundPaintable *self = CC_BACKGROUND_PAINTABLE (paintable); + + return gdk_paintable_get_intrinsic_aspect_ratio (self->texture); +} + +static void +cc_background_paintable_paintable_init (GdkPaintableInterface *iface) +{ + iface->snapshot = cc_background_paintable_snapshot; + iface->get_intrinsic_width = cc_background_paintable_get_intrinsic_width; + iface->get_intrinsic_height = cc_background_paintable_get_intrinsic_height; + iface->get_intrinsic_aspect_ratio = cc_background_paintable_get_intrinsic_aspect_ratio; +} + +CcBackgroundPaintable * +cc_background_paintable_new (BgSource *source, + CcBackgroundItem *item) +{ + g_return_val_if_fail (BG_IS_SOURCE (source), NULL); + g_return_val_if_fail (CC_IS_BACKGROUND_ITEM (item), NULL); + + return g_object_new (CC_TYPE_BACKGROUND_PAINTABLE, + "source", source, + "item", item, + NULL); +} diff --git a/panels/background/cc-background-paintable.h b/panels/background/cc-background-paintable.h new file mode 100644 index 0000000000000000000000000000000000000000..75360dc409eb1a319c38db0d57feda7ac03df72b --- /dev/null +++ b/panels/background/cc-background-paintable.h @@ -0,0 +1,35 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2021 Alexander Mikhaylenko + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + */ + +#pragma once + +#include + +#include "bg-source.h" +#include "cc-background-item.h" + +G_BEGIN_DECLS + +#define CC_TYPE_BACKGROUND_PAINTABLE (cc_background_paintable_get_type ()) +G_DECLARE_FINAL_TYPE (CcBackgroundPaintable, cc_background_paintable, CC, BACKGROUND_PAINTABLE, GObject) + +CcBackgroundPaintable * cc_background_paintable_new (BgSource *source, + CcBackgroundItem *item); + +G_END_DECLS diff --git a/panels/background/cc-background-panel.c b/panels/background/cc-background-panel.c index d55566c55aec6ec04fb692ed88cfdd9699670bc4..8fff61f72dcbd3dae9866a4743abe16e81764069 100644 --- a/panels/background/cc-background-panel.c +++ b/panels/background/cc-background-panel.c @@ -38,6 +38,7 @@ #define WP_PATH_ID "org.gnome.desktop.background" #define WP_LOCK_PATH_ID "org.gnome.desktop.screensaver" #define WP_URI_KEY "picture-uri" +#define WP_URI_DARK_KEY "picture-uri-dark" #define WP_OPTIONS_KEY "picture-options" #define WP_SHADING_KEY "color-shading-type" #define WP_PCOLOR_KEY "primary-color" @@ -152,6 +153,7 @@ reload_current_bg (CcBackgroundPanel *panel) CcBackgroundItem *configured; GSettings *settings = NULL; g_autofree gchar *uri = NULL; + g_autofree gchar *dark_uri = NULL; g_autofree gchar *pcolor = NULL; g_autofree gchar *scolor = NULL; @@ -165,12 +167,15 @@ reload_current_bg (CcBackgroundPanel *panel) if (uri && *uri == '\0') g_clear_pointer (&uri, g_free); + configured = cc_background_item_new (uri); + dark_uri = g_settings_get_string (settings, WP_URI_DARK_KEY); pcolor = g_settings_get_string (settings, WP_PCOLOR_KEY); scolor = g_settings_get_string (settings, WP_SCOLOR_KEY); g_object_set (G_OBJECT (configured), "name", _("Current background"), + "uri-dark", dark_uri, "placement", g_settings_get_enum (settings, WP_OPTIONS_KEY), "shading", g_settings_get_enum (settings, WP_SHADING_KEY), "primary-color", pcolor, @@ -217,7 +222,8 @@ create_save_dir (void) static void set_background (CcBackgroundPanel *panel, GSettings *settings, - CcBackgroundItem *item) + CcBackgroundItem *item, + gboolean set_dark) { GDesktopBackgroundStyle style; CcBackgroundItemFlags flags; @@ -232,6 +238,18 @@ set_background (CcBackgroundPanel *panel, g_settings_set_string (settings, WP_URI_KEY, uri); + if (set_dark) + { + const char *uri_dark; + + uri_dark = cc_background_item_get_uri_dark (item); + + if (uri_dark && uri_dark[0]) + g_settings_set_string (settings, WP_URI_DARK_KEY, uri_dark); + else + g_settings_set_string (settings, WP_URI_DARK_KEY, uri); + } + /* Also set the placement if we have a URI and the previous value was none */ if (flags & CC_BACKGROUND_ITEM_HAS_PLACEMENT) { @@ -263,8 +281,8 @@ static void on_chooser_background_chosen_cb (CcBackgroundPanel *self, CcBackgroundItem *item) { - set_background (self, self->settings, item); - set_background (self, self->lock_settings, item); + set_background (self, self->settings, item, TRUE); + set_background (self, self->lock_settings, item, FALSE); } static void diff --git a/panels/background/cc-background-panel.ui b/panels/background/cc-background-panel.ui index 40344ed5c466791426bd8e06dc0fa65c3c67a3d2..71621a17b6c7a49916be71819238983d0d0de150 100644 --- a/panels/background/cc-background-panel.ui +++ b/panels/background/cc-background-panel.ui @@ -112,7 +112,6 @@ True - True diff --git a/panels/background/cc-background-preview.c b/panels/background/cc-background-preview.c index 216ab78c30c1df75c48af939e5ef935ec8f3d0ef..428c44f8bff61ddedb5aa221e2abf81aa05dc811 100644 --- a/panels/background/cc-background-preview.c +++ b/panels/background/cc-background-preview.c @@ -71,7 +71,9 @@ draw_preview_func (GtkDrawingArea *drawing_area, height, scale_factor, 0, - TRUE); + TRUE, + self->is_dark && + cc_background_item_has_dark_version (self->item)); gdk_cairo_set_source_pixbuf (cr, pixbuf, 0, 0); @@ -133,6 +135,7 @@ cc_background_preview_get_property (GObject *object, { case PROP_IS_DARK: g_value_set_boolean (value, self->is_dark); + break; case PROP_ITEM: g_value_set_object (value, self->item); diff --git a/panels/background/cc-background-xml.c b/panels/background/cc-background-xml.c index 270fcc2fba4dbf5d42f597ab5f8190771976f794..84f0a047e08671bc49a6d9b9f4cf24a0128c19ff 100644 --- a/panels/background/cc-background-xml.c +++ b/panels/background/cc-background-xml.c @@ -210,6 +210,27 @@ cc_background_xml_load_xml_internal (CcBackgroundXml *xml, } else { break; } + } else if (!strcmp ((gchar *)wpa->name, "filename-dark")) { + if (wpa->last != NULL && wpa->last->content != NULL) { + gchar *content = g_strstrip ((gchar *)wpa->last->content); + g_autofree gchar *bg_uri = NULL; + + /* FIXME same rubbish as in other parts of the code */ + if (strcmp (content, NONE) == 0) { + bg_uri = NULL; + } else { + g_autoptr(GFile) file = NULL; + g_autofree gchar *dirname = NULL; + + dirname = g_path_get_dirname (filename); + file = g_file_new_for_commandline_arg_and_cwd (content, dirname); + bg_uri = g_file_get_uri (file); + } + SET_FLAG(CC_BACKGROUND_ITEM_HAS_URI_DARK); + g_object_set (G_OBJECT (item), "uri-dark", bg_uri, NULL); + } else { + break; + } } else if (!strcmp ((gchar *)wpa->name, "name")) { if (wpa->last != NULL && wpa->last->content != NULL) { g_autofree gchar *name = NULL; diff --git a/panels/background/meson.build b/panels/background/meson.build index 9348dac722e55295faac585e708e77b48f448345..3634c4727e19dc8e7ff57a51a6650b0c54ca7eb8 100644 --- a/panels/background/meson.build +++ b/panels/background/meson.build @@ -70,6 +70,7 @@ sources = common_sources + files( 'bg-wallpapers-source.c', 'cc-background-chooser.c', 'cc-background-item.c', + 'cc-background-paintable.c', 'cc-background-panel.c', 'cc-background-preview.c', 'cc-background-xml.c',