[gnome-flashback] desktop: add light or dark css class based on average color
- From: Alberts Muktupāvels <muktupavels src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-flashback] desktop: add light or dark css class based on average color
- Date: Tue, 26 Nov 2019 19:11:07 +0000 (UTC)
commit b73b78b510a582907243c0042e1081bdde540f13
Author: Alberts Muktupāvels <alberts muktupavels gmail com>
Date: Tue Nov 26 20:04:57 2019 +0200
desktop: add light or dark css class based on average color
gnome-flashback/libcommon/gf-background-utils.c | 6 ++
gnome-flashback/libcommon/gf-background-utils.h | 26 ++---
gnome-flashback/libdesktop/gf-background.c | 12 +--
gnome-flashback/libdesktop/gf-background.h | 4 +-
gnome-flashback/libdesktop/gf-desktop-window.c | 137 ++++++++++++++++--------
5 files changed, 120 insertions(+), 65 deletions(-)
---
diff --git a/gnome-flashback/libcommon/gf-background-utils.c b/gnome-flashback/libcommon/gf-background-utils.c
index f45bbfb..8a3a6ed 100644
--- a/gnome-flashback/libcommon/gf-background-utils.c
+++ b/gnome-flashback/libcommon/gf-background-utils.c
@@ -507,3 +507,9 @@ gf_background_surface_set_as_root (GdkDisplay *display,
gdk_x11_display_ungrab (display);
}
+
+GdkRGBA *
+gf_background_surface_get_average_color (cairo_surface_t *surface)
+{
+ return cairo_surface_get_user_data (surface, &average_color_key);
+}
diff --git a/gnome-flashback/libcommon/gf-background-utils.h b/gnome-flashback/libcommon/gf-background-utils.h
index a2c100e..229c5a6 100644
--- a/gnome-flashback/libcommon/gf-background-utils.h
+++ b/gnome-flashback/libcommon/gf-background-utils.h
@@ -22,18 +22,20 @@
G_BEGIN_DECLS
-cairo_surface_t *gf_background_surface_create (GdkDisplay *display,
- GnomeBG *bg,
- GdkWindow *window,
- int width,
- int height);
-
-cairo_surface_t *gf_background_surface_get_from_root (GdkDisplay *display,
- int width,
- int height);
-
-void gf_background_surface_set_as_root (GdkDisplay *display,
- cairo_surface_t *surface);
+cairo_surface_t *gf_background_surface_create (GdkDisplay *display,
+ GnomeBG *bg,
+ GdkWindow *window,
+ int width,
+ int height);
+
+cairo_surface_t *gf_background_surface_get_from_root (GdkDisplay *display,
+ int width,
+ int height);
+
+void gf_background_surface_set_as_root (GdkDisplay *display,
+ cairo_surface_t *surface);
+
+GdkRGBA *gf_background_surface_get_average_color (cairo_surface_t *surface);
G_END_DECLS
diff --git a/gnome-flashback/libdesktop/gf-background.c b/gnome-flashback/libdesktop/gf-background.c
index 869fbd2..0beacdf 100644
--- a/gnome-flashback/libdesktop/gf-background.c
+++ b/gnome-flashback/libdesktop/gf-background.c
@@ -446,14 +446,8 @@ gf_background_new (GtkWidget *window)
NULL);
}
-gboolean
-gf_background_is_dark (GfBackground *self)
+GdkRGBA *
+gf_background_get_average_color (GfBackground *self)
{
- int width;
- int height;
-
- width = gf_desktop_window_get_width (GF_DESKTOP_WINDOW (self->window));
- height = gf_desktop_window_get_height (GF_DESKTOP_WINDOW (self->window));
-
- return gnome_bg_is_dark (self->bg, width, height);
+ return gf_background_surface_get_average_color (self->surface);
}
diff --git a/gnome-flashback/libdesktop/gf-background.h b/gnome-flashback/libdesktop/gf-background.h
index 2aa466f..ba4192d 100644
--- a/gnome-flashback/libdesktop/gf-background.h
+++ b/gnome-flashback/libdesktop/gf-background.h
@@ -25,9 +25,9 @@ G_BEGIN_DECLS
#define GF_TYPE_BACKGROUND (gf_background_get_type ())
G_DECLARE_FINAL_TYPE (GfBackground, gf_background, GF, BACKGROUND, GObject)
-GfBackground *gf_background_new (GtkWidget *window);
+GfBackground *gf_background_new (GtkWidget *window);
-gboolean gf_background_is_dark (GfBackground *self);
+GdkRGBA *gf_background_get_average_color (GfBackground *self);
G_END_DECLS
diff --git a/gnome-flashback/libdesktop/gf-desktop-window.c b/gnome-flashback/libdesktop/gf-desktop-window.c
index bbb1b22..55fa234 100644
--- a/gnome-flashback/libdesktop/gf-desktop-window.c
+++ b/gnome-flashback/libdesktop/gf-desktop-window.c
@@ -45,6 +45,8 @@ struct _GfDesktopWindow
guint move_resize_id;
gboolean ready;
+
+ GdkRGBA *representative_color;
};
enum
@@ -128,40 +130,73 @@ get_representative_color (GfDesktopWindow *self,
return TRUE;
}
-static void
-update_representative_color (GfDesktopWindow *self)
+static gboolean
+color_is_dark (GdkRGBA *color)
{
- GdkRGBA color;
- GfIconView *icon_view;
-
- icon_view = GF_ICON_VIEW (self->icon_view);
+ double relative_luminance;
- if (icon_view == NULL)
- return;
+ /* CCIR 601 */
+ relative_luminance = 0.299 * color->red +
+ 0.587 * color->green +
+ 0.114 * color->blue;
- if (get_representative_color (self, &color))
- gf_icon_view_set_representative_color (icon_view, &color);
- else
- gf_icon_view_set_representative_color (icon_view, NULL);
+ return relative_luminance < 0.5;
}
static void
update_css_class (GfDesktopWindow *self)
{
- gboolean dark;
GtkStyleContext *context;
- dark = FALSE;
+ context = gtk_widget_get_style_context (GTK_WIDGET (self));
- if (self->background != NULL)
- dark = gf_background_is_dark (self->background);
+ if (self->representative_color != NULL)
+ {
+ if (color_is_dark (self->representative_color))
+ {
+ gtk_style_context_remove_class (context, "light");
+ gtk_style_context_add_class (context, "dark");
+ }
+ else
+ {
+ gtk_style_context_remove_class (context, "dark");
+ gtk_style_context_add_class (context, "light");
+ }
+ }
+ else
+ {
+ gtk_style_context_remove_class (context, "dark");
+ gtk_style_context_remove_class (context, "light");
+ }
+}
- context = gtk_widget_get_style_context (GTK_WIDGET (self));
+static void
+update_representative_color (GfDesktopWindow *self)
+{
+ g_clear_pointer (&self->representative_color, gdk_rgba_free);
+
+ if (self->background != NULL)
+ {
+ GdkRGBA *color;
- if (!dark)
- gtk_style_context_remove_class (context, "dark");
+ color = gf_background_get_average_color (self->background);
+ self->representative_color = gdk_rgba_copy (color);
+ }
else
- gtk_style_context_add_class (context, "dark");
+ {
+ GdkRGBA color;
+
+ if (get_representative_color (self, &color))
+ self->representative_color = gdk_rgba_copy (&color);
+ }
+
+ if (self->icon_view != NULL)
+ {
+ gf_icon_view_set_representative_color (GF_ICON_VIEW (self->icon_view),
+ self->representative_color);
+ }
+
+ update_css_class (self);
}
static void
@@ -179,7 +214,6 @@ ensure_surface (GfDesktopWindow *self)
self->height);
gtk_widget_queue_draw (widget);
- update_css_class (self);
}
static GdkFilterReturn
@@ -188,23 +222,43 @@ filter_func (GdkXEvent *xevent,
gpointer user_data)
{
XEvent *x;
- GdkAtom atom;
GfDesktopWindow *self;
+ GdkDisplay *display;
+ Display *xdisplay;
+ Atom pixmap_atom;
+ Atom color_atom;
x = (XEvent *) xevent;
if (x->type != PropertyNotify)
return GDK_FILTER_CONTINUE;
- atom = gdk_atom_intern_static_string ("_XROOTPMAP_ID");
+ self = GF_DESKTOP_WINDOW (user_data);
- if (x->xproperty.atom != gdk_x11_atom_to_xatom (atom))
- return GDK_FILTER_CONTINUE;
+ display = gtk_widget_get_display (GTK_WIDGET (self));
+ xdisplay = gdk_x11_display_get_xdisplay (display);
- self = GF_DESKTOP_WINDOW (user_data);
+ pixmap_atom = XInternAtom (xdisplay, "_XROOTPMAP_ID", False);
+ color_atom = XInternAtom (xdisplay,
+ "_GNOME_BACKGROUND_REPRESENTATIVE_COLORS",
+ False);
- g_clear_pointer (&self->surface, cairo_surface_destroy);
- ensure_surface (self);
+ if (x->xproperty.atom == pixmap_atom)
+ {
+ GdkScreen *screen;
+
+ screen = gtk_widget_get_screen (GTK_WIDGET (self));
+
+ if (!gdk_screen_is_composited (screen))
+ {
+ g_clear_pointer (&self->surface, cairo_surface_destroy);
+ ensure_surface (self);
+ }
+ }
+ else if (x->xproperty.atom != color_atom)
+ {
+ update_representative_color (self);
+ }
return GDK_FILTER_CONTINUE;
}
@@ -249,15 +303,9 @@ composited_changed_cb (GdkScreen *screen,
return;
if (gdk_screen_is_composited (screen))
- {
- remove_event_filter (self);
- g_clear_pointer (&self->surface, cairo_surface_destroy);
- }
+ g_clear_pointer (&self->surface, cairo_surface_destroy);
else
- {
- add_event_filter (self);
- ensure_surface (self);
- }
+ ensure_surface (self);
}
static void
@@ -281,7 +329,6 @@ static void
changed_cb (GfBackground *background,
GfDesktopWindow *self)
{
- update_css_class (self);
update_representative_color (self);
}
@@ -310,11 +357,11 @@ draw_background_changed (GfDesktopWindow *self)
screen = gtk_widget_get_screen (GTK_WIDGET (self));
+ add_event_filter (self);
+ update_representative_color (self);
+
if (!gdk_screen_is_composited (screen))
- {
- add_event_filter (self);
- ensure_surface (self);
- }
+ ensure_surface (self);
emit_ready (self);
}
@@ -328,7 +375,11 @@ show_icons_changed (GfDesktopWindow *self)
g_assert (self->icon_view == NULL);
self->icon_view = gf_icon_view_new ();
- update_representative_color (self);
+ if (self->representative_color != NULL)
+ {
+ gf_icon_view_set_representative_color (GF_ICON_VIEW (self->icon_view),
+ self->representative_color);
+ }
gtk_container_add (GTK_CONTAINER (self), self->icon_view);
gtk_widget_show (self->icon_view);
@@ -561,6 +612,8 @@ gf_desktop_window_finalize (GObject *object)
remove_event_filter (self);
g_clear_pointer (&self->surface, cairo_surface_destroy);
+ g_clear_pointer (&self->representative_color, gdk_rgba_free);
+
if (self->move_resize_id != 0)
{
g_source_remove (self->move_resize_id);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]