[Xfce4-commits] <xfdesktop:master> Don't cache the pixbufs in single workspace mode

Eric Koegel noreply at xfce.org
Fri Nov 1 08:44:01 CET 2013


Updating branch refs/heads/master
         to 160cb351381664faac01a0506d91fa46559e2bb6 (commit)
       from cec316ea5c7c4d241cabd778aed3bfcd8299ea95 (commit)

commit 160cb351381664faac01a0506d91fa46559e2bb6
Author: Eric Koegel <eric.koegel at gmail.com>
Date:   Fri Nov 1 10:41:48 2013 +0300

    Don't cache the pixbufs in single workspace mode
    
    While in single workspace mode there's no reason to cache any of
    the pixbufs since they won't change. This will lower the amount
    of memory used by xfdesktop and make the memory footprint similar
    to previous versions while in single workspace mode.

 src/xfce-backdrop.c  |   54 ++++++++++++++++++++++++++++++-
 src/xfce-backdrop.h  |    4 +++
 src/xfce-desktop.c   |   47 +++++++++++++++++++++------
 src/xfce-workspace.c |   87 ++++++++++++++++++++++++++++++++++++++++++++++++--
 src/xfce-workspace.h |    4 +++
 5 files changed, 183 insertions(+), 13 deletions(-)

diff --git a/src/xfce-backdrop.c b/src/xfce-backdrop.c
index 929c6ee..11b950c 100644
--- a/src/xfce-backdrop.c
+++ b/src/xfce-backdrop.c
@@ -95,6 +95,7 @@ struct _XfceBackdropPriv
 
     GdkPixbuf *pix;
     XfceBackdropImageData *image_data;
+    gboolean cache_pixbuf;
 
     XfceBackdropColorStyle color_style;
     GdkColor color1;
@@ -1246,6 +1247,47 @@ xfce_backdrop_get_random_order(XfceBackdrop *backdrop)
     return backdrop->priv->random_backdrop_order;
 }
 
+/**
+ * xfce_backdrop_set_cache_pixbuf:
+ * @backdrop: An #XfceBackdrop.
+ * @cache_pixbuf: When TRUE XfceBackdrop will keep a reference to the current
+ *                pixbuf until another one is set.
+ *
+ * XfceBackdrop can be set to keep a reference to the current backdrop and
+ * increment the reference count when xfce_backdrop_get_pixbuf is called.
+ * Setting cache_pixbuf to FALSE will cause xfce_backdrop_get_pixbuf to
+ * return XfceBackdrop's only reference and free any memory allocated. This
+ * will use less memory, especially when the backdrop isn't expected to change
+ * as in single workspace mode.
+ **/
+void
+xfce_backdrop_set_cache_pixbuf(XfceBackdrop *backdrop,
+                               gboolean cache_pixbuf)
+{
+    g_return_if_fail(XFCE_IS_BACKDROP(backdrop));
+
+    TRACE("entering");
+
+    if(backdrop->priv->cache_pixbuf == cache_pixbuf)
+        return;
+
+    backdrop->priv->cache_pixbuf = cache_pixbuf;
+
+    DBG("cache_pixbuf now %s", cache_pixbuf ? "TRUE" : "FALSE");
+
+    /* release any cached pixbuf now to save memory */
+    if(!cache_pixbuf)
+        xfce_backdrop_clear_cached_image(backdrop);
+}
+
+gboolean
+xfce_backdrop_get_cache_pixbuf(XfceBackdrop *backdrop)
+{
+    g_return_val_if_fail(XFCE_IS_BACKDROP(backdrop), FALSE);
+
+    return backdrop->priv->cache_pixbuf;
+}
+
 /* Generates the background that will either be displayed or will have the
  * image drawn on top of */
 static GdkPixbuf *
@@ -1317,9 +1359,19 @@ xfce_backdrop_get_pixbuf(XfceBackdrop *backdrop)
 {
     TRACE("entering");
 
-    if(backdrop->priv->pix)
+    if(backdrop->priv->pix && backdrop->priv->cache_pixbuf) {
+        /* return a reference so we can cache it */
         return g_object_ref(backdrop->priv->pix);
+    } else if(backdrop->priv->pix) {
+        /* We're not going to cache it so return our reference and set our
+         * pointer to NULL */
+        GdkPixbuf *pix = backdrop->priv->pix;
+        backdrop->priv->pix = NULL;
+
+        return pix;
+    }
 
+    /* !backdrop->priv->pix, call xfce_backdrop_generate_async */
     return NULL;
 }
 
diff --git a/src/xfce-backdrop.h b/src/xfce-backdrop.h
index 85707ae..3077a75 100644
--- a/src/xfce-backdrop.h
+++ b/src/xfce-backdrop.h
@@ -143,6 +143,10 @@ void xfce_backdrop_set_random_order      (XfceBackdrop *backdrop,
                                           gboolean random_order);
 gboolean xfce_backdrop_get_random_order  (XfceBackdrop *backdrop);
 
+void xfce_backdrop_set_cache_pixbuf      (XfceBackdrop *backdrop,
+                                          gboolean cache_pixbuf);
+gboolean xfce_backdrop_get_cache_pixbuf  (XfceBackdrop *backdrop);
+
 GdkPixbuf *xfce_backdrop_get_pixbuf      (XfceBackdrop *backdrop);
 
 void xfce_backdrop_generate_async        (XfceBackdrop *backdrop);
diff --git a/src/xfce-desktop.c b/src/xfce-desktop.c
index 4963851..e874a20 100644
--- a/src/xfce-desktop.c
+++ b/src/xfce-desktop.c
@@ -377,13 +377,6 @@ backdrop_changed_cb(XfceBackdrop *backdrop, gpointer user_data)
     if(desktop->priv->updates_frozen || !gtk_widget_get_realized(GTK_WIDGET(desktop)))
         return;
 
-    if(!GDK_IS_PIXMAP(pmap)) {
-        pmap = create_bg_pixmap(gscreen, desktop);
-
-        if(!GDK_IS_PIXMAP(pmap))
-            return;
-    }
-
     TRACE("really entering");
 
     current_workspace = xfce_desktop_get_current_workspace(desktop);
@@ -479,9 +472,27 @@ backdrop_changed_cb(XfceBackdrop *backdrop, gpointer user_data)
         /* create the backdrop if needed */
         if(!pix) {
             xfce_backdrop_generate_async(backdrop);
+
+            if(clip_region != NULL)
+                gdk_region_destroy(clip_region);
+
             return;
         }
 
+        /* Create the background pixmap if it isn't already */
+        if(!GDK_IS_PIXMAP(pmap)) {
+            pmap = create_bg_pixmap(gscreen, desktop);
+
+            if(!GDK_IS_PIXMAP(pmap)) {
+                g_object_unref(pix);
+
+                if(clip_region != NULL)
+                    gdk_region_destroy(clip_region);
+
+                return;
+            }
+        }
+
         cr = gdk_cairo_create(GDK_DRAWABLE(pmap));
         gdk_cairo_set_source_pixbuf(cr, pix, rect.x, rect.y);
 
@@ -520,9 +531,6 @@ screen_size_changed_cb(GdkScreen *gscreen, gpointer user_data)
 
     TRACE("entering");
 
-    if(!create_bg_pixmap(gscreen, desktop))
-        return;
-
     current_workspace = xfce_desktop_get_current_workspace(desktop);
 
     if(desktop->priv->nworkspaces <= current_workspace)
@@ -599,6 +607,11 @@ workspace_changed_cb(WnckScreen *wnck_screen,
 
     TRACE("entering");
 
+    /* Ignore workspace changes in single workspace mode so long as we
+     * already have the bg_pixmap loaded */
+    if(xfce_desktop_get_single_workspace_mode(desktop) && desktop->priv->bg_pixmap)
+        return;
+
     current_workspace = desktop->priv->current_workspace;
     new_workspace = xfce_desktop_get_current_workspace(desktop);
 
@@ -658,6 +671,10 @@ workspace_created_cb(WnckScreen *wnck_screen,
                                                                     desktop->priv->property_prefix,
                                                                     nlast_workspace);
 
+    /* Tell workspace whether to cache pixbufs */
+    xfce_workspace_set_cache_pixbufs(desktop->priv->workspaces[nlast_workspace],
+                                     !desktop->priv->single_workspace_mode);
+
     xfce_workspace_monitors_changed(desktop->priv->workspaces[nlast_workspace],
                                     desktop->priv->gscreen);
 
@@ -1486,6 +1503,8 @@ static void
 xfce_desktop_set_single_workspace_mode(XfceDesktop *desktop,
                                        gboolean single_workspace)
 {
+    gint i;
+
     g_return_if_fail(XFCE_IS_DESKTOP(desktop));
 
     if(single_workspace == desktop->priv->single_workspace_mode)
@@ -1495,6 +1514,14 @@ xfce_desktop_set_single_workspace_mode(XfceDesktop *desktop,
 
     DBG("single_workspace_mode now %s", single_workspace ? "TRUE" : "FALSE");
 
+    /* update the workspaces & backdrops if they should cache their pixbuf */
+    if(desktop->priv->workspaces) {
+        for(i = 0; i < desktop->priv->nworkspaces; i++) {
+            /* set cache to TRUE when single_workspace is FALSE */
+            xfce_workspace_set_cache_pixbufs(desktop->priv->workspaces[i], !single_workspace);
+        }
+    }
+
     /* If the desktop has been realized then fake a screen size change to
      * update the backdrop. There's no reason to if there's no desktop yet */
     if(gtk_widget_get_realized(GTK_WIDGET(desktop)))
diff --git a/src/xfce-workspace.c b/src/xfce-workspace.c
index 68339ef..0a9f84a 100644
--- a/src/xfce-workspace.c
+++ b/src/xfce-workspace.c
@@ -84,6 +84,7 @@ struct _XfceWorkspacePriv
     guint nbackdrops;
     gboolean xinerama_stretch;
     XfceBackdrop **backdrops;
+    gboolean cache_pixbufs;
 
     gulong *first_color_id;
     gulong *second_color_id;
@@ -118,6 +119,14 @@ static void xfce_workspace_remove_backdrops(XfceWorkspace *workspace);
 
 G_DEFINE_TYPE(XfceWorkspace, xfce_workspace, G_TYPE_OBJECT)
 
+
+/**
+ * xfce_workspace_get_xinerama_stretch:
+ * @workspace: An #XfceWorkspace.
+ *
+ * returns whether the first backdrop is set to spanning screens since it's
+ * the only backdrop where that setting is applicable.
+ **/
 gboolean
 xfce_workspace_get_xinerama_stretch(XfceWorkspace *workspace)
 {
@@ -215,6 +224,14 @@ backdrop_changed_cb(XfceBackdrop *backdrop, gpointer user_data)
     g_signal_emit(G_OBJECT(user_data), signals[WORKSPACE_BACKDROP_CHANGED], 0, backdrop);
 }
 
+/**
+ * xfce_workspace_set_workspace_num:
+ * @workspace: An #XfceWorkspace.
+ * @GdkScreen: screen the workspace is on.
+ *
+ * Updates the backdrops to correctly display the right settings since GTK/GDK
+ * uses monitor numbers rather than names.
+ **/
 void
 xfce_workspace_monitors_changed(XfceWorkspace *workspace,
                                 GdkScreen *gscreen)
@@ -564,6 +581,10 @@ xfce_workspace_connect_backdrop_settings(XfceWorkspace *workspace,
     if(xfce_backdrop_get_image_style(backdrop) == XFCE_BACKDROP_IMAGE_INVALID)
         xfce_workspace_migrate_backdrop_image_style(workspace, backdrop, monitor);
 
+    /* determine if the backdrop will be required to keep a ref of it's pixbuf
+     * when it generates one */
+    xfce_backdrop_set_cache_pixbuf(backdrop, workspace->priv->cache_pixbufs);
+
     g_free(monitor_name);
 }
 
@@ -644,6 +665,14 @@ xfce_workspace_get_workspace_num(XfceWorkspace *workspace)
     return workspace->priv->workspace_num;
 }
 
+/**
+ * xfce_workspace_set_workspace_num:
+ * @workspace: An #XfceWorkspace.
+ * @number: workspace number
+ *
+ * Identifies which workspace this is. Required for XfceWorkspace to get
+ * the correct xfconf settings for its backdrops.
+ **/
 void
 xfce_workspace_set_workspace_num(XfceWorkspace *workspace, gint number)
 {
@@ -652,10 +681,64 @@ xfce_workspace_set_workspace_num(XfceWorkspace *workspace, gint number)
     workspace->priv->workspace_num = number;
 }
 
+/**
+ * xfce_workspace_set_cache_pixbufs:
+ * @workspace: An #XfceWorkspace.
+ * @cache_pixbuf: When TRUE XfceWorkspace will have all it's backdrops keep
+ *                a reference to the current pixbuf.
+ *
+ * This function will control whether XfceWorkspace's backdrops keep a reference
+ * to their respective pixbufs or not. Setting it to TRUE is useful for the
+ * per-workspace-wallpapers, FALSE will save memory for single workspace mode.
+ **/
+void
+xfce_workspace_set_cache_pixbufs(XfceWorkspace *workspace,
+                                 gboolean cache_pixbuf)
+{
+    guint i;
+    guint n_monitors;
+
+    g_return_if_fail(XFCE_IS_WORKSPACE(workspace));
+
+    /* If nothing changed then avoid doing any work */
+    if(workspace->priv->cache_pixbufs == cache_pixbuf)
+        return;
+
+    workspace->priv->cache_pixbufs = cache_pixbuf;
+
+    DBG("cache_pixbuf now %s", cache_pixbuf ? "TRUE" : "FALSE");
+
+    n_monitors = gdk_screen_get_n_monitors(workspace->priv->gscreen);
+
+    /* update all the backdrops */
+    for(i = 0; i < n_monitors && i < workspace->priv->nbackdrops; ++i) {
+        xfce_backdrop_set_cache_pixbuf(workspace->priv->backdrops[i], cache_pixbuf);
+    }
+}
+
+gboolean
+xfce_workspace_get_cache_pixbufs(XfceWorkspace *workspace)
+{
+    g_return_val_if_fail(XFCE_IS_WORKSPACE(workspace), FALSE);
+
+    return workspace->priv->cache_pixbufs;
+}
+
+/**
+ * xfce_workspace_get_backdrop:
+ * @workspace: An #XfceWorkspace.
+ * @monitor: monitor number
+ *
+ * Returns the XfceBackdrop on the specified monitor. Returns NULL on an
+ * invalid monitor number.
+ **/
 XfceBackdrop *xfce_workspace_get_backdrop(XfceWorkspace *workspace,
                                           guint monitor)
 {
-    g_return_val_if_fail(XFCE_IS_WORKSPACE(workspace)
-                         && monitor < workspace->priv->nbackdrops, NULL);
+    g_return_val_if_fail(XFCE_IS_WORKSPACE(workspace), NULL);
+
+    if(monitor >= workspace->priv->nbackdrops)
+        return NULL;
+
     return workspace->priv->backdrops[monitor];
 }
diff --git a/src/xfce-workspace.h b/src/xfce-workspace.h
index df8e945..dc4c6b6 100644
--- a/src/xfce-workspace.h
+++ b/src/xfce-workspace.h
@@ -70,6 +70,10 @@ void xfce_workspace_monitors_changed(XfceWorkspace *workspace,
 
 gboolean xfce_workspace_get_xinerama_stretch(XfceWorkspace *workspace);
 
+void xfce_workspace_set_cache_pixbufs    (XfceWorkspace *workspace,
+                                          gboolean cache_pixbuf);
+gboolean xfce_workspace_get_cache_pixbufs(XfceWorkspace *workspace);
+
 XfceBackdrop *xfce_workspace_get_backdrop(XfceWorkspace *workspace,
                                           guint monitor);
 


More information about the Xfce4-commits mailing list