[gnome-flashback] libdesktop-background: rewrite background drawing



commit 4bc1c03b773393caf22fe8e1627ab672e151fe63
Author: Alberts Muktupāvels <alberts muktupavels gmail com>
Date:   Thu Sep 25 16:01:23 2014 +0300

    libdesktop-background: rewrite background drawing

 gnome-flashback/flashback-application.c            |    6 +-
 gnome-flashback/gnome-flashback.desktop.in         |    2 +
 gnome-flashback/libdesktop-background/Makefile.am  |    6 +-
 .../libdesktop-background/desktop-background.c     |  328 ++++++++++++++++++++
 .../libdesktop-background/desktop-background.h     |   47 +++
 .../libdesktop-background/desktop-window.c         |  303 ++++++++++++++++++
 .../libdesktop-background/desktop-window.h         |   47 +++
 .../flashback-desktop-background.c                 |  158 ----------
 .../flashback-desktop-background.h                 |   46 ---
 .../org.gnome.gnome-flashback.gschema.xml.in.in    |    8 +-
 10 files changed, 736 insertions(+), 215 deletions(-)
---
diff --git a/gnome-flashback/flashback-application.c b/gnome-flashback/flashback-application.c
index 3f3d6b0..dc5afda 100644
--- a/gnome-flashback/flashback-application.c
+++ b/gnome-flashback/flashback-application.c
@@ -19,7 +19,7 @@
 #include <gtk/gtk.h>
 #include "config.h"
 #include "flashback-application.h"
-#include "libdesktop-background/flashback-desktop-background.h"
+#include "libdesktop-background/desktop-background.h"
 #include "libdisplay-config/flashback-display-config.h"
 #include "libend-session-dialog/flashback-end-session-dialog.h"
 #include "libidle-monitor/meta-idle-monitor-dbus.h"
@@ -35,7 +35,7 @@
 struct _FlashbackApplicationPrivate {
        GSettings                  *settings;
 
-       FlashbackDesktopBackground *background;
+       DesktopBackground          *background;
        FlashbackDisplayConfig     *config;
        FlashbackEndSessionDialog  *dialog;
        MetaIdleMonitorDBus        *idle_monitor;
@@ -54,7 +54,7 @@ flashback_application_settings_changed (GSettings   *settings,
        if (key == NULL || g_strcmp0 (key, KEY_DESKTOP_BACKGROUND) == 0) {
                if (g_settings_get_boolean (settings, KEY_DESKTOP_BACKGROUND)) {
                        if (app->priv->background == NULL) {
-                               app->priv->background = flashback_desktop_background_new ();
+                               app->priv->background = desktop_background_new ();
                        }
                } else {
                        if (app->priv->background) {
diff --git a/gnome-flashback/gnome-flashback.desktop.in b/gnome-flashback/gnome-flashback.desktop.in
index 87ec702..9881665 100644
--- a/gnome-flashback/gnome-flashback.desktop.in
+++ b/gnome-flashback/gnome-flashback.desktop.in
@@ -4,3 +4,5 @@ Type=Application
 Exec=gnome-flashback
 OnlyShowIn=GNOME;
 NoDisplay=true
+X-GNOME-Autostart-Phase=Desktop
+X-GNOME-AutoRestart=true
diff --git a/gnome-flashback/libdesktop-background/Makefile.am 
b/gnome-flashback/libdesktop-background/Makefile.am
index caba574..0697cf9 100644
--- a/gnome-flashback/libdesktop-background/Makefile.am
+++ b/gnome-flashback/libdesktop-background/Makefile.am
@@ -7,8 +7,10 @@ AM_CPPFLAGS = \
        -DGNOME_DESKTOP_USE_UNSTABLE_API
 
 libdesktop_background_la_SOURCES = \
-       flashback-desktop-background.c \
-       flashback-desktop-background.h
+       desktop-background.c \
+       desktop-background.h \
+       desktop-window.c \
+       desktop-window.h
 
 libdesktop_background_la_LIBADD = \
        $(DESKTOP_BACKGROUND_LIBS)
diff --git a/gnome-flashback/libdesktop-background/desktop-background.c 
b/gnome-flashback/libdesktop-background/desktop-background.c
new file mode 100644
index 0000000..4d8e7b9
--- /dev/null
+++ b/gnome-flashback/libdesktop-background/desktop-background.c
@@ -0,0 +1,328 @@
+/*
+ * Copyright (C) 2014 Alberts Muktupāvels
+ *
+ * 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 3 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <gtk/gtk.h>
+#include <libgnome-desktop/gnome-bg.h>
+
+#include "desktop-window.h"
+#include "desktop-background.h"
+
+struct _DesktopBackgroundPrivate {
+       GnomeBG          *bg;
+       GnomeBGCrossfade *fade;
+
+       GSettings        *gnome_settings;
+       GSettings        *background_settings;
+
+       GtkWidget        *background;
+
+       cairo_surface_t  *surface;
+       int               width;
+       int               height;
+
+       guint             change_idle_id;
+};
+
+G_DEFINE_TYPE_WITH_PRIVATE (DesktopBackground, desktop_background, G_TYPE_OBJECT);
+
+static void
+free_fade (DesktopBackground *background)
+{
+       g_clear_object (&background->priv->fade);
+}
+
+static void
+free_surface (DesktopBackground *background)
+{
+       if (background->priv->surface != NULL) {
+               cairo_surface_destroy (background->priv->surface);
+               background->priv->surface = NULL;
+       }
+}
+
+static void
+background_unrealize (DesktopBackground *background)
+{
+       free_surface (background);
+
+       background->priv->width = 0;
+       background->priv->height = 0;
+}
+
+static void
+init_fade (DesktopBackground *background)
+{
+       DesktopBackgroundPrivate *priv;
+       gboolean                  fade;
+       GdkScreen                *screen;
+
+       priv = background->priv;
+       fade = g_settings_get_boolean (priv->background_settings, "fade");
+       screen = gdk_screen_get_default ();
+
+       if (!fade)
+               return;
+
+       if (priv->fade == NULL) {
+               GdkWindow *window = gtk_widget_get_window (priv->background);
+               int width = gdk_screen_get_width (screen);
+               int height = gdk_screen_get_height (screen);
+
+               if (width == gdk_window_get_width (window) && height == gdk_window_get_height (window)) {
+                       priv->fade = gnome_bg_crossfade_new (width, height);
+                       g_signal_connect_swapped (priv->fade, "finished", G_CALLBACK (free_fade), background);
+               }
+       }
+
+       if (priv->fade != NULL && !gnome_bg_crossfade_is_started (priv->fade)) {
+               cairo_surface_t *surface;
+
+               if (priv->surface == NULL) {
+                       surface = gnome_bg_get_surface_from_root (screen);
+               } else {
+                       surface = cairo_surface_reference (priv->surface);
+               }
+
+               gnome_bg_crossfade_set_start_surface (priv->fade, surface);
+               cairo_surface_destroy (surface);
+       }
+}
+
+static void
+background_ensure_realized (DesktopBackground *bg)
+{
+       int        width;
+       int        height;
+       GdkScreen *screen;
+       GdkWindow *window;
+
+       screen = gdk_screen_get_default ();
+       height = gdk_screen_get_height (screen);
+       width = gdk_screen_get_width (screen);
+
+       if (width == bg->priv->width && height == bg->priv->height)
+               return;
+
+       free_surface (bg);
+
+       window = gtk_widget_get_window (bg->priv->background);
+       bg->priv->surface = gnome_bg_create_surface (bg->priv->bg, window, width, height, TRUE);
+
+       bg->priv->width = width;
+       bg->priv->height = height;
+}
+
+static void
+on_fade_finished (GnomeBGCrossfade *fade,
+                  GdkWindow        *window,
+                  gpointer          user_data)
+{
+    DesktopBackground        *background;
+    DesktopBackgroundPrivate *priv;
+
+       background = DESKTOP_BACKGROUND (user_data);
+       priv = background->priv;
+
+       background_ensure_realized (background);
+
+       if (priv->surface != NULL)
+               gnome_bg_set_surface_as_root (gdk_window_get_screen (window), priv->surface);
+}
+
+static gboolean
+fade_to_surface (DesktopBackground *background,
+                 GdkWindow         *window,
+                 cairo_surface_t   *surface)
+{
+       DesktopBackgroundPrivate *priv;
+
+       priv = background->priv;
+
+       if (priv->fade == NULL || !gnome_bg_crossfade_set_end_surface (priv->fade, surface))
+               return FALSE;
+
+       if (!gnome_bg_crossfade_is_started (priv->fade)) {
+               gnome_bg_crossfade_start (priv->fade, window);
+               g_signal_connect (priv->fade, "finished", G_CALLBACK (on_fade_finished), background);
+       }
+
+       return gnome_bg_crossfade_is_started (priv->fade);
+}
+
+static void
+background_set_up (DesktopBackground *background)
+{
+       DesktopBackgroundPrivate *priv;
+       GdkWindow                *window;
+
+       priv = background->priv;
+
+       background_ensure_realized (background);
+
+       if (priv->surface == NULL)
+               return;
+
+       window = gtk_widget_get_window (priv->background);
+
+       if (!fade_to_surface (background, window, priv->surface)) {
+               cairo_pattern_t *pattern;
+
+               pattern = cairo_pattern_create_for_surface (priv->surface);
+               gdk_window_set_background_pattern (window, pattern);
+               cairo_pattern_destroy (pattern);
+
+               gnome_bg_set_surface_as_root (gdk_screen_get_default (), priv->surface);
+       }
+}
+
+static gboolean
+background_changed_cb (gpointer user_data)
+{
+       DesktopBackground *background = DESKTOP_BACKGROUND (user_data);
+
+       background->priv->change_idle_id = 0;
+
+       background_unrealize (background);
+       background_set_up (background);
+
+       gtk_widget_queue_draw (background->priv->background);
+
+       return G_SOURCE_REMOVE;
+}
+
+static void
+queue_background_change (DesktopBackground *background)
+{
+       DesktopBackgroundPrivate *priv;
+
+       priv = background->priv;
+
+       if (priv->change_idle_id != 0) {
+               g_source_remove (priv->change_idle_id);
+       }
+
+       priv->change_idle_id = g_idle_add (background_changed_cb, background);
+}
+
+static void
+desktop_background_changed (GnomeBG  *bg,
+                            gpointer  user_data)
+{
+       DesktopBackground *background = DESKTOP_BACKGROUND (user_data);
+
+       init_fade (background);
+       queue_background_change (background);
+}
+
+static void
+desktop_background_transitioned (GnomeBG  *bg,
+                                 gpointer  user_data)
+{
+       DesktopBackground *background = DESKTOP_BACKGROUND (user_data);
+
+       init_fade (background);
+       queue_background_change (background);
+}
+
+static gboolean
+desktop_background_change_event (GSettings *settings,
+                                 gpointer   keys,
+                                 gint       n_keys,
+                                 gpointer   user_data)
+{
+       DesktopBackground *background = DESKTOP_BACKGROUND (user_data);
+
+       gnome_bg_load_from_preferences (background->priv->bg, background->priv->gnome_settings);
+
+       return TRUE;
+}
+
+static void
+desktop_background_finalize (GObject *object)
+{
+       DesktopBackground        *background;
+       DesktopBackgroundPrivate *priv;
+
+       background = DESKTOP_BACKGROUND (object);
+       priv = background->priv;
+
+       g_signal_handlers_disconnect_by_func (priv->gnome_settings,
+                                             desktop_background_change_event,
+                                             background);
+
+       g_clear_object (&priv->bg);
+       g_clear_object (&priv->gnome_settings);
+
+       free_surface (background);
+       free_fade (background);
+
+       g_clear_object (&priv->gnome_settings);
+       g_clear_object (&priv->background_settings);
+
+       G_OBJECT_CLASS (desktop_background_parent_class)->finalize (object);
+}
+
+static void
+desktop_background_update (DesktopWindow *window,
+                           gpointer       user_data)
+{
+       DesktopBackground *background = DESKTOP_BACKGROUND (user_data);
+
+       queue_background_change (user_data);
+}
+
+static void
+desktop_background_init (DesktopBackground *background)
+{
+       DesktopBackgroundPrivate *priv;
+
+       priv = background->priv = desktop_background_get_instance_private (background);
+
+       priv->bg = gnome_bg_new ();
+       priv->gnome_settings = g_settings_new ("org.gnome.desktop.background");
+       priv->background_settings = g_settings_new ("org.gnome.gnome-flashback.desktop-background");
+
+       g_signal_connect (priv->bg, "changed",
+                         G_CALLBACK (desktop_background_changed), background);
+       g_signal_connect (priv->bg, "transitioned",
+                         G_CALLBACK (desktop_background_transitioned), background);
+
+       gnome_bg_load_from_preferences (priv->bg, priv->gnome_settings);
+
+       g_signal_connect (priv->gnome_settings, "change-event",
+                         G_CALLBACK (desktop_background_change_event), background);
+
+       priv->background = desktop_window_new ();
+       g_signal_connect (priv->background, "update",
+                         G_CALLBACK (desktop_background_update), background);
+
+       queue_background_change (background);
+}
+
+static void
+desktop_background_class_init (DesktopBackgroundClass *class)
+{
+       GObjectClass *object_class = G_OBJECT_CLASS (class);
+
+       object_class->finalize = desktop_background_finalize;
+}
+
+DesktopBackground *
+desktop_background_new (void)
+{
+       return DESKTOP_BACKGROUND (g_object_new (DESKTOP_BACKGROUND_TYPE, NULL));
+}
diff --git a/gnome-flashback/libdesktop-background/desktop-background.h 
b/gnome-flashback/libdesktop-background/desktop-background.h
new file mode 100644
index 0000000..bb763d9
--- /dev/null
+++ b/gnome-flashback/libdesktop-background/desktop-background.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2014 Alberts Muktupāvels
+ *
+ * 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 3 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 <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef DESKTOP_BACKGROUND_H
+#define DESKTOP_BACKGROUND_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define DESKTOP_BACKGROUND_TYPE     (desktop_background_get_type ())
+#define DESKTOP_BACKGROUND(o)       (G_TYPE_CHECK_INSTANCE_CAST ((o), DESKTOP_BACKGROUND_TYPE, 
DesktopBackground))
+#define DESKTOP_BACKGROUND_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), DESKTOP_BACKGROUND_TYPE, 
DesktopBackgroundClass))
+
+typedef struct _DesktopBackground        DesktopBackground;
+typedef struct _DesktopBackgroundClass   DesktopBackgroundClass;
+typedef struct _DesktopBackgroundPrivate DesktopBackgroundPrivate;
+
+struct _DesktopBackground {
+       GObject                   parent;
+       DesktopBackgroundPrivate *priv;
+};
+
+struct _DesktopBackgroundClass {
+    GObjectClass parent_class;
+};
+
+GType              desktop_background_get_type (void);
+DesktopBackground *desktop_background_new      (void);
+
+G_END_DECLS
+
+#endif
diff --git a/gnome-flashback/libdesktop-background/desktop-window.c 
b/gnome-flashback/libdesktop-background/desktop-window.c
new file mode 100644
index 0000000..2490490
--- /dev/null
+++ b/gnome-flashback/libdesktop-background/desktop-window.c
@@ -0,0 +1,303 @@
+/*
+ * Copyright (C) 2014 Alberts Muktupāvels
+ *
+ * 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 3 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <gdk/gdkx.h>
+#include <X11/Xatom.h>
+#include "desktop-window.h"
+
+struct _DesktopWindowPrivate {
+       gulong size_changed_id;
+       gulong monitors_changed_id;
+};
+
+G_DEFINE_TYPE_WITH_PRIVATE (DesktopWindow, desktop_window, GTK_TYPE_WINDOW);
+
+enum {
+       UPDATE_SIGNAL,
+       LAST_SIGNAL
+};
+
+static guint signals [LAST_SIGNAL] = { 0 };
+
+static Atom _NET_CLIENT_LIST = None;
+static Atom _NET_WM_WINDOW_TYPE = None;
+static Atom _NET_WM_WINDOW_TYPE_DESKTOP = None;
+
+static Window *
+get_windows (Display       *display,
+             unsigned long *items)
+{
+       Atom           type;
+       unsigned long  left;
+    unsigned char *list;
+    int            result;
+    int            format;
+
+       result = XGetWindowProperty (display, XDefaultRootWindow (display), _NET_CLIENT_LIST,
+                                    0L, 1024L, False, XA_WINDOW, &type, &format,
+                                    items, &left, &list);
+
+       if (result != Success)
+               return (Window *) 0;
+
+       return (Window *) list;
+}
+
+static gboolean
+is_desktop_window (Display *display,
+                   Window   window)
+{
+       Atom           type;
+       Atom          *atoms;
+       int            result;
+       int            format;
+       unsigned long  items;
+       unsigned long  left;
+       unsigned char *data;
+
+       result = XGetWindowProperty (display, window, _NET_WM_WINDOW_TYPE,
+                                    0L, 1L, False, XA_ATOM, &type, &format,
+                                    &items, &left, &data);
+
+       if (result != Success)
+               return FALSE;
+
+       atoms = (Atom *) data;
+
+       if (items && atoms[0] == _NET_WM_WINDOW_TYPE_DESKTOP) {
+               XFree (data);
+               return TRUE;
+       }
+
+       XFree (data);
+       return FALSE;
+}
+
+static Window *
+get_desktop_windows_list (Display       *display,
+                          unsigned long *items)
+{
+       Window        *list;
+       unsigned long  all_items;
+       int            i;
+       Window        *desktops;
+
+       *items = 0;
+       list = get_windows (display, &all_items);
+       desktops = g_new0 (Window, all_items);
+
+       for (i = 0; i < all_items; i++) {
+               if (is_desktop_window (display, list[i])) {
+                       desktops[(*items)++] = list[i];
+               }
+       }
+
+       return desktops;
+}
+
+static void
+desktop_window_ensure_below (GtkWidget *widget)
+{
+       GdkWindow     *our_desktop_window;
+       GdkWindow     *other_desktop_window;
+       GdkDisplay    *display;
+       Window        *list;
+       unsigned long  items;
+       int            i;
+
+       gdk_error_trap_push ();
+
+       our_desktop_window = gtk_widget_get_window (widget);
+       display = gdk_display_get_default ();
+       list = get_desktop_windows_list (gdk_x11_display_get_xdisplay (display), &items);
+
+       for (i = 0; i < items; i++) {
+               other_desktop_window = gdk_x11_window_foreign_new_for_display (display, list[i]);
+               if (other_desktop_window != our_desktop_window) {
+                       gdk_window_raise (other_desktop_window);
+               }
+       }
+
+       gdk_error_trap_pop_ignored ();
+
+       g_free (list);
+}
+
+static void
+desktop_window_screen_changed (GdkScreen *screen,
+                               gpointer   user_data)
+{
+       DesktopWindow *window;
+       gint           width;
+       gint           height;
+
+       window = DESKTOP_WINDOW (user_data);
+       width = gdk_screen_get_width (screen);
+       height = gdk_screen_get_height (screen);
+
+       g_object_set (window,
+                     "width-request", width,
+                     "height-request", height,
+                     NULL);
+
+       g_signal_emit (window, signals [UPDATE_SIGNAL], 0);
+}
+
+static void
+desktop_window_dispose (GObject *object)
+{
+       DesktopWindow        *window;
+       DesktopWindowPrivate *priv;
+       GdkScreen            *screen;
+
+       window = DESKTOP_WINDOW (object);
+       priv = window->priv;
+       screen = gdk_screen_get_default ();
+
+       if (priv->size_changed_id > 0) {
+               g_signal_handler_disconnect (screen, priv->size_changed_id);
+               priv->size_changed_id = 0;
+       }
+
+       if (priv->monitors_changed_id > 0) {
+               g_signal_handler_disconnect (screen, priv->monitors_changed_id);
+               priv->monitors_changed_id = 0;
+       }
+
+       G_OBJECT_CLASS (desktop_window_parent_class)->dispose (object);
+}
+
+static void
+desktop_window_relaize (GtkWidget *widget)
+{
+       GdkWindow *window;
+       GdkAtom    atom;
+
+       GTK_WIDGET_CLASS (desktop_window_parent_class)->realize (widget);
+
+       window = gtk_widget_get_window (widget);
+       atom = gdk_atom_intern ("_NET_WM_WINDOW_TYPE_DESKTOP", FALSE);
+       gdk_property_change (window,
+                            gdk_atom_intern ("_NET_WM_WINDOW_TYPE", FALSE),
+                            gdk_x11_xatom_to_atom (XA_ATOM), 32,
+                            GDK_PROP_MODE_REPLACE, (guchar *) &atom, 1);
+}
+
+static void
+desktop_window_unrelaize (GtkWidget *widget)
+{
+       GTK_WIDGET_CLASS (desktop_window_parent_class)->unrealize (widget);
+}
+
+static void
+desktop_window_map (GtkWidget *widget)
+{
+       GTK_WIDGET_CLASS (desktop_window_parent_class)->map (widget);
+
+       gdk_window_lower (gtk_widget_get_window (widget));
+}
+
+static void
+desktop_window_init (DesktopWindow *window)
+{
+       DesktopWindowPrivate *priv;
+       gint                  id;
+       GdkScreen            *screen;
+       Display              *display;
+
+       priv = window->priv = desktop_window_get_instance_private (window);
+       screen = gdk_screen_get_default ();
+       display = gdk_x11_display_get_xdisplay (gdk_display_get_default ());
+
+       id = g_signal_connect (screen, "monitors-changed",
+                              G_CALLBACK (desktop_window_screen_changed), window);
+       priv->monitors_changed_id = id;
+
+       id = g_signal_connect (screen, "size-changed",
+                              G_CALLBACK (desktop_window_screen_changed), window);
+       priv->size_changed_id = id;
+
+       desktop_window_screen_changed (screen, window);
+
+       _NET_CLIENT_LIST = XInternAtom (display, "_NET_CLIENT_LIST", False);
+       _NET_WM_WINDOW_TYPE = XInternAtom (display, "_NET_WM_WINDOW_TYPE", False);
+       _NET_WM_WINDOW_TYPE_DESKTOP = XInternAtom (display, "_NET_WM_WINDOW_TYPE_DESKTOP", False);
+}
+
+static gboolean
+desktop_window_configure_event (GtkWidget         *widget,
+                                GdkEventConfigure *event)
+{
+       if (GTK_WIDGET_CLASS (desktop_window_parent_class)->configure_event)
+               GTK_WIDGET_CLASS (desktop_window_parent_class)->configure_event (widget, event);
+
+       desktop_window_ensure_below (widget);
+
+       return TRUE;
+}
+
+static void
+desktop_window_class_init (DesktopWindowClass *class)
+{
+       GObjectClass   *object_class;
+       GtkWidgetClass *widget_class;
+
+       object_class = G_OBJECT_CLASS (class);
+       widget_class = GTK_WIDGET_CLASS (class);
+
+       object_class->dispose = desktop_window_dispose;
+
+       widget_class->realize = desktop_window_relaize;
+       widget_class->unrealize = desktop_window_unrelaize;
+       widget_class->map = desktop_window_map;
+       widget_class->configure_event = desktop_window_configure_event;
+
+       signals [UPDATE_SIGNAL] =
+               g_signal_new ("update",
+                             G_TYPE_FROM_CLASS (object_class),
+                             G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
+                             0,
+                             NULL,
+                             NULL,
+                             g_cclosure_marshal_VOID__VOID,
+                             G_TYPE_NONE,
+                             0);
+}
+
+GtkWidget *
+desktop_window_new (void)
+{
+       GObject   *object;
+       GtkWidget *widget;
+       GtkWindow *window;
+
+       object = g_object_new (DESKTOP_WINDOW_TYPE,
+                              "type", GTK_WINDOW_TOPLEVEL,
+                              "decorated", FALSE,
+                              "skip-pager-hint", TRUE,
+                              "skip-taskbar-hint", TRUE,
+                              "resizable", FALSE,
+                              "app-paintable", TRUE,
+                              NULL);
+       widget = GTK_WIDGET (object);
+       window = GTK_WINDOW (widget);
+
+       gtk_window_set_keep_below (window, TRUE);
+       gtk_window_present (window);
+
+       return widget;
+}
diff --git a/gnome-flashback/libdesktop-background/desktop-window.h 
b/gnome-flashback/libdesktop-background/desktop-window.h
new file mode 100644
index 0000000..5d62f98
--- /dev/null
+++ b/gnome-flashback/libdesktop-background/desktop-window.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2014 Alberts Muktupāvels
+ *
+ * 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 3 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 <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef DESKTOP_WINDOW_H
+#define DESKTOP_WINDOW_H
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define DESKTOP_WINDOW_TYPE     (desktop_window_get_type ())
+#define DESKTOP_WINDOW(o)       (G_TYPE_CHECK_INSTANCE_CAST ((o), DESKTOP_WINDOW_TYPE, DesktopWindow))
+#define DESKTOP_WINDOW_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), DESKTOP_WINDOW_TYPE, DesktopWindowClass))
+
+typedef struct _DesktopWindow        DesktopWindow;
+typedef struct _DesktopWindowClass   DesktopWindowClass;
+typedef struct _DesktopWindowPrivate DesktopWindowPrivate;
+
+struct _DesktopWindow {
+       GtkWindow             parent;
+       DesktopWindowPrivate *priv;
+};
+
+struct _DesktopWindowClass {
+       GtkWindowClass parent_class;
+};
+
+GType      desktop_window_get_type (void);
+GtkWidget *desktop_window_new      (void);
+
+G_END_DECLS
+
+#endif
diff --git a/gnome-flashback/org.gnome.gnome-flashback.gschema.xml.in.in 
b/gnome-flashback/org.gnome.gnome-flashback.gschema.xml.in.in
index ff0bd48..38ed32b 100644
--- a/gnome-flashback/org.gnome.gnome-flashback.gschema.xml.in.in
+++ b/gnome-flashback/org.gnome.gnome-flashback.gschema.xml.in.in
@@ -26,18 +26,14 @@
                        <_description>If set to true, then GNOME Flashback application will be used to show 
sound applet. This is same sound applet that used to be part of GNOME Control Center.</_description>
                </key>
 
-               <!--
-               <child name="background" schema="org.gnome.gnome-flashback.background"/>
-               -->
+               <child name="desktop-background" schema="org.gnome.gnome-flashback.desktop-background"/>
        </schema>
 
-       <!--
-       <schema id="org.gnome.gnome-flashback.background" path="/org/gnome/gnome-flashback/background/">
+       <schema id="org.gnome.gnome-flashback.desktop-background" 
path="/org/gnome/gnome-flashback/desktop-background/">
                <key name="fade" type="b">
                        <default>true</default>
                        <_summary>Fade the background on change</_summary>
                        <_description>If set to true, then fade effect will be used to change the desktop 
background.</_description>
                </key>
        </schema>
-       -->
 </schemalist>


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]