[Xfce4-commits] [apps/xfdashboard] 01/08: Add new X11 specific window tracker and window content classes

noreply at xfce.org noreply at xfce.org
Tue Apr 4 18:41:52 CEST 2017


This is an automated email from the git hooks/post-receive script.

nomad pushed a commit to branch master
in repository apps/xfdashboard.

commit db70887e50f7cec64f45ed6a5d6924738f33a625
Author: Stephan Haller <nomad at froevel.de>
Date:   Tue Apr 4 17:25:26 2017 +0200

    Add new X11 specific window tracker and window content classes
---
 libxfdashboard/x11/window-content-x11.c           | 2701 +++++++++++++++++++++
 libxfdashboard/x11/window-content-x11.h           |  111 +
 libxfdashboard/x11/window-tracker-monitor-x11.c   |  393 +++
 libxfdashboard/x11/window-tracker-monitor-x11.h   |   76 +
 libxfdashboard/x11/window-tracker-window-x11.c    | 1811 ++++++++++++++
 libxfdashboard/x11/window-tracker-window-x11.h    |   82 +
 libxfdashboard/x11/window-tracker-workspace-x11.c |  442 ++++
 libxfdashboard/x11/window-tracker-workspace-x11.h |   82 +
 libxfdashboard/x11/window-tracker-x11.c           | 1890 ++++++++++++++
 libxfdashboard/x11/window-tracker-x11.h           |   90 +
 10 files changed, 7678 insertions(+)

diff --git a/libxfdashboard/x11/window-content-x11.c b/libxfdashboard/x11/window-content-x11.c
new file mode 100644
index 0000000..81d2bcf
--- /dev/null
+++ b/libxfdashboard/x11/window-content-x11.c
@@ -0,0 +1,2701 @@
+/*
+ * window: A managed window of window manager
+ * 
+ * Copyright 2012-2017 Stephan Haller <nomad at froevel.de>
+ * 
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ * 
+ * 
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#define COGL_ENABLE_EXPERIMENTAL_API
+#define CLUTTER_ENABLE_EXPERIMENTAL_API
+
+#include <libxfdashboard/x11/window-content-x11.h>
+
+#include <glib/gi18n-lib.h>
+#include <clutter/x11/clutter-x11.h>
+#include <cogl/cogl-texture-pixmap-x11.h>
+#ifdef HAVE_XCOMPOSITE
+#include <X11/extensions/Xcomposite.h>
+#endif
+#ifdef HAVE_XDAMAGE
+#include <X11/extensions/Xdamage.h>
+#endif
+#include <gdk/gdkx.h>
+
+#include <libxfdashboard/window-content.h>
+#include <libxfdashboard/x11/window-tracker-window-x11.h>
+#include <libxfdashboard/application.h>
+#include <libxfdashboard/marshal.h>
+#include <libxfdashboard/stylable.h>
+#include <libxfdashboard/window-tracker.h>
+#include <libxfdashboard/enums.h>
+#include <libxfdashboard/compat.h>
+#include <libxfdashboard/debug.h>
+
+
+/* Definitions */
+typedef enum /*< skip,prefix=XFDASHBOARD_WINDOW_CONTENT_X11_WORKAROUND_MODE >*/
+{
+	XFDASHBOARD_WINDOW_CONTENT_X11_WORKAROUND_MODE_NONE=0,
+	XFDASHBOARD_WINDOW_CONTENT_X11_WORKAROUND_MODE_UNMINIMIZING,
+	XFDASHBOARD_WINDOW_CONTENT_X11_WORKAROUND_MODE_REMINIMIZING,
+	XFDASHBOARD_WINDOW_CONTENT_X11_WORKAROUND_MODE_DONE
+} XfdashboardWindowContentX11WorkaroundMode;
+
+/* Define this class in GObject system */
+static void _xfdashboard_window_content_clutter_content_iface_init(ClutterContentIface *iface);
+static void _xfdashboard_window_content_x11_stylable_iface_init(XfdashboardStylableInterface *iface);
+
+G_DEFINE_TYPE_WITH_CODE(XfdashboardWindowContentX11,
+						xfdashboard_window_content_x11,
+						XFDASHBOARD_TYPE_WINDOW_CONTENT,
+						G_IMPLEMENT_INTERFACE(CLUTTER_TYPE_CONTENT, _xfdashboard_window_content_clutter_content_iface_init)
+						G_IMPLEMENT_INTERFACE(XFDASHBOARD_TYPE_STYLABLE, _xfdashboard_window_content_x11_stylable_iface_init))
+
+/* Private structure - access only by public API if needed */
+#define XFDASHBOARD_WINDOW_CONTENT_X11_GET_PRIVATE(obj)                        \
+	(G_TYPE_INSTANCE_GET_PRIVATE((obj), XFDASHBOARD_TYPE_WINDOW_CONTENT_X11, XfdashboardWindowContentX11Private))
+
+struct _XfdashboardWindowContentX11Private
+{
+	/* Properties related */
+	XfdashboardWindowTrackerWindowX11			*window;
+	ClutterColor								*outlineColor;
+	gfloat										outlineWidth;
+	gboolean									isSuspended;
+	gboolean									includeWindowFrame;
+
+	gboolean									unmappedWindowIconXFill;
+	gboolean									unmappedWindowIconYFill;
+	gfloat										unmappedWindowIconXAlign;
+	gfloat										unmappedWindowIconYAlign;
+	gfloat										unmappedWindowIconXScale;
+	gfloat										unmappedWindowIconYScale;
+	XfdashboardAnchorPoint						unmappedWindowIconAnchorPoint;
+
+	gchar										*styleClasses;
+	gchar										*stylePseudoClasses;
+
+	/* Instance related */
+	gboolean									isFallback;
+	CoglTexture									*texture;
+	Window										xWindowID;
+	Pixmap										pixmap;
+#ifdef HAVE_XDAMAGE
+	Damage										damage;
+#endif
+
+	guint										suspendSignalID;
+	gboolean									isMapped;
+	gboolean									isAppSuspended;
+
+	XfdashboardWindowTracker					*windowTracker;
+	XfdashboardWindowContentX11WorkaroundMode	workaroundMode;
+	guint										workaroundStateSignalID;
+
+	gboolean									suspendAfterResumeOnIdle;
+};
+
+/* Properties */
+enum
+{
+	PROP_0,
+
+	PROP_WINDOW,
+
+	PROP_SUSPENDED,
+
+	PROP_OUTLINE_COLOR,
+	PROP_OUTLINE_WIDTH,
+
+	PROP_INCLUDE_WINDOW_FRAME,
+
+	PROP_UNMAPPED_WINDOW_ICON_X_FILL,
+	PROP_UNMAPPED_WINDOW_ICON_Y_FILL,
+	PROP_UNMAPPED_WINDOW_ICON_X_ALIGN,
+	PROP_UNMAPPED_WINDOW_ICON_Y_ALIGN,
+	PROP_UNMAPPED_WINDOW_ICON_X_SCALE,
+	PROP_UNMAPPED_WINDOW_ICON_Y_SCALE,
+	PROP_UNMAPPED_WINDOW_ICON_ANCHOR_POINT,
+
+	/* From interface: XfdashboardStylable */
+	PROP_STYLE_CLASSES,
+	PROP_STYLE_PSEUDO_CLASSES,
+
+	PROP_LAST
+};
+
+static GParamSpec* XfdashboardWindowContentX11Properties[PROP_LAST]={ 0, };
+
+/* IMPLEMENTATION: Private variables and methods */
+#define COMPOSITE_VERSION_MIN_MAJOR		0
+#define COMPOSITE_VERSION_MIN_MINOR		2
+
+#define WORKAROUND_UNMAPPED_WINDOW_XFCONF_PROP				"/enable-unmapped-window-workaround"
+#define DEFAULT_WORKAROUND_UNMAPPED_WINDOW					FALSE
+
+#define WINDOW_CONTENT_CREATION_PRIORITY_XFCONF_PROP		"/window-content-creation-priority"
+#define DEFAULT_WINDOW_CONTENT_X11_CREATION_PRIORITY		"immediate"
+
+struct _XfdashboardWindowContentX11PriorityMap
+{
+	const gchar		*name;
+	gint			priority;
+};
+typedef struct _XfdashboardWindowContentX11PriorityMap		XfdashboardWindowContentX11PriorityMap;
+
+static gboolean									_xfdashboard_window_content_x11_have_checked_extensions=FALSE;
+static gboolean									_xfdashboard_window_content_x11_have_composite_extension=FALSE;
+static gboolean									_xfdashboard_window_content_x11_have_damage_extension=FALSE;
+static int										_xfdashboard_window_content_x11_damage_event_base=0;
+
+static GHashTable*								_xfdashboard_window_content_x11_cache=NULL;
+static guint									_xfdashboard_window_content_x11_cache_shutdown_signal_id=0;
+
+static GList*									_xfdashboard_window_content_x11_resume_idle_queue=NULL;
+static guint									_xfdashboard_window_content_x11_resume_idle_id=0;
+static guint									_xfdashboard_window_content_x11_resume_shutdown_signal_id=0;
+
+static guint									_xfdashboard_window_content_x11_xfconf_priority_notify_id=0;
+static gint										_xfdashboard_window_content_x11_window_creation_priority=-1;
+static XfdashboardWindowContentX11PriorityMap	_xfdashboard_window_content_x11_window_creation_priority_map[]=
+												{
+													{ "immediate", -1 }, /* First entry is default value */
+													{ "high", G_PRIORITY_HIGH_IDLE },
+													{ "normal", G_PRIORITY_DEFAULT_IDLE },
+													{ "low", G_PRIORITY_LOW },
+													{ NULL, 0 },
+												};
+static guint									_xfdashboard_window_content_x11_window_creation_shutdown_signal_id=0;
+
+/* Forward declarations */
+static void _xfdashboard_window_content_x11_suspend(XfdashboardWindowContentX11 *self);
+static void _xfdashboard_window_content_x11_resume(XfdashboardWindowContentX11 *self);
+static gboolean _xfdashboard_window_content_x11_resume_on_idle(gpointer inUserData);
+
+/* Remove all entries from resume queue and release all allocated resources */
+static void _xfdashboard_window_content_x11_destroy_resume_queue(void)
+{
+	XfdashboardApplication					*application;
+	gint									queueSize;
+
+	/* Disconnect application "shutdown" signal handler */
+	if(_xfdashboard_window_content_x11_resume_shutdown_signal_id)
+	{
+		XFDASHBOARD_DEBUG(NULL, WINDOWS,
+							"Disconnecting shutdown signal handler %u because of resume queue destruction",
+							_xfdashboard_window_content_x11_resume_shutdown_signal_id);
+
+		application=xfdashboard_application_get_default();
+		g_signal_handler_disconnect(application, _xfdashboard_window_content_x11_resume_shutdown_signal_id);
+		_xfdashboard_window_content_x11_resume_shutdown_signal_id=0;
+	}
+
+	/* Remove idle source if available */
+	if(_xfdashboard_window_content_x11_resume_idle_id)
+	{
+		XFDASHBOARD_DEBUG(NULL, WINDOWS,
+							"Removing resume window content idle source with ID %u",
+							_xfdashboard_window_content_x11_resume_idle_id);
+
+		g_source_remove(_xfdashboard_window_content_x11_resume_idle_id);
+		_xfdashboard_window_content_x11_resume_idle_id=0;
+	}
+
+	/* Destroy resume-on-idle queue if available*/
+	if(_xfdashboard_window_content_x11_resume_idle_queue)
+	{
+		queueSize=g_list_length(_xfdashboard_window_content_x11_resume_idle_queue);
+		if(queueSize>0) g_warning(_("Destroying window content resume queue containing %d windows."), queueSize);
+#ifdef DEBUG
+		if(queueSize>0)
+		{
+			GList								*iter;
+			XfdashboardWindowContentX11			*content;
+			XfdashboardWindowTrackerWindow		*window;
+
+			for(iter=_xfdashboard_window_content_x11_resume_idle_queue; iter; iter=g_list_next(iter))
+			{
+				content=XFDASHBOARD_WINDOW_CONTENT_X11(iter->data);
+				window=xfdashboard_window_content_x11_get_window(content);
+				g_print("Window content in resume queue: Item %s@%p for window '%s'\n",
+							G_OBJECT_TYPE_NAME(content), content,
+							xfdashboard_window_tracker_window_get_name(window));
+			}
+		}
+#endif
+
+		XFDASHBOARD_DEBUG(NULL, WINDOWS, "Destroying window content resume queue");
+		g_list_free(_xfdashboard_window_content_x11_resume_idle_queue);
+		_xfdashboard_window_content_x11_resume_idle_queue=NULL;
+	}
+}
+
+/* Remove window content from resume on idle queue */
+static void _xfdashboard_window_content_x11_resume_on_idle_remove(XfdashboardWindowContentX11 *self)
+{
+	XfdashboardWindowContentX11Private		*priv;
+
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_CONTENT_X11(self));
+
+	priv=self->priv;
+
+	/* Remove window content from queue */
+	if(_xfdashboard_window_content_x11_resume_idle_queue)
+	{
+		GList								*queueEntry;
+
+		/* Lookup window content in queue and remove it from queue. If queue is empty
+		 * after removal, remove idle source also.
+		 */
+		queueEntry=g_list_find(_xfdashboard_window_content_x11_resume_idle_queue, self);
+		if(queueEntry)
+		{
+			/* Remove window content from queue */
+			_xfdashboard_window_content_x11_resume_idle_queue=g_list_delete_link(_xfdashboard_window_content_x11_resume_idle_queue, queueEntry);
+			XFDASHBOARD_DEBUG(self, WINDOWS,
+								"Removed queue entry %p for window '%s' because of releasing resources",
+								queueEntry,
+								xfdashboard_window_tracker_window_get_name(XFDASHBOARD_WINDOW_TRACKER_WINDOW(priv->window)));
+		}
+	}
+
+	/* If queue is empty remove idle source as well */
+	if(!_xfdashboard_window_content_x11_resume_idle_queue &&
+		_xfdashboard_window_content_x11_resume_idle_id)
+	{
+		XFDASHBOARD_DEBUG(self, WINDOWS,
+							"Removing idle source with ID %u because queue is empty",
+							_xfdashboard_window_content_x11_resume_idle_id);
+
+		g_source_remove(_xfdashboard_window_content_x11_resume_idle_id);
+		_xfdashboard_window_content_x11_resume_idle_id=0;
+	}
+}
+
+/* Add window content to resume on idle queue */
+static void _xfdashboard_window_content_x11_resume_on_idle_add(XfdashboardWindowContentX11 *self)
+{
+	XfdashboardWindowContentX11Private		*priv;
+
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_CONTENT_X11(self));
+
+	priv=self->priv;
+
+	XFDASHBOARD_DEBUG(self, WINDOWS,
+						"Using resume on idle for window '%s'",
+						xfdashboard_window_tracker_window_get_name(XFDASHBOARD_WINDOW_TRACKER_WINDOW(priv->window)));
+
+	/* Only add callback to resume window content if no one was added */
+	if(!g_list_find(_xfdashboard_window_content_x11_resume_idle_queue, self))
+	{
+		/* Queue window content for resume */
+		_xfdashboard_window_content_x11_resume_idle_queue=g_list_append(_xfdashboard_window_content_x11_resume_idle_queue, self);
+		XFDASHBOARD_DEBUG(self, WINDOWS,
+							"Queued window resume of '%s'",
+							xfdashboard_window_tracker_window_get_name(XFDASHBOARD_WINDOW_TRACKER_WINDOW(priv->window)));
+	}
+
+	/* Create idle source for resuming queued window contents but with
+	 * high priority to get window content created as soon as possible.
+	 */
+	if(_xfdashboard_window_content_x11_resume_idle_queue &&
+		!_xfdashboard_window_content_x11_resume_idle_id)
+	{
+		_xfdashboard_window_content_x11_resume_idle_id=clutter_threads_add_idle_full(_xfdashboard_window_content_x11_window_creation_priority,
+																				_xfdashboard_window_content_x11_resume_on_idle,
+																				NULL,
+																				NULL);
+		XFDASHBOARD_DEBUG(self, WINDOWS,
+							"Created idle source with ID %u with priority of %d because of new resume queue created for window resume of '%s'",
+							_xfdashboard_window_content_x11_resume_idle_id,
+							_xfdashboard_window_content_x11_window_creation_priority,
+							xfdashboard_window_tracker_window_get_name(XFDASHBOARD_WINDOW_TRACKER_WINDOW(priv->window)));
+	}
+
+	/* Connect to "shutdown" signal of application to clean up resume queue */
+	if(!_xfdashboard_window_content_x11_resume_shutdown_signal_id)
+	{
+		XfdashboardApplication			*application;
+
+		application=xfdashboard_application_get_default();
+		_xfdashboard_window_content_x11_resume_shutdown_signal_id=g_signal_connect(application,
+																				"shutdown-final",
+																				G_CALLBACK(_xfdashboard_window_content_x11_destroy_resume_queue),
+																				NULL);
+		XFDASHBOARD_DEBUG(self, WINDOWS,
+							"Connected to shutdown signal with handler ID %u for resume queue destruction",
+							_xfdashboard_window_content_x11_resume_shutdown_signal_id);
+	}
+}
+
+/* Value for window creation priority in xfconf has changed */
+static void _xfdashboard_window_content_x11_on_window_creation_priority_value_changed(XfconfChannel *inChannel,
+																					const gchar *inProperty,
+																					const GValue *inValue,
+																					gpointer inUserData)
+{
+	const gchar									*priorityValue;
+	XfdashboardWindowContentX11PriorityMap		*found;
+
+	g_return_if_fail(g_strcmp0(inProperty, WINDOW_CONTENT_CREATION_PRIORITY_XFCONF_PROP)==0);
+	g_return_if_fail(inValue && G_VALUE_HOLDS_STRING(inValue));
+
+	/* Determine priority from new value */
+	priorityValue=g_value_get_string(inValue);
+	found=_xfdashboard_window_content_x11_window_creation_priority_map;
+	while(found->name && g_strcmp0(priorityValue, found->name)!=0) found++;
+
+	/* Set default value if no match was found in priority map was found */
+	if(!found || !found->name)
+	{
+		/* Default value is the first one in mapping */
+		found=_xfdashboard_window_content_x11_window_creation_priority_map;
+
+		g_warning(_("Unknown value '%s' for property '%s' - defaulting to '%s' with priority of %d"),
+					priorityValue,
+					inProperty,
+					found->name,
+					found->priority);
+	}
+
+	/* Set priority */
+	if(found)
+	{
+		_xfdashboard_window_content_x11_window_creation_priority=found->priority;
+		XFDASHBOARD_DEBUG(NULL, WINDOWS,
+							"Setting window creation priority to '%s' with priority of %d",
+							found->name,
+							found->priority);
+	}
+}
+
+/* Disconnect signal handler for xfconf value change notification on window priority */
+static void _xfdashboard_window_content_x11_on_window_creation_priority_shutdown(void)
+{
+	XfdashboardApplication					*application;
+
+	/* Disconnect application "shutdown" signal handler */
+	if(_xfdashboard_window_content_x11_window_creation_shutdown_signal_id)
+	{
+		XFDASHBOARD_DEBUG(NULL, WINDOWS,
+							"Disconnecting shutdown signal handler %u for window creation priority value change notifications",
+							_xfdashboard_window_content_x11_window_creation_shutdown_signal_id);
+
+		application=xfdashboard_application_get_default();
+		g_signal_handler_disconnect(application, _xfdashboard_window_content_x11_window_creation_shutdown_signal_id);
+		_xfdashboard_window_content_x11_window_creation_shutdown_signal_id=0;
+	}
+
+	/* Disconnect property changed signal handler */
+	if(_xfdashboard_window_content_x11_xfconf_priority_notify_id)
+	{
+		XfconfChannel					*xfconfChannel;
+
+		XFDASHBOARD_DEBUG(NULL, WINDOWS,
+							"Disconnecting property changed signal handler %u for window creation priority value change notifications",
+							_xfdashboard_window_content_x11_xfconf_priority_notify_id);
+
+		xfconfChannel=xfdashboard_application_get_xfconf_channel(NULL);
+		g_signal_handler_disconnect(xfconfChannel, _xfdashboard_window_content_x11_xfconf_priority_notify_id);
+		_xfdashboard_window_content_x11_xfconf_priority_notify_id=0;
+	}
+}
+
+/* Check if we should workaround unmapped window for requested window and set up workaround */
+static void _xfdashboard_window_content_x11_on_workaround_state_changed(XfdashboardWindowContentX11 *self,
+																	gpointer inUserData)
+{
+	XfdashboardWindowContentX11Private		*priv;
+	XfdashboardWindowTrackerWindowState		windowState;
+
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_CONTENT_X11(self));
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_WINDOW_X11(inUserData));
+
+	priv=self->priv;
+
+	/* Handle state change of window */
+	windowState=xfdashboard_window_tracker_window_get_state(XFDASHBOARD_WINDOW_TRACKER_WINDOW(priv->window));
+
+	switch(priv->workaroundMode)
+	{
+		case XFDASHBOARD_WINDOW_CONTENT_X11_WORKAROUND_MODE_UNMINIMIZING:
+			/* Check if window is unminized now, then update content texture and
+			 * minimize window again.
+			 */
+			if(!(windowState & XFDASHBOARD_WINDOW_TRACKER_WINDOW_STATE_MINIMIZED))
+			{
+				if(priv->texture &&
+					priv->workaroundMode!=XFDASHBOARD_WINDOW_CONTENT_X11_WORKAROUND_MODE_NONE &&
+					priv->isMapped==TRUE)
+				{
+					/* Copy current texture as it might get inaccessible. If we copy it now
+					 * when can draw the last image known. If we can copy it successfully
+					 * replace current texture with the copied one.
+					 */
+					CoglPixelFormat			textureFormat;
+					guint					textureWidth;
+					guint					textureHeight;
+					gint					textureSize;
+					guint8					*textureData;
+
+					textureFormat=cogl_texture_get_format(priv->texture);
+					textureSize=cogl_texture_get_data(priv->texture, textureFormat, 0, NULL);
+					textureWidth=cogl_texture_get_width(priv->texture);
+					textureHeight=cogl_texture_get_height(priv->texture);
+					textureData=g_malloc(textureSize);
+					if(textureData)
+					{
+						CoglTexture			*copyTexture;
+						gint				copyTextureSize;
+#if COGL_VERSION_CHECK(1, 18, 0)
+						ClutterBackend		*backend;
+						CoglContext			*context;
+						CoglError			*error;
+#endif
+
+						/* Get texture data to copy */
+						copyTextureSize=cogl_texture_get_data(priv->texture, textureFormat, 0, textureData);
+						if(copyTextureSize)
+						{
+#if COGL_VERSION_CHECK(1, 18, 0)
+							error=NULL;
+
+							backend=clutter_get_default_backend();
+							context=clutter_backend_get_cogl_context(backend);
+							copyTexture=cogl_texture_2d_new_from_data(context,
+																		textureWidth,
+																		textureHeight,
+																		textureFormat,
+																		0,
+																		textureData,
+																		&error);
+
+							if(!copyTexture || error)
+							{
+								/* Show warning */
+								g_warning(_("Could not create copy of texture of mininized window '%s': %s"),
+											xfdashboard_window_tracker_window_get_name(XFDASHBOARD_WINDOW_TRACKER_WINDOW(priv->window)),
+											(error && error->message) ? error->message : _("Unknown error"));
+
+								/* Release allocated resources */
+								if(copyTexture)
+								{
+									cogl_object_unref(copyTexture);
+									copyTexture=NULL;
+								}
+
+								if(error)
+								{
+									cogl_error_free(error);
+									error=NULL;
+								}
+							}
+#else
+							copyTexture=cogl_texture_new_from_data(textureWidth,
+																	textureHeight,
+																	COGL_TEXTURE_NONE,
+																	textureFormat,
+																	textureFormat,
+																	0,
+																	textureData);
+							if(!copyTexture)
+							{
+								/* Show warning */
+								g_warning(_("Could not create copy of texture of mininized window '%s'"),
+											xfdashboard_window_tracker_window_get_name(XFDASHBOARD_WINDOW_TRACKER_WINDOW(priv->window)));
+							}
+#endif
+
+							if(copyTexture)
+							{
+								cogl_object_unref(priv->texture);
+								priv->texture=copyTexture;
+							}
+						}
+							else g_warning(_("Could not determine size of texture of minimized window '%s'"),
+											xfdashboard_window_tracker_window_get_name(XFDASHBOARD_WINDOW_TRACKER_WINDOW(priv->window)));
+					}
+						else
+						{
+							g_warning(_("Could not allocate memory for copy of texture of mininized window '%s'"),
+										xfdashboard_window_tracker_window_get_name(XFDASHBOARD_WINDOW_TRACKER_WINDOW(priv->window)));
+						}
+				}
+
+				xfdashboard_window_tracker_window_hide(XFDASHBOARD_WINDOW_TRACKER_WINDOW(priv->window));
+				priv->workaroundMode=XFDASHBOARD_WINDOW_CONTENT_X11_WORKAROUND_MODE_REMINIMIZING;
+			}
+			break;
+
+		case XFDASHBOARD_WINDOW_CONTENT_X11_WORKAROUND_MODE_REMINIMIZING:
+			/* Check if window is now minized again, so stop workaround and
+			 * disconnecting signals.
+			 */
+			if(windowState & XFDASHBOARD_WINDOW_TRACKER_WINDOW_STATE_MINIMIZED)
+			{
+				priv->workaroundMode=XFDASHBOARD_WINDOW_CONTENT_X11_WORKAROUND_MODE_DONE;
+				if(priv->workaroundStateSignalID)
+				{
+					g_signal_handler_disconnect(priv->windowTracker, priv->workaroundStateSignalID);
+					priv->workaroundStateSignalID=0;
+				}
+			}
+			break;
+
+		default:
+			/* We should never get here but if we do it is more or less
+			 * a critical error. Ensure that window is minimized (again)
+			 * and stop xfdashboard.
+			 */
+			xfdashboard_window_tracker_window_hide(XFDASHBOARD_WINDOW_TRACKER_WINDOW(priv->window));
+			g_assert_not_reached();
+			break;
+	}
+}
+
+static void _xfdashboard_window_content_x11_setup_workaround(XfdashboardWindowContentX11 *self, XfdashboardWindowTrackerWindowX11 *inWindow)
+{
+	XfdashboardWindowContentX11Private		*priv;
+	gboolean								doWorkaround;
+	XfdashboardWindowTrackerWindowState		windowState;
+
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_CONTENT_X11(self));
+	g_return_if_fail(inWindow!=NULL && XFDASHBOARD_IS_WINDOW_TRACKER_WINDOW_X11(inWindow));
+
+	priv=self->priv;
+
+	/* Check if should workaround unmapped windows at all */
+	doWorkaround=xfconf_channel_get_bool(xfdashboard_application_get_xfconf_channel(NULL),
+											WORKAROUND_UNMAPPED_WINDOW_XFCONF_PROP,
+											DEFAULT_WORKAROUND_UNMAPPED_WINDOW);
+	if(!doWorkaround) return;
+
+	/* Only workaround unmapped windows */
+	windowState=xfdashboard_window_tracker_window_get_state(XFDASHBOARD_WINDOW_TRACKER_WINDOW(inWindow));
+	if(!(windowState & XFDASHBOARD_WINDOW_TRACKER_WINDOW_STATE_MINIMIZED)) return;
+
+	/* Check if workaround is already set up */
+	if(priv->workaroundMode!=XFDASHBOARD_WINDOW_CONTENT_X11_WORKAROUND_MODE_NONE) return;
+
+	/* Set flag that workaround is (going to be) set up */
+	priv->workaroundMode=XFDASHBOARD_WINDOW_CONTENT_X11_WORKAROUND_MODE_UNMINIMIZING;
+
+	/* The workaround is as follows:
+	 *
+	 * 1.) Set up signal handlers to get notified about changes of window
+	 * 2.) Unminimize window
+	 * 3.) If window is visible it will be activated by design, so reactivate
+	 *     last active window
+	 * 4.) Minimize window again
+	 * 5.) Stop watching for changes of window by disconnecting signal handlers
+	 */
+	priv->workaroundStateSignalID=g_signal_connect_swapped(priv->windowTracker,
+															"window-state-changed",
+															G_CALLBACK(_xfdashboard_window_content_x11_on_workaround_state_changed),
+															self);
+	xfdashboard_window_tracker_window_show(XFDASHBOARD_WINDOW_TRACKER_WINDOW(inWindow));
+}
+
+/* Check extension and set up basics */
+static void _xfdashboard_window_content_x11_check_extension(void)
+{
+	Display		*display G_GNUC_UNUSED;
+#ifdef HAVE_XDAMAGE
+	int			damageError=0;
+#endif
+#ifdef HAVE_XCOMPOSITE
+	int			compositeMajor, compositeMinor;
+#endif
+
+	/* Check if we have already checked extensions */
+	if(_xfdashboard_window_content_x11_have_checked_extensions!=FALSE) return;
+
+	/* Mark that we have check for extensions regardless of any error*/
+	_xfdashboard_window_content_x11_have_checked_extensions=TRUE;
+
+	/* Get display */
+	display=clutter_x11_get_default_display();
+
+	/* Check for composite extenstion */
+	_xfdashboard_window_content_x11_have_composite_extension=FALSE;
+#ifdef HAVE_XCOMPOSITE
+	if(clutter_x11_has_composite_extension())
+	{
+		compositeMajor=compositeMinor=0;
+		if(XCompositeQueryVersion(display, &compositeMajor, &compositeMinor))
+		{
+			if(compositeMajor>=COMPOSITE_VERSION_MIN_MAJOR && compositeMinor>=COMPOSITE_VERSION_MIN_MINOR)
+			{
+				_xfdashboard_window_content_x11_have_composite_extension=TRUE;
+			}
+				else
+				{
+					g_warning(_("Need at least version %d.%d of composite extension but found %d.%d - using only fallback images"),
+								COMPOSITE_VERSION_MIN_MAJOR, COMPOSITE_VERSION_MIN_MINOR, compositeMajor, compositeMinor);
+				}
+		}
+			else g_warning(_("Query for X composite extension failed - using only fallback imagess"));
+	}
+		else g_warning(_("X does not support composite extension - using only fallback images"));
+#endif
+
+	/* Get base of damage event in X */
+	_xfdashboard_window_content_x11_have_damage_extension=FALSE;
+	_xfdashboard_window_content_x11_damage_event_base=0;
+
+#ifdef HAVE_XDAMAGE
+	if(!XDamageQueryExtension(display, &_xfdashboard_window_content_x11_damage_event_base, &damageError))
+	{
+		g_warning(_("Query for X damage extension resulted in error code %d - using only still images of windows"), damageError);
+	}
+		else _xfdashboard_window_content_x11_have_damage_extension=TRUE;
+#endif
+}
+
+/* Suspension state of application changed */
+static void _xfdashboard_window_content_x11_on_application_suspended_changed(XfdashboardWindowContentX11 *self,
+																			GParamSpec *inSpec,
+																			gpointer inUserData)
+{
+	XfdashboardWindowContentX11Private		*priv;
+	XfdashboardApplication					*app;
+
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_CONTENT_X11(self));
+	g_return_if_fail(XFDASHBOARD_IS_APPLICATION(inUserData));
+
+	priv=self->priv;
+	app=XFDASHBOARD_APPLICATION(inUserData);
+
+	/* Get application suspend state */
+	priv->isAppSuspended=xfdashboard_application_is_suspended(app);
+
+	/* If application is suspended then suspend this window too ... */
+	if(priv->isAppSuspended)
+	{
+		_xfdashboard_window_content_x11_suspend(self);
+	}
+		/* ... otherwise resume window if it is mapped */
+		else
+		{
+			if(priv->isMapped) _xfdashboard_window_content_x11_resume(self);
+		}
+}
+
+/* Filter X events for damages */
+static ClutterX11FilterReturn _xfdashboard_window_content_x11_on_x_event(XEvent *inXEvent, ClutterEvent *inEvent, gpointer inUserData)
+{
+	XfdashboardWindowContentX11				*self;
+	XfdashboardWindowContentX11Private		*priv;
+
+	g_return_val_if_fail(XFDASHBOARD_IS_WINDOW_CONTENT_X11(inUserData), CLUTTER_X11_FILTER_CONTINUE);
+
+	self=XFDASHBOARD_WINDOW_CONTENT_X11(inUserData);
+	priv=self->priv;
+
+	/* Check for mapped, unmapped related X events as pixmap, damage, texture etc.
+	 * needs to get resumed (acquired) or suspended (released)
+	 */
+	if(inXEvent->xany.window==priv->xWindowID)
+	{
+		switch(inXEvent->type)
+		{
+			case MapNotify:
+			case ConfigureNotify:
+				priv->isMapped=TRUE;
+				if(!priv->isAppSuspended) _xfdashboard_window_content_x11_resume(self);
+				break;
+
+			case UnmapNotify:
+			case DestroyNotify:
+				priv->isMapped=FALSE;
+				_xfdashboard_window_content_x11_suspend(self);
+				break;
+
+			default:
+				/* We do not handle this type of X event, drop through ... */
+				break;
+		}
+	}
+
+	/* Check for damage event */
+#ifdef HAVE_XDAMAGE
+	if(_xfdashboard_window_content_x11_have_damage_extension &&
+		_xfdashboard_window_content_x11_damage_event_base &&
+		inXEvent->type==(_xfdashboard_window_content_x11_damage_event_base + XDamageNotify) &&
+		((XDamageNotifyEvent*)inXEvent)->damage==priv->damage &&
+		priv->workaroundMode==XFDASHBOARD_WINDOW_CONTENT_X11_WORKAROUND_MODE_NONE)
+	{
+		/* Update texture for live window content */
+		clutter_content_invalidate(CLUTTER_CONTENT(self));
+	}
+#endif
+
+	return(CLUTTER_X11_FILTER_CONTINUE);
+}
+
+/* Release all resources used by this instance */
+static void _xfdashboard_window_content_x11_release_resources(XfdashboardWindowContentX11 *self)
+{
+	XfdashboardWindowContentX11Private		*priv;
+	Display									*display;
+	gint									trapError;
+
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_CONTENT_X11(self));
+
+	priv=self->priv;
+
+	/* This live update will be suspended so remove it from queue */
+	_xfdashboard_window_content_x11_resume_on_idle_remove(self);
+
+	/* Get display as it used more than once ;) */
+	display=clutter_x11_get_default_display();
+
+	/* Release resources. It might be important to release them
+	 * in reverse order as they were created.
+	 */
+	clutter_x11_remove_filter(_xfdashboard_window_content_x11_on_x_event, (gpointer)self);
+
+	clutter_x11_trap_x_errors();
+	{
+		if(priv->texture)
+		{
+			cogl_object_unref(priv->texture);
+			priv->texture=NULL;
+		}
+
+#ifdef HAVE_XDAMAGE
+		if(priv->damage!=None)
+		{
+			XDamageDestroy(display, priv->damage);
+			XSync(display, False);
+			priv->damage=None;
+		}
+#endif
+		if(priv->pixmap!=None)
+		{
+			XFreePixmap(display, priv->pixmap);
+			priv->pixmap=None;
+		}
+
+		if(priv->xWindowID!=None)
+		{
+#ifdef HAVE_XCOMPOSITE
+			if(_xfdashboard_window_content_x11_have_composite_extension)
+			{
+				XCompositeUnredirectWindow(display, priv->xWindowID, CompositeRedirectAutomatic);
+				XSync(display, False);
+			}
+#endif
+			priv->xWindowID=None;
+		}
+
+		/* Window is suspended now */
+		if(priv->isSuspended!=TRUE)
+		{
+			priv->isSuspended=TRUE;
+
+			/* Notify about property change */
+			g_object_notify_by_pspec(G_OBJECT(self), XfdashboardWindowContentX11Properties[PROP_SUSPENDED]);
+		}
+	}
+
+	/* Check if everything went well */
+	trapError=clutter_x11_untrap_x_errors();
+	if(trapError!=0)
+	{
+		XFDASHBOARD_DEBUG(self, WINDOWS,
+							"X error %d occured while releasing resources for window '%s'",
+							trapError,
+							xfdashboard_window_tracker_window_get_name(XFDASHBOARD_WINDOW_TRACKER_WINDOW(priv->window)),
+							self);
+		return;
+	}
+
+	XFDASHBOARD_DEBUG(self, WINDOWS,
+						"Released resources for window '%s' to handle live texture updates",
+						xfdashboard_window_tracker_window_get_name(XFDASHBOARD_WINDOW_TRACKER_WINDOW(priv->window)));
+}
+
+/* Suspend from handling live updates */
+static void _xfdashboard_window_content_x11_suspend(XfdashboardWindowContentX11 *self)
+{
+	XfdashboardWindowContentX11Private		*priv;
+	Display									*display;
+	gint									trapError;
+
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_CONTENT_X11(self));
+
+	priv=self->priv;
+
+	/* This live update will be suspended so remove it from queue */
+	_xfdashboard_window_content_x11_resume_on_idle_remove(self);
+
+	/* Get display as it used more than once ;) */
+	display=clutter_x11_get_default_display();
+
+	/* Release resources */
+	clutter_x11_trap_x_errors();
+	{
+		/* Suspend live updates from texture */
+		if(priv->texture && !priv->isFallback)
+		{
+#ifdef HAVE_XDAMAGE
+			cogl_texture_pixmap_x11_set_damage_object(COGL_TEXTURE_PIXMAP_X11(priv->texture), 0, 0);
+#endif
+		}
+
+		/* Release damage */
+#ifdef HAVE_XDAMAGE
+		if(priv->damage!=None)
+		{
+			XDamageDestroy(display, priv->damage);
+			XSync(display, False);
+			priv->damage=None;
+		}
+#endif
+
+		/* Release pixmap */
+		if(priv->pixmap!=None)
+		{
+			XFreePixmap(display, priv->pixmap);
+			priv->pixmap=None;
+		}
+
+		/* Window is suspended now */
+		if(priv->isSuspended!=TRUE)
+		{
+			priv->isSuspended=TRUE;
+
+			/* Notify about property change */
+			g_object_notify_by_pspec(G_OBJECT(self), XfdashboardWindowContentX11Properties[PROP_SUSPENDED]);
+		}
+	}
+
+	/* Check if everything went well */
+	trapError=clutter_x11_untrap_x_errors();
+	if(trapError!=0)
+	{
+		XFDASHBOARD_DEBUG(self, WINDOWS,
+							"X error %d occured while suspending '%s",
+							trapError,
+							xfdashboard_window_tracker_window_get_name(XFDASHBOARD_WINDOW_TRACKER_WINDOW(priv->window)));
+		return;
+	}
+
+	XFDASHBOARD_DEBUG(self, WINDOWS,
+						"Successfully suspended live texture updates for window '%s'",
+						xfdashboard_window_tracker_window_get_name(XFDASHBOARD_WINDOW_TRACKER_WINDOW(priv->window)));
+}
+
+/* Resume to handle live window updates */
+static gboolean _xfdashboard_window_content_x11_resume_on_idle(gpointer inUserData)
+{
+	XfdashboardWindowContentX11				*self;
+	XfdashboardWindowContentX11Private		*priv;
+	GList									*queueEntry;
+	Display									*display;
+	CoglContext								*context;
+	GError									*error;
+	gint									trapError;
+	CoglTexture								*windowTexture;
+	gboolean								doContinueSource;
+
+	error=NULL;
+	windowTexture=NULL;
+
+	/* Get window content object from first entry in queue and remove it from queue */
+	queueEntry=g_list_first(_xfdashboard_window_content_x11_resume_idle_queue);
+	if(!queueEntry)
+	{
+		g_warning(_("Resume handler called for empty queue."));
+
+		/* Queue must be empty but ensure it will */
+		if(_xfdashboard_window_content_x11_resume_idle_queue)
+		{
+			XFDASHBOARD_DEBUG(NULL, WINDOWS, "Ensuring that window content resume queue is empty");
+			g_list_free(_xfdashboard_window_content_x11_resume_idle_queue);
+			_xfdashboard_window_content_x11_resume_idle_queue=NULL;
+		}
+
+		/* Queue must be empty so remove idle source */
+		_xfdashboard_window_content_x11_resume_idle_id=0;
+		return(G_SOURCE_REMOVE);
+	}
+
+	self=XFDASHBOARD_WINDOW_CONTENT_X11(queueEntry->data);
+	priv=self->priv;
+	XFDASHBOARD_DEBUG(self, WINDOWS,
+						"Entering idle source with ID %u for window resume of '%s'",
+						_xfdashboard_window_content_x11_resume_idle_id,
+						xfdashboard_window_tracker_window_get_name(XFDASHBOARD_WINDOW_TRACKER_WINDOW(priv->window)));
+
+	XFDASHBOARD_DEBUG(self, WINDOWS,
+						"Removing queued entry %p for window resume of '%s'@%p",
+						queueEntry,
+						xfdashboard_window_tracker_window_get_name(XFDASHBOARD_WINDOW_TRACKER_WINDOW(priv->window)));
+	_xfdashboard_window_content_x11_resume_idle_queue=g_list_delete_link(_xfdashboard_window_content_x11_resume_idle_queue, queueEntry);
+	if(_xfdashboard_window_content_x11_resume_idle_queue)
+	{
+		doContinueSource=G_SOURCE_CONTINUE;
+	}
+		else
+		{
+			XFDASHBOARD_DEBUG(self, WINDOWS,
+								"Resume idle source with ID %u will be remove because queue is empty",
+								_xfdashboard_window_content_x11_resume_idle_id);
+
+			doContinueSource=G_SOURCE_REMOVE;
+			_xfdashboard_window_content_x11_resume_idle_id=0;
+		}
+
+
+	/* We need at least the X composite extension to display images of windows
+	 * if still images or live updated ones
+	 */
+	if(!_xfdashboard_window_content_x11_have_composite_extension)
+	{
+		return(doContinueSource);
+	}
+
+	/* Get display as it used more than once ;) */
+	display=clutter_x11_get_default_display();
+
+	/* Set up resources */
+	clutter_x11_trap_x_errors();
+	while(1)
+	{
+#ifdef HAVE_XCOMPOSITE
+		/* Get pixmap to render texture for */
+		priv->pixmap=XCompositeNameWindowPixmap(display, priv->xWindowID);
+		XSync(display, False);
+		if(priv->pixmap==None)
+		{
+			g_warning(_("Could not get pixmap for window '%s"), xfdashboard_window_tracker_window_get_name(XFDASHBOARD_WINDOW_TRACKER_WINDOW(priv->window)));
+
+			/* Set flag to suspend window content after resuming because of error */
+			priv->suspendAfterResumeOnIdle=TRUE;
+			break;
+		}
+#else
+		/* We should never get here as existance of composite extension was checked before */
+		g_critical(_("Cannot resume window '%s' as composite extension is not available"),
+					xfdashboard_window_tracker_window_get_name(XFDASHBOARD_WINDOW_TRACKER_WINDOW(priv->window)));
+		break;
+#endif
+
+		/* Create cogl X11 texture for live updates */
+		context=clutter_backend_get_cogl_context(clutter_get_default_backend());
+		windowTexture=COGL_TEXTURE(cogl_texture_pixmap_x11_new(context, priv->pixmap, FALSE, &error));
+		if(!windowTexture || error)
+		{
+			/* Creating texture may fail if window is _NOT_ on active workspace
+			 * so display error message just as debug message (this time)
+			 */
+			XFDASHBOARD_DEBUG(self, WINDOWS,
+								"Could not create texture for window '%s': %s",
+								xfdashboard_window_tracker_window_get_name(XFDASHBOARD_WINDOW_TRACKER_WINDOW(priv->window)),
+								error ? error->message : _("Unknown error"));
+			if(error)
+			{
+				g_error_free(error);
+				error=NULL;
+			}
+
+			if(windowTexture)
+			{
+				cogl_object_unref(windowTexture);
+				windowTexture=NULL;
+			}
+
+			/* Set flag to suspend window content after resuming because of error */
+			priv->suspendAfterResumeOnIdle=TRUE;
+
+			break;
+		}
+
+		/* Set up damage to get notified about changed in pixmap */
+#ifdef HAVE_XDAMAGE
+		if(_xfdashboard_window_content_x11_have_damage_extension)
+		{
+			priv->damage=XDamageCreate(display, priv->pixmap, XDamageReportBoundingBox);
+			XSync(display, False);
+			if(priv->damage==None)
+			{
+				g_warning(_("Could not create damage for window '%s' - using still image of window"), xfdashboard_window_tracker_window_get_name(XFDASHBOARD_WINDOW_TRACKER_WINDOW(priv->window)));
+			}
+		}
+#endif
+
+		/* Release old texture (should be the fallback texture) and set new texture */
+		if(priv->texture)
+		{
+			cogl_object_unref(priv->texture);
+			priv->texture=windowTexture;
+		}
+
+		/* Set damage to new window texture */
+#ifdef HAVE_XDAMAGE
+		if(_xfdashboard_window_content_x11_have_damage_extension &&
+			priv->damage!=None)
+		{
+			cogl_texture_pixmap_x11_set_damage_object(COGL_TEXTURE_PIXMAP_X11(priv->texture), priv->damage, COGL_TEXTURE_PIXMAP_X11_DAMAGE_BOUNDING_BOX);
+		}
+#endif
+
+		/* Now we use the window as texture and not the fallback texture anymore */
+		priv->isFallback=FALSE;
+
+		/* Window is not suspended anymore */
+		if(priv->isSuspended!=FALSE)
+		{
+			priv->isSuspended=FALSE;
+
+			/* Notify about property change */
+			g_object_notify_by_pspec(G_OBJECT(self), XfdashboardWindowContentX11Properties[PROP_SUSPENDED]);
+		}
+
+		/* Invalidate content to get it redrawn as soon as possible */
+		clutter_content_invalidate(CLUTTER_CONTENT(self));
+
+		/* We were able to set up window content so this window is definitely mapped */
+		priv->isMapped=TRUE;
+
+		/* End reached so break to get out of while loop */
+		break;
+	}
+
+	/* Check if window content should be suspended again after resume was done,
+	 * e.g. initial window content creation in suspended daemon mode.
+	 */
+	if(priv->suspendAfterResumeOnIdle)
+	{
+		_xfdashboard_window_content_x11_suspend(self);
+		priv->suspendAfterResumeOnIdle=FALSE;
+	}
+
+	/* Check if everything went well */
+	trapError=clutter_x11_untrap_x_errors();
+	if(trapError!=0)
+	{
+		XFDASHBOARD_DEBUG(self, WINDOWS,
+							"X error %d occured while resuming window '%s",
+							trapError,
+							xfdashboard_window_tracker_window_get_name(XFDASHBOARD_WINDOW_TRACKER_WINDOW(priv->window)));
+		return(doContinueSource);
+	}
+
+	XFDASHBOARD_DEBUG(self, WINDOWS,
+						"Resuming live texture updates for window '%s'",
+						xfdashboard_window_tracker_window_get_name(XFDASHBOARD_WINDOW_TRACKER_WINDOW(priv->window)));
+	return(doContinueSource);
+}
+
+static void _xfdashboard_window_content_x11_resume(XfdashboardWindowContentX11 *self)
+{
+	XfdashboardWindowContentX11Private		*priv;
+	Display									*display;
+	CoglContext								*context;
+	GError									*error;
+	gint									trapError;
+	CoglTexture								*windowTexture;
+
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_CONTENT_X11(self));
+	g_return_if_fail(self->priv->window);
+
+	priv=self->priv;
+	error=NULL;
+	windowTexture=NULL;
+
+	/* Check if to use new experimental code to resume window content
+	 * in an idle source.
+	 */
+	if(_xfdashboard_window_content_x11_window_creation_priority>0)
+	{
+		_xfdashboard_window_content_x11_resume_on_idle_add(self);
+		return;
+	}
+
+	/* We need at least the X composite extension to display images of windows
+	 * if still images or live updated ones
+	 */
+	if(!_xfdashboard_window_content_x11_have_composite_extension) return;
+
+	/* Get display as it used more than once ;) */
+	display=clutter_x11_get_default_display();
+
+	/* Set up resources */
+	clutter_x11_trap_x_errors();
+	while(1)
+	{
+#ifdef HAVE_XCOMPOSITE
+		/* Get pixmap to render texture for */
+		priv->pixmap=XCompositeNameWindowPixmap(display, priv->xWindowID);
+		XSync(display, False);
+		if(priv->pixmap==None)
+		{
+			g_warning(_("Could not get pixmap for window '%s"), xfdashboard_window_tracker_window_get_name(XFDASHBOARD_WINDOW_TRACKER_WINDOW(priv->window)));
+			_xfdashboard_window_content_x11_suspend(self);
+			break;
+		}
+#else
+		/* We should never get here as existance of composite extension was checked before */
+		g_critical(_("Cannot resume window '%s' as composite extension is not available"),
+					xfdashboard_window_tracker_window_get_name(XFDASHBOARD_WINDOW_TRACKER_WINDOW(priv->window)));
+		break;
+#endif
+
+		/* Create cogl X11 texture for live updates */
+		context=clutter_backend_get_cogl_context(clutter_get_default_backend());
+		windowTexture=COGL_TEXTURE(cogl_texture_pixmap_x11_new(context, priv->pixmap, FALSE, &error));
+		if(!windowTexture || error)
+		{
+			/* Creating texture may fail if window is _NOT_ on active workspace
+			 * so display error message just as debug message (this time)
+			 */
+			XFDASHBOARD_DEBUG(self, WINDOWS,
+								"Could not create texture for window '%s': %s",
+								xfdashboard_window_tracker_window_get_name(XFDASHBOARD_WINDOW_TRACKER_WINDOW(priv->window)),
+								error ? error->message : _("Unknown error"));
+			if(error)
+			{
+				g_error_free(error);
+				error=NULL;
+			}
+
+			if(windowTexture)
+			{
+				cogl_object_unref(windowTexture);
+				windowTexture=NULL;
+			}
+
+			_xfdashboard_window_content_x11_suspend(self);
+
+			break;
+		}
+
+		/* Set up damage to get notified about changed in pixmap */
+#ifdef HAVE_XDAMAGE
+		if(_xfdashboard_window_content_x11_have_damage_extension)
+		{
+			priv->damage=XDamageCreate(display, priv->pixmap, XDamageReportBoundingBox);
+			XSync(display, False);
+			if(priv->damage==None)
+			{
+				g_warning(_("Could not create damage for window '%s' - using still image of window"), xfdashboard_window_tracker_window_get_name(XFDASHBOARD_WINDOW_TRACKER_WINDOW(priv->window)));
+			}
+		}
+#endif
+
+		/* Release old texture (should be the fallback texture) and set new texture */
+		if(priv->texture)
+		{
+			cogl_object_unref(priv->texture);
+			priv->texture=windowTexture;
+		}
+
+		/* Set damage to new window texture */
+#ifdef HAVE_XDAMAGE
+		if(_xfdashboard_window_content_x11_have_damage_extension &&
+			priv->damage!=None)
+		{
+			cogl_texture_pixmap_x11_set_damage_object(COGL_TEXTURE_PIXMAP_X11(priv->texture), priv->damage, COGL_TEXTURE_PIXMAP_X11_DAMAGE_BOUNDING_BOX);
+		}
+#endif
+
+		/* Now we use the window as texture and not the fallback texture anymore */
+		priv->isFallback=FALSE;
+
+		/* Window is not suspended anymore */
+		if(priv->isSuspended!=FALSE)
+		{
+			priv->isSuspended=FALSE;
+
+			/* Notify about property change */
+			g_object_notify_by_pspec(G_OBJECT(self), XfdashboardWindowContentX11Properties[PROP_SUSPENDED]);
+		}
+
+		/* Invalidate content to get it redrawn as soon as possible */
+		clutter_content_invalidate(CLUTTER_CONTENT(self));
+
+		/* We were able to set up window content so this window is definitely mapped */
+		priv->isMapped=TRUE;
+
+		/* End reached so break to get out of while loop */
+		break;
+	}
+
+	/* Check if everything went well */
+	trapError=clutter_x11_untrap_x_errors();
+	if(trapError!=0)
+	{
+		XFDASHBOARD_DEBUG(self, WINDOWS,
+							"X error %d occured while resuming window '%s",
+							trapError,
+							xfdashboard_window_tracker_window_get_name(XFDASHBOARD_WINDOW_TRACKER_WINDOW(priv->window)));
+		return;
+	}
+
+	XFDASHBOARD_DEBUG(self, WINDOWS,
+						"Resuming live texture updates for window '%s'",
+						xfdashboard_window_tracker_window_get_name(XFDASHBOARD_WINDOW_TRACKER_WINDOW(priv->window)));
+}
+
+/* Find X window for window frame of given X window content */
+static Window _xfdashboard_window_content_x11_get_window_frame_xid(Display *inDisplay,
+																	XfdashboardWindowTrackerWindowX11 *inWindow)
+{
+	Window				xWindowID;
+	Window				iterXWindowID;
+	Window				rootXWindowID;
+	Window				foundXWindowID;
+	GdkDisplay			*gdkDisplay;
+	GdkWindow			*gdkWindow;
+	GdkWMDecoration		gdkWindowDecoration;
+
+	g_return_val_if_fail(inDisplay, 0);
+	g_return_val_if_fail(inWindow, 0);
+
+	/* Get X window */
+	xWindowID=xfdashboard_window_tracker_window_x11_get_xid(inWindow);
+	g_return_val_if_fail(xWindowID!=0, 0);
+
+	/* Check if window is client side decorated and if it has no decorations
+	 * so skip finding window frame and behave like we did not found it.
+	 */
+	gdkDisplay=gdk_display_get_default();
+	gdkWindow=gdk_x11_window_foreign_new_for_display(gdkDisplay, xWindowID);
+	if(gdkWindow)
+	{
+		if(gdk_window_get_decorations(gdkWindow, &gdkWindowDecoration) &&
+			gdkWindowDecoration==0)
+		{
+			XFDASHBOARD_DEBUG(inWindow, WINDOWS,
+								"Window '%s' has CSD enabled and no decorations so skip finding window frame.",
+								xfdashboard_window_tracker_window_get_name(XFDASHBOARD_WINDOW_TRACKER_WINDOW(inWindow)));
+
+			/* Release allocated resources */
+			g_object_unref(gdkWindow);
+
+			/* Skip finding window frame but return "not-found" result */
+			return(0);
+		}
+		g_object_unref(gdkWindow);
+	}
+		else
+		{
+			XFDASHBOARD_DEBUG(inWindow, WINDOWS,
+								"Could not get window decoration from window '%s'",
+								xfdashboard_window_tracker_window_get_name(XFDASHBOARD_WINDOW_TRACKER_WINDOW(inWindow)));
+		}
+
+	/* Iterate through X window tree list upwards until root window reached.
+	 * The last X window before root window is the one we are looking for.
+	 */
+	rootXWindowID=0;
+	foundXWindowID=0;
+	for(iterXWindowID=xWindowID; iterXWindowID && iterXWindowID!=rootXWindowID; )
+	{
+		Window	*children;
+		guint	numberChildren;
+
+		children=NULL;
+		numberChildren=0;
+		foundXWindowID=iterXWindowID;
+		if(!XQueryTree(inDisplay, iterXWindowID, &rootXWindowID, &iterXWindowID, &children, &numberChildren))
+		{
+			iterXWindowID=0;
+		}
+		if(children) XFree(children);
+	}
+
+	/* Return found X window ID */
+	return(foundXWindowID);
+}
+
+/* Set window to handle and to display */
+static void _xfdashboard_window_content_x11_set_window(XfdashboardWindowContentX11 *self, XfdashboardWindowTrackerWindowX11 *inWindow)
+{
+	XfdashboardWindowContentX11Private		*priv;
+	XfdashboardApplication					*application;
+	Display									*display;
+	GdkPixbuf								*windowIcon;
+	XWindowAttributes						windowAttrs;
+#if COGL_VERSION_CHECK(1, 18, 0)
+	ClutterBackend							*backend;
+	CoglContext								*context;
+	CoglError								*error;
+#endif
+
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_CONTENT_X11(self));
+	g_return_if_fail(inWindow!=NULL && XFDASHBOARD_IS_WINDOW_TRACKER_WINDOW_X11(inWindow));
+	g_return_if_fail(self->priv->window==NULL);
+	g_return_if_fail(self->priv->xWindowID==0);
+
+	priv=self->priv;
+
+	/* Freeze notifications and collect them */
+	g_object_freeze_notify(G_OBJECT(self));
+
+	/* Get display as it used more than once ;) */
+	display=clutter_x11_get_default_display();
+
+	/* Set new value */
+	priv->window=inWindow;
+
+	/* Create fallback texture first in case we cannot create
+	 * a live updated texture for window in the next steps
+	 */
+	windowIcon=xfdashboard_window_tracker_window_get_icon(XFDASHBOARD_WINDOW_TRACKER_WINDOW(priv->window));
+#if COGL_VERSION_CHECK(1, 18, 0)
+	error=NULL;
+
+	backend=clutter_get_default_backend();
+	context=clutter_backend_get_cogl_context(backend);
+	priv->texture=cogl_texture_2d_new_from_data(context,
+												gdk_pixbuf_get_width(windowIcon),
+												gdk_pixbuf_get_height(windowIcon),
+												gdk_pixbuf_get_has_alpha(windowIcon) ? COGL_PIXEL_FORMAT_RGBA_8888 : COGL_PIXEL_FORMAT_RGB_888,
+												gdk_pixbuf_get_rowstride(windowIcon),
+												gdk_pixbuf_get_pixels(windowIcon),
+												&error);
+
+	if(!priv->texture || error)
+	{
+		/* Show warning */
+		g_warning(_("Could not create fallback texture for window '%s': %s"),
+					xfdashboard_window_tracker_window_get_name(XFDASHBOARD_WINDOW_TRACKER_WINDOW(priv->window)),
+					(error && error->message) ? error->message : _("Unknown error"));
+
+		/* Release allocated resources */
+		if(priv->texture)
+		{
+			cogl_object_unref(priv->texture);
+			priv->texture=NULL;
+		}
+
+		if(error)
+		{
+			cogl_error_free(error);
+			error=NULL;
+		}
+	}
+#else
+	priv->texture=cogl_texture_new_from_data(gdk_pixbuf_get_width(windowIcon),
+												gdk_pixbuf_get_height(windowIcon),
+												COGL_TEXTURE_NONE,
+												gdk_pixbuf_get_has_alpha(windowIcon) ? COGL_PIXEL_FORMAT_RGBA_8888 : COGL_PIXEL_FORMAT_RGB_888,
+												COGL_PIXEL_FORMAT_ANY,
+												gdk_pixbuf_get_rowstride(windowIcon),
+												gdk_pixbuf_get_pixels(windowIcon));
+#endif
+
+	priv->isFallback=TRUE;
+
+	/* Get X window and its attributes */
+	if(priv->includeWindowFrame)
+	{
+		priv->xWindowID=_xfdashboard_window_content_x11_get_window_frame_xid(display, priv->window);
+	}
+
+	if(!priv->xWindowID)
+	{
+		priv->xWindowID=xfdashboard_window_tracker_window_x11_get_xid(priv->window);
+	}
+
+	if(!XGetWindowAttributes(display, priv->xWindowID, &windowAttrs))
+	{
+		g_warning(_("Could not get attributes of window '%s'"), xfdashboard_window_tracker_window_get_name(XFDASHBOARD_WINDOW_TRACKER_WINDOW(priv->window)));
+		XSync(display, False);
+	}
+
+	/* We need at least the X composite extension to display images of windows
+	 * if still images or live updated ones by redirecting window
+	 */
+#ifdef HAVE_XCOMPOSITE
+	if(_xfdashboard_window_content_x11_have_composite_extension)
+	{
+		/* Redirect window */
+		XCompositeRedirectWindow(display, priv->xWindowID, CompositeRedirectAutomatic);
+		XSync(display, False);
+	}
+#endif
+
+	/* We are interested in receiving mapping events of windows */
+	XSelectInput(display, priv->xWindowID, windowAttrs.your_event_mask | StructureNotifyMask);
+
+	/* Acquire new window and handle live updates */
+	_xfdashboard_window_content_x11_resume(self);
+	priv->isMapped=!priv->isSuspended;
+
+	/* But suspend window immediately again if application is suspended
+	 * (xfdashboard runs in daemon mode and is not active currently)
+	 */
+	application=xfdashboard_application_get_default();
+	if(xfdashboard_application_is_suspended(application))
+	{
+		if(_xfdashboard_window_content_x11_window_creation_priority>0)
+		{
+			priv->suspendAfterResumeOnIdle=TRUE;
+		}
+			else
+			{
+				_xfdashboard_window_content_x11_suspend(self);
+			}
+	}
+
+	/* Notify about property change */
+	g_object_notify_by_pspec(G_OBJECT(self), XfdashboardWindowContentX11Properties[PROP_WINDOW]);
+
+	/* Thaw notifications and send them now */
+	g_object_thaw_notify(G_OBJECT(self));
+
+	/* Set up workaround mechanism for unmapped windows if wanted and needed */
+	_xfdashboard_window_content_x11_setup_workaround(self, inWindow);
+}
+
+/* Destroy cache hashtable */
+static void _xfdashboard_window_content_x11_destroy_cache(void)
+{
+	XfdashboardApplication					*application;
+	gint									cacheSize;
+
+	/* Only an existing cache can be destroyed */
+	if(!_xfdashboard_window_content_x11_cache) return;
+
+	/* Disconnect application "shutdown" signal handler */
+	application=xfdashboard_application_get_default();
+	g_signal_handler_disconnect(application, _xfdashboard_window_content_x11_cache_shutdown_signal_id);
+	_xfdashboard_window_content_x11_cache_shutdown_signal_id=0;
+
+	/* Destroy cache hashtable */
+	cacheSize=g_hash_table_size(_xfdashboard_window_content_x11_cache);
+	if(cacheSize>0) g_warning(_("Destroying window content cache still containing %d windows."), cacheSize);
+#ifdef DEBUG
+	if(cacheSize>0)
+	{
+		GHashTableIter						iter;
+		gpointer							key, value;
+		XfdashboardWindowContentX11			*content;
+		XfdashboardWindowTrackerWindow		*window;
+
+		g_hash_table_iter_init(&iter, _xfdashboard_window_content_x11_cache);
+		while(g_hash_table_iter_next (&iter, &key, &value))
+		{
+			content=XFDASHBOARD_WINDOW_CONTENT_X11(value);
+			window=xfdashboard_window_content_x11_get_window(content);
+			g_print("Window content in cache: Item %s@%p for window '%s'\n",
+						G_OBJECT_TYPE_NAME(content), content,
+						xfdashboard_window_tracker_window_get_name(window));
+		}
+	}
+#endif
+
+	XFDASHBOARD_DEBUG(NULL, WINDOWS, "Destroying window content cache hashtable");
+	g_hash_table_destroy(_xfdashboard_window_content_x11_cache);
+	_xfdashboard_window_content_x11_cache=NULL;
+}
+
+/* Create cache hashtable if not already set up */
+static void _xfdashboard_window_content_x11_create_cache(void)
+{
+	XfdashboardApplication		*application;
+
+	/* Cache was already set up */
+	if(_xfdashboard_window_content_x11_cache) return;
+
+	/* Create create hashtable */
+	_xfdashboard_window_content_x11_cache=g_hash_table_new(g_direct_hash, g_direct_equal);
+	XFDASHBOARD_DEBUG(NULL, WINDOWS, "Created window content cache hashtable");
+
+	/* Connect to "shutdown" signal of application to clean up hashtable */
+	application=xfdashboard_application_get_default();
+	_xfdashboard_window_content_x11_cache_shutdown_signal_id=g_signal_connect(application,
+																		"shutdown-final",
+																		G_CALLBACK(_xfdashboard_window_content_x11_destroy_cache),
+																		NULL);
+}
+
+/* IMPLEMENTATION: ClutterContent */
+
+/* Paint texture */
+static void _xdashboard_window_content_clutter_content_iface_paint_content(ClutterContent *inContent,
+																			ClutterActor *inActor,
+																			ClutterPaintNode *inRootNode)
+{
+	XfdashboardWindowContentX11				*self=XFDASHBOARD_WINDOW_CONTENT_X11(inContent);
+	XfdashboardWindowContentX11Private		*priv=self->priv;
+	ClutterScalingFilter					minFilter, magFilter;
+	ClutterPaintNode						*node;
+	ClutterActorBox							textureAllocationBox;
+	ClutterActorBox							textureCoordBox;
+	ClutterActorBox							outlineBox;
+	ClutterColor							color;
+	guint8									opacity;
+	ClutterColor							outlineColor;
+	ClutterActorBox							outlinePath;
+
+	/* Check if we have a texture to paint */
+	if(priv->texture==NULL) return;
+
+	/* Get needed data for painting */
+	clutter_actor_box_init(&textureCoordBox, 0.0f, 0.0f, 1.0f, 1.0f);
+	clutter_actor_get_content_box(inActor, &textureAllocationBox);
+	clutter_actor_get_content_box(inActor, &outlineBox);
+	clutter_actor_get_content_scaling_filters(inActor, &minFilter, &magFilter);
+	opacity=clutter_actor_get_paint_opacity(inActor);
+
+	color.red=opacity;
+	color.green=opacity;
+	color.blue=opacity;
+	color.alpha=opacity;
+
+	/* Draw background if texture is a fallback */
+	if(priv->isFallback)
+	{
+		ClutterColor					backgroundColor;
+
+		/* Set up background color */
+		backgroundColor.red=0;
+		backgroundColor.green=0;
+		backgroundColor.blue=0;
+		backgroundColor.alpha=opacity;
+
+		/* Draw background */
+		node=clutter_color_node_new(&backgroundColor);
+		clutter_paint_node_set_name(node, "fallback-background");
+		clutter_paint_node_add_rectangle(node, &outlineBox);
+		clutter_paint_node_add_child(inRootNode, node);
+		clutter_paint_node_unref(node);
+	}
+
+	/* Determine actor box allocation to draw texture into when unmapped window
+	 * icon (fallback) will be drawn. We can skip calculation if unmapped window
+	 * icon should be expanded in both (x and y) direction.
+	 */
+	if(priv->isFallback &&
+		(!priv->unmappedWindowIconXFill || !priv->unmappedWindowIconYFill))
+	{
+		gfloat							allocationWidth;
+		gfloat							allocationHeight;
+
+		/* Get width and height of allocation */
+		allocationWidth=(outlineBox.x2-outlineBox.x1);
+		allocationHeight=(outlineBox.y2-outlineBox.y1);
+
+		/* Determine left and right boundary of unmapped window icon
+		 * if unmapped window icon should not expand in X axis.
+		 */
+		if(!priv->unmappedWindowIconXFill)
+		{
+			gfloat						offset;
+			gfloat						textureWidth;
+			gfloat						oversize;
+
+			/* Get scaled width of unmapped window icon */
+			textureWidth=cogl_texture_get_width(priv->texture);
+			textureWidth*=priv->unmappedWindowIconXScale;
+
+			/* Get boundary in X axis depending on gravity and scaled width */
+			offset=(priv->unmappedWindowIconXAlign*allocationWidth);
+			switch(priv->unmappedWindowIconAnchorPoint)
+			{
+				/* Align to left boundary.
+				 * This is also the default if gravity is none or undefined.
+				 */
+				default:
+				case XFDASHBOARD_ANCHOR_POINT_NONE:
+				case XFDASHBOARD_ANCHOR_POINT_WEST:
+				case XFDASHBOARD_ANCHOR_POINT_NORTH_WEST:
+				case XFDASHBOARD_ANCHOR_POINT_SOUTH_WEST:
+					break;
+
+				/* Align to center of X axis */
+				case XFDASHBOARD_ANCHOR_POINT_CENTER:
+				case XFDASHBOARD_ANCHOR_POINT_NORTH:
+				case XFDASHBOARD_ANCHOR_POINT_SOUTH:
+					offset-=(textureWidth/2.0f);
+					break;
+
+				/* Align to right boundary */
+				case XFDASHBOARD_ANCHOR_POINT_EAST:
+				case XFDASHBOARD_ANCHOR_POINT_NORTH_EAST:
+				case XFDASHBOARD_ANCHOR_POINT_SOUTH_EAST:
+					offset-=textureWidth;
+					break;
+			}
+
+			/* Set boundary in X axis */
+			textureAllocationBox.x1=outlineBox.x1+offset;
+			textureAllocationBox.x2=textureAllocationBox.x1+textureWidth;
+
+			/* Clip texture in X axis if it does not fit into allocation */
+			if(textureAllocationBox.x1<outlineBox.x1)
+			{
+				oversize=outlineBox.x1-textureAllocationBox.x1;
+				textureCoordBox.x1=oversize/textureWidth;
+				textureAllocationBox.x1=outlineBox.x1;
+			}
+
+			if(textureAllocationBox.x2>outlineBox.x2)
+			{
+				oversize=textureAllocationBox.x2-outlineBox.x2;
+				textureCoordBox.x2=1.0f-(oversize/textureWidth);
+				textureAllocationBox.x2=outlineBox.x2;
+			}
+		}
+
+		/* Determine left and right boundary of unmapped window icon
+		 * if unmapped window icon should not expand in X axis.
+		 */
+		if(!priv->unmappedWindowIconYFill)
+		{
+			gfloat						offset;
+			gfloat						textureHeight;
+			gfloat						oversize;
+
+			/* Get scaled width of unmapped window icon */
+			textureHeight=cogl_texture_get_height(priv->texture);
+			textureHeight*=priv->unmappedWindowIconYScale;
+
+			/* Get boundary in Y axis depending on gravity and scaled width */
+			offset=(priv->unmappedWindowIconYAlign*allocationHeight);
+			switch(priv->unmappedWindowIconAnchorPoint)
+			{
+				/* Align to upper boundary.
+				 * This is also the default if gravity is none or undefined.
+				 */
+				default:
+				case XFDASHBOARD_ANCHOR_POINT_NONE:
+				case XFDASHBOARD_ANCHOR_POINT_NORTH:
+				case XFDASHBOARD_ANCHOR_POINT_NORTH_WEST:
+				case XFDASHBOARD_ANCHOR_POINT_NORTH_EAST:
+					break;
+
+				/* Align to center of Y axis */
+				case XFDASHBOARD_ANCHOR_POINT_CENTER:
+				case XFDASHBOARD_ANCHOR_POINT_WEST:
+				case XFDASHBOARD_ANCHOR_POINT_EAST:
+					offset-=(textureHeight/2.0f);
+					break;
+
+				/* Align to lower boundary */
+				case XFDASHBOARD_ANCHOR_POINT_SOUTH:
+				case XFDASHBOARD_ANCHOR_POINT_SOUTH_WEST:
+				case XFDASHBOARD_ANCHOR_POINT_SOUTH_EAST:
+					offset-=textureHeight;
+					break;
+			}
+
+			/* Set boundary in Y axis */
+			textureAllocationBox.y1=outlineBox.y1+offset;
+			textureAllocationBox.y2=textureAllocationBox.y1+textureHeight;
+
+			/* Clip texture in Y axis if it does not fit into allocation */
+			if(textureAllocationBox.y1<outlineBox.y1)
+			{
+				oversize=outlineBox.y1-textureAllocationBox.y1;
+				textureCoordBox.y1=oversize/textureHeight;
+				textureAllocationBox.y1=outlineBox.y1;
+			}
+
+			if(textureAllocationBox.y2>outlineBox.y2)
+			{
+				oversize=textureAllocationBox.y2-outlineBox.y2;
+				textureCoordBox.y2=1.0f-(oversize/textureHeight);
+				textureAllocationBox.y2=outlineBox.y2;
+			}
+		}
+	}
+
+	/* Set up paint nodes for texture */
+	node=clutter_texture_node_new(priv->texture, &color, minFilter, magFilter);
+	clutter_paint_node_set_name(node, G_OBJECT_TYPE_NAME(self));
+	clutter_paint_node_add_texture_rectangle(node,
+												&textureAllocationBox,
+												textureCoordBox.x1,
+												textureCoordBox.y1,
+												textureCoordBox.x2,
+												textureCoordBox.y2);
+	clutter_paint_node_add_child(inRootNode, node);
+	clutter_paint_node_unref(node);
+
+	/* Draw outline (color is depending is texture is fallback or not.
+	 * That should be done last to get outline always visible
+	 */
+	if(priv->isFallback || priv->outlineColor==NULL)
+	{
+		outlineColor.red=0xff;
+		outlineColor.green=0xff;
+		outlineColor.blue=0xff;
+		outlineColor.alpha=opacity;
+	}
+		else
+		{
+			outlineColor.red=priv->outlineColor->red;
+			outlineColor.green=priv->outlineColor->green;
+			outlineColor.blue=priv->outlineColor->blue;
+			outlineColor.alpha=opacity;
+		}
+
+	node=clutter_color_node_new(&outlineColor);
+	clutter_paint_node_set_name(node, "outline-top");
+	clutter_actor_box_init_rect(&outlinePath, outlineBox.x1, 0.0f, outlineBox.x2-outlineBox.x1, priv->outlineWidth);
+	clutter_paint_node_add_rectangle(node, &outlinePath);
+	clutter_paint_node_add_child(inRootNode, node);
+	clutter_paint_node_unref(node);
+
+	node=clutter_color_node_new(&outlineColor);
+	clutter_paint_node_set_name(node, "outline-bottom");
+	clutter_actor_box_init_rect(&outlinePath, outlineBox.x1, outlineBox.y2-priv->outlineWidth, outlineBox.x2-outlineBox.x1, priv->outlineWidth);
+	clutter_paint_node_add_rectangle(node, &outlinePath);
+	clutter_paint_node_add_child(inRootNode, node);
+	clutter_paint_node_unref(node);
+
+	node=clutter_color_node_new(&outlineColor);
+	clutter_paint_node_set_name(node, "outline-left");
+	clutter_actor_box_init_rect(&outlinePath, outlineBox.x1, outlineBox.y1, priv->outlineWidth, outlineBox.y2-outlineBox.y1);
+	clutter_paint_node_add_rectangle(node, &outlinePath);
+	clutter_paint_node_add_child(inRootNode, node);
+	clutter_paint_node_unref(node);
+
+	node=clutter_color_node_new(&outlineColor);
+	clutter_paint_node_set_name(node, "outline-right");
+	clutter_actor_box_init_rect(&outlinePath, outlineBox.x2-priv->outlineWidth, outlineBox.y1, priv->outlineWidth, outlineBox.y2-outlineBox.y1);
+	clutter_paint_node_add_rectangle(node, &outlinePath);
+	clutter_paint_node_add_child(inRootNode, node);
+	clutter_paint_node_unref(node);
+}
+
+/* Get preferred size of texture */
+static gboolean _xdashboard_window_content_clutter_content_iface_get_preferred_size(ClutterContent *inContent,
+																					gfloat *outWidth,
+																					gfloat *outHeight)
+{
+	XfdashboardWindowContentX11Private		*priv=XFDASHBOARD_WINDOW_CONTENT_X11(inContent)->priv;
+	gfloat									w, h;
+
+	/* No texture - no size to retrieve */
+	if(priv->texture==NULL) return(FALSE);
+
+	/* If window is suspended or if we use the fallback image
+	 * get real window size ...
+	 */
+	if(priv->isFallback || priv->isSuspended)
+	{
+		/* Is a fallback texture so get real window size */
+		gint							windowW, windowH;
+
+		xfdashboard_window_tracker_window_get_geometry(XFDASHBOARD_WINDOW_TRACKER_WINDOW(priv->window), NULL, NULL, &windowW, &windowH);
+		w=windowW;
+		h=windowH;
+	}
+		else
+		{
+			/* ... otherwise get size of texture */
+			w=cogl_texture_get_width(priv->texture);
+			h=cogl_texture_get_height(priv->texture);
+		}
+
+	/* Set result values */
+	if(outWidth) *outWidth=w;
+	if(outHeight) *outHeight=h;
+
+	return(TRUE);
+}
+
+/* Initialize interface of type ClutterContent */
+static void _xfdashboard_window_content_clutter_content_iface_init(ClutterContentIface *iface)
+{
+	iface->get_preferred_size=_xdashboard_window_content_clutter_content_iface_get_preferred_size;
+	iface->paint_content=_xdashboard_window_content_clutter_content_iface_paint_content;
+}
+
+/* IMPLEMENTATION: Interface XfdashboardStylable */
+
+/* Get stylable properties of stage */
+static void _xfdashboard_window_content_x11_stylable_get_stylable_properties(XfdashboardStylable *self,
+																			GHashTable *ioStylableProperties)
+{
+	g_return_if_fail(XFDASHBOARD_IS_STYLABLE(self));
+
+	/* Add stylable properties to hashtable */
+	xfdashboard_stylable_add_stylable_property(self, ioStylableProperties, "include-window-frame");
+	xfdashboard_stylable_add_stylable_property(self, ioStylableProperties, "unmapped-window-icon-x-fill");
+	xfdashboard_stylable_add_stylable_property(self, ioStylableProperties, "unmapped-window-icon-y-fill");
+	xfdashboard_stylable_add_stylable_property(self, ioStylableProperties, "unmapped-window-icon-x-align");
+	xfdashboard_stylable_add_stylable_property(self, ioStylableProperties, "unmapped-window-icon-y-align");
+	xfdashboard_stylable_add_stylable_property(self, ioStylableProperties, "unmapped-window-icon-x-scale");
+	xfdashboard_stylable_add_stylable_property(self, ioStylableProperties, "unmapped-window-icon-y-scale");
+	xfdashboard_stylable_add_stylable_property(self, ioStylableProperties, "unmapped-window-icon-anchor-point");
+}
+
+/* Get/set style classes of stage */
+static const gchar* _xfdashboard_window_content_x11_stylable_get_classes(XfdashboardStylable *inStylable)
+{
+	/* Not implemented */
+	return(NULL);
+}
+
+static void _xfdashboard_window_content_x11_stylable_set_classes(XfdashboardStylable *inStylable, const gchar *inStyleClasses)
+{
+	/* Not implemented */
+}
+
+/* Get/set style pseudo-classes of stage */
+static const gchar* _xfdashboard_window_content_x11_stylable_get_pseudo_classes(XfdashboardStylable *inStylable)
+{
+	/* Not implemented */
+	return(NULL);
+}
+
+static void _xfdashboard_window_content_x11_stylable_set_pseudo_classes(XfdashboardStylable *inStylable, const gchar *inStylePseudoClasses)
+{
+	/* Not implemented */
+}
+
+/* Interface initialization
+ * Set up default functions
+ */
+void _xfdashboard_window_content_x11_stylable_iface_init(XfdashboardStylableInterface *iface)
+{
+	iface->get_stylable_properties=_xfdashboard_window_content_x11_stylable_get_stylable_properties;
+	iface->get_classes=_xfdashboard_window_content_x11_stylable_get_classes;
+	iface->set_classes=_xfdashboard_window_content_x11_stylable_set_classes;
+	iface->get_pseudo_classes=_xfdashboard_window_content_x11_stylable_get_pseudo_classes;
+	iface->set_pseudo_classes=_xfdashboard_window_content_x11_stylable_set_pseudo_classes;
+}
+
+/* IMPLEMENTATION: GObject */
+
+/* Dispose this object */
+static void _xfdashboard_window_content_x11_dispose(GObject *inObject)
+{
+	XfdashboardWindowContentX11				*self=XFDASHBOARD_WINDOW_CONTENT_X11(inObject);
+	XfdashboardWindowContentX11Private		*priv=self->priv;
+
+	/* Dispose allocated resources */
+	_xfdashboard_window_content_x11_release_resources(self);
+
+	if(priv->workaroundStateSignalID)
+	{
+		g_signal_handler_disconnect(priv->windowTracker, priv->workaroundStateSignalID);
+		priv->workaroundStateSignalID=0;
+
+		/* This signal was still connected to the window tracker so the window may be unminized
+		 * and need to ensure it is minimized again. We need to do this now, before we release
+		 * our handle to the window (priv->window).
+		 */
+		xfdashboard_window_tracker_window_hide(XFDASHBOARD_WINDOW_TRACKER_WINDOW(priv->window));
+	}
+
+	if(priv->windowTracker)
+	{
+		g_signal_handlers_disconnect_by_data(priv->windowTracker, self);
+		g_object_unref(priv->windowTracker);
+		priv->windowTracker=NULL;
+	}
+
+	if(priv->window)
+	{
+		/* Remove from cache */
+		XFDASHBOARD_DEBUG(self, WINDOWS,
+							"Removing window content for window '%s' with ref-count %d" ,
+							xfdashboard_window_tracker_window_get_name(XFDASHBOARD_WINDOW_TRACKER_WINDOW(priv->window)),
+							G_OBJECT(self)->ref_count);
+		g_hash_table_remove(_xfdashboard_window_content_x11_cache, priv->window);
+
+		/* Disconnect signals */
+		g_signal_handlers_disconnect_by_data(priv->window, self);
+
+		/* libwnck resources should never be freed. Just set to NULL */
+		priv->window=NULL;
+	}
+
+	if(priv->suspendSignalID)
+	{
+		g_signal_handler_disconnect(xfdashboard_application_get_default(), priv->suspendSignalID);
+		priv->suspendSignalID=0;
+	}
+
+	if(priv->outlineColor)
+	{
+		clutter_color_free(priv->outlineColor);
+		priv->outlineColor=NULL;
+	}
+
+	if(priv->styleClasses)
+	{
+		g_free(priv->styleClasses);
+		priv->styleClasses=NULL;
+	}
+
+	if(priv->stylePseudoClasses)
+	{
+		g_free(priv->stylePseudoClasses);
+		priv->stylePseudoClasses=NULL;
+	}
+
+	/* Call parent's class dispose method */
+	G_OBJECT_CLASS(xfdashboard_window_content_x11_parent_class)->dispose(inObject);
+}
+
+/* Set/get properties */
+static void _xfdashboard_window_content_x11_set_property(GObject *inObject,
+												guint inPropID,
+												const GValue *inValue,
+												GParamSpec *inSpec)
+{
+	XfdashboardWindowContentX11		*self=XFDASHBOARD_WINDOW_CONTENT_X11(inObject);
+
+	switch(inPropID)
+	{
+		case PROP_WINDOW:
+			_xfdashboard_window_content_x11_set_window(self, XFDASHBOARD_WINDOW_TRACKER_WINDOW_X11(g_value_get_object(inValue)));
+			break;
+
+		case PROP_OUTLINE_COLOR:
+			xfdashboard_window_content_x11_set_outline_color(self, clutter_value_get_color(inValue));
+			break;
+
+		case PROP_OUTLINE_WIDTH:
+			xfdashboard_window_content_x11_set_outline_width(self, g_value_get_float(inValue));
+			break;
+
+		case PROP_INCLUDE_WINDOW_FRAME:
+			xfdashboard_window_content_x11_set_include_window_frame(self, g_value_get_boolean(inValue));
+			break;
+
+		case PROP_UNMAPPED_WINDOW_ICON_X_FILL:
+			xfdashboard_window_content_x11_set_unmapped_window_icon_x_fill(self, g_value_get_boolean(inValue));
+			break;
+
+		case PROP_UNMAPPED_WINDOW_ICON_Y_FILL:
+			xfdashboard_window_content_x11_set_unmapped_window_icon_y_fill(self, g_value_get_boolean(inValue));
+			break;
+
+		case PROP_UNMAPPED_WINDOW_ICON_X_ALIGN:
+			xfdashboard_window_content_x11_set_unmapped_window_icon_x_align(self, g_value_get_float(inValue));
+			break;
+
+		case PROP_UNMAPPED_WINDOW_ICON_Y_ALIGN:
+			xfdashboard_window_content_x11_set_unmapped_window_icon_y_align(self, g_value_get_float(inValue));
+			break;
+
+		case PROP_UNMAPPED_WINDOW_ICON_X_SCALE:
+			xfdashboard_window_content_x11_set_unmapped_window_icon_x_scale(self, g_value_get_float(inValue));
+			break;
+
+		case PROP_UNMAPPED_WINDOW_ICON_Y_SCALE:
+			xfdashboard_window_content_x11_set_unmapped_window_icon_y_scale(self, g_value_get_float(inValue));
+			break;
+
+		case PROP_UNMAPPED_WINDOW_ICON_ANCHOR_POINT:
+			xfdashboard_window_content_x11_set_unmapped_window_icon_anchor_point(self, g_value_get_enum(inValue));
+			break;
+
+		case PROP_STYLE_CLASSES:
+			_xfdashboard_window_content_x11_stylable_set_classes(XFDASHBOARD_STYLABLE(self), g_value_get_string(inValue));
+			break;
+
+		case PROP_STYLE_PSEUDO_CLASSES:
+			_xfdashboard_window_content_x11_stylable_set_pseudo_classes(XFDASHBOARD_STYLABLE(self), g_value_get_string(inValue));
+			break;
+
+		default:
+			G_OBJECT_WARN_INVALID_PROPERTY_ID(inObject, inPropID, inSpec);
+			break;
+	}
+}
+
+static void _xfdashboard_window_content_x11_get_property(GObject *inObject,
+												guint inPropID,
+												GValue *outValue,
+												GParamSpec *inSpec)
+{
+	XfdashboardWindowContentX11				*self=XFDASHBOARD_WINDOW_CONTENT_X11(inObject);
+	XfdashboardWindowContentX11Private		*priv=self->priv;
+
+	switch(inPropID)
+	{
+		case PROP_WINDOW:
+			g_value_set_object(outValue, priv->window);
+			break;
+
+		case PROP_SUSPENDED:
+			g_value_set_boolean(outValue, priv->isSuspended);
+			break;
+
+		case PROP_OUTLINE_COLOR:
+			clutter_value_set_color(outValue, priv->outlineColor);
+			break;
+
+		case PROP_OUTLINE_WIDTH:
+			g_value_set_float(outValue, priv->outlineWidth);
+			break;
+
+		case PROP_INCLUDE_WINDOW_FRAME:
+			g_value_set_boolean(outValue, priv->includeWindowFrame);
+			break;
+
+		case PROP_UNMAPPED_WINDOW_ICON_X_FILL:
+			g_value_set_boolean(outValue, priv->unmappedWindowIconXFill);
+			break;
+
+		case PROP_UNMAPPED_WINDOW_ICON_Y_FILL:
+			g_value_set_boolean(outValue, priv->unmappedWindowIconYFill);
+			break;
+
+		case PROP_UNMAPPED_WINDOW_ICON_X_ALIGN:
+			g_value_set_float(outValue, priv->unmappedWindowIconXAlign);
+			break;
+
+		case PROP_UNMAPPED_WINDOW_ICON_Y_ALIGN:
+			g_value_set_float(outValue, priv->unmappedWindowIconYAlign);
+			break;
+
+		case PROP_UNMAPPED_WINDOW_ICON_X_SCALE:
+			g_value_set_float(outValue, priv->unmappedWindowIconXScale);
+			break;
+
+		case PROP_UNMAPPED_WINDOW_ICON_Y_SCALE:
+			g_value_set_float(outValue, priv->unmappedWindowIconYScale);
+			break;
+
+		case PROP_UNMAPPED_WINDOW_ICON_ANCHOR_POINT:
+			g_value_set_enum(outValue, priv->unmappedWindowIconAnchorPoint);
+			break;
+
+		case PROP_STYLE_CLASSES:
+			g_value_set_string(outValue, priv->styleClasses);
+			break;
+
+		case PROP_STYLE_PSEUDO_CLASSES:
+			g_value_set_string(outValue, priv->stylePseudoClasses);
+			break;
+
+		default:
+			G_OBJECT_WARN_INVALID_PROPERTY_ID(inObject, inPropID, inSpec);
+			break;
+	}
+}
+
+/* Class initialization
+ * Override functions in parent classes and define properties
+ * and signals
+ */
+void xfdashboard_window_content_x11_class_init(XfdashboardWindowContentX11Class *klass)
+{
+	GObjectClass					*gobjectClass=G_OBJECT_CLASS(klass);
+	XfdashboardStylableInterface	*stylableIface;
+	GParamSpec						*paramSpec;
+
+	/* Override functions */
+	gobjectClass->dispose=_xfdashboard_window_content_x11_dispose;
+	gobjectClass->set_property=_xfdashboard_window_content_x11_set_property;
+	gobjectClass->get_property=_xfdashboard_window_content_x11_get_property;
+
+	stylableIface=g_type_default_interface_ref(XFDASHBOARD_TYPE_STYLABLE);
+
+	/* Set up private structure */
+	g_type_class_add_private(klass, sizeof(XfdashboardWindowContentX11Private));
+
+	/* Define properties */
+	XfdashboardWindowContentX11Properties[PROP_WINDOW]=
+		g_param_spec_object("window",
+							_("Window"),
+							_("The window to handle and display"),
+							XFDASHBOARD_TYPE_WINDOW_TRACKER_WINDOW,
+							G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY);
+
+	XfdashboardWindowContentX11Properties[PROP_SUSPENDED]=
+		g_param_spec_boolean("suspended",
+							_("Suspended"),
+							_("Is this window suspended"),
+							TRUE,
+							G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+
+	XfdashboardWindowContentX11Properties[PROP_OUTLINE_COLOR]=
+		clutter_param_spec_color("outline-color",
+									_("Outline color"),
+									_("Color to draw outline of mapped windows with"),
+									CLUTTER_COLOR_Black,
+									G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+
+	XfdashboardWindowContentX11Properties[PROP_OUTLINE_WIDTH]=
+		g_param_spec_float("outline-width",
+							_("Outline width"),
+							_("Width of line used to draw outline of mapped windows"),
+							0.0f, G_MAXFLOAT,
+							1.0f,
+							G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+
+	XfdashboardWindowContentX11Properties[PROP_INCLUDE_WINDOW_FRAME]=
+		g_param_spec_boolean("include-window-frame",
+							_("Include window frame"),
+							_("Whether the window frame should be included or only the window content should be shown"),
+							FALSE,
+							G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+
+	XfdashboardWindowContentX11Properties[PROP_UNMAPPED_WINDOW_ICON_X_FILL]=
+		g_param_spec_boolean("unmapped-window-icon-x-fill",
+							_("Unmapped window icon X fill"),
+							_("Whether the unmapped window icon should fill up horizontal space"),
+							TRUE,
+							G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+
+	XfdashboardWindowContentX11Properties[PROP_UNMAPPED_WINDOW_ICON_Y_FILL]=
+		g_param_spec_boolean("unmapped-window-icon-y-fill",
+							_("Unmapped window icon y fill"),
+							_("Whether the unmapped window icon should fill up vertical space"),
+							TRUE,
+							G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+
+	XfdashboardWindowContentX11Properties[PROP_UNMAPPED_WINDOW_ICON_X_ALIGN]=
+		g_param_spec_float("unmapped-window-icon-x-align",
+							_("Unmapped window icon X align"),
+							_("The alignment of the unmapped window icon on the X axis within the allocation in normalized coordinate between 0 and 1"),
+							0.0f, 1.0f,
+							0.0f,
+							G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+
+	XfdashboardWindowContentX11Properties[PROP_UNMAPPED_WINDOW_ICON_Y_ALIGN]=
+		g_param_spec_float("unmapped-window-icon-y-align",
+							_("Unmapped window icon Y align"),
+							_("The alignment of the unmapped window icon on the Y axis within the allocation in normalized coordinate between 0 and 1"),
+							0.0f, 1.0f,
+							0.0f,
+							G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+
+	XfdashboardWindowContentX11Properties[PROP_UNMAPPED_WINDOW_ICON_X_SCALE]=
+		g_param_spec_float("unmapped-window-icon-x-scale",
+							_("Unmapped window icon X scale"),
+							_("Scale factor of unmapped window icon on the X axis"),
+							0.0f, G_MAXFLOAT,
+							1.0f,
+							G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+
+	XfdashboardWindowContentX11Properties[PROP_UNMAPPED_WINDOW_ICON_Y_SCALE]=
+		g_param_spec_float("unmapped-window-icon-y-scale",
+							_("Unmapped window icon Y scale"),
+							_("Scale factor of unmapped window icon on the Y axis"),
+							0.0f, G_MAXFLOAT,
+							1.0f,
+							G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+
+	XfdashboardWindowContentX11Properties[PROP_UNMAPPED_WINDOW_ICON_ANCHOR_POINT]=
+		g_param_spec_enum("unmapped-window-icon-anchor-point",
+							_("Unmapped window icon anchor point"),
+							_("The anchor point of unmapped window icon"),
+							XFDASHBOARD_TYPE_ANCHOR_POINT,
+							XFDASHBOARD_ANCHOR_POINT_NONE,
+							G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+
+	paramSpec=g_object_interface_find_property(stylableIface, "style-classes");
+	XfdashboardWindowContentX11Properties[PROP_STYLE_CLASSES]=
+		g_param_spec_override("style-classes", paramSpec);
+
+	paramSpec=g_object_interface_find_property(stylableIface, "style-pseudo-classes");
+	XfdashboardWindowContentX11Properties[PROP_STYLE_PSEUDO_CLASSES]=
+		g_param_spec_override("style-pseudo-classes", paramSpec);
+
+	g_object_class_install_properties(gobjectClass, PROP_LAST, XfdashboardWindowContentX11Properties);
+
+	/* Release allocated resources */
+	g_type_default_interface_unref(stylableIface);
+}
+
+/* Object initialization
+ * Create private structure and set up default values
+ */
+void xfdashboard_window_content_x11_init(XfdashboardWindowContentX11 *self)
+{
+	XfdashboardWindowContentX11Private		*priv;
+	XfdashboardApplication				*app;
+
+	priv=self->priv=XFDASHBOARD_WINDOW_CONTENT_X11_GET_PRIVATE(self);
+
+	/* Set default values */
+	priv->window=NULL;
+	priv->texture=NULL;
+	priv->xWindowID=None;
+	priv->pixmap=None;
+#ifdef HAVE_XDAMAGE
+	priv->damage=None;
+#endif
+	priv->isFallback=FALSE;
+	priv->outlineColor=clutter_color_copy(CLUTTER_COLOR_Black);
+	priv->outlineWidth=1.0f;
+	priv->isSuspended=TRUE;
+	priv->suspendSignalID=0;
+	priv->isMapped=FALSE;
+	priv->includeWindowFrame=FALSE;
+	priv->styleClasses=NULL;
+	priv->stylePseudoClasses=NULL;
+	priv->windowTracker=xfdashboard_window_tracker_get_default();
+	priv->workaroundMode=XFDASHBOARD_WINDOW_CONTENT_X11_WORKAROUND_MODE_NONE;
+	priv->workaroundStateSignalID=0;
+	priv->unmappedWindowIconXFill=FALSE;
+	priv->unmappedWindowIconYFill=FALSE;
+	priv->unmappedWindowIconXAlign=0.0f;
+	priv->unmappedWindowIconYAlign=0.0f;
+	priv->unmappedWindowIconXScale=1.0f;
+	priv->unmappedWindowIconYScale=1.0f;
+	priv->unmappedWindowIconAnchorPoint=XFDASHBOARD_ANCHOR_POINT_NONE;
+	priv->suspendAfterResumeOnIdle=FALSE;
+
+	/* Check extensions (will only be done once) */
+	_xfdashboard_window_content_x11_check_extension();
+
+	/* Add event filter for this instance */
+	clutter_x11_add_filter(_xfdashboard_window_content_x11_on_x_event, self);
+
+	/* Style content */
+	xfdashboard_stylable_invalidate(XFDASHBOARD_STYLABLE(self));
+
+	/* Handle suspension signals from application */
+	app=xfdashboard_application_get_default();
+	priv->suspendSignalID=g_signal_connect_swapped(app,
+													"notify::is-suspended",
+													G_CALLBACK(_xfdashboard_window_content_x11_on_application_suspended_changed),
+													self);
+	priv->isAppSuspended=xfdashboard_application_is_suspended(app);
+
+	/* Register global signal handler for xfconf value change notification
+	 * if not done already.
+	 */
+	if(!_xfdashboard_window_content_x11_xfconf_priority_notify_id)
+	{
+		XfconfChannel					*xfconfChannel;
+		gchar							*detailedSignal;
+
+		/* Connect to property changed signal in xfconf */
+		xfconfChannel=xfdashboard_application_get_xfconf_channel(NULL);
+		detailedSignal=g_strconcat("property-changed::", WINDOW_CONTENT_CREATION_PRIORITY_XFCONF_PROP, NULL);
+		_xfdashboard_window_content_x11_xfconf_priority_notify_id=g_signal_connect(xfconfChannel,
+																				detailedSignal,
+																				G_CALLBACK(_xfdashboard_window_content_x11_on_window_creation_priority_value_changed),
+																				NULL);
+		if(detailedSignal) g_free(detailedSignal);
+		XFDASHBOARD_DEBUG(self, WINDOWS,
+							"Connected to property changed signal with handler ID %u for xfconf value change notifications",
+							_xfdashboard_window_content_x11_xfconf_priority_notify_id);
+
+		/* Connect to application shutdown signal for xfconf value change notification */
+		_xfdashboard_window_content_x11_window_creation_shutdown_signal_id=g_signal_connect(app,
+																				"shutdown-final",
+																				G_CALLBACK(_xfdashboard_window_content_x11_on_window_creation_priority_shutdown),
+																				NULL);
+		XFDASHBOARD_DEBUG(self, WINDOWS,
+							"Connected to shutdown signal with handler ID %u for xfconf value change notifications",
+							_xfdashboard_window_content_x11_window_creation_shutdown_signal_id);
+	}
+}
+
+/* IMPLEMENTATION: Public API */
+
+/* Create new instance */
+ClutterContent* xfdashboard_window_content_x11_new_for_window(XfdashboardWindowTrackerWindowX11 *inWindow)
+{
+	ClutterContent		*content;
+
+	g_return_val_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_WINDOW_X11(inWindow), NULL);
+
+	/* If we a hash table (cache) set up lookup if window content is already cached
+	 * and return a new reference to it
+	 */
+	if(_xfdashboard_window_content_x11_cache &&
+		g_hash_table_contains(_xfdashboard_window_content_x11_cache, inWindow))
+	{
+		content=CLUTTER_CONTENT(g_hash_table_lookup(_xfdashboard_window_content_x11_cache, inWindow));
+		g_object_ref(content);
+		XFDASHBOARD_DEBUG(content, WINDOWS,
+							"Using cached window content for '%s' - ref-count is now %d" ,
+							xfdashboard_window_tracker_window_get_name(XFDASHBOARD_WINDOW_TRACKER_WINDOW(XFDASHBOARD_WINDOW_CONTENT_X11(content)->priv->window)),
+							G_OBJECT(content)->ref_count);
+
+		return(content);
+	}
+
+	/* Create window content */
+	content=CLUTTER_CONTENT(g_object_new(XFDASHBOARD_TYPE_WINDOW_CONTENT_X11,
+											"window", inWindow,
+											NULL));
+	g_return_val_if_fail(content, NULL);
+
+	/* Create cache if not available */
+	if(!_xfdashboard_window_content_x11_cache) _xfdashboard_window_content_x11_create_cache();
+
+	/* Store new window content into cache */
+	g_hash_table_insert(_xfdashboard_window_content_x11_cache, inWindow, content);
+	XFDASHBOARD_DEBUG(content, WINDOWS,
+						"Added window content for '%s' with ref-count %d" ,
+						xfdashboard_window_tracker_window_get_name(XFDASHBOARD_WINDOW_TRACKER_WINDOW(inWindow)),
+						G_OBJECT(content)->ref_count);
+
+	return(content);
+}
+
+/* Get window to handle and to display */
+XfdashboardWindowTrackerWindow* xfdashboard_window_content_x11_get_window(XfdashboardWindowContentX11 *self)
+{
+	g_return_val_if_fail(XFDASHBOARD_IS_WINDOW_CONTENT_X11(self), NULL);
+
+	return(XFDASHBOARD_WINDOW_TRACKER_WINDOW(self->priv->window));
+}
+
+/* Get state of suspension */
+gboolean xfdashboard_window_content_x11_is_suspended(XfdashboardWindowContentX11 *self)
+{
+	g_return_val_if_fail(XFDASHBOARD_IS_WINDOW_CONTENT_X11(self), TRUE);
+
+	return(self->priv->isSuspended);
+}
+
+/* Get/set color to draw outline with */
+const ClutterColor* xfdashboard_window_content_x11_get_outline_color(XfdashboardWindowContentX11 *self)
+{
+	g_return_val_if_fail(XFDASHBOARD_IS_WINDOW_CONTENT_X11(self), NULL);
+
+	return(self->priv->outlineColor);
+}
+
+void xfdashboard_window_content_x11_set_outline_color(XfdashboardWindowContentX11 *self, const ClutterColor *inColor)
+{
+	XfdashboardWindowContentX11Private		*priv;
+
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_CONTENT_X11(self));
+	g_return_if_fail(inColor);
+
+	priv=self->priv;
+
+	/* Set value if changed */
+	if(priv->outlineColor==NULL || clutter_color_equal(inColor, priv->outlineColor)==FALSE)
+	{
+		/* Set value */
+		if(priv->outlineColor) clutter_color_free(priv->outlineColor);
+		priv->outlineColor=clutter_color_copy(inColor);
+
+		/* Invalidate ourselve to get us redrawn */
+		clutter_content_invalidate(CLUTTER_CONTENT(self));
+
+		/* Notify about property change */
+		g_object_notify_by_pspec(G_OBJECT(self), XfdashboardWindowContentX11Properties[PROP_OUTLINE_COLOR]);
+	}
+}
+
+/* Get/set line width for outline */
+gfloat xfdashboard_window_content_x11_get_outline_width(XfdashboardWindowContentX11 *self)
+{
+	g_return_val_if_fail(XFDASHBOARD_IS_WINDOW_CONTENT_X11(self), 0.0f);
+
+	return(self->priv->outlineWidth);
+}
+
+void xfdashboard_window_content_x11_set_outline_width(XfdashboardWindowContentX11 *self, const gfloat inWidth)
+{
+	XfdashboardWindowContentX11Private		*priv;
+
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_CONTENT_X11(self));
+	g_return_if_fail(inWidth>=0.0f);
+
+	priv=self->priv;
+
+	/* Set value if changed */
+	if(priv->outlineWidth!=inWidth)
+	{
+		/* Set value */
+		priv->outlineWidth=inWidth;
+
+		/* Invalidate ourselve to get us redrawn */
+		clutter_content_invalidate(CLUTTER_CONTENT(self));
+
+		/* Notify about property change */
+		g_object_notify_by_pspec(G_OBJECT(self), XfdashboardWindowContentX11Properties[PROP_OUTLINE_WIDTH]);
+	}
+}
+
+/* Get/set flag to indicate whether to include the window frame or not */
+gboolean xfdashboard_window_content_x11_get_include_window_frame(XfdashboardWindowContentX11 *self)
+{
+	g_return_val_if_fail(XFDASHBOARD_IS_WINDOW_CONTENT_X11(self), TRUE);
+
+	return(self->priv->includeWindowFrame);
+}
+
+void xfdashboard_window_content_x11_set_include_window_frame(XfdashboardWindowContentX11 *self, const gboolean inIncludeFrame)
+{
+	XfdashboardWindowContentX11Private				*priv;
+
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_CONTENT_X11(self));
+
+	priv=self->priv;
+
+	/* Set value if changed */
+	if(priv->includeWindowFrame!=inIncludeFrame)
+	{
+		/* Set value */
+		priv->includeWindowFrame=inIncludeFrame;
+
+		/* (Re-)Setup window content */
+		if(priv->window)
+		{
+			XfdashboardWindowTrackerWindowX11		*window;
+
+			/* Re-setup window by releasing all resources first and unsetting window
+			 * but remember window to set it again.
+			 */
+			_xfdashboard_window_content_x11_release_resources(self);
+
+			/* libwnck resources should never be freed. Just set to NULL */
+			window=priv->window;
+			priv->window=NULL;
+
+			/* Now set same window again which causes this object to set up all
+			 * needed X resources again.
+			 */
+			_xfdashboard_window_content_x11_set_window(self, window);
+		}
+
+		/* Invalidate ourselve to get us redrawn */
+		clutter_content_invalidate(CLUTTER_CONTENT(self));
+
+		/* Notify about property change */
+		g_object_notify_by_pspec(G_OBJECT(self), XfdashboardWindowContentX11Properties[PROP_INCLUDE_WINDOW_FRAME]);
+	}
+}
+
+/* Get/set x fill of unmapped window icon */
+gboolean xfdashboard_window_content_x11_get_unmapped_window_icon_x_fill(XfdashboardWindowContentX11 *self)
+{
+	g_return_val_if_fail(XFDASHBOARD_IS_WINDOW_CONTENT_X11(self), FALSE);
+
+	return(self->priv->unmappedWindowIconXFill);
+}
+
+void xfdashboard_window_content_x11_set_unmapped_window_icon_x_fill(XfdashboardWindowContentX11 *self, const gboolean inFill)
+{
+	XfdashboardWindowContentX11Private		*priv;
+
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_CONTENT_X11(self));
+
+	priv=self->priv;
+
+	/* Set value if changed */
+	if(priv->unmappedWindowIconXFill!=inFill)
+	{
+		/* Set value */
+		priv->unmappedWindowIconXFill=inFill;
+
+		/* Invalidate ourselve to get us redrawn */
+		clutter_content_invalidate(CLUTTER_CONTENT(self));
+
+		/* Notify about property change */
+		g_object_notify_by_pspec(G_OBJECT(self), XfdashboardWindowContentX11Properties[PROP_UNMAPPED_WINDOW_ICON_X_FILL]);
+	}
+}
+
+/* Get/set y fill of unmapped window icon */
+gboolean xfdashboard_window_content_x11_get_unmapped_window_icon_y_fill(XfdashboardWindowContentX11 *self)
+{
+	g_return_val_if_fail(XFDASHBOARD_IS_WINDOW_CONTENT_X11(self), FALSE);
+
+	return(self->priv->unmappedWindowIconYFill);
+}
+
+void xfdashboard_window_content_x11_set_unmapped_window_icon_y_fill(XfdashboardWindowContentX11 *self, const gboolean inFill)
+{
+	XfdashboardWindowContentX11Private		*priv;
+
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_CONTENT_X11(self));
+
+	priv=self->priv;
+
+	/* Set value if changed */
+	if(priv->unmappedWindowIconYFill!=inFill)
+	{
+		/* Set value */
+		priv->unmappedWindowIconYFill=inFill;
+
+		/* Invalidate ourselve to get us redrawn */
+		clutter_content_invalidate(CLUTTER_CONTENT(self));
+
+		/* Notify about property change */
+		g_object_notify_by_pspec(G_OBJECT(self), XfdashboardWindowContentX11Properties[PROP_UNMAPPED_WINDOW_ICON_Y_FILL]);
+	}
+}
+
+/* Get/set x align of unmapped window icon */
+gfloat xfdashboard_window_content_x11_get_unmapped_window_icon_x_align(XfdashboardWindowContentX11 *self)
+{
+	g_return_val_if_fail(XFDASHBOARD_IS_WINDOW_CONTENT_X11(self), 0.0f);
+
+	return(self->priv->unmappedWindowIconXAlign);
+}
+
+void xfdashboard_window_content_x11_set_unmapped_window_icon_x_align(XfdashboardWindowContentX11 *self, const gfloat inAlign)
+{
+	XfdashboardWindowContentX11Private		*priv;
+
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_CONTENT_X11(self));
+	g_return_if_fail(inAlign>=0.0f && inAlign<=1.0f);
+
+	priv=self->priv;
+
+	/* Set value if changed */
+	if(priv->unmappedWindowIconXAlign!=inAlign)
+	{
+		/* Set value */
+		priv->unmappedWindowIconXAlign=inAlign;
+
+		/* Invalidate ourselve to get us redrawn */
+		clutter_content_invalidate(CLUTTER_CONTENT(self));
+
+		/* Notify about property change */
+		g_object_notify_by_pspec(G_OBJECT(self), XfdashboardWindowContentX11Properties[PROP_UNMAPPED_WINDOW_ICON_X_ALIGN]);
+	}
+}
+
+/* Get/set y align of unmapped window icon */
+gfloat xfdashboard_window_content_x11_get_unmapped_window_icon_y_align(XfdashboardWindowContentX11 *self)
+{
+	g_return_val_if_fail(XFDASHBOARD_IS_WINDOW_CONTENT_X11(self), 0.0f);
+
+	return(self->priv->unmappedWindowIconYAlign);
+}
+
+void xfdashboard_window_content_x11_set_unmapped_window_icon_y_align(XfdashboardWindowContentX11 *self, const gfloat inAlign)
+{
+	XfdashboardWindowContentX11Private		*priv;
+
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_CONTENT_X11(self));
+	g_return_if_fail(inAlign>=0.0f && inAlign<=1.0f);
+
+	priv=self->priv;
+
+	/* Set value if changed */
+	if(priv->unmappedWindowIconYAlign!=inAlign)
+	{
+		/* Set value */
+		priv->unmappedWindowIconYAlign=inAlign;
+
+		/* Invalidate ourselve to get us redrawn */
+		clutter_content_invalidate(CLUTTER_CONTENT(self));
+
+		/* Notify about property change */
+		g_object_notify_by_pspec(G_OBJECT(self), XfdashboardWindowContentX11Properties[PROP_UNMAPPED_WINDOW_ICON_Y_ALIGN]);
+	}
+}
+
+/* Get/set x scale of unmapped window icon */
+gfloat xfdashboard_window_content_x11_get_unmapped_window_icon_x_scale(XfdashboardWindowContentX11 *self)
+{
+	g_return_val_if_fail(XFDASHBOARD_IS_WINDOW_CONTENT_X11(self), 0.0f);
+
+	return(self->priv->unmappedWindowIconXScale);
+}
+
+void xfdashboard_window_content_x11_set_unmapped_window_icon_x_scale(XfdashboardWindowContentX11 *self, const gfloat inScale)
+{
+	XfdashboardWindowContentX11Private		*priv;
+
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_CONTENT_X11(self));
+	g_return_if_fail(inScale>=0.0f);
+
+	priv=self->priv;
+
+	/* Set value if changed */
+	if(priv->unmappedWindowIconXScale!=inScale)
+	{
+		/* Set value */
+		priv->unmappedWindowIconXScale=inScale;
+
+		/* Invalidate ourselve to get us redrawn */
+		clutter_content_invalidate(CLUTTER_CONTENT(self));
+
+		/* Notify about property change */
+		g_object_notify_by_pspec(G_OBJECT(self), XfdashboardWindowContentX11Properties[PROP_UNMAPPED_WINDOW_ICON_X_SCALE]);
+	}
+}
+
+/* Get/set y scale of unmapped window icon */
+gfloat xfdashboard_window_content_x11_get_unmapped_window_icon_y_scale(XfdashboardWindowContentX11 *self)
+{
+	g_return_val_if_fail(XFDASHBOARD_IS_WINDOW_CONTENT_X11(self), 0.0f);
+
+	return(self->priv->unmappedWindowIconYScale);
+}
+
+void xfdashboard_window_content_x11_set_unmapped_window_icon_y_scale(XfdashboardWindowContentX11 *self, const gfloat inScale)
+{
+	XfdashboardWindowContentX11Private		*priv;
+
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_CONTENT_X11(self));
+	g_return_if_fail(inScale>=0.0f);
+
+	priv=self->priv;
+
+	/* Set value if changed */
+	if(priv->unmappedWindowIconYScale!=inScale)
+	{
+		/* Set value */
+		priv->unmappedWindowIconYScale=inScale;
+
+		/* Invalidate ourselve to get us redrawn */
+		clutter_content_invalidate(CLUTTER_CONTENT(self));
+
+		/* Notify about property change */
+		g_object_notify_by_pspec(G_OBJECT(self), XfdashboardWindowContentX11Properties[PROP_UNMAPPED_WINDOW_ICON_Y_SCALE]);
+	}
+}
+
+/* Get/set gravity (anchor point) of unmapped window icon */
+XfdashboardAnchorPoint xfdashboard_window_content_x11_get_unmapped_window_icon_anchor_point(XfdashboardWindowContentX11 *self)
+{
+	g_return_val_if_fail(XFDASHBOARD_IS_WINDOW_CONTENT_X11(self), XFDASHBOARD_ANCHOR_POINT_NONE);
+
+	return(self->priv->unmappedWindowIconAnchorPoint);
+}
+
+void xfdashboard_window_content_x11_set_unmapped_window_icon_anchor_point(XfdashboardWindowContentX11 *self, const XfdashboardAnchorPoint inAnchorPoint)
+{
+	XfdashboardWindowContentX11Private		*priv;
+
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_CONTENT_X11(self));
+	g_return_if_fail(inAnchorPoint>=XFDASHBOARD_ANCHOR_POINT_NONE);
+	g_return_if_fail(inAnchorPoint<=XFDASHBOARD_ANCHOR_POINT_CENTER);
+
+	priv=self->priv;
+
+	/* Set value if changed */
+	if(priv->unmappedWindowIconAnchorPoint!=inAnchorPoint)
+	{
+		/* Set value */
+		priv->unmappedWindowIconAnchorPoint=inAnchorPoint;
+
+		/* Invalidate ourselve to get us redrawn */
+		clutter_content_invalidate(CLUTTER_CONTENT(self));
+
+		/* Notify about property change */
+		g_object_notify_by_pspec(G_OBJECT(self), XfdashboardWindowContentX11Properties[PROP_UNMAPPED_WINDOW_ICON_ANCHOR_POINT]);
+	}
+}
diff --git a/libxfdashboard/x11/window-content-x11.h b/libxfdashboard/x11/window-content-x11.h
new file mode 100644
index 0000000..1f2be66
--- /dev/null
+++ b/libxfdashboard/x11/window-content-x11.h
@@ -0,0 +1,111 @@
+/*
+ * window-content: A content to share texture of a window
+ *
+ * Copyright 2012-2017 Stephan Haller <nomad at froevel.de>
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ *
+ *
+ */
+
+#ifndef __LIBXFDASHBOARD_WINDOW_CONTENT_X11__
+#define __LIBXFDASHBOARD_WINDOW_CONTENT_X11__
+
+#if !defined(__LIBXFDASHBOARD_H_INSIDE__) && !defined(LIBXFDASHBOARD_COMPILATION)
+#error "Only <libxfdashboard/libxfdashboard.h> can be included directly."
+#endif
+
+#include <clutter/clutter.h>
+
+#include <libxfdashboard/x11/window-tracker-window-x11.h>
+#include <libxfdashboard/window-tracker-window.h>
+#include <libxfdashboard/types.h>
+
+G_BEGIN_DECLS
+
+#define XFDASHBOARD_TYPE_WINDOW_CONTENT_X11				(xfdashboard_window_content_x11_get_type())
+#define XFDASHBOARD_WINDOW_CONTENT_X11(obj)				(G_TYPE_CHECK_INSTANCE_CAST((obj), XFDASHBOARD_TYPE_WINDOW_CONTENT_X11, XfdashboardWindowContentX11))
+#define XFDASHBOARD_IS_WINDOW_CONTENT_X11(obj)			(G_TYPE_CHECK_INSTANCE_TYPE((obj), XFDASHBOARD_TYPE_WINDOW_CONTENT_X11))
+#define XFDASHBOARD_WINDOW_CONTENT_X11_CLASS(klass)		(G_TYPE_CHECK_CLASS_CAST((klass), XFDASHBOARD_TYPE_WINDOW_CONTENT_X11, XfdashboardWindowContentX11Class))
+#define XFDASHBOARD_IS_WINDOW_CONTENT_X11_CLASS(klass)	(G_TYPE_CHECK_CLASS_TYPE((klass), XFDASHBOARD_TYPE_WINDOW_CONTENT_X11))
+#define XFDASHBOARD_WINDOW_CONTENT_X11_GET_CLASS(obj)	(G_TYPE_INSTANCE_GET_CLASS((obj), XFDASHBOARD_TYPE_WINDOW_CONTENT_X11, XfdashboardWindowContentX11Class))
+
+typedef struct _XfdashboardWindowContentX11				XfdashboardWindowContentX11;
+typedef struct _XfdashboardWindowContentX11Class		XfdashboardWindowContentX11Class;
+typedef struct _XfdashboardWindowContentX11Private		XfdashboardWindowContentX11Private;
+
+struct _XfdashboardWindowContentX11
+{
+	/*< private >*/
+	/* Parent instance */
+	GObject										parent_instance;
+
+	/* Private structure */
+	XfdashboardWindowContentX11Private			*priv;
+};
+
+struct _XfdashboardWindowContentX11Class
+{
+	/*< private >*/
+	/* Parent class */
+	GObjectClass								parent_class;
+
+	/*< public >*/
+	/* Virtual functions */
+};
+
+/* Public API */
+GType xfdashboard_window_content_x11_get_type(void) G_GNUC_CONST;
+
+ClutterContent* xfdashboard_window_content_x11_new_for_window(XfdashboardWindowTrackerWindowX11 *inWindow);
+
+XfdashboardWindowTrackerWindow* xfdashboard_window_content_x11_get_window(XfdashboardWindowContentX11 *self);
+
+gboolean xfdashboard_window_content_x11_is_suspended(XfdashboardWindowContentX11 *self);
+
+const ClutterColor* xfdashboard_window_content_x11_get_outline_color(XfdashboardWindowContentX11 *self);
+void xfdashboard_window_content_x11_set_outline_color(XfdashboardWindowContentX11 *self, const ClutterColor *inColor);
+
+gfloat xfdashboard_window_content_x11_get_outline_width(XfdashboardWindowContentX11 *self);
+void xfdashboard_window_content_x11_set_outline_width(XfdashboardWindowContentX11 *self, const gfloat inWidth);
+
+gboolean xfdashboard_window_content_x11_get_include_window_frame(XfdashboardWindowContentX11 *self);
+void xfdashboard_window_content_x11_set_include_window_frame(XfdashboardWindowContentX11 *self, const gboolean inIncludeFrame);
+
+gboolean xfdashboard_window_content_x11_get_unmapped_window_icon_x_fill(XfdashboardWindowContentX11 *self);
+void xfdashboard_window_content_x11_set_unmapped_window_icon_x_fill(XfdashboardWindowContentX11 *self, const gboolean inFill);
+
+gboolean xfdashboard_window_content_x11_get_unmapped_window_icon_y_fill(XfdashboardWindowContentX11 *self);
+void xfdashboard_window_content_x11_set_unmapped_window_icon_y_fill(XfdashboardWindowContentX11 *self, const gboolean inFill);
+
+gfloat xfdashboard_window_content_x11_get_unmapped_window_icon_x_align(XfdashboardWindowContentX11 *self);
+void xfdashboard_window_content_x11_set_unmapped_window_icon_x_align(XfdashboardWindowContentX11 *self, const gfloat inAlign);
+
+gfloat xfdashboard_window_content_x11_get_unmapped_window_icon_y_align(XfdashboardWindowContentX11 *self);
+void xfdashboard_window_content_x11_set_unmapped_window_icon_y_align(XfdashboardWindowContentX11 *self, const gfloat inAlign);
+
+gfloat xfdashboard_window_content_x11_get_unmapped_window_icon_x_scale(XfdashboardWindowContentX11 *self);
+void xfdashboard_window_content_x11_set_unmapped_window_icon_x_scale(XfdashboardWindowContentX11 *self, const gfloat inScale);
+
+gfloat xfdashboard_window_content_x11_get_unmapped_window_icon_y_scale(XfdashboardWindowContentX11 *self);
+void xfdashboard_window_content_x11_set_unmapped_window_icon_y_scale(XfdashboardWindowContentX11 *self, const gfloat inScale);
+
+XfdashboardAnchorPoint xfdashboard_window_content_x11_get_unmapped_window_icon_anchor_point(XfdashboardWindowContentX11 *self);
+void xfdashboard_window_content_x11_set_unmapped_window_icon_anchor_point(XfdashboardWindowContentX11 *self, const XfdashboardAnchorPoint inAnchorPoint);
+
+G_END_DECLS
+
+#endif
diff --git a/libxfdashboard/x11/window-tracker-monitor-x11.c b/libxfdashboard/x11/window-tracker-monitor-x11.c
new file mode 100644
index 0000000..4a83bdb
--- /dev/null
+++ b/libxfdashboard/x11/window-tracker-monitor-x11.c
@@ -0,0 +1,393 @@
+/*
+ * window-tracker-monitor: A monitor object tracked by window tracker.
+ *                         It provides information about position and
+ *                         size of monitor within screen and also a flag
+ *                         if this monitor is the primary one.
+ * 
+ * Copyright 2012-2017 Stephan Haller <nomad at froevel.de>
+ * 
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ * 
+ * 
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <libxfdashboard/x11/window-tracker-monitor-x11.h>
+
+#include <glib/gi18n-lib.h>
+#include <gdk/gdkx.h>
+
+#include <libxfdashboard/window-tracker-monitor.h>
+#include <libxfdashboard/compat.h>
+#include <libxfdashboard/debug.h>
+
+
+/* Define this class in GObject system */
+static void _xfdashboard_window_tracker_monitor_x11_x11_window_tracker_monitor_iface_init(XfdashboardWindowTrackerMonitorInterface *iface);
+
+G_DEFINE_TYPE_WITH_CODE(XfdashboardWindowTrackerMonitorX11,
+						xfdashboard_window_tracker_monitor_x11,
+						G_TYPE_OBJECT,
+						G_IMPLEMENT_INTERFACE(XFDASHBOARD_TYPE_WINDOW_TRACKER_MONITOR, _xfdashboard_window_tracker_monitor_x11_x11_window_tracker_monitor_iface_init))
+
+/* Private structure - access only by public API if needed */
+#define XFDASHBOARD_WINDOW_TRACKER_MONITOR_X11_GET_PRIVATE(obj)                \
+	(G_TYPE_INSTANCE_GET_PRIVATE((obj), XFDASHBOARD_TYPE_WINDOW_TRACKER_MONITOR_X11, XfdashboardWindowTrackerMonitorX11Private))
+
+struct _XfdashboardWindowTrackerMonitorX11Private
+{
+	/* Properties related */
+	gint				monitorIndex;
+	gboolean			isPrimary;
+
+	/* Instance related */
+	GdkScreen			*screen;
+	GdkRectangle		geometry;
+};
+
+/* Properties */
+enum
+{
+	PROP_0,
+
+	/* Overriden properties of interface: XfdashboardWindowTrackerMonitor */
+	PROP_MONITOR_INDEX,
+	PROP_IS_PRIMARY,
+
+	PROP_LAST
+};
+
+static GParamSpec* XfdashboardWindowTrackerMonitorX11Properties[PROP_LAST]={ 0, };
+
+
+/* IMPLEMENTATION: Private variables and methods */
+
+/* Set primary monitor flag */
+static void _xfdashboard_window_tracker_monitor_x11_update_primary(XfdashboardWindowTrackerMonitorX11 *self)
+{
+	XfdashboardWindowTrackerMonitorX11Private	*priv;
+	gint										primaryIndex;
+	gboolean									isPrimary;
+
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_MONITOR(self));
+
+	priv=self->priv;
+
+	/* Get primary flag */
+	primaryIndex=gdk_screen_get_primary_monitor(priv->screen);
+	if(primaryIndex==priv->monitorIndex) isPrimary=TRUE;
+		else isPrimary=FALSE;
+
+	/* Set value if changed */
+	if(priv->isPrimary!=isPrimary)
+	{
+		XFDASHBOARD_DEBUG(self, WINDOWS,
+							"Monitor %d changes primary state from %s to %s",
+							priv->monitorIndex,
+							priv->isPrimary ? "yes" : "no",
+							isPrimary ? "yes" : "no");
+
+		/* Set value */
+		priv->isPrimary=isPrimary;
+
+		/* Notify about property change */
+		g_object_notify_by_pspec(G_OBJECT(self), XfdashboardWindowTrackerMonitorX11Properties[PROP_IS_PRIMARY]);
+
+		/* Emit signal */
+		g_signal_emit_by_name(self, "primary-changed");
+	}
+}
+
+/* Update monitor geometry */
+static void _xfdashboard_window_tracker_monitor_x11_update_geometry(XfdashboardWindowTrackerMonitorX11 *self)
+{
+	XfdashboardWindowTrackerMonitorX11Private	*priv;
+	GdkRectangle								geometry;
+
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_MONITOR_X11(self));
+
+	priv=self->priv;
+
+	/* Check if monitor is valid */
+	if(priv->monitorIndex>=gdk_screen_get_n_monitors(priv->screen)) return;
+
+	/* Get monitor geometry */
+	gdk_screen_get_monitor_geometry(priv->screen, priv->monitorIndex, &geometry);
+
+	/* Set value if changed */
+	if(geometry.x!=priv->geometry.x ||
+		geometry.y!=priv->geometry.y ||
+		geometry.width!=priv->geometry.width ||
+		geometry.height!=priv->geometry.height)
+	{
+		/* Set value */
+		priv->geometry.x=geometry.x;
+		priv->geometry.y=geometry.y;
+		priv->geometry.width=geometry.width;
+		priv->geometry.height=geometry.height;
+
+		/* Emit signal */
+		g_signal_emit_by_name(self, "geometry-changed");
+		XFDASHBOARD_DEBUG(self, WINDOWS,
+							"Monitor %d moved to %d,%d and resized to %dx%d",
+							priv->monitorIndex,
+							priv->geometry.x, priv->geometry.y,
+							priv->geometry.width, priv->geometry.height);
+	}
+}
+
+/* Set monitor index this object belongs to and to monitor */
+static void _xfdashboard_window_tracker_monitor_x11_set_index(XfdashboardWindowTrackerMonitorX11 *self,
+																gint inIndex)
+{
+	XfdashboardWindowTrackerMonitorX11Private		*priv;
+
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_MONITOR_X11(self));
+	g_return_if_fail(inIndex>=0);
+	g_return_if_fail(inIndex<gdk_screen_get_n_monitors(self->priv->screen));
+
+	priv=self->priv;
+
+	/* Freeze notification */
+	g_object_freeze_notify(G_OBJECT(self));
+
+	/* Set value if changed */
+	if(priv->monitorIndex!=inIndex)
+	{
+		/* Set value */
+		priv->monitorIndex=inIndex;
+
+		/* Update primary monitor flag */
+		_xfdashboard_window_tracker_monitor_x11_update_primary(self);
+
+		/* Update geometry of monitor */
+		_xfdashboard_window_tracker_monitor_x11_update_geometry(self);
+
+		/* Notify about property change */
+		g_object_notify_by_pspec(G_OBJECT(self), XfdashboardWindowTrackerMonitorX11Properties[PROP_MONITOR_INDEX]);
+	}
+
+	/* Thaw notification */
+	g_object_thaw_notify(G_OBJECT(self));
+}
+
+/* Number of monitors, primary monitor or size of any monitor changed */
+static void _xfdashboard_window_tracker_monitor_x11_on_monitors_changed(XfdashboardWindowTrackerMonitorX11 *self,
+																			gpointer inUserData)
+{
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_MONITOR_X11(self));
+	g_return_if_fail(GDK_IS_SCREEN(inUserData));
+
+	/* Update primary monitor flag */
+	_xfdashboard_window_tracker_monitor_x11_update_primary(self);
+
+	/* Update geometry of monitor */
+	_xfdashboard_window_tracker_monitor_x11_update_geometry(self);
+}
+
+
+/* IMPLEMENTATION: Interface XfdashboardWindowTrackerMonitor */
+
+/* Determine if monitor is primary one */
+static gboolean _xfdashboard_window_tracker_monitor_x11_x11_window_tracker_monitor_is_primary(XfdashboardWindowTrackerMonitor *inMonitor)
+{
+	XfdashboardWindowTrackerMonitorX11			*self;
+	XfdashboardWindowTrackerMonitorX11Private	*priv;
+
+	g_return_val_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_MONITOR_X11(inMonitor), FALSE);
+
+	self=XFDASHBOARD_WINDOW_TRACKER_MONITOR_X11(inMonitor);
+	priv=self->priv;
+
+	return(priv->isPrimary);
+}
+
+/* Get monitor index */
+static gint _xfdashboard_window_tracker_monitor_x11_x11_window_tracker_monitor_get_number(XfdashboardWindowTrackerMonitor *inMonitor)
+{
+	XfdashboardWindowTrackerMonitorX11			*self;
+	XfdashboardWindowTrackerMonitorX11Private	*priv;
+
+	g_return_val_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_MONITOR_X11(inMonitor), 0);
+
+	self=XFDASHBOARD_WINDOW_TRACKER_MONITOR_X11(inMonitor);
+	priv=self->priv;
+
+	return(priv->monitorIndex);
+}
+
+/* Get geometry of monitor */
+static void _xfdashboard_window_tracker_monitor_x11_x11_window_tracker_monitor_get_geometry(XfdashboardWindowTrackerMonitor *inMonitor,
+																							gint *outX,
+																							gint *outY,
+																							gint *outWidth,
+																							gint *outHeight)
+{
+	XfdashboardWindowTrackerMonitorX11			*self;
+	XfdashboardWindowTrackerMonitorX11Private	*priv;
+
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_MONITOR_X11(inMonitor));
+
+	self=XFDASHBOARD_WINDOW_TRACKER_MONITOR_X11(inMonitor);
+	priv=self->priv;
+
+	/* Set position and size of monitor */
+	if(outX) *outX=priv->geometry.x;
+	if(outY) *outY=priv->geometry.y;
+	if(outWidth) *outWidth=priv->geometry.width;
+	if(outHeight) *outHeight=priv->geometry.height;
+}
+
+/* Interface initialization
+ * Set up default functions
+ */
+static void _xfdashboard_window_tracker_monitor_x11_x11_window_tracker_monitor_iface_init(XfdashboardWindowTrackerMonitorInterface *iface)
+{
+	iface->is_primary=_xfdashboard_window_tracker_monitor_x11_x11_window_tracker_monitor_is_primary;
+	iface->get_number=_xfdashboard_window_tracker_monitor_x11_x11_window_tracker_monitor_get_number;
+	iface->get_geometry=_xfdashboard_window_tracker_monitor_x11_x11_window_tracker_monitor_get_geometry;
+}
+
+
+/* IMPLEMENTATION: GObject */
+
+/* Dispose this object */
+static void _xfdashboard_window_tracker_monitor_x11_dispose(GObject *inObject)
+{
+	XfdashboardWindowTrackerMonitorX11			*self=XFDASHBOARD_WINDOW_TRACKER_MONITOR_X11(inObject);
+	XfdashboardWindowTrackerMonitorX11Private	*priv=self->priv;
+
+	/* Release allocated resources */
+	if(priv->screen)
+	{
+		g_signal_handlers_disconnect_by_data(priv->screen, self);
+		priv->screen=NULL;
+	}
+
+	/* Call parent's class dispose method */
+	G_OBJECT_CLASS(xfdashboard_window_tracker_monitor_x11_parent_class)->dispose(inObject);
+}
+
+/* Set/get properties */
+static void _xfdashboard_window_tracker_monitor_x11_set_property(GObject *inObject,
+																	guint inPropID,
+																	const GValue *inValue,
+																	GParamSpec *inSpec)
+{
+	XfdashboardWindowTrackerMonitorX11			*self=XFDASHBOARD_WINDOW_TRACKER_MONITOR_X11(inObject);
+
+	switch(inPropID)
+	{
+		case PROP_MONITOR_INDEX:
+			_xfdashboard_window_tracker_monitor_x11_set_index(self, g_value_get_int(inValue));
+			break;
+
+		default:
+			G_OBJECT_WARN_INVALID_PROPERTY_ID(inObject, inPropID, inSpec);
+			break;
+	}
+}
+
+static void _xfdashboard_window_tracker_monitor_x11_get_property(GObject *inObject,
+																	guint inPropID,
+																	GValue *outValue,
+																	GParamSpec *inSpec)
+{
+	XfdashboardWindowTrackerMonitorX11			*self=XFDASHBOARD_WINDOW_TRACKER_MONITOR_X11(inObject);
+	XfdashboardWindowTrackerMonitorX11Private	*priv=self->priv;
+
+	switch(inPropID)
+	{
+		case PROP_IS_PRIMARY:
+			g_value_set_boolean(outValue, priv->isPrimary);
+			break;
+
+		case PROP_MONITOR_INDEX:
+			g_value_set_uint(outValue, priv->monitorIndex);
+			break;
+
+		default:
+			G_OBJECT_WARN_INVALID_PROPERTY_ID(inObject, inPropID, inSpec);
+			break;
+	}
+}
+
+/* Class initialization
+ * Override functions in parent classes and define properties
+ * and signals
+ */
+static void xfdashboard_window_tracker_monitor_x11_class_init(XfdashboardWindowTrackerMonitorX11Class *klass)
+{
+	GObjectClass						*gobjectClass=G_OBJECT_CLASS(klass);
+	XfdashboardWindowTrackerMonitor		*monitorIface;
+	GParamSpec							*paramSpec;
+
+	/* Reference interface type to lookup properties etc. */
+	monitorIface=g_type_default_interface_ref(XFDASHBOARD_TYPE_WINDOW_TRACKER_MONITOR);
+
+	/* Override functions */
+	gobjectClass->dispose=_xfdashboard_window_tracker_monitor_x11_dispose;
+	gobjectClass->set_property=_xfdashboard_window_tracker_monitor_x11_set_property;
+	gobjectClass->get_property=_xfdashboard_window_tracker_monitor_x11_get_property;
+
+	/* Set up private structure */
+	g_type_class_add_private(klass, sizeof(XfdashboardWindowTrackerMonitorX11Private));
+
+	/* Define properties */
+	paramSpec=g_object_interface_find_property(monitorIface, "is-primary");
+	XfdashboardWindowTrackerMonitorX11Properties[PROP_IS_PRIMARY]=
+		g_param_spec_override("is-primary", paramSpec);
+
+	paramSpec=g_object_interface_find_property(monitorIface, "monitor-index");
+	XfdashboardWindowTrackerMonitorX11Properties[PROP_MONITOR_INDEX]=
+		g_param_spec_override("monitor-index", paramSpec);
+
+	g_object_class_install_properties(gobjectClass, PROP_LAST, XfdashboardWindowTrackerMonitorX11Properties);
+
+	/* Release allocated resources */
+	g_type_default_interface_unref(monitorIface);
+}
+
+/* Object initialization
+ * Create private structure and set up default values
+ */
+static void xfdashboard_window_tracker_monitor_x11_init(XfdashboardWindowTrackerMonitorX11 *self)
+{
+	XfdashboardWindowTrackerMonitorX11Private		*priv;
+
+	priv=self->priv=XFDASHBOARD_WINDOW_TRACKER_MONITOR_X11_GET_PRIVATE(self);
+
+	/* Set default values */
+	priv->monitorIndex=0;
+	priv->isPrimary=FALSE;
+	priv->screen=gdk_screen_get_default();
+	priv->geometry.x=0;
+	priv->geometry.y=0;
+	priv->geometry.width=0;
+	priv->geometry.height=0;
+
+	/* Get initial primary monitor flag */
+	_xfdashboard_window_tracker_monitor_x11_update_primary(self);
+
+	/* Get initial geometry of monitor */
+	_xfdashboard_window_tracker_monitor_x11_update_geometry(self);
+
+	/* Connect signals */
+	g_signal_connect_swapped(priv->screen, "monitors-changed", G_CALLBACK(_xfdashboard_window_tracker_monitor_x11_on_monitors_changed), self);
+}
diff --git a/libxfdashboard/x11/window-tracker-monitor-x11.h b/libxfdashboard/x11/window-tracker-monitor-x11.h
new file mode 100644
index 0000000..b98afce
--- /dev/null
+++ b/libxfdashboard/x11/window-tracker-monitor-x11.h
@@ -0,0 +1,76 @@
+/*
+ * window-tracker-monitor: A monitor object tracked by window tracker.
+ *                         It provides information about position and
+ *                         size of monitor within screen and also a flag
+ *                         if this monitor is the primary one.
+ * 
+ * Copyright 2012-2017 Stephan Haller <nomad at froevel.de>
+ * 
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ * 
+ * 
+ */
+
+#ifndef __LIBXFDASHBOARD_WINDOW_TRACKER_MONITOR_X11__
+#define __LIBXFDASHBOARD_WINDOW_TRACKER_MONITOR_X11__
+
+#if !defined(__LIBXFDASHBOARD_H_INSIDE__) && !defined(LIBXFDASHBOARD_COMPILATION)
+#error "Only <libxfdashboard/libxfdashboard.h> can be included directly."
+#endif
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define XFDASHBOARD_TYPE_WINDOW_TRACKER_MONITOR_X11					(xfdashboard_window_tracker_monitor_x11_get_type())
+#define XFDASHBOARD_WINDOW_TRACKER_MONITOR_X11(obj)					(G_TYPE_CHECK_INSTANCE_CAST((obj), XFDASHBOARD_TYPE_WINDOW_TRACKER_MONITOR_X11, XfdashboardWindowTrackerMonitorX11))
+#define XFDASHBOARD_IS_WINDOW_TRACKER_MONITOR_X11(obj)				(G_TYPE_CHECK_INSTANCE_TYPE((obj), XFDASHBOARD_TYPE_WINDOW_TRACKER_MONITOR_X11))
+#define XFDASHBOARD_WINDOW_TRACKER_MONITOR_X11_CLASS(klass)			(G_TYPE_CHECK_CLASS_CAST((klass), XFDASHBOARD_TYPE_WINDOW_TRACKER_MONITOR_X11, XfdashboardWindowTrackerMonitorX11Class))
+#define XFDASHBOARD_IS_WINDOW_TRACKER_MONITOR_X11_CLASS(klass)		(G_TYPE_CHECK_CLASS_TYPE((klass), XFDASHBOARD_TYPE_WINDOW_TRACKER_MONITOR_X11))
+#define XFDASHBOARD_WINDOW_TRACKER_MONITOR_X11_GET_CLASS(obj)		(G_TYPE_INSTANCE_GET_CLASS((obj), XFDASHBOARD_TYPE_WINDOW_TRACKER_MONITOR_X11, XfdashboardWindowTrackerMonitorX11Class))
+
+typedef struct _XfdashboardWindowTrackerMonitorX11					XfdashboardWindowTrackerMonitorX11;
+typedef struct _XfdashboardWindowTrackerMonitorX11Class				XfdashboardWindowTrackerMonitorX11Class;
+typedef struct _XfdashboardWindowTrackerMonitorX11Private			XfdashboardWindowTrackerMonitorX11Private;
+
+struct _XfdashboardWindowTrackerMonitorX11
+{
+	/*< private >*/
+	/* Parent instance */
+	GObject										parent_instance;
+
+	/* Private structure */
+	XfdashboardWindowTrackerMonitorX11Private		*priv;
+};
+
+struct _XfdashboardWindowTrackerMonitorX11Class
+{
+	/*< private >*/
+	/* Parent class */
+	GObjectClass								parent_class;
+
+	/*< public >*/
+	/* Virtual functions */
+	void (*primary_changed)(XfdashboardWindowTrackerMonitorX11 *self);
+	void (*geometry_changed)(XfdashboardWindowTrackerMonitorX11 *self);
+};
+
+/* Public API */
+GType xfdashboard_window_tracker_monitor_x11_get_type(void) G_GNUC_CONST;
+
+G_END_DECLS
+
+#endif	/* __LIBXFDASHBOARD_WINDOW_TRACKER_MONITOR_X11__ */
diff --git a/libxfdashboard/x11/window-tracker-window-x11.c b/libxfdashboard/x11/window-tracker-window-x11.c
new file mode 100644
index 0000000..9337eff
--- /dev/null
+++ b/libxfdashboard/x11/window-tracker-window-x11.c
@@ -0,0 +1,1811 @@
+/*
+ * window-tracker-window: A window tracked by window tracker and also
+ *                        a wrapper class around WnckWindow.
+ *                        By wrapping libwnck objects we can use a virtual
+ *                        stable API while the API in libwnck changes
+ *                        within versions. We only need to use #ifdefs in
+ *                        window tracker object and nowhere else in the code.
+ * 
+ * Copyright 2012-2017 Stephan Haller <nomad at froevel.de>
+ * 
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ * 
+ * 
+ */
+
+/**
+ * SECTION:window-tracker-window-x11
+ * @short_description: A window used by X11 window tracker
+ * @include: xfdashboard/x11/window-tracker-window-x11.h
+ *
+ * TODO: DESCRIPTION
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <libxfdashboard/x11/window-tracker-window-x11.h>
+
+#define WNCK_I_KNOW_THIS_IS_UNSTABLE
+#include <libwnck/libwnck.h>
+
+#include <glib/gi18n-lib.h>
+#include <clutter/x11/clutter-x11.h>
+#include <gtk/gtkx.h>
+#include <gdk/gdkx.h>
+#ifdef HAVE_XINERAMA
+#include <X11/extensions/Xinerama.h>
+#endif
+
+#include <libxfdashboard/x11/window-content-x11.h>
+#include <libxfdashboard/x11/window-tracker-workspace-x11.h>
+#include <libxfdashboard/x11/window-tracker-x11.h>
+#include <libxfdashboard/window-tracker.h>
+#include <libxfdashboard/marshal.h>
+#include <libxfdashboard/compat.h>
+#include <libxfdashboard/debug.h>
+
+
+/* Define this class in GObject system */
+static void _xfdashboard_window_tracker_window_x11_window_tracker_window_iface_init(XfdashboardWindowTrackerWindowInterface *iface);
+
+G_DEFINE_TYPE_WITH_CODE(XfdashboardWindowTrackerWindowX11,
+						xfdashboard_window_tracker_window_x11,
+						G_TYPE_OBJECT,
+						G_IMPLEMENT_INTERFACE(XFDASHBOARD_TYPE_WINDOW_TRACKER_WINDOW, _xfdashboard_window_tracker_window_x11_window_tracker_window_iface_init))
+
+/* Private structure - access only by public API if needed */
+#define XFDASHBOARD_WINDOW_TRACKER_WINDOW_X11_GET_PRIVATE(obj)                 \
+	(G_TYPE_INSTANCE_GET_PRIVATE((obj), XFDASHBOARD_TYPE_WINDOW_TRACKER_WINDOW_X11, XfdashboardWindowTrackerWindowX11Private))
+
+struct _XfdashboardWindowTrackerWindowX11Private
+{
+	/* Properties related */
+	WnckWindow								*window;
+	XfdashboardWindowTrackerWindowState		state;
+	XfdashboardWindowTrackerWindowAction	actions;
+
+	/* Instance related */
+	WnckWorkspace							*workspace;
+
+	gint									lastGeometryX;
+	gint									lastGeometryY;
+	gint									lastGeometryWidth;
+	gint									lastGeometryHeight;
+};
+
+
+/* Properties */
+enum
+{
+	PROP_0,
+
+	PROP_WINDOW,
+
+	/* Overriden properties of interface: XfdashboardWindowTrackerWindow */
+	PROP_STATE,
+	PROP_ACTIONS,
+
+	PROP_LAST
+};
+
+static GParamSpec* XfdashboardWindowTrackerWindowX11Properties[PROP_LAST]={ 0, };
+
+
+/* IMPLEMENTATION: Private variables and methods */
+#define XFDASHBOARD_WINDOW_TRACKER_WINDOW_X11_WARN_NO_WINDOW(self)             \
+	g_critical(_("No wnck window wrapped at %s in called function %s"),        \
+				G_OBJECT_TYPE_NAME(self),                                      \
+				__func__);
+
+#define XFDASHBOARD_WINDOW_TRACKER_WINDOW_X11_WARN_WRONG_WINDOW(self)          \
+	g_critical(_("Got signal from wrong wnck window wrapped at %s in called function %s"),\
+				G_OBJECT_TYPE_NAME(self),                                      \
+				__func__);
+
+/* Get state of window */
+static void _xfdashboard_window_tracker_window_x11_update_state(XfdashboardWindowTrackerWindowX11 *self)
+{
+	XfdashboardWindowTrackerWindowX11Private	*priv;
+	XfdashboardWindowTrackerWindowState			newState;
+	WnckWindowState								wnckState;
+
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_WINDOW_X11(self));
+
+	priv=self->priv;
+	newState=0;
+
+	/* A wnck window must be wrapped by this object */
+	if(!priv->window)
+	{
+		XFDASHBOARD_WINDOW_TRACKER_WINDOW_X11_WARN_NO_WINDOW(self);
+	}
+		else
+		{
+			/* Get state of wnck window to determine state */
+			wnckState=wnck_window_get_state(priv->window);
+
+			/* Determine window state */
+			if(wnckState & WNCK_WINDOW_STATE_HIDDEN) newState|=XFDASHBOARD_WINDOW_TRACKER_WINDOW_STATE_HIDDEN;
+
+			if(wnckState & WNCK_WINDOW_STATE_MINIMIZED)
+			{
+				newState|=XFDASHBOARD_WINDOW_TRACKER_WINDOW_STATE_MINIMIZED;
+			}
+				else
+				{
+					if((wnckState & WNCK_WINDOW_STATE_MAXIMIZED_HORIZONTALLY) &&
+						(wnckState & WNCK_WINDOW_STATE_MAXIMIZED_VERTICALLY))
+					{
+						newState|=XFDASHBOARD_WINDOW_TRACKER_WINDOW_STATE_MAXIMIZED;
+					}
+				}
+
+			if(wnckState & WNCK_WINDOW_STATE_FULLSCREEN) newState|=XFDASHBOARD_WINDOW_TRACKER_WINDOW_STATE_FULLSCREEN;
+			if(wnckState & WNCK_WINDOW_STATE_SKIP_PAGER) newState|=XFDASHBOARD_WINDOW_TRACKER_WINDOW_STATE_SKIP_PAGER;
+			if(wnckState & WNCK_WINDOW_STATE_SKIP_TASKLIST) newState|=XFDASHBOARD_WINDOW_TRACKER_WINDOW_STATE_SKIP_TASKLIST;
+			if(wnckState & WNCK_WINDOW_STATE_DEMANDS_ATTENTION) newState|=XFDASHBOARD_WINDOW_TRACKER_WINDOW_STATE_URGENT;
+			if(wnckState & WNCK_WINDOW_STATE_URGENT) newState|=XFDASHBOARD_WINDOW_TRACKER_WINDOW_STATE_URGENT;
+
+			/* "Pin" is not a wnck window state and do not get confused with the
+			 * "sticky" state as it refers only to the window's stickyness on
+			 * the viewport. So we have to ask wnck if it is pinned.
+			 */
+			if(wnck_window_is_pinned(priv->window)) newState|=XFDASHBOARD_WINDOW_TRACKER_WINDOW_STATE_PINNED;
+		}
+
+	/* Set value if changed */
+	if(priv->state!=newState)
+	{
+		/* Set value */
+		priv->state=newState;
+
+		/* Notify about property change */
+		g_object_notify_by_pspec(G_OBJECT(self), XfdashboardWindowTrackerWindowX11Properties[PROP_STATE]);
+	}
+}
+
+/* Get actions of window */
+static void _xfdashboard_window_tracker_window_x11_update_actions(XfdashboardWindowTrackerWindowX11 *self)
+{
+	XfdashboardWindowTrackerWindowX11Private	*priv;
+	XfdashboardWindowTrackerWindowAction		newActions;
+	WnckWindowActions							wnckActions;
+
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_WINDOW_X11(self));
+
+	priv=self->priv;
+	newActions=0;
+
+	/* A wnck window must be wrapped by this object */
+	if(!priv->window)
+	{
+		XFDASHBOARD_WINDOW_TRACKER_WINDOW_X11_WARN_NO_WINDOW(self);
+	}
+		else
+		{
+			/* Get actions of wnck window to determine state */
+			wnckActions=wnck_window_get_actions(priv->window);
+
+			/* Determine window actions */
+			if(wnckActions & WNCK_WINDOW_ACTION_CLOSE) newActions|=XFDASHBOARD_WINDOW_TRACKER_WINDOW_ACTION_CLOSE;
+		}
+
+	/* Set value if changed */
+	if(priv->actions!=newActions)
+	{
+		/* Set value */
+		priv->actions=newActions;
+
+		/* Notify about property change */
+		g_object_notify_by_pspec(G_OBJECT(self), XfdashboardWindowTrackerWindowX11Properties[PROP_ACTIONS]);
+	}
+}
+
+/* Size of screen has changed so resize stage window */
+static void _xfdashboard_window_tracker_window_x11_on_stage_screen_size_changed(XfdashboardWindowTracker *inWindowTracker,
+																				gint inWidth,
+																				gint inHeight,
+																				gpointer inUserData)
+{
+#ifdef HAVE_XINERAMA
+	XfdashboardWindowTrackerWindowX11	*realStageWindow;
+	WnckWindow							*stageWindow;
+	GdkDisplay							*display;
+	GdkScreen							*screen;
+	XineramaScreenInfo					*monitors;
+	int									monitorsCount;
+	gint								top, bottom, left, right;
+	gint								topIndex, bottomIndex, leftIndex, rightIndex;
+	gint								i;
+	Atom								atomFullscreenMonitors;
+	XEvent								xEvent;
+
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER(inWindowTracker));
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_WINDOW_X11(inUserData));
+
+	realStageWindow=XFDASHBOARD_WINDOW_TRACKER_WINDOW_X11(inUserData);
+
+	XFDASHBOARD_DEBUG(inWindowTracker, WINDOWS, "Set fullscreen across all monitors using Xinerama");
+
+	/* Get wnck window for stage window object as it is needed a lot from this
+	 * point on.
+	 */
+	stageWindow=xfdashboard_window_tracker_window_x11_get_window(realStageWindow);
+
+	/* If window manager does not support fullscreen across all monitors
+	 * return here.
+	 */
+	if(!wnck_screen_net_wm_supports(wnck_window_get_screen(stageWindow), "_NET_WM_FULLSCREEN_MONITORS"))
+	{
+		g_warning(_("Keep window fullscreen on primary monitor because window manager does not support _NET_WM_FULLSCREEN_MONITORS."));
+		return;
+	}
+
+	/* Get display */
+	display=gdk_display_get_default();
+
+	/* Get screen */
+	screen=gdk_screen_get_default();
+
+	/* Check if Xinerama is active on display. If not try to move and resize
+	 * stage window to primary monitor.
+	 */
+	if(!XineramaIsActive(GDK_DISPLAY_XDISPLAY(display)))
+	{
+		gint				primaryMonitor;
+		GdkRectangle		geometry;
+
+		/* Get position and size of primary monitor and try to move and resize
+		 * stage window to its position and size. Even if it fails it should
+		 * resize the stage to the size of current monitor this window is
+		 * fullscreened to. Tested with xfwm4.
+		 */
+		primaryMonitor=gdk_screen_get_primary_monitor(screen);
+		gdk_screen_get_monitor_geometry(screen, primaryMonitor, &geometry);
+		wnck_window_set_geometry(stageWindow,
+									WNCK_WINDOW_GRAVITY_STATIC,
+									WNCK_WINDOW_CHANGE_X | WNCK_WINDOW_CHANGE_Y | WNCK_WINDOW_CHANGE_WIDTH | WNCK_WINDOW_CHANGE_HEIGHT,
+									geometry.x, geometry.y, geometry.width, geometry.height);
+		return;
+	}
+
+	/* Get monitors from Xinerama */
+	monitors=XineramaQueryScreens(GDK_DISPLAY_XDISPLAY(display), &monitorsCount);
+	if(monitorsCount<=0 || !monitors)
+	{
+		if(monitors) XFree(monitors);
+		return;
+	}
+
+	/* Get monitor indices for each corner of screen */
+	top=gdk_screen_get_height(screen);
+	left=gdk_screen_get_width(screen);
+	bottom=0;
+	right=0;
+	topIndex=bottomIndex=leftIndex=rightIndex=0;
+	for(i=0; i<monitorsCount; i++)
+	{
+		XFDASHBOARD_DEBUG(inWindowTracker, WINDOWS,
+							"Checking edges at monitor %d with upper-left at %d,%d and lower-right at %d,%d [size: %dx%d]",
+							i,
+							monitors[i].x_org,
+							monitors[i].y_org,
+							monitors[i].x_org+monitors[i].width, monitors[i].y_org+monitors[i].height,
+							monitors[i].width, monitors[i].height);
+
+		if(left>monitors[i].x_org)
+		{
+			left=monitors[i].x_org;
+			leftIndex=i;
+		}
+
+		if(right<(monitors[i].x_org+monitors[i].width))
+		{
+			right=(monitors[i].x_org+monitors[i].width);
+			rightIndex=i;
+		}
+
+		if(top>monitors[i].y_org)
+		{
+			top=monitors[i].y_org;
+			topIndex=i;
+		}
+
+		if(bottom<(monitors[i].y_org+monitors[i].height))
+		{
+			bottom=(monitors[i].y_org+monitors[i].height);
+			bottomIndex=i;
+		}
+	}
+	XFDASHBOARD_DEBUG(inWindowTracker, WINDOWS,
+						"Found edge monitors: left=%d (monitor %d), right=%d (monitor %d), top=%d (monitor %d), bottom=%d (monitor %d)",
+						left, leftIndex,
+						right, rightIndex,
+						top, topIndex,
+						bottom, bottomIndex);
+
+	/* Get X atom for fullscreen-across-all-monitors */
+	atomFullscreenMonitors=XInternAtom(GDK_DISPLAY_XDISPLAY(display),
+										"_NET_WM_FULLSCREEN_MONITORS",
+										False);
+
+	/* Send event to X to set window to fullscreen over all monitors */
+	memset(&xEvent, 0, sizeof(xEvent));
+	xEvent.type=ClientMessage;
+	xEvent.xclient.window=wnck_window_get_xid(stageWindow);
+	xEvent.xclient.display=GDK_DISPLAY_XDISPLAY(display);
+	xEvent.xclient.message_type=atomFullscreenMonitors;
+	xEvent.xclient.format=32;
+	xEvent.xclient.data.l[0]=topIndex;
+	xEvent.xclient.data.l[1]=bottomIndex;
+	xEvent.xclient.data.l[2]=leftIndex;
+	xEvent.xclient.data.l[3]=rightIndex;
+	xEvent.xclient.data.l[4]=0;
+	XSendEvent(GDK_DISPLAY_XDISPLAY(display),
+				DefaultRootWindow(GDK_DISPLAY_XDISPLAY(display)),
+				False,
+				SubstructureRedirectMask | SubstructureNotifyMask,
+				&xEvent);
+
+	/* Release allocated resources */
+	if(monitors) XFree(monitors);
+#else
+	XfdashboardWindowTrackerWindowX11	*realStageWindow;
+	WnckWindow							*stageWindow;
+	GdkScreen							*screen;
+	gint								primaryMonitor;
+	GdkRectangle						geometry;
+
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER(inWindowTracker));
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_WINDOW_X11(inUserData));
+
+	realStageWindow=XFDASHBOARD_WINDOW_TRACKER_WINDOW_X11(inUserData);
+
+	XFDASHBOARD_DEBUG(inWindowTracker, WINDOWS, "No support for multiple monitor: Setting fullscreen on primary monitor");
+
+	/* Get wnck window for stage window object as it is needed a lot from this
+	 * point on.
+	 */
+	stageWindow=xfdashboard_window_tracker_window_x11_get_window(realStageWindow);
+
+	/* Get screen */
+	screen=gdk_screen_get_default();
+
+	/* Get position and size of primary monitor and try to move and resize
+	 * stage window to its position and size. Even if it fails it should
+	 * resize the stage to the size of current monitor this window is
+	 * fullscreened to. Tested with xfwm4.
+	 */
+	primaryMonitor=gdk_screen_get_primary_monitor(screen);
+	gdk_screen_get_monitor_geometry(screen, primaryMonitor, &geometry);
+	wnck_window_set_geometry(stageWindow,
+								WNCK_WINDOW_GRAVITY_STATIC,
+								WNCK_WINDOW_CHANGE_X | WNCK_WINDOW_CHANGE_Y | WNCK_WINDOW_CHANGE_WIDTH | WNCK_WINDOW_CHANGE_HEIGHT,
+								geometry.x, geometry.y, geometry.width, geometry.height);
+
+	XFDASHBOARD_DEBUG(inWindowTracker, WINDOWS,
+						"Moving stage window to %d,%d and resize to %dx%d",
+						geometry.x, geometry.y,
+						geometry.width, geometry.height);
+#endif
+}
+
+/* State of stage window changed */
+static void _xfdashboard_window_tracker_window_x11_on_stage_state_changed(WnckWindow *inWindow,
+																			WnckWindowState inChangedMask,
+																			WnckWindowState inNewValue,
+																			gpointer inUserData)
+{
+	g_return_if_fail(WNCK_IS_WINDOW(inWindow));
+
+	/* Set 'skip-tasklist' if changed */
+	if((inChangedMask & WNCK_WINDOW_STATE_SKIP_TASKLIST) &&
+		!(inNewValue & WNCK_WINDOW_STATE_SKIP_TASKLIST))
+	{
+		wnck_window_set_skip_tasklist(WNCK_WINDOW(inWindow), TRUE);
+		XFDASHBOARD_DEBUG(inWindow, WINDOWS,
+							"State 'skip-tasklist' for stage window %p needs reset",
+							inWindow);
+	}
+
+	/* Set 'skip-pager' if changed */
+	if((inChangedMask & WNCK_WINDOW_STATE_SKIP_PAGER) &&
+		!(inNewValue & WNCK_WINDOW_STATE_SKIP_PAGER))
+	{
+		wnck_window_set_skip_pager(WNCK_WINDOW(inWindow), TRUE);
+		XFDASHBOARD_DEBUG(inWindow, WINDOWS,
+							"State 'skip-pager' for stage window %p needs reset",
+							inWindow);
+	}
+
+	/* Set 'make-above' if changed */
+	if((inChangedMask & WNCK_WINDOW_STATE_ABOVE) &&
+		!(inNewValue & WNCK_WINDOW_STATE_ABOVE))
+	{
+		wnck_window_make_above(WNCK_WINDOW(inWindow));
+		XFDASHBOARD_DEBUG(inWindow, WINDOWS,
+							"State 'make-above' for stage window %p needs reset",
+							inWindow);
+	}
+}
+
+/* The active window changed. Reselect stage window as active one if it is visible */
+static void _xfdashboard_window_tracker_window_x11_on_stage_active_window_changed(WnckScreen *inScreen,
+																					WnckWindow *inPreviousWindow,
+																					gpointer inUserData)
+{
+	XfdashboardWindowTrackerWindowX11			*self;
+	XfdashboardWindowTrackerWindowX11Private	*priv;
+	WnckWindow									*activeWindow;
+	gboolean									reselect;
+
+	g_return_if_fail(WNCK_IS_SCREEN(inScreen));
+	g_return_if_fail(inPreviousWindow==NULL || WNCK_IS_WINDOW(inPreviousWindow));
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_WINDOW_X11(inUserData));
+
+	self=XFDASHBOARD_WINDOW_TRACKER_WINDOW_X11(inUserData);
+	priv=self->priv;
+	reselect=FALSE;
+
+	/* Reactive stage window if not hidden */
+	activeWindow=wnck_screen_get_active_window(inScreen);
+
+	if(inPreviousWindow && inPreviousWindow==priv->window) reselect=TRUE;
+	if(!activeWindow || activeWindow!=priv->window) reselect=TRUE;
+	if(!(priv->state & (XFDASHBOARD_WINDOW_TRACKER_WINDOW_STATE_MINIMIZED | XFDASHBOARD_WINDOW_TRACKER_WINDOW_STATE_HIDDEN))) reselect=TRUE;
+
+	if(reselect)
+	{
+		wnck_window_activate_transient(priv->window, xfdashboard_window_tracker_x11_get_time());
+		XFDASHBOARD_DEBUG(self, WINDOWS,
+							"Active window changed from %p (%s) to %p (%s) but stage window %p is visible and should be active one",
+							inPreviousWindow, inPreviousWindow ? wnck_window_get_name(inPreviousWindow) : "<nil>",
+							activeWindow, activeWindow ? wnck_window_get_name(activeWindow) : "<nil>",
+							priv->window);
+	}
+}
+
+/* Proxy signal for mapped wnck window which changed name */
+static void _xfdashboard_window_tracker_window_x11_on_wnck_name_changed(XfdashboardWindowTrackerWindowX11 *self,
+																		gpointer inUserData)
+{
+	XfdashboardWindowTrackerWindowX11Private	*priv;
+	WnckWindow									*window;
+
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_WINDOW_X11(self));
+	g_return_if_fail(WNCK_IS_WINDOW(inUserData));
+
+	priv=self->priv;
+	window=WNCK_WINDOW(inUserData);
+
+	/* Check that window emitting this signal is the mapped window of this object */
+	if(priv->window!=window)
+	{
+		XFDASHBOARD_WINDOW_TRACKER_WINDOW_X11_WARN_WRONG_WINDOW(self);
+		return;
+	}
+
+	/* Proxy signal */
+	g_signal_emit_by_name(self, "name-changed");
+}
+
+/* Proxy signal for mapped wnck window which changed states */
+static void _xfdashboard_window_tracker_window_x11_on_wnck_state_changed(XfdashboardWindowTrackerWindowX11 *self,
+																			WnckWindowState inChangedStates,
+																			WnckWindowState inNewState,
+																			gpointer inUserData)
+{
+	XfdashboardWindowTrackerWindowX11Private	*priv;
+	WnckWindow									*window;
+
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_WINDOW_X11(self));
+	g_return_if_fail(WNCK_IS_WINDOW(inUserData));
+
+	priv=self->priv;
+	window=WNCK_WINDOW(inUserData);
+
+	/* Check that window emitting this signal is the mapped window of this object */
+	if(priv->window!=window)
+	{
+		XFDASHBOARD_WINDOW_TRACKER_WINDOW_X11_WARN_WRONG_WINDOW(self);
+		return;
+	}
+
+	/* Update state before emitting signal */
+	_xfdashboard_window_tracker_window_x11_update_state(self);
+
+	/* Proxy signal */
+	g_signal_emit_by_name(self, "state-changed", inChangedStates, inNewState);
+}
+
+/* Proxy signal for mapped wnck window which changed actions */
+static void _xfdashboard_window_tracker_window_x11_on_wnck_actions_changed(XfdashboardWindowTrackerWindowX11 *self,
+																			WnckWindowActions inChangedActions,
+																			WnckWindowActions inNewActions,
+																			gpointer inUserData)
+{
+	XfdashboardWindowTrackerWindowX11Private	*priv;
+	WnckWindow									*window;
+
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_WINDOW_X11(self));
+	g_return_if_fail(WNCK_IS_WINDOW(inUserData));
+
+	priv=self->priv;
+	window=WNCK_WINDOW(inUserData);
+
+	/* Check that window emitting this signal is the mapped window of this object */
+	if(priv->window!=window)
+	{
+		XFDASHBOARD_WINDOW_TRACKER_WINDOW_X11_WARN_WRONG_WINDOW(self);
+		return;
+	}
+
+	/* Update actions before emitting signal */
+	_xfdashboard_window_tracker_window_x11_update_actions(self);
+
+	/* Proxy signal */
+	g_signal_emit_by_name(self, "actions-changed", inChangedActions, inNewActions);
+}
+
+/* Proxy signal for mapped wnck window which changed icon */
+static void _xfdashboard_window_tracker_window_x11_on_wnck_icon_changed(XfdashboardWindowTrackerWindowX11 *self,
+																		gpointer inUserData)
+{
+	XfdashboardWindowTrackerWindowX11Private	*priv;
+	WnckWindow									*window;
+
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_WINDOW_X11(self));
+	g_return_if_fail(WNCK_IS_WINDOW(inUserData));
+
+	priv=self->priv;
+	window=WNCK_WINDOW(inUserData);
+
+	/* Check that window emitting this signal is the mapped window of this object */
+	if(priv->window!=window)
+	{
+		XFDASHBOARD_WINDOW_TRACKER_WINDOW_X11_WARN_WRONG_WINDOW(self);
+		return;
+	}
+
+	/* Proxy signal */
+	g_signal_emit_by_name(self, "icon-changed");
+}
+
+/* Proxy signal for mapped wnck window which changed workspace */
+static void _xfdashboard_window_tracker_window_x11_on_wnck_workspace_changed(XfdashboardWindowTrackerWindowX11 *self,
+																				gpointer inUserData)
+{
+	XfdashboardWindowTrackerWindowX11Private	*priv;
+	WnckWindow									*window;
+	XfdashboardWindowTrackerWorkspace			*oldWorkspace;
+
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_WINDOW_X11(self));
+	g_return_if_fail(WNCK_IS_WINDOW(inUserData));
+
+	priv=self->priv;
+	window=WNCK_WINDOW(inUserData);
+
+	/* Check that window emitting this signal is the mapped window of this object */
+	if(priv->window!=window)
+	{
+		XFDASHBOARD_WINDOW_TRACKER_WINDOW_X11_WARN_WRONG_WINDOW(self);
+		return;
+	}
+
+	/* Get mapped workspace object for last known workspace of this window */
+	oldWorkspace=NULL;
+	if(priv->workspace)
+	{
+		XfdashboardWindowTracker				*windowTracker;
+
+		windowTracker=xfdashboard_window_tracker_get_default();
+		oldWorkspace=xfdashboard_window_tracker_x11_get_workspace_for_wnck(XFDASHBOARD_WINDOW_TRACKER_X11(windowTracker), priv->workspace);
+		g_object_unref(windowTracker);
+	}
+
+	/* Proxy signal */
+	g_signal_emit_by_name(self, "workspace-changed", oldWorkspace);
+
+	/* Remember new workspace as last known workspace */
+	priv->workspace=wnck_window_get_workspace(window);
+}
+
+/* Proxy signal for mapped wnck window which changed geometry */
+static void _xfdashboard_window_tracker_window_x11_on_wnck_geometry_changed(XfdashboardWindowTrackerWindowX11 *self,
+																			gpointer inUserData)
+{
+	XfdashboardWindowTrackerWindowX11Private	*priv;
+	WnckWindow									*window;
+	gint										x, y, width, height;
+
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_WINDOW_X11(self));
+	g_return_if_fail(WNCK_IS_WINDOW(inUserData));
+
+	priv=self->priv;
+	window=WNCK_WINDOW(inUserData);
+
+	/* Check that window emitting this signal is the mapped window of this object */
+	if(priv->window!=window)
+	{
+		XFDASHBOARD_WINDOW_TRACKER_WINDOW_X11_WARN_WRONG_WINDOW(self);
+		return;
+	}
+
+	/* Get current position and size of window and check against last known
+	 * position and size of window to determine if window has moved or resized.
+	 */
+	wnck_window_get_geometry(priv->window, &x, &y, &width, &height);
+	if(priv->lastGeometryX!=x ||
+		priv->lastGeometryY!=y ||
+		priv->lastGeometryWidth!=width ||
+		priv->lastGeometryHeight!=height)
+	{
+		XfdashboardWindowTracker				*windowTracker;
+		gint									screenWidth, screenHeight;
+		XfdashboardWindowTrackerMonitor			*oldMonitor;
+		XfdashboardWindowTrackerMonitor			*currentMonitor;
+		gint									windowMiddleX, windowMiddleY;
+
+		/* Get window tracker */
+		windowTracker=xfdashboard_window_tracker_get_default();
+
+		/* Get monitor at old position of window and the monitor at current.
+		 * If they differ emit signal for window changed monitor.
+		 */
+		xfdashboard_window_tracker_get_screen_size(windowTracker, &screenWidth, &screenHeight);
+
+		windowMiddleX=priv->lastGeometryX+(priv->lastGeometryWidth/2);
+		if(windowMiddleX>screenWidth) windowMiddleX=screenWidth-1;
+
+		windowMiddleY=priv->lastGeometryY+(priv->lastGeometryHeight/2);
+		if(windowMiddleY>screenHeight) windowMiddleY=screenHeight-1;
+
+		oldMonitor=xfdashboard_window_tracker_get_monitor_by_position(windowTracker, windowMiddleX, windowMiddleY);
+
+		currentMonitor=xfdashboard_window_tracker_window_get_monitor(XFDASHBOARD_WINDOW_TRACKER_WINDOW(self));
+
+		if(currentMonitor!=oldMonitor)
+		{
+			/* Emit signal */
+			XFDASHBOARD_DEBUG(self, WINDOWS,
+								"Window '%s' moved from monitor %d (%s) to %d (%s)",
+								wnck_window_get_name(priv->window),
+								oldMonitor ? xfdashboard_window_tracker_monitor_get_number(oldMonitor) : -1,
+								(oldMonitor && xfdashboard_window_tracker_monitor_is_primary(oldMonitor)) ? "primary" : "non-primary",
+								currentMonitor ? xfdashboard_window_tracker_monitor_get_number(currentMonitor) : -1,
+								(currentMonitor && xfdashboard_window_tracker_monitor_is_primary(currentMonitor)) ? "primary" : "non-primary");
+			g_signal_emit_by_name(self, "monitor-changed", oldMonitor);
+		}
+
+		/* Remember current position and size as last known ones */
+		priv->lastGeometryX=x;
+		priv->lastGeometryY=y;
+		priv->lastGeometryWidth=width;
+		priv->lastGeometryHeight=height;
+
+		/* Release allocated resources */
+		g_object_unref(windowTracker);
+	}
+
+	/* Proxy signal */
+	g_signal_emit_by_name(self, "geometry-changed");
+}
+
+/* Set wnck window to map in this window object */
+static void _xfdashboard_window_tracker_window_x11_set_window(XfdashboardWindowTrackerWindowX11 *self,
+																WnckWindow *inWindow)
+{
+	XfdashboardWindowTrackerWindowX11Private	*priv;
+
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_WINDOW_X11(self));
+	g_return_if_fail(!inWindow || WNCK_IS_WINDOW(inWindow));
+
+	priv=self->priv;
+
+	/* Set value if changed */
+	if(priv->window!=inWindow)
+	{
+		/* Disconnect signals to old window (if available) and reset states */
+		if(priv->window)
+		{
+			/* Remove weak reference at old window */
+			g_object_remove_weak_pointer(G_OBJECT(priv->window), (gpointer*)&priv->window);
+
+			/* Disconnect signal handlers */
+			g_signal_handlers_disconnect_by_data(priv->window, self);
+			priv->window=NULL;
+		}
+		priv->state=0;
+		priv->actions=0;
+		priv->workspace=NULL;
+
+		/* Set new value */
+		priv->window=inWindow;
+
+		/* Initialize states and connect signals if window is set */
+		if(priv->window)
+		{
+			/* Add weak reference at new window */
+			g_object_add_weak_pointer(G_OBJECT(priv->window), (gpointer*)&priv->window);
+
+			/* Initialize states */
+			_xfdashboard_window_tracker_window_x11_update_state(self);
+			_xfdashboard_window_tracker_window_x11_update_actions(self);
+			priv->workspace=wnck_window_get_workspace(priv->window);
+			wnck_window_get_geometry(priv->window,
+										&priv->lastGeometryX,
+										&priv->lastGeometryY,
+										&priv->lastGeometryWidth,
+										&priv->lastGeometryHeight);
+
+			/* Connect signals */
+			g_signal_connect_swapped(priv->window,
+										"name-changed",
+										G_CALLBACK(_xfdashboard_window_tracker_window_x11_on_wnck_name_changed),
+										self);
+			g_signal_connect_swapped(priv->window,
+										"state-changed",
+										G_CALLBACK(_xfdashboard_window_tracker_window_x11_on_wnck_state_changed),
+										self);
+			g_signal_connect_swapped(priv->window,
+										"actions-changed",
+										G_CALLBACK(_xfdashboard_window_tracker_window_x11_on_wnck_actions_changed),
+										self);
+			g_signal_connect_swapped(priv->window,
+										"icon-changed",
+										G_CALLBACK(_xfdashboard_window_tracker_window_x11_on_wnck_icon_changed),
+										self);
+			g_signal_connect_swapped(priv->window,
+										"workspace-changed",
+										G_CALLBACK(_xfdashboard_window_tracker_window_x11_on_wnck_workspace_changed),
+										self);
+			g_signal_connect_swapped(priv->window,
+										"geometry-changed",
+										G_CALLBACK(_xfdashboard_window_tracker_window_x11_on_wnck_geometry_changed),
+										self);
+		}
+
+		/* Notify about property change */
+		g_object_notify_by_pspec(G_OBJECT(self), XfdashboardWindowTrackerWindowX11Properties[PROP_WINDOW]);
+	}
+}
+
+
+/* IMPLEMENTATION: Interface XfdashboardWindowTrackerWindow */
+
+/* Determine if window is visible */
+static gboolean _xfdashboard_window_tracker_window_x11_window_tracker_window_is_visible(XfdashboardWindowTrackerWindow *inWindow)
+{
+	XfdashboardWindowTrackerWindowX11			*self;
+	XfdashboardWindowTrackerWindowX11Private	*priv;
+
+	g_return_val_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_WINDOW_X11(inWindow), FALSE);
+
+	self=XFDASHBOARD_WINDOW_TRACKER_WINDOW_X11(inWindow);
+	priv=self->priv;
+
+	/* Windows are invisible if hidden but not minimized */
+	if((priv->state & XFDASHBOARD_WINDOW_TRACKER_WINDOW_STATE_HIDDEN) &&
+		!(priv->state & XFDASHBOARD_WINDOW_TRACKER_WINDOW_STATE_MINIMIZED))
+	{
+		return(FALSE);
+	}
+
+	/* If we get here the window is visible */
+	return(TRUE);
+}
+
+/* Show window */
+static void _xfdashboard_window_tracker_window_x11_window_tracker_window_show(XfdashboardWindowTrackerWindow *inWindow)
+{
+	XfdashboardWindowTrackerWindowX11			*self;
+	XfdashboardWindowTrackerWindowX11Private	*priv;
+
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_WINDOW_X11(inWindow));
+
+	self=XFDASHBOARD_WINDOW_TRACKER_WINDOW_X11(inWindow);
+	priv=self->priv;
+
+	/* A wnck window must be wrapped by this object */
+	if(!priv->window)
+	{
+		XFDASHBOARD_WINDOW_TRACKER_WINDOW_X11_WARN_NO_WINDOW(self);
+		return;
+	}
+
+	/* Show (unminize) window */
+	wnck_window_unminimize(priv->window, xfdashboard_window_tracker_x11_get_time());
+}
+
+/* Show window */
+static void _xfdashboard_window_tracker_window_x11_window_tracker_window_hide(XfdashboardWindowTrackerWindow *inWindow)
+{
+	XfdashboardWindowTrackerWindowX11			*self;
+	XfdashboardWindowTrackerWindowX11Private	*priv;
+
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_WINDOW_X11(inWindow));
+
+	self=XFDASHBOARD_WINDOW_TRACKER_WINDOW_X11(inWindow);
+	priv=self->priv;
+
+	/* A wnck window must be wrapped by this object */
+	if(!priv->window)
+	{
+		XFDASHBOARD_WINDOW_TRACKER_WINDOW_X11_WARN_NO_WINDOW(self);
+		return;
+	}
+
+	/* Hide (minimize) window */
+	wnck_window_minimize(priv->window);
+}
+
+/* Get parent window if this window is a child window */
+static XfdashboardWindowTrackerWindow* _xfdashboard_window_tracker_window_x11_window_tracker_window_get_parent(XfdashboardWindowTrackerWindow *inWindow)
+{
+	XfdashboardWindowTrackerWindowX11			*self;
+	XfdashboardWindowTrackerWindowX11Private	*priv;
+	WnckWindow									*parentWindow;
+	XfdashboardWindowTracker					*windowTracker;
+	XfdashboardWindowTrackerWindow				*foundWindow;
+
+	g_return_val_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_WINDOW_X11(inWindow), NULL);
+
+	self=XFDASHBOARD_WINDOW_TRACKER_WINDOW_X11(inWindow);
+	priv=self->priv;
+
+	/* A wnck window must be wrapped by this object */
+	if(!priv->window)
+	{
+		XFDASHBOARD_WINDOW_TRACKER_WINDOW_X11_WARN_NO_WINDOW(self);
+		return(NULL);
+	}
+
+	/* Get parent window */
+	parentWindow=wnck_window_get_transient(priv->window);
+	if(!parentWindow) return(NULL);
+
+	/* Get window tracker and lookup the mapped and matching XfdashboardWindowTrackerWindow
+	 * for wnck window.
+	 */
+	windowTracker=xfdashboard_window_tracker_get_default();
+	foundWindow=xfdashboard_window_tracker_x11_get_window_for_wnck(XFDASHBOARD_WINDOW_TRACKER_X11(windowTracker), parentWindow);
+	g_object_unref(windowTracker);
+
+	/* Return found window object */
+	return(foundWindow);
+}
+
+/* Get window state */
+static XfdashboardWindowTrackerWindowState _xfdashboard_window_tracker_window_x11_window_tracker_window_get_state(XfdashboardWindowTrackerWindow *inWindow)
+{
+	XfdashboardWindowTrackerWindowX11			*self;
+	XfdashboardWindowTrackerWindowX11Private	*priv;
+
+	g_return_val_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_WINDOW_X11(inWindow), 0);
+
+	self=XFDASHBOARD_WINDOW_TRACKER_WINDOW_X11(inWindow);
+	priv=self->priv;
+
+	/* Return state of window */
+	return(priv->state);
+}
+
+/* Get window actions */
+static XfdashboardWindowTrackerWindowAction _xfdashboard_window_tracker_window_x11_window_tracker_window_get_actions(XfdashboardWindowTrackerWindow *inWindow)
+{
+	XfdashboardWindowTrackerWindowX11			*self;
+	XfdashboardWindowTrackerWindowX11Private	*priv;
+
+	g_return_val_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_WINDOW_X11(inWindow), 0);
+
+	self=XFDASHBOARD_WINDOW_TRACKER_WINDOW_X11(inWindow);
+	priv=self->priv;
+
+	/* Return actions of window */
+	return(priv->actions);
+}
+
+/* Get name (title) of window */
+static const gchar* _xfdashboard_window_tracker_window_x11_window_tracker_window_get_name(XfdashboardWindowTrackerWindow *inWindow)
+{
+	XfdashboardWindowTrackerWindowX11			*self;
+	XfdashboardWindowTrackerWindowX11Private	*priv;
+
+	g_return_val_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_WINDOW_X11(inWindow), NULL);
+
+	self=XFDASHBOARD_WINDOW_TRACKER_WINDOW_X11(inWindow);
+	priv=self->priv;
+
+	/* A wnck window must be wrapped by this object */
+	if(!priv->window)
+	{
+		XFDASHBOARD_WINDOW_TRACKER_WINDOW_X11_WARN_NO_WINDOW(self);
+		return(NULL);
+	}
+
+	/* Check if window has a name to return and return name or NULL */
+	if(!wnck_window_has_name(priv->window)) return(NULL);
+
+	return(wnck_window_get_name(priv->window));
+}
+
+/* Get icon of window */
+static GdkPixbuf* _xfdashboard_window_tracker_window_x11_window_tracker_window_get_icon(XfdashboardWindowTrackerWindow *inWindow)
+{
+	XfdashboardWindowTrackerWindowX11			*self;
+	XfdashboardWindowTrackerWindowX11Private	*priv;
+
+	g_return_val_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_WINDOW_X11(inWindow), NULL);
+
+	self=XFDASHBOARD_WINDOW_TRACKER_WINDOW_X11(inWindow);
+	priv=self->priv;
+
+	/* A wnck window must be wrapped by this object */
+	if(!priv->window)
+	{
+		XFDASHBOARD_WINDOW_TRACKER_WINDOW_X11_WARN_NO_WINDOW(self);
+		return(NULL);
+	}
+
+	/* Return icon as pixbuf of window */
+	return(wnck_window_get_icon(priv->window));
+}
+
+static const gchar* _xfdashboard_window_tracker_window_x11_window_tracker_window_get_icon_name(XfdashboardWindowTrackerWindow *inWindow)
+{
+	XfdashboardWindowTrackerWindowX11			*self;
+	XfdashboardWindowTrackerWindowX11Private	*priv;
+
+	g_return_val_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_WINDOW_X11(inWindow), NULL);
+
+	self=XFDASHBOARD_WINDOW_TRACKER_WINDOW_X11(inWindow);
+	priv=self->priv;
+
+	/* A wnck window must be wrapped by this object */
+	if(!priv->window)
+	{
+		XFDASHBOARD_WINDOW_TRACKER_WINDOW_X11_WARN_NO_WINDOW(self);
+		return(NULL);
+	}
+
+	/* Check if window has an icon name to return and return icon name or NULL */
+	if(!wnck_window_has_icon_name(priv->window)) return(NULL);
+
+	return(wnck_window_get_icon_name(priv->window));
+}
+
+/* Get workspace where window is on */
+static XfdashboardWindowTrackerWorkspace* _xfdashboard_window_tracker_window_x11_window_tracker_window_get_workspace(XfdashboardWindowTrackerWindow *inWindow)
+{
+	XfdashboardWindowTrackerWindowX11			*self;
+	XfdashboardWindowTrackerWindowX11Private	*priv;
+	WnckWorkspace								*wantedWorkspace;
+	XfdashboardWindowTracker					*windowTracker;
+	XfdashboardWindowTrackerWorkspace			*foundWorkspace;
+
+	g_return_val_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_WINDOW_X11(inWindow), NULL);
+
+	self=XFDASHBOARD_WINDOW_TRACKER_WINDOW_X11(inWindow);
+	priv=self->priv;
+
+	/* A wnck window must be wrapped by this object */
+	if(!priv->window)
+	{
+		XFDASHBOARD_WINDOW_TRACKER_WINDOW_X11_WARN_NO_WINDOW(self);
+		return(NULL);
+	}
+
+	/* Get real wnck workspace of window to lookup a mapped and matching
+	 * XfdashboardWindowTrackerWorkspace object.
+	 * NOTE: Workspace may be NULL. In this case return NULL immediately and
+	 *       do not lookup a matching workspace object.
+	 */
+	wantedWorkspace=wnck_window_get_workspace(priv->window);
+	if(!wantedWorkspace) return(NULL);
+
+	/* Get window tracker and lookup the mapped and matching XfdashboardWindowTrackerWorkspace
+	 * for wnck workspace.
+	 */
+	windowTracker=xfdashboard_window_tracker_get_default();
+	foundWorkspace=xfdashboard_window_tracker_x11_get_workspace_for_wnck(XFDASHBOARD_WINDOW_TRACKER_X11(windowTracker), wantedWorkspace);
+	g_object_unref(windowTracker);
+
+	/* Return found workspace */
+	return(foundWorkspace);
+}
+
+/* Determine if window is on requested workspace */
+static gboolean _xfdashboard_window_tracker_window_x11_window_tracker_window_is_on_workspace(XfdashboardWindowTrackerWindow *inWindow,
+																								XfdashboardWindowTrackerWorkspace *inWorkspace)
+{
+	XfdashboardWindowTrackerWindowX11			*self;
+	XfdashboardWindowTrackerWindowX11Private	*priv;
+	WnckWorkspace								*workspace;
+
+	g_return_val_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_WINDOW_X11(inWindow), FALSE);
+	g_return_val_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_WORKSPACE_X11(inWorkspace), FALSE);
+
+	self=XFDASHBOARD_WINDOW_TRACKER_WINDOW_X11(inWindow);
+	priv=self->priv;
+
+	/* A wnck window must be wrapped by this object */
+	if(!priv->window)
+	{
+		XFDASHBOARD_WINDOW_TRACKER_WINDOW_X11_WARN_NO_WINDOW(self);
+		return(FALSE);
+	}
+
+	/* Get wnck workspace to check if window is on this one */
+	workspace=xfdashboard_window_tracker_workspace_x11_get_workspace(XFDASHBOARD_WINDOW_TRACKER_WORKSPACE_X11(inWorkspace));
+	if(!workspace)
+	{
+		g_critical(_("Either no wnck workspace is wrapped at %s or workspace is not available anymore when called at function %s"),
+					G_OBJECT_TYPE_NAME(inWorkspace),
+					__func__);
+		return(FALSE);
+	}
+
+	/* Check if window is on that workspace */
+	return(wnck_window_is_on_workspace(priv->window, workspace));
+}
+
+/* Get geometry (position and size) of window */
+static void _xfdashboard_window_tracker_window_x11_window_tracker_window_get_geometry(XfdashboardWindowTrackerWindow *inWindow,
+																				gint *outX,
+																				gint *outY,
+																				gint *outWidth,
+																				gint *outHeight)
+{
+	XfdashboardWindowTrackerWindowX11			*self;
+	XfdashboardWindowTrackerWindowX11Private	*priv;
+	gint										x, y, width, height;
+
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_WINDOW_X11(inWindow));
+
+	self=XFDASHBOARD_WINDOW_TRACKER_WINDOW_X11(inWindow);
+	priv=self->priv;
+
+	/* A wnck window must be wrapped by this object */
+	if(!priv->window)
+	{
+		XFDASHBOARD_WINDOW_TRACKER_WINDOW_X11_WARN_NO_WINDOW(self);
+		return;
+	}
+
+	/* Get window geometry */
+	wnck_window_get_client_window_geometry(priv->window, &x, &y, &width, &height);
+
+	/* Set result */
+	if(outX) *outX=x;
+	if(outX) *outY=y;
+	if(outWidth) *outWidth=width;
+	if(outHeight) *outHeight=height;
+}
+
+/* Set geometry (position and size) of window */
+static void _xfdashboard_window_tracker_window_x11_window_tracker_window_set_geometry(XfdashboardWindowTrackerWindow *inWindow,
+																				gint inX,
+																				gint inY,
+																				gint inWidth,
+																				gint inHeight)
+{
+	XfdashboardWindowTrackerWindowX11			*self;
+	XfdashboardWindowTrackerWindowX11Private	*priv;
+	WnckWindowMoveResizeMask					flags;
+	gint										contentX, contentY;
+	gint										contentWidth, contentHeight;
+	gint										borderX, borderY;
+	gint										borderWidth, borderHeight;
+
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_WINDOW_X11(inWindow));
+
+	self=XFDASHBOARD_WINDOW_TRACKER_WINDOW_X11(inWindow);
+	priv=self->priv;
+
+	/* A wnck window must be wrapped by this object */
+	if(!priv->window)
+	{
+		XFDASHBOARD_WINDOW_TRACKER_WINDOW_X11_WARN_NO_WINDOW(self);
+		return;
+	}
+
+	/* Get window border size to respect it when moving window */
+	wnck_window_get_client_window_geometry(priv->window, &contentX, &contentY, &contentWidth, &contentHeight);
+	wnck_window_get_geometry(priv->window, &borderX, &borderY, &borderWidth, &borderHeight);
+
+	/* Get modification flags */
+	flags=0;
+	if(inX>=0)
+	{
+		flags|=WNCK_WINDOW_CHANGE_X;
+		inX-=(contentX-borderX);
+	}
+
+	if(inY>=0)
+	{
+		flags|=WNCK_WINDOW_CHANGE_Y;
+		inY-=(contentY-borderY);
+	}
+
+	if(inWidth>=0)
+	{
+		flags|=WNCK_WINDOW_CHANGE_WIDTH;
+		inWidth+=(borderWidth-contentWidth);
+	}
+
+	if(inHeight>=0)
+	{
+		flags|=WNCK_WINDOW_CHANGE_HEIGHT;
+		inHeight+=(borderHeight-contentHeight);
+	}
+
+	/* Set geometry */
+	wnck_window_set_geometry(priv->window,
+								WNCK_WINDOW_GRAVITY_STATIC,
+								flags,
+								inX, inY, inWidth, inHeight);
+}
+
+/* Move window */
+static void _xfdashboard_window_tracker_window_x11_window_tracker_window_move(XfdashboardWindowTrackerWindow *inWindow,
+																		gint inX,
+																		gint inY)
+{
+	_xfdashboard_window_tracker_window_x11_window_tracker_window_set_geometry(inWindow, inX, inY, -1, -1);
+}
+
+/* Resize window */
+static void _xfdashboard_window_tracker_window_x11_window_tracker_window_resize(XfdashboardWindowTrackerWindow *inWindow,
+																			gint inWidth,
+																			gint inHeight)
+{
+	_xfdashboard_window_tracker_window_x11_window_tracker_window_set_geometry(inWindow, -1, -1, inWidth, inHeight);
+}
+
+/* Move a window to another workspace */
+static void _xfdashboard_window_tracker_window_x11_window_tracker_window_move_to_workspace(XfdashboardWindowTrackerWindow *inWindow,
+																					XfdashboardWindowTrackerWorkspace *inWorkspace)
+{
+	XfdashboardWindowTrackerWindowX11			*self;
+	XfdashboardWindowTrackerWindowX11Private	*priv;
+	WnckWorkspace								*workspace;
+
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_WINDOW_X11(inWindow));
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_WORKSPACE_X11(inWorkspace));
+
+	self=XFDASHBOARD_WINDOW_TRACKER_WINDOW_X11(inWindow);
+	priv=self->priv;
+
+	/* A wnck window must be wrapped by this object */
+	if(!priv->window)
+	{
+		XFDASHBOARD_WINDOW_TRACKER_WINDOW_X11_WARN_NO_WINDOW(self);
+		return;
+	}
+
+	/* Get wnck workspace to move window to */
+	workspace=xfdashboard_window_tracker_workspace_x11_get_workspace(XFDASHBOARD_WINDOW_TRACKER_WORKSPACE_X11(inWorkspace));
+	if(!workspace)
+	{
+		g_critical(_("Either no wnck workspace is wrapped at %s or workspace is not available anymore when called at function %s"),
+					G_OBJECT_TYPE_NAME(inWorkspace),
+					__func__);
+		return;
+	}
+
+	/* Move window to workspace */
+	wnck_window_move_to_workspace(priv->window, workspace);
+}
+
+/* Activate window with its transient windows */
+static void _xfdashboard_window_tracker_window_x11_window_tracker_window_activate(XfdashboardWindowTrackerWindow *inWindow)
+{
+	XfdashboardWindowTrackerWindowX11			*self;
+	XfdashboardWindowTrackerWindowX11Private	*priv;
+
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_WINDOW_X11(inWindow));
+
+	self=XFDASHBOARD_WINDOW_TRACKER_WINDOW_X11(inWindow);
+	priv=self->priv;
+
+	/* A wnck window must be wrapped by this object */
+	if(!priv->window)
+	{
+		XFDASHBOARD_WINDOW_TRACKER_WINDOW_X11_WARN_NO_WINDOW(self);
+		return;
+	}
+
+	/* Activate window */
+	wnck_window_activate_transient(priv->window, xfdashboard_window_tracker_x11_get_time());
+}
+
+/* Close window */
+static void _xfdashboard_window_tracker_window_x11_window_tracker_window_close(XfdashboardWindowTrackerWindow *inWindow)
+{
+	XfdashboardWindowTrackerWindowX11			*self;
+	XfdashboardWindowTrackerWindowX11Private	*priv;
+
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_WINDOW_X11(inWindow));
+
+	self=XFDASHBOARD_WINDOW_TRACKER_WINDOW_X11(inWindow);
+	priv=self->priv;
+
+	/* A wnck window must be wrapped by this object */
+	if(!priv->window)
+	{
+		XFDASHBOARD_WINDOW_TRACKER_WINDOW_X11_WARN_NO_WINDOW(self);
+		return;
+	}
+
+	/* Close window */
+	wnck_window_close(priv->window, xfdashboard_window_tracker_x11_get_time());
+}
+
+/* Get process ID owning the requested window */
+static gint _xfdashboard_window_tracker_window_x11_window_tracker_window_get_pid(XfdashboardWindowTrackerWindow *inWindow)
+{
+	XfdashboardWindowTrackerWindowX11			*self;
+	XfdashboardWindowTrackerWindowX11Private	*priv;
+
+	g_return_val_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_WINDOW_X11(inWindow), -1);
+
+	self=XFDASHBOARD_WINDOW_TRACKER_WINDOW_X11(inWindow);
+	priv=self->priv;
+
+	/* A wnck window must be wrapped by this object */
+	if(!priv->window)
+	{
+		XFDASHBOARD_WINDOW_TRACKER_WINDOW_X11_WARN_NO_WINDOW(self);
+		return(-1);
+	}
+
+	/* Return PID retrieved from wnck window */
+	return(wnck_window_get_pid(priv->window));
+}
+
+/* Get all possible instance name for window, e.g. class name, instance name.
+ * Caller is responsible to free result with g_strfreev() if not NULL.
+ */
+static gchar** _xfdashboard_window_tracker_window_x11_window_tracker_window_get_instance_names(XfdashboardWindowTrackerWindow *inWindow)
+{
+	XfdashboardWindowTrackerWindowX11			*self;
+	XfdashboardWindowTrackerWindowX11Private	*priv;
+	GSList										*names;
+	GSList										*iter;
+	const gchar									*value;
+	guint										numberEntries;
+	gchar										**result;
+
+	g_return_val_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_WINDOW_X11(inWindow), NULL);
+
+	self=XFDASHBOARD_WINDOW_TRACKER_WINDOW_X11(inWindow);
+	priv=self->priv;
+	names=NULL;
+	result=NULL;
+
+	/* A wnck window must be wrapped by this object */
+	if(!priv->window)
+	{
+		XFDASHBOARD_WINDOW_TRACKER_WINDOW_X11_WARN_NO_WINDOW(self);
+		return(NULL);
+	}
+
+	/* Add class name of window to list */
+	value=wnck_window_get_class_group_name(priv->window);
+	if(value) names=g_slist_prepend(names, g_strdup(value));
+
+	/* Add instance name of window to list */
+	value=wnck_window_get_class_instance_name(priv->window);
+	if(value) names=g_slist_prepend(names, g_strdup(value));
+
+	/* Add role of window to list */
+	value=wnck_window_get_role(priv->window);
+	if(value) names=g_slist_prepend(names, g_strdup(value));
+
+	/* If nothing was added to list of name, stop here and return */
+	if(!names) return(NULL);
+
+	/* Build result list as a NULL-terminated list of strings */
+	numberEntries=g_slist_length(names);
+
+	result=g_new(gchar*, numberEntries+1);
+	result[numberEntries]=NULL;
+	for(iter=names; iter; iter=g_slist_next(iter))
+	{
+		numberEntries--;
+		result[numberEntries]=iter->data;
+	}
+
+	/* Release allocated resources */
+	g_slist_free(names);
+
+	/* Return result list */
+	return(result);
+}
+
+/* Get content for this window for use in actors.
+ * Caller is responsible to remove reference with g_object_unref().
+ */
+static ClutterContent* _xfdashboard_window_tracker_window_x11_window_tracker_window_get_content(XfdashboardWindowTrackerWindow *inWindow)
+{
+	XfdashboardWindowTrackerWindowX11			*self;
+	XfdashboardWindowTrackerWindowX11Private	*priv;
+	ClutterContent								*content;
+
+	g_return_val_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_WINDOW_X11(inWindow), NULL);
+
+	self=XFDASHBOARD_WINDOW_TRACKER_WINDOW_X11(inWindow);
+	priv=self->priv;
+
+	/* A wnck window must be wrapped by this object */
+	if(!priv->window)
+	{
+		XFDASHBOARD_WINDOW_TRACKER_WINDOW_X11_WARN_NO_WINDOW(self);
+		return(NULL);
+	}
+
+	/* Create content for window */
+	content=xfdashboard_window_content_x11_new_for_window(self);
+
+	/* Return content */
+	return(content);
+}
+
+/* Get associated stage of window */
+static ClutterStage* _xfdashboard_window_tracker_window_x11_window_tracker_window_get_stage(XfdashboardWindowTrackerWindow *inWindow)
+{
+	XfdashboardWindowTrackerWindowX11			*self;
+	XfdashboardWindowTrackerWindowX11Private	*priv;
+	ClutterStage								*foundStage;
+	ClutterStage								*stage;
+	Window										stageXWindow;
+	GSList										*stages, *entry;
+
+	g_return_val_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_WINDOW_X11(inWindow), NULL);
+
+	self=XFDASHBOARD_WINDOW_TRACKER_WINDOW_X11(inWindow);
+	priv=self->priv;
+
+	/* A wnck window must be wrapped by this object */
+	if(!priv->window)
+	{
+		XFDASHBOARD_WINDOW_TRACKER_WINDOW_X11_WARN_NO_WINDOW(self);
+		return(NULL);
+	}
+
+	/* Iterate through stages and check if stage window matches requested one */
+	foundStage=NULL;
+	stages=clutter_stage_manager_list_stages(clutter_stage_manager_get_default());
+	for(entry=stages; !foundStage && entry; entry=g_slist_next(entry))
+	{
+		stage=CLUTTER_STAGE(entry->data);
+		if(stage)
+		{
+			stageXWindow=clutter_x11_get_stage_window(stage);
+			if(stageXWindow==wnck_window_get_xid(priv->window)) foundStage=stage;
+		}
+	}
+	g_slist_free(stages);
+
+	return(foundStage);
+}
+
+/* Set up window for use as stage window */
+static void _xfdashboard_window_tracker_window_x11_window_tracker_window_make_stage_window(XfdashboardWindowTrackerWindow *inWindow)
+{
+	XfdashboardWindowTrackerWindowX11			*self;
+	XfdashboardWindowTrackerWindowX11Private	*priv;
+	XfdashboardWindowTracker					*windowTracker;
+	WnckScreen									*screen;
+	guint										signalID;
+	gulong										handlerID;
+	gint										width, height;
+
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_WINDOW_X11(inWindow));
+
+	self=XFDASHBOARD_WINDOW_TRACKER_WINDOW_X11(inWindow);
+	priv=self->priv;
+
+	/* A wnck window must be wrapped by this object */
+	if(!priv->window)
+	{
+		XFDASHBOARD_WINDOW_TRACKER_WINDOW_X11_WARN_NO_WINDOW(self);
+		return;
+	}
+
+	/* Window of stage should always be above all other windows, pinned to all
+	 * workspaces, not be listed in window pager and set to fullscreen
+	 */
+	if(!wnck_window_is_skip_tasklist(priv->window)) wnck_window_set_skip_tasklist(priv->window, TRUE);
+	if(!wnck_window_is_skip_pager(priv->window)) wnck_window_set_skip_pager(priv->window, TRUE);
+	if(!wnck_window_is_above(priv->window)) wnck_window_make_above(priv->window);
+	if(!wnck_window_is_pinned(priv->window)) wnck_window_pin(priv->window);
+
+	/* Get screen of window */
+	screen=wnck_window_get_screen(priv->window);
+
+	/* Connect signals if not already connected */
+	signalID=g_signal_lookup("state-changed", WNCK_TYPE_WINDOW);
+	handlerID=g_signal_handler_find(priv->window,
+									G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC,
+									signalID,
+									0,
+									NULL,
+									G_CALLBACK(_xfdashboard_window_tracker_window_x11_on_stage_state_changed),
+									NULL);
+	if(!handlerID)
+	{
+		g_signal_connect(priv->window,
+							"state-changed",
+							G_CALLBACK(_xfdashboard_window_tracker_window_x11_on_stage_state_changed),
+							NULL);
+		XFDASHBOARD_DEBUG(self, WINDOWS,
+							"Connecting signal to 'state-changed' at window %p (wnck-window=%p)",
+							self,
+							priv->window);
+	}
+
+	signalID=g_signal_lookup("active-window-changed", WNCK_TYPE_SCREEN);
+	handlerID=g_signal_handler_find(screen,
+									G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC,
+									signalID,
+									0,
+									NULL,
+									G_CALLBACK(_xfdashboard_window_tracker_window_x11_on_stage_active_window_changed),
+									NULL);
+	if(!handlerID)
+	{
+		g_signal_connect(screen,
+							"active-window-changed",
+							G_CALLBACK(_xfdashboard_window_tracker_window_x11_on_stage_active_window_changed),
+							self);
+		XFDASHBOARD_DEBUG(self, WINDOWS,
+							"Connecting signal to 'active-window-changed' at screen %p of window %p (wnck-window=%p)",
+							screen,
+							self,
+							priv->window);
+	}
+
+	windowTracker=xfdashboard_window_tracker_get_default();
+	signalID=g_signal_lookup("screen-size-changed", XFDASHBOARD_TYPE_WINDOW_TRACKER);
+	handlerID=g_signal_handler_find(windowTracker,
+									G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC,
+									signalID,
+									0,
+									NULL,
+									G_CALLBACK(_xfdashboard_window_tracker_window_x11_on_stage_screen_size_changed),
+									NULL);
+	if(!handlerID)
+	{
+		g_signal_connect(windowTracker,
+							"screen-size-changed",
+							G_CALLBACK(_xfdashboard_window_tracker_window_x11_on_stage_screen_size_changed),
+							self);
+		XFDASHBOARD_DEBUG(self, WINDOWS,
+							"Connecting signal to 'screen-size-changed' at window %p (wnck-window=%p)",
+							self,
+							priv->window);
+	}
+	xfdashboard_window_tracker_get_screen_size(windowTracker, &width, &height);
+	_xfdashboard_window_tracker_window_x11_on_stage_screen_size_changed(windowTracker,
+																	width,
+																	height,
+																	self);
+	g_object_unref(windowTracker);
+}
+
+/* Unset up stage window (only remove connected signals) */
+static void _xfdashboard_window_tracker_window_x11_window_tracker_window_unmake_stage_window(XfdashboardWindowTrackerWindow *inWindow)
+{
+	XfdashboardWindowTrackerWindowX11			*self;
+	XfdashboardWindowTrackerWindowX11Private	*priv;
+	XfdashboardWindowTracker					*windowTracker;
+	WnckScreen									*screen;
+	guint										signalID;
+	gulong										handlerID;
+
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_WINDOW_X11(inWindow));
+
+	self=XFDASHBOARD_WINDOW_TRACKER_WINDOW_X11(inWindow);
+	priv=self->priv;
+
+	/* A wnck window must be wrapped by this object */
+	if(!priv->window)
+	{
+		XFDASHBOARD_WINDOW_TRACKER_WINDOW_X11_WARN_NO_WINDOW(self);
+		return;
+	}
+
+	/* Get screen of window */
+	screen=wnck_window_get_screen(WNCK_WINDOW(priv->window));
+
+	/* Disconnect signals */
+	signalID=g_signal_lookup("state-changed", WNCK_TYPE_WINDOW);
+	handlerID=g_signal_handler_find(priv->window,
+									G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC,
+									signalID,
+									0,
+									NULL,
+									G_CALLBACK(_xfdashboard_window_tracker_window_x11_on_stage_state_changed),
+									NULL);
+	if(handlerID)
+	{
+		g_signal_handler_disconnect(priv->window, handlerID);
+		XFDASHBOARD_DEBUG(self, WINDOWS,
+							"Disconnecting handler %lu for signal 'state-changed' at window %p (wnck-window=%p)",
+							handlerID,
+							self,
+							priv->window);
+	}
+
+	signalID=g_signal_lookup("active-window-changed", WNCK_TYPE_SCREEN);
+	handlerID=g_signal_handler_find(screen,
+									G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC,
+									signalID,
+									0,
+									NULL,
+									G_CALLBACK(_xfdashboard_window_tracker_window_x11_on_stage_active_window_changed),
+									NULL);
+	if(handlerID)
+	{
+		g_signal_handler_disconnect(screen, handlerID);
+		XFDASHBOARD_DEBUG(self, WINDOWS,
+							"Disconnecting handler %lu for signal 'active-window-changed' at screen %p of window %p (wnck-window=%p)",
+							handlerID,
+							screen,
+							self,
+							priv->window);
+	}
+
+	windowTracker=xfdashboard_window_tracker_get_default();
+	signalID=g_signal_lookup("screen-size-changed", XFDASHBOARD_TYPE_WINDOW_TRACKER);
+	handlerID=g_signal_handler_find(windowTracker,
+									G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC,
+									signalID,
+									0,
+									NULL,
+									G_CALLBACK(_xfdashboard_window_tracker_window_x11_on_stage_screen_size_changed),
+									NULL);
+	if(handlerID)
+	{
+		g_signal_handler_disconnect(windowTracker, handlerID);
+		XFDASHBOARD_DEBUG(self, WINDOWS,
+							"Disconnecting handler %lu for signal 'screen-size-changed' at window %p (wnck-window=%p)",
+							handlerID,
+							self,
+							priv->window);
+	}
+	g_object_unref(windowTracker);
+}
+
+/* Interface initialization
+ * Set up default functions
+ */
+static void _xfdashboard_window_tracker_window_x11_window_tracker_window_iface_init(XfdashboardWindowTrackerWindowInterface *iface)
+{
+	iface->is_visible=_xfdashboard_window_tracker_window_x11_window_tracker_window_is_visible;
+	iface->show=_xfdashboard_window_tracker_window_x11_window_tracker_window_show;
+	iface->hide=_xfdashboard_window_tracker_window_x11_window_tracker_window_hide;
+
+	iface->get_parent=_xfdashboard_window_tracker_window_x11_window_tracker_window_get_parent;
+
+	iface->get_state=_xfdashboard_window_tracker_window_x11_window_tracker_window_get_state;
+	iface->get_actions=_xfdashboard_window_tracker_window_x11_window_tracker_window_get_actions;
+
+	iface->get_name=_xfdashboard_window_tracker_window_x11_window_tracker_window_get_name;
+
+	iface->get_icon=_xfdashboard_window_tracker_window_x11_window_tracker_window_get_icon;
+	iface->get_icon_name=_xfdashboard_window_tracker_window_x11_window_tracker_window_get_icon_name;
+
+	iface->get_workspace=_xfdashboard_window_tracker_window_x11_window_tracker_window_get_workspace;
+	iface->is_on_workspace=_xfdashboard_window_tracker_window_x11_window_tracker_window_is_on_workspace;
+
+	iface->get_geometry=_xfdashboard_window_tracker_window_x11_window_tracker_window_get_geometry;
+	iface->set_geometry=_xfdashboard_window_tracker_window_x11_window_tracker_window_set_geometry;
+	iface->move=_xfdashboard_window_tracker_window_x11_window_tracker_window_move;
+	iface->resize=_xfdashboard_window_tracker_window_x11_window_tracker_window_resize;
+	iface->move_to_workspace=_xfdashboard_window_tracker_window_x11_window_tracker_window_move_to_workspace;
+	iface->activate=_xfdashboard_window_tracker_window_x11_window_tracker_window_activate;
+	iface->close=_xfdashboard_window_tracker_window_x11_window_tracker_window_close;
+
+	iface->get_pid=_xfdashboard_window_tracker_window_x11_window_tracker_window_get_pid;
+	iface->get_instance_names=_xfdashboard_window_tracker_window_x11_window_tracker_window_get_instance_names;
+
+	iface->get_content=_xfdashboard_window_tracker_window_x11_window_tracker_window_get_content;
+
+	iface->get_stage=_xfdashboard_window_tracker_window_x11_window_tracker_window_get_stage;
+	iface->make_stage_window=_xfdashboard_window_tracker_window_x11_window_tracker_window_make_stage_window;
+	iface->unmake_stage_window=_xfdashboard_window_tracker_window_x11_window_tracker_window_unmake_stage_window;
+}
+
+
+/* IMPLEMENTATION: GObject */
+
+/* Dispose this object */
+static void _xfdashboard_window_tracker_window_x11_dispose(GObject *inObject)
+{
+	XfdashboardWindowTrackerWindowX11			*self=XFDASHBOARD_WINDOW_TRACKER_WINDOW_X11(inObject);
+	XfdashboardWindowTrackerWindowX11Private	*priv=self->priv;
+
+	/* Dispose allocated resources */
+	if(priv->window)
+	{
+		/* Remove weak reference at current window */
+		g_object_remove_weak_pointer(G_OBJECT(priv->window), (gpointer*)&priv->window);
+
+		/* Disconnect signal handlers */
+		g_signal_handlers_disconnect_by_data(priv->window, self);
+		priv->window=NULL;
+	}
+
+	/* Call parent's class dispose method */
+	G_OBJECT_CLASS(xfdashboard_window_tracker_window_x11_parent_class)->dispose(inObject);
+}
+
+/* Set/get properties */
+static void _xfdashboard_window_tracker_window_x11_set_property(GObject *inObject,
+																guint inPropID,
+																const GValue *inValue,
+																GParamSpec *inSpec)
+{
+	XfdashboardWindowTrackerWindowX11		*self=XFDASHBOARD_WINDOW_TRACKER_WINDOW_X11(inObject);
+
+	switch(inPropID)
+	{
+		case PROP_WINDOW:
+			_xfdashboard_window_tracker_window_x11_set_window(self, WNCK_WINDOW(g_value_get_object(inValue)));
+			break;
+
+		default:
+			G_OBJECT_WARN_INVALID_PROPERTY_ID(inObject, inPropID, inSpec);
+			break;
+	}
+}
+
+static void _xfdashboard_window_tracker_window_x11_get_property(GObject *inObject,
+																guint inPropID,
+																GValue *outValue,
+																GParamSpec *inSpec)
+{
+	XfdashboardWindowTrackerWindowX11		*self=XFDASHBOARD_WINDOW_TRACKER_WINDOW_X11(inObject);
+
+	switch(inPropID)
+	{
+		case PROP_WINDOW:
+			g_value_set_object(outValue, self->priv->window);
+			break;
+
+		default:
+			G_OBJECT_WARN_INVALID_PROPERTY_ID(inObject, inPropID, inSpec);
+			break;
+	}
+}
+
+/* Class initialization
+ * Override functions in parent classes and define properties
+ * and signals
+ */
+void xfdashboard_window_tracker_window_x11_class_init(XfdashboardWindowTrackerWindowX11Class *klass)
+{
+	GObjectClass						*gobjectClass=G_OBJECT_CLASS(klass);
+	XfdashboardWindowTracker			*windowIface;
+	GParamSpec							*paramSpec;
+
+	/* Reference interface type to lookup properties etc. */
+	windowIface=g_type_default_interface_ref(XFDASHBOARD_TYPE_WINDOW_TRACKER_WINDOW);
+
+	/* Override functions */
+	gobjectClass->dispose=_xfdashboard_window_tracker_window_x11_dispose;
+	gobjectClass->set_property=_xfdashboard_window_tracker_window_x11_set_property;
+	gobjectClass->get_property=_xfdashboard_window_tracker_window_x11_get_property;
+
+	/* Set up private structure */
+	g_type_class_add_private(klass, sizeof(XfdashboardWindowTrackerWindowX11Private));
+
+	/* Define properties */
+	XfdashboardWindowTrackerWindowX11Properties[PROP_WINDOW]=
+		g_param_spec_object("window",
+							_("Window"),
+							_("The mapped wnck window"),
+							WNCK_TYPE_WINDOW,
+							G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
+
+	paramSpec=g_object_interface_find_property(windowIface, "state");
+	XfdashboardWindowTrackerWindowX11Properties[PROP_STATE]=
+		g_param_spec_override("state", paramSpec);
+
+	paramSpec=g_object_interface_find_property(windowIface, "actions");
+	XfdashboardWindowTrackerWindowX11Properties[PROP_ACTIONS]=
+		g_param_spec_override("actions", paramSpec);
+
+	g_object_class_install_properties(gobjectClass, PROP_LAST, XfdashboardWindowTrackerWindowX11Properties);
+
+	/* Release allocated resources */
+	g_type_default_interface_unref(windowIface);
+}
+
+/* Object initialization
+ * Create private structure and set up default values
+ */
+void xfdashboard_window_tracker_window_x11_init(XfdashboardWindowTrackerWindowX11 *self)
+{
+	XfdashboardWindowTrackerWindowX11Private	*priv;
+
+	priv=self->priv=XFDASHBOARD_WINDOW_TRACKER_WINDOW_X11_GET_PRIVATE(self);
+
+	/* Set default values */
+	priv->window=NULL;
+}
+
+
+/* IMPLEMENTATION: Public API */
+
+/**
+ * xfdashboard_window_tracker_window_x11_get_window:
+ * @self: A #XfdashboardWindowTrackerWindowX11
+ *
+ * Returns the wrapped window of libwnck.
+ *
+ * Return value: (transfer none): the #WnckWindow wrapped by @self. The returned
+ *   #WnckWindow is owned by libwnck and must not be referenced or unreferenced.
+ */
+WnckWindow* xfdashboard_window_tracker_window_x11_get_window(XfdashboardWindowTrackerWindowX11 *self)
+{
+	XfdashboardWindowTrackerWindowX11Private	*priv;
+
+	g_return_val_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_WINDOW_X11(self), NULL);
+
+	priv=self->priv;
+
+	/* A wnck window must be wrapped by this object */
+	if(!priv->window)
+	{
+		XFDASHBOARD_WINDOW_TRACKER_WINDOW_X11_WARN_NO_WINDOW(self);
+		return(NULL);
+	}
+
+	/* Return wrapped libwnck window */
+	return(self->priv->window);
+}
+
+/**
+ * xfdashboard_window_tracker_window_x11_get_xid:
+ * @self: A #XfdashboardWindowTrackerWindowX11
+ *
+ * Gets the X window ID of the wrapped libwnck's window at @self.
+ *
+ * Return value: the X window ID of @self.
+ **/
+gulong xfdashboard_window_tracker_window_x11_get_xid(XfdashboardWindowTrackerWindowX11 *self)
+{
+	XfdashboardWindowTrackerWindowX11Private	*priv;
+
+	g_return_val_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_WINDOW_X11(self), None);
+
+	priv=self->priv;
+
+	/* A wnck window must be wrapped by this object */
+	if(!priv->window)
+	{
+		XFDASHBOARD_WINDOW_TRACKER_WINDOW_X11_WARN_NO_WINDOW(self);
+		return(None);
+	}
+
+	/* Return X window ID */
+	return(wnck_window_get_xid(priv->window));
+}
diff --git a/libxfdashboard/x11/window-tracker-window-x11.h b/libxfdashboard/x11/window-tracker-window-x11.h
new file mode 100644
index 0000000..691e318
--- /dev/null
+++ b/libxfdashboard/x11/window-tracker-window-x11.h
@@ -0,0 +1,82 @@
+/*
+ * window-tracker-window: A window tracked by window tracker and also
+ *                        a wrapper class around WnckWindow.
+ *                        By wrapping libwnck objects we can use a virtual
+ *                        stable API while the API in libwnck changes
+ *                        within versions. We only need to use #ifdefs in
+ *                        window tracker object and nowhere else in the code.
+ * 
+ * Copyright 2012-2017 Stephan Haller <nomad at froevel.de>
+ * 
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ * 
+ * 
+ */
+
+#ifndef __LIBXFDASHBOARD_WINDOW_TRACKER_WINDOW_X11__
+#define __LIBXFDASHBOARD_WINDOW_TRACKER_WINDOW_X11__
+
+#if !defined(__LIBXFDASHBOARD_H_INSIDE__) && !defined(LIBXFDASHBOARD_COMPILATION)
+#error "Only <libxfdashboard/libxfdashboard.h> can be included directly."
+#endif
+
+#include <glib-object.h>
+
+#define WNCK_I_KNOW_THIS_IS_UNSTABLE
+#include <libwnck/libwnck.h>
+
+G_BEGIN_DECLS
+
+#define XFDASHBOARD_TYPE_WINDOW_TRACKER_WINDOW_X11				(xfdashboard_window_tracker_window_x11_get_type())
+#define XFDASHBOARD_WINDOW_TRACKER_WINDOW_X11(obj)				(G_TYPE_CHECK_INSTANCE_CAST((obj), XFDASHBOARD_TYPE_WINDOW_TRACKER_WINDOW_X11, XfdashboardWindowTrackerWindowX11))
+#define XFDASHBOARD_IS_WINDOW_TRACKER_WINDOW_X11(obj)			(G_TYPE_CHECK_INSTANCE_TYPE((obj), XFDASHBOARD_TYPE_WINDOW_TRACKER_WINDOW_X11))
+#define XFDASHBOARD_WINDOW_TRACKER_WINDOW_X11_CLASS(klass)		(G_TYPE_CHECK_CLASS_CAST((klass), XFDASHBOARD_TYPE_WINDOW_TRACKER_WINDOW_X11, XfdashboardWindowTrackerWindowX11Class))
+#define XFDASHBOARD_IS_WINDOW_TRACKER_WINDOW_X11_CLASS(klass)	(G_TYPE_CHECK_CLASS_TYPE((klass), XFDASHBOARD_TYPE_WINDOW_TRACKER_WINDOW_X11))
+#define XFDASHBOARD_WINDOW_TRACKER_WINDOW_X11_GET_CLASS(obj)	(G_TYPE_INSTANCE_GET_CLASS((obj), XFDASHBOARD_TYPE_WINDOW_TRACKER_WINDOW_X11, XfdashboardWindowTrackerWindowX11Class))
+
+typedef struct _XfdashboardWindowTrackerWindowX11				XfdashboardWindowTrackerWindowX11;
+typedef struct _XfdashboardWindowTrackerWindowX11Class			XfdashboardWindowTrackerWindowX11Class;
+typedef struct _XfdashboardWindowTrackerWindowX11Private		XfdashboardWindowTrackerWindowX11Private;
+
+struct _XfdashboardWindowTrackerWindowX11
+{
+	/*< private >*/
+	/* Parent instance */
+	GObject										parent_instance;
+
+	/* Private structure */
+	XfdashboardWindowTrackerWindowX11Private	*priv;
+};
+
+struct _XfdashboardWindowTrackerWindowX11Class
+{
+	/*< private >*/
+	/* Parent class */
+	GObjectClass								parent_class;
+
+	/*< public >*/
+	/* Virtual functions */
+};
+
+/* Public API */
+GType xfdashboard_window_tracker_window_x11_get_type(void) G_GNUC_CONST;
+
+WnckWindow* xfdashboard_window_tracker_window_x11_get_window(XfdashboardWindowTrackerWindowX11 *self);
+gulong xfdashboard_window_tracker_window_x11_get_xid(XfdashboardWindowTrackerWindowX11 *self);
+
+G_END_DECLS
+
+#endif	/* __LIBXFDASHBOARD_WINDOW_TRACKER_WINDOW_X11__ */
diff --git a/libxfdashboard/x11/window-tracker-workspace-x11.c b/libxfdashboard/x11/window-tracker-workspace-x11.c
new file mode 100644
index 0000000..32cf889
--- /dev/null
+++ b/libxfdashboard/x11/window-tracker-workspace-x11.c
@@ -0,0 +1,442 @@
+/*
+ * window-tracker-workspace: A workspace tracked by window tracker and
+ *                           also a wrapper class around WnckWorkspace.
+ *                           By wrapping libwnck objects we can use a 
+ *                           virtual stable API while the API in libwnck
+ *                           changes within versions. We only need to
+ *                           use #ifdefs in window tracker object and
+ *                           nowhere else in the code.
+ * 
+ * Copyright 2012-2017 Stephan Haller <nomad at froevel.de>
+ * 
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ * 
+ * 
+ */
+
+/**
+ * SECTION:window-tracker-workspace-x11
+ * @short_description: A workspace used by X11 window tracker
+ * @include: xfdashboard/x11/window-tracker-workspace-x11.h
+ *
+ * TODO: DESCRIPTION
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <libxfdashboard/x11/window-tracker-workspace-x11.h>
+
+#define WNCK_I_KNOW_THIS_IS_UNSTABLE
+#include <libwnck/libwnck.h>
+
+#include <glib/gi18n-lib.h>
+
+#include <libxfdashboard/x11/window-tracker-x11.h>
+#include <libxfdashboard/window-tracker.h>
+#include <libxfdashboard/marshal.h>
+#include <libxfdashboard/compat.h>
+
+
+/* Define this class in GObject system */
+static void _xfdashboard_window_tracker_workspace_x11_window_tracker_workspace_iface_init(XfdashboardWindowTrackerWorkspaceInterface *iface);
+
+G_DEFINE_TYPE_WITH_CODE(XfdashboardWindowTrackerWorkspaceX11,
+						xfdashboard_window_tracker_workspace_x11,
+						G_TYPE_OBJECT,
+						G_IMPLEMENT_INTERFACE(XFDASHBOARD_TYPE_WINDOW_TRACKER_WORKSPACE, _xfdashboard_window_tracker_workspace_x11_window_tracker_workspace_iface_init))
+
+/* Private structure - access only by public API if needed */
+#define XFDASHBOARD_WINDOW_TRACKER_WORKSPACE_X11_GET_PRIVATE(obj)              \
+	(G_TYPE_INSTANCE_GET_PRIVATE((obj), XFDASHBOARD_TYPE_WINDOW_TRACKER_WORKSPACE_X11, XfdashboardWindowTrackerWorkspaceX11Private))
+
+struct _XfdashboardWindowTrackerWorkspaceX11Private
+{
+	/* Properties related */
+	WnckWorkspace							*workspace;
+};
+
+
+/* Properties */
+enum
+{
+	PROP_0,
+
+	PROP_WORKSPACE,
+
+	PROP_LAST
+};
+
+static GParamSpec* XfdashboardWindowTrackerWorkspaceX11Properties[PROP_LAST]={ 0, };
+
+
+/* IMPLEMENTATION: Private variables and methods */
+#define XFDASHBOARD_WINDOW_TRACKER_WORKSPACE_X11_WARN_NO_WORKSPACE(self)       \
+	g_critical(_("No wnck workspace wrapped at %s in called function %s"),     \
+				G_OBJECT_TYPE_NAME(self),                                      \
+				__func__);
+
+#define XFDASHBOARD_WINDOW_TRACKER_WORKSPACE_X11_WARN_WRONG_WORKSPACE(self)    \
+	g_critical(_("Got signal from wrong wnck workspace wrapped at %s in called function %s"),\
+				G_OBJECT_TYPE_NAME(self),                                      \
+				__func__);
+
+/* Proxy signal for mapped wnck window which changed name */
+static void _xfdashboard_window_tracker_workspace_x11_on_wnck_name_changed(XfdashboardWindowTrackerWorkspaceX11 *self,
+																			gpointer inUserData)
+{
+	XfdashboardWindowTrackerWorkspaceX11Private		*priv;
+	WnckWorkspace									*workspace;
+
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_WORKSPACE_X11(self));
+	g_return_if_fail(WNCK_IS_WORKSPACE(inUserData));
+
+	priv=self->priv;
+	workspace=WNCK_WORKSPACE(inUserData);
+
+	/* Check that workspace emitting this signal is the mapped workspace of this object */
+	if(priv->workspace!=workspace)
+	{
+		XFDASHBOARD_WINDOW_TRACKER_WORKSPACE_X11_WARN_WRONG_WORKSPACE(self);
+		return;
+	}
+
+	/* Proxy signal */
+	g_signal_emit_by_name(self, "name-changed");
+}
+
+/* Set wnck workspace to map in this workspace object */
+static void _xfdashboard_window_tracker_workspace_x11_set_workspace(XfdashboardWindowTrackerWorkspaceX11 *self,
+																	WnckWorkspace *inWorkspace)
+{
+	XfdashboardWindowTrackerWorkspaceX11Private		*priv;
+
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_WORKSPACE_X11(self));
+	g_return_if_fail(!inWorkspace || WNCK_IS_WORKSPACE(inWorkspace));
+
+	priv=self->priv;
+
+	/* Set value if changed */
+	if(priv->workspace!=inWorkspace)
+	{
+		/* Disconnect signals to old window (if available) and reset states */
+		if(priv->workspace)
+		{
+			/* Remove weak reference at old workspace */
+			g_object_remove_weak_pointer(G_OBJECT(priv->workspace), (gpointer*)&priv->workspace);
+
+			/* Disconnect signal handlers */
+			g_signal_handlers_disconnect_by_data(priv->workspace, self);
+			priv->workspace=NULL;
+		}
+
+		/* Set new value */
+		priv->workspace=inWorkspace;
+
+		/* Initialize states and connect signals if window is set */
+		if(priv->workspace)
+		{
+			/* Add weak reference at new workspace */
+			g_object_add_weak_pointer(G_OBJECT(priv->workspace), (gpointer*)&priv->workspace);
+
+			/* Connect signals */
+			g_signal_connect_swapped(priv->workspace,
+										"name-changed",
+										G_CALLBACK(_xfdashboard_window_tracker_workspace_x11_on_wnck_name_changed),
+										self);
+		}
+
+		/* Notify about property change */
+		g_object_notify_by_pspec(G_OBJECT(self), XfdashboardWindowTrackerWorkspaceX11Properties[PROP_WORKSPACE]);
+	}
+}
+
+
+/* IMPLEMENTATION: Interface XfdashboardWindowTrackerWorkspace */
+
+/* Get number of workspace */
+static gint _xfdashboard_window_tracker_workspace_x11_window_tracker_workspace_get_number(XfdashboardWindowTrackerWorkspace *inWorkspace)
+{
+	XfdashboardWindowTrackerWorkspaceX11			*self;
+	XfdashboardWindowTrackerWorkspaceX11Private		*priv;
+
+	g_return_val_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_WORKSPACE_X11(inWorkspace), -1);
+
+	self=XFDASHBOARD_WINDOW_TRACKER_WORKSPACE_X11(inWorkspace);
+	priv=self->priv;
+
+	/* A wnck workspace must be wrapped by this object */
+	if(!priv->workspace)
+	{
+		XFDASHBOARD_WINDOW_TRACKER_WORKSPACE_X11_WARN_NO_WORKSPACE(self);
+		return(-1);
+	}
+
+	/* Return number of workspace */
+	return(wnck_workspace_get_number(priv->workspace));
+}
+
+/* Get name of workspace */
+static const gchar* _xfdashboard_window_tracker_workspace_x11_window_tracker_workspace_get_name(XfdashboardWindowTrackerWorkspace *inWorkspace)
+{
+	XfdashboardWindowTrackerWorkspaceX11			*self;
+	XfdashboardWindowTrackerWorkspaceX11Private		*priv;
+
+	g_return_val_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_WORKSPACE_X11(inWorkspace), NULL);
+
+	self=XFDASHBOARD_WINDOW_TRACKER_WORKSPACE_X11(inWorkspace);
+	priv=self->priv;
+
+	/* A wnck workspace must be wrapped by this object */
+	if(!priv->workspace)
+	{
+		XFDASHBOARD_WINDOW_TRACKER_WORKSPACE_X11_WARN_NO_WORKSPACE(self);
+		return(NULL);
+	}
+
+	/* Return name of workspace */
+	return(wnck_workspace_get_name(priv->workspace));
+}
+
+/* Get size of workspace */
+static void _xfdashboard_window_tracker_workspace_x11_window_tracker_workspace_get_size(XfdashboardWindowTrackerWorkspace *inWorkspace,
+																						gint *outWidth,
+																						gint *outHeight)
+{
+	XfdashboardWindowTrackerWorkspaceX11			*self;
+	XfdashboardWindowTrackerWorkspaceX11Private		*priv;
+	gint											width, height;
+
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_WORKSPACE_X11(inWorkspace));
+
+	self=XFDASHBOARD_WINDOW_TRACKER_WORKSPACE_X11(inWorkspace);
+	priv=self->priv;
+
+	/* A wnck workspace must be wrapped by this object */
+	if(!priv->workspace)
+	{
+		XFDASHBOARD_WINDOW_TRACKER_WORKSPACE_X11_WARN_NO_WORKSPACE(self);
+		return;
+	}
+
+	/* Get width and height of workspace */
+	width=wnck_workspace_get_width(priv->workspace);
+	height=wnck_workspace_get_height(priv->workspace);
+
+	/* Set values */
+	if(outWidth) *outWidth=width;
+	if(outHeight) *outHeight=height;
+}
+
+/* Determine if this workspace is the active one */
+static gboolean _xfdashboard_window_tracker_workspace_x11_window_tracker_workspace_is_active(XfdashboardWindowTrackerWorkspace *inWorkspace)
+{
+	XfdashboardWindowTrackerWorkspaceX11			*self;
+	XfdashboardWindowTrackerWorkspaceX11Private		*priv;
+	XfdashboardWindowTracker						*windowTracker;
+	XfdashboardWindowTrackerWorkspace				*activeWorkspace;
+
+	g_return_val_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_WORKSPACE_X11(inWorkspace), FALSE);
+
+	self=XFDASHBOARD_WINDOW_TRACKER_WORKSPACE_X11(inWorkspace);
+	priv=self->priv;
+
+	/* A wnck workspace must be wrapped by this object */
+	if(!priv->workspace)
+	{
+		XFDASHBOARD_WINDOW_TRACKER_WORKSPACE_X11_WARN_NO_WORKSPACE(self);
+		return(FALSE);
+	}
+
+	/* Get current active workspace */
+	windowTracker=xfdashboard_window_tracker_get_default();
+	activeWorkspace=xfdashboard_window_tracker_get_active_workspace(windowTracker);
+	g_object_unref(windowTracker);
+
+	/* Return TRUE if current active workspace is this workspace */
+	return(xfdashboard_window_tracker_workspace_is_equal(inWorkspace, activeWorkspace));
+}
+
+/* Activate workspace */
+static void _xfdashboard_window_tracker_workspace_x11_window_tracker_workspace_activate(XfdashboardWindowTrackerWorkspace *inWorkspace)
+{
+	XfdashboardWindowTrackerWorkspaceX11			*self;
+	XfdashboardWindowTrackerWorkspaceX11Private		*priv;
+
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_WORKSPACE_X11(inWorkspace));
+
+	self=XFDASHBOARD_WINDOW_TRACKER_WORKSPACE_X11(inWorkspace);
+	priv=self->priv;
+
+	/* A wnck workspace must be wrapped by this object */
+	if(!priv->workspace)
+	{
+		XFDASHBOARD_WINDOW_TRACKER_WORKSPACE_X11_WARN_NO_WORKSPACE(self);
+		return;
+	}
+
+	/* Activate workspace */
+	wnck_workspace_activate(priv->workspace, xfdashboard_window_tracker_x11_get_time());
+}
+
+/* Interface initialization
+ * Set up default functions
+ */
+static void _xfdashboard_window_tracker_workspace_x11_window_tracker_workspace_iface_init(XfdashboardWindowTrackerWorkspaceInterface *iface)
+{
+	iface->get_number=_xfdashboard_window_tracker_workspace_x11_window_tracker_workspace_get_number;
+	iface->get_name=_xfdashboard_window_tracker_workspace_x11_window_tracker_workspace_get_name;
+
+	iface->get_size=_xfdashboard_window_tracker_workspace_x11_window_tracker_workspace_get_size;
+
+	iface->is_active=_xfdashboard_window_tracker_workspace_x11_window_tracker_workspace_is_active;
+	iface->activate=_xfdashboard_window_tracker_workspace_x11_window_tracker_workspace_activate;
+}
+
+
+/* IMPLEMENTATION: GObject */
+
+/* Dispose this object */
+static void _xfdashboard_window_tracker_workspace_x11_dispose(GObject *inObject)
+{
+	XfdashboardWindowTrackerWorkspaceX11			*self=XFDASHBOARD_WINDOW_TRACKER_WORKSPACE_X11(inObject);
+	XfdashboardWindowTrackerWorkspaceX11Private		*priv=self->priv;
+
+	/* Dispose allocated resources */
+	if(priv->workspace)
+	{
+		/* Remove weak reference at current workspace */
+		g_object_remove_weak_pointer(G_OBJECT(priv->workspace), (gpointer*)&priv->workspace);
+
+		/* Disconnect signal handlers */
+		g_signal_handlers_disconnect_by_data(priv->workspace, self);
+		priv->workspace=NULL;
+	}
+
+	/* Call parent's class dispose method */
+	G_OBJECT_CLASS(xfdashboard_window_tracker_workspace_x11_parent_class)->dispose(inObject);
+}
+
+/* Set/get properties */
+static void _xfdashboard_window_tracker_workspace_x11_set_property(GObject *inObject,
+																	guint inPropID,
+																	const GValue *inValue,
+																	GParamSpec *inSpec)
+{
+	XfdashboardWindowTrackerWorkspaceX11		*self=XFDASHBOARD_WINDOW_TRACKER_WORKSPACE_X11(inObject);
+
+	switch(inPropID)
+	{
+		case PROP_WORKSPACE:
+			_xfdashboard_window_tracker_workspace_x11_set_workspace(self, WNCK_WORKSPACE(g_value_get_object(inValue)));
+			break;
+
+		default:
+			G_OBJECT_WARN_INVALID_PROPERTY_ID(inObject, inPropID, inSpec);
+			break;
+	}
+}
+
+static void _xfdashboard_window_tracker_workspace_x11_get_property(GObject *inObject,
+																	guint inPropID,
+																	GValue *outValue,
+																	GParamSpec *inSpec)
+{
+	XfdashboardWindowTrackerWorkspaceX11		*self=XFDASHBOARD_WINDOW_TRACKER_WORKSPACE_X11(inObject);
+
+	switch(inPropID)
+	{
+		case PROP_WORKSPACE:
+			g_value_set_object(outValue, self->priv->workspace);
+			break;
+
+		default:
+			G_OBJECT_WARN_INVALID_PROPERTY_ID(inObject, inPropID, inSpec);
+			break;
+	}
+}
+
+/* Class initialization
+ * Override functions in parent classes and define properties
+ * and signals
+ */
+void xfdashboard_window_tracker_workspace_x11_class_init(XfdashboardWindowTrackerWorkspaceX11Class *klass)
+{
+	GObjectClass		*gobjectClass=G_OBJECT_CLASS(klass);
+
+	/* Override functions */
+	gobjectClass->dispose=_xfdashboard_window_tracker_workspace_x11_dispose;
+	gobjectClass->set_property=_xfdashboard_window_tracker_workspace_x11_set_property;
+	gobjectClass->get_property=_xfdashboard_window_tracker_workspace_x11_get_property;
+
+	/* Set up private structure */
+	g_type_class_add_private(klass, sizeof(XfdashboardWindowTrackerWorkspaceX11Private));
+
+	/* Define properties */
+	XfdashboardWindowTrackerWorkspaceX11Properties[PROP_WORKSPACE]=
+		g_param_spec_object("workspace",
+							_("Window"),
+							_("The mapped wnck workspace"),
+							WNCK_TYPE_WORKSPACE,
+							G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
+
+	g_object_class_install_properties(gobjectClass, PROP_LAST, XfdashboardWindowTrackerWorkspaceX11Properties);
+}
+
+/* Object initialization
+ * Create private structure and set up default values
+ */
+void xfdashboard_window_tracker_workspace_x11_init(XfdashboardWindowTrackerWorkspaceX11 *self)
+{
+	XfdashboardWindowTrackerWorkspaceX11Private	*priv;
+
+	priv=self->priv=XFDASHBOARD_WINDOW_TRACKER_WORKSPACE_X11_GET_PRIVATE(self);
+
+	/* Set default values */
+	priv->workspace=NULL;
+}
+
+
+/* IMPLEMENTATION: Public API */
+
+/**
+ * xfdashboard_window_tracker_workspace_x11_get_workspace:
+ * @self: A #XfdashboardWindowTrackerWorkspaceX11
+ *
+ * Returns the wrapped workspace of libwnck.
+ *
+ * Return value: (transfer none): the #WnckWorkspace wrapped by @self. The returned
+ *   #WnckWorkspace is owned by libwnck and must not be referenced or unreferenced.
+ */
+WnckWorkspace* xfdashboard_window_tracker_workspace_x11_get_workspace(XfdashboardWindowTrackerWorkspaceX11 *self)
+{
+	XfdashboardWindowTrackerWorkspaceX11Private		*priv;
+
+	g_return_val_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_WORKSPACE_X11(self), NULL);
+
+	priv=self->priv;
+
+	/* A wnck workspace must be wrapped by this object */
+	if(!priv->workspace)
+	{
+		XFDASHBOARD_WINDOW_TRACKER_WORKSPACE_X11_WARN_NO_WORKSPACE(self);
+		return(NULL);
+	}
+
+	/* Return wrapped libwnck workspace */
+	return(self->priv->workspace);
+}
diff --git a/libxfdashboard/x11/window-tracker-workspace-x11.h b/libxfdashboard/x11/window-tracker-workspace-x11.h
new file mode 100644
index 0000000..f0f2265
--- /dev/null
+++ b/libxfdashboard/x11/window-tracker-workspace-x11.h
@@ -0,0 +1,82 @@
+/*
+ * window-tracker-workspace: A workspace tracked by window tracker and
+ *                           also a wrapper class around WnckWorkspace.
+ *                           By wrapping libwnck objects we can use a 
+ *                           virtual stable API while the API in libwnck
+ *                           changes within versions. We only need to
+ *                           use #ifdefs in window tracker object and
+ *                           nowhere else in the code.
+ * 
+ * Copyright 2012-2017 Stephan Haller <nomad at froevel.de>
+ * 
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ * 
+ * 
+ */
+
+#ifndef __LIBXFDASHBOARD_WINDOW_TRACKER_WORKSPACE_X11__
+#define __LIBXFDASHBOARD_WINDOW_TRACKER_WORKSPACE_X11__
+
+#if !defined(__LIBXFDASHBOARD_H_INSIDE__) && !defined(LIBXFDASHBOARD_COMPILATION)
+#error "Only <libxfdashboard/libxfdashboard.h> can be included directly."
+#endif
+
+#include <glib-object.h>
+
+#define WNCK_I_KNOW_THIS_IS_UNSTABLE
+#include <libwnck/libwnck.h>
+
+G_BEGIN_DECLS
+
+#define XFDASHBOARD_TYPE_WINDOW_TRACKER_WORKSPACE_X11				(xfdashboard_window_tracker_workspace_x11_get_type())
+#define XFDASHBOARD_WINDOW_TRACKER_WORKSPACE_X11(obj)				(G_TYPE_CHECK_INSTANCE_CAST((obj), XFDASHBOARD_TYPE_WINDOW_TRACKER_WORKSPACE_X11, XfdashboardWindowTrackerWorkspaceX11))
+#define XFDASHBOARD_IS_WINDOW_TRACKER_WORKSPACE_X11(obj)			(G_TYPE_CHECK_INSTANCE_TYPE((obj), XFDASHBOARD_TYPE_WINDOW_TRACKER_WORKSPACE_X11))
+#define XFDASHBOARD_WINDOW_TRACKER_WORKSPACE_X11_CLASS(klass)		(G_TYPE_CHECK_CLASS_CAST((klass), XFDASHBOARD_TYPE_WINDOW_TRACKER_WORKSPACE_X11, XfdashboardWindowTrackerWorkspaceX11Class))
+#define XFDASHBOARD_IS_WINDOW_TRACKER_WORKSPACE_X11_CLASS(klass)	(G_TYPE_CHECK_CLASS_TYPE((klass), XFDASHBOARD_TYPE_WINDOW_TRACKER_WORKSPACE_X11))
+#define XFDASHBOARD_WINDOW_TRACKER_WORKSPACE_X11_GET_CLASS(obj)		(G_TYPE_INSTANCE_GET_CLASS((obj), XFDASHBOARD_TYPE_WINDOW_TRACKER_WORKSPACE_X11, XfdashboardWindowTrackerWorkspaceX11Class))
+
+typedef struct _XfdashboardWindowTrackerWorkspaceX11				XfdashboardWindowTrackerWorkspaceX11;
+typedef struct _XfdashboardWindowTrackerWorkspaceX11Class			XfdashboardWindowTrackerWorkspaceX11Class;
+typedef struct _XfdashboardWindowTrackerWorkspaceX11Private			XfdashboardWindowTrackerWorkspaceX11Private;
+
+struct _XfdashboardWindowTrackerWorkspaceX11
+{
+	/*< private >*/
+	/* Parent instance */
+	GObject											parent_instance;
+
+	/* Private structure */
+	XfdashboardWindowTrackerWorkspaceX11Private		*priv;
+};
+
+struct _XfdashboardWindowTrackerWorkspaceX11Class
+{
+	/*< private >*/
+	/* Parent class */
+	GObjectClass									parent_class;
+
+	/*< public >*/
+	/* Virtual functions */
+};
+
+/* Public API */
+GType xfdashboard_window_tracker_workspace_x11_get_type(void) G_GNUC_CONST;
+
+WnckWorkspace* xfdashboard_window_tracker_workspace_x11_get_workspace(XfdashboardWindowTrackerWorkspaceX11 *self);
+
+G_END_DECLS
+
+#endif	/* __LIBXFDASHBOARD_WINDOW_TRACKER_WORKSPACE_X11__ */
diff --git a/libxfdashboard/x11/window-tracker-x11.c b/libxfdashboard/x11/window-tracker-x11.c
new file mode 100644
index 0000000..e333a83
--- /dev/null
+++ b/libxfdashboard/x11/window-tracker-x11.c
@@ -0,0 +1,1890 @@
+/*
+ * window-tracker: Tracks windows, workspaces, monitors and
+ *                 listens for changes. It also bundles libwnck into one
+ *                 class.
+ *                 By wrapping libwnck objects we can use a virtual
+ *                 stable API while the API in libwnck changes within versions.
+ *                 We only need to use #ifdefs in window tracker object
+ *                 and nowhere else in the code.
+ * 
+ * Copyright 2012-2017 Stephan Haller <nomad at froevel.de>
+ * 
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ * 
+ * 
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <libxfdashboard/x11/window-tracker-x11.h>
+
+#define WNCK_I_KNOW_THIS_IS_UNSTABLE
+#include <libwnck/libwnck.h>
+
+#include <glib/gi18n-lib.h>
+#include <clutter/clutter.h>
+#include <clutter/x11/clutter-x11.h>
+#include <gdk/gdkx.h>
+#ifdef HAVE_XINERAMA
+#include <X11/extensions/Xinerama.h>
+#endif
+
+#include <libxfdashboard/window-tracker.h>
+#include <libxfdashboard/x11/window-tracker-monitor-x11.h>
+#include <libxfdashboard/x11/window-tracker-window-x11.h>
+#include <libxfdashboard/x11/window-tracker-workspace-x11.h>
+#include <libxfdashboard/marshal.h>
+#include <libxfdashboard/application.h>
+#include <libxfdashboard/compat.h>
+#include <libxfdashboard/debug.h>
+
+
+/* Define this class in GObject system */
+static void _xfdashboard_window_tracker_x11_window_tracker_iface_init(XfdashboardWindowTrackerInterface *iface);
+
+G_DEFINE_TYPE_WITH_CODE(XfdashboardWindowTrackerX11,
+						xfdashboard_window_tracker_x11,
+						G_TYPE_OBJECT,
+						G_IMPLEMENT_INTERFACE(XFDASHBOARD_TYPE_WINDOW_TRACKER, _xfdashboard_window_tracker_x11_window_tracker_iface_init))
+
+/* Private structure - access only by public API if needed */
+#define XFDASHBOARD_WINDOW_TRACKER_X11_GET_PRIVATE(obj)                        \
+	(G_TYPE_INSTANCE_GET_PRIVATE((obj), XFDASHBOARD_TYPE_WINDOW_TRACKER_X11, XfdashboardWindowTrackerX11Private))
+
+struct _XfdashboardWindowTrackerX11Private
+{
+	/* Properties related */
+	XfdashboardWindowTrackerWindowX11		*activeWindow;
+	XfdashboardWindowTrackerWorkspaceX11	*activeWorkspace;
+	XfdashboardWindowTrackerMonitorX11		*primaryMonitor;
+
+	/* Instance related */
+	GList									*windows;
+	GList									*workspaces;
+	GList									*monitors;
+
+	XfdashboardApplication					*application;
+	gboolean								isAppSuspended;
+	guint									suspendSignalID;
+
+	WnckScreen								*screen;
+
+	gboolean								supportsMultipleMonitors;
+	GdkScreen								*gdkScreen;
+};
+
+/* Properties */
+enum
+{
+	PROP_0,
+
+	/* Overriden properties of interface: XfdashboardWindowTracker */
+	PROP_ACTIVE_WINDOW,
+	PROP_ACTIVE_WORKSPACE,
+	PROP_PRIMARY_MONITOR,
+
+	PROP_LAST
+};
+
+static GParamSpec* XfdashboardWindowTrackerX11Properties[PROP_LAST]={ 0, };
+
+
+/* IMPLEMENTATION: Private variables and methods */
+
+/* Free workspace object */
+static void _xfdashboard_window_tracker_x11_free_workspace(XfdashboardWindowTrackerX11 *self,
+															XfdashboardWindowTrackerWorkspaceX11 *inWorkspace)
+{
+	XfdashboardWindowTrackerX11Private		*priv;
+	GList									*iter;
+
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_X11(self));
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_WORKSPACE_X11(inWorkspace));
+
+	priv=self->priv;
+
+#if DEBUG
+	/* There must be only one reference on that workspace object */
+	XFDASHBOARD_DEBUG(self, WINDOWS,
+				"Freeing workspace %s@%p named '%s' with ref-count=%d",
+				G_OBJECT_TYPE_NAME(inWorkspace), inWorkspace,
+				xfdashboard_window_tracker_workspace_get_name(XFDASHBOARD_WINDOW_TRACKER_WORKSPACE(inWorkspace)),
+				G_OBJECT(inWorkspace)->ref_count);
+	g_assert(G_OBJECT(inWorkspace)->ref_count==1);
+#endif
+
+	/* Find entry in workspace list and remove it if found */
+	iter=g_list_find(priv->workspaces, inWorkspace);
+	if(iter)
+	{
+		priv->workspaces=g_list_delete_link(priv->workspaces, iter);
+	}
+
+	/* Free workspace object */
+	g_object_unref(inWorkspace);
+}
+
+/* Get workspace object for requested wnck workspace */
+static XfdashboardWindowTrackerWorkspaceX11* _xfdashboard_window_tracker_x11_get_workspace_for_wnck(XfdashboardWindowTrackerX11 *self,
+																									WnckWorkspace *inWorkspace)
+{
+	XfdashboardWindowTrackerX11Private		*priv;
+	GList									*iter;
+	XfdashboardWindowTrackerWorkspaceX11	*workspace;
+
+	g_return_val_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_X11(self), NULL);
+	g_return_val_if_fail(WNCK_IS_WORKSPACE(inWorkspace), NULL);
+
+	priv=self->priv;
+
+	/* Iterate through list of workspace object and check if an object for the
+	 * request wnck workspace exist. If one is found then return this existing
+	 * workspace object.
+	 */
+	for(iter=priv->workspaces; iter; iter=g_list_next(iter))
+	{
+		/* Get currently iterated workspace object */
+		workspace=XFDASHBOARD_WINDOW_TRACKER_WORKSPACE_X11(iter->data);
+		if(!workspace) continue;
+
+		/* Check if this workspace object wraps the requested wnck workspace */
+		if(xfdashboard_window_tracker_workspace_x11_get_workspace(workspace)==inWorkspace)
+		{
+			/* Return existing workspace object */
+			return(workspace);
+		}
+	}
+
+	/* If we get here, return NULL as we have not found a matching workspace
+	 * object for the requested wnck workspace.
+	 */
+	return(NULL);
+}
+
+/* Create workspace object which must not exist yet */
+static XfdashboardWindowTrackerWorkspaceX11* _xfdashboard_window_tracker_x11_create_workspace_for_wnck(XfdashboardWindowTrackerX11 *self,
+																										WnckWorkspace *inWorkspace)
+{
+	XfdashboardWindowTrackerX11Private		*priv;
+	XfdashboardWindowTrackerWorkspaceX11	*workspace;
+
+	g_return_val_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_X11(self), NULL);
+	g_return_val_if_fail(WNCK_IS_WORKSPACE(inWorkspace), NULL);
+
+	priv=self->priv;
+
+	/* Iterate through list of workspace object and check if an object for the
+	 * request wnck workspace exist. If one is found then the existing workspace object.
+	 */
+	workspace=_xfdashboard_window_tracker_x11_get_workspace_for_wnck(self, inWorkspace);
+	if(workspace)
+	{
+		/* Return existing workspace object */
+		XFDASHBOARD_DEBUG(self, WINDOWS,
+					"A workspace object %s@%p for wnck workspace %s@%p named '%s' exists already",
+					G_OBJECT_TYPE_NAME(workspace), workspace,
+					G_OBJECT_TYPE_NAME(inWorkspace), inWorkspace, wnck_workspace_get_name(inWorkspace));
+
+		return(workspace);
+	}
+
+	/* Create workspace object */
+	workspace=XFDASHBOARD_WINDOW_TRACKER_WORKSPACE_X11(g_object_new(XFDASHBOARD_TYPE_WINDOW_TRACKER_WORKSPACE_X11,
+														"workspace", inWorkspace,
+														NULL));
+	if(!workspace)
+	{
+		g_critical(_("Could not create workspace object of type %s for workspace '%s'"),
+					g_type_name(XFDASHBOARD_TYPE_WINDOW_TRACKER_WORKSPACE_X11),
+					wnck_workspace_get_name(inWorkspace));
+		return(NULL);
+	}
+
+	/* Add new workspace object to list of workspace objects */
+	priv->workspaces=g_list_prepend(priv->workspaces, workspace);
+
+	/* Return new workspace object */
+	XFDASHBOARD_DEBUG(self, WINDOWS,
+				"Created workspace object %s@%p for wnck workspace %s@%p named '%s'",
+				G_OBJECT_TYPE_NAME(workspace), workspace,
+				G_OBJECT_TYPE_NAME(inWorkspace), inWorkspace, wnck_workspace_get_name(inWorkspace));
+	return(workspace);
+}
+
+/* Free window object */
+static void _xfdashboard_window_tracker_x11_free_window(XfdashboardWindowTrackerX11 *self,
+														XfdashboardWindowTrackerWindowX11 *inWindow)
+{
+	XfdashboardWindowTrackerX11Private		*priv;
+	GList									*iter;
+
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_X11(self));
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_WINDOW_X11(inWindow));
+
+	priv=self->priv;
+
+#if DEBUG
+	/* There must be only one reference on that window object */
+	XFDASHBOARD_DEBUG(self, WINDOWS,
+				"Freeing window %s@%p named '%s' with ref-count=%d",
+				G_OBJECT_TYPE_NAME(inWindow), inWindow,
+				xfdashboard_window_tracker_window_get_name(XFDASHBOARD_WINDOW_TRACKER_WINDOW(inWindow)),
+				G_OBJECT(inWindow)->ref_count);
+	g_assert(G_OBJECT(inWindow)->ref_count==1);
+#endif
+
+	/* Find entry in window list and remove it if found */
+	iter=g_list_find(priv->windows, inWindow);
+	if(iter)
+	{
+		priv->windows=g_list_delete_link(priv->windows, iter);
+	}
+
+	/* Free window object */
+	g_object_unref(inWindow);
+}
+
+/* Get window object for requested wnck window */
+static XfdashboardWindowTrackerWindowX11* _xfdashboard_window_tracker_x11_get_window_for_wnck(XfdashboardWindowTrackerX11 *self,
+																								WnckWindow *inWindow)
+{
+	XfdashboardWindowTrackerX11Private		*priv;
+	GList									*iter;
+	XfdashboardWindowTrackerWindowX11		*window;
+
+	g_return_val_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_X11(self), NULL);
+	g_return_val_if_fail(WNCK_IS_WINDOW(inWindow), NULL);
+
+	priv=self->priv;
+
+	/* Iterate through list of window object and check if an object for the
+	 * request wnck window exist. If one is found then return this existing
+	 * window object.
+	 */
+	for(iter=priv->windows; iter; iter=g_list_next(iter))
+	{
+		/* Get currently iterated window object */
+		window=XFDASHBOARD_WINDOW_TRACKER_WINDOW_X11(iter->data);
+		if(!window) continue;
+
+		/* Check if this window object wraps the requested wnck window */
+		if(xfdashboard_window_tracker_window_x11_get_window(window)==inWindow)
+		{
+			/* Return existing window object */
+			return(window);
+		}
+	}
+
+	/* If we get here, return NULL as we have not found a matching window
+	 * object for the requested wnck window.
+	 */
+	return(NULL);
+}
+
+/* Create window object which must not exist yet */
+static XfdashboardWindowTrackerWindowX11* _xfdashboard_window_tracker_x11_create_window_for_wnck(XfdashboardWindowTrackerX11 *self,
+																									WnckWindow *inWindow)
+{
+	XfdashboardWindowTrackerX11Private		*priv;
+	XfdashboardWindowTrackerWindowX11		*window;
+
+	g_return_val_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_X11(self), NULL);
+	g_return_val_if_fail(WNCK_IS_WINDOW(inWindow), NULL);
+
+	priv=self->priv;
+
+	/* Iterate through list of window object and check if an object for the
+	 * request wnck window exist. If one is found then the existing window object.
+	 */
+	window=_xfdashboard_window_tracker_x11_get_window_for_wnck(self, inWindow);
+	if(window)
+	{
+		/* Return existing window object */
+		XFDASHBOARD_DEBUG(self, WINDOWS,
+					"A window object %s@%p for wnck window %s@%p named '%s' exists already",
+					G_OBJECT_TYPE_NAME(window), window,
+					G_OBJECT_TYPE_NAME(inWindow), inWindow, wnck_window_get_name(inWindow));
+
+		return(window);
+	}
+
+	/* Create window object */
+	window=XFDASHBOARD_WINDOW_TRACKER_WINDOW_X11(g_object_new(XFDASHBOARD_TYPE_WINDOW_TRACKER_WINDOW_X11,
+																"window", inWindow,
+																NULL));
+	if(!window)
+	{
+		g_critical(_("Could not create window object of type %s for window '%s'"),
+					g_type_name(XFDASHBOARD_TYPE_WINDOW_TRACKER_WINDOW_X11),
+					wnck_window_get_name(inWindow));
+		return(NULL);
+	}
+
+	/* Add new window object to list of window objects */
+	priv->windows=g_list_prepend(priv->windows, window);
+
+	/* Return new window object */
+	XFDASHBOARD_DEBUG(self, WINDOWS,
+				"Created window object %s@%p for wnck window %s@%p named '%s'",
+				G_OBJECT_TYPE_NAME(window), window,
+				G_OBJECT_TYPE_NAME(inWindow), inWindow, wnck_window_get_name(inWindow));
+	return(window);
+}
+
+/* Position and/or size of window has changed */
+static void _xfdashboard_window_tracker_x11_on_window_geometry_changed(XfdashboardWindowTrackerX11 *self,
+																		gpointer inUserData)
+{
+	XfdashboardWindowTrackerWindowX11		*window;
+
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER(self));
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_WINDOW_X11(inUserData));
+
+	window=XFDASHBOARD_WINDOW_TRACKER_WINDOW_X11(inUserData);
+
+	/* Emit signal */
+	XFDASHBOARD_DEBUG(self, WINDOWS,
+						"Window '%s' changed position and/or size",
+						xfdashboard_window_tracker_window_get_name(XFDASHBOARD_WINDOW_TRACKER_WINDOW(window)));
+	g_signal_emit_by_name(self, "window-geometry-changed", window);
+}
+
+/* Action items of window has changed */
+static void _xfdashboard_window_tracker_x11_on_window_actions_changed(XfdashboardWindowTrackerX11 *self,
+																		XfdashboardWindowTrackerWindowAction inChangedMask,
+																		XfdashboardWindowTrackerWindowAction inNewValue,
+																		gpointer inUserData)
+{
+	XfdashboardWindowTrackerWindowX11	*window;
+
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER(self));
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_WINDOW_X11(inUserData));
+
+	window=XFDASHBOARD_WINDOW_TRACKER_WINDOW_X11(inUserData);
+
+	/* Emit signal */
+	XFDASHBOARD_DEBUG(self, WINDOWS,
+						"Window '%s' changed actions to %u with mask %u",
+						xfdashboard_window_tracker_window_get_name(XFDASHBOARD_WINDOW_TRACKER_WINDOW(window)),
+						inNewValue, inChangedMask);
+	g_signal_emit_by_name(self, "window-actions-changed", window);
+}
+
+/* State of window has changed */
+static void _xfdashboard_window_tracker_x11_on_window_state_changed(XfdashboardWindowTrackerX11 *self,
+																	XfdashboardWindowTrackerWindowState inChangedMask,
+																	XfdashboardWindowTrackerWindowState inNewValue,
+																	gpointer inUserData)
+{
+	XfdashboardWindowTrackerWindowX11	*window;
+
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER(self));
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_WINDOW_X11(inUserData));
+
+	window=XFDASHBOARD_WINDOW_TRACKER_WINDOW_X11(inUserData);
+
+	/* Emit signal */
+	XFDASHBOARD_DEBUG(self, WINDOWS,
+						"Window '%s' changed state to %u with mask %u",
+						xfdashboard_window_tracker_window_get_name(XFDASHBOARD_WINDOW_TRACKER_WINDOW(window)),
+						inNewValue, inChangedMask);
+	g_signal_emit_by_name(self, "window-state-changed", window);
+}
+
+/* Icon of window has changed */
+static void _xfdashboard_window_tracker_x11_on_window_icon_changed(XfdashboardWindowTrackerX11 *self,
+																	gpointer inUserData)
+{
+	XfdashboardWindowTrackerWindowX11	*window;
+
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER(self));
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_WINDOW_X11(inUserData));
+
+	window=XFDASHBOARD_WINDOW_TRACKER_WINDOW_X11(inUserData);
+
+	/* Emit signal */
+	XFDASHBOARD_DEBUG(self, WINDOWS,
+						"Window '%s' changed its icon",
+						xfdashboard_window_tracker_window_get_name(XFDASHBOARD_WINDOW_TRACKER_WINDOW(window)));
+	g_signal_emit_by_name(self, "window-icon-changed", window);
+}
+
+/* Name of window has changed */
+static void _xfdashboard_window_tracker_x11_on_window_name_changed(XfdashboardWindowTrackerX11 *self,
+																	gpointer inUserData)
+{
+	XfdashboardWindowTrackerWindowX11	*window;
+
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER(self));
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_WINDOW_X11(inUserData));
+
+	window=XFDASHBOARD_WINDOW_TRACKER_WINDOW_X11(inUserData);
+
+	/* Emit signal */
+	XFDASHBOARD_DEBUG(self, WINDOWS,
+						"Window changed its name to '%s'",
+						xfdashboard_window_tracker_window_get_name(XFDASHBOARD_WINDOW_TRACKER_WINDOW(window)));
+	g_signal_emit_by_name(self, "window-name-changed", window);
+}
+
+/* A window has moved to another monitor */
+static void _xfdashboard_window_tracker_x11_on_window_monitor_changed(XfdashboardWindowTrackerX11 *self,
+																		XfdashboardWindowTrackerMonitor *inOldMonitor,
+																		gpointer inUserData)
+{
+	XfdashboardWindowTrackerWindowX11		*window;
+	XfdashboardWindowTrackerMonitor			*newMonitor;
+
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER(self));
+	g_return_if_fail(!inOldMonitor || XFDASHBOARD_IS_WINDOW_TRACKER_MONITOR_X11(inOldMonitor));
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_WINDOW_X11(inUserData));
+
+	window=XFDASHBOARD_WINDOW_TRACKER_WINDOW_X11(inUserData);
+
+	/* Get monitor window resides on. */
+	newMonitor=xfdashboard_window_tracker_window_get_monitor(XFDASHBOARD_WINDOW_TRACKER_WINDOW(window));
+
+	/* Emit signal */
+	XFDASHBOARD_DEBUG(self, WINDOWS,
+						"Window '%s' moved from monitor %d (%s) to %d (%s)",
+						xfdashboard_window_tracker_window_get_name(XFDASHBOARD_WINDOW_TRACKER_WINDOW(window)),
+						inOldMonitor ? xfdashboard_window_tracker_monitor_get_number(inOldMonitor) : -1,
+						(inOldMonitor && xfdashboard_window_tracker_monitor_is_primary(inOldMonitor)) ? "primary" : "non-primary",
+						newMonitor ? xfdashboard_window_tracker_monitor_get_number(newMonitor) : -1,
+						(newMonitor && xfdashboard_window_tracker_monitor_is_primary(newMonitor)) ? "primary" : "non-primary");
+	g_signal_emit_by_name(self, "window-monitor-changed", window, inOldMonitor, newMonitor);
+}
+
+/* A window has moved to another workspace */
+static void _xfdashboard_window_tracker_x11_on_window_workspace_changed(XfdashboardWindowTrackerX11 *self,
+																		XfdashboardWindowTrackerWorkspace *inOldWorkspace,
+																		gpointer inUserData)
+{
+	XfdashboardWindowTrackerWindowX11		*window;
+	XfdashboardWindowTrackerWorkspace		*newWorkspace;
+
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER(self));
+	g_return_if_fail(!inOldWorkspace || XFDASHBOARD_IS_WINDOW_TRACKER_WORKSPACE_X11(inOldWorkspace));
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_WINDOW_X11(inUserData));
+
+	window=XFDASHBOARD_WINDOW_TRACKER_WINDOW_X11(inUserData);
+
+	/* Get workspace window resides on. */
+	newWorkspace=xfdashboard_window_tracker_window_get_workspace(XFDASHBOARD_WINDOW_TRACKER_WINDOW(window));
+
+	/* Emit signal */
+	XFDASHBOARD_DEBUG(self, WINDOWS,
+						"Window '%s' moved to workspace %d (%s)",
+						xfdashboard_window_tracker_window_get_name(XFDASHBOARD_WINDOW_TRACKER_WINDOW(window)),
+						newWorkspace ? xfdashboard_window_tracker_workspace_get_number(newWorkspace) : -1,
+						newWorkspace ? xfdashboard_window_tracker_workspace_get_name(newWorkspace) : "<nil>");
+	g_signal_emit_by_name(self, "window-workspace-changed", window, newWorkspace);
+}
+
+/* A window was activated */
+static void _xfdashboard_window_tracker_x11_on_active_window_changed(XfdashboardWindowTrackerX11 *self,
+																		WnckWindow *inPreviousWindow,
+																		gpointer inUserData)
+{
+	XfdashboardWindowTrackerX11Private		*priv;
+	WnckScreen								*screen;
+	XfdashboardWindowTrackerWindowX11		*oldActiveWindow;
+	XfdashboardWindowTrackerWindowX11		*newActiveWindow;
+	WnckWindow								*activeWindow;
+
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER(self));
+	g_return_if_fail(inPreviousWindow==NULL || WNCK_IS_WINDOW(inPreviousWindow));
+	g_return_if_fail(WNCK_IS_SCREEN(inUserData));
+
+	priv=self->priv;
+	screen=WNCK_SCREEN(inUserData);
+
+	/* Get and remember new active window */
+	oldActiveWindow=priv->activeWindow;
+
+	newActiveWindow=NULL;
+	activeWindow=wnck_screen_get_active_window(screen);
+	if(activeWindow)
+	{
+		newActiveWindow=_xfdashboard_window_tracker_x11_get_window_for_wnck(self, activeWindow);
+		if(!newActiveWindow)
+		{
+			XFDASHBOARD_DEBUG(self, WINDOWS,
+						"No window object of type %s found for new active wnck window %s@%p named '%s'",
+						g_type_name(XFDASHBOARD_TYPE_WINDOW_TRACKER_WINDOW_X11),
+						G_OBJECT_TYPE_NAME(activeWindow), activeWindow, wnck_window_get_name(activeWindow));
+
+			return;
+		}
+	}
+
+	priv->activeWindow=newActiveWindow;
+
+	/* Emit signal */
+	XFDASHBOARD_DEBUG(self, WINDOWS,
+						"Active window changed from '%s' to '%s'",
+						oldActiveWindow ? xfdashboard_window_tracker_window_get_name(XFDASHBOARD_WINDOW_TRACKER_WINDOW(oldActiveWindow)) : "<nil>",
+						newActiveWindow ? xfdashboard_window_tracker_window_get_name(XFDASHBOARD_WINDOW_TRACKER_WINDOW(newActiveWindow)) : "<nil>");
+	g_signal_emit_by_name(self, "active-window-changed", oldActiveWindow, priv->activeWindow);
+}
+
+/* A window was closed */
+static void _xfdashboard_window_tracker_x11_on_window_closed(XfdashboardWindowTrackerX11 *self,
+																WnckWindow *inWindow,
+																gpointer inUserData)
+{
+	XfdashboardWindowTrackerX11Private		*priv;
+	XfdashboardWindowTrackerWindowX11		*window;
+
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER(self));
+	g_return_if_fail(WNCK_IS_WINDOW(inWindow));
+	g_return_if_fail(WNCK_IS_SCREEN(inUserData));
+
+	priv=self->priv;
+
+	/* Should not happen but if closed window is the last active known one, then
+	 * reset to NULL
+	 */
+	if(xfdashboard_window_tracker_window_x11_get_window(priv->activeWindow)==inWindow)
+	{
+		priv->activeWindow=NULL;
+	}
+
+	/* Get window object for closed wnck window */
+	window=_xfdashboard_window_tracker_x11_get_window_for_wnck(self, inWindow);
+	if(!window)
+	{
+		XFDASHBOARD_DEBUG(self, WINDOWS,
+					"No window object of type %s found for wnck window %s@%p named '%s'",
+					g_type_name(XFDASHBOARD_TYPE_WINDOW_TRACKER_WINDOW_X11),
+					G_OBJECT_TYPE_NAME(inWindow), inWindow, wnck_window_get_name(inWindow));
+
+		return;
+	}
+
+	/* Remove all signal handlers for closed window */
+	g_signal_handlers_disconnect_by_data(window, self);
+
+	/* Emit signals */
+	XFDASHBOARD_DEBUG(self, WINDOWS,
+						"Window '%s' closed",
+						wnck_window_get_name(inWindow));
+	g_signal_emit_by_name(self, "window-closed", window);
+
+	/* Remove window from window list */
+	_xfdashboard_window_tracker_x11_free_window(self, window);
+}
+
+/* A new window was opened */
+static void _xfdashboard_window_tracker_x11_on_window_opened(XfdashboardWindowTrackerX11 *self,
+																WnckWindow *inWindow,
+																gpointer inUserData)
+{
+	XfdashboardWindowTrackerX11Private		*priv;
+	XfdashboardWindowTrackerWindowX11		*window;
+
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER(self));
+	g_return_if_fail(WNCK_IS_WINDOW(inWindow));
+	g_return_if_fail(WNCK_IS_SCREEN(inUserData));
+
+	priv=self->priv;
+
+	/* Create window object */
+	window=_xfdashboard_window_tracker_x11_create_window_for_wnck(self, inWindow);
+	if(!window) return;
+
+	/* Connect signals on newly opened window */
+	g_signal_connect_swapped(window, "actions-changed", G_CALLBACK(_xfdashboard_window_tracker_x11_on_window_actions_changed), self);
+	g_signal_connect_swapped(window, "state-changed", G_CALLBACK(_xfdashboard_window_tracker_x11_on_window_state_changed), self);
+	g_signal_connect_swapped(window, "icon-changed", G_CALLBACK(_xfdashboard_window_tracker_x11_on_window_icon_changed), self);
+	g_signal_connect_swapped(window, "name-changed", G_CALLBACK(_xfdashboard_window_tracker_x11_on_window_name_changed), self);
+	g_signal_connect_swapped(window, "monitor-changed", G_CALLBACK(_xfdashboard_window_tracker_x11_on_window_monitor_changed), self);
+	g_signal_connect_swapped(window, "workspace-changed", G_CALLBACK(_xfdashboard_window_tracker_x11_on_window_workspace_changed), self);
+	g_signal_connect_swapped(window, "geometry-changed", G_CALLBACK(_xfdashboard_window_tracker_x11_on_window_geometry_changed), self);
+
+	/* Block signal handler for 'geometry-changed' at window if application is suspended */
+	if(priv->isAppSuspended)
+	{
+		g_signal_handlers_block_by_func(window, _xfdashboard_window_tracker_x11_on_window_geometry_changed, self);
+	}
+
+	/* Emit signal */
+	XFDASHBOARD_DEBUG(self, WINDOWS,
+				"Window '%s' created",
+				wnck_window_get_name(inWindow));
+	g_signal_emit_by_name(self, "window-opened", window);
+}
+
+/* Window stacking has changed */
+static void _xfdashboard_window_tracker_x11_on_window_stacking_changed(XfdashboardWindowTrackerX11 *self,
+																		gpointer inUserData)
+{
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER(self));
+
+	/* Emit signal */
+	XFDASHBOARD_DEBUG(self, WINDOWS, "Window stacking has changed");
+	g_signal_emit_by_name(self, "window-stacking-changed");
+}
+
+/* A workspace changed its name */
+static void _xfdashboard_window_tracker_x11_on_workspace_name_changed(XfdashboardWindowTrackerX11 *self,
+																		gpointer inUserData)
+{
+	XfdashboardWindowTrackerWorkspaceX11	*workspace;
+
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER(self));
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_WORKSPACE_X11(inUserData));
+
+	workspace=XFDASHBOARD_WINDOW_TRACKER_WORKSPACE_X11(inUserData);
+
+	/* Emit signal */
+	XFDASHBOARD_DEBUG(self, WINDOWS,
+						"Workspace #%d changed name to '%s'",
+						xfdashboard_window_tracker_workspace_get_number(XFDASHBOARD_WINDOW_TRACKER_WORKSPACE(workspace)),
+						xfdashboard_window_tracker_workspace_get_name(XFDASHBOARD_WINDOW_TRACKER_WORKSPACE(workspace)));
+	g_signal_emit_by_name(self, "workspace-name-changed", workspace);
+
+}
+
+/* A workspace was activated */
+static void _xfdashboard_window_tracker_x11_on_active_workspace_changed(XfdashboardWindowTrackerX11 *self,
+																		WnckWorkspace *inPreviousWorkspace,
+																		gpointer inUserData)
+{
+	XfdashboardWindowTrackerX11Private		*priv;
+	WnckScreen								*screen;
+	XfdashboardWindowTrackerWorkspaceX11	*oldActiveWorkspace;
+	XfdashboardWindowTrackerWorkspaceX11	*newActiveWorkspace;
+	WnckWorkspace							*activeWorkspace;
+
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER(self));
+	g_return_if_fail(inPreviousWorkspace==NULL || WNCK_IS_WORKSPACE(inPreviousWorkspace));
+	g_return_if_fail(WNCK_IS_SCREEN(inUserData));
+
+	priv=self->priv;
+	screen=WNCK_SCREEN(inUserData);
+
+	/* Get and remember new active workspace */
+	oldActiveWorkspace=priv->activeWorkspace;
+
+	newActiveWorkspace=NULL;
+	activeWorkspace=wnck_screen_get_active_workspace(screen);
+	if(activeWorkspace)
+	{
+		newActiveWorkspace=_xfdashboard_window_tracker_x11_get_workspace_for_wnck(self, activeWorkspace);
+		if(!newActiveWorkspace)
+		{
+			XFDASHBOARD_DEBUG(self, WINDOWS,
+						"No workspace object of type %s found for new active wnck workspace %s@%p named '%s'",
+						g_type_name(XFDASHBOARD_TYPE_WINDOW_TRACKER_WORKSPACE_X11),
+						G_OBJECT_TYPE_NAME(activeWorkspace), activeWorkspace, wnck_workspace_get_name(activeWorkspace));
+
+			return;
+		}
+	}
+
+	priv->activeWorkspace=newActiveWorkspace;
+
+	/* Emit signal */
+	XFDASHBOARD_DEBUG(self, WINDOWS,
+						"Active workspace changed from #%d (%s) to #%d (%s)",
+						oldActiveWorkspace ? wnck_workspace_get_number(inPreviousWorkspace) : -1,
+						oldActiveWorkspace ? wnck_workspace_get_name(inPreviousWorkspace) : "<nil>",
+						priv->activeWorkspace ? wnck_workspace_get_number(activeWorkspace) : -1,
+						priv->activeWorkspace ? wnck_workspace_get_name(activeWorkspace) : "<nil>");
+	g_signal_emit_by_name(self, "active-workspace-changed", oldActiveWorkspace, priv->activeWorkspace);
+}
+
+/* A workspace was destroyed */
+static void _xfdashboard_window_tracker_x11_on_workspace_destroyed(XfdashboardWindowTrackerX11 *self,
+																	WnckWorkspace *inWorkspace,
+																	gpointer inUserData)
+{
+	XfdashboardWindowTrackerX11Private		*priv;
+	XfdashboardWindowTrackerWorkspaceX11	*workspace;
+
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER(self));
+	g_return_if_fail(WNCK_IS_WORKSPACE(inWorkspace));
+	g_return_if_fail(WNCK_IS_SCREEN(inUserData));
+
+	priv=self->priv;
+
+	/* Should not happen but if destroyed workspace is the last active known one,
+	 * then reset to NULL
+	 */
+	if(xfdashboard_window_tracker_workspace_x11_get_workspace(priv->activeWorkspace)==inWorkspace)
+	{
+		priv->activeWorkspace=NULL;
+	}
+
+	/* Get workspace object for wnck workspace */
+	workspace=_xfdashboard_window_tracker_x11_get_workspace_for_wnck(self, inWorkspace);
+	if(!workspace)
+	{
+		XFDASHBOARD_DEBUG(self, WINDOWS,
+					"No workspace object of type %s found for wnck workspace %s@%p named '%s'",
+					g_type_name(XFDASHBOARD_TYPE_WINDOW_TRACKER_WINDOW_X11),
+					G_OBJECT_TYPE_NAME(inWorkspace), inWorkspace, wnck_workspace_get_name(inWorkspace));
+
+		return;
+	}
+
+	/* Remove all signal handlers for closed window */
+	g_signal_handlers_disconnect_by_data(workspace, self);
+
+	/* Emit signal */
+	XFDASHBOARD_DEBUG(self, WINDOWS,
+						"Workspace #%d (%s) destroyed",
+						wnck_workspace_get_number(inWorkspace),
+						wnck_workspace_get_name(inWorkspace));
+	g_signal_emit_by_name(self, "workspace-removed", workspace);
+
+	/* Remove workspace from workspace list */
+	_xfdashboard_window_tracker_x11_free_workspace(self, workspace);
+}
+
+/* A new workspace was created */
+static void _xfdashboard_window_tracker_x11_on_workspace_created(XfdashboardWindowTrackerX11 *self,
+																	WnckWorkspace *inWorkspace,
+																	gpointer inUserData)
+{
+	XfdashboardWindowTrackerWorkspaceX11		*workspace;
+
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER(self));
+	g_return_if_fail(WNCK_IS_WORKSPACE(inWorkspace));
+	g_return_if_fail(WNCK_IS_SCREEN(inUserData));
+
+	/* Create workspace object */
+	workspace=_xfdashboard_window_tracker_x11_create_workspace_for_wnck(self, inWorkspace);
+	if(!workspace) return;
+
+	/* Connect signals on newly created workspace */
+	g_signal_connect_swapped(workspace, "name-changed", G_CALLBACK(_xfdashboard_window_tracker_x11_on_workspace_name_changed), self);
+
+	/* Emit signal */
+	XFDASHBOARD_DEBUG(self, WINDOWS,
+						"New workspace #%d (%s) created",
+						wnck_workspace_get_number(inWorkspace),
+						wnck_workspace_get_name(inWorkspace));
+	g_signal_emit_by_name(self, "workspace-added", workspace);
+}
+
+/* Primary monitor has changed */
+static void _xfdashboard_window_tracker_x11_on_primary_monitor_changed(XfdashboardWindowTrackerX11 *self,
+																		gpointer inUserData)
+{
+	XfdashboardWindowTrackerX11Private		*priv;
+	XfdashboardWindowTrackerMonitorX11		*monitor;
+
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER(self));
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_MONITOR_X11(inUserData));
+
+	priv=self->priv;
+	monitor=XFDASHBOARD_WINDOW_TRACKER_MONITOR_X11(inUserData);
+
+	/* If monitor emitting this signal is the (new) primary one
+	 * then update primary monitor value of this instance.
+	 */
+	if(xfdashboard_window_tracker_monitor_is_primary(XFDASHBOARD_WINDOW_TRACKER_MONITOR(monitor)) &&
+		priv->primaryMonitor!=monitor)
+	{
+		XfdashboardWindowTrackerMonitorX11	*oldMonitor;
+
+		/* Remember old monitor for signal emission */
+		oldMonitor=priv->primaryMonitor;
+
+		/* Set value */
+		priv->primaryMonitor=monitor;
+
+		/* Emit signal */
+		g_signal_emit_by_name(self, "primary-monitor-changed", oldMonitor, priv->primaryMonitor);
+
+		/* Notify about property change */
+		g_object_notify_by_pspec(G_OBJECT(self), XfdashboardWindowTrackerX11Properties[PROP_PRIMARY_MONITOR]);
+
+		XFDASHBOARD_DEBUG(self, WINDOWS,
+							"Primary monitor changed from %d to %d",
+							oldMonitor ? xfdashboard_window_tracker_monitor_get_number(XFDASHBOARD_WINDOW_TRACKER_MONITOR(oldMonitor)) : -1,
+							xfdashboard_window_tracker_monitor_get_number(XFDASHBOARD_WINDOW_TRACKER_MONITOR(monitor)));
+	}
+}
+
+/* A monitor has changed its position and/or size */
+static void _xfdashboard_window_tracker_x11_on_monitor_geometry_changed(XfdashboardWindowTrackerX11 *self,
+																		gpointer inUserData)
+{
+	XfdashboardWindowTrackerMonitorX11			*monitor;
+
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER(self));
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_MONITOR_X11(inUserData));
+
+	monitor=XFDASHBOARD_WINDOW_TRACKER_MONITOR_X11(inUserData);
+
+	/* A monitor changed its position and/or size so re-emit the signal */
+	g_signal_emit_by_name(self, "monitor-geometry-changed", monitor);
+}
+
+/* Create a monitor object */
+static XfdashboardWindowTrackerMonitorX11* _xfdashboard_window_tracker_x11_monitor_new(XfdashboardWindowTrackerX11 *self,
+																						guint inMonitorIndex)
+{
+	XfdashboardWindowTrackerX11Private		*priv;
+	XfdashboardWindowTrackerMonitorX11		*monitor;
+
+	g_return_val_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER(self), NULL);
+	g_return_val_if_fail(inMonitorIndex>=g_list_length(self->priv->monitors), NULL);
+
+	priv=self->priv;
+
+	/* Create monitor object */
+	monitor=XFDASHBOARD_WINDOW_TRACKER_MONITOR_X11(g_object_new(XFDASHBOARD_TYPE_WINDOW_TRACKER_MONITOR_X11,
+															"monitor-index", inMonitorIndex,
+															NULL));
+	priv->monitors=g_list_append(priv->monitors, monitor);
+
+	/* Connect signals */
+	g_signal_connect_swapped(monitor,
+								"primary-changed",
+								G_CALLBACK(_xfdashboard_window_tracker_x11_on_primary_monitor_changed),
+								self);
+	g_signal_connect_swapped(monitor,
+								"geometry-changed",
+								G_CALLBACK(_xfdashboard_window_tracker_x11_on_monitor_geometry_changed),
+								self);
+
+	/* Emit signal */
+	g_signal_emit_by_name(self, "monitor-added", monitor);
+	XFDASHBOARD_DEBUG(self, WINDOWS,
+						"Monitor %d added",
+						inMonitorIndex);
+
+	/* If we newly added monitor is the primary one then emit signal. We could not
+	 * have done it yet because the signals were connect to new monitor object
+	 * after its creation.
+	 */
+	if(xfdashboard_window_tracker_monitor_is_primary(XFDASHBOARD_WINDOW_TRACKER_MONITOR(monitor)))
+	{
+		_xfdashboard_window_tracker_x11_on_primary_monitor_changed(self, monitor);
+	}
+
+	/* Return newly created monitor */
+	return(monitor);
+}
+
+/* Free a monitor object */
+static void _xfdashboard_window_tracker_x11_monitor_free(XfdashboardWindowTrackerX11 *self,
+															XfdashboardWindowTrackerMonitorX11 *inMonitor)
+{
+	XfdashboardWindowTrackerX11Private		*priv;
+	GList									*iter;
+
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_X11(self));
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_MONITOR_X11(inMonitor));
+
+	priv=self->priv;
+
+	/* Find monitor to free */
+	iter=g_list_find(priv->monitors,  inMonitor);
+	if(!iter)
+	{
+		g_critical(_("Cannot release unknown monitor %d"),
+					xfdashboard_window_tracker_monitor_get_number(XFDASHBOARD_WINDOW_TRACKER_MONITOR(inMonitor)));
+		return;
+	}
+
+	/* Disconnect signals */
+	g_signal_handlers_disconnect_by_data(inMonitor, self);
+
+	/* Emit signal */
+	g_signal_emit_by_name(self, "monitor-removed", inMonitor);
+	XFDASHBOARD_DEBUG(self, WINDOWS,
+						"Monitor %d removed",
+						xfdashboard_window_tracker_monitor_get_number(XFDASHBOARD_WINDOW_TRACKER_MONITOR(inMonitor)));
+
+	/* Remove monitor object from list */
+	priv->monitors=g_list_delete_link(priv->monitors, iter);
+
+	/* Unref monitor object. Usually this is the last reference released
+	 * and the object will be destroyed.
+	 */
+	g_object_unref(inMonitor);
+}
+
+#ifdef HAVE_XINERAMA
+/* Number of monitors, primary monitor or size of any monitor changed */
+static void _xfdashboard_window_tracker_x11_on_monitors_changed(XfdashboardWindowTrackerX11 *self,
+																gpointer inUserData)
+{
+	XfdashboardWindowTrackerX11Private			*priv;
+	GdkScreen								*screen;
+	gint									currentMonitorCount;
+	gint									newMonitorCount;
+	gint									i;
+	XfdashboardWindowTrackerMonitorX11		*monitor;
+	GList									*iter;
+
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER(self));
+	g_return_if_fail(GDK_IS_SCREEN(inUserData));
+
+	priv=self->priv;
+	screen=GDK_SCREEN(inUserData);
+
+	/* Get current monitor states */
+	currentMonitorCount=g_list_length(priv->monitors);
+
+	/* Get new monitor state */
+	newMonitorCount=gdk_screen_get_n_monitors(screen);
+	if(newMonitorCount!=currentMonitorCount)
+	{
+		XFDASHBOARD_DEBUG(self, WINDOWS,
+							"Number of monitors changed from %d to %d",
+							currentMonitorCount,
+							newMonitorCount);
+	}
+
+	/* There is no need to check if size of any monitor has changed because
+	 * XfdashboardWindowTrackerMonitor instances should also be connected to
+	 * this signal and will raise a signal if their size changed. This instance
+	 * is connected to this "monitor-has-changed-signal' and will re-emit them.
+	 * The same is with primary monitor.
+	 */
+
+	/* If number of monitors has increased create newly added monitors */
+	if(newMonitorCount>currentMonitorCount)
+	{
+		for(i=currentMonitorCount; i<newMonitorCount; i++)
+		{
+			/* Create monitor object */
+			_xfdashboard_window_tracker_x11_monitor_new(self, i);
+		}
+	}
+
+	/* If number of monitors has decreased remove all monitors beyond
+	 * the new number of monitors.
+	 */
+	if(newMonitorCount<currentMonitorCount)
+	{
+		for(i=currentMonitorCount; i>newMonitorCount; i--)
+		{
+			/* Get monitor object */
+			iter=g_list_last(priv->monitors);
+			if(!iter) continue;
+
+			monitor=XFDASHBOARD_WINDOW_TRACKER_MONITOR_X11(iter->data);
+
+			/* Free monitor object */
+			_xfdashboard_window_tracker_x11_monitor_free(self, monitor);
+		}
+	}
+}
+#endif
+
+/* Total size of screen changed */
+static void _xfdashboard_window_tracker_x11_on_screen_size_changed(XfdashboardWindowTrackerX11 *self,
+																gpointer inUserData)
+{
+	GdkScreen		*screen;
+	gint			w, h;
+
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER(self));
+	g_return_if_fail(GDK_IS_SCREEN(inUserData));
+
+	screen=GDK_SCREEN(inUserData);
+
+	/* Get new total size of screen */
+	w=gdk_screen_get_width(screen);
+	h=gdk_screen_get_height(screen);
+
+	/* Emit signal to tell that screen size has changed */
+	XFDASHBOARD_DEBUG(self, WINDOWS,
+						"Screen size changed to %dx%d",
+						w,
+						h);
+	g_signal_emit_by_name(self, "screen-size-changed", w, h);
+}
+
+/* Suspension state of application changed */
+static void _xfdashboard_window_tracker_x11_on_application_suspended_changed(XfdashboardWindowTrackerX11 *self,
+																				GParamSpec *inSpec,
+																				gpointer inUserData)
+{
+	XfdashboardWindowTrackerX11Private		*priv;
+	XfdashboardApplication					*app;
+	GList									*iter;
+	XfdashboardWindowTrackerWindow			*window;
+
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER(self));
+	g_return_if_fail(XFDASHBOARD_IS_APPLICATION(inUserData));
+
+	priv=self->priv;
+	app=XFDASHBOARD_APPLICATION(inUserData);
+
+	/* Get application suspend state */
+	priv->isAppSuspended=xfdashboard_application_is_suspended(app);
+
+	/* Iterate through all windows and connect handler to signal 'geometry-changed'
+	 * if application was resumed or disconnect signal handler if it was suspended.
+	 */
+	for(iter=xfdashboard_window_tracker_get_windows(XFDASHBOARD_WINDOW_TRACKER(self)); iter; iter=g_list_next(iter))
+	{
+		/* Get window */
+		window=XFDASHBOARD_WINDOW_TRACKER_WINDOW(iter->data);
+		if(!window) continue;
+
+		/* If application was suspended disconnect signal handlers ... */
+		if(priv->isAppSuspended)
+		{
+			g_signal_handlers_block_by_func(window, _xfdashboard_window_tracker_x11_on_window_geometry_changed, self);
+		}
+			/* ... otherwise if application was resumed reconnect signals handlers
+			 * and emit 'geometry-changed' signal to reflect latest changes of
+			 * position and size of window.
+			 */
+			else
+			{
+				/* Reconnect signal handler */
+				g_signal_handlers_unblock_by_func(window, _xfdashboard_window_tracker_x11_on_window_geometry_changed, self);
+
+				/* Call signal handler to reflect latest changes */
+				_xfdashboard_window_tracker_x11_on_window_geometry_changed(self, window);
+			}
+	}
+}
+
+
+/* IMPLEMENTATION: Interface XfdashboardWindowTracker */
+
+/* Get list of all windows (if wanted in stack order) */
+static GList* _xfdashboard_window_tracker_x11_window_tracker_get_windows(XfdashboardWindowTracker *inWindowTracker)
+{
+	XfdashboardWindowTrackerX11				*self;
+	XfdashboardWindowTrackerX11Private		*priv;
+
+	g_return_val_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_X11(inWindowTracker), NULL);
+
+	self=XFDASHBOARD_WINDOW_TRACKER_X11(inWindowTracker);
+	priv=self->priv;
+
+	/* Return list of window objects created */
+	return(priv->windows);
+}
+
+/* Get list of all windows in stack order */
+static GList* _xfdashboard_window_tracker_x11_window_tracker_get_windows_stacked(XfdashboardWindowTracker *inWindowTracker)
+{
+	XfdashboardWindowTrackerX11				*self;
+	XfdashboardWindowTrackerX11Private		*priv;
+
+	g_return_val_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_X11(inWindowTracker), NULL);
+
+	self=XFDASHBOARD_WINDOW_TRACKER_X11(inWindowTracker);
+	priv=self->priv;
+
+	/* Return list of window in stack order */
+	// TODO: return(wnck_screen_get_windows_stacked(priv->screen));
+	return(priv->windows);
+}
+
+/* Get active window */
+static XfdashboardWindowTrackerWindow* _xfdashboard_window_tracker_x11_window_tracker_get_active_window(XfdashboardWindowTracker *inWindowTracker)
+{
+	XfdashboardWindowTrackerX11				*self;
+	XfdashboardWindowTrackerX11Private		*priv;
+
+	g_return_val_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_X11(inWindowTracker), NULL);
+
+	self=XFDASHBOARD_WINDOW_TRACKER_X11(inWindowTracker);
+	priv=self->priv;
+
+	return(XFDASHBOARD_WINDOW_TRACKER_WINDOW(priv->activeWindow));
+}
+
+/* Get number of workspaces */
+static gint _xfdashboard_window_tracker_x11_window_tracker_get_workspaces_count(XfdashboardWindowTracker *inWindowTracker)
+{
+	XfdashboardWindowTrackerX11				*self;
+	XfdashboardWindowTrackerX11Private		*priv;
+
+	g_return_val_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_X11(inWindowTracker), 0);
+
+	self=XFDASHBOARD_WINDOW_TRACKER_X11(inWindowTracker);
+	priv=self->priv;
+
+	/* Return number of workspaces */
+	return(wnck_screen_get_workspace_count(priv->screen));
+}
+
+/* Get list of workspaces */
+static GList* _xfdashboard_window_tracker_x11_window_tracker_get_workspaces(XfdashboardWindowTracker *inWindowTracker)
+{
+	XfdashboardWindowTrackerX11				*self;
+	XfdashboardWindowTrackerX11Private		*priv;
+
+	g_return_val_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_X11(inWindowTracker), NULL);
+
+	self=XFDASHBOARD_WINDOW_TRACKER_X11(inWindowTracker);
+	priv=self->priv;
+
+	/* Return list of workspaces */
+	return(priv->workspaces);
+}
+
+/* Get active workspace */
+static XfdashboardWindowTrackerWorkspace* _xfdashboard_window_tracker_x11_window_tracker_get_active_workspace(XfdashboardWindowTracker *inWindowTracker)
+{
+	XfdashboardWindowTrackerX11				*self;
+	XfdashboardWindowTrackerX11Private		*priv;
+
+	g_return_val_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_X11(inWindowTracker), NULL);
+
+	self=XFDASHBOARD_WINDOW_TRACKER_X11(inWindowTracker);
+	priv=self->priv;
+
+	return(XFDASHBOARD_WINDOW_TRACKER_WORKSPACE(priv->activeWorkspace));
+}
+
+/* Get workspace by number */
+static XfdashboardWindowTrackerWorkspace* _xfdashboard_window_tracker_x11_window_tracker_get_workspace_by_number(XfdashboardWindowTracker *inWindowTracker,
+																															gint inNumber)
+{
+	XfdashboardWindowTrackerX11				*self;
+	XfdashboardWindowTrackerX11Private		*priv;
+	WnckWorkspace							*wnckWorkspace;
+	XfdashboardWindowTrackerWorkspaceX11	*workspace;
+
+	g_return_val_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_X11(inWindowTracker), NULL);
+
+	self=XFDASHBOARD_WINDOW_TRACKER_X11(inWindowTracker);
+	priv=self->priv;
+
+	g_return_val_if_fail(inNumber>=0 && inNumber<wnck_screen_get_workspace_count(priv->screen), NULL);
+
+	/* Get wnck workspace by number */
+	wnckWorkspace=wnck_screen_get_workspace(priv->screen, inNumber);
+
+	/* Get workspace object for wnck workspace */
+	workspace=_xfdashboard_window_tracker_x11_get_workspace_for_wnck(self, wnckWorkspace);
+	if(!workspace)
+	{
+		XFDASHBOARD_DEBUG(self, WINDOWS,
+					"No workspace object of type %s found for wnck workspace %s@%p named '%s'",
+					g_type_name(XFDASHBOARD_TYPE_WINDOW_TRACKER_WINDOW_X11),
+					G_OBJECT_TYPE_NAME(wnckWorkspace), wnckWorkspace, wnck_workspace_get_name(wnckWorkspace));
+
+		return(NULL);
+	}
+
+	/* Return workspace object */
+	return(XFDASHBOARD_WINDOW_TRACKER_WORKSPACE(workspace));
+}
+
+/* Determine if multiple monitors are supported */
+static gboolean _xfdashboard_window_tracker_x11_window_tracker_supports_multiple_monitors(XfdashboardWindowTracker *inWindowTracker)
+{
+	XfdashboardWindowTrackerX11				*self;
+	XfdashboardWindowTrackerX11Private		*priv;
+
+	g_return_val_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_X11(inWindowTracker), FALSE);
+
+	self=XFDASHBOARD_WINDOW_TRACKER_X11(inWindowTracker);
+	priv=self->priv;
+
+	return(priv->supportsMultipleMonitors);
+}
+
+/* Get number of monitors */
+static gint _xfdashboard_window_tracker_x11_window_tracker_get_monitors_count(XfdashboardWindowTracker *inWindowTracker)
+{
+	XfdashboardWindowTrackerX11				*self;
+	XfdashboardWindowTrackerX11Private		*priv;
+
+	g_return_val_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_X11(inWindowTracker), 0);
+
+	self=XFDASHBOARD_WINDOW_TRACKER_X11(inWindowTracker);
+	priv=self->priv;
+
+	/* Return number of monitors */
+	return(g_list_length(priv->monitors));
+}
+
+/* Get list of monitors */
+static GList* _xfdashboard_window_tracker_x11_window_tracker_get_monitors(XfdashboardWindowTracker *inWindowTracker)
+{
+	XfdashboardWindowTrackerX11				*self;
+	XfdashboardWindowTrackerX11Private		*priv;
+
+	g_return_val_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_X11(inWindowTracker), NULL);
+
+	self=XFDASHBOARD_WINDOW_TRACKER_X11(inWindowTracker);
+	priv=self->priv;
+
+	/* Return list of workspaces */
+	return(priv->monitors);
+}
+
+/* Get primary monitor */
+static XfdashboardWindowTrackerMonitor* _xfdashboard_window_tracker_x11_window_tracker_get_primary_monitor(XfdashboardWindowTracker *inWindowTracker)
+{
+	XfdashboardWindowTrackerX11				*self;
+	XfdashboardWindowTrackerX11Private		*priv;
+
+	g_return_val_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_X11(inWindowTracker), NULL);
+
+	self=XFDASHBOARD_WINDOW_TRACKER_X11(inWindowTracker);
+	priv=self->priv;
+
+	return(XFDASHBOARD_WINDOW_TRACKER_MONITOR(priv->primaryMonitor));
+}
+
+/* Get monitor by number */
+static XfdashboardWindowTrackerMonitor* _xfdashboard_window_tracker_x11_window_tracker_get_monitor_by_number(XfdashboardWindowTracker *inWindowTracker,
+																														gint inNumber)
+{
+	XfdashboardWindowTrackerX11				*self;
+	XfdashboardWindowTrackerX11Private		*priv;
+
+	g_return_val_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_X11(inWindowTracker), NULL);
+
+	self=XFDASHBOARD_WINDOW_TRACKER_X11(inWindowTracker);
+	priv=self->priv;
+
+	g_return_val_if_fail(inNumber>=0, NULL);
+	g_return_val_if_fail(((guint)inNumber)<g_list_length(priv->monitors), NULL);
+
+	/* Return monitor at index */
+	return(XFDASHBOARD_WINDOW_TRACKER_MONITOR(g_list_nth_data(priv->monitors, inNumber)));
+}
+
+/* Get monitor at requested position */
+static XfdashboardWindowTrackerMonitor* _xfdashboard_window_tracker_x11_window_tracker_get_monitor_by_position(XfdashboardWindowTracker *inWindowTracker,
+																														gint inX,
+																														gint inY)
+{
+	XfdashboardWindowTrackerX11				*self;
+	XfdashboardWindowTrackerX11Private		*priv;
+	GList									*iter;
+	XfdashboardWindowTrackerMonitorX11		*monitor;
+
+	g_return_val_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_X11(inWindowTracker), NULL);
+
+	self=XFDASHBOARD_WINDOW_TRACKER_X11(inWindowTracker);
+	priv=self->priv;
+
+	/* Iterate through monitors and return the one containing the requested position */
+	for(iter=priv->monitors; iter; iter=g_list_next(iter))
+	{
+		/* Get monitor at iterator */
+		monitor=XFDASHBOARD_WINDOW_TRACKER_MONITOR_X11(iter->data);
+		if(!monitor) continue;
+
+		/* Check if this monitor contains the requested position. If it does
+		 * then return it.
+		 */
+		if(xfdashboard_window_tracker_monitor_contains(XFDASHBOARD_WINDOW_TRACKER_MONITOR(monitor), inX, inY))
+		{
+			return(XFDASHBOARD_WINDOW_TRACKER_MONITOR(monitor));
+		}
+	}
+
+	/* If we get here none of the monitors contains the requested position,
+	 * so return NULL here.
+	 */
+	return(NULL);
+}
+
+/* Get size of screen */
+static void _xfdashboard_window_tracker_x11_window_tracker_get_screen_size(XfdashboardWindowTracker *inWindowTracker,
+																					gint *outWidth,
+																					gint *outHeight)
+{
+	XfdashboardWindowTrackerX11				*self;
+	XfdashboardWindowTrackerX11Private		*priv;
+	gint									width, height;
+
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_X11(inWindowTracker));
+
+	self=XFDASHBOARD_WINDOW_TRACKER_X11(inWindowTracker);
+	priv=self->priv;
+
+	/* Get width and height of screen */
+	width=gdk_screen_get_width(priv->gdkScreen);
+	height=gdk_screen_get_height(priv->gdkScreen);
+
+	/* Store result */
+	if(outWidth) *outWidth=width;
+	if(outHeight) *outHeight=height;
+}
+
+/* Get root (desktop) window */
+static XfdashboardWindowTrackerWindow* _xfdashboard_window_tracker_x11_window_tracker_get_root_window(XfdashboardWindowTracker *inWindowTracker)
+{
+	XfdashboardWindowTrackerX11				*self;
+	XfdashboardWindowTrackerX11Private		*priv;
+	gulong									backgroundWindowID;
+	GList									*windows;
+	XfdashboardWindowTrackerWindowX11		*window;
+
+	g_return_val_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_X11(inWindowTracker), NULL);
+
+	self=XFDASHBOARD_WINDOW_TRACKER_X11(inWindowTracker);
+	priv=self->priv;
+
+	/* Find and return root window (the desktop) by known ID */
+	backgroundWindowID=wnck_screen_get_background_pixmap(priv->screen);
+	if(backgroundWindowID)
+	{
+		WnckWindow							*backgroundWindow;
+
+		backgroundWindow=wnck_window_get(backgroundWindowID);
+		if(backgroundWindow)
+		{
+			XFDASHBOARD_DEBUG(self, WINDOWS,
+						"Found desktop window %s@%p by known background pixmap ID",
+						G_OBJECT_TYPE_NAME(backgroundWindow), backgroundWindow);
+
+			/* Get or create window object for wnck background window */
+			window=_xfdashboard_window_tracker_x11_create_window_for_wnck(self, backgroundWindow);
+			XFDASHBOARD_DEBUG(self, WINDOWS,
+						"Resolved desktop window %s@%p to window object %s@%p",
+						G_OBJECT_TYPE_NAME(backgroundWindow), backgroundWindow,
+						G_OBJECT_TYPE_NAME(window), window);
+
+			/* Return window object found or created */
+			return(XFDASHBOARD_WINDOW_TRACKER_WINDOW(window));
+		}
+	}
+
+	/* Either there was no known ID for the root window or the root window
+	 * could not be found (happened a lot when running in daemon mode).
+	 * So iterate through list of all known windows and lookup window of
+	 * type 'desktop'.
+	 */
+	for(windows=wnck_screen_get_windows(priv->screen); windows; windows=g_list_next(windows))
+	{
+		WnckWindow					*wnckWindow;
+		WnckWindowType				wnckWindowType;
+
+		wnckWindow=(WnckWindow*)windows->data;
+		wnckWindowType=wnck_window_get_window_type(wnckWindow);
+		if(wnckWindowType==WNCK_WINDOW_DESKTOP)
+		{
+			XFDASHBOARD_DEBUG(self, WINDOWS,
+						"Desktop window %s@%p found while iterating through window list",
+						G_OBJECT_TYPE_NAME(wnckWindow), wnckWindow);
+
+			/* Get or create window object for wnck background window */
+			window=_xfdashboard_window_tracker_x11_create_window_for_wnck(self, wnckWindow);
+			XFDASHBOARD_DEBUG(self, WINDOWS,
+						"Resolved desktop window %s@%p to window object %s@%p",
+						G_OBJECT_TYPE_NAME(wnckWindow), wnckWindow,
+						G_OBJECT_TYPE_NAME(window), window);
+
+			/* Return window object found or created */
+			return(XFDASHBOARD_WINDOW_TRACKER_WINDOW(window));
+		}
+	}
+
+	/* If we get here either desktop window does not exist or is not known
+	 * in window list. So return NULL here.
+	 */
+	XFDASHBOARD_DEBUG(self, WINDOWS, "Desktop window could not be found");
+	return(NULL);
+}
+
+/* Get window of stage */
+static XfdashboardWindowTrackerWindow* _xfdashboard_window_tracker_x11_window_tracker_get_stage_window(XfdashboardWindowTracker *inWindowTracker,
+																										ClutterStage *inStage)
+{
+	XfdashboardWindowTrackerX11				*self;
+	Window									stageXWindow;
+	WnckWindow								*wnckWindow;
+	XfdashboardWindowTrackerWindowX11		*window;
+
+	g_return_val_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_X11(inWindowTracker), NULL);
+	g_return_val_if_fail(CLUTTER_IS_STAGE(inStage), NULL);
+
+	self=XFDASHBOARD_WINDOW_TRACKER_X11(inWindowTracker);
+
+	/* Get stage X window and translate to needed window type */
+	stageXWindow=clutter_x11_get_stage_window(inStage);
+	wnckWindow=wnck_window_get(stageXWindow);
+
+	/* Get or create window object for wnck background window */
+	window=_xfdashboard_window_tracker_x11_create_window_for_wnck(self, wnckWindow);
+	XFDASHBOARD_DEBUG(self, WINDOWS,
+				"Resolved stage window %s@%p to window object %s@%p",
+				G_OBJECT_TYPE_NAME(wnckWindow), wnckWindow,
+				G_OBJECT_TYPE_NAME(window), window);
+
+	return(XFDASHBOARD_WINDOW_TRACKER_WINDOW(window));
+}
+
+/* Interface initialization
+ * Set up default functions
+ */
+static void _xfdashboard_window_tracker_x11_window_tracker_iface_init(XfdashboardWindowTrackerInterface *iface)
+{
+	iface->get_windows=_xfdashboard_window_tracker_x11_window_tracker_get_windows;
+	iface->get_windows_stacked=_xfdashboard_window_tracker_x11_window_tracker_get_windows_stacked;
+	iface->get_active_window=_xfdashboard_window_tracker_x11_window_tracker_get_active_window;
+
+	iface->get_workspaces_count=_xfdashboard_window_tracker_x11_window_tracker_get_workspaces_count;
+	iface->get_workspaces=_xfdashboard_window_tracker_x11_window_tracker_get_workspaces;
+	iface->get_active_workspace=_xfdashboard_window_tracker_x11_window_tracker_get_active_workspace;
+	iface->get_workspace_by_number=_xfdashboard_window_tracker_x11_window_tracker_get_workspace_by_number;
+
+	iface->supports_multiple_monitors=_xfdashboard_window_tracker_x11_window_tracker_supports_multiple_monitors;
+	iface->get_monitors_count=_xfdashboard_window_tracker_x11_window_tracker_get_monitors_count;
+	iface->get_monitors=_xfdashboard_window_tracker_x11_window_tracker_get_monitors;
+	iface->get_primary_monitor=_xfdashboard_window_tracker_x11_window_tracker_get_primary_monitor;
+	iface->get_monitor_by_number=_xfdashboard_window_tracker_x11_window_tracker_get_monitor_by_number;
+	iface->get_monitor_by_position=_xfdashboard_window_tracker_x11_window_tracker_get_monitor_by_position;
+
+	iface->get_screen_size=_xfdashboard_window_tracker_x11_window_tracker_get_screen_size;
+
+	iface->get_root_window=_xfdashboard_window_tracker_x11_window_tracker_get_root_window;
+	iface->get_stage_window=_xfdashboard_window_tracker_x11_window_tracker_get_stage_window;
+}
+
+
+/* IMPLEMENTATION: GObject */
+
+/* Dispose this object */
+static void _xfdashboard_window_tracker_x11_dispose_free_window(gpointer inData,
+																gpointer inUserData)
+{
+	XfdashboardWindowTrackerX11				*self;
+	XfdashboardWindowTrackerWindowX11		*window;
+
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_WINDOW_X11(inData));
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_X11(inUserData));
+
+	self=XFDASHBOARD_WINDOW_TRACKER_X11(inUserData);
+	window=XFDASHBOARD_WINDOW_TRACKER_WINDOW_X11(inData);
+
+	/* Unreference window */
+	_xfdashboard_window_tracker_x11_free_window(self, window);
+}
+
+static void _xfdashboard_window_tracker_x11_dispose_free_workspace(gpointer inData,
+																	gpointer inUserData)
+{
+	XfdashboardWindowTrackerX11				*self;
+	XfdashboardWindowTrackerWorkspaceX11	*workspace;
+
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_WORKSPACE_X11(inData));
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_X11(inUserData));
+
+	self=XFDASHBOARD_WINDOW_TRACKER_X11(inUserData);
+	workspace=XFDASHBOARD_WINDOW_TRACKER_WORKSPACE_X11(inData);
+
+	/* Unreference workspace */
+	_xfdashboard_window_tracker_x11_free_workspace(self, workspace);
+}
+
+static void _xfdashboard_window_tracker_x11_dispose_free_monitor(gpointer inData,
+																	gpointer inUserData)
+{
+	XfdashboardWindowTrackerX11				*self;
+	XfdashboardWindowTrackerMonitorX11		*monitor;
+
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_MONITOR_X11(inData));
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_X11(inUserData));
+
+	self=XFDASHBOARD_WINDOW_TRACKER_X11(inUserData);
+	monitor=XFDASHBOARD_WINDOW_TRACKER_MONITOR_X11(inData);
+
+	/* Unreference monitor */
+	_xfdashboard_window_tracker_x11_monitor_free(self, monitor);
+}
+
+static void _xfdashboard_window_tracker_x11_dispose(GObject *inObject)
+{
+	XfdashboardWindowTrackerX11				*self=XFDASHBOARD_WINDOW_TRACKER_X11(inObject);
+	XfdashboardWindowTrackerX11Private		*priv=self->priv;
+
+	/* Dispose allocated resources */
+	if(priv->suspendSignalID)
+	{
+		g_signal_handler_disconnect(xfdashboard_application_get_default(), priv->suspendSignalID);
+		priv->suspendSignalID=0;
+	}
+
+	if(priv->activeWindow)
+	{
+		priv->activeWindow=NULL;
+	}
+
+	if(priv->windows)
+	{
+		g_list_foreach(priv->windows, _xfdashboard_window_tracker_x11_dispose_free_window, self);
+		g_list_free(priv->windows);
+		priv->windows=NULL;
+	}
+
+	if(priv->activeWorkspace)
+	{
+		priv->activeWorkspace=NULL;
+	}
+
+	if(priv->workspaces)
+	{
+		g_list_foreach(priv->workspaces, _xfdashboard_window_tracker_x11_dispose_free_workspace, self);
+		g_list_free(priv->workspaces);
+		priv->workspaces=NULL;
+	}
+
+	if(priv->primaryMonitor)
+	{
+		priv->primaryMonitor=NULL;
+	}
+
+	if(priv->monitors)
+	{
+		g_list_foreach(priv->monitors, _xfdashboard_window_tracker_x11_dispose_free_monitor, self);
+		g_list_free(priv->monitors);
+		priv->monitors=NULL;
+	}
+
+	if(priv->gdkScreen)
+	{
+		g_signal_handlers_disconnect_by_data(priv->gdkScreen, self);
+		priv->gdkScreen=NULL;
+	}
+
+	if(priv->screen)
+	{
+		g_signal_handlers_disconnect_by_data(priv->screen, self);
+		priv->screen=NULL;
+	}
+
+	/* Call parent's class dispose method */
+	G_OBJECT_CLASS(xfdashboard_window_tracker_x11_parent_class)->dispose(inObject);
+}
+
+/* Set/get properties */
+static void _xfdashboard_window_tracker_x11_set_property(GObject *inObject,
+															guint inPropID,
+															const GValue *inValue,
+															GParamSpec *inSpec)
+{
+	switch(inPropID)
+	{
+		default:
+			G_OBJECT_WARN_INVALID_PROPERTY_ID(inObject, inPropID, inSpec);
+			break;
+	}
+}
+
+static void _xfdashboard_window_tracker_x11_get_property(GObject *inObject,
+															guint inPropID,
+															GValue *outValue,
+															GParamSpec *inSpec)
+{
+	XfdashboardWindowTrackerX11			*self=XFDASHBOARD_WINDOW_TRACKER_X11(inObject);
+
+	switch(inPropID)
+	{
+		case PROP_ACTIVE_WINDOW:
+			g_value_set_object(outValue, self->priv->activeWindow);
+			break;
+
+		case PROP_ACTIVE_WORKSPACE:
+			g_value_set_object(outValue, self->priv->activeWorkspace);
+			break;
+
+		case PROP_PRIMARY_MONITOR:
+			g_value_set_object(outValue, self->priv->primaryMonitor);
+			break;
+
+		default:
+			G_OBJECT_WARN_INVALID_PROPERTY_ID(inObject, inPropID, inSpec);
+			break;
+	}
+}
+
+/* Class initialization
+ * Override functions in parent classes and define properties
+ * and signals
+ */
+void xfdashboard_window_tracker_x11_class_init(XfdashboardWindowTrackerX11Class *klass)
+{
+	GObjectClass						*gobjectClass=G_OBJECT_CLASS(klass);
+	XfdashboardWindowTracker			*trackerIface;
+	GParamSpec							*paramSpec;
+
+	/* Reference interface type to lookup properties etc. */
+	trackerIface=g_type_default_interface_ref(XFDASHBOARD_TYPE_WINDOW_TRACKER);
+
+	/* Override functions */
+	gobjectClass->dispose=_xfdashboard_window_tracker_x11_dispose;
+	gobjectClass->set_property=_xfdashboard_window_tracker_x11_set_property;
+	gobjectClass->get_property=_xfdashboard_window_tracker_x11_get_property;
+
+	/* Set up private structure */
+	g_type_class_add_private(klass, sizeof(XfdashboardWindowTrackerX11Private));
+
+	/* Define properties */
+	paramSpec=g_object_interface_find_property(trackerIface, "active-window");
+	XfdashboardWindowTrackerX11Properties[PROP_ACTIVE_WINDOW]=
+		g_param_spec_override("active-window", paramSpec);
+
+	paramSpec=g_object_interface_find_property(trackerIface, "active-workspace");
+	XfdashboardWindowTrackerX11Properties[PROP_ACTIVE_WORKSPACE]=
+		g_param_spec_override("active-workspace", paramSpec);
+
+	paramSpec=g_object_interface_find_property(trackerIface, "primary-monitor");
+	XfdashboardWindowTrackerX11Properties[PROP_PRIMARY_MONITOR]=
+		g_param_spec_override("primary-monitor", paramSpec);
+
+	g_object_class_install_properties(gobjectClass, PROP_LAST, XfdashboardWindowTrackerX11Properties);
+
+	/* Release allocated resources */
+	g_type_default_interface_unref(trackerIface);
+}
+
+/* Object initialization
+ * Create private structure and set up default values
+ */
+void xfdashboard_window_tracker_x11_init(XfdashboardWindowTrackerX11 *self)
+{
+	XfdashboardWindowTrackerX11Private		*priv;
+	XfdashboardApplication					*app;
+
+	priv=self->priv=XFDASHBOARD_WINDOW_TRACKER_X11_GET_PRIVATE(self);
+
+	XFDASHBOARD_DEBUG(self, WINDOWS, "Initializing window tracker");
+
+	/* Set default values */
+	priv->windows=NULL;
+	priv->workspaces=NULL;
+	priv->monitors=NULL;
+	priv->screen=wnck_screen_get_default();
+	priv->gdkScreen=gdk_screen_get_default();
+	priv->activeWindow=NULL;
+	priv->activeWorkspace=NULL;
+	priv->primaryMonitor=NULL;
+	priv->supportsMultipleMonitors=FALSE;
+
+	/* The very first call to libwnck should be setting the client type */
+	wnck_set_client_type(WNCK_CLIENT_TYPE_PAGER);
+
+	/* Connect signals to screen */
+	g_signal_connect_swapped(priv->screen,
+								"window-stacking-changed",
+								G_CALLBACK(_xfdashboard_window_tracker_x11_on_window_stacking_changed),
+								self);
+
+	g_signal_connect_swapped(priv->screen,
+								"window-closed",
+								G_CALLBACK(_xfdashboard_window_tracker_x11_on_window_closed),
+								self);
+	g_signal_connect_swapped(priv->screen,
+								"window-opened",
+								G_CALLBACK(_xfdashboard_window_tracker_x11_on_window_opened),
+								self);
+	g_signal_connect_swapped(priv->screen,
+								"active-window-changed",
+								G_CALLBACK(_xfdashboard_window_tracker_x11_on_active_window_changed),
+								self);
+
+	g_signal_connect_swapped(priv->screen,
+								"workspace-destroyed",
+								G_CALLBACK(_xfdashboard_window_tracker_x11_on_workspace_destroyed),
+								self);
+	g_signal_connect_swapped(priv->screen,
+								"workspace-created",
+								G_CALLBACK(_xfdashboard_window_tracker_x11_on_workspace_created),
+								self);
+	g_signal_connect_swapped(priv->screen,
+								"active-workspace-changed",
+								G_CALLBACK(_xfdashboard_window_tracker_x11_on_active_workspace_changed),
+								self);
+
+	g_signal_connect_swapped(priv->gdkScreen,
+								"size-changed",
+								G_CALLBACK(_xfdashboard_window_tracker_x11_on_screen_size_changed),
+								self);
+
+#ifdef HAVE_XINERAMA
+	/* Check if multiple monitors are supported */
+	if(XineramaIsActive(GDK_SCREEN_XDISPLAY(priv->gdkScreen)))
+	{
+		XfdashboardWindowTrackerMonitorX11	*monitor;
+		gint								i;
+
+		/* Set flag that multiple monitors are supported */
+		priv->supportsMultipleMonitors=TRUE;
+
+		/* This signal must be called at least after the default signal handler - best at last.
+		 * The reason is that all other signal handler should been processed because this handler
+		 * could destroy monitor instances even the one of the primary monitor if it was not
+		 * handled before. So give the other signal handlers a chance ;)
+		 */
+		g_signal_connect_data(priv->gdkScreen,
+								"monitors-changed",
+								G_CALLBACK(_xfdashboard_window_tracker_x11_on_monitors_changed),
+								self,
+								NULL,
+								G_CONNECT_AFTER | G_CONNECT_SWAPPED);
+
+		/* Get monitors */
+		for(i=0; i<gdk_screen_get_n_monitors(priv->gdkScreen); i++)
+		{
+			/* Create monitor object */
+			monitor=_xfdashboard_window_tracker_x11_monitor_new(self, i);
+
+			/* Remember primary monitor */
+			if(xfdashboard_window_tracker_monitor_is_primary(XFDASHBOARD_WINDOW_TRACKER_MONITOR(monitor)))
+			{
+				priv->primaryMonitor=monitor;
+			}
+		}
+	}
+#endif
+
+	/* Handle suspension signals from application */
+	app=xfdashboard_application_get_default();
+	priv->suspendSignalID=g_signal_connect_swapped(app,
+													"notify::is-suspended",
+													G_CALLBACK(_xfdashboard_window_tracker_x11_on_application_suspended_changed),
+													self);
+	priv->isAppSuspended=xfdashboard_application_is_suspended(app);
+}
+
+
+/* IMPLEMENTATION: Public API */
+
+/* Get last timestamp for use in libwnck */
+guint32 xfdashboard_window_tracker_x11_get_time(void)
+{
+	const ClutterEvent		*currentClutterEvent;
+	guint32					timestamp;
+	GdkDisplay				*display;
+	GdkWindow				*window;
+	GdkEventMask			eventMask;
+	GSList					*stages, *entry;
+	ClutterStage			*stage;
+
+	/* We don't use clutter_get_current_event_time as it can return
+	 * a too old timestamp if there is no current event.
+	 */
+	currentClutterEvent=clutter_get_current_event();
+	if(currentClutterEvent!=NULL) return(clutter_event_get_time(currentClutterEvent));
+
+	/* Next we try timestamp of last GTK+ event */
+	timestamp=gtk_get_current_event_time();
+	if(timestamp>0) return(timestamp);
+
+	/* Next we try to ask GDK for a timestamp */
+	timestamp=gdk_x11_display_get_user_time(gdk_display_get_default());
+	if(timestamp>0) return(timestamp);
+
+	/* Next we try to retrieve timestamp of last X11 event in clutter */
+	XFDASHBOARD_DEBUG(_xfdashboard_window_tracker_singleton, WINDOWS, "No timestamp for windows - trying timestamp of last X11 event in Clutter");
+	timestamp=(guint32)clutter_x11_get_current_event_time();
+	if(timestamp!=0)
+	{
+		XFDASHBOARD_DEBUG(_xfdashboard_window_tracker_singleton, WINDOWS,
+							"Got timestamp %u of last X11 event in Clutter",
+							timestamp);
+		return(timestamp);
+	}
+
+	/* Last resort is to get X11 server time via stage windows */
+	XFDASHBOARD_DEBUG(_xfdashboard_window_tracker_singleton, WINDOWS, "No timestamp for windows - trying last resort via stage windows");
+
+	display=gdk_display_get_default();
+	if(!display)
+	{
+		XFDASHBOARD_DEBUG(_xfdashboard_window_tracker_singleton, WINDOWS, "No default display found in GDK to get timestamp for windows");
+		return(0);
+	}
+
+	/* Iterate through stages, get their GDK window and try to retrieve timestamp */
+	timestamp=0;
+	stages=clutter_stage_manager_list_stages(clutter_stage_manager_get_default());
+	for(entry=stages; timestamp==0 && entry; entry=g_slist_next(entry))
+	{
+		/* Get stage */
+		stage=CLUTTER_STAGE(entry->data);
+		if(stage)
+		{
+			/* Get GDK window of stage */
+			window=gdk_x11_window_lookup_for_display(display, clutter_x11_get_stage_window(stage));
+			if(!window)
+			{
+				XFDASHBOARD_DEBUG(_xfdashboard_window_tracker_singleton, WINDOWS,
+									"No GDK window found for stage %p to get timestamp for windows",
+									stage);
+				continue;
+			}
+
+			/* Check if GDK window supports GDK_PROPERTY_CHANGE_MASK event
+			 * or application (or worst X server) will hang
+			 */
+			eventMask=gdk_window_get_events(window);
+			if(!(eventMask & GDK_PROPERTY_CHANGE_MASK))
+			{
+				XFDASHBOARD_DEBUG(_xfdashboard_window_tracker_singleton, WINDOWS,
+									"GDK window %p for stage %p does not support GDK_PROPERTY_CHANGE_MASK to get timestamp for windows",
+									window,
+									stage);
+				continue;
+			}
+
+			timestamp=gdk_x11_get_server_time(window);
+		}
+	}
+	g_slist_free(stages);
+
+	/* Return timestamp of last resort */
+	XFDASHBOARD_DEBUG(_xfdashboard_window_tracker_singleton, WINDOWS,
+						"Last resort timestamp for windows %s (%u)",
+						timestamp ? "found" : "not found",
+						timestamp);
+	return(timestamp);
+}
+
+/* Find and return XfdashboardWindowTrackerWindow object for mapped wnck window */
+XfdashboardWindowTrackerWindow* xfdashboard_window_tracker_x11_get_window_for_wnck(XfdashboardWindowTrackerX11 *self,
+																					WnckWindow *inWindow)
+{
+	XfdashboardWindowTrackerWindowX11		*window;
+
+	g_return_val_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_X11(self), NULL);
+	g_return_val_if_fail(WNCK_IS_WINDOW(inWindow), NULL);
+
+	/* Lookup window object for requested wnck window and return it */
+	window=_xfdashboard_window_tracker_x11_get_window_for_wnck(self, inWindow);
+	return(XFDASHBOARD_WINDOW_TRACKER_WINDOW(window));
+}
+
+/* Find and return XfdashboardWindowTrackerWorkspace object for mapped wnck workspace */
+XfdashboardWindowTrackerWorkspace* xfdashboard_window_tracker_x11_get_workspace_for_wnck(XfdashboardWindowTrackerX11 *self,
+																							WnckWorkspace *inWorkspace)
+{
+	XfdashboardWindowTrackerWorkspaceX11	*workspace;
+
+	g_return_val_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_X11(self), NULL);
+	g_return_val_if_fail(WNCK_IS_WORKSPACE(inWorkspace), NULL);
+
+	/* Lookup workspace object for requested wnck workspace and return it */
+	workspace=_xfdashboard_window_tracker_x11_get_workspace_for_wnck(self, inWorkspace);
+	return(XFDASHBOARD_WINDOW_TRACKER_WORKSPACE(workspace));
+}
diff --git a/libxfdashboard/x11/window-tracker-x11.h b/libxfdashboard/x11/window-tracker-x11.h
new file mode 100644
index 0000000..b001438
--- /dev/null
+++ b/libxfdashboard/x11/window-tracker-x11.h
@@ -0,0 +1,90 @@
+/*
+ * window-tracker: Tracks windows, workspaces, monitors and
+ *                 listens for changes. It also bundles libwnck into one
+ *                 class.
+ *                 By wrapping libwnck objects we can use a virtual
+ *                 stable API while the API in libwnck changes within versions.
+ *                 We only need to use #ifdefs in window tracker object
+ *                 and nowhere else in the code.
+ * 
+ * Copyright 2012-2017 Stephan Haller <nomad at froevel.de>
+ * 
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ * 
+ * 
+ */
+
+#ifndef __LIBXFDASHBOARD_WINDOW_TRACKER_X11__
+#define __LIBXFDASHBOARD_WINDOW_TRACKER_X11__
+
+#if !defined(__LIBXFDASHBOARD_H_INSIDE__) && !defined(LIBXFDASHBOARD_COMPILATION)
+#error "Only <libxfdashboard/libxfdashboard.h> can be included directly."
+#endif
+
+#include <glib-object.h>
+
+#include <libxfdashboard/window-tracker-window.h>
+#include <libxfdashboard/window-tracker-workspace.h>
+
+#define WNCK_I_KNOW_THIS_IS_UNSTABLE
+#include <libwnck/libwnck.h>
+
+G_BEGIN_DECLS
+
+#define XFDASHBOARD_TYPE_WINDOW_TRACKER_X11				(xfdashboard_window_tracker_x11_get_type())
+#define XFDASHBOARD_WINDOW_TRACKER_X11(obj)				(G_TYPE_CHECK_INSTANCE_CAST((obj), XFDASHBOARD_TYPE_WINDOW_TRACKER_X11, XfdashboardWindowTrackerX11))
+#define XFDASHBOARD_IS_WINDOW_TRACKER_X11(obj)			(G_TYPE_CHECK_INSTANCE_TYPE((obj), XFDASHBOARD_TYPE_WINDOW_TRACKER_X11))
+#define XFDASHBOARD_WINDOW_TRACKER_X11_CLASS(klass)		(G_TYPE_CHECK_CLASS_CAST((klass), XFDASHBOARD_TYPE_WINDOW_TRACKER_X11, XfdashboardWindowTrackerX11Class))
+#define XFDASHBOARD_IS_WINDOW_TRACKER_X11_CLASS(klass)	(G_TYPE_CHECK_CLASS_TYPE((klass), XFDASHBOARD_TYPE_WINDOW_TRACKER_X11))
+#define XFDASHBOARD_WINDOW_TRACKER_X11_GET_CLASS(obj)	(G_TYPE_INSTANCE_GET_CLASS((obj), XFDASHBOARD_TYPE_WINDOW_TRACKER_X11, XfdashboardWindowTrackerX11Class))
+
+typedef struct _XfdashboardWindowTrackerX11				XfdashboardWindowTrackerX11;
+typedef struct _XfdashboardWindowTrackerX11Class		XfdashboardWindowTrackerX11Class;
+typedef struct _XfdashboardWindowTrackerX11Private		XfdashboardWindowTrackerX11Private;
+
+struct _XfdashboardWindowTrackerX11
+{
+	/*< private >*/
+	/* Parent instance */
+	GObject									parent_instance;
+
+	/* Private structure */
+	XfdashboardWindowTrackerX11Private		*priv;
+};
+
+struct _XfdashboardWindowTrackerX11Class
+{
+	/*< private >*/
+	/* Parent class */
+	GObjectClass							parent_class;
+
+	/*< public >*/
+	/* Virtual functions */
+};
+
+/* Public API */
+GType xfdashboard_window_tracker_x11_get_type(void) G_GNUC_CONST;
+
+guint32 xfdashboard_window_tracker_x11_get_time(void);
+
+XfdashboardWindowTrackerWindow* xfdashboard_window_tracker_x11_get_window_for_wnck(XfdashboardWindowTrackerX11 *self,
+																					WnckWindow *inWindow);
+XfdashboardWindowTrackerWorkspace* xfdashboard_window_tracker_x11_get_workspace_for_wnck(XfdashboardWindowTrackerX11 *self,
+																							WnckWorkspace *inWorkspace);
+
+G_END_DECLS
+
+#endif	/* __LIBXFDASHBOARD_WINDOW_TRACKER_X11__ */

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the Xfce4-commits mailing list