All pastes #581071 Raw Edit

Someone

public text v1 · immutable
·published 2007-06-21 11:10 UTC
rendered paste body
diff -Nur libwnck-2.19.3.1/libwnck/application.c libwnck-2.19.4/libwnck/application.c
--- libwnck-2.19.3.1/libwnck/application.c	2007-06-05 20:25:40.000000000 +0200
+++ libwnck-2.19.4/libwnck/application.c	2007-06-18 21:59:14.000000000 +0200
@@ -1,4 +1,5 @@
 /* application object */
+/* vim: set sw=2 et: */
 
 /*
  * Copyright (C) 2001 Havoc Pennington
@@ -26,6 +27,26 @@
 #include "application.h"
 #include "private.h"
 
+/**
+ * SECTION:application
+ * @short_description: an object representing a group of windows of the same
+ * application.
+ * @see_also: wnck_window_get_application()
+ * @stability: Unstable
+ *
+ * The #WnckApplication is a group of #WnckWindow that are all in the same
+ * application. It can be used to represent windows by applications, group
+ * windows by applications or to manipulate all windows of a particular
+ * application.
+ *
+ * A #WnckApplication is identified by the group leader of the #WnckWindow
+ * belonging to it, and new #WnckWindow are added to a #WnckApplication if and
+ * only if they have the group leader of the #WnckApplication.
+ *
+ * The #WnckApplication objects are always owned by libwnck and must not be
+ * referenced or unreferenced.
+ */
+
 #define FALLBACK_NAME _("Untitled application")
 
 static GHashTable *app_hash = NULL;
@@ -55,6 +76,8 @@
   guint need_emit_icon_changed : 1;
 };
 
+G_DEFINE_TYPE (WnckApplication, wnck_application, G_TYPE_OBJECT);
+
 enum {
   NAME_CHANGED,
   ICON_CHANGED,
@@ -72,40 +95,8 @@
 static void wnck_application_finalize    (GObject        *object);
 
 
-static gpointer parent_class;
 static guint signals[LAST_SIGNAL] = { 0 };
 
-GType
-wnck_application_get_type (void)
-{
-  static GType object_type = 0;
-
-  g_type_init ();
-  
-  if (!object_type)
-    {
-      const GTypeInfo object_info =
-      {
-        sizeof (WnckApplicationClass),
-        (GBaseInitFunc) NULL,
-        (GBaseFinalizeFunc) NULL,
-        (GClassInitFunc) wnck_application_class_init,
-        NULL,           /* class_finalize */
-        NULL,           /* class_data */
-        sizeof (WnckApplication),
-        0,              /* n_preallocs */
-        (GInstanceInitFunc) wnck_application_init,
-        NULL            /* value_table */
-      };
-      
-      object_type = g_type_register_static (G_TYPE_OBJECT,
-                                            "WnckApplication",
-                                            &object_info, 0);
-    }
-  
-  return object_type;
-}
-
 static void
 wnck_application_init (WnckApplication *application)
 {  
@@ -121,10 +112,14 @@
 {
   GObjectClass *object_class = G_OBJECT_CLASS (klass);
   
-  parent_class = g_type_class_peek_parent (klass);
-
   object_class->finalize = wnck_application_finalize;
   
+  /**
+   * WnckApplication::name-changed:
+   * @app: the #WnckApplication which emitted the signal.
+   *
+   * Emitted when the name of @app changes.
+   */
   signals[NAME_CHANGED] =
     g_signal_new ("name_changed",
                   G_OBJECT_CLASS_TYPE (object_class),
@@ -134,6 +129,12 @@
                   g_cclosure_marshal_VOID__VOID,
                   G_TYPE_NONE, 0);
 
+  /**
+   * WnckApplication::icon-changed:
+   * @app: the #WnckApplication which emitted the signal.
+   *
+   * Emitted when the icon of @app changes.
+   */
   signals[ICON_CHANGED] =
     g_signal_new ("icon_changed",
                   G_OBJECT_CLASS_TYPE (object_class),
@@ -163,9 +164,20 @@
   
   g_free (application->priv);
   
-  G_OBJECT_CLASS (parent_class)->finalize (object);
+  G_OBJECT_CLASS (wnck_application_parent_class)->finalize (object);
 }
 
+/**
+ * wnck_application_get:
+ * @xwindow: the X window ID of a group leader.
+ *
+ * Returns the #WnckApplication corresponding to the group leader with @xwindow
+ * as X window ID.
+ *
+ * Return value: the #WnckApplication corresponding to @xwindow, or %NULL if
+ * there no such #WnckApplication could be found. The returned #WnckApplication
+ * is owned by libwnck and must not be referenced or unreferenced.
+ */
 WnckApplication*
 wnck_application_get (gulong xwindow)
 {
@@ -177,11 +189,11 @@
 
 /**
  * wnck_application_get_xid:
- * @app: a #WnckApplication
+ * @app: a #WnckApplication.
  * 
- * Gets the X id of the group leader window for the app.
+ * Returns the X window ID of the group leader window for @app.
  * 
- * Return value: X id for the app
+ * Return value: the X window ID of the group leader window for @app.
  **/
 gulong
 wnck_application_get_xid (WnckApplication *app)
@@ -193,12 +205,13 @@
 
 /**
  * wnck_application_get_windows:
- * @app: a #WnckApplication
+ * @app: a #WnckApplication.
  * 
- * Gets a list of all windows belonging to @app. The list
- * is returned by reference and should not be freed.
+ * Returns the list of #WnckWindow belonging to @app.
  * 
- * Return value: list of #WnckWindow in this app
+ * Return value: the list of #WnckWindow belonging to @app, or %NULL if the
+ * application contains no window. The list should not be modified nor freed,
+ * as it is owned by @app.
  **/
 GList*
 wnck_application_get_windows (WnckApplication *app)
@@ -208,6 +221,14 @@
   return app->priv->windows;
 }
 
+/**
+ * wnck_application_get_n_windows:
+ * @app: a #WnckApplication.
+ * 
+ * Returns the number of #WnckWindow belonging to @app.
+ * 
+ * Return value: the number of #WnckWindow belonging to @app.
+ **/
 int
 wnck_application_get_n_windows (WnckApplication *app)
 {
@@ -218,16 +239,16 @@
 
 /**
  * wnck_application_get_name:
- * @app: a #WnckApplication
+ * @app: a #WnckApplication.
  * 
- * Gets the name of an application, employing various
- * suboptimal heuristics to try to figure it out.
- * Probably GTK should have a function to allow apps to
- * set _NET_WM_NAME on the group leader as the app name,
- * and the WM spec should say that's where the app name
- * goes.
+ * Returns the name of @app. Since there is no way to properly find this name,
+ * various suboptimal heuristics are used to find it. GTK+ should probably have
+ * a function to allow applications to set the _NET_WM_NAME property on the
+ * group leader as the application name, and the <ulink
+ * url="http://standards.freedesktop.org/wm-spec/wm-spec-latest.html">EWMH</ulink>
+ * should say that this is where the application name goes.
  * 
- * Return value: name of the application
+ * Return value: the name of @app, or a fallback name if no name is available.
  **/
 const char*
 wnck_application_get_name (WnckApplication *app)
@@ -244,10 +265,12 @@
  * wnck_application_get_icon_name:
  * @app: a #WnckApplication
  * 
- * Gets the icon name of an application, employing various
- * suboptimal heuristics to try to figure it out.
+ * Returns the icon name of @app (to be used when @app is minimized). Since
+ * there is no way to properly find this name, various suboptimal heuristics
+ * are used to find it.
  * 
- * Return value: name of the application when minimized
+ * Return value: the icon name of @app, or a fallback icon name if no icon name
+ * is available.
  **/
 const char*
 wnck_application_get_icon_name (WnckApplication *app)
@@ -266,12 +289,11 @@
 
 /**
  * wnck_application_get_pid:
- * @app: a #WnckApplication
+ * @app: a #WnckApplication.
  * 
- * Gets the process ID of an application, or 0 if none
- * is available.
+ * Returns the process ID of @app.
  * 
- * Return value: process ID or 0
+ * Return value: the process ID of @app, or 0 if none is available.
  **/
 int
 wnck_application_get_pid (WnckApplication *app)
@@ -344,9 +366,22 @@
     return NULL;
 }
 
+/**
+ * wnck_application_get_icon:
+ * @app: a #WnckApplication.
+ * 
+ * Returns the icon to be used for @app. Since there is no way to
+ * properly find the icon, a suboptimal heuristic is used to find it. If
+ * no icon was found, a fallback icon is used.
+ * 
+ * Return value: the icon for @app. The caller should reference the returned
+ * <classname>GdkPixbuf</classname> if it needs to keep the icon around.
+ **/
 GdkPixbuf*
 wnck_application_get_icon (WnckApplication *app)
 {
+  g_return_val_if_fail (WNCK_IS_APPLICATION (app), NULL);
+
   get_icons (app);
   if (app->priv->need_emit_icon_changed)
     emit_icon_changed (app);
@@ -363,9 +398,23 @@
     }
 }
 
+/**
+ * wnck_application_get_mini_icon:
+ * @app: a #WnckApplication.
+ * 
+ * Returns the mini-icon to be used for @app. Since there is no way to
+ * properly find the mini-icon, a suboptimal heuristic is used to find it. If
+ * no mini-icon was found, a fallback mini-icon is used.
+ * 
+ * Return value: the mini-icon for @app. The caller should reference the
+ * returned <classname>GdkPixbuf</classname> if it needs to keep the mini-icon
+ * around.
+ **/
 GdkPixbuf*
 wnck_application_get_mini_icon (WnckApplication *app)
 {
+  g_return_val_if_fail (WNCK_IS_APPLICATION (app), NULL);
+
   get_icons (app);
   if (app->priv->need_emit_icon_changed)
     emit_icon_changed (app);
@@ -386,10 +435,10 @@
  * wnck_application_get_icon_is_fallback:
  * @app: a #WnckApplication
  *
- * Checks if we are using a default fallback icon because
- * none was set on the application.
+ * Returns whether a default fallback icon is used for @app (because none
+ * was set on @app).
  * 
- * Return value: %TRUE if icon is a fallback
+ * Return value: %TRUE if the icon for @app is a fallback, %FALSE otherwise.
  **/
 gboolean
 wnck_application_get_icon_is_fallback (WnckApplication *app)
@@ -399,6 +448,17 @@
   return _wnck_icon_cache_get_is_fallback (app->priv->icon_cache);
 }
 
+/**
+ * wnck_application_get_startup_id:
+ * @app: a #WnckApplication.
+ *
+ * Returns the startup sequence ID used for startup notification of @app.
+ *
+ * Return value: the startup sequence ID used for startup notification of @app,
+ * or %NULL if none is available.
+ *
+ * Since: 2.2
+ */
 const char*
 wnck_application_get_startup_id (WnckApplication *app)
 {
diff -Nur libwnck-2.19.3.1/libwnck/application.h libwnck-2.19.4/libwnck/application.h
--- libwnck-2.19.3.1/libwnck/application.h	2007-06-05 20:25:40.000000000 +0200
+++ libwnck-2.19.4/libwnck/application.h	2007-06-18 21:59:14.000000000 +0200
@@ -1,4 +1,5 @@
 /* application object */
+/* vim: set sw=2 et: */
 
 /*
  * Copyright (C) 2001 Havoc Pennington
@@ -38,6 +39,12 @@
 typedef struct _WnckApplicationClass   WnckApplicationClass;
 typedef struct _WnckApplicationPrivate WnckApplicationPrivate;
 
+/**
+ * WnckApplication:
+ *
+ * The #WnckApplication struct contains only private fields and should not be
+ * directly accessed.
+ */
 struct _WnckApplication
 {
   GObject parent_instance;
diff -Nur libwnck-2.19.3.1/libwnck/class-group.c libwnck-2.19.4/libwnck/class-group.c
--- libwnck-2.19.3.1/libwnck/class-group.c	2007-06-05 20:25:40.000000000 +0200
+++ libwnck-2.19.4/libwnck/class-group.c	2007-06-18 21:59:14.000000000 +0200
@@ -1,4 +1,5 @@
 /* class group object */
+/* vim: set sw=2 et: */
 
 /*
  * Copyright (C) 2003 Ximian, Inc.
@@ -25,6 +26,26 @@
 #include "window.h"
 #include "private.h"
 
+/**
+ * SECTION:class-group
+ * @short_description: an object representing a group of windows of the same
+ * class.
+ * @see_also: wnck_window_get_class_group()
+ * @stability: Unstable
+ *
+ * The #WnckClassGroup is a group of #WnckWindow that are all in the same
+ * class. It can be used to represent windows by classes, group windows by
+ * classes or to manipulate all windows of a particular class.
+ *
+ * The class of a window is defined by the WM_CLASS property of this window.
+ * More information about the WM_CLASS property is available in the <ulink
+ * url="http://tronche.com/gui/x/icccm/sec-4.html&num;s-4.1.2.5">WM_CLASS Property</ulink>
+ * section (section 4.1.2.5) of the <ulink
+ * url="http://tronche.com/gui/x/icccm/">ICCCM</ulink>.
+ *
+ * The #WnckClassGroup objects are always owned by libwnck and must not be
+ * referenced or unreferenced.
+ */
 
 /* Private part of the WnckClassGroup structure */
 struct _WnckClassGroupPrivate {
@@ -36,8 +57,7 @@
   GdkPixbuf *mini_icon;
 };
 
-#define ICON_SIZE 32
-#define MINI_ICON_SIZE 16
+G_DEFINE_TYPE (WnckClassGroup, wnck_class_group, G_TYPE_OBJECT);
 
 /* Hash table that maps res_class strings -> WnckClassGroup instances */
 static GHashTable *class_group_hash = NULL;
@@ -56,48 +76,19 @@
 
 static guint signals[LAST_SIGNAL] = { 0 };
 
-static gpointer *parent_class;
-
-
-GType
-wnck_class_group_get_type (void)
-{
-  static GType object_type = 0;
-
-  g_type_init ();
-
-  if (!object_type)
-    {
-      const GTypeInfo object_info =
-      {
-        sizeof (WnckClassGroupClass),
-        (GBaseInitFunc) NULL,
-        (GBaseFinalizeFunc) NULL,
-        (GClassInitFunc) wnck_class_group_class_init,
-        NULL,           /* class_finalize */
-        NULL,           /* class_data */
-        sizeof (WnckClassGroup),
-        0,              /* n_preallocs */
-        (GInstanceInitFunc) wnck_class_group_init,
-      };
-
-      object_type = g_type_register_static (G_TYPE_OBJECT,
-                                            "WnckClassGroup",
-                                            &object_info, 0);
-    }
-
-  return object_type;
-}
-
 static void
 wnck_class_group_class_init (WnckClassGroupClass *class)
 {
   GObjectClass *gobject_class = G_OBJECT_CLASS (class);
 
-  parent_class = g_type_class_peek_parent (class);
-
   gobject_class->finalize = wnck_class_group_finalize;
 
+  /**
+   * WnckClassGroup::name-changed:
+   * @class_group: the #WnckClassGroup which emitted the signal.
+   *
+   * Emitted when the name of @class_group changes.
+   */
   signals[NAME_CHANGED] =
     g_signal_new ("name_changed",
                   G_OBJECT_CLASS_TYPE (gobject_class),
@@ -106,6 +97,12 @@
                   NULL, NULL,
                   g_cclosure_marshal_VOID__VOID,
                   G_TYPE_NONE, 0);
+  /**
+   * WnckClassGroup::icon-changed:
+   * @class_group: the #WnckClassGroup which emitted the signal.
+   *
+   * Emitted when the icon of @class_group changes.
+   */
   signals[ICON_CHANGED] =
     g_signal_new ("icon_changed",
                   G_OBJECT_CLASS_TYPE (gobject_class),
@@ -157,17 +154,21 @@
 
   g_free (priv);
 
-  G_OBJECT_CLASS (parent_class)->finalize (object);
+  G_OBJECT_CLASS (wnck_class_group_parent_class)->finalize (object);
 }
 
 /**
  * wnck_class_group_get:
- * @res_class: Name of the sought resource class.
+ * @res_class: name of the sought resource class.
+ *
+ * Returns the #WnckClassGroup corresponding to @res_class.
  *
- * Gets an existing class group based on its resource class name.
+ * Return value: the #WnckClassGroup corresponding to @res_class, or %NULL if
+ * there is no #WnckClassGroup with the specified @res_class. The returned
+ * #WnckClassGroup is owned by libwnck and must not be referenced or
+ * unreferenced.
  *
- * Return value: An existing #WnckClassGroup, or NULL if there is no groups with
- * the specified @res_class.
+ * Since: 2.2
  **/
 WnckClassGroup *
 wnck_class_group_get (const char *res_class)
@@ -180,13 +181,13 @@
 
 /**
  * _wnck_class_group_create:
- * @res_class: Name of the resource class for the group.
+ * @res_class: name of the resource class for the group.
  *
  * Creates a new WnckClassGroup with the specified resource class name.  If
  * @res_class is #NULL, then windows without a resource class name will get
  * grouped under this class group.
  *
- * Return value: A newly-created #WnckClassGroup, or an existing one that
+ * Return value: a newly-created #WnckClassGroup, or an existing one that
  * matches the @res_class.
  **/
 WnckClassGroup *
@@ -214,7 +215,7 @@
 
 /**
  * _wnck_class_group_destroy:
- * @class_group: A window class group.
+ * @class_group: a #WnckClassGroup.
  *
  * Destroys the specified @class_group.
  **/
@@ -439,8 +440,12 @@
     get_icons_from_windows (class_group, &icon, &mini_icon);
 
   if (!icon || !mini_icon)
-      _wnck_get_fallback_icons (&icon, ICON_SIZE, ICON_SIZE,
-				&mini_icon, MINI_ICON_SIZE, MINI_ICON_SIZE);
+      _wnck_get_fallback_icons (&icon,
+                                DEFAULT_ICON_WIDTH,
+                                DEFAULT_ICON_HEIGHT,
+                                &mini_icon,
+                                DEFAULT_MINI_ICON_WIDTH,
+                                DEFAULT_MINI_ICON_HEIGHT);
 
   g_assert (icon && mini_icon);
 
@@ -458,10 +463,10 @@
 
 /**
  * _wnck_class_group_add_window:
- * @class_group: A window class group.
- * @window: A window.
+ * @class_group: a #WnckClassGroup.
+ * @window: a #WnckWindow.
  *
- * Adds a window to a class group.  You should only do this if the resource
+ * Adds a window to @class_group.  You should only do this if the resource
  * class of the window matches the @class_group<!-- -->'s.
  **/
 void
@@ -489,8 +494,8 @@
 
 /**
  * _wnck_class_group_remove_window:
- * @class_group: A window class group.
- * @window: A window.
+ * @class_group: a #WnckClassGroup.
+ * @window: a #WnckWindow.
  * 
  * Removes a window from the list of windows that are grouped under the
  * specified @class_group.
@@ -516,12 +521,15 @@
 
 /**
  * wnck_class_group_get_windows:
- * @class_group: A window class group.
+ * @class_group: a #WnckClassGroup.
  * 
- * Gets the list of windows that are grouped in a @class_group.
+ * Returns the list of #WnckWindow that are grouped in @class_group.
  * 
- * Return value: A list of windows, or NULL if the group contains no windows.
- * The list should not be freed, as it belongs to the @class_group.
+ * Return value: the list of #WnckWindow grouped in @class_group, or %NULL if
+ * the group contains no window. The list should not be modified nor freed, as
+ * it is owned by @class_group.
+ *
+ * Since: 2.2
  **/
 GList *
 wnck_class_group_get_windows (WnckClassGroup *class_group)
@@ -536,12 +544,14 @@
 
 /**
  * wnck_class_group_get_res_class:
- * @class_group: A window class group.
+ * @class_group: a #WnckClassGroup.
  * 
- * Queries the resource class name for a class group.
+ * Returns the resource class name for @class_group.
  * 
- * Return value: The resource class name of the specified @class_group, or the
- * empty string if the group has no name.  The string should not be freed.
+ * Return value: the resource class name of @class_group, or an
+ * empty string if the group has no resource class name.
+ *
+ * Since: 2.2
  **/
 const char *
 wnck_class_group_get_res_class (WnckClassGroup *class_group)
@@ -556,11 +566,19 @@
 
 /**
  * wnck_class_group_get_name:
- * @class_group: A window class group.
+ * @class_group: a #WnckClassGroup.
  * 
- * Queries the human-readable name for a class group.
+ * Returns an human-readable name for @class_group. Since there is no way to
+ * properly find this name, a suboptimal heuristic is used to find it. The name
+ * is the name of all #WnckApplication for each #WnckWindow in @class_group if
+ * they all have the same name. If all #WnckApplication don't have the same
+ * name, the name is the name of all #WnckWindow in @class_group if they all
+ * have the same name. If all #WnckWindow don't have the same name, the
+ * resource class name is used.
  * 
- * Return value: Name of the class group.
+ * Return value: an human-readable name for @class_group.
+ *
+ * Since: 2.2
  **/
 const char *
 wnck_class_group_get_name (WnckClassGroup *class_group)
@@ -576,11 +594,19 @@
 
 /**
  * wnck_class_group_get_icon:
- * @class_group: A window class group.
- * 
- * Queries the icon to be used for a class group.
+ * @class_group: a #WnckClassGroup.
  * 
- * Return value: The icon to use.
+ * Returns the icon to be used for @class_group. Since there is no way to
+ * properly find the icon, a suboptimal heuristic is used to find it. The icon
+ * is the first icon found by looking at all the #WnckApplication for each
+ * #WnckWindow in @class_group, then at all the #WnckWindow in @class_group. If
+ * no icon was found, a fallback icon is used.
+ * 
+ * Return value: the icon for @class_group. The caller should reference the
+ * returned <classname>GdkPixbuf</classname> if it needs to keep the icon
+ * around.
+ *
+ * Since: 2.2
  **/
 GdkPixbuf *
 wnck_class_group_get_icon (WnckClassGroup *class_group)
@@ -596,11 +622,17 @@
 
 /**
  * wnck_class_group_get_mini_icon:
- * @class_group: A window class group.
- * 
- * Queries the mini-icon to be used for a class group.
+ * @class_group: a #WnckClassGroup.
  * 
- * Return value: The mini-icon to use.
+ * Returns the mini-icon to be used for @class_group. Since there is no way to
+ * properly find the mini-icon, the same suboptimal heuristic as the one for
+ * wnck_class_group_get_icon() is used to find it.
+ * 
+ * Return value: the mini-icon for @class_group. The caller should reference
+ * the returned <classname>GdkPixbuf</classname> if it needs to keep the
+ * mini-icon around.
+ *
+ * Since: 2.2
  **/
 GdkPixbuf *
 wnck_class_group_get_mini_icon (WnckClassGroup *class_group)
diff -Nur libwnck-2.19.3.1/libwnck/class-group.h libwnck-2.19.4/libwnck/class-group.h
--- libwnck-2.19.3.1/libwnck/class-group.h	2007-06-05 20:25:40.000000000 +0200
+++ libwnck-2.19.4/libwnck/class-group.h	2007-06-18 21:59:14.000000000 +0200
@@ -1,4 +1,5 @@
 /* class group object */
+/* vim: set sw=2 et: */
 
 /*
  * Copyright (C) 2003 Ximian, Inc.
@@ -39,6 +40,12 @@
 typedef struct _WnckClassGroupClass   WnckClassGroupClass;
 typedef struct _WnckClassGroupPrivate WnckClassGroupPrivate;
 
+/**
+ * WnckClassGroup:
+ *
+ * The #WnckClassGroup struct contains only private fields and should not be
+ * directly accessed.
+ */
 struct _WnckClassGroup
 {
   GObject parent_instance;
diff -Nur libwnck-2.19.3.1/libwnck/libwnck.h libwnck-2.19.4/libwnck/libwnck.h
--- libwnck-2.19.3.1/libwnck/libwnck.h	2007-06-05 20:25:40.000000000 +0200
+++ libwnck-2.19.4/libwnck/libwnck.h	2007-06-18 21:59:14.000000000 +0200
@@ -1,4 +1,5 @@
 /* libwnck header */
+/* vim: set sw=2 et: */
 
 /*
  * Copyright (C) 2001 Havoc Pennington
@@ -22,17 +23,21 @@
 #ifndef WNCK_LIB_H
 #define WNCK_LIB_H
 
-#include <libwnck/application.h>
-#include <libwnck/screen.h>
-#include <libwnck/util.h>
 #include <libwnck/window.h>
+#include <libwnck/application.h>
+#include <libwnck/class-group.h>
 #include <libwnck/workspace.h>
-#include <libwnck/wnck-enum-types.h>
+#include <libwnck/screen.h>
 
 #include <libwnck/pager.h>
 #include <libwnck/tasklist.h>
 #include <libwnck/selector.h>
 
+#include <libwnck/window-action-menu.h>
+#include <libwnck/util.h>
+
+#include <libwnck/wnck-enum-types.h>
+
 #endif /* WNCK_LIB_H */
 
 
diff -Nur libwnck-2.19.3.1/libwnck/Makefile.am libwnck-2.19.4/libwnck/Makefile.am
--- libwnck-2.19.3.1/libwnck/Makefile.am	2007-06-05 20:25:40.000000000 +0200
+++ libwnck-2.19.4/libwnck/Makefile.am	2007-06-18 21:59:14.000000000 +0200
@@ -59,6 +59,12 @@
 
 $(libwnck_1_la_OBJECTS): inlinepixbufs.h
 
+wnckprop_SOURCES=		\
+	wnckprop.c
+
+wnckprop_LDADD=   \
+	@LIBWNCK_LIBS@ @X_LIBS@ ./$(lib_LTLIBRARIES)
+
 test_wnck_SOURCES=		\
 	test-wnck.c
 
@@ -72,6 +78,7 @@
 	test-pager.c
 
 noinst_PROGRAMS=		\
+	wnckprop		\
 	test-pager		\
 	test-wnck		\
 	test-selector		\
diff -Nur libwnck-2.19.3.1/libwnck/Makefile.in libwnck-2.19.4/libwnck/Makefile.in
--- libwnck-2.19.3.1/libwnck/Makefile.in	2007-06-05 20:29:18.000000000 +0200
+++ libwnck-2.19.4/libwnck/Makefile.in	2007-06-18 22:16:23.000000000 +0200
@@ -39,8 +39,9 @@
 POST_UNINSTALL = :
 build_triplet = @build@
 host_triplet = @host@
-noinst_PROGRAMS = test-pager$(EXEEXT) test-wnck$(EXEEXT) \
-	test-selector$(EXEEXT) test-tasklist$(EXEEXT)
+noinst_PROGRAMS = wnckprop$(EXEEXT) test-pager$(EXEEXT) \
+	test-wnck$(EXEEXT) test-selector$(EXEEXT) \
+	test-tasklist$(EXEEXT)
 subdir = libwnck
 DIST_COMMON = $(libwnckinclude_HEADERS) $(srcdir)/Makefile.am \
 	$(srcdir)/Makefile.in
@@ -85,6 +86,9 @@
 am_test_wnck_OBJECTS = test-wnck.$(OBJEXT)
 test_wnck_OBJECTS = $(am_test_wnck_OBJECTS)
 test_wnck_DEPENDENCIES = libwnck-1.la
+am_wnckprop_OBJECTS = wnckprop.$(OBJEXT)
+wnckprop_OBJECTS = $(am_wnckprop_OBJECTS)
+wnckprop_DEPENDENCIES = ./$(lib_LTLIBRARIES)
 DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
 depcomp = $(SHELL) $(top_srcdir)/depcomp
 am__depfiles_maybe = depfiles
@@ -98,10 +102,10 @@
 	$(AM_LDFLAGS) $(LDFLAGS) -o $@
 SOURCES = $(libwnck_1_la_SOURCES) $(test_pager_SOURCES) \
 	$(test_selector_SOURCES) $(test_tasklist_SOURCES) \
-	$(test_wnck_SOURCES)
+	$(test_wnck_SOURCES) $(wnckprop_SOURCES)
 DIST_SOURCES = $(libwnck_1_la_SOURCES) $(test_pager_SOURCES) \
 	$(test_selector_SOURCES) $(test_tasklist_SOURCES) \
-	$(test_wnck_SOURCES)
+	$(test_wnck_SOURCES) $(wnckprop_SOURCES)
 DATA = $(noinst_DATA)
 libwnckincludeHEADERS_INSTALL = $(INSTALL_HEADER)
 HEADERS = $(libwnckinclude_HEADERS)
@@ -338,6 +342,12 @@
 	xutils.h		\
 	$(wnck_accessibility_files)
 
+wnckprop_SOURCES = \
+	wnckprop.c
+
+wnckprop_LDADD = \
+	@LIBWNCK_LIBS@ @X_LIBS@ ./$(lib_LTLIBRARIES)
+
 test_wnck_SOURCES = \
 	test-wnck.c
 
@@ -469,6 +479,9 @@
 test-wnck$(EXEEXT): $(test_wnck_OBJECTS) $(test_wnck_DEPENDENCIES) 
 	@rm -f test-wnck$(EXEEXT)
 	$(LINK) $(test_wnck_LDFLAGS) $(test_wnck_OBJECTS) $(test_wnck_LDADD) $(LIBS)
+wnckprop$(EXEEXT): $(wnckprop_OBJECTS) $(wnckprop_DEPENDENCIES) 
+	@rm -f wnckprop$(EXEEXT)
+	$(LINK) $(wnckprop_LDFLAGS) $(wnckprop_OBJECTS) $(wnckprop_LDADD) $(LIBS)
 
 mostlyclean-compile:
 	-rm -f *.$(OBJEXT)
@@ -493,6 +506,7 @@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/window.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wnck-enum-types.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wnck-marshal.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wnckprop.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/workspace-accessible-factory.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/workspace-accessible.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/workspace.Plo@am__quote@
diff -Nur libwnck-2.19.3.1/libwnck/pager-accessible.c libwnck-2.19.4/libwnck/pager-accessible.c
--- libwnck-2.19.3.1/libwnck/pager-accessible.c	2007-06-05 20:25:40.000000000 +0200
+++ libwnck-2.19.4/libwnck/pager-accessible.c	2007-06-18 21:59:14.000000000 +0200
@@ -1,3 +1,4 @@
+/* vim: set sw=2 et: */
 /*
  * Copyright 2002 Sun Microsystems Inc.
  *
diff -Nur libwnck-2.19.3.1/libwnck/pager-accessible-factory.c libwnck-2.19.4/libwnck/pager-accessible-factory.c
--- libwnck-2.19.3.1/libwnck/pager-accessible-factory.c	2007-06-05 20:25:40.000000000 +0200
+++ libwnck-2.19.4/libwnck/pager-accessible-factory.c	2007-06-18 21:59:14.000000000 +0200
@@ -1,3 +1,4 @@
+/* vim: set sw=2 et: */
 /*
  * Copyright 2002 Sun Microsystems Inc.
  *
@@ -21,35 +22,12 @@
 #include "pager-accessible-factory.h"
 #include "pager-accessible.h"
 
-static void       wnck_pager_accessible_factory_class_init          (WnckPagerAccessibleFactoryClass *klass);
-static AtkObject* wnck_pager_accessible_factory_create_accessible   (GObject                         *obj);
+G_DEFINE_TYPE (WnckPagerAccessibleFactory,
+               wnck_pager_accessible_factory, ATK_TYPE_OBJECT_FACTORY);
 
-static GType      wnck_pager_accessible_factory_get_accessible_type (void);
-
-GType
-wnck_pager_accessible_factory_get_type (void)
-{
-  static GType type = 0;
+static AtkObject* wnck_pager_accessible_factory_create_accessible (GObject *obj);
 
-  if (!type) 
-    {
-      const GTypeInfo tinfo = 
-        {
-          sizeof (WnckPagerAccessibleFactoryClass),
-          (GBaseInitFunc) NULL, /* base init */
-          (GBaseFinalizeFunc) NULL, /* base finalize */
-          (GClassInitFunc) wnck_pager_accessible_factory_class_init,
-          (GClassFinalizeFunc) NULL, /* class finalize */
-          NULL, /* class data */
-          sizeof (WnckPagerAccessibleFactory),
-          0, /* nb preallocs */
-          (GInstanceInitFunc) NULL, /* instance init */
-          NULL /* value table */
-        };
-      type = g_type_register_static (ATK_TYPE_OBJECT_FACTORY, "WnckPagerAccessibleFactory", &tinfo, 0);
-    }
-  return type;
-}
+static GType      wnck_pager_accessible_factory_get_accessible_type (void);
 
 static void
 wnck_pager_accessible_factory_class_init (WnckPagerAccessibleFactoryClass *klass)
@@ -60,6 +38,11 @@
   class->get_accessible_type = wnck_pager_accessible_factory_get_accessible_type;
 }
 
+static void
+wnck_pager_accessible_factory_init (WnckPagerAccessibleFactory *factory)
+{
+}
+
 AtkObjectFactory*
 wnck_pager_accessible_factory_new (void)
 {
diff -Nur libwnck-2.19.3.1/libwnck/pager-accessible-factory.h libwnck-2.19.4/libwnck/pager-accessible-factory.h
--- libwnck-2.19.3.1/libwnck/pager-accessible-factory.h	2007-06-05 20:25:40.000000000 +0200
+++ libwnck-2.19.4/libwnck/pager-accessible-factory.h	2007-06-18 21:59:14.000000000 +0200
@@ -1,3 +1,4 @@
+/* vim: set sw=2 et: */
 /*
  * Copyright 2002 Sun Microsystems Inc.
  *
diff -Nur libwnck-2.19.3.1/libwnck/pager-accessible.h libwnck-2.19.4/libwnck/pager-accessible.h
--- libwnck-2.19.3.1/libwnck/pager-accessible.h	2007-06-05 20:25:40.000000000 +0200
+++ libwnck-2.19.4/libwnck/pager-accessible.h	2007-06-18 21:59:14.000000000 +0200
@@ -1,3 +1,4 @@
+/* vim: set sw=2 et: */
 /*
  * Copyright 2002 Sun Microsystems Inc.
  *
diff -Nur libwnck-2.19.3.1/libwnck/pager.c libwnck-2.19.4/libwnck/pager.c
--- libwnck-2.19.3.1/libwnck/pager.c	2007-06-05 20:25:40.000000000 +0200
+++ libwnck-2.19.4/libwnck/pager.c	2007-06-18 21:59:14.000000000 +0200
@@ -1,4 +1,5 @@
 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 2 -*- */
+/* vim: set sw=2 et: */
 /* pager object */
 
 /*
@@ -32,6 +33,28 @@
 #include "private.h"
 #include <math.h>
 
+/**
+ * SECTION:pager
+ * @short_description: a pager widget, showing the content of workspaces.
+ * @see_also: #WnckScreen
+ * @stability: Unstable
+ *
+ * A #WnckPager shows a miniature view of the workspaces, representing managed
+ * windows by small rectangles, and allows the user to initiate various window
+ * manager actions by manipulating these representations. The #WnckPager offers
+ * ways to move windows between workspaces and to change the current workspace.
+ *
+ * Alternatively, a #WnckPager can be configured to only show the names of the
+ * workspace instead of their contents.
+ *
+ * The #WnckPager is also responsible for setting the layout of the workspaces.
+ * Since only one application can be responsible for setting the layout on a
+ * screen, the #WnckPager automatically tries to obtain the manager selection
+ * for the screen and only sets the layout if it owns the manager selection.
+ * See wnck_pager_set_orientation() and wnck_pager_set_n_rows() to change the
+ * layout.
+ */
+
 #define N_SCREEN_CONNECTIONS 11
 
 struct _WnckPagerPrivate
@@ -62,6 +85,8 @@
   guint dnd_time; /* time of last event during dnd (for delayed workspace activation) */
 };
 
+G_DEFINE_TYPE (WnckPager, wnck_pager, GTK_TYPE_WIDGET);
+
 enum
 {
   dummy, /* remove this when you add more signals */
@@ -134,13 +159,12 @@
 static void wnck_pager_queue_draw_window (WnckPager	   *pager,
 					  WnckWindow	   *window);
 
-static void wnck_pager_connect_screen    (WnckPager  *pager,
-                                          WnckScreen *screen);
+static void wnck_pager_connect_screen    (WnckPager  *pager);
 static void wnck_pager_connect_window    (WnckPager  *pager,
                                           WnckWindow *window);
 static void wnck_pager_disconnect_screen (WnckPager  *pager);
 
-static void wnck_pager_set_layout_hint   (WnckPager  *pager);
+static gboolean wnck_pager_set_layout_hint (WnckPager  *pager);
 
 static void wnck_pager_clear_drag (WnckPager *pager);
 static void wnck_pager_check_prelight (WnckPager *pager,
@@ -155,39 +179,6 @@
 static AtkObject* wnck_pager_get_accessible (GtkWidget *widget);
 
 
-static gpointer parent_class;
-
-GType
-wnck_pager_get_type (void)
-{
-  static GType object_type = 0;
-
-  g_type_init ();
-  
-  if (!object_type)
-    {
-      const GTypeInfo object_info =
-      {
-        sizeof (WnckPagerClass),
-        (GBaseInitFunc) NULL,
-        (GBaseFinalizeFunc) NULL,
-        (GClassInitFunc) wnck_pager_class_init,
-        NULL,           /* class_finalize */
-        NULL,           /* class_data */
-        sizeof (WnckPager),
-        0,              /* n_preallocs */
-        (GInstanceInitFunc) wnck_pager_init,
-        NULL            /* value_table */
-      };
-      
-      object_type = g_type_register_static (GTK_TYPE_WIDGET,
-                                            "WnckPager",
-                                            &object_info, 0);
-    }
-  
-  return object_type;
-}
-
 static void
 wnck_pager_init (WnckPager *pager)
 {  
@@ -217,8 +208,6 @@
   GObjectClass *object_class = G_OBJECT_CLASS (klass);
   GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
   
-  parent_class = g_type_class_peek_parent (klass);
-  
   object_class->finalize = wnck_pager_finalize;
 
   widget_class->realize = wnck_pager_realize;
@@ -247,8 +236,6 @@
 
   pager = WNCK_PAGER (object);
 
-  wnck_pager_disconnect_screen (pager);
-
   if (pager->priv->bg_cache)
     {
       g_object_unref (G_OBJECT (pager->priv->bg_cache));
@@ -263,7 +250,39 @@
 
   g_free (pager->priv);
   
-  G_OBJECT_CLASS (parent_class)->finalize (object);
+  G_OBJECT_CLASS (wnck_pager_parent_class)->finalize (object);
+}
+
+static void
+_wnck_pager_set_screen (WnckPager *pager)
+{
+  GdkScreen *gdkscreen;
+
+  gdkscreen = gtk_widget_get_screen (GTK_WIDGET (pager));
+  pager->priv->screen = wnck_screen_get (gdk_screen_get_number (gdkscreen));
+
+  if (!wnck_pager_set_layout_hint (pager))
+    {
+      _WnckLayoutOrientation orientation;
+
+      /* we couldn't set the layout on the screen. This means someone else owns
+       * it. Let's at least show the correct layout. */
+      _wnck_screen_get_workspace_layout (pager->priv->screen,
+                                         &orientation,
+                                         &pager->priv->n_rows,
+                                         NULL, NULL);
+
+      /* test in this order to default to horizontal in case there was in issue
+       * when fetching the layout */
+      if (orientation == WNCK_LAYOUT_ORIENTATION_VERTICAL)
+        pager->priv->orientation = GTK_ORIENTATION_VERTICAL;
+      else
+        pager->priv->orientation = GTK_ORIENTATION_HORIZONTAL;
+
+      gtk_widget_queue_resize (GTK_WIDGET (pager));
+    }
+
+  wnck_pager_connect_screen (pager);
 }
 
 static void
@@ -276,6 +295,8 @@
 
   pager = WNCK_PAGER (widget);
 
+  /* do not call the parent class realize since we're doing things a bit
+   * differently here */
   GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
 
   attributes.window_type = GDK_WINDOW_CHILD;
@@ -299,7 +320,11 @@
   widget->style = gtk_style_attach (widget->style, widget->window);
   gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL);
 
-  wnck_pager_set_layout_hint (pager);
+  /* connect to the screen of this pager. In theory, this will already have
+   * been done in wnck_pager_size_request() */
+  if (pager->priv->screen == NULL)
+    _wnck_pager_set_screen (pager);
+  g_assert (pager->priv->screen != NULL);
 }
 
 static void
@@ -315,7 +340,10 @@
   wnck_screen_release_workspace_layout (pager->priv->screen,
                                         pager->priv->layout_manager_token);
   
-  GTK_WIDGET_CLASS (parent_class)->unrealize (widget);
+  wnck_pager_disconnect_screen (pager);
+  pager->priv->screen = NULL;
+
+  GTK_WIDGET_CLASS (wnck_pager_parent_class)->unrealize (widget);
 }
 
 static void
@@ -334,6 +362,11 @@
 
   pager = WNCK_PAGER (widget);
   
+  /* if we're not realized, we don't know about our screen yet */
+  if (pager->priv->screen == NULL)
+    _wnck_pager_set_screen (pager);
+  g_assert (pager->priv->screen != NULL);
+
   n_spaces = wnck_screen_get_workspace_count (pager->priv->screen);
 
   g_assert (pager->priv->n_rows > 0);
@@ -491,7 +524,8 @@
       return;
     }
 
-  GTK_WIDGET_CLASS (parent_class)->size_allocate (widget, allocation);
+  GTK_WIDGET_CLASS (wnck_pager_parent_class)->size_allocate (widget,
+                                                             allocation);
 }
 
 static void
@@ -1430,6 +1464,9 @@
   GtkWidget *widget;
 
   widget = g_object_get_data (G_OBJECT (context), "wnck-drag-source-widget");
+  if (!widget)
+    return;
+
   if (!gtk_icon_size_lookup_for_settings (gtk_widget_get_settings (widget),
 					  GTK_ICON_SIZE_DND, &dnd_w, &dnd_h))
     dnd_w = dnd_h = 32;
@@ -1461,7 +1498,7 @@
   gtk_drag_set_icon_pixmap (context, 
                             gdk_drawable_get_colormap (GDK_DRAWABLE (pixmap)),
 			    pixmap, NULL,
-			    rect.width / 4, 0);
+			    -2, -2);
 
   g_object_unref (pixmap);
 }
@@ -1474,6 +1511,13 @@
                       FALSE, TRUE);
 }
 
+static void
+wnck_drag_source_destroyed (gpointer  contextp,
+                            GObject  *drag_source)
+{
+  g_object_steal_data (G_OBJECT (contextp), "wnck-drag-source-widget");
+}
+
 /* CAREFUL: This function is a bit brittle, because the pointers given may be
  * finalized already */
 static void
@@ -1493,7 +1537,17 @@
 
   if (clean_up_context)
     {
-      g_object_steal_data (G_OBJECT (context), "wnck-drag-source-widget");
+      GtkWidget *drag_source;
+
+      drag_source = g_object_get_data (G_OBJECT (context),
+                                       "wnck-drag-source-widget");
+      if (drag_source)
+        {
+          g_object_steal_data (G_OBJECT (context), "wnck-drag-source-widget");
+          g_object_weak_unref (G_OBJECT (drag_source),
+                               wnck_drag_source_destroyed, context);
+        }
+
       g_object_weak_unref (G_OBJECT (context),
                            wnck_drag_context_destroyed, window);
     }
@@ -1503,7 +1557,8 @@
  * wnck_window_set_as_drag_icon:
  * @window: #WnckWindow to use as drag icon
  * @context: #GdkDragContext to set the icon on
- * @drag_source: #GtkWidget that started the drag
+ * @drag_source: #GtkWidget that started the drag, or one of its parent. This
+ * widget needs to stay alive as long as possible during the drag.
  *
  * Sets the given @window as the drag icon for @context.
  **/
@@ -1522,6 +1577,8 @@
                     G_CALLBACK (wnck_update_drag_icon), context);
 
   g_object_set_data (G_OBJECT (context), "wnck-drag-source-widget", drag_source);
+  g_object_weak_ref (G_OBJECT (drag_source), wnck_drag_source_destroyed, context);
+
   g_object_weak_ref (G_OBJECT (context), wnck_drag_context_destroyed, window);
 
   wnck_update_drag_icon (window, context);
@@ -1643,22 +1700,35 @@
 
   pager = WNCK_PAGER (widget);
   
-  return GTK_WIDGET_CLASS (parent_class)->focus (widget, direction);
+  return GTK_WIDGET_CLASS (wnck_pager_parent_class)->focus (widget, direction);
 }
 
+/**
+ * wnck_pager_set_screen:
+ * @pager: a #WnckPager.
+ * @screen: a #WnckScreen.
+ *
+ * Does nothing.
+ *
+ * Since: 2.2
+ * Deprecated:
+ */
 void
 wnck_pager_set_screen (WnckPager  *pager,
 		       WnckScreen *screen)
 {
-  if (pager->priv->screen == screen)
-    return;
-
-  if (pager->priv->screen)
-    wnck_pager_disconnect_screen (pager);
-
-  wnck_pager_connect_screen (pager, screen);
 }
 
+/**
+ * wnck_pager_new:
+ * @screen: deprecated argument, can be %NULL.
+ *
+ * Creates a new #WnckPager. The #WnckPager will show the #WnckWorkspace of the
+ * #WnckScreen it is on.
+ *
+ * Return value: a newly created #WnckPager.
+ */
+/* TODO: when we break API again, remove the screen from here */
 GtkWidget*
 wnck_pager_new (WnckScreen *screen)
 {
@@ -1666,24 +1736,27 @@
   
   pager = g_object_new (WNCK_TYPE_PAGER, NULL);
 
-  wnck_pager_connect_screen (pager, screen);
-
   return GTK_WIDGET (pager);
 }
 
-static void
+static gboolean
 wnck_pager_set_layout_hint (WnckPager *pager)
 {
   int layout_rows;
   int layout_cols;
 
+  /* if we're not realized, we don't know about our screen yet */
+  if (pager->priv->screen == NULL)
+    _wnck_pager_set_screen (pager);
+  g_assert (pager->priv->screen != NULL);
+
   /* The visual representation of the pager doesn't
    * correspond to the layout of the workspaces
    * here. i.e. the user will not pay any attention
    * to the n_rows setting on this pager.
    */
   if (!pager->priv->show_all_workspaces)
-    return;
+    return FALSE;
 
   if (pager->priv->orientation == GTK_ORIENTATION_HORIZONTAL)
     {
@@ -1701,39 +1774,115 @@
                                           pager->priv->layout_manager_token,
                                           layout_rows,
                                           layout_cols);
+
+  return (pager->priv->layout_manager_token != WNCK_NO_MANAGER_TOKEN);
 }
 
-void
+/**
+ * wnck_pager_set_orientation:
+ * @pager: a #WnckPager.
+ * @orientation: orientation to use for the layout of #WnckWorkspace on the
+ * #WnckScreen @pager is watching.
+ *
+ * Tries to change the orientation of the layout of #WnckWorkspace on the
+ * #WnckScreen @pager is watching. Since no more than one application should
+ * set this property of a #WnckScreen at a time, setting the layout is not
+ * guaranteed to work. 
+ *
+ * If @orientation is %GTK_ORIENTATION_HORIZONTAL, the #WnckWorkspace will be
+ * laid out in rows, with the first #WnckWorkspace in the top left corner.
+ *
+ * If @orientation is %GTK_ORIENTATION_VERTICAL, the #WnckWorkspace will be
+ * laid out in columns, with the first #WnckWorkspace in the top left corner.
+ *
+ * For example, if the layout contains one row, but the orientation of the
+ * layout is vertical, the #WnckPager will display a column of #WnckWorkspace.
+ *
+ * Return value: %TRUE if the layout of #WnckWorkspace has been successfully
+ * changed or did not need to be changed, %FALSE otherwise.
+ */
+gboolean
 wnck_pager_set_orientation (WnckPager     *pager,
                             GtkOrientation orientation)
 {
-  g_return_if_fail (WNCK_IS_PAGER (pager));
+  GtkOrientation old_orientation;
+  gboolean       old_orientation_is_valid;
+
+  g_return_val_if_fail (WNCK_IS_PAGER (pager), FALSE);
 
   if (pager->priv->orientation == orientation)
-    return;
+    return TRUE;
+
+  old_orientation = pager->priv->orientation;
+  old_orientation_is_valid = pager->priv->screen != NULL;
 
   pager->priv->orientation = orientation;
-  gtk_widget_queue_resize (GTK_WIDGET (pager));
 
-  wnck_pager_set_layout_hint (pager);
+  if (wnck_pager_set_layout_hint (pager))
+    {
+      gtk_widget_queue_resize (GTK_WIDGET (pager));
+      return TRUE;
+    }
+  else
+    {
+      if (old_orientation_is_valid)
+        pager->priv->orientation = old_orientation;
+      return FALSE;
+    }
 }
 
-void
+/**
+ * wnck_pager_set_n_rows:
+ * @pager: a #WnckPager.
+ * @n_rows: the number of rows to use for the layout of #WnckWorkspace on the
+ * #WnckScreen @pager is watching.
+ *
+ * Tries to change the number of rows in the layout of #WnckWorkspace on the
+ * #WnckScreen @pager is watching. Since no more than one application should
+ * set this property of a #WnckScreen at a time, setting the layout is not
+ * guaranteed to work. 
+ *
+ * Return value: %TRUE if the layout of #WnckWorkspace has been successfully
+ * changed or did not need to be changed, %FALSE otherwise.
+ */
+gboolean
 wnck_pager_set_n_rows (WnckPager *pager,
 		       int        n_rows)
 {
-  g_return_if_fail (WNCK_IS_PAGER (pager));
-  g_return_if_fail (n_rows > 0);
+  int      old_n_rows;
+  gboolean old_n_rows_is_valid;
+
+  g_return_val_if_fail (WNCK_IS_PAGER (pager), FALSE);
+  g_return_val_if_fail (n_rows > 0, FALSE);
 
   if (pager->priv->n_rows == n_rows)
-    return;
+    return TRUE;
+
+  old_n_rows = pager->priv->n_rows;
+  old_n_rows_is_valid = pager->priv->screen != NULL;
 
   pager->priv->n_rows = n_rows;
-  gtk_widget_queue_resize (GTK_WIDGET (pager));
 
-  wnck_pager_set_layout_hint (pager);
+  if (wnck_pager_set_layout_hint (pager))
+    {
+      gtk_widget_queue_resize (GTK_WIDGET (pager));
+      return TRUE;
+    }
+  else
+    {
+      if (old_n_rows_is_valid)
+        pager->priv->n_rows = old_n_rows;
+      return FALSE;
+    }
 }
 
+/**
+ * wnck_pager_set_display_mode:
+ * @pager: a #WnckPager.
+ * @mode: a display mode.
+ *
+ * Sets the display mode for @pager to @mode.
+ */
 void
 wnck_pager_set_display_mode (WnckPager            *pager,
 			     WnckPagerDisplayMode  mode)
@@ -1747,6 +1896,14 @@
   gtk_widget_queue_resize (GTK_WIDGET (pager));
 }
 
+/**
+ * wnck_pager_set_show_all:
+ * @pager: a #WnckPager.
+ * @show_all_workspaces: whether to display all #WnckWorkspace in @pager.
+ *
+ * Sets @pager to display all #WnckWorkspace or not, according to
+ * @show_all_workspaces.
+ */
 void
 wnck_pager_set_show_all (WnckPager *pager,
 			 gboolean   show_all_workspaces)
@@ -1762,6 +1919,17 @@
   gtk_widget_queue_resize (GTK_WIDGET (pager));
 }
 
+/**
+ * wnck_pager_set_shadow_type:
+ * @pager: a #WnckPager.
+ * @shadow_type: a shadow type.
+ *
+ * Sets the shadow type for @pager to @shadow_type. The main use of this
+ * function is proper integration of #WnckPager in panels with non-system
+ * backgrounds.
+ *
+ * Since: 2.2
+ */
 void
 wnck_pager_set_shadow_type (WnckPager *   pager,
 			    GtkShadowType shadow_type)
@@ -1935,17 +2103,17 @@
 }
 
 static void
-wnck_pager_connect_screen (WnckPager  *pager,
-                           WnckScreen *screen)
+wnck_pager_connect_screen (WnckPager *pager)
 {
   int i;
   guint *c;
   GList *tmp;
+  WnckScreen *screen;
   
-  g_return_if_fail (pager->priv->screen == NULL);
-  
-  pager->priv->screen = screen;
+  g_return_if_fail (pager->priv->screen != NULL);
 
+  screen = pager->priv->screen;
+  
   for (tmp = wnck_screen_get_windows (screen); tmp; tmp = tmp->next)
     {
       wnck_pager_connect_window (pager, WNCK_WINDOW (tmp->data));
@@ -2068,8 +2236,6 @@
       space = wnck_screen_get_workspace (pager->priv->screen, i);
       g_signal_handlers_disconnect_by_func (space, G_CALLBACK (workspace_name_changed_callback), pager);
     }
-
-  pager->priv->screen = NULL;
 }
 
 static void
@@ -2185,7 +2351,7 @@
         }
       first_time = FALSE;
     }
-  return GTK_WIDGET_CLASS (parent_class)->get_accessible (widget);
+  return GTK_WIDGET_CLASS (wnck_pager_parent_class)->get_accessible (widget);
 }
 
 int 
diff -Nur libwnck-2.19.3.1/libwnck/pager.h libwnck-2.19.4/libwnck/pager.h
--- libwnck-2.19.3.1/libwnck/pager.h	2007-06-05 20:25:40.000000000 +0200
+++ libwnck-2.19.4/libwnck/pager.h	2007-06-18 21:59:14.000000000 +0200
@@ -1,4 +1,5 @@
 /* pager object */
+/* vim: set sw=2 et: */
 
 /*
  * Copyright (C) 2001 Havoc Pennington
@@ -38,6 +39,12 @@
 typedef struct _WnckPagerClass   WnckPagerClass;
 typedef struct _WnckPagerPrivate WnckPagerPrivate;
 
+/**
+ * WnckPager:
+ *
+ * The #WnckPager struct contains only private fields and should not be
+ * directly accessed.
+ */
 struct _WnckPager
 {
   GtkContainer parent_instance;
@@ -56,6 +63,15 @@
   void (* pad4) (void);
 };
 
+/**
+ * WnckPagerDisplayMode:
+ * @WNCK_PAGER_DISPLAY_NAME: the #WnckPager will only display the names of the
+ * workspaces.
+ * @WNCK_PAGER_DISPLAY_CONTENT: the #WnckPager will display a representation
+ * for each window in the workspaces.
+ *
+ * Mode defining what a #WnckPager will display.
+ */
 typedef enum {
   WNCK_PAGER_DISPLAY_NAME,
   WNCK_PAGER_DISPLAY_CONTENT
@@ -65,11 +81,9 @@
 
 GtkWidget* wnck_pager_new (WnckScreen *screen);
 
-void wnck_pager_set_screen       (WnckPager            *pager,
-				  WnckScreen           *screen);
-void wnck_pager_set_orientation  (WnckPager            *pager,
-				  GtkOrientation        orientation);
-void wnck_pager_set_n_rows       (WnckPager            *pager,
+gboolean wnck_pager_set_orientation (WnckPager         *pager,
+				     GtkOrientation     orientation);
+gboolean wnck_pager_set_n_rows   (WnckPager            *pager,
 				  int                   n_rows);
 void wnck_pager_set_display_mode (WnckPager            *pager,
 				  WnckPagerDisplayMode  mode);
@@ -78,6 +92,12 @@
 void wnck_pager_set_shadow_type  (WnckPager	       *pager,
 				  GtkShadowType		shadow_type);
 
+
+#ifndef WNCK_DISABLE_DEPRECATED
+void wnck_pager_set_screen       (WnckPager            *pager,
+				  WnckScreen           *screen);
+#endif /* WNCK_DISABLE_DEPRECATED */
+
 G_END_DECLS
 
 #endif /* WNCK_PAGER_H */
diff -Nur libwnck-2.19.3.1/libwnck/private.h libwnck-2.19.4/libwnck/private.h
--- libwnck-2.19.3.1/libwnck/private.h	2007-06-05 20:25:40.000000000 +0200
+++ libwnck-2.19.4/libwnck/private.h	2007-06-18 21:59:14.000000000 +0200
@@ -1,4 +1,5 @@
 /* Private stuff */
+/* vim: set sw=2 et: */
 
 /*
  * Copyright (C) 2001 Havoc Pennington
@@ -103,7 +104,6 @@
 #define WNCK_SCREEN_XSCREEN(screen) (_wnck_screen_get_xscreen (screen))
 
 Screen    *_wnck_screen_get_xscreen    (WnckScreen *screen);
-int        _wnck_screen_get_number     (WnckScreen *screen);
 GdkScreen *_wnck_screen_get_gdk_screen (WnckScreen *screen);
 
 #ifdef HAVE_STARTUP_NOTIFICATION
@@ -126,6 +126,7 @@
 
 void           _make_gtk_label_bold   (GtkLabel *label);
 void           _make_gtk_label_normal (GtkLabel *label);
+void           _wnck_stock_icons_init (void);
 
 
 G_END_DECLS
diff -Nur libwnck-2.19.3.1/libwnck/screen.c libwnck-2.19.4/libwnck/screen.c
--- libwnck-2.19.3.1/libwnck/screen.c	2007-06-05 20:25:40.000000000 +0200
+++ libwnck-2.19.4/libwnck/screen.c	2007-06-18 21:59:14.000000000 +0200
@@ -1,4 +1,5 @@
 /* screen object */
+/* vim: set sw=2 et: */
 
 /*
  * Copyright (C) 2001 Havoc Pennington
@@ -36,6 +37,25 @@
 #include <string.h>
 #include <stdlib.h>
 
+/**
+ * SECTION:screen
+ * @short_description: an object representing a screen.
+ * @see_also: #WnckWindow, #WnckWorkspace
+ * @stability: Unstable
+ *
+ * The #WnckScreen represents a physical screen. A screen may consist of
+ * multiple monitors which are merged to form a large screen area. The
+ * #WnckScreen is at the bottom of the libwnck stack of objects: #WnckWorkspace
+ * objects exist a #WnckScreen and #WnckWindow objects are displayed on a
+ * #WnckWorkspace.
+ *
+ * The #WnckScreen corresponds to the notion of
+ * <classname>GdkScreen</classname> in GDK.
+ *
+ * The #WnckScreen objects are always owned by libwnck and must not be
+ * referenced or unreferenced.
+ */
+
 #define _NET_WM_ORIENTATION_HORZ 0
 #define _NET_WM_ORIENTATION_VERT 1
 
@@ -44,14 +64,6 @@
 #define _NET_WM_BOTTOMRIGHT 2
 #define _NET_WM_BOTTOMLEFT  3
 
-typedef enum
-{
-  SCREEN_TOPLEFT,
-  SCREEN_TOPRIGHT,
-  SCREEN_BOTTOMLEFT,
-  SCREEN_BOTTOMRIGHT
-} ScreenCorner;
-
 static WnckScreen** screens = NULL;
 
 struct _WnckScreenPrivate
@@ -68,10 +80,13 @@
   GList *workspaces;
 
   /* previously_active_window is used in tandem with active_window to
-   * determine return status of meta_window_is_most_recently_actived().
+   * determine return status of wnck_window_is_most_recently_actived().
+   * These are usually shared for all screens, although this is not guaranteed
+   * to be true.
    */
   WnckWindow *active_window;
   WnckWindow *previously_active_window;
+
   WnckWorkspace *active_workspace;
 
   /* Provides the sorting order number for the next window, to make
@@ -80,6 +95,8 @@
   gint window_order;
 
   Pixmap bg_pixmap;
+
+  char *wm_name;
   
   guint update_handler;  
 
@@ -90,7 +107,7 @@
   guint showing_desktop : 1;
   
   guint vertical_workspaces : 1;
-  ScreenCorner starting_corner;
+  _WnckLayoutCorner starting_corner;
   gint rows_of_workspaces;
   gint columns_of_workspaces;  
 
@@ -106,8 +123,11 @@
   guint need_update_workspace_names : 1;
   guint need_update_bg_pixmap : 1;
   guint need_update_showing_desktop : 1;
+  guint need_update_wm : 1;
 };
 
+G_DEFINE_TYPE (WnckScreen, wnck_screen, G_TYPE_OBJECT);
+
 enum {
   ACTIVE_WINDOW_CHANGED,
   ACTIVE_WORKSPACE_CHANGED,
@@ -123,6 +143,7 @@
   BACKGROUND_CHANGED,
   SHOWING_DESKTOP_CHANGED,
   VIEWPORTS_CHANGED,
+  WM_CHANGED,
   LAST_SIGNAL
 };
 
@@ -166,41 +187,10 @@
 static void emit_background_changed       (WnckScreen      *screen);
 static void emit_showing_desktop_changed  (WnckScreen      *screen);
 static void emit_viewports_changed        (WnckScreen      *screen);
+static void emit_wm_changed               (WnckScreen *screen);
 
-static gpointer parent_class;
 static guint signals[LAST_SIGNAL] = { 0 };
 
-GType
-wnck_screen_get_type (void)
-{
-  static GType object_type = 0;
-
-  g_type_init ();
-  
-  if (!object_type)
-    {
-      const GTypeInfo object_info =
-      {
-        sizeof (WnckScreenClass),
-        (GBaseInitFunc) NULL,
-        (GBaseFinalizeFunc) NULL,
-        (GClassInitFunc) wnck_screen_class_init,
-        NULL,           /* class_finalize */
-        NULL,           /* class_data */
-        sizeof (WnckScreen),
-        0,              /* n_preallocs */
-        (GInstanceInitFunc) wnck_screen_init,
-        NULL            /* value_table */
-      };
-      
-      object_type = g_type_register_static (G_TYPE_OBJECT,
-                                            "WnckScreen",
-                                            &object_info, 0);
-    }
-  
-  return object_type;
-}
-
 static void
 wnck_screen_init (WnckScreen *screen)
 {  
@@ -215,10 +205,16 @@
 
   _wnck_init ();
   
-  parent_class = g_type_class_peek_parent (klass);
-  
   object_class->finalize = wnck_screen_finalize;
 
+  /**
+   * WnckScreen::active-window-changed:
+   * @screen: the #WnckScreen which emitted the signal.
+   * @previously_active_window: the previously active #WnckWindow before this
+   * change.
+   *
+   * Emitted when the active window on @screen has changed.
+   */
   signals[ACTIVE_WINDOW_CHANGED] =
     g_signal_new ("active_window_changed",
                   G_OBJECT_CLASS_TYPE (object_class),
@@ -228,6 +224,14 @@
                   g_cclosure_marshal_VOID__OBJECT,
                   G_TYPE_NONE, 1, WNCK_TYPE_WINDOW);
 
+  /**
+   * WnckScreen::active-workspace-changed:
+   * @screen: the #WnckScreen which emitted the signal.
+   * @previously_active_space: the previously active #WnckWorkspace before this
+   * change.
+   *
+   * Emitted when the active workspace on @screen has changed.
+   */
   signals[ACTIVE_WORKSPACE_CHANGED] =
     g_signal_new ("active_workspace_changed",
                   G_OBJECT_CLASS_TYPE (object_class),
@@ -237,6 +241,12 @@
                   g_cclosure_marshal_VOID__OBJECT,
                   G_TYPE_NONE, 1, WNCK_TYPE_WORKSPACE);
   
+  /**
+   * WnckScreen::window-stacking-changed:
+   * @screen: the #WnckScreen which emitted the signal.
+   *
+   * Emitted when the stacking order of #WnckWindow on @screen has changed.
+   */
   signals[WINDOW_STACKING_CHANGED] =
     g_signal_new ("window_stacking_changed",
                   G_OBJECT_CLASS_TYPE (object_class),
@@ -246,6 +256,13 @@
                   g_cclosure_marshal_VOID__VOID,
                   G_TYPE_NONE, 0);
 
+  /**
+   * WnckScreen::window-opened:
+   * @screen: the #WnckScreen which emitted the signal.
+   * @window: the opened #WnckWindow.
+   *
+   * Emitted when a new #WnckWindow is opened on @screen.
+   */
   signals[WINDOW_OPENED] =
     g_signal_new ("window_opened",
                   G_OBJECT_CLASS_TYPE (object_class),
@@ -255,6 +272,13 @@
                   g_cclosure_marshal_VOID__OBJECT,
                   G_TYPE_NONE, 1, WNCK_TYPE_WINDOW);
 
+  /**
+   * WnckScreen::window-closed:
+   * @screen: the #WnckScreen which emitted the signal.
+   * @window: the closed #WnckWindow.
+   *
+   * Emitted when a #WnckWindow is closed on @screen.
+   */
   signals[WINDOW_CLOSED] =
     g_signal_new ("window_closed",
                   G_OBJECT_CLASS_TYPE (object_class),
@@ -264,6 +288,13 @@
                   g_cclosure_marshal_VOID__OBJECT,
                   G_TYPE_NONE, 1, WNCK_TYPE_WINDOW);
   
+  /**
+   * WnckScreen::workspace-created:
+   * @screen: the #WnckScreen which emitted the signal.
+   * @space: the workspace that has been created. 
+   *
+   * Emitted when a #WnckWorkspace is created on @screen.
+   */
   signals[WORKSPACE_CREATED] =
     g_signal_new ("workspace_created",
                   G_OBJECT_CLASS_TYPE (object_class),
@@ -273,6 +304,13 @@
                   g_cclosure_marshal_VOID__OBJECT,
                   G_TYPE_NONE, 1, WNCK_TYPE_WORKSPACE);
   
+  /**
+   * WnckScreen::workspace-destroyed:
+   * @screen: the #WnckScreen which emitted the signal.
+   * @space: the workspace that has been destroyed. 
+   *
+   * Emitted when a #WnckWorkspace is destroyed on @screen.
+   */
   signals[WORKSPACE_DESTROYED] =
     g_signal_new ("workspace_destroyed",
                   G_OBJECT_CLASS_TYPE (object_class),
@@ -282,6 +320,13 @@
                   g_cclosure_marshal_VOID__OBJECT,
                   G_TYPE_NONE, 1, WNCK_TYPE_WORKSPACE);
 
+  /**
+   * WnckScreen::application-opened:
+   * @screen: the #WnckScreen which emitted the signal.
+   * @app: the opened #WnckApplication.
+   *
+   * Emitted when a new #WnckApplication is opened on @screen.
+   */
   signals[APPLICATION_OPENED] =
     g_signal_new ("application_opened",
                   G_OBJECT_CLASS_TYPE (object_class),
@@ -291,6 +336,13 @@
                   g_cclosure_marshal_VOID__OBJECT,
                   G_TYPE_NONE, 1, WNCK_TYPE_APPLICATION);
 
+  /**
+   * WnckScreen::application-closed:
+   * @screen: the #WnckScreen which emitted the signal.
+   * @app: the closed #WnckApplication.
+   *
+   * Emitted when a #WnckApplication is closed on @screen.
+   */
   signals[APPLICATION_CLOSED] =
     g_signal_new ("application_closed",
                   G_OBJECT_CLASS_TYPE (object_class),
@@ -300,6 +352,15 @@
                   g_cclosure_marshal_VOID__OBJECT,
                   G_TYPE_NONE, 1, WNCK_TYPE_APPLICATION);
 
+  /**
+   * WnckScreen::class-group-opened:
+   * @screen: the #WnckScreen which emitted the signal.
+   * @class_group: the opened #WnckClassGroup.
+   *
+   * Emitted when a new #WnckClassGroup is opened on @screen.
+   *
+   * Since: 2.20
+   */
   signals[CLASS_GROUP_OPENED] =
     g_signal_new ("class_group_opened",
                   G_OBJECT_CLASS_TYPE (object_class),
@@ -309,6 +370,15 @@
                   g_cclosure_marshal_VOID__OBJECT,
                   G_TYPE_NONE, 1, WNCK_TYPE_CLASS_GROUP);
 
+  /**
+   * WnckScreen::class-group-closed:
+   * @screen: the #WnckScreen which emitted the signal.
+   * @class_group: the closed #WnckClassGroup.
+   *
+   * Emitted when a #WnckClassGroup is closed on @screen.
+   *
+   * Since: 2.20
+   */
   signals[CLASS_GROUP_CLOSED] =
     g_signal_new ("class_group_closed",
                   G_OBJECT_CLASS_TYPE (object_class),
@@ -318,6 +388,12 @@
                   g_cclosure_marshal_VOID__OBJECT,
                   G_TYPE_NONE, 1, WNCK_TYPE_CLASS_GROUP);
 
+  /**
+   * WnckScreen::background-changed:
+   * @screen: the #WnckScreen which emitted the signal.
+   *
+   * Emitted when the background on the root window of @screen has changed.
+   */
   signals[BACKGROUND_CHANGED] =
     g_signal_new ("background_changed",
                   G_OBJECT_CLASS_TYPE (object_class),
@@ -326,6 +402,15 @@
                   NULL, NULL,
                   g_cclosure_marshal_VOID__VOID,
                   G_TYPE_NONE, 0);
+
+  /**
+   * WnckScreen::showing-desktop-changed:
+   * @screen: the #WnckScreen which emitted the signal.
+   *
+   * Emitted when "showing the desktop" mode of @screen is toggled.
+   *
+   * Since: 2.20
+   */
   signals[SHOWING_DESKTOP_CHANGED] =
     g_signal_new ("showing_desktop_changed",
                   G_OBJECT_CLASS_TYPE (object_class),
@@ -335,6 +420,15 @@
                   g_cclosure_marshal_VOID__VOID,
                   G_TYPE_NONE, 0);
 
+  /**
+   * WnckScreen::viewports-changed:
+   * @screen: the #WnckScreen which emitted the signal.
+   *
+   * Emitted when a viewport position has changed in a #WnckWorkspace of
+   * @screen or when a #WnckWorkspace of @screen gets or loses its viewport.
+   *
+   * Since: 2.20
+   */
     signals[VIEWPORTS_CHANGED] =
     g_signal_new ("viewports_changed",
                   G_OBJECT_CLASS_TYPE (object_class),
@@ -343,12 +437,30 @@
                   NULL, NULL,
                   g_cclosure_marshal_VOID__VOID,
                   G_TYPE_NONE, 0);
+
+  /**
+   * WnckScreen::window-manager-changed:
+   * @screen: the #WnckScreen which emitted the signal.
+   *
+   * Emitted when the window manager on @screen has changed.
+   *
+   * Since: 2.20
+   */
+    signals[WM_CHANGED] =
+    g_signal_new ("window_manager_changed",
+                  G_OBJECT_CLASS_TYPE (object_class),
+                  G_SIGNAL_RUN_LAST,
+                  G_STRUCT_OFFSET (WnckScreenClass, window_manager_changed),
+                  NULL, NULL,
+                  g_cclosure_marshal_VOID__VOID,
+                  G_TYPE_NONE, 0);
 }
 
 static void
 wnck_screen_finalize (GObject *object)
 {
   WnckScreen *screen;
+  gpointer weak_pointer;
 
   screen = WNCK_SCREEN (object);
   
@@ -362,6 +474,20 @@
   g_list_free (screen->priv->stacked_windows);
   g_list_free (screen->priv->workspaces);
 
+  weak_pointer = &screen->priv->active_window;
+  if (screen->priv->active_window != NULL)
+    g_object_remove_weak_pointer (G_OBJECT (screen->priv->active_window),
+                                  weak_pointer);
+  screen->priv->active_window = NULL;
+
+  weak_pointer = &screen->priv->previously_active_window;
+  if (screen->priv->previously_active_window != NULL)
+    g_object_remove_weak_pointer (G_OBJECT (screen->priv->previously_active_window),
+                                  weak_pointer);
+  screen->priv->previously_active_window = NULL;
+
+  g_free (screen->priv->wm_name);
+
   screens[screen->priv->number] = NULL;
 
 #ifdef HAVE_STARTUP_NOTIFICATION
@@ -370,7 +496,7 @@
   
   g_free (screen->priv);
   
-  G_OBJECT_CLASS (parent_class)->finalize (object);
+  G_OBJECT_CLASS (wnck_screen_parent_class)->finalize (object);
 }
 
 #ifdef HAVE_STARTUP_NOTIFICATION
@@ -402,7 +528,7 @@
   screen->priv->rows_of_workspaces = 1;
   screen->priv->columns_of_workspaces = -1;
   screen->priv->vertical_workspaces = FALSE;
-  screen->priv->starting_corner = SCREEN_TOPLEFT;
+  screen->priv->starting_corner = WNCK_LAYOUT_CORNER_TOPLEFT;
 
 #ifdef HAVE_STARTUP_NOTIFICATION
   screen->priv->sn_display = sn_display_new (gdk_display,
@@ -424,18 +550,19 @@
   screen->priv->need_update_workspace_names = TRUE;
   screen->priv->need_update_bg_pixmap = TRUE;
   screen->priv->need_update_showing_desktop = TRUE;
+  screen->priv->need_update_wm = TRUE;
   
   queue_update (screen);
 }
 
 /**
  * wnck_screen_get:
- * @index: screen number, starting from 0, as for Xlib
+ * @index: screen number, starting from 0.
  * 
- * Gets the #WnckScreen for a given screen on the default display.
- * Creates the #WnckScreen if necessary.
+ * Returns the #WnckScreen for a given screen on the default display.
  * 
- * Return value: the #WnckScreen for screen @index
+ * Return value: the #WnckScreen for screen @index. The returned #WnckScreen is
+ * owned by libwnck and must not be referenced or unreferenced.
  **/
 WnckScreen*
 wnck_screen_get (int index)
@@ -471,6 +598,14 @@
     return NULL;
 }
 
+/**
+ * wnck_screen_get_default:
+ * 
+ * Returns the default #WnckScreen on the default display.
+ * 
+ * Return value: the default #WnckScreen. The returned #WnckScreen is
+ * owned by libwnck and must not be referenced or unreferenced.
+ **/
 WnckScreen*
 wnck_screen_get_default (void)
 {
@@ -483,13 +618,17 @@
 
 /**
  * wnck_screen_get_for_root:
- * @root_window_id: an Xlib window ID
+ * @root_window_id: an X window ID.
  * 
- * Gets the #WnckScreen for the root window at @root_window_id, or
- * returns %NULL if no #WnckScreen exists for this root window. Never
- * creates a new #WnckScreen, unlike wnck_screen_get().
+ * Returns the #WnckScreen for the root window at @root_window_id, or
+ * %NULL if no #WnckScreen exists for this root window.
+ *
+ * This function does not work if wnck_screen_get() was not called for the
+ * sought #WnckScreen before, and returns %NULL.
  * 
- * Return value: #WnckScreen or %NULL
+ * Return value: the #WnckScreen for the root window at @root_window_id, or
+ * %NULL. The returned #WnckScreen is owned by libwnck and must not be
+ * referenced or unreferenced.
  **/
 WnckScreen*
 wnck_screen_get_for_root (gulong root_window_id)
@@ -512,20 +651,42 @@
 }
 
 /**
+ * wnck_screen_get_number:
+ * @screen: a #WnckScreen.
+ * 
+ * Returns the index of @screen on the display to which it belongs. The first
+ * #WnckScreen has an index of 0.
+ * 
+ * Return value: the index of @space on @screen, or -1 on errors.
+ *
+ * Since: 2.20
+ **/
+int
+wnck_screen_get_number (WnckScreen *screen)
+{
+  g_return_val_if_fail (WNCK_IS_SCREEN (screen), -1);
+
+  return screen->priv->number;
+}
+
+/**
  * wnck_screen_get_workspace:
- * @screen: a #WnckScreen
- * @workspace: a workspace index
+ * @screen: a #WnckScreen.
+ * @workspace: a workspace index, starting from 0.
  * 
- * Gets the workspace numbered @workspace for screen @screen, or returns %NULL
- * if no such workspace exists.
+ * Returns the #WnckWorkspace numbered @workspace on @screen.
  * 
- * Return value: the workspace, or %NULL
+ * Return value: the #WnckWorkspace numbered @workspace on @screen, or
+ * %NULL if no such workspace exists. The returned #WnckWorkspace is owned by
+ * libwnck and must not be referenced or unreferenced.
  **/
 WnckWorkspace*
 wnck_screen_get_workspace (WnckScreen *screen,
 			   int         workspace)
 {
   GList *list;
+
+  g_return_val_if_fail (WNCK_IS_SCREEN (screen), NULL);
   
   /* We trust this function with property-provided numbers, it
    * must reliably return NULL on bad data
@@ -538,18 +699,33 @@
   return WNCK_WORKSPACE (list->data);
 }
 
+/**
+ * wnck_screen_get_workspace_index:
+ * @screen: a #WnckScreen.
+ * @space: a #WnckWorkspace.
+ * 
+ * Returns the index of @space on @screen. The first #WnckWorkspace has an
+ * index of 0. See also wnck_workspace_get_number().
+ * 
+ * Return value: the index of @space on @screen, or -1 on errors.
+ *
+ * Since: 2.14
+ **/
+/* TODO: when we break API again, kill this function */
 int
 wnck_screen_get_workspace_index (WnckScreen    *screen,
-                                 WnckWorkspace *workspace)
+                                 WnckWorkspace *space)
 {
   GList *tmp;
   int i;
 
+  g_return_val_if_fail (WNCK_IS_SCREEN (screen), -1);
+
   i = 0;
   tmp = screen->priv->workspaces;
   while (tmp != NULL)
     {
-      if (tmp->data == workspace)
+      if (tmp->data == space)
         return i;
 
       ++i;
@@ -561,13 +737,15 @@
 
 /**
  * wnck_screen_get_active_workspace:
- * @screen: a #WnckScreen 
- * 
- * Gets the active workspace. May return %NULL sometimes,
- * if we are in a weird state due to the asynchronous
- * nature of our interaction with the window manager.
+ * @screen: a #WnckScreen.
  * 
- * Return value: active workspace or %NULL
+ * Returns the active #WnckWorkspace on @screen. May return %NULL sometimes,
+ * if libwnck is in a weird state due to the asynchronous nature of the
+ * interaction with the window manager.
+ * 
+ * Return value: the active #WnckWorkspace on @screen, or %NULL. The returned
+ * #WnckWorkspace is owned by libwnck and must not be referenced or
+ * unreferenced.
  **/
 WnckWorkspace*
 wnck_screen_get_active_workspace (WnckScreen *screen)
@@ -577,19 +755,36 @@
   return screen->priv->active_workspace;
 }
 
+/**
+ * wnck_screen_get_workspace_neighbor:
+ * @screen: a #WnckScreen.
+ * @space: a #WnckWorkspace.
+ * @direction: direction in which to search the neighbor.
+ * 
+ * Returns the neighbor #WnckWorkspace of @space in the @direction direction on
+ * @screen.
+ * 
+ * Return value: the neighbor #WnckWorkspace of @space in the @direction
+ * direction on @screen, or %NULL if no such neighbor #WnckWorkspace exists.
+ * The returned #WnckWorkspace is owned by libwnck and must not be referenced
+ * or unreferenced.
+ *
+ * Since: 2.14
+ **/
 WnckWorkspace*
 wnck_screen_get_workspace_neighbor (WnckScreen         *screen,
-                                    WnckWorkspace      *workspace,
+                                    WnckWorkspace      *space,
                                     WnckMotionDirection direction)
 {
   WnckWorkspaceLayout layout;
-  int i, current_space, num_workspaces;
+  int i, space_index;
+
+  g_return_val_if_fail (WNCK_IS_SCREEN (screen), NULL);
 
-  current_space = wnck_screen_get_workspace_index (screen, workspace);
-  num_workspaces = wnck_screen_get_workspace_count (screen);
+  space_index = wnck_screen_get_workspace_index (screen, space);
 
-  wnck_screen_calc_workspace_layout (screen, num_workspaces,
-                                     current_space, &layout);
+  wnck_screen_calc_workspace_layout (screen, -1,
+                                     space_index, &layout);
 
   switch (direction)
     {
@@ -619,7 +814,7 @@
   i = layout.grid[layout.current_row * layout.cols + layout.current_col];
 
   if (i < 0)
-    i = current_space;
+    i = space_index;
 
   wnck_screen_free_workspace_layout (&layout);
   return wnck_screen_get_workspace (screen, i);
@@ -627,13 +822,13 @@
 
 /**
  * wnck_screen_get_active_window:
- * @screen: a #WnckScreen
+ * @screen: a #WnckScreen.
  * 
- * Gets the active window. May return %NULL sometimes,
- * since not all window managers guarantee that a window
- * is always active.
+ * Returns the active #WnckWindow on @screen. May return %NULL sometimes, since
+ * not all window managers guarantee that a window is always active.
  * 
- * Return value: active window or %NULL
+ * Return value: the active #WnckWindow on @screen, or %NULL. The returned
+ * #WnckWindow is owned by libwnck and must not be referenced or unreferenced.
  **/
 WnckWindow*
 wnck_screen_get_active_window (WnckScreen *screen)
@@ -645,13 +840,17 @@
 
 /**
  * wnck_screen_get_previously_active_window:
- * @screen: a #WnckScreen
+ * @screen: a #WnckScreen.
  * 
- * Gets the previously active window. May return %NULL
- * sometimes, since not all window managers guarantee
- * that a window is always active.
- * 
- * Return value: previously active window or %NULL
+ * Returns the previously active #WnckWindow on @screen. May return %NULL
+ * sometimes, since not all window managers guarantee that a window is always
+ * active.
+ * 
+ * Return value: the previously active #WnckWindow on @screen, or %NULL. The
+ * returned #WnckWindow is owned by libwnck and must not be referenced or
+ * unreferenced.
+ *
+ * Since: 2.8
  **/
 WnckWindow*
 wnck_screen_get_previously_active_window (WnckScreen *screen)
@@ -663,15 +862,16 @@
 
 /**
  * wnck_screen_get_windows:
- * @screen: a #WnckScreen
- * 
- * Gets the screen's list of windows. The list is not copied
- * and should not be freed. The list is not in a defined order,
- * but should be "stable" (windows shouldn't reorder themselves in
- * it). (However, the stability of the list is established by
- * the window manager, so don't blame libwnck if it breaks down.)
+ * @screen: a #WnckScreen.
  * 
- * Return value: reference to list of windows
+ * Returns the list of #WnckWindow on #WnckScreen. The list is not in a defined
+ * order, but should be "stable" (windows should not be reordered in it).
+ * However, the stability of the list is established by the window manager, so
+ * don't blame libwnck if it breaks down.
+ * 
+ * Return value: the list of #WnckWindow on @screen, or %NULL if there is no
+ * window on @screen. The list should not be modified nor freed, as it is owned
+ * by @screen.
  **/
 GList*
 wnck_screen_get_windows (WnckScreen *screen)
@@ -683,12 +883,13 @@
 
 /**
  * wnck_screen_get_windows_stacked:
- * @screen: a #WnckScreen
+ * @screen: a #WnckScreen.
  * 
- * Gets the screen's list of windows in bottom-to-top order.
- * The list is not copied and should not be freed.
+ * Returns the list of #WnckWindow on #WnckScreen in bottom-to-top order.
  * 
- * Return value: reference to list of windows in stacking order
+ * Return value: the list of #WnckWindow in stacking order on @screen, or %NULL
+ * if there is no window on @screen. The list should not be modified nor freed,
+ * as it is owned by @screen.
  **/
 GList*
 wnck_screen_get_windows_stacked (WnckScreen *screen)
@@ -700,12 +901,13 @@
 
 /**
  * _wnck_screen_get_gdk_screen:
- * @screen: a #WnckScreen
+ * @screen: a #WnckScreen.
  * 
- * Obtains the #GdkScreen referring to the same screen
- * as @screen.
+ * Returns the <classname>GdkScreen</classname referring to the same screen as
+ * @screen.
  * 
- * Return value: a #GdkScreen
+ * Return value: the <classname>GdkScreen</classname referring to the same
+ * screen as @screen.
  **/
 GdkScreen *
 _wnck_screen_get_gdk_screen (WnckScreen *screen)
@@ -718,13 +920,16 @@
 
 /**
  * wnck_screen_force_update:
- * @screen: a #WnckScreen
- * 
- * Synchronously and immediately update the window list.  This is
- * usually a bad idea for both performance and correctness reasons (to
- * get things right, you need to write model-view code that tracks
- * changes, not get a static list of open windows).
+ * @screen: a #WnckScreen.
  * 
+ * Synchronously and immediately updates the list of #WnckWindow on @screen.
+ * This bypasses the standard update mechanism, where the list of #WnckWindow
+ * is updated in the idle loop.
+ *
+ * This is usually a bad idea for both performance and correctness reasons (to
+ * get things right, you need to write model-view code that tracks changes, not
+ * get a static list of open windows). However, this function can be useful for
+ * small applications that just do something and then exit.
  **/
 void
 wnck_screen_force_update (WnckScreen *screen)
@@ -736,11 +941,11 @@
 
 /**
  * wnck_screen_get_workspace_count:
- * @screen: a #WnckScreen
+ * @screen: a #WnckScreen.
  * 
- * Gets the number of workspaces.
+ * Returns the number of #WnckWorkspace on @screen.
  * 
- * Return value: number of workspaces
+ * Return value: the number of #WnckWorkspace on @screen.
  **/
 int
 wnck_screen_get_workspace_count (WnckScreen *screen)
@@ -752,10 +957,12 @@
 
 /**
  * wnck_screen_change_workspace_count:
- * @screen: a #WnckScreen
- * @count: requested count
+ * @screen: a #WnckScreen.
+ * @count: the number of #WnckWorkspace to request.
  * 
- * Asks the window manager to change the number of workspaces.
+ * Asks the window manager to change the number of #WnckWorkspace on @screen.
+ *
+ * Since: 2.2
  **/
 void
 wnck_screen_change_workspace_count (WnckScreen *screen,
@@ -849,12 +1056,34 @@
       screen->priv->need_update_showing_desktop = TRUE;
       queue_update (screen);
     }
+  else if (xevent->xproperty.atom ==
+           _wnck_atom_get ("_NET_SUPPORTING_WM_CHECK"))
+    {
+      screen->priv->need_update_wm = TRUE;
+      queue_update (screen);
+    }
 }
 
+/**
+ * wnck_screen_calc_workspace_layout:
+ * @screen: a #WnckScreen.
+ * @num_workspaces: the number of #WnckWorkspace on @screen, or -1 to let
+ * wnck_screen_calc_workspace_layout() find this number.
+ * @space_index: the index of a #Workspace.
+ * @layout: return location for the layout of #WnckWorkspace with additional
+ * information.
+ *
+ * Calculates the layout of #WnckWorkspace, with additional information like
+ * the row and column of the #WnckWorkspace with index @space_index.
+ *
+ * Since: 2.12
+ */
+/* TODO: when we break API again, make this function (and WnckWorkspaceLayout)
+ * private. Also remove num_workspaces since we can get it from screen! */
 void
 wnck_screen_calc_workspace_layout (WnckScreen          *screen,
                                    int                  num_workspaces,
-                                   int                  current_space,
+                                   int                  space_index,
                                    WnckWorkspaceLayout *layout)
 {
   int rows, cols;
@@ -863,6 +1092,12 @@
   int i, r, c;
   int current_row, current_col;
 
+  g_return_if_fail (WNCK_IS_SCREEN (screen));
+  g_return_if_fail (layout != NULL);
+
+  if (num_workspaces < 0)
+    num_workspaces = wnck_screen_get_workspace_count (screen);
+
   rows = screen->priv->rows_of_workspaces;
   cols = screen->priv->columns_of_workspaces;
 
@@ -892,7 +1127,7 @@
 
   switch (screen->priv->starting_corner)
     {
-    case SCREEN_TOPLEFT:
+    case WNCK_LAYOUT_CORNER_TOPLEFT:
       if (screen->priv->vertical_workspaces)
         {
           c = 0;
@@ -924,7 +1159,7 @@
             }
         }
       break;
-    case SCREEN_TOPRIGHT:
+    case WNCK_LAYOUT_CORNER_TOPRIGHT:
       if (screen->priv->vertical_workspaces)
         {
           c = cols - 1;
@@ -956,7 +1191,7 @@
             }
         }
       break;
-    case SCREEN_BOTTOMLEFT:
+    case WNCK_LAYOUT_CORNER_BOTTOMLEFT:
       if (screen->priv->vertical_workspaces)
         {
           c = 0;
@@ -988,7 +1223,7 @@
             }
         }
       break;
-    case SCREEN_BOTTOMRIGHT:
+    case WNCK_LAYOUT_CORNER_BOTTOMRIGHT:
       if (screen->priv->vertical_workspaces)
         {
           c = cols - 1;
@@ -1030,7 +1265,7 @@
       c = 0;
       while (c < cols)
         {
-          if (grid[r*cols+c] == current_space)
+          if (grid[r*cols+c] == space_index)
             {
               current_row = r;
               current_col = c;
@@ -1052,12 +1287,67 @@
   layout->current_col = current_col;
 }
 
+/**
+ * wnck_screen_free_workspace_layout:
+ * @layout: a #WnckWorkspaceLayout.
+ *
+ * Frees the content of @layout. This does not free @layout itself, so you
+ * might want to free @layout yourself after calling this.
+ *
+ * Since: 2.12
+ */
+/* TODO: when we break API again, make this function (and WnckWorkspaceLayout)
+ * private. */
 void
 wnck_screen_free_workspace_layout (WnckWorkspaceLayout *layout)
 {
+  g_return_if_fail (layout != NULL);
+
   g_free (layout->grid);
 }
 
+static void
+set_active_window (WnckScreen *screen,
+                   WnckWindow *window)
+{
+  gpointer weak_pointer;
+
+  weak_pointer = &screen->priv->active_window;
+
+  /* we need the weak pointer since the active window might be shared between
+   * two screens, and so the value for one screen might become invalid when
+   * the window is destroyed on another screen */
+  if (screen->priv->active_window != NULL)
+    g_object_remove_weak_pointer (G_OBJECT (screen->priv->active_window),
+                                  weak_pointer);
+
+  screen->priv->active_window = window;
+  if (screen->priv->active_window != NULL)
+    g_object_add_weak_pointer (G_OBJECT (screen->priv->active_window),
+                               weak_pointer);
+}
+
+static void
+set_previously_active_window (WnckScreen *screen,
+                              WnckWindow *window)
+{
+  gpointer weak_pointer;
+
+  weak_pointer = &screen->priv->previously_active_window;
+
+  /* we need the weak pointer since the active window might be shared between
+   * two screens, and so the value for one screen might become invalid when
+   * the window is destroyed on another screen */
+  if (screen->priv->previously_active_window != NULL)
+    g_object_remove_weak_pointer (G_OBJECT (screen->priv->previously_active_window),
+                                  weak_pointer);
+
+  screen->priv->previously_active_window = window;
+  if (screen->priv->previously_active_window != NULL)
+    g_object_add_weak_pointer (G_OBJECT (screen->priv->previously_active_window),
+                               weak_pointer);
+}
+
 static gboolean
 lists_equal (GList *a,
              GList *b)
@@ -1136,11 +1426,11 @@
 update_client_list (WnckScreen *screen)
 {
   /* stacking order */
-  Window *stack = NULL;
-  int stack_length = 0;
+  Window *stack;
+  int stack_length;
   /* mapping order */
-  Window *mapping = NULL;
-  int mapping_length = 0;
+  Window *mapping;
+  int mapping_length;
   GList *new_stack_list;
   GList *new_list;
   GList *created;
@@ -1164,11 +1454,15 @@
   
   screen->priv->need_update_stack_list = FALSE;
   
+  stack = NULL;
+  stack_length = 0;
   _wnck_get_window_list (screen->priv->xroot,
                          _wnck_atom_get ("_NET_CLIENT_LIST_STACKING"),
                          &stack,
                          &stack_length);
 
+  mapping = NULL;
+  mapping_length = 0;
   _wnck_get_window_list (screen->priv->xroot,
                          _wnck_atom_get ("_NET_CLIENT_LIST"),
                          &mapping,
@@ -1363,18 +1657,18 @@
 
       window = WNCK_WINDOW (tmp->data);
 
+      if (window == screen->priv->previously_active_window)
+        {
+          set_previously_active_window (screen, NULL);
+        }
+      
       if (window == screen->priv->active_window)
         {
-          screen->priv->previously_active_window = screen->priv->active_window;
-          screen->priv->active_window = NULL;
+          set_previously_active_window (screen, screen->priv->active_window);
+          set_active_window (screen, NULL);
           active_changed = TRUE;
         }
 
-      if (window == screen->priv->previously_active_window)
-        {
-          screen->priv->previously_active_window = NULL;
-        }
-      
       emit_window_closed (screen, window);
     }
 
@@ -1439,9 +1733,16 @@
   ++reentrancy_guard;
   
   n_spaces = 0;
-  _wnck_get_cardinal (screen->priv->xroot,
-                      _wnck_atom_get ("_NET_NUMBER_OF_DESKTOPS"),
-                      &n_spaces);
+  if (!_wnck_get_cardinal (screen->priv->xroot,
+                           _wnck_atom_get ("_NET_NUMBER_OF_DESKTOPS"),
+                           &n_spaces))
+    n_spaces = 1;
+
+  if (n_spaces <= 0)
+    {
+      g_warning ("Someone set a weird number of desktops in _NET_NUMBER_OF_DESKTOPS, assuming the value is 1\n");
+      n_spaces = 1;
+    }
   
   old_n_spaces = g_list_length (screen->priv->workspaces);
 
@@ -1562,6 +1863,8 @@
   space_width = wnck_screen_get_width (screen);
   space_height = wnck_screen_get_height (screen);
   
+  p_coord = NULL;
+  n_coord = 0;
   if (_wnck_get_cardinal_list (screen->priv->xroot,
 			       _wnck_atom_get ("_NET_DESKTOP_GEOMETRY"),
                                &p_coord, &n_coord) &&
@@ -1593,6 +1896,8 @@
 
   got_viewport_prop = FALSE;
   
+  p_coord = NULL;
+  n_coord = 0;
   if (_wnck_get_cardinal_list (screen->priv->xroot,
                                _wnck_atom_get ("_NET_DESKTOP_VIEWPORT"),
                                &p_coord, &n_coord) &&
@@ -1700,8 +2005,8 @@
   if (window == screen->priv->active_window)
     return;
 
-  screen->priv->previously_active_window = screen->priv->active_window;
-  screen->priv->active_window = window;
+  set_previously_active_window (screen, screen->priv->active_window);
+  set_active_window (screen, window);
 
   emit_active_window_changed (screen);
 }
@@ -1712,14 +2017,13 @@
   gulong *list;
   int n_items;
 
-  list = NULL;
-  n_items = 0;
-
   if (!screen->priv->need_update_workspace_layout)
     return;
 
   screen->priv->need_update_workspace_layout = FALSE;
 
+  list = NULL;
+  n_items = 0;
   if (_wnck_get_cardinal_list (screen->priv->xroot,
                                _wnck_atom_get ("_NET_DESKTOP_LAYOUT"),
                                &list, 
@@ -1766,16 +2070,16 @@
               switch (list[3])
                 {
                   case _NET_WM_TOPLEFT:
-                    screen->priv->starting_corner = SCREEN_TOPLEFT;
+                    screen->priv->starting_corner = WNCK_LAYOUT_CORNER_TOPLEFT;
                     break;
                   case _NET_WM_TOPRIGHT:
-                    screen->priv->starting_corner = SCREEN_TOPRIGHT;
+                    screen->priv->starting_corner = WNCK_LAYOUT_CORNER_TOPRIGHT;
                     break;
                   case _NET_WM_BOTTOMRIGHT:
-                    screen->priv->starting_corner = SCREEN_BOTTOMRIGHT;
+                    screen->priv->starting_corner = WNCK_LAYOUT_CORNER_BOTTOMRIGHT;
                     break;
                   case _NET_WM_BOTTOMLEFT:
-                    screen->priv->starting_corner = SCREEN_BOTTOMLEFT;
+                    screen->priv->starting_corner = WNCK_LAYOUT_CORNER_BOTTOMLEFT;
                     break;
                   default:
                     g_warning ("Someone set a weird starting corner in _NET_DESKTOP_LAYOUT\n");
@@ -1783,7 +2087,7 @@
                 }
             }
           else
-            screen->priv->starting_corner = SCREEN_TOPLEFT;
+            screen->priv->starting_corner = WNCK_LAYOUT_CORNER_TOPLEFT;
         }
       else
         {
@@ -1873,6 +2177,32 @@
 }
 
 static void
+update_wm (WnckScreen *screen)
+{
+  Window  wm_window;
+  
+  if (!screen->priv->need_update_wm)
+    return;
+  
+  screen->priv->need_update_wm = FALSE;
+
+  wm_window = None;
+  _wnck_get_window (screen->priv->xroot,
+                    _wnck_atom_get ("_NET_SUPPORTING_WM_CHECK"),
+                    &wm_window);
+
+  g_free (screen->priv->wm_name);
+
+  if (wm_window != None)
+    screen->priv->wm_name = _wnck_get_utf8_property (wm_window,
+                                                     _wnck_atom_get ("_NET_WM_NAME"));
+  else
+    screen->priv->wm_name = NULL;
+
+  emit_wm_changed (screen);
+}
+
+static void
 do_update_now (WnckScreen *screen)
 {
   if (screen->priv->update_handler)
@@ -1903,6 +2233,7 @@
   update_workspace_layout (screen);
   update_workspace_names (screen);
   update_showing_desktop (screen);
+  update_wm (screen);
   
   update_bg_pixmap (screen);
 }
@@ -2061,13 +2392,75 @@
                  0);
 }
 
+static void
+emit_wm_changed (WnckScreen *screen)
+{
+  g_signal_emit (G_OBJECT (screen),
+                 signals[WM_CHANGED],
+                 0);
+}
+
+/**
+ * wnck_screen_get_window_manager_name:
+ * @screen: a #WnckScreen.
+ *
+ * Returns the name of the window manager.
+ *
+ * Return value: the name of the window manager, or %NULL if the window manager
+ * does not comply with the <ulink
+ * url="http://standards.freedesktop.org/wm-spec/wm-spec-latest.html">EWMH</ulink>
+ * specification.
+ *
+ * Since: 2.20
+ */
+const char *
+wnck_screen_get_window_manager_name (WnckScreen *screen)
+{
+  g_return_val_if_fail (WNCK_IS_SCREEN (screen), NULL);
+
+  return screen->priv->wm_name;
+}
+
+/**
+ * wnck_screen_net_wm_supports:
+ * @screen: a #WnckScreen.
+ * @atom: a property atom.
+ *
+ * Returns whether the window manager for @screen supports a certain hint from
+ * the <ulink
+ * url="http://standards.freedesktop.org/wm-spec/wm-spec-latest.html">Extended
+ * Window Manager Hints specification</ulink> (EWMH).
+ *
+ * When using this function, keep in mind that the window manager can change
+ * over time; so you should not use this function in a way that impacts
+ * persistent application state. A common bug is that your application can
+ * start up before the window manager does when the user logs in, and before
+ * the window manager starts wnck_screen_net_wm_supports() will return %FALSE
+ * for every property.
+ *
+ * See also gdk_x11_screen_supports_net_wm_hint() in GDK.
+ *
+ * Return value: %TRUE if the window manager for @screen supports the @atom
+ * hint, %FALSE otherwise.
+ */
 gboolean
 wnck_screen_net_wm_supports (WnckScreen *screen,
                              const char *atom)
 {
-  return gdk_net_wm_supports (gdk_atom_intern (atom, FALSE));
+  g_return_val_if_fail (WNCK_IS_SCREEN (screen), FALSE);
+
+  return gdk_x11_screen_supports_net_wm_hint (_wnck_screen_get_gdk_screen (screen),
+                                              gdk_atom_intern (atom, FALSE));
 }
 
+/**
+ * wnck_screen_get_background_pixmap:
+ * @screen: a #WnckScreen.
+ *
+ * Returns the X window ID of the background pixmap of @screen.
+ *
+ * Returns: the X window ID of the background pixmap of @screen.
+ */
 gulong
 wnck_screen_get_background_pixmap (WnckScreen *screen)
 {
@@ -2076,6 +2469,14 @@
   return screen->priv->bg_pixmap;
 }
 
+/**
+ * wnck_screen_get_width:
+ * @screen: a #WnckScreen.
+ *
+ * Returns the width of @screen.
+ *
+ * Returns: the width of @screen.
+ */
 int
 wnck_screen_get_width (WnckScreen *screen)
 {
@@ -2084,6 +2485,14 @@
   return WidthOfScreen (screen->priv->xscreen);
 }
 
+/**
+ * wnck_screen_get_height:
+ * @screen: a #WnckScreen.
+ *
+ * Returns the height of @screen.
+ *
+ * Returns: the height of @screen.
+ */
 int
 wnck_screen_get_height (WnckScreen *screen)
 {
@@ -2098,12 +2507,75 @@
   return screen->priv->xscreen;
 }
 
-int
-_wnck_screen_get_number (WnckScreen *screen)
+/**
+ * wnck_screen_get_workspace_layout:
+ * @screen: a #WnckScreen.
+ * @orientation: return location for the orientation used in the #WnckWorkspace
+ * layout. See wnck_pager_set_orientation() for more information.
+ * @rows: return location for the number of rows in the #WnckWorkspace layout.
+ * @columns: return location for the number of columns in the #WnckWorkspace
+ * layout.
+ * @starting_corner: return location for the starting corner in the
+ * #WnckWorkspace layout (i.e. the corner containing the first #WnckWorkspace).
+ *
+ * Returns the layout of #WnckWorkspace on @screen.
+ */
+/* TODO: when we are sure about this API, add this function,
+ * WnckLayoutOrientation, WnckLayoutCorner and a "layout-changed" signal. But
+ * to make it really better, use a WnckScreenLayout struct. We might also want
+ * to wait for deprecation of WnckWorkspaceLayout. */
+void
+_wnck_screen_get_workspace_layout (WnckScreen             *screen,
+                                   _WnckLayoutOrientation *orientation,
+                                   int                    *rows,
+                                   int                    *columns,
+                                   _WnckLayoutCorner      *starting_corner)
 {
-  return screen->priv->number;
+  g_return_if_fail (WNCK_IS_SCREEN (screen));
+  
+  if (orientation)
+    *orientation = screen->priv->vertical_workspaces ?
+                       WNCK_LAYOUT_ORIENTATION_VERTICAL :
+                       WNCK_LAYOUT_ORIENTATION_HORIZONTAL;
+
+  if (rows)
+    *rows = screen->priv->rows_of_workspaces;
+
+  if (columns)
+    *columns = screen->priv->columns_of_workspaces;
+
+  if (starting_corner)
+    *starting_corner = screen->priv->starting_corner;
 }
 
+/**
+ * wnck_screen_try_set_workspace_layout:
+ * @screen: a #WnckScreen.
+ * @current_token: a token. Use 0 if you do not called
+ * wnck_screen_try_set_workspace_layout() before, or if you did not keep the
+ * old token.
+ * @rows: the number of rows to use for the #WnckWorkspace layout.
+ * @columns: the number of columns to use for the #WnckWorkspace layout.
+ *
+ * Tries to modify the layout of #WnckWorkspace on @screen. To do this, tries
+ * to acquire ownership of the layout. If the current process is the owner of
+ * the layout, @current_token is used to determine if the caller is the owner
+ * (there might be more than one part of the same process trying to set the
+ * layout). Since no more than one application should set this property of
+ * @screen at a time, setting the layout is not guaranteed to work.
+ *
+ * If @rows is 0, the actual number of rows will be determined based on
+ * @columns and the number of #WnckWorkspace. If @columns is 0, the actual
+ * number of columns will be determined based on @rows and the number of
+ * #WnckWorkspace. @rows and @columns must not be 0 at the same time.
+ *
+ * You have to release the ownership of the layout with
+ * wnck_screen_release_workspace_layout() when you do not need it anymore.
+ *
+ * Return value: a token to use for future calls to
+ * wnck_screen_try_set_workspace_layout() and to
+ * wnck_screen_release_workspace_layout(), or 0 if the layout could not be set.
+ */
 int
 wnck_screen_try_set_workspace_layout (WnckScreen *screen,
                                       int         current_token,
@@ -2114,6 +2586,8 @@
   
   g_return_val_if_fail (WNCK_IS_SCREEN (screen),
                         WNCK_NO_MANAGER_TOKEN);
+  g_return_val_if_fail (rows != 0 || columns != 0,
+                        WNCK_NO_MANAGER_TOKEN);
   
   retval = _wnck_try_desktop_layout_manager (screen->priv->xscreen, current_token);
 
@@ -2125,15 +2599,38 @@
   return retval;
 }
 
+/**
+ * wnck_screen_release_workspace_layout:
+ * @screen: a #WnckScreen.
+ * @current_token: the token obtained through
+ * wnck_screen_try_set_workspace_layout().
+ *
+ * Releases the ownership of the layout of #WnckWorkspace on @screen.
+ * @current_token is used to verify that the caller is the owner of the layout.
+ * If the verification fails, nothing happens.
+ */
 void
 wnck_screen_release_workspace_layout (WnckScreen *screen,
                                       int         current_token)
 {
+  g_return_if_fail (WNCK_IS_SCREEN (screen));
+
   _wnck_release_desktop_layout_manager (screen->priv->xscreen,
                                         current_token);
 
 }
 
+/**
+ * wnck_screen_get_showing_desktop:
+ * @screen: a #WnckScreen.
+ *
+ * Returns whether @screen is in the "showing the desktop" mode. This mode is
+ * changed when a #WnckScreen::showing-desktop-changed signal gets emitted.
+ *
+ * Return value: %TRUE if @window is fullscreen, %FALSE otherwise.
+ *
+ * Since: 2.2
+ **/
 gboolean
 wnck_screen_get_showing_desktop (WnckScreen *screen)
 {
@@ -2142,6 +2639,16 @@
   return screen->priv->showing_desktop;
 }
 
+/**
+ * wnck_screen_toggle_showing_desktop:
+ * @screen: a #WnckScreen.
+ * @show: whether to activate the "showing the desktop" mode on @screen.
+ *
+ * Asks the window manager to set the "showing the desktop" mode on @screen
+ * according to @show.
+ *
+ * Since: 2.2
+ **/
 void
 wnck_screen_toggle_showing_desktop (WnckScreen *screen,
                                     gboolean    show)
@@ -2155,11 +2662,14 @@
 
 /**
  * wnck_screen_move_viewport:
- * @screen: a #WnckScreen
- * @x: X offset of viewport
- * @y: Y offset of viewport
+ * @screen: a #WnckScreen.
+ * @x: X offset in pixels of viewport.
+ * @y: Y offset in pixels of viewport.
+ *
+ * Asks the window manager to move the viewport of the current #WnckWorkspace
+ * on @screen.
  *
- * Ask window manager to move the viewport of the current workspace.
+ * Since: 2.4
  */
 void
 wnck_screen_move_viewport (WnckScreen *screen,
diff -Nur libwnck-2.19.3.1/libwnck/screen.h libwnck-2.19.4/libwnck/screen.h
--- libwnck-2.19.3.1/libwnck/screen.h	2007-06-05 20:25:40.000000000 +0200
+++ libwnck-2.19.4/libwnck/screen.h	2007-06-18 21:59:14.000000000 +0200
@@ -1,4 +1,5 @@
 /* screen object */
+/* vim: set sw=2 et: */
 
 /*
  * Copyright (C) 2001 Havoc Pennington
@@ -45,6 +46,12 @@
 typedef struct _WnckScreenClass   WnckScreenClass;
 typedef struct _WnckScreenPrivate WnckScreenPrivate;
 
+/**
+ * WnckScreen:
+ *
+ * The #WnckScreen struct contains only private fields and should not be
+ * directly accessed.
+ */
 struct _WnckScreen
 {
   GObject parent_instance;
@@ -98,8 +105,10 @@
   /* Viewport stuff changed */
   void (* viewports_changed)        (WnckScreen      *screen);
   
+  /* Window manager changed */
+  void (* window_manager_changed)   (WnckScreen      *screen);
+
   /* Padding for future expansion */
-  void (* pad1) (void);
   void (* pad2) (void);
   void (* pad3) (void);
   void (* pad4) (void);
@@ -109,6 +118,25 @@
 
 typedef struct _WnckWorkspaceLayout WnckWorkspaceLayout;
 
+/**
+ * WnckWorkspaceLayout:
+ * @rows: number of rows in the layout grid.
+ * @cols: number of columns in the layout grid.
+ * @grid: array of size @grid_area containing the index (starting from 0) of
+ * the #WnckWorkspace for each position in the layout grid, or -1 if the
+ * position does not correspond to any #WnckWorkspace.
+ * @grid_area: size of the grid containing all #WnckWorkspace. This can be
+ * bigger than the number of #WnckWorskpace because the grid might not be
+ * filled.
+ * @current_row: row of the specific #WnckWorkspace, starting from 0.
+ * @current_col: column of the specific #WnckWorkspace, starting from 0.
+ *
+ * The #WnckWorkspaceLayout struct contains information about the layout of
+ * #WnckWorkspace on a #WnckScreen, and the exact position of a specific
+ * #WnckWorkspace.
+ *
+ * Since: 2.12
+ */
 struct _WnckWorkspaceLayout
 {
   int rows;
@@ -119,6 +147,21 @@
   int current_col;
 };
 
+/**
+ * WnckMotionDirection:
+ * @WNCK_MOTION_UP: search a neighbor #WnckWorkspace above another
+ * #WnckWorkspace. 
+ * @WNCK_MOTION_DOWN: search a neighbor #WnckWorkspace below another
+ * #WnckWorkspace.
+ * @WNCK_MOTION_LEFT: search a neighbor #WnckWorkspace at the left of another
+ * #WnckWorkspace.
+ * @WNCK_MOTION_RIGHT: search a neighbor #WnckWorkspace at the right of another
+ * #WnckWorkspace.
+ *
+ * Type defining a direction in which to search a neighbor #WnckWorkspace.
+ *
+ * Since: 2.14
+ */
 typedef enum
 {
   WNCK_MOTION_UP = -1,
@@ -127,17 +170,56 @@
   WNCK_MOTION_RIGHT = -4
 } WnckMotionDirection;
 
+/**
+ * WnckLayoutOrientation:
+ * @WNCK_LAYOUT_ORIENTATION_HORIZONTAL: the #WnckWorkspace are laid out in
+ * rows, with the first #WnckWorkspace in the defined #WnckLayoutCorner.
+ * @WNCK_LAYOUT_ORIENTATION_VERTICAL: the #WnckWorkspace are laid out in
+ * columns, with the first #WnckWorkspace in the defined #WnckLayoutCorner.
+ *
+ * Type defining the orientation of the layout of #WnckWorkspace. See
+ * wnck_pager_set_orientation() for more information.
+ */
+typedef enum
+{
+  WNCK_LAYOUT_ORIENTATION_HORIZONTAL,
+  WNCK_LAYOUT_ORIENTATION_VERTICAL
+} _WnckLayoutOrientation;
+
+/**
+ * WnckLayoutCorner:
+ * @WNCK_LAYOUT_CORNER_TOPLEFT: the first #WnckWorkspace is in the top left
+ * corner of the layout.
+ * @WNCK_LAYOUT_CORNER_TOPRIGHT: the first #WnckWorkspace is in the top right
+ * corner of the layout.
+ * @WNCK_LAYOUT_CORNER_BOTTOMRIGHT: the first #WnckWorkspace is in the bottom
+ * right corner of the layout.
+ * @WNCK_LAYOUT_CORNER_BOTTOMLEFT: the first #WnckWorkspace is in the bottom
+ * left corner of the layout.
+ *
+ * Type defining the starting corner of the layout of #WnckWorkspace, i.e. the
+ * corner containing the first #WnckWorkspace.
+ */
+typedef enum
+{
+  WNCK_LAYOUT_CORNER_TOPLEFT,
+  WNCK_LAYOUT_CORNER_TOPRIGHT,
+  WNCK_LAYOUT_CORNER_BOTTOMRIGHT,
+  WNCK_LAYOUT_CORNER_BOTTOMLEFT
+} _WnckLayoutCorner;
+
 GType wnck_screen_get_type (void) G_GNUC_CONST;
 
 WnckScreen*    wnck_screen_get_default              (void);
 WnckScreen*    wnck_screen_get                      (int         index);
 WnckScreen*    wnck_screen_get_for_root             (gulong      root_window_id);
+int            wnck_screen_get_number               (WnckScreen *screen);
 WnckWorkspace* wnck_screen_get_workspace            (WnckScreen *screen,
                                                      int         workspace);
 int            wnck_screen_get_workspace_index      (WnckScreen    *screen,
-                                                     WnckWorkspace *workspace);
+                                                     WnckWorkspace *space);
 WnckWorkspace* wnck_screen_get_workspace_neighbor   (WnckScreen         *screen,
-                                                     WnckWorkspace      *workspace,
+                                                     WnckWorkspace      *space,
                                                      WnckMotionDirection direction);
 WnckWorkspace* wnck_screen_get_active_workspace     (WnckScreen *screen);
 WnckWindow*    wnck_screen_get_active_window        (WnckScreen *screen);
@@ -148,6 +230,7 @@
 int            wnck_screen_get_workspace_count      (WnckScreen *screen);
 void           wnck_screen_change_workspace_count   (WnckScreen *screen,
                                                      int         count);
+const char*    wnck_screen_get_window_manager_name  (WnckScreen *screen);
 gboolean       wnck_screen_net_wm_supports          (WnckScreen *screen,
                                                      const char *atom);
 gulong         wnck_screen_get_background_pixmap    (WnckScreen *screen);
@@ -159,6 +242,11 @@
 void           wnck_screen_move_viewport            (WnckScreen *screen,
                                                      int         x,
                                                      int         y);
+void           _wnck_screen_get_workspace_layout     (WnckScreen             *screen,
+                                                      _WnckLayoutOrientation *orientation,
+                                                      int                    *rows,
+                                                      int                    *columns,
+                                                      _WnckLayoutCorner      *starting_corner);
 int            wnck_screen_try_set_workspace_layout (WnckScreen *screen,
                                                      int         current_token,
                                                      int         rows,
@@ -167,7 +255,7 @@
                                                      int         current_token);
 void           wnck_screen_calc_workspace_layout    (WnckScreen          *screen,
                                                      int                  num_workspaces,
-                                                     int                  current_space,
+                                                     int                  space_index,
                                                      WnckWorkspaceLayout *layout);
 void           wnck_screen_free_workspace_layout (WnckWorkspaceLayout *layout);
 
diff -Nur libwnck-2.19.3.1/libwnck/selector.c libwnck-2.19.4/libwnck/selector.c
--- libwnck-2.19.3.1/libwnck/selector.c	2007-06-05 20:25:40.000000000 +0200
+++ libwnck-2.19.4/libwnck/selector.c	2007-06-18 21:59:14.000000000 +0200
@@ -1,3 +1,5 @@
+/* selector */
+/* vim: set sw=2 et: */
 /*
  * Copyright (C) 2003 Sun Microsystems, Inc.
  * Copyright (C) 2001 Free Software Foundation, Inc.
@@ -35,6 +37,21 @@
 #include "screen.h"
 #include "private.h"
 
+/**
+ * SECTION:selector
+ * @short_description: a window selector widget, showing the list of windows as
+ * a menu.
+ * @see_also: #WnckTasklist
+ * @stability: Unstable
+ *
+ * The #WnckSelector represents client windows on a screen as a menu, where
+ * menu items are labelled with the window titles and icons. Activating a menu
+ * item activates the represented window.
+ *
+ * The #WnckSelector will automatically detect the screen it is on, and will
+ * represent windows of this screen only.
+ */
+
 typedef struct
 {
   GtkWidget *item;
@@ -57,6 +74,9 @@
 
 G_DEFINE_TYPE (WnckSelector, wnck_selector, GTK_TYPE_MENU_BAR);
 
+static GObject *wnck_selector_constructor (GType                  type,
+                                           guint                  n_construct_properties,
+                                           GObjectConstructParam *construct_properties);
 static void wnck_selector_finalize          (GObject           *object);
 static void wnck_selector_realize           (GtkWidget *widget);
 static void wnck_selector_unrealize         (GtkWidget *widget);
@@ -552,7 +572,19 @@
 			  GdkDragContext     *context,
 			  WnckWindow         *window)
 {
-  _wnck_window_set_as_drag_icon (window, context, widget);
+  while (widget)
+    {
+      if (WNCK_IS_SELECTOR (widget))
+        break;
+
+      if (GTK_IS_MENU (widget))
+        widget = gtk_menu_get_attach_widget (GTK_MENU (widget));
+      else
+        widget = widget->parent;
+    }
+
+  if (widget)
+    _wnck_window_set_as_drag_icon (window, context, widget);
 }
 
 static void  
@@ -1242,6 +1274,7 @@
   GtkObjectClass *gtk_object_class = GTK_OBJECT_CLASS (klass);
   GtkWidgetClass *widget_class     = GTK_WIDGET_CLASS (klass);
 
+  object_class->constructor = wnck_selector_constructor;
   object_class->finalize = wnck_selector_finalize;
 
   gtk_object_class->destroy = wnck_selector_destroy;
@@ -1252,6 +1285,23 @@
   g_type_class_add_private (klass, sizeof (WnckSelectorPrivate));
 }
 
+static GObject *
+wnck_selector_constructor (GType                  type,
+                           guint                  n_construct_properties,
+                           GObjectConstructParam *construct_properties)
+{
+  GObject *obj;
+
+  obj = G_OBJECT_CLASS (wnck_selector_parent_class)->constructor (
+                                                      type,
+                                                      n_construct_properties,
+                                                      construct_properties);
+
+  wnck_selector_fill (WNCK_SELECTOR (obj));
+
+  return obj;
+}
+
 static void
 wnck_selector_finalize (GObject *object)
 {
@@ -1323,6 +1373,16 @@
   GTK_WIDGET_CLASS (wnck_selector_parent_class)->unrealize (widget);
 }
 
+/**
+ * wnck_selector_new:
+ *
+ * Creates a new #WnckSelector. The #WnckSelector will list #WnckWindow of the
+ * #WnckScreen it is on.
+ *
+ * Return value: a newly created #WnckSelector.
+ *
+ * Since: 2.10
+ */
 GtkWidget *
 wnck_selector_new (void)
 {
@@ -1330,7 +1390,5 @@
 
   selector = g_object_new (WNCK_TYPE_SELECTOR, NULL);
 
-  wnck_selector_fill (selector);
-
   return GTK_WIDGET (selector);
 }
diff -Nur libwnck-2.19.3.1/libwnck/selector.h libwnck-2.19.4/libwnck/selector.h
--- libwnck-2.19.3.1/libwnck/selector.h	2007-06-05 20:25:40.000000000 +0200
+++ libwnck-2.19.4/libwnck/selector.h	2007-06-18 21:59:14.000000000 +0200
@@ -1,4 +1,5 @@
 /* selector */
+/* vim: set sw=2 et: */
 
 /*
  * Copyright (C) 2001 Havoc Pennington
@@ -35,6 +36,12 @@
 typedef struct _WnckSelectorClass WnckSelectorClass;
 typedef struct _WnckSelectorPrivate WnckSelectorPrivate;
 
+/**
+ * WnckSelector:
+ *
+ * The #WnckSelector struct contains only private fields and should not be
+ * directly accessed.
+ */
 struct _WnckSelector
 {
   GtkMenuBar parent_instance;
diff -Nur libwnck-2.19.3.1/libwnck/tasklist.c libwnck-2.19.4/libwnck/tasklist.c
--- libwnck-2.19.3.1/libwnck/tasklist.c	2007-06-05 20:25:40.000000000 +0200
+++ libwnck-2.19.4/libwnck/tasklist.c	2007-06-18 21:59:14.000000000 +0200
@@ -1,4 +1,5 @@
 /* tasklist object */
+/* vim: set sw=2 et: */
 
 /*
  * Copyright (C) 2001 Havoc Pennington
@@ -35,6 +36,31 @@
 #include "xutils.h"
 #include "private.h"
 
+/**
+ * SECTION:tasklist
+ * @short_description: a tasklist widget, showing the list of windows as a list
+ * of buttons.
+ * @see_also: #WnckScreen, #WnckSelector
+ * @stability: Unstable
+ *
+ * The #WnckTasklist represents client windows on a screen as a list of buttons
+ * labelled with the window titles and icons. Pressing a button can activate or
+ * minimize the represented window, and other typical actions are available
+ * through a popup menu.
+ *
+ * The behavior of the #WnckTasklist can be customized in various ways, like
+ * grouping multiple windows of the same application in one button (see
+ * wnck_tasklist_set_grouping() and wnck_tasklist_set_grouping_limit()), or
+ * showing windows from all workspaces (see
+ * wnck_tasklist_set_include_all_workspaces()).
+ *
+ * The tasklist also acts as iconification destination. If there are multiple
+ * #WnckTasklist or other applications setting the iconification destination
+ * for windows, the iconification destinations might not be consistent among
+ * windows and it is not possible to determine which #WnckTasklist (or which
+ * other application) owns this propriety.
+ */
+
 /* TODO:
  * 
  *  Add total focused time to the grouping score function
@@ -169,8 +195,6 @@
   GHashTable *class_group_hash;
   GHashTable *win_hash;
   
-  GtkTooltips *tooltips;
-
   gint max_button_width;
   gint max_button_height;
 
@@ -206,6 +230,10 @@
   GdkPixmap *background;
 };
 
+static GType wnck_task_get_type (void);
+
+G_DEFINE_TYPE (WnckTask, wnck_task, G_TYPE_OBJECT);
+G_DEFINE_TYPE (WnckTasklist, wnck_tasklist, GTK_TYPE_CONTAINER);
 
 static void wnck_task_init        (WnckTask      *task);
 static void wnck_task_class_init  (WnckTaskClass *klass);
@@ -233,9 +261,12 @@
                                                   WnckWindowState  changed_mask, 
                                                   WnckWindowState  new_state,
                                                   gpointer         data);
-static void wnck_tasklist_init        (WnckTasklist      *tasklist);
-static void wnck_tasklist_class_init  (WnckTasklistClass *klass);
-static void wnck_tasklist_finalize    (GObject        *object);
+static void     wnck_tasklist_init          (WnckTasklist      *tasklist);
+static void     wnck_tasklist_class_init    (WnckTasklistClass *klass);
+static GObject *wnck_tasklist_constructor   (GType              type,
+                                             guint              n_construct_properties,
+                                             GObjectConstructParam *construct_properties);
+static void     wnck_tasklist_finalize      (GObject        *object);
 
 static void     wnck_tasklist_size_request  (GtkWidget        *widget,
                                              GtkRequisition   *requisition);
@@ -251,6 +282,9 @@
                                              gpointer          callback_data);
 static void     wnck_tasklist_remove	    (GtkContainer   *container,
 					     GtkWidget	    *widget);
+static gboolean wnck_tasklist_scroll_cb     (WnckTasklist   *tasklist,
+                                             GdkEventScroll *event,
+                                             gpointer        user_data);
 static void     wnck_tasklist_free_tasks    (WnckTasklist   *tasklist);
 static void     wnck_tasklist_update_lists  (WnckTasklist   *tasklist);
 static int      wnck_tasklist_layout        (GtkAllocation  *allocation,
@@ -276,6 +310,8 @@
 							WnckTasklist *tasklist);
 static void     wnck_tasklist_connect_window           (WnckTasklist *tasklist,
 							WnckWindow   *window);
+static void     wnck_tasklist_disconnect_window        (WnckTasklist *tasklist,
+							WnckWindow   *window);
 
 static void     wnck_tasklist_change_active_task       (WnckTasklist *tasklist,
 							WnckTask *active_task);
@@ -285,8 +321,7 @@
 
 static void     wnck_tasklist_update_icon_geometries   (WnckTasklist *tasklist,
 							GList        *visible_tasks);
-static void     wnck_tasklist_connect_screen           (WnckTasklist *tasklist,
-                                                        WnckScreen   *screen);
+static void     wnck_tasklist_connect_screen           (WnckTasklist *tasklist);
 static void     wnck_tasklist_disconnect_screen        (WnckTasklist *tasklist);
 
 #ifdef HAVE_STARTUP_NOTIFICATION
@@ -297,9 +332,6 @@
 #endif
 
 
-static gpointer task_parent_class;
-static gpointer tasklist_parent_class;
-
 /*
  * Keep track of all tasklist instances so we can decide
  * whether to show windows from all monitors in the
@@ -325,37 +357,6 @@
     }
 }
 
-static GType
-wnck_task_get_type (void)
-{
-  static GType object_type = 0;
-
-  g_type_init ();
-  
-  if (!object_type)
-    {
-      const GTypeInfo object_info =
-      {
-        sizeof (WnckTaskClass),
-        (GBaseInitFunc) NULL,
-        (GBaseFinalizeFunc) NULL,
-        (GClassInitFunc) wnck_task_class_init,
-        NULL,           /* class_finalize */
-        NULL,           /* class_data */
-        sizeof (WnckTask),
-        0,              /* n_preallocs */
-        (GInstanceInitFunc) wnck_task_init,
-        NULL            /* value_table */
-      };
-      
-      object_type = g_type_register_static (G_TYPE_OBJECT,
-                                            "WnckTask",
-                                            &object_info, 0);
-    }
-  
-  return object_type;
-}
-
 static void
 wnck_task_init (WnckTask *task)
 {  
@@ -370,8 +371,6 @@
 {
   GObjectClass *object_class = G_OBJECT_CLASS (klass);
   
-  task_parent_class = g_type_class_peek_parent (klass);
-  
   object_class->finalize = wnck_task_finalize;
 
   gtk_rc_parse_string ("\n"
@@ -578,38 +577,7 @@
 
   wnck_task_stop_glow (task);
 
-  G_OBJECT_CLASS (task_parent_class)->finalize (object);
-}
-
-GType
-wnck_tasklist_get_type (void)
-{
-  static GType object_type = 0;
-
-  g_type_init ();
-  
-  if (!object_type)
-    {
-      const GTypeInfo object_info =
-      {
-        sizeof (WnckTasklistClass),
-        (GBaseInitFunc) NULL,
-        (GBaseFinalizeFunc) NULL,
-        (GClassInitFunc) wnck_tasklist_class_init,
-        NULL,           /* class_finalize */
-        NULL,           /* class_data */
-        sizeof (WnckTasklist),
-        0,              /* n_preallocs */
-        (GInstanceInitFunc) wnck_tasklist_init,
-        NULL            /* value_table */
-      };
-      
-      object_type = g_type_register_static (GTK_TYPE_CONTAINER,
-                                            "WnckTasklist",
-                                            &object_info, 0);
-    }
-  
-  return object_type;
+  G_OBJECT_CLASS (wnck_task_parent_class)->finalize (object);
 }
 
 static void
@@ -656,8 +624,7 @@
   GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
   GtkContainerClass *container_class = GTK_CONTAINER_CLASS (klass);
   
-  tasklist_parent_class = g_type_class_peek_parent (klass);
-  
+  object_class->constructor = wnck_tasklist_constructor;
   object_class->finalize = wnck_tasklist_finalize;
 
   widget_class->size_request = wnck_tasklist_size_request;
@@ -691,6 +658,24 @@
                                                               G_PARAM_READABLE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB));
 }
 
+static GObject *
+wnck_tasklist_constructor (GType                  type,
+                           guint                  n_construct_properties,
+                           GObjectConstructParam *construct_properties)
+{
+  GObject *obj;
+
+  obj = G_OBJECT_CLASS (wnck_tasklist_parent_class)->constructor (
+                                                      type,
+                                                      n_construct_properties,
+                                                      construct_properties);
+
+  g_signal_connect (obj, "scroll-event",
+                    G_CALLBACK (wnck_tasklist_scroll_cb), NULL);
+
+  return obj;
+}
+
 static void
 wnck_tasklist_free_skipped_windows (WnckTasklist  *tasklist)
 {
@@ -726,8 +711,6 @@
       tasklist->priv->skipped_windows = NULL;
     }
   
-  wnck_tasklist_disconnect_screen (tasklist);
-
   /* Tasks should have gone away due to removing their
    * buttons in container destruction
    */
@@ -754,12 +737,6 @@
       tasklist->priv->idle_callback_tag = 0;
     }
     
-  if (tasklist->priv->tooltips)
-    {
-      g_object_unref (tasklist->priv->tooltips);
-      tasklist->priv->tooltips = NULL;
-    }
-
   g_free (tasklist->priv->size_hints);
   tasklist->priv->size_hints = NULL;
   tasklist->priv->size_hints_len = 0;
@@ -773,9 +750,16 @@
   g_free (tasklist->priv);
   tasklist->priv = NULL;  
   
-  G_OBJECT_CLASS (tasklist_parent_class)->finalize (object);
+  G_OBJECT_CLASS (wnck_tasklist_parent_class)->finalize (object);
 }
 
+/**
+ * wnck_tasklist_set_grouping:
+ * @tasklist: a #WnckTasklist.
+ * @grouping: a grouping policy.
+ *
+ * Sets the grouping policy for @tasklist to @grouping.
+ */
 void
 wnck_tasklist_set_grouping (WnckTasklist            *tasklist,
 			    WnckTasklistGroupingType grouping)
@@ -797,11 +781,24 @@
   gtk_button_set_relief (GTK_BUTTON (task->button), tasklist->priv->relief);
 }
 
+/**
+ * wnck_tasklist_set_button_relief:
+ * @tasklist: a #WnckTasklist.
+ * @relief: a relief type.
+ *
+ * Sets the relief type of the buttons in @tasklist to @relief. The main use of
+ * this function is proper integration of #WnckTasklist in panels with
+ * non-system backgrounds.
+ *
+ * Since: 2.12
+ */
 void
 wnck_tasklist_set_button_relief (WnckTasklist *tasklist, GtkReliefStyle relief)
 {
   GList *walk;
 
+  g_return_if_fail (WNCK_IS_TASKLIST (tasklist));
+
   if (relief == tasklist->priv->relief)
     return;
 
@@ -814,6 +811,17 @@
     gtk_button_set_relief (GTK_BUTTON (WNCK_TASK (walk->data)->button), relief);
 }
 
+/**
+ * wnck_tasklist_set_switch_workspace_on_unminimize:
+ * @tasklist: a #WnckTasklist.
+ * @switch_workspace_on_unminimize: whether to activate the #WnckWorkspace a
+ * #WnckWindow is on when unminimizing it.
+ *
+ * Sets @tasklist to activate or not the #WnckWorkspace a #WnckWindow is on
+ * when unminimizing it, according to @switch_workspace_on_unminimize.
+ *
+ * FIXME: does it still work?
+ */
 void
 wnck_tasklist_set_switch_workspace_on_unminimize (WnckTasklist  *tasklist,
 						  gboolean       switch_workspace_on_unminimize)
@@ -823,6 +831,15 @@
   tasklist->priv->switch_workspace_on_unminimize = switch_workspace_on_unminimize;
 }
 
+/**
+ * wnck_tasklist_set_include_all_workspaces:
+ * @tasklist: a #WnckTasklist.
+ * @include_all_workspaces: whether to display #WnckWindow from all
+ * #WnckWorkspace in @tasklist.
+ *
+ * Sets @tasklist to display #WnckWindow from all #WnckWorkspace or not,
+ * according to @include_all_workspaces.
+ */
 void
 wnck_tasklist_set_include_all_workspaces (WnckTasklist *tasklist,
 					  gboolean      include_all_workspaces)
@@ -839,6 +856,16 @@
   gtk_widget_queue_resize (GTK_WIDGET (tasklist));
 }
 
+/**
+ * wnck_tasklist_set_grouping_limit:
+ * @tasklist: a #WnckTasklist.
+ * @limit: a size in pixels.
+ *
+ * Sets the maximum size of buttons in @tasklist before @tasklist tries to
+ * group #WnckWindow in the same #WnckApplication in only one button. This
+ * limit is valid only when the grouping policy of @tasklist is
+ * %WNCK_TASKLIST_AUTO_GROUP.
+ */
 void
 wnck_tasklist_set_grouping_limit (WnckTasklist *tasklist,
 				  gint          limit)
@@ -852,8 +879,14 @@
   gtk_widget_queue_resize (GTK_WIDGET (tasklist));
 }
 
-/* set the minimum width 
- * use -1 to unset it (resulting in the default width */
+/**
+ * wnck_tasklist_set_minimum_width:
+ * @tasklist: a #WnckTasklist.
+ * @size: a minimum width in pixels.
+ *
+ * Sets the minimum width to use for @tasklist to @size pixels. If @size is -1,
+ * sets the minimum width to a default.
+ */
 void 
 wnck_tasklist_set_minimum_width (WnckTasklist *tasklist, gint size)
 {
@@ -868,7 +901,14 @@
   gtk_widget_queue_resize (GTK_WIDGET (tasklist));
 }
  
-/* get the minimum width */
+/**
+ * wnck_tasklist_get_minimum_width:
+ * @tasklist: a #WnckTasklist.
+ *
+ * Returns the minimum width of @tasklist.
+ *
+ * Return value: the minimum width of @tasklist.
+ */
 gint
 wnck_tasklist_get_minimum_width (WnckTasklist *tasklist)
 {
@@ -877,8 +917,14 @@
   return tasklist->priv->minimum_width;
 }
 
-/* set the minimum height
- * use -1 to unset it (resulting in the default height */
+/**
+ * wnck_tasklist_set_minimum_height:
+ * @tasklist: a #WnckTasklist.
+ * @size: a minimum height in pixels.
+ *
+ * Sets the minimum height to use for @tasklist to @size pixels. If @size is -1,
+ * sets the minimum height to a default.
+ */
 void 
 wnck_tasklist_set_minimum_height (WnckTasklist *tasklist, gint size)
 {
@@ -893,7 +939,14 @@
   gtk_widget_queue_resize (GTK_WIDGET (tasklist));
 }
  
-/* get the minimum height */
+/**
+ * wnck_tasklist_get_minimum_height:
+ * @tasklist: a #WnckTasklist.
+ *
+ * Returns the minimum height of @tasklist.
+ *
+ * Return value: the minimum height of @tasklist.
+ */
 gint
 wnck_tasklist_get_minimum_height (WnckTasklist *tasklist)
 {
@@ -909,11 +962,9 @@
  * @data: data for icon loader function
  * @free_data_func: function to free the data
  *
- * Sets a function to be used for loading icons. The icon
- * loader function takes an icon name as in the Icon field
- * in a .desktop file. The "flags" field for the function
- * is not defined to do anything yet.
+ * Sets a function to be used for loading icons.
  * 
+ * Since: 2.2
  **/
 void
 wnck_tasklist_set_icon_loader (WnckTasklist         *tasklist,
@@ -921,6 +972,8 @@
                                void                 *data,
                                GDestroyNotify        free_data_func)
 {
+  g_return_if_fail (WNCK_IS_TASKLIST (tasklist));
+
   if (tasklist->priv->free_icon_loader_data != NULL)
     (* tasklist->priv->free_icon_loader_data) (tasklist->priv->icon_loader_data);
 
@@ -1239,10 +1292,26 @@
   tasklist->priv->size_hints = (int *)g_array_free (array, FALSE);
 }
 
+/**
+ * wnck_tasklist_get_size_hint_list:
+ * @tasklist: a #WnckTasklist.
+ * @n_elements: return location for the number of elements in the array
+ * returned by this function. This number should always be pair.
+ *
+ * Since a #WnckTasklist does not have a fixed size (#WnckWindow can be grouped
+ * when needed, for example), the standard size request mechanism in GTK+ is
+ * not enough to announce what sizes can be used by @tasklist. The size hints
+ * mechanism is a solution for this. See panel_applet_set_size_hints() for more
+ * information.
+ *
+ * Return value: a list of size hints that can be used to allocate an
+ * appropriate size for @tasklist.
+ */
 const int *
 wnck_tasklist_get_size_hint_list (WnckTasklist  *tasklist,
 				  int           *n_elements)
 {
+  g_return_val_if_fail (WNCK_IS_TASKLIST (tasklist), NULL);
   g_return_val_if_fail (n_elements != NULL, NULL);
 
   *n_elements = tasklist->priv->size_hints_len;
@@ -1415,31 +1484,41 @@
   g_list_free (ungrouped_class_groups);
   tasklist->priv->windows = windows_sorted;
  
-  GTK_WIDGET_CLASS (tasklist_parent_class)->size_allocate (widget, allocation);
+  GTK_WIDGET_CLASS (wnck_tasklist_parent_class)->size_allocate (widget,
+                                                                allocation);
 }
 
 static void
 wnck_tasklist_realize (GtkWidget *widget)
 {
   WnckTasklist *tasklist;
+  GdkScreen *gdkscreen;
 
   tasklist = WNCK_TASKLIST (widget);  
 
+  gdkscreen = gtk_widget_get_screen (widget);
+  tasklist->priv->screen = wnck_screen_get (gdk_screen_get_number (gdkscreen));
+  g_assert (tasklist->priv->screen != NULL);
+
 #ifdef HAVE_STARTUP_NOTIFICATION
   tasklist->priv->sn_context =
     sn_monitor_context_new (_wnck_screen_get_sn_display (tasklist->priv->screen),
-                            _wnck_screen_get_number (tasklist->priv->screen),
+                            wnck_screen_get_number (tasklist->priv->screen),
                             wnck_tasklist_sn_event,
                             tasklist,
                             NULL);
 #endif
   
-  (* GTK_WIDGET_CLASS (tasklist_parent_class)->realize) (widget);
+  (* GTK_WIDGET_CLASS (wnck_tasklist_parent_class)->realize) (widget);
 
   tasklist_instances = g_slist_append (tasklist_instances, tasklist);
   g_slist_foreach (tasklist_instances,
 		   (GFunc) wnck_tasklist_update_lists,
 		   NULL);
+
+  wnck_tasklist_update_lists (tasklist);
+
+  wnck_tasklist_connect_screen (tasklist);
 }
 
 static void
@@ -1449,12 +1528,15 @@
 
   tasklist = WNCK_TASKLIST (widget);
 
+  wnck_tasklist_disconnect_screen (tasklist);
+  tasklist->priv->screen = NULL;
+
 #ifdef HAVE_STARTUP_NOTIFICATION
   sn_monitor_context_unref (tasklist->priv->sn_context);
   tasklist->priv->sn_context = NULL;
 #endif
   
-  (* GTK_WIDGET_CLASS (tasklist_parent_class)->unrealize) (widget);
+  (* GTK_WIDGET_CLASS (wnck_tasklist_parent_class)->unrealize) (widget);
   
   tasklist_instances = g_slist_remove (tasklist_instances, tasklist);
   g_slist_foreach (tasklist_instances,
@@ -1492,7 +1574,7 @@
       g_object_unref (gc);
     }
   
-  return (* GTK_WIDGET_CLASS (tasklist_parent_class)->expose_event) (widget, event);
+  return (* GTK_WIDGET_CLASS (wnck_tasklist_parent_class)->expose_event) (widget, event);
 }
 
 static void
@@ -1608,12 +1690,16 @@
 }
 
 static void
-wnck_tasklist_connect_screen (WnckTasklist *tasklist,
-			      WnckScreen   *screen)
+wnck_tasklist_connect_screen (WnckTasklist *tasklist)
 {
   GList *windows;
   guint *c;
   int    i;
+  WnckScreen *screen;
+
+  g_return_if_fail (tasklist->priv->screen != NULL);
+
+  screen = tasklist->priv->screen;
 
   i = 0;
   c = tasklist->priv->screen_connections;
@@ -1648,7 +1734,15 @@
 static void
 wnck_tasklist_disconnect_screen (WnckTasklist *tasklist)
 {
-  int i;
+  GList *windows;
+  int    i;
+
+  windows = wnck_screen_get_windows (tasklist->priv->screen);
+  while (windows != NULL)
+    {
+      wnck_tasklist_disconnect_window (tasklist, windows->data);
+      windows = windows->next;
+    }
 
   i = 0;
   while (i < N_SCREEN_CONNECTIONS)
@@ -1662,6 +1756,8 @@
       ++i;
     }
 
+  g_assert (i == N_SCREEN_CONNECTIONS);
+
 #ifdef HAVE_STARTUP_NOTIFICATION
   if (tasklist->priv->startup_sequence_timeout != 0)
     {
@@ -1671,21 +1767,20 @@
 #endif
 }
 
+/**
+ * wnck_tasklist_set_screen:
+ * @tasklist: a #WnckTasklist.
+ * @screen: a #WnckScreen.
+ *
+ * Does nothing.
+ *
+ * Since: 2.2
+ * Deprecated:
+ */
 void
 wnck_tasklist_set_screen (WnckTasklist *tasklist,
 			  WnckScreen   *screen)
 {
-  if (tasklist->priv->screen == screen)
-    return;
-
-  if (tasklist->priv->screen)
-    wnck_tasklist_disconnect_screen (tasklist);
-
-  tasklist->priv->screen = screen;
-
-  wnck_tasklist_update_lists (tasklist);
-
-  wnck_tasklist_connect_screen (tasklist, screen);
 }
 
 static gboolean
@@ -1810,6 +1905,16 @@
   return TRUE;
 }
 
+/**
+ * wnck_tasklist_new:
+ * @screen: deprecated argument, can be %NULL.
+ *
+ * Creates a new #WnckTasklist. The #WnckTasklist will list #WnckWindow of the
+ * #WnckScreen it is on.
+ *
+ * Return value: a newly created #WnckTasklist.
+ */
+/* TODO: when we break API again, remove the screen from here */
 GtkWidget*
 wnck_tasklist_new (WnckScreen *screen)
 {
@@ -1817,18 +1922,6 @@
 
   tasklist = g_object_new (WNCK_TYPE_TASKLIST, NULL);
 
-  tasklist->priv->tooltips = gtk_tooltips_new ();
-  g_object_ref_sink (G_OBJECT (tasklist->priv->tooltips));
-
-  wnck_tasklist_set_screen (tasklist, screen);
-
-  /* callback when there is a scroll-event for switching to the next window  */
-  g_signal_connect_object (G_OBJECT (tasklist),
-                           "scroll-event",
-                           G_CALLBACK (wnck_tasklist_scroll_cb),
-                           G_OBJECT (tasklist),
-                           0);
-  
   return GTK_WIDGET (tasklist);
 }
 
@@ -1958,6 +2051,10 @@
   WnckTask *class_group_task;
 
   wnck_tasklist_free_tasks (tasklist);
+
+  /* wnck_tasklist_update_lists() will be called on realize */
+  if (!GTK_WIDGET_REALIZED (tasklist))
+    return;
   
   if (GTK_WIDGET (tasklist)->window != NULL)
     {
@@ -2296,6 +2393,18 @@
 }
 
 static void
+wnck_tasklist_disconnect_window (WnckTasklist *tasklist,
+			         WnckWindow   *window)
+{
+  g_signal_handlers_disconnect_by_func (window,
+                                        wnck_tasklist_window_changed_workspace,
+                                        tasklist);
+  g_signal_handlers_disconnect_by_func (window,
+                                        wnck_tasklist_window_changed_geometry,
+                                        tasklist);
+}
+
+static void
 wnck_tasklist_window_added (WnckScreen   *screen,
 			    WnckWindow   *win,
 			    WnckTasklist *tasklist)
@@ -3005,10 +3114,11 @@
           wnck_task_stop_glow (task);
         }
       g_free (text);
+
       text = wnck_task_get_text (task, FALSE);
       if (text != NULL)
         {
-          gtk_tooltips_set_tip (task->tasklist->priv->tooltips, task->button, text, NULL);
+          gtk_widget_set_tooltip_text (task->button, text);
           g_free (text);
         }
     }
@@ -3182,7 +3292,8 @@
 		      GdkDragContext     *context,
 		      WnckTask           *task)
 {
-  _wnck_window_set_as_drag_icon (task->window, context, widget);
+  _wnck_window_set_as_drag_icon (task->window, context,
+                                 GTK_WIDGET (task->tasklist));
 }
 
 static void
@@ -3420,7 +3531,7 @@
   g_free (text);
   
   text = wnck_task_get_text (task, FALSE);
-  gtk_tooltips_set_tip (task->tasklist->priv->tooltips, task->button, text, NULL);
+  gtk_widget_set_tooltip_text (task->button, text);
   g_free (text);
   
   /* Set up signals */
@@ -3923,8 +4034,8 @@
         if (tasklist->priv->startup_sequence_timeout == 0)
           {
             tasklist->priv->startup_sequence_timeout =
-              g_timeout_add (1000, sequence_timeout_callback,
-                             tasklist);
+              g_timeout_add_seconds (1, sequence_timeout_callback,
+                                     tasklist);
           }
         
         gtk_widget_queue_resize (GTK_WIDGET (tasklist));
diff -Nur libwnck-2.19.3.1/libwnck/tasklist.h libwnck-2.19.4/libwnck/tasklist.h
--- libwnck-2.19.3.1/libwnck/tasklist.h	2007-06-05 20:25:40.000000000 +0200
+++ libwnck-2.19.4/libwnck/tasklist.h	2007-06-18 21:59:14.000000000 +0200
@@ -1,4 +1,5 @@
 /* tasklist object */
+/* vim: set sw=2 et: */
 
 /*
  * Copyright (C) 2001 Havoc Pennington
@@ -38,6 +39,12 @@
 typedef struct _WnckTasklistClass   WnckTasklistClass;
 typedef struct _WnckTasklistPrivate WnckTasklistPrivate;
 
+/**
+ * WnckTasklist:
+ *
+ * The #WnckTasklist struct contains only private fields and should not be
+ * directly accessed.
+ */
 struct _WnckTasklist
 {
   GtkContainer parent_instance;
@@ -56,6 +63,19 @@
   void (* pad4) (void);
 };
 
+/**
+ * WnckTasklistGroupingType:
+ * @WNCK_TASKLIST_NEVER_GROUP: never group multiple #WnckWindow of the same
+ * #WnckApplication.
+ * @WNCK_TASKLIST_AUTO_GROUP: group multiple #WnckWindow of the same
+ * #WnckApplication for some #WnckApplication, when there is not enough place
+ * to have a good-looking list of all #WnckWindow.
+ * @WNCK_TASKLIST_ALWAYS_GROUP: always group multiple #WnckWindow of the same
+ * #WnckApplication, for all #WnckApplication.
+ *
+ * Type defining the policy of the #WnckTasklist for grouping multiple
+ * #WnckWindow of the same #WnckApplication.
+ */
 typedef enum {
   WNCK_TASKLIST_NEVER_GROUP,
   WNCK_TASKLIST_AUTO_GROUP,
@@ -65,8 +85,6 @@
 GType wnck_tasklist_get_type (void) G_GNUC_CONST;
 
 GtkWidget *wnck_tasklist_new (WnckScreen *screen);
-void       wnck_tasklist_set_screen (WnckTasklist *tasklist,
-				     WnckScreen   *screen);
 const int *wnck_tasklist_get_size_hint_list (WnckTasklist  *tasklist,
 					      int           *n_elements);
 
@@ -85,6 +103,23 @@
 void wnck_tasklist_set_minimum_height (WnckTasklist *tasklist, gint size);
 gint wnck_tasklist_get_minimum_height (WnckTasklist *tasklist);
 
+/**
+ * WnckLoadIconFunction:
+ * @icon_name: an icon name as in the Icon field in a .desktop file for the
+ * icon to load.
+ * @size: the desired icon size.
+ * @flags: not defined to do anything yet.
+ * @data: data passed to the function, set when the #WnckLoadIconFunction has
+ * been set for the #WnckTasklist.
+ *
+ * Specifies the type of function passed to wnck_tasklist_set_icon_loader().
+ *
+ * Returns: it should return a <classname>GdkPixbuf</classname> of @icon_name
+ * at size @size, or %NULL if no icon for @icon_name at size @size could be
+ * loaded.
+ *
+ * Since: 2.2
+ */
 typedef GdkPixbuf* (*WnckLoadIconFunction) (const char   *icon_name,
                                             int           size,
                                             unsigned int  flags,
@@ -96,6 +131,10 @@
                                     GDestroyNotify        free_data_func);
 
 
+#ifndef WNCK_DISABLE_DEPRECATED
+void       wnck_tasklist_set_screen (WnckTasklist *tasklist,
+				     WnckScreen   *screen);
+#endif /* WNCK_DISABLE_DEPRECATED */
 
 G_END_DECLS
 
diff -Nur libwnck-2.19.3.1/libwnck/test-pager.c libwnck-2.19.4/libwnck/test-pager.c
--- libwnck-2.19.3.1/libwnck/test-pager.c	2007-06-05 20:25:40.000000000 +0200
+++ libwnck-2.19.4/libwnck/test-pager.c	2007-06-18 21:59:14.000000000 +0200
@@ -1,3 +1,5 @@
+/* vim: set sw=2 et: */
+
 #include <libwnck/libwnck.h>
 #include <gtk/gtk.h>
 
diff -Nur libwnck-2.19.3.1/libwnck/test-selector.c libwnck-2.19.4/libwnck/test-selector.c
--- libwnck-2.19.3.1/libwnck/test-selector.c	2007-06-05 20:25:40.000000000 +0200
+++ libwnck-2.19.4/libwnck/test-selector.c	2007-06-18 21:59:14.000000000 +0200
@@ -1,3 +1,4 @@
+/* vim: set sw=2 et: */
 
 #include <libwnck/libwnck.h>
 #include <gtk/gtk.h>
diff -Nur libwnck-2.19.3.1/libwnck/test-tasklist.c libwnck-2.19.4/libwnck/test-tasklist.c
--- libwnck-2.19.3.1/libwnck/test-tasklist.c	2007-06-05 20:25:40.000000000 +0200
+++ libwnck-2.19.4/libwnck/test-tasklist.c	2007-06-18 21:59:14.000000000 +0200
@@ -1,3 +1,5 @@
+/* vim: set sw=2 et: */
+
 #include <libwnck/libwnck.h>
 #include <gtk/gtk.h>
 
diff -Nur libwnck-2.19.3.1/libwnck/test-wnck.c libwnck-2.19.4/libwnck/test-wnck.c
--- libwnck-2.19.3.1/libwnck/test-wnck.c	2007-06-05 20:25:40.000000000 +0200
+++ libwnck-2.19.4/libwnck/test-wnck.c	2007-06-18 21:59:14.000000000 +0200
@@ -1,3 +1,4 @@
+/* vim: set sw=2 et: */
 
 #include <libwnck/libwnck.h>
 #include <gtk/gtk.h>
diff -Nur libwnck-2.19.3.1/libwnck/util.c libwnck-2.19.4/libwnck/util.c
--- libwnck-2.19.3.1/libwnck/util.c	2007-06-05 20:25:40.000000000 +0200
+++ libwnck-2.19.4/libwnck/util.c	2007-06-18 21:59:14.000000000 +0200
@@ -1,4 +1,5 @@
 /* util header */
+/* vim: set sw=2 et: */
 
 /*
  * Copyright (C) 2001 Havoc Pennington
@@ -25,26 +26,41 @@
 #include "util.h"
 #include "xutils.h"
 #include "private.h"
+#include "inlinepixbufs.h"
 #include <gdk/gdkx.h>
 #include <string.h>
 #ifdef HAVE_XRES
 #include <X11/extensions/XRes.h>
 #endif
 
-static void
-set_dock_realize_handler (GtkWidget *widget, gpointer data)
-{
-  _wnck_set_dock_type_hint (GDK_WINDOW_XWINDOW (widget->window));
-}
+/**
+ * SECTION:util
+ * @short_description: reading resource usage of X clients, and other
+ * additional features.
+ * @see_also: wnck_window_get_xid(), wnck_application_get_xid(), wnck_window_get_pid(), wnck_application_get_pid()
+ * @stability: Unstable
+ *
+ * These functions are utility functions providing some additional features to
+ * libwcnk users, like functions to read resource usage of X clients.
+ */
 
+/**
+ * wnck_gtk_window_set_dock_type:
+ * @window: a <classname>GtkWindow</classname>.
+ *
+ * Sets the semantic type of @window to %WNCK_WINDOW_DOCK.
+ *
+ * Deprecated: Use gdk_window_set_type_hint() instead.
+ */
+/* TODO: when we break API again, remove this: nothing is using it, and it
+ * looks useless... */
 void
 wnck_gtk_window_set_dock_type (GtkWindow *window)
 {
-  /*  FIXME don't set it 10 times if this function is called 10 times */
-  g_signal_connect (G_OBJECT (window),
-                    "realize",
-                    G_CALLBACK (set_dock_realize_handler),
-                    NULL);
+  g_return_if_fail (GTK_IS_WINDOW (window));
+
+  gdk_window_set_type_hint (GTK_WIDGET (window)->window,
+		  	    GDK_WINDOW_TYPE_HINT_DOCK);
 }
 
 typedef enum
@@ -54,15 +70,68 @@
   WNCK_EXT_MISSING = 2
 } WnckExtStatus;
 
+
+#if 0
+/* useful for debugging */
+static void
+_wnck_print_resource_usage (WnckResourceUsage *usage)
+{
+  if (!usage)
+    return;
+
+  g_print ("\twindows       : %d\n"
+           "\tGCs           : %d\n"
+           "\tfonts         : %d\n"
+           "\tpixmaps       : %d\n"
+           "\tpictures      : %d\n"
+           "\tglyphsets     : %d\n"
+           "\tcolormaps     : %d\n"
+           "\tpassive grabs : %d\n"
+           "\tcursors       : %d\n"
+           "\tunknowns      : %d\n"
+           "\tpixmap bytes  : %ld\n"
+           "\ttotal bytes   : ~%ld\n",
+           usage->n_windows, 
+           usage->n_gcs, 
+           usage->n_fonts,
+           usage->n_pixmaps,  
+           usage->n_pictures,
+           usage->n_glyphsets,
+           usage->n_colormap_entries,
+           usage->n_passive_grabs,
+           usage->n_cursors,
+           usage->n_other, 
+           usage->pixmap_bytes,
+           usage->total_bytes_estimate);
+}
+#endif
+
+/**
+ * wnck_xid_read_resource_usage:
+ * @gdk_display: a <classname>GdkDisplay</classname>.
+ * @xid: an X window ID.
+ * @usage: return location for the X resource usage of the application owning
+ * the X window ID @xid.
+ *
+ * Looks for the X resource usage of the application owning the X window ID
+ * @xid on display @gdisplay. If no resource usage can be found, then all
+ * fields of @usage are set to 0.
+ *
+ * To properly work, this function requires the XRes extension on the X server.
+ *
+ * Since: 2.6
+ */
 void
 wnck_xid_read_resource_usage (GdkDisplay        *gdisplay,
-                              unsigned long      xid,
+                              gulong             xid,
                               WnckResourceUsage *usage)
 {
   int event, error;
   Display *xdisplay;
   WnckExtStatus status;
 
+  g_return_if_fail (usage != NULL);
+
   xdisplay = GDK_DISPLAY_XDISPLAY (gdisplay);
 
   status = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (gdisplay),
@@ -126,9 +195,9 @@
    pixmap_atom = _wnck_atom_get ("PIXMAP");
    window_atom = _wnck_atom_get ("WINDOW");
    gc_atom = _wnck_atom_get ("GC");
-   picture_atom = _wnck_atom_get ("FONT");
+   font_atom = _wnck_atom_get ("FONT");
    glyphset_atom = _wnck_atom_get ("GLYPHSET");
-   font_atom = _wnck_atom_get ("PICTURE");
+   picture_atom = _wnck_atom_get ("PICTURE");
    colormap_entry_atom = _wnck_atom_get ("COLORMAP ENTRY");
    passive_grab_atom = _wnck_atom_get ("PASSIVE GRAB");
    cursor_atom = _wnck_atom_get ("CURSOR");
@@ -186,24 +255,287 @@
 #endif /* HAVE_XRES */
 }
 
-void
-wnck_pid_read_resource_usage (GdkDisplay        *gdisplay,
-                              unsigned long      pid,
-                              WnckResourceUsage *usage)
+#ifdef HAVE_XRES
+static void
+wnck_pid_read_resource_usage_free_hash (gpointer data)
+{
+  g_slice_free (gulong, data);
+}
+
+static guint
+wnck_gulong_hash (gconstpointer v)
+{
+  /* FIXME: this is obvioulsy wrong, but nearly 100% of the time, the gulong
+   * only contains guint values */
+  return *(const guint *) v;
+}
+
+static gboolean
+wnck_gulong_equal (gconstpointer a,
+                   gconstpointer b)
+{
+  return *((const gulong *) a) == *((const gulong *) b);
+}
+
+static gulong
+wnck_check_window_for_pid (Window win,
+                           XID    match_xid,
+                           XID    mask)
+{
+  if ((win & ~mask) == match_xid) {
+    return _wnck_get_pid (win);
+  }
+
+  return 0;
+}
+
+static void
+wnck_find_pid_for_resource_r (Display *xdisplay,
+                              Window   win_top,
+                              XID      match_xid,
+                              XID      mask,
+                              gulong  *xid,
+                              gulong  *pid)
+{
+  Status   qtres;
+  int      err;
+  Window   dummy;
+  Window  *children;
+  guint    n_children;
+  int      i;
+  gulong   found_pid = 0;
+
+  while (gtk_events_pending ())
+    gtk_main_iteration ();
+
+  found_pid = wnck_check_window_for_pid (win_top, match_xid, mask);
+  if (found_pid != 0)
+    {
+      *xid = win_top;
+      *pid = found_pid;
+    }
+
+  _wnck_error_trap_push ();
+  qtres = XQueryTree (xdisplay, win_top, &dummy, &dummy,
+                      &children, &n_children);
+  err = _wnck_error_trap_pop ();   
+
+  if (!qtres || err != Success)
+    return;
+
+  for (i = 0; i < n_children; i++) 
+    {
+      wnck_find_pid_for_resource_r (xdisplay, children[i],
+                                    match_xid, mask, xid, pid);
+
+      if (*pid != 0)
+	break;
+    }
+
+  if (children)
+    XFree ((char *)children);
+}
+
+struct xresclient_state
+{
+  XResClient *clients;
+  int         n_clients;
+  int         next;
+  Display    *xdisplay;
+  GHashTable *hashtable_pid;
+};
+
+static struct xresclient_state xres_state = { NULL, 0, -1, NULL, NULL };
+static guint       xres_idleid = 0;
+static GHashTable *xres_hashtable = NULL;
+static time_t      start_update = 0;
+static time_t      end_update = 0;
+static guint       xres_removeid = 0;
+
+static void
+wnck_pid_read_resource_usage_xres_state_free (gpointer data)
+{
+  struct xresclient_state *state;
+
+  state = (struct xresclient_state *) data;
+
+  if (state->clients)
+    XFree (state->clients);
+  state->clients = NULL;
+
+  state->n_clients = 0;
+  state->next = -1;
+  state->xdisplay = NULL;
+
+  if (state->hashtable_pid)
+    g_hash_table_destroy (state->hashtable_pid);
+  state->hashtable_pid = NULL;
+}
+
+static gboolean
+wnck_pid_read_resource_usage_fill_cache (struct xresclient_state *state)
+{
+  int    i;
+  gulong pid;
+  gulong xid;
+  XID    match_xid;
+
+  if (state->next >= state->n_clients)
+    {
+      if (xres_hashtable)
+        g_hash_table_destroy (xres_hashtable);
+      xres_hashtable = state->hashtable_pid;
+      state->hashtable_pid = NULL;
+
+      time (&end_update);
+
+      xres_idleid = 0;
+      return FALSE;
+    }
+
+  match_xid = (state->clients[state->next].resource_base &
+               ~state->clients[state->next].resource_mask);
+
+  for (i = 0; i < ScreenCount (state->xdisplay); i++)
+    {
+      Window root;
+
+      root = RootWindow (state->xdisplay, i);
+
+      if (root == None)
+        continue;
+
+      pid = 0;
+      xid = 0;
+      wnck_find_pid_for_resource_r (state->xdisplay, root, match_xid,
+                                    state->clients[state->next].resource_mask,
+                                    &xid, &pid);
+
+      if (pid != 0 && xid != 0)
+        break;
+    }
+
+  if (pid != 0 && xid != 0)
+    {
+      gulong *key;
+      gulong *value;
+
+      key = g_slice_new (gulong);
+      value = g_slice_new (gulong);
+      *key = pid;
+      *value = xid;
+      g_hash_table_insert (state->hashtable_pid, key, value);
+    }
+
+  state->next++;
+
+  return TRUE;
+}
+
+static void
+wnck_pid_read_resource_usage_start_build_cache (GdkDisplay *gdisplay)
+{
+  Display *xdisplay;
+  int      err;
+
+  if (xres_idleid != 0)
+    return;
+
+  time (&start_update);
+
+  xdisplay = GDK_DISPLAY_XDISPLAY (gdisplay);
+
+  _wnck_error_trap_push ();
+  XResQueryClients (xdisplay, &xres_state.n_clients, &xres_state.clients); 
+  err = _wnck_error_trap_pop ();
+
+  if (err != Success)
+    return;
+
+  xres_state.next = (xres_state.n_clients > 0) ? 0 : -1;
+  xres_state.xdisplay = xdisplay;
+  xres_state.hashtable_pid = g_hash_table_new_full (
+                                     wnck_gulong_hash,
+                                     wnck_gulong_equal,
+                                     wnck_pid_read_resource_usage_free_hash,
+                                     wnck_pid_read_resource_usage_free_hash);
+
+  xres_idleid = g_idle_add_full (
+                        G_PRIORITY_HIGH_IDLE,
+                        (GSourceFunc) wnck_pid_read_resource_usage_fill_cache,
+                        &xres_state, wnck_pid_read_resource_usage_xres_state_free);
+}
+
+static gboolean
+wnck_pid_read_resource_usage_destroy_hash_table (gpointer data)
+{
+  xres_removeid = 0;
+
+  if (xres_hashtable)
+    g_hash_table_destroy (xres_hashtable);
+
+  xres_hashtable = NULL;
+
+  return FALSE;
+}
+
+#define XRES_UPDATE_RATE_SEC 30
+static gboolean
+wnck_pid_read_resource_usage_from_cache (GdkDisplay        *gdisplay,
+                                         gulong             pid,
+                                         WnckResourceUsage *usage)
+{
+  gboolean  need_rebuild;
+  gulong   *xid_p;
+  int       cache_validity;
+
+  if (end_update == 0)
+    time (&end_update);
+
+  cache_validity = MAX (XRES_UPDATE_RATE_SEC, (end_update - start_update) * 2);
+
+  /* we rebuild the cache if it was never built or if it's old */
+  need_rebuild = (xres_hashtable == NULL ||
+                  (end_update < time (NULL) - cache_validity));
+
+  if (xres_hashtable)
+    {
+      /* clear the cache after quite some time, because it might not be used
+       * anymore */
+      if (xres_removeid != 0)
+        g_source_remove (xres_removeid);
+      xres_removeid = g_timeout_add_seconds (cache_validity * 2,
+                                             wnck_pid_read_resource_usage_destroy_hash_table,
+                                             NULL);
+    }
+
+  if (need_rebuild)
+    wnck_pid_read_resource_usage_start_build_cache (gdisplay);
+
+  if (xres_hashtable)
+    xid_p = g_hash_table_lookup (xres_hashtable, &pid);
+  else
+    xid_p = NULL;
+
+  if (xid_p)
+    {
+      wnck_xid_read_resource_usage (gdisplay, *xid_p, usage);
+      return TRUE;
+    }
+
+  return FALSE;
+}
+
+static void
+wnck_pid_read_resource_usage_no_cache (GdkDisplay        *gdisplay,
+                                       gulong             pid,
+                                       WnckResourceUsage *usage)
 {
   Display *xdisplay;
   int i;
 
-  /* FIXME to be fast and correct, we need to avoid the linear search and
-   * we should assume a process ID can have more than one X connection.
-   * So we would essentially want to maintain a map from process ID
-   * to the X resource base/mask, and query resources for the base/mask.
-   */
-  
   xdisplay = GDK_DISPLAY_XDISPLAY (gdisplay);
 
-  memset (usage, '\0', sizeof (*usage));
-  
   i = 0;
   while (i < ScreenCount (xdisplay))
     {
@@ -235,9 +567,64 @@
       ++i;
     }
 }
+#endif /* HAVE_XRES */
+
+/**
+ * wnck_pid_read_resource_usage:
+ * @gdk_display: a <classname>GdkDisplay</classname>.
+ * @pid: a process ID.
+ * @usage: return location for the X resource usage of the application with
+ * process ID @pid.
+ *
+ * Looks for the X resource usage of the application with process ID @pid on
+ * display @gdisplay. If no resource usage can be found, then all fields of
+ * @usage are set to 0.
+ *
+ * In order to find the resource usage of an application that does not have an
+ * X window visible to libwnck (panel applets do not have any toplevel windows,
+ * for example), wnck_pid_read_resource_usage() walks through the whole tree of
+ * X windows. Since this walk is expensive in CPU, a cache is created. This
+ * cache is updated in the background. This means there is a non-null
+ * probability that no resource usage will be found for an application, even if
+ * it is an X client. If this happens, calling wnck_pid_read_resource_usage()
+ * again after a few seconds should work.
+ *
+ * To properly work, this function requires the XRes extension on the X server.
+ *
+ * Since: 2.6
+ */
+void
+wnck_pid_read_resource_usage (GdkDisplay        *gdisplay,
+                              gulong             pid,
+                              WnckResourceUsage *usage)
+{
+  g_return_if_fail (usage != NULL);
+
+#ifndef HAVE_XRES
+  memset (usage, '\0', sizeof (*usage));
+  return;
+#else
+  memset (usage, '\0', sizeof (*usage));
+
+  if (!wnck_pid_read_resource_usage_from_cache (gdisplay, pid, usage))
+    /* the cache might not be built, might be outdated or might not contain
+     * data for a new X client, so try to fallback to something else */
+    wnck_pid_read_resource_usage_no_cache (gdisplay, pid, usage);
+#endif /* HAVE_XRES */
+}
 
 static WnckClientType client_type = 0;
 
+/**
+ * wnck_set_client_type:
+ * @ewmh_sourceindication_client_type: a role for the client.
+ *
+ * Sets the role of the libwnck user. For applications providing some window
+ * management features, like pagers or tasklists, it is important to set the
+ * role to %WNCK_CLIENT_TYPE_PAGER for libwnck to properly work.
+ *
+ * Since: 2.14
+ */
 void
 wnck_set_client_type (WnckClientType ewmh_sourceindication_client_type)
 {
@@ -320,3 +707,51 @@
       done = TRUE;
     }
 }
+
+/* stock icon code Copyright (C) 2002 Jorn Baayen <jorn@nl.linux.org> */
+typedef struct
+{
+  char *stock_id;
+  const guint8 *icon_data;
+} StockIcon;
+
+void
+_wnck_stock_icons_init (void)
+{
+  GtkIconFactory *factory;
+  int i;
+  static gboolean done = FALSE;
+
+  StockIcon items[] =
+  {
+    { WNCK_STOCK_DELETE,   stock_delete_data   },
+    { WNCK_STOCK_MINIMIZE, stock_minimize_data },
+    { WNCK_STOCK_MAXIMIZE, stock_maximize_data }
+  };
+
+  if (done)
+    return;
+
+  done = TRUE;
+  
+  factory = gtk_icon_factory_new ();
+  gtk_icon_factory_add_default (factory);
+
+  for (i = 0; i < (gint) G_N_ELEMENTS (items); i++)
+    {
+      GtkIconSet *icon_set;
+      GdkPixbuf *pixbuf;
+
+      pixbuf = gdk_pixbuf_new_from_inline (-1, items[i].icon_data,
+					   FALSE,
+					   NULL);
+
+      icon_set = gtk_icon_set_new_from_pixbuf (pixbuf);
+      gtk_icon_factory_add (factory, items[i].stock_id, icon_set);
+      gtk_icon_set_unref (icon_set);
+		
+      g_object_unref (G_OBJECT (pixbuf));
+    }
+
+  g_object_unref (G_OBJECT (factory));
+}
diff -Nur libwnck-2.19.3.1/libwnck/util.h libwnck-2.19.4/libwnck/util.h
--- libwnck-2.19.3.1/libwnck/util.h	2007-06-05 20:25:40.000000000 +0200
+++ libwnck-2.19.4/libwnck/util.h	2007-06-18 21:59:14.000000000 +0200
@@ -1,4 +1,5 @@
 /* util header */
+/* vim: set sw=2 et: */
 
 /*
  * Copyright (C) 2001 Havoc Pennington
@@ -25,11 +26,36 @@
 
 #include <gtk/gtk.h>
 
-typedef struct
+typedef struct _WnckResourceUsage WnckResourceUsage;
+
+/**
+ * WnckResourceUsage:
+ * @total_bytes_estimate: estimation of the total number of bytes allocated in
+ * the X server.
+ * @pixmap_bytes: number of bytes allocated in the X server for resources of
+ * type Pixmap.
+ * @n_pixmaps: number of Pixmap resources allocated.
+ * @n_windows: number of Window resources allocated.
+ * @n_gcs: number of GContext resources allocated.
+ * @n_pictures: number of Picture resources allocated.
+ * @n_glyphsets: number of Glyphset resources allocated.
+ * @n_fonts: number of Font resources allocated.
+ * @n_colormap_entries: number of Colormap resources allocated.
+ * @n_passive_grabs: number of PassiveGrab resources allocated.
+ * @n_cursors: number of Cursor resources allocated.
+ * @n_other: number of other resources allocated.
+ *
+ * The #WnckResourceUsage struct contains information about the total resource
+ * usage of an X client, and the number of resources allocated for each
+ * resource type.
+ *
+ * Since: 2.6
+ */
+struct _WnckResourceUsage
 {
-  unsigned long total_bytes_estimate;
+  gulong        total_bytes_estimate;
   
-  unsigned long pixmap_bytes;
+  gulong        pixmap_bytes;
 
   unsigned int n_pixmaps;
   unsigned int n_windows;
@@ -42,6 +68,7 @@
   unsigned int n_cursors;
   unsigned int n_other;
 
+  /*< private >*/
   unsigned int pad1;
   unsigned int pad2;
   unsigned int pad3;
@@ -51,26 +78,38 @@
   unsigned long pad7;
   unsigned long pad8;
   unsigned long pad9;
-  
-} WnckResourceUsage;
+};
 
+/**
+ * WnckClientType:
+ * @WNCK_CLIENT_TYPE_APPLICATION: the libwnck user is a normal application.
+ * @WNCK_CLIENT_TYPE_PAGER: the libwnck user is an utility application dealing
+ * with window management, like pagers and taskbars.
+ *
+ * Type describing the role of the libwnck user.
+ *
+ * Since: 2.14
+ */
 typedef enum {
   WNCK_CLIENT_TYPE_APPLICATION = 1,
   WNCK_CLIENT_TYPE_PAGER = 2
 } WnckClientType;
 
-void wnck_gtk_window_set_dock_type (GtkWindow *window);
-
 void wnck_set_client_type (WnckClientType ewmh_sourceindication_client_type);
 
 void wnck_xid_read_resource_usage (GdkDisplay        *gdk_display,
-                                   unsigned long      xid,
+                                   gulong             xid,
                                    WnckResourceUsage *usage);
 
 void wnck_pid_read_resource_usage (GdkDisplay        *gdk_display,
-                                   unsigned long      pid,
+                                   gulong             pid,
                                    WnckResourceUsage *usage);
 
+
+#ifndef WNCK_DISABLE_DEPRECATED
+void wnck_gtk_window_set_dock_type (GtkWindow *window);
+#endif /* WNCK_DISABLE_DEPRECATED */
+
 #endif /* WNCK_UTIL_H */
 
 
diff -Nur libwnck-2.19.3.1/libwnck/window-action-menu.c libwnck-2.19.4/libwnck/window-action-menu.c
--- libwnck-2.19.3.1/libwnck/window-action-menu.c	2007-06-05 20:25:40.000000000 +0200
+++ libwnck-2.19.4/libwnck/window-action-menu.c	2007-06-18 21:59:14.000000000 +0200
@@ -1,4 +1,5 @@
 /* window action menu (ops on a single window) */
+/* vim: set sw=2 et: */
 
 /*
  * Copyright (C) 2001 Havoc Pennington
@@ -28,6 +29,17 @@
 #include "window-action-menu.h"
 #include "private.h"
 
+/**
+ * SECTION:window-action-menu
+ * @short_description: context menu used to manipulate a window.
+ * @see_also: #WnckWindow
+ * @stability: Unstable
+ *
+ * These functions are related to the context menu that is usually used to
+ * manipulate a window (closing it, minimizing it, maximizing it, moving it to
+ * another workspace, etc.).
+ */
+
 typedef enum
 {
   CLOSE,
@@ -551,11 +563,12 @@
 
 /**
  * wnck_create_window_action_menu:
- * @window: a #WnckWindow
+ * @window: the #WnckWindow for which a menu will be created.
  * 
  * Creates a menu of window operations for @window.
  * 
- * Return value: a new menu of window operations
+ * Return value: a new GtkMenu, filled with menu items for window operations on
+ * @window.
  **/
 GtkWidget*
 wnck_create_window_action_menu (WnckWindow *window)
@@ -563,11 +576,13 @@
   GtkWidget *menu, *submenu;
   ActionMenuData *amd;
   GtkWidget *separator;
-  int num_workspaces, present_workspace, i;
+  int num_workspaces, window_space, i;
   WnckWorkspace *workspace;
   WnckWorkspaceLayout layout;
   GSList *pin_group;
 
+  g_return_val_if_fail (WNCK_IS_WINDOW (window), NULL);
+
   _wnck_stock_icons_init ();
   
   amd = g_new0 (ActionMenuData, 1);
@@ -637,13 +652,13 @@
   num_workspaces = wnck_screen_get_workspace_count (wnck_window_get_screen (amd->window));
 
   if (workspace)
-    present_workspace = wnck_workspace_get_number (workspace);
+    window_space = wnck_workspace_get_number (workspace);
   else
-    present_workspace = -1;
+    window_space = -1; //FIXME: this probably causes weird results. How to verify?
 
   wnck_screen_calc_workspace_layout (wnck_window_get_screen (amd->window),
                                      num_workspaces,
-                                     present_workspace,
+                                     window_space,
                                      &layout);
 
   if (!wnck_window_is_pinned (amd->window))
@@ -715,7 +730,7 @@
       item = make_menu_item (amd, MOVE_TO_WORKSPACE);
       g_object_set_data (G_OBJECT (item), "workspace", GINT_TO_POINTER (i));
 
-      if (i == present_workspace)
+      if (i == window_space)
         gtk_widget_set_sensitive (item, FALSE);
 
       gtk_menu_shell_append (GTK_MENU_SHELL (submenu), item);
diff -Nur libwnck-2.19.3.1/libwnck/window-action-menu.h libwnck-2.19.4/libwnck/window-action-menu.h
--- libwnck-2.19.3.1/libwnck/window-action-menu.h	2007-06-05 20:25:40.000000000 +0200
+++ libwnck-2.19.4/libwnck/window-action-menu.h	2007-06-18 21:59:14.000000000 +0200
@@ -1,4 +1,5 @@
 /* window action menu (ops on a single window) */
+/* vim: set sw=2 et: */
 
 /*
  * Copyright (C) 2001 Havoc Pennington
diff -Nur libwnck-2.19.3.1/libwnck/window.c libwnck-2.19.4/libwnck/window.c
--- libwnck-2.19.3.1/libwnck/window.c	2007-06-05 20:25:40.000000000 +0200
+++ libwnck-2.19.4/libwnck/window.c	2007-06-18 21:59:14.000000000 +0200
@@ -1,4 +1,5 @@
 /* window object */
+/* vim: set sw=2 et: */
 
 /*
  * Copyright (C) 2001 Havoc Pennington
@@ -33,6 +34,16 @@
 #include "wnck-enum-types.h"
 #include "wnck-marshal.h"
 
+/**
+ * SECTION:window
+ * @short_description: an object representing a window.
+ * @see_also: #WnckWorkspace, #WnckApplication, #WnckClassGroup
+ * @stability: Unstable
+ *
+ * The #WnckWindow objects are always owned by libwnck and must not be
+ * referenced or unreferenced.
+ */
+
 #define FALLBACK_NAME _("Untitled window")
 #define ALL_WORKSPACES (0xFFFFFFFF)
 
@@ -86,6 +97,11 @@
   int width;
   int height;
 
+  int left_frame;
+  int right_frame;
+  int top_frame;
+  int bottom_frame;
+
   char *startup_id;
 
   char *res_class;
@@ -134,11 +150,14 @@
   guint need_update_startup_id : 1;
   guint need_update_wmclass : 1;
   guint need_update_wmhints : 1;
+  guint need_update_frame_extents : 1;
 
   guint need_emit_name_changed : 1;
   guint need_emit_icon_changed : 1;
 };
 
+G_DEFINE_TYPE (WnckWindow, wnck_window, G_TYPE_OBJECT);
+
 enum {
   NAME_CHANGED,
   STATE_CHANGED,
@@ -174,6 +193,7 @@
 static void update_transient_for (WnckWindow *window);
 static void update_startup_id (WnckWindow *window);
 static void update_wmclass    (WnckWindow *window);
+static void update_frame_extents (WnckWindow *window);
 static void unqueue_update   (WnckWindow *window);
 static void queue_update     (WnckWindow *window);
 static void force_update_now (WnckWindow *window);
@@ -181,40 +201,8 @@
 static WnckWindow* find_last_transient_for (GList *windows,
                                             Window xwindow);
 
-static gpointer parent_class;
 static guint signals[LAST_SIGNAL] = { 0 };
 
-GType
-wnck_window_get_type (void)
-{
-  static GType object_type = 0;
-
-  g_type_init ();
-
-  if (!object_type)
-    {
-      const GTypeInfo object_info =
-      {
-        sizeof (WnckWindowClass),
-        (GBaseInitFunc) NULL,
-        (GBaseFinalizeFunc) NULL,
-        (GClassInitFunc) wnck_window_class_init,
-        NULL,           /* class_finalize */
-        NULL,           /* class_data */
-        sizeof (WnckWindow),
-        0,              /* n_preallocs */
-        (GInstanceInitFunc) wnck_window_init,
-        NULL            /* value_table */
-      };
-
-      object_type = g_type_register_static (G_TYPE_OBJECT,
-                                            "WnckWindow",
-                                            &object_info, 0);
-    }
-
-  return object_type;
-}
-
 static void
 wnck_window_init (WnckWindow *window)
 {
@@ -233,10 +221,14 @@
 {
   GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
-  parent_class = g_type_class_peek_parent (klass);
-
   object_class->finalize = wnck_window_finalize;
 
+  /**
+   * WnckWindow::name-changed:
+   * @window: the #WnckWindow which emitted the signal.
+   *
+   * Emitted when the name of @window changes.
+   */
   signals[NAME_CHANGED] =
     g_signal_new ("name_changed",
                   G_OBJECT_CLASS_TYPE (object_class),
@@ -246,6 +238,18 @@
                   g_cclosure_marshal_VOID__VOID,
                   G_TYPE_NONE, 0);
 
+  /**
+   * WnckWindow::state-changed:
+   * @window: the #WnckWindow which emitted the signal.
+   * @changed_mask: the bitmask containing bits set for all states of @window
+   * that have changed. 
+   * @new_state: the new state of @window.
+   *
+   * Emitted when the state of @window changes. This can happen when @window is
+   * (un)minimized, (un)maximized, (un)sticked, (un)shaded, (un)made above,
+   * (un)set fullscreen, when it needs attention, etc. See #WnckWindowState for
+   * the complete list of states that might have changed.
+   */
   signals[STATE_CHANGED] =
     g_signal_new ("state_changed",
                   G_OBJECT_CLASS_TYPE (object_class),
@@ -256,6 +260,13 @@
                   G_TYPE_NONE, 2,
                   WNCK_TYPE_WINDOW_STATE, WNCK_TYPE_WINDOW_STATE);
 
+  /**
+   * WnckWindow::workspace-changed:
+   * @window: the #WnckWindow which emitted the signal.
+   *
+   * Emitted when the current workspace of @window changes, or if @window has
+   * been pinned or unpinned.
+   */
   signals[WORKSPACE_CHANGED] =
     g_signal_new ("workspace_changed",
                   G_OBJECT_CLASS_TYPE (object_class),
@@ -265,6 +276,12 @@
                   g_cclosure_marshal_VOID__VOID,
                   G_TYPE_NONE, 0);
 
+  /**
+   * WnckWindow::icon-changed:
+   * @window: the #WnckWindow which emitted the signal.
+   *
+   * Emitted when the icon of @window changes.
+   */
   signals[ICON_CHANGED] =
     g_signal_new ("icon_changed",
                   G_OBJECT_CLASS_TYPE (object_class),
@@ -274,6 +291,15 @@
                   g_cclosure_marshal_VOID__VOID,
                   G_TYPE_NONE, 0);
 
+  /**
+   * WnckWindow::actions-changed:
+   * @window: the #WnckWindow which emitted the signal.
+   * @changed_mask: the bitmask containing bits set for all actions
+   * availabilities for @window that have changed. 
+   * @new_state: the new actions availabilities for @window.
+   *
+   * Emitted when the actions availabilities for @window change.
+   */
   signals[ACTIONS_CHANGED] =
     g_signal_new ("actions_changed",
                   G_OBJECT_CLASS_TYPE (object_class),
@@ -285,6 +311,12 @@
                   WNCK_TYPE_WINDOW_ACTIONS,
                   WNCK_TYPE_WINDOW_ACTIONS);
 
+  /**
+   * WnckWindow::geometry-changed:
+   * @window: the #WnckWindow which emitted the signal.
+   *
+   * Emitted when the geometry of @window changes.
+   */
   signals[GEOMETRY_CHANGED] =
     g_signal_new ("geometry_changed",
                   G_OBJECT_CLASS_TYPE (object_class),
@@ -324,18 +356,19 @@
 
   g_free (window->priv);
 
-  G_OBJECT_CLASS (parent_class)->finalize (object);
+  G_OBJECT_CLASS (wnck_window_parent_class)->finalize (object);
 }
 
 /**
  * wnck_window_get:
- * @xwindow: an Xlib window ID
+ * @xwindow: an X window ID.
  *
- * Gets a preexisting #WnckWindow for the X window @xwindow.
- * Will not create a #WnckWindow if none exists. Robust
- * against bogus window IDs.
+ * Returns a preexisting #WnckWindow for the X window @xwindow. This will not
+ * create a #WnckWindow if none exists. The function is robust against bogus
+ * window IDs.
  *
- * Return value: the #WnckWindow for this X window
+ * Return value: the #WnckWindow for @xwindow. The returned #WnckWindow is
+ * owned by libwnck and must not be referenced or unreferenced.
  **/
 WnckWindow*
 wnck_window_get (gulong xwindow)
@@ -348,11 +381,12 @@
 
 /**
  * wnck_window_get_screen:
- * @window: a #WnckWindow
+ * @window: a #WnckWindow.
  *
- * Gets the screen this window is on.
+ * Returns the #WnckScreen @window is on.
  *
- * Return value: a #WnckScreen
+ * Return value: the #WnckScreen @window is on. The returned #WnckScreen is
+ * owned by libwnck and must not be referenced or unreferenced.
  **/
 WnckScreen*
 wnck_window_get_screen (WnckWindow *window)
@@ -401,6 +435,10 @@
   window->priv->pid =
     _wnck_get_pid (window->priv->xwindow);
 
+  window->priv->x = 0;
+  window->priv->y = 0;
+  window->priv->width = 0;
+  window->priv->height = 0;
   _wnck_get_window_geometry (WNCK_SCREEN_XSCREEN (window->priv->screen),
 			     xwindow,
                              &window->priv->x,
@@ -421,6 +459,7 @@
   window->priv->need_update_startup_id = TRUE;
   window->priv->need_update_wmclass = TRUE;
   window->priv->need_update_wmhints = TRUE;
+  window->priv->need_update_frame_extents = TRUE;
   window->priv->need_emit_name_changed = FALSE;
   window->priv->need_emit_icon_changed = FALSE;
   force_update_now (window);
@@ -445,17 +484,19 @@
 
 /**
  * wnck_window_has_name:
- * @window: a #WnckWindow
+ * @window: a #WnckWindow.
  *
  * Checks whether or not @window has a name. wnck_window_get_name()
- * will always return some value, even if the window hasn't set a
- * name; wnck_window_has_name() can be used to tell if that name is
+ * will always return some value, even if @window has no name set;
+ * wnck_window_has_name() can be used to tell if that name is
  * real or not.
  *
  * For icons titles, use wnck_window_has_icon_name() instead.
  *
- * Return value: %TRUE if wnck_window_get_name() returns the window's
- * real name, %FALSE if it returns a fallback name.
+ * Return value: %TRUE if wnck_window_get_name() returns @window<!-- -->'s
+ * name, %FALSE if it returns a fallback name.
+ *
+ * Since: 2.16
  **/
 gboolean
 wnck_window_has_name (WnckWindow *window)
@@ -467,16 +508,17 @@
 
 /**
  * wnck_window_get_name:
- * @window: a #WnckWindow
+ * @window: a #WnckWindow.
  *
- * Gets the name of the window, as it should be displayed in a pager
- * or tasklist. Always returns some value, even if the window
- * hasn't set a name; use wnck_window_has_name() if you need to know
- * whether the returned name is "real" or not.
+ * Returns the name of @window, as it should be displayed in a pager
+ * or tasklist. Always returns some value, even if @window has no name
+ * set; use wnck_window_has_name() if you need to know whether the returned
+ * name is "real" or not.
  *
  * For icons titles, use wnck_window_get_icon_name() instead.
  *
- * Return value: name of the window
+ * Return value: the name of @window, or a fallback name if no name is
+ * available.
  **/
 const char*
 wnck_window_get_name (WnckWindow *window)
@@ -495,17 +537,19 @@
  *
  * Checks whether or not @window has an icon name.
  * wnck_window_get_icon_name() will always return some value, even if
- * the window hasn't set an icon name; wnck_window_has_icon_name() can
- * be used to tell if that name is real or not.
+ * @window has no icon name set; wnck_window_has_icon_name() can
+ * be used to tell if that icon name is real or not.
  *
  * (Note that if wnck_window_has_icon_name() returns %FALSE, but
  * wnck_window_has_name() returns %TRUE, then the name returned by
- * wnck_window_get_icon_name() is the window name. Only when both
+ * wnck_window_get_icon_name() is @window<!-- -->'s name. Only when both
  * methods return %FALSE does wnck_window_get_icon_name() return a
  * generic fallback name.)
  *
- * Return value: %TRUE if wnck_window_get_icon_name() returns the
- * window's real icon name, %FALSE if it returns a fallback name.
+ * Return value: %TRUE if wnck_window_get_icon_name() returns
+ * @window<!-- -->'s icon name, %FALSE if it returns a fallback name.
+ *
+ * Since: 2.16
  **/
 gboolean
 wnck_window_has_icon_name (WnckWindow *window)
@@ -519,13 +563,16 @@
  * wnck_window_get_icon_name:
  * @window: a #WnckWindow
  *
- * Gets the name of the window, as it should be displayed for an icon.
- * Always returns some value, even if the window hasn't set a name;
- * use wnck_window_has_icon_name() if you need to know if the name is
- * "real" or not. Contrast with wnck_window_get_name(), which returns
- * the window title, not the icon title.
+ * Returns the icon name of @window, as it should be displayed for an icon
+ * (minimized state). Always returns some value, even if @window has no icon
+ * name set; use wnck_window_has_icon_name() if you need to know whether the
+ * returned icon name is "real" or not.
  *
- * Return value: name of the window
+ * Contrast with wnck_window_get_name(), which returns @window<!-- -->'s
+ * title, not its icon title.
+ *
+ * Return value: the icon name of @window, or a fallback icon name if no icon
+ * name is available.
  **/
 const char*
 wnck_window_get_icon_name (WnckWindow *window)
@@ -540,6 +587,16 @@
     return FALLBACK_NAME;
 }
 
+/**
+ * wnck_window_get_application:
+ * @window: a #WnckWindow.
+ *
+ * Returns the #WnckApplication to which @window belongs.
+ *
+ * Return value: the #WnckApplication to which @window belongs. The returned
+ * #WnckApplication is owned by libwnck and must not be referenced or
+ * unreferenced.
+ **/
 WnckApplication*
 wnck_window_get_application  (WnckWindow *window)
 {
@@ -548,6 +605,17 @@
   return window->priv->app;
 }
 
+/**
+ * wnck_window_get_transient:
+ * @window: a #WnckWindow.
+ *
+ * Returns the #WnckWindow for which @window is transient.
+ *
+ * Return value: the #WnckWindow for which @window is transient, or %NULL if
+ * @window is not transient for any #WnckWindow.
+ *
+ * Since: 2.12
+ **/
 WnckWindow*
 wnck_window_get_transient (WnckWindow *window)
 {
@@ -556,6 +624,16 @@
   return wnck_window_get (window->priv->transient_for);
 }
 
+/**
+ * wnck_window_get_group_leader:
+ * @window: a #WnckWindow.
+ *
+ * Returns the group leader of the group of windows to which @window belongs.
+ *
+ * Return value: the group leader of the group of windows to which @window
+ * belongs, or the X window ID of @window if @window does not belong to any
+ * group.
+ **/
 gulong
 wnck_window_get_group_leader (WnckWindow *window)
 {
@@ -564,6 +642,14 @@
   return window->priv->group_leader;
 }
 
+/**
+ * wnck_window_get_xid:
+ * @window: a #WnckWindow.
+ *
+ * Returns the X window ID of @window.
+ *
+ * Return value: the X window ID of @window.
+ **/
 gulong
 wnck_window_get_xid (WnckWindow *window)
 {
@@ -572,6 +658,18 @@
   return window->priv->xwindow;
 }
 
+/**
+ * wnck_window_get_class_group:
+ * @window: a #WnckWindow.
+ *
+ * Returns the #WnckClassGroup to which @window belongs.
+ *
+ * Return value: the #WnckClassGroup to which @window belongs. The returned
+ * #WnckClassGroup is owned by libwnck and must not be referenced or
+ * unreferenced.
+ *
+ * Since: 2.2
+ **/
 WnckClassGroup *
 wnck_window_get_class_group (WnckWindow *window)
 {
@@ -582,14 +680,15 @@
 
 /**
  * wnck_window_get_session_id:
- * @window: a #WnckWindow
+ * @window: a #WnckWindow.
  *
- * Gets the session ID for @window in Latin-1 encoding.
+ * Returns the session ID for @window in Latin-1 encoding.
  * NOTE: this is invalid UTF-8. You can't display this
- * string in a GTK widget without converting to UTF-8.
+ * string in a GTK+ widget without converting to UTF-8.
  * See wnck_window_get_session_id_utf8().
  *
- * Return value: session ID in Latin-1
+ * Return value: the session ID for @window in Latin-1, or %NULL if @window has
+ * no session ID.
  **/
 const char*
 wnck_window_get_session_id (WnckWindow *window)
@@ -599,6 +698,18 @@
   return window->priv->session_id;
 }
 
+/**
+ * wnck_window_get_session_id_utf8:
+ * @window: a #WnckWindow.
+ *
+ * Returns the session ID for @window in UTF-8 encoding.
+ * The session ID should be in Latin-1 encoding, so the conversion should work,
+ * but a broken client could set a session ID that might not be convertable to
+ * UTF-8.
+ *
+ * Return value: the session ID for @window in UTF-8, or %NULL if @window has
+ * no session ID.
+ **/
 const char*
 wnck_window_get_session_id_utf8 (WnckWindow *window)
 {
@@ -627,11 +738,11 @@
 
 /**
  * wnck_window_get_pid:
- * @window: a #WnckWindow
+ * @window: a #WnckWindow.
  *
- * Gets the process ID of @window, if available.
+ * Returns the process ID of @window.
  *
- * Return value: PID of @window, or 0 if none available
+ * Return value: the process ID of @window, or 0 if none is available.
  **/
 int
 wnck_window_get_pid (WnckWindow *window)
@@ -643,12 +754,15 @@
 
 /**
  * wnck_window_get_sort_order:
- * @window: a #WnckWindow
+ * @window: a #WnckWindow.
+ *
+ * Returns the sort order of @window, used for ordering of @window in
+ * #WnckSelector and #WnckTasklist. The sort order is an internal state in
+ * libwnck. The initial value is defined when the window is created.
  *
- * Gets the sort order of @window; used for ordering of the window in
- * the tasklist.  The initial value is defined when the window is created.
+ * Return value: the sort order of @window, or G_MAXINT if none is available.
  *
- * Return value: sort order of @window, or G_MAXINT if none available
+ * Since: 2.10
  **/
 gint
 wnck_window_get_sort_order (WnckWindow *window)
@@ -660,12 +774,13 @@
 
 /**
  * wnck_window_set_sort_order:
- * @window: a #WnckWindow
- * @order: new order
+ * @window: a #WnckWindow.
+ * @order: new sort order for @window.
  *
- * Sets the sort order of @window; used for ordering of the window in
- * the tasklist. 
+ * Sets the sort order of @window. The sort order is used for ordering of
+ * @window in #WnckSelector and #WnckTasklist.
  *
+ * Since: 2.20
  **/
 void        wnck_window_set_sort_order        (WnckWindow *window, 
 					       gint order)
@@ -678,15 +793,16 @@
 
 /**
  * wnck_window_get_window_type:
- * @window: a #WnckWindow
+ * @window: a #WnckWindow.
  * 
- * Retrieves the semantic type of the window.
+ * Returns the semantic type of @window.
  * 
- * Return value: semantic type
+ * Return value: the semantic type of @window.
  **/
 WnckWindowType
 wnck_window_get_window_type (WnckWindow *window)
 {
+  /* FIXME: should we have an invalid window type for this? */
   g_return_val_if_fail (WNCK_IS_WINDOW (window), 0);
   
   return window->priv->wintype;
@@ -694,11 +810,12 @@
 
 /**
  * wnck_window_set_window_type:
- * @window: a #WnckWindow
- * @wintype: the #WnckWindowType type hint
- * 
- * Sets the semantic type of the window.
+ * @window: a #WnckWindow.
+ * @wintype: a semantic type.
  * 
+ * Sets the semantic type of @window to @wintype.
+ *
+ * Since: 2.12
  **/
 void
 wnck_window_set_window_type (WnckWindow *window, WnckWindowType wintype)
@@ -748,12 +865,12 @@
 
 /**
  * wnck_window_is_minimized:
- * @window: a #WnckWindow
+ * @window: a #WnckWindow.
  *
- * If the window is minimized returns %TRUE. Minimization state
- * may change anytime a state_changed signal gets emitted.
+ * Returns whether @window is minimized. Minimization state may change anytime
+ * a #WnckWindow::state-changed signal gets emitted.
  *
- * Return value: %TRUE if window is minimized
+ * Return value: %TRUE if @window is minimized, %FALSE otherwise.
  **/
 gboolean
 wnck_window_is_minimized (WnckWindow *window)
@@ -765,13 +882,17 @@
 
 /**
  * wnck_window_needs_attention:
- * @window: a #WnckWindow
+ * @window: a #WnckWindow.
+ *
+ * Returns whether @window needs attention. This state may change anytime
+ * a #WnckWindow::state-changed signal gets emitted.
  *
- * If the window needs attention returns %TRUE. This state may change
- * anytime a state_changed signal gets emitted, as it can depend on flags
- * such as the demands_attention and is_urgent hints.
+ * This state depends on flags such as the demands_attention and is_urgent
+ * hints.
  *
- * Return value: %TRUE if window needs attention
+ * Return value: %TRUE if @window needs attention, %FALSE otherwise.
+ *
+ * Since: 2.12
  **/
 gboolean
 wnck_window_needs_attention (WnckWindow *window)
@@ -809,12 +930,15 @@
 
 /**
  * wnck_window_or_transient_needs_attention:
- * @window: a #WnckWindow
+ * @window: a #WnckWindow.
  *
- * If the window or one of its transients needs attention returns %TRUE.
- * This state may change anytime a state_changed signal gets emitted.
+ * Returns whether @window or one of its transients needs attention. This state
+ * may change anytime a #WnckWindow::state-changed signal gets emitted.
  *
- * Return value: %TRUE if window or one of its transients needs attention
+ * Return value: %TRUE if @window or one of its transients needs attention,
+ * %FALSE otherwise.
+ *
+ * Since: 2.12
  **/
 gboolean
 wnck_window_or_transient_needs_attention (WnckWindow *window)
@@ -823,6 +947,15 @@
          transient_needs_attention (window);
 }
 
+/**
+ * wnck_window_is_maximized_horizontally:
+ * @window: a #WnckWindow.
+ *
+ * Returns whether @window is maximized horizontally. Horizontal maximization
+ * state may change anytime a #WnckWindow::state-changed signal gets emitted.
+ *
+ * Return value: %TRUE if @window is maximized horizontally, %FALSE otherwise.
+ **/
 gboolean
 wnck_window_is_maximized_horizontally (WnckWindow *window)
 {
@@ -831,6 +964,15 @@
   return window->priv->is_maximized_horz;
 }
 
+/**
+ * wnck_window_is_maximized_vertically:
+ * @window: a #WnckWindow.
+ *
+ * Returns whether @window is maximized vertically. vertiVal maximization
+ * state may change anytime a #WnckWindow::state-changed signal gets emitted.
+ *
+ * Return value: %TRUE if @window is maximized vertically, %FALSE otherwise.
+ **/
 gboolean
 wnck_window_is_maximized_vertically   (WnckWindow *window)
 {
@@ -880,12 +1022,17 @@
 
 /**
  * wnck_window_is_maximized:
- * @window: a #WnckWindow
+ * @window: a #WnckWindow.
+ *
+ * Returns whether @window is maximized. Maximization state may change
+ * anytime a #WnckWindow::state-changed signal gets emitted.
  *
- * As for GDK, "maximized" means both vertically and horizontally.
- * If only one, then the window isn't considered maximized.
+ * As for GDK, "maximized" means both vertically and horizontally. If @window
+ * is maximized in only one direction, then @window is not considered
+ * maximized.
  *
- * Return value: %TRUE if the window is maximized in both directions
+ * Return value: %TRUE if @window is maximized in both directions, %FALSE
+ * otherwise.
  **/
 gboolean
 wnck_window_is_maximized (WnckWindow *window)
@@ -897,6 +1044,15 @@
     window->priv->is_maximized_vert;
 }
 
+/**
+ * wnck_window_is_shaded:
+ * @window: a #WnckWindow.
+ *
+ * Returns whether @window is shaded. Shade state may change anytime
+ * a #WnckWindow::state-changed signal gets emitted.
+ *
+ * Return value: %TRUE if @window is shaded, %FALSE otherwise.
+ **/
 gboolean
 wnck_window_is_shaded                 (WnckWindow *window)
 {
@@ -905,6 +1061,19 @@
   return window->priv->is_shaded;
 }
 
+/**
+ * wnck_window_is_above:
+ * @window: a #WnckWindow.
+ *
+ * Returns whether @window is above other windows. This state may change
+ * anytime a #WnckWindow::state-changed signal gets emitted.
+ *
+ * See wnck_window_make_above() for more details on this state.
+ *
+ * Return value: %TRUE if @window is above other windows, %FALSE otherwise.
+ *
+ * Since: 2.14
+ **/
 gboolean
 wnck_window_is_above                  (WnckWindow *window)
 {
@@ -913,6 +1082,15 @@
   return window->priv->is_above;
 }
 
+/**
+ * wnck_window_is_skip_pager:
+ * @window: a #WnckWindow.
+ *
+ * Returns whether @window is included on pagers. This state may change
+ * anytime a #WnckWindow::state-changed signal gets emitted.
+ *
+ * Return value: %TRUE if @window is included on pagers, %FALSE otherwise.
+ **/
 gboolean
 wnck_window_is_skip_pager             (WnckWindow *window)
 {
@@ -921,6 +1099,13 @@
   return window->priv->skip_pager;
 }
 
+/**
+ * wnck_window_set_skip_pager:
+ * @window: a #WnckWindow.
+ * @skip: whether @window should be included on pagers.
+ *
+ * Asks the window manager to make @window included or not included on pagers.
+ **/
 void
 wnck_window_set_skip_pager (WnckWindow *window,
                             gboolean skip)
@@ -933,6 +1118,15 @@
                       0);
 }
 
+/**
+ * wnck_window_is_skip_tasklist:
+ * @window: a #WnckWindow.
+ *
+ * Returns whether @window is included on tasklists. This state may change
+ * anytime a #WnckWindow::state-changed signal gets emitted.
+ *
+ * Return value: %TRUE if @window is included on tasklists, %FALSE otherwise.
+ **/
 gboolean
 wnck_window_is_skip_tasklist          (WnckWindow *window)
 {
@@ -941,6 +1135,17 @@
   return window->priv->skip_taskbar;
 }
 
+/**
+ * wnck_window_is_fullscreen:
+ * @window: a #WnckWindow.
+ *
+ * Returns whether @window is fullscreen. Fullscreen state may change
+ * anytime a #WnckWindow::state-changed signal gets emitted.
+ *
+ * Return value: %TRUE if @window is fullscreen, %FALSE otherwise.
+ *
+ * Since: 2.8
+ **/
 gboolean
 wnck_window_is_fullscreen                 (WnckWindow *window)
 {
@@ -949,6 +1154,14 @@
   return window->priv->is_fullscreen;
 }
 
+/**
+ * wnck_window_set_skip_tasklist:
+ * @window: a #WnckWindow.
+ * @skip: whether @window should be included on tasklists.
+ *
+ * Asks the window manager to make @window included or not included on
+ * tasklists.
+ **/
 void
 wnck_window_set_skip_tasklist (WnckWindow *window,
                                gboolean skip)
@@ -961,6 +1174,16 @@
                       0);
 }
 
+/**
+ * wnck_window_set_fullscreen:
+ * @window: a #WnckWindow.
+ * @fullscreen: whether to make @window fullscreen.
+ *
+ * Asks the window manager to set the fullscreen state of @window according to
+ * @fullscreen.
+ *
+ * Since: 2.8
+ **/
 void
 wnck_window_set_fullscreen (WnckWindow *window,
                                gboolean fullscreen)
@@ -975,15 +1198,17 @@
 
 /**
  * wnck_window_is_sticky:
- * @window: a #WnckWindow
+ * @window: a #WnckWindow.
+ *
+ * Returns whether @window is sticky. Sticky state may change
+ * anytime a #WnckWindow::state-changed signal gets emitted.
  *
- * Sticky here means "stuck to the glass," i.e. does not scroll with
- * the viewport. In GDK/GTK,
- * e.g. gdk_window_stick()/gtk_window_stick(), sticky means stuck to
- * the glass and _also_ that the window is on all workspaces.
- * But here it only means the viewport aspect of it.
+ * Sticky here means "stuck to the glass", i.e. does not scroll with the
+ * viewport. In GDK/GTK+ (e.g. gdk_window_stick()/gtk_window_stick()), sticky
+ * means "stuck to the glass" and <emphasis>also</emphasis> that the window is
+ * on all workspaces. But here it only means the viewport aspect of it.
  *
- * Return value: %TRUE if the window is "stuck to the glass"
+ * Return value: %TRUE if @window is "stuck to the glass", %FALSE otherwise.
  **/
 gboolean
 wnck_window_is_sticky                 (WnckWindow *window)
@@ -993,6 +1218,16 @@
   return window->priv->is_sticky;
 }
 
+/**
+ * wnck_window_close:
+ * @window: a #WnckWindow.
+ * @timestamp: the X server timestamp of the user interaction event that caused
+ * this call to occur.
+ *
+ * Closes @window.
+ *
+ * Since: 2.6 (@timestamp argument was missing in earlier versions)
+ **/
 void
 wnck_window_close (WnckWindow *window,
 		   guint32     timestamp)
@@ -1003,6 +1238,12 @@
 	       window->priv->xwindow, timestamp);
 }
 
+/**
+ * wnck_window_minimize:
+ * @window: a #WnckWindow.
+ *
+ * Minimizes @window.
+ **/
 void
 wnck_window_minimize                (WnckWindow *window)
 {
@@ -1011,6 +1252,15 @@
   _wnck_iconify (window->priv->xwindow);
 }
 
+/**
+ * wnck_window_unminimize:
+ * @window: a #WnckWindow.
+ * @timestamp: the X server timestamp of the user interaction event that caused
+ * this call to occur.
+ *
+ * Unminimizes @window by activating it or one of its transients. See
+ * wnck_window_activate_transient() for details on how the activation is done.
+ **/
 void
 wnck_window_unminimize              (WnckWindow *window,
                                      guint32     timestamp)
@@ -1020,6 +1270,12 @@
   wnck_window_activate_transient (window, timestamp);
 }
 
+/**
+ * wnck_window_maximize:
+ * @window: a #WnckWindow.
+ *
+ * Asks the window manager to maximize @window.
+ **/
 void
 wnck_window_maximize                (WnckWindow *window)
 {
@@ -1032,6 +1288,12 @@
                       _wnck_atom_get ("_NET_WM_STATE_MAXIMIZED_HORZ"));
 }
 
+/**
+ * wnck_window_unmaximize:
+ * @window: a #WnckWindow.
+ *
+ * Asks the window manager to unmaximize @window.
+ **/
 void
 wnck_window_unmaximize              (WnckWindow *window)
 {
@@ -1044,6 +1306,12 @@
                       _wnck_atom_get ("_NET_WM_STATE_MAXIMIZED_HORZ"));
 }
 
+/**
+ * wnck_window_maximize_horizontally:
+ * @window: a #WnckWindow.
+ *
+ * Asks the window manager to maximize horizontally @window.
+ **/
 void
 wnck_window_maximize_horizontally   (WnckWindow *window)
 {
@@ -1056,6 +1324,12 @@
                       0);
 }
 
+/**
+ * wnck_window_unmaximize_horizontally:
+ * @window: a #WnckWindow.
+ *
+ * Asks the window manager to unmaximize horizontally @window.
+ **/
 void
 wnck_window_unmaximize_horizontally (WnckWindow *window)
 {
@@ -1068,6 +1342,12 @@
                       0);
 }
 
+/**
+ * wnck_window_maximize_vertically:
+ * @window: a #WnckWindow.
+ *
+ * Asks the window manager to maximize vertically @window.
+ **/
 void
 wnck_window_maximize_vertically     (WnckWindow *window)
 {
@@ -1080,6 +1360,12 @@
                       0);
 }
 
+/**
+ * wnck_window_unmaximize_vertically:
+ * @window: a #WnckWindow.
+ *
+ * Asks the window manager to unmaximize vertically @window.
+ **/
 void
 wnck_window_unmaximize_vertically   (WnckWindow *window)
 {
@@ -1092,6 +1378,12 @@
                       0);
 }
 
+/**
+ * wnck_window_shade:
+ * @window: a #WnckWindow.
+ *
+ * Asks the window manager to shade @window.
+ **/
 void
 wnck_window_shade                   (WnckWindow *window)
 {
@@ -1104,6 +1396,12 @@
                       0);
 }
 
+/**
+ * wnck_window_unshade:
+ * @window: a #WnckWindow.
+ *
+ * Asks the window manager to unshade @window.
+ **/
 void
 wnck_window_unshade                 (WnckWindow *window)
 {
@@ -1116,6 +1414,16 @@
                       0);
 }
 
+/**
+ * wnck_window_make_above:
+ * @window: a #WnckWindow.
+ *
+ * Asks the window manager to put @window on top of most windows (@window will
+ * not be on top of focused fullscreen windows, of other windows with this
+ * setting and of dock windows).
+ *
+ * Since: 2.14
+ **/
 void
 wnck_window_make_above (WnckWindow *window)
 {
@@ -1128,6 +1436,15 @@
                       0);
 }
 
+/**
+ * wnck_window_unmake_above:
+ * @window: a #WnckWindow.
+ *
+ * Asks the window manager to not put @window on top of most windows, and to
+ * put it again in the stack with other windows.
+ *
+ * Since: 2.14
+ **/
 void
 wnck_window_unmake_above (WnckWindow *window)
 {
@@ -1140,6 +1457,13 @@
                       0);
 }
 
+/**
+ * wnck_window_stick:
+ * @window: a #WnckWindow.
+ *
+ * Asks the window manager to keep the @window<!-- -->'s position fixed on the
+ * screen, even when the workspace or viewport scrolls.
+ **/
 void
 wnck_window_stick                   (WnckWindow *window)
 {
@@ -1152,6 +1476,13 @@
                       0);
 }
 
+/**
+ * wnck_window_unstick:
+ * @window: a #WnckWindow.
+ *
+ * Asks the window manager to not have @window<!-- -->'s position fixed on the
+ * screen when the workspace or viewport scrolls.
+ **/
 void
 wnck_window_unstick                 (WnckWindow *window)
 {
@@ -1164,6 +1495,12 @@
                       0);
 }
 
+/**
+ * wnck_window_keyboard_move:
+ * @window: a #WnckWindow.
+ *
+ * Asks the window manager to start moving @window via keyboard.
+ **/
 void
 wnck_window_keyboard_move (WnckWindow *window)
 {
@@ -1173,6 +1510,12 @@
                        window->priv->xwindow);
 }
 
+/**
+ * wnck_window_keyboard_size:
+ * @window: a #WnckWindow.
+ *
+ * Asks the window manager to start resizing @window via keyboard.
+ **/
 void
 wnck_window_keyboard_size (WnckWindow *window)
 {
@@ -1184,23 +1527,35 @@
 
 /**
  * wnck_window_get_workspace:
- * @window: a #WnckWindow
+ * @window: a #WnckWindow.
  *
- * Gets the window's current workspace. If the window is
- * pinned (on all workspaces), or not on any workspaces,
- * %NULL may be returned.
+ * Returns the current workspace @window is on. If the window is pinned (on all
+ * workspaces), or not on any workspaces, %NULL may be returned.
  *
- * Return value: single current workspace or %NULL
+ * Return value: the single current workspace @window is on, or %NULL. The
+ * returned #WnckWorkspace is owned by libwnck and must not be referenced or
+ * unreferenced.
  **/
 WnckWorkspace*
 wnck_window_get_workspace (WnckWindow *window)
 {
+  g_return_val_if_fail (WNCK_IS_WINDOW (window), NULL);
+
   if (window->priv->workspace == ALL_WORKSPACES)
     return NULL;
   else
     return wnck_screen_get_workspace (window->priv->screen, window->priv->workspace);
 }
 
+/**
+ * wnck_window_move_to_workspace:
+ * @window: a #WnckWindow.
+ * @space: a #WnckWorkspace.
+ *
+ * Asks the window manager to move @window to @space.
+ *
+ * FIXME: what happens if @window is pinned?
+ **/
 void
 wnck_window_move_to_workspace (WnckWindow    *window,
                                WnckWorkspace *space)
@@ -1215,13 +1570,13 @@
 
 /**
  * wnck_window_is_pinned:
- * @window: a #WnckWindow
+ * @window: a #WnckWindow.
  *
- * %TRUE if the window is on all workspaces. Note that if this
- * changes, it's signalled by a workspace_changed signal,
- * not state_changed.
+ * Returns whether @window is on all workspace. Pinned state may change
+ * anytime a #WnckWindow::workspace-changed signal gets emitted, but not when
+ * a #WnckWindow::state-changed gets emitted.
  *
- * Return value: %TRUE if on all workspaces
+ * Return value: %TRUE if @window is on all workspaces, %FALSE otherwise.
  **/
 gboolean
 wnck_window_is_pinned (WnckWindow *window)
@@ -1231,6 +1586,12 @@
   return window->priv->workspace == ALL_WORKSPACES;
 }
 
+/**
+ * wnck_window_pin:
+ * @window: a #WnckWindow.
+ *
+ * Asks the window manager to put @window on all workspaces.
+ **/
 void
 wnck_window_pin (WnckWindow *window)
 {
@@ -1243,14 +1604,13 @@
 
 /**
  * wnck_window_unpin:
- * @window: a #WnckWindow
- *
- * Sets @window's workspace to only the currently active workspace,
- * if the window was previously pinned. If the window wasn't pinned,
- * doesn't change the window's workspace. If the active workspace
- * isn't known for some reason (shouldn't happen much), sets the
- * window's workspace to 0.
+ * @window: a #WnckWindow.
  *
+ * Asks the window manager to put @window only in the currently active
+ * workspace, if @window was previously pinned. If @window was not pinned,
+ * does not change @window<!-- -->'s workspace. If the active workspace
+ * is not known for some reason (it should not happen much), sets
+ * @window<!-- -->'s workspace to the first workspace.
  **/
 void
 wnck_window_unpin (WnckWindow *window)
@@ -1271,12 +1631,16 @@
 
 /**
  * wnck_window_activate:
- * @window: a #WnckWindow
- * @timestamp: the X server timestamp of the user interaction event that
- *             caused this call to occur
+ * @window: a #WnckWindow.
+ * @timestamp: the X server timestamp of the user interaction event that caused
+ * this call to occur.
+ *
+ * Asks the window manager to make @window the active window. The
+ * window manager may choose to raise @window along with focusing it, and may
+ * decide to refuse the request (to not steal the focus if there is a more
+ * recent user activity, for example).
  *
- * Ask the window manager to make @window the active window.  The
- * window manager may choose to raise @window along with focusing it.
+ * Since: 2.10 (@timestamp argument was missing in earlier versions)
  **/
 void
 wnck_window_activate (WnckWindow *window,
@@ -1291,11 +1655,12 @@
 
 /**
  * wnck_window_is_active:
- * @window: a #WnckWindow
- *
+ * @window: a #WnckWindow.
  *
+ * Returns whether @window is the active window on its #WnckScreen.
  *
- * Return value: %TRUE if the window is the active window
+ * Return value: %TRUE if @window is the active window on its #WnckScreen,
+ * %FALSE otherwise.
  **/
 gboolean
 wnck_window_is_active (WnckWindow *window)
@@ -1307,15 +1672,20 @@
 
 /**
  * wnck_window_is_most_recently_activated:
- * @window: a #WnckWindow
+ * @window: a #WnckWindow.
+ *
+ * Returns whether @window is the most recently activated window on its
+ * #WnckScreen.
  *
- * Determines whether @window is the most recently activated window.
  * The most recently activated window is identical to the active
  * window for click and sloppy focus methods (since a window is always
  * active in those cases) but differs slightly for mouse focus since
- * we often have no window active.
+ * there often is no active window.
  *
- * Return value: %TRUE if window was the most recently activated window
+ * Return value: %TRUE if @window was the most recently activated window on its
+ * #WnckScreen, %FALSE otherwise.
+ *
+ * Since: 2.8
  **/
 gboolean
 wnck_window_is_most_recently_activated (WnckWindow *window)
@@ -1365,9 +1735,9 @@
 
 /**
  * wnck_window_activate_transient:
- * @window: a #WnckWindow
- * @timestamp: the X server timestamp of the user interaction event that
- *             caused this call to occur
+ * @window: a #WnckWindow.
+ * @timestamp: the X server timestamp of the user interaction event that caused
+ * this call to occur.
  *
  * If @window has transients, activates the most likely transient
  * instead of the window itself. Otherwise activates @window.
@@ -1376,6 +1746,7 @@
  * the most recently active window among @window and its transients.
  * This is probably best implemented on the window manager side.
  * 
+ * Since: 2.10 (@timestamp argument was missing in earlier versions)
  **/
 void
 wnck_window_activate_transient (WnckWindow *window,
@@ -1414,19 +1785,23 @@
 
 /**
  * wnck_window_transient_is_most_recently_activated:
- * @window: a #WnckWindow
+ * @window: a #WnckWindow.
  *
- * Return whether one of the transients of @window is the most
- * recently activated window.  See
+ * Returns whether one of the transients of @window is the most
+ * recently activated window. See
  * wnck_window_is_most_recently_activated() for a more complete
  * description of what is meant by most recently activated.  This
- * function is needed because clicking on the tasklist once will
- * activate a transient instead of the window itself
+ * function is needed because clicking on a #WnckTasklist once will
+ * activate a transient instead of @window itself
  * (wnck_window_activate_transient), and clicking again should
- * minimize the window and it's transients.  (Not doing this can be
+ * minimize @window and its transients.  (Not doing this can be
  * especially annoying in the case of modal dialogs that don't appear
- * in the tasklist).
+ * in the #WnckTaslist).
  * 
+ * Return value: %TRUE if one of the transients of @window is the most recently
+ * activated window, %FALSE otherwise.
+ *
+ * Since: 2.12
  **/
 gboolean
 wnck_window_transient_is_most_recently_activated (WnckWindow *window)
@@ -1434,8 +1809,7 @@
   GList *windows;
   WnckWindow *transient;
   
-  if (!WNCK_IS_WINDOW (window))
-    return FALSE;
+  g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE);
 
   windows = wnck_screen_get_windows_stacked (window->priv->screen);
 
@@ -1486,6 +1860,18 @@
             !(window->priv->icon || window->priv->mini_icon));
 }
 
+/**
+ * wnck_window_get_icon:
+ * @window: a #WnckWindow.
+ * 
+ * Returns the icon to be used for @window. If no icon was found, a fallback
+ * icon is used. wnck_window_get_icon_is_fallback() can be used to tell if the
+ * icon is the fallback icon. 
+ * 
+ * Return value: the icon for @window. The caller should reference the
+ * returned <classname>GdkPixbuf</classname> if it needs to keep the icon
+ * around.
+ **/
 GdkPixbuf*
 wnck_window_get_icon (WnckWindow *window)
 {
@@ -1500,6 +1886,18 @@
   return window->priv->icon;
 }
 
+/**
+ * wnck_window_get_mini_icon:
+ * @window: a #WnckWindow.
+ * 
+ * Returns the mini-icon to be used for @window. If no mini-icon was found, a
+ * fallback mini-icon is used. wnck_window_get_icon_is_fallback() can be used
+ * to tell if the mini-icon is the fallback mini-icon. 
+ * 
+ * Return value: the mini-icon for @window. The caller should reference the
+ * returned <classname>GdkPixbuf</classname> if it needs to keep the icon
+ * around.
+ **/
 GdkPixbuf*
 wnck_window_get_mini_icon (WnckWindow *window)
 {
@@ -1516,12 +1914,12 @@
 
 /**
  * wnck_window_get_icon_is_fallback:
- * @window: a #WnckWindow
+ * @window: a #WnckWindow.
  *
- * Checks if we are using a default fallback icon because
- * none was set on the window.
+ * Returns whether a default fallback icon is used for @window (because none
+ * was set on @window).
  * 
- * Return value: %TRUE if icon is a fallback
+ * Return value: %TRUE if the icon for @window is a fallback, %FALSE otherwise.
  **/
 gboolean
 wnck_window_get_icon_is_fallback (WnckWindow *window)
@@ -1533,11 +1931,11 @@
 
 /**
  * wnck_window_get_actions:
- * @window: a #WnckWindow
+ * @window: a #WnckWindow.
  * 
- * Gets the window operations that should be sensitive for @window.
+ * Returns the actions that can be done for @window.
  * 
- * Return value: bitmask of actions the window supports
+ * Return value: bitmask of actions that can be done for @window.
  **/
 WnckWindowActions
 wnck_window_get_actions (WnckWindow *window)
@@ -1550,11 +1948,11 @@
 
 /**
  * wnck_window_get_state:
- * @window: a #WnckWindow
+ * @window: a #WnckWindow.
  * 
- * Gets the state of a window as a bitmask.
+ * Returns the state of @window.
  * 
- * Return value: bitmask of active state flags.
+ * Return value: bitmask of active states for @window.
  **/
 WnckWindowState
 wnck_window_get_state (WnckWindow *window)
@@ -1565,18 +1963,60 @@
 }
 
 /**
- * wnck_window_get_geometry:
- * @window: a #WnckWindow
- * @xp: return location for X coordinate of window 
- * @yp: return location for Y coordinate of window
- * @widthp: return location for width of window
- * @heightp: return location for height of window
+ * wnck_window_get_client_window_geometry:
+ * @window: a #WnckWindow.
+ * @xp: return location for X coordinate in pixels of @window.
+ * @yp: return location for Y coordinate in pixels of @window.
+ * @widthp: return location for width in pixels of @window.
+ * @heightp: return location for height in pixels of @window.
  *
- * Gets the size and position of the window, as last received
- * in a configure notify (i.e. this call does not round-trip
+ * Gets the size and position of @window, as last received
+ * in a ConfigureNotify event (i.e. this call does not round-trip
  * to the server, just gets the last size we were notified of).
  * The X and Y coordinates are relative to the root window.
- * 
+ *
+ * The window manager usually adds a frame around windows. If
+ * you need to know the size of @window with the frame, use
+ * wnck_window_get_geometry().
+ *
+ * Since: 2.20
+ **/
+void
+wnck_window_get_client_window_geometry (WnckWindow *window,
+                                        int        *xp,
+					int        *yp,
+					int        *widthp,
+					int        *heightp)
+{
+  g_return_if_fail (WNCK_IS_WINDOW (window));
+
+  if (xp)
+    *xp = window->priv->x;
+  if (yp)
+    *yp = window->priv->y;
+  if (widthp)
+    *widthp = window->priv->width;
+  if (heightp)
+    *heightp = window->priv->height;
+}
+
+/**
+ * wnck_window_get_geometry:
+ * @window: a #WnckWindow.
+ * @xp: return location for X coordinate in pixels of @window.
+ * @yp: return location for Y coordinate in pixels of @window.
+ * @widthp: return location for width in pixels of @window.
+ * @heightp: return location for height in pixels of @window.
+ *
+ * Gets the size and position of @window, including decorations. This
+ * function uses the information last received in a ConfigureNotify
+ * event and adjusts it according to the size of the frame that is
+ * added by the window manager (this call does not round-trip to the
+ * server, it just gets the last sizes that were notified). The
+ * X and Y coordinates are relative to the root window.
+ *
+ * If you need to know the actual size of @window ignoring the frame
+ * added by the window manager, use wnck_window_get_client_window_geometry().
  **/
 void
 wnck_window_get_geometry (WnckWindow *window,
@@ -1588,27 +2028,36 @@
   g_return_if_fail (WNCK_IS_WINDOW (window));
 
   if (xp)
-    *xp = window->priv->x;
+    *xp = window->priv->x - window->priv->left_frame;
   if (yp)
-    *yp = window->priv->y;
+    *yp = window->priv->y - window->priv->top_frame;
   if (widthp)
-    *widthp = window->priv->width;
+    *widthp = window->priv->width + window->priv->left_frame + window->priv->right_frame;
   if (heightp)
-    *heightp = window->priv->height;
+    *heightp = window->priv->height + window->priv->top_frame + window->priv->bottom_frame;
 }
 
 /**
  * wnck_window_set_geometry:
- * @window: a #WnckWindow
- * @gravity: one of #WnckWindowGravity
- * @geometry_mask: a mask of #WnckWindowMoveResizeMask
- * @x: new X coordinate of window
- * @y: new Y coordinate of window
- * @width: new width of window
- * @height: new height of window
- *
- * Sets the size and position of the window.
+ * @window: a #WnckWindow.
+ * @gravity: the gravity point to use as a reference for the new position.
+ * @geometry_mask: a bitmask containing flags for what should be set.
+ * @x: new X coordinate in pixels of @window.
+ * @y: new Y coordinate in pixels of @window.
+ * @width: new width in pixels of @window.
+ * @height: new height in pixels of @window.
+ *
+ * Sets the size and position of @window. The X and Y coordinates should be
+ * relative to the root window.
+ *
+ * Note that the new size and position apply to @window with its frame added
+ * by the window manager. Therefore, using wnck_window_set_geometry() with
+ * the values returned by wnck_window_get_geometry() should be a no-op, while
+ * using wnck_window_set_geometry() with the values returned by
+ * wnck_window_get_client_window_geometry() should reduce the size of @window
+ * and move it.
  *
+ * Since: 2.16
  **/
 void
 wnck_window_set_geometry (WnckWindow               *window,
@@ -1636,13 +2085,14 @@
 
 /**
  * wnck_window_is_visible_on_workspace:
- * @window: a #WnckWindow
- * @workspace: a #WnckWorkspace
+ * @window: a #WnckWindow.
+ * @workspace: a #WnckWorkspace.
  * 
  * Like wnck_window_is_on_workspace(), but also checks that
  * the window is in a visible state (i.e. not minimized or shaded).
  * 
- * Return value: %TRUE if @window appears on @workspace in normal state
+ * Return value: %TRUE if @window appears on @workspace in normal state, %FALSE
+ * otherwise.
  **/
 gboolean
 wnck_window_is_visible_on_workspace (WnckWindow    *window,
@@ -1663,13 +2113,14 @@
 
 /**
  * wnck_window_set_icon_geometry:
- * @window: a #WnckWindow
- * @x: x coordinate in pixels
- * @y: y coordinate in pixels
- * @width: width in pixels
- * @height: height in pixels
+ * @window: a #WnckWindow.
+ * @x: X coordinate in pixels.
+ * @y: Y coordinate in pixels.
+ * @width: width in pixels.
+ * @height: height in pixels.
  *
- * Set the icon geometry for a WnckWindow.
+ * Sets the icon geometry for @window. A typical use case for this is the
+ * destination of the minimization animation of @window.
  */
 void
 wnck_window_set_icon_geometry (WnckWindow *window,
@@ -1678,6 +2129,8 @@
 			       int         width,
 			       int         height)
 {
+  g_return_if_fail (WNCK_IS_WINDOW (window));
+
   if (window->priv->icon_geometry.x == x &&
       window->priv->icon_geometry.y == y &&
       window->priv->icon_geometry.width == width &&
@@ -1695,12 +2148,12 @@
 
 /**
  * wnck_window_is_on_workspace:
- * @window: a #WnckWindow
- * @workspace: a #WnckWorkspace
- * 
+ * @window: a #WnckWindow.
+ * @workspace: a #WnckWorkspace.
  * 
- * 
- * Return value: %TRUE if @window appears on @workspace
+ * Returns whether @window appears on @workspace.
+ *
+ * Return value: %TRUE if @window appears on @workspace, %FALSE otherwise.
  **/
 gboolean
 wnck_window_is_on_workspace (WnckWindow    *window,
@@ -1715,13 +2168,15 @@
 
 /**
  * wnck_window_is_in_viewport:
- * @window: a #WnckWindow
- * @workspace: a #WnckWorkspace
+ * @window: a #WnckWindow.
+ * @workspace: a #WnckWorkspace.
  * 
- * Returns #TRUE if the window is inside the current viewport
- * of the given workspace.
+ * Returns %TRUE if @window appears in the current viewport of @workspace.
  * 
- * Return value: %TRUE if @window appears in current viewport
+ * Return value: %TRUE if @window appears in current viewport of @workspace,
+ * %FALSE otherwise.
+ *
+ * Since: 2.4
  **/
 gboolean
 wnck_window_is_in_viewport (WnckWindow    *window,
@@ -1744,10 +2199,10 @@
   viewport_rect.width = wnck_screen_get_width (window->priv->screen);
   viewport_rect.height = wnck_screen_get_height (window->priv->screen);
 
-  window_rect.x = window->priv->x + viewport_rect.x;
-  window_rect.y = window->priv->y + viewport_rect.y;
-  window_rect.width = window->priv->width;
-  window_rect.height = window->priv->height;
+  window_rect.x = window->priv->x - window->priv->left_frame + viewport_rect.x;
+  window_rect.y = window->priv->y - window->priv->top_frame + viewport_rect.y;
+  window_rect.width = window->priv->width + window->priv->left_frame + window->priv->right_frame;
+  window_rect.height = window->priv->height + window->priv->top_frame + window->priv->bottom_frame;
 
   return gdk_rectangle_intersect (&viewport_rect, &window_rect, &window_rect);
 }
@@ -1867,6 +2322,12 @@
       window->priv->need_update_wmhints = TRUE;
       queue_update (window);
     }
+  else if (xevent->xproperty.atom ==
+           _wnck_atom_get ("_NET_FRAME_EXTENTS"))
+    {
+      window->priv->need_update_frame_extents = TRUE;
+      queue_update (window);
+    }
 }
 
 void
@@ -1993,7 +2454,7 @@
       /* Skip taskbar if the window is transient
        * for some main application window
        */
-      if (window->priv->transient_for != None &&
+      if (wnck_window_get_transient (window) != NULL &&
           !window->priv->transient_for_root)
         window->priv->skip_taskbar = TRUE;
       break;
@@ -2079,17 +2540,7 @@
 
   window->priv->need_update_icon_name = FALSE;
 
-  if (new_name == NULL)
-    new_name = _wnck_get_utf8_property (window->priv->xwindow,
-                                        _wnck_atom_get ("_NET_WM_VISIBLE_ICON_NAME"));
-
-  if (new_name == NULL)
-    new_name = _wnck_get_utf8_property (window->priv->xwindow,
-                                        _wnck_atom_get ("_NET_WM_ICON_NAME"));
-
-  if (new_name == NULL)
-    new_name = _wnck_get_text_property (window->priv->xwindow,
-                                        XA_WM_ICON_NAME);
+  new_name = _wnck_get_icon_name (window->priv->xwindow);
 
   if (!nullstr_equal (window->priv->icon_name, new_name))
     window->priv->need_emit_name_changed = TRUE;
@@ -2136,6 +2587,8 @@
 
   window->priv->actions = 0;
 
+  atoms = NULL;
+  n_atoms = 0;
   if (!_wnck_get_atom_list (window->priv->xwindow,
                             _wnck_atom_get ("_NET_WM_ALLOWED_ACTIONS"),
                             &atoms,
@@ -2145,7 +2598,6 @@
                 WNCK_WINDOW_ACTION_MOVE                    |
                 WNCK_WINDOW_ACTION_RESIZE                  |
                 WNCK_WINDOW_ACTION_SHADE                   |
-                WNCK_WINDOW_ACTION_ABOVE                   |
                 WNCK_WINDOW_ACTION_STICK                   |
                 WNCK_WINDOW_ACTION_MAXIMIZE_HORIZONTALLY   |
                 WNCK_WINDOW_ACTION_MAXIMIZE_VERTICALLY     |
@@ -2155,11 +2607,13 @@
                 WNCK_WINDOW_ACTION_UNMAXIMIZE_VERTICALLY   |
                 WNCK_WINDOW_ACTION_UNSHADE                 |
                 WNCK_WINDOW_ACTION_UNSTICK                 |
-                WNCK_WINDOW_ACTION_MAXIMIZE                |
-                WNCK_WINDOW_ACTION_UNMAXIMIZE              |
                 WNCK_WINDOW_ACTION_MINIMIZE                |
                 WNCK_WINDOW_ACTION_UNMINIMIZE              |
-                WNCK_WINDOW_ACTION_FULLSCREEN;
+                WNCK_WINDOW_ACTION_MAXIMIZE                |
+                WNCK_WINDOW_ACTION_UNMAXIMIZE              |
+                WNCK_WINDOW_ACTION_FULLSCREEN              |
+                WNCK_WINDOW_ACTION_ABOVE                   |
+                WNCK_WINDOW_ACTION_BELOW;
       return;
     }
 
@@ -2241,6 +2695,8 @@
   found_type = FALSE;
   type = WNCK_WINDOW_NORMAL;
   
+  atoms = NULL;
+  n_atoms = 0;
   if (_wnck_get_atom_list (window->priv->xwindow,
                            _wnck_atom_get ("_NET_WM_WINDOW_TYPE"),
                            &atoms,
@@ -2306,6 +2762,7 @@
 
   window->priv->need_update_transient_for = FALSE;
   
+  parent = None;
   if (_wnck_get_window (window->priv->xwindow,
                         _wnck_atom_get ("WM_TRANSIENT_FOR"),
                         &parent) &&
@@ -2350,6 +2807,9 @@
   g_free (window->priv->res_class);
   g_free (window->priv->res_name);
 
+  window->priv->res_class = NULL;
+  window->priv->res_name = NULL;
+
   _wnck_get_wmclass (window->priv->xwindow,
                      &window->priv->res_class,
                      &window->priv->res_name);
@@ -2389,6 +2849,36 @@
 }
 
 static void
+update_frame_extents (WnckWindow *window)
+{
+  int left, right, top, bottom;
+
+  if (!window->priv->need_update_frame_extents)
+    return;
+
+  window->priv->need_update_frame_extents = FALSE;
+
+  left = right = top = bottom = 0;
+
+  if (!_wnck_get_frame_extents (window->priv->xwindow,
+                                &left, &right, &top, &bottom))
+    return;
+
+  if (left   != window->priv->left_frame ||
+      right  != window->priv->right_frame ||
+      top    != window->priv->top_frame ||
+      bottom != window->priv->bottom_frame)
+    {
+      window->priv->left_frame   = left;
+      window->priv->right_frame  = right;
+      window->priv->top_frame    = top;
+      window->priv->bottom_frame = bottom;
+
+      emit_geometry_changed (window);
+    }
+}
+
+static void
 force_update_now (WnckWindow *window)
 {
   WnckWindowState old_state;
@@ -2423,6 +2913,7 @@
                               */
   update_workspace (window); /* emits signals */
   update_actions (window);
+  update_frame_extents (window); /* emits signals */
 
   get_icons (window);
   
diff -Nur libwnck-2.19.3.1/libwnck/window.h libwnck-2.19.4/libwnck/window.h
--- libwnck-2.19.3.1/libwnck/window.h	2007-06-05 20:25:40.000000000 +0200
+++ libwnck-2.19.4/libwnck/window.h	2007-06-18 21:59:14.000000000 +0200
@@ -1,4 +1,5 @@
 /* window object */
+/* vim: set sw=2 et: */
 
 /*
  * Copyright (C) 2001 Havoc Pennington
@@ -32,6 +33,30 @@
 
 G_BEGIN_DECLS
 
+/**
+ * WnckWindowState:
+ * @WNCK_WINDOW_STATE_MINIMIZED: the window is minimized.
+ * @WNCK_WINDOW_STATE_MAXIMIZED_HORIZONTALLY: the window is horizontically
+ * maximized.
+ * @WNCK_WINDOW_STATE_MAXIMIZED_VERTICALLY: the window is vertically maximized.
+ * @WNCK_WINDOW_STATE_SHADED: the window is shaded.
+ * @WNCK_WINDOW_STATE_SKIP_PAGER: the window should not be included on pagers.
+ * @WNCK_WINDOW_STATE_SKIP_TASKLIST: the window should not be included on
+ * tasklists.
+ * @WNCK_WINDOW_STATE_STICKY: the window is sticky (see
+ * wnck_window_is_sticky()).
+ * @WNCK_WINDOW_STATE_HIDDEN: the window is not visible on its #WnckWorkspace
+ * and viewport (when minimized, for example).
+ * @WNCK_WINDOW_STATE_FULLSCREEN: the window is fullscreen.
+ * @WNCK_WINDOW_STATE_DEMANDS_ATTENTION: the window needs attention (because
+ * the window requested activation but the window manager refused it, for
+ * example).
+ * @WNCK_WINDOW_STATE_URGENT: the window requires a response from the user.
+ * @WNCK_WINDOW_STATE_ABOVE: the window is above other windows (see
+ * wnck_window_make_above()).
+ *
+ * Type used as a bitmask to describe the state of a #WnckWindow.
+ */
 typedef enum
 {
   WNCK_WINDOW_STATE_MINIMIZED              = 1 << 0,
@@ -48,6 +73,36 @@
   WNCK_WINDOW_STATE_ABOVE                  = 1 << 11
 } WnckWindowState;
 
+/**
+ * WnckWindowActions:
+ * @WNCK_WINDOW_ACTION_MOVE: the window may be moved around the screen. 
+ * @WNCK_WINDOW_ACTION_RESIZE: the window may be resized.
+ * @WNCK_WINDOW_ACTION_SHADE: the window may be shaded.
+ * @WNCK_WINDOW_ACTION_STICK: the window may be sticked.
+ * @WNCK_WINDOW_ACTION_MAXIMIZE_HORIZONTALLY: the window may be maximized
+ * horizontally.
+ * @WNCK_WINDOW_ACTION_MAXIMIZE_VERTICALLY: the window may be maximized
+ * vertically.
+ * @WNCK_WINDOW_ACTION_CHANGE_WORKSPACE: the window may be moved between
+ * workspaces, or (un)pinned.
+ * @WNCK_WINDOW_ACTION_CLOSE: the window may be closed.
+ * @WNCK_WINDOW_ACTION_UNMAXIMIZE_HORIZONTALLY: the window may be unmaximized
+ * horizontally.
+ * @WNCK_WINDOW_ACTION_UNMAXIMIZE_VERTICALLY: the window may be maximized
+ * vertically.
+ * @WNCK_WINDOW_ACTION_UNSHADE: the window may be unshaded.
+ * @WNCK_WINDOW_ACTION_UNSTICK: the window may be unsticked.
+ * @WNCK_WINDOW_ACTION_MINIMIZE: the window may be minimized.
+ * @WNCK_WINDOW_ACTION_UNMINIMIZE: the window may be unminimized.
+ * @WNCK_WINDOW_ACTION_MAXIMIZE: the window may be maximized.
+ * @WNCK_WINDOW_ACTION_UNMAXIMIZE: the window may be unmaximized.
+ * @WNCK_WINDOW_ACTION_FULLSCREEN: the window may be brought to fullscreen.
+ * @WNCK_WINDOW_ACTION_ABOVE: the window may be made above other windows.
+ * @WNCK_WINDOW_ACTION_BELOW: the window may be made below other windows.
+ *
+ * Type used as a bitmask to describe the actions that can be done for a
+ * #WnckWindow.
+ */
 typedef enum
 {
   WNCK_WINDOW_ACTION_MOVE                    = 1 << 0,
@@ -71,6 +126,21 @@
   WNCK_WINDOW_ACTION_BELOW                   = 1 << 18
 } WnckWindowActions;
 
+/**
+ * WnckWindowType:
+ * @WNCK_WINDOW_NORMAL: the window is a normal window.
+ * @WNCK_WINDOW_DESKTOP: the window is a desktop.
+ * @WNCK_WINDOW_DOCK: the window is a dock or a panel.
+ * @WNCK_WINDOW_DIALOG: the window is a dialog window.
+ * @WNCK_WINDOW_TOOLBAR: the window is a tearoff toolbar.
+ * @WNCK_WINDOW_MENU: the window is a tearoff menu.
+ * @WNCK_WINDOW_UTILITY: the window is a small persistent utility window, such
+ * as a palette or toolbox.
+ * @WNCK_WINDOW_SPLASHSCREEN: the window is a splash screen displayed as an
+ * application is starting up.
+ *
+ * Type describing the semantic type of a #WnckWindow.
+ */
 typedef enum
 {
   WNCK_WINDOW_NORMAL,       /* document/app window */
@@ -83,6 +153,35 @@
   WNCK_WINDOW_SPLASHSCREEN  /* splash screen */
 } WnckWindowType;
 
+/**
+ * WnckWindowGravity:
+ * @WNCK_WINDOW_GRAVITY_CURRENT: keep the current gravity point.
+ * @WNCK_WINDOW_GRAVITY_NORTHWEST: use the left top corner of the frame window
+ * as gravity point.
+ * @WNCK_WINDOW_GRAVITY_NORTH: use the center of the frame window's top side as
+ * gravity point.
+ * @WNCK_WINDOW_GRAVITY_NORTHEAST: use the right top corner of the frame window
+ * as gravity point.
+ * @WNCK_WINDOW_GRAVITY_WEST: use the center of the frame window's left side as
+ * gravity point.
+ * @WNCK_WINDOW_GRAVITY_CENTER: use the center of the frame window as gravity
+ * point.
+ * @WNCK_WINDOW_GRAVITY_EAST: use the center of the frame window's right side
+ * as gravity point.
+ * @WNCK_WINDOW_GRAVITY_SOUTHWEST: use the left bottom corner of the frame
+ * window as gravity point.
+ * @WNCK_WINDOW_GRAVITY_SOUTH: use the center of the frame window's bottom side
+ * as gravity point.
+ * @WNCK_WINDOW_GRAVITY_SOUTHEAST: use the right bottom corner of the frame
+ * window as gravity point.
+ * @WNCK_WINDOW_GRAVITY_STATIC: use the left top corner of the client window as
+ * gravity point.
+ *
+ * Flag used when changing the geometry of a #WnckWindow. This is the gravity
+ * point to use as a reference for the new position.
+ *
+ * Since: 2.16
+ */
 typedef enum
 {
   WNCK_WINDOW_GRAVITY_CURRENT   = 0,
@@ -98,6 +197,18 @@
   WNCK_WINDOW_GRAVITY_STATIC    = 10
 } WnckWindowGravity;
 
+/**
+ * WnckWindowMoveResizeMask:
+ * @WNCK_WINDOW_CHANGE_X: X coordinate of the window should be changed.
+ * @WNCK_WINDOW_CHANGE_Y: Y coordinate of the window should be changed.
+ * @WNCK_WINDOW_CHANGE_WIDTH: width of the window should be changed.
+ * @WNCK_WINDOW_CHANGE_HEIGHT: height of the window should be changed.
+ *
+ * Flag used as a bitmask when changing the geometry of a #WnckWindow. This
+ * indicates which part of the geometry should be changed.
+ *
+ * Since: 2.16
+ */
 typedef enum
 {
   WNCK_WINDOW_CHANGE_X      = 1 << 0,
@@ -116,6 +227,12 @@
 typedef struct _WnckWindowClass   WnckWindowClass;
 typedef struct _WnckWindowPrivate WnckWindowPrivate;
 
+/**
+ * WnckWindow:
+ *
+ * The #WnckWindow struct contains only private fields and should not be
+ * directly accessed.
+ */
 struct _WnckWindow
 {
   GObject parent_instance;
@@ -258,6 +375,11 @@
 WnckWindowActions wnck_window_get_actions (WnckWindow *window);
 WnckWindowState   wnck_window_get_state   (WnckWindow *window);
 
+void wnck_window_get_client_window_geometry (WnckWindow *window,
+                                             int        *xp,
+                                             int        *yp,
+                                             int        *widthp,
+                                             int        *heightp);
 void wnck_window_get_geometry (WnckWindow *window,
                                int        *xp,
                                int        *yp,
diff -Nur libwnck-2.19.3.1/libwnck/wnck-enum-types.c libwnck-2.19.4/libwnck/wnck-enum-types.c
--- libwnck-2.19.3.1/libwnck/wnck-enum-types.c	2007-06-05 20:29:44.000000000 +0200
+++ libwnck-2.19.4/libwnck/wnck-enum-types.c	2007-06-18 22:16:50.000000000 +0200
@@ -36,6 +36,36 @@
   }
   return etype;
 }
+GType
+_wncklayoutorientation___wnck_layout_orientation_get_type (void)
+{
+  static GType etype = 0;
+  if (etype == 0) {
+    static const GEnumValue values[] = {
+      { WNCK_LAYOUT_ORIENTATION_HORIZONTAL, "WNCK_LAYOUT_ORIENTATION_HORIZONTAL", "horizontal" },
+      { WNCK_LAYOUT_ORIENTATION_VERTICAL, "WNCK_LAYOUT_ORIENTATION_VERTICAL", "vertical" },
+      { 0, NULL, NULL }
+    };
+    etype = g_enum_register_static ("_WnckLayoutOrientation", values);
+  }
+  return etype;
+}
+GType
+_wncklayoutcorner___wnck_layout_corner_get_type (void)
+{
+  static GType etype = 0;
+  if (etype == 0) {
+    static const GEnumValue values[] = {
+      { WNCK_LAYOUT_CORNER_TOPLEFT, "WNCK_LAYOUT_CORNER_TOPLEFT", "topleft" },
+      { WNCK_LAYOUT_CORNER_TOPRIGHT, "WNCK_LAYOUT_CORNER_TOPRIGHT", "topright" },
+      { WNCK_LAYOUT_CORNER_BOTTOMRIGHT, "WNCK_LAYOUT_CORNER_BOTTOMRIGHT", "bottomright" },
+      { WNCK_LAYOUT_CORNER_BOTTOMLEFT, "WNCK_LAYOUT_CORNER_BOTTOMLEFT", "bottomleft" },
+      { 0, NULL, NULL }
+    };
+    etype = g_enum_register_static ("_WnckLayoutCorner", values);
+  }
+  return etype;
+}
 
 /* enumerations from "tasklist.h" */
 GType
diff -Nur libwnck-2.19.3.1/libwnck/wnck-enum-types.h libwnck-2.19.4/libwnck/wnck-enum-types.h
--- libwnck-2.19.3.1/libwnck/wnck-enum-types.h	2007-06-05 20:29:28.000000000 +0200
+++ libwnck-2.19.4/libwnck/wnck-enum-types.h	2007-06-18 22:16:33.000000000 +0200
@@ -9,6 +9,10 @@
 /* enumerations from "screen.h" */
 GType wnck_motion_direction_get_type (void);
 #define WNCK_TYPE_MOTION_DIRECTION (wnck_motion_direction_get_type())
+GType _wncklayoutorientation___wnck_layout_orientation_get_type (void);
+#define WNCK_TYPE___WNCK_LAYOUT_ORIENTATION (_wncklayoutorientation___wnck_layout_orientation_get_type())
+GType _wncklayoutcorner___wnck_layout_corner_get_type (void);
+#define WNCK_TYPE___WNCK_LAYOUT_CORNER (_wncklayoutcorner___wnck_layout_corner_get_type())
 /* enumerations from "tasklist.h" */
 GType wnck_tasklist_grouping_type_get_type (void);
 #define WNCK_TYPE_TASKLIST_GROUPING_TYPE (wnck_tasklist_grouping_type_get_type())
diff -Nur libwnck-2.19.3.1/libwnck/wnckprop.c libwnck-2.19.4/libwnck/wnckprop.c
--- libwnck-2.19.3.1/libwnck/wnckprop.c	1970-01-01 01:00:00.000000000 +0100
+++ libwnck-2.19.4/libwnck/wnckprop.c	2007-06-18 21:59:14.000000000 +0200
@@ -0,0 +1,430 @@
+/* vim: set sw=2 et: */
+/*
+ * Copyright (C) 2007 Vincent Untz 
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Authors:
+ *	Vincent Untz <vuntz@gnome.org>
+ *
+ * Some of this code is based on code from gnome-panel/panel-force-quit.c
+ * This part of the code was written by Mark McLoughlin <mark@skynet.ie> and
+ * copyrighted by Sun. Sun (through Glynn Foster <glynn.foster@sun.com>)
+ * agreed to relicense it from the GPL to the LGPL.
+ */
+
+#include <string.h>
+#include <X11/Xlib.h>
+
+#include <gtk/gtk.h>
+#include <gdk/gdkx.h>
+
+#include <glib/gi18n.h>
+
+#include <libwnck/libwnck.h>
+#include <libwnck/class-group.h>
+
+gulong xid = 0;
+
+static GOptionEntry entries[] = {
+	{"xid", 'x', 0, G_OPTION_ARG_INT, &xid, N_("X window ID of the window to examine"), N_("XID")},
+	{ NULL }
+};
+
+static void clean_up (void);
+
+static void
+print_props (WnckWindow *window)
+{
+  gboolean           need_comma;
+  WnckWindowType     type;
+  int                x, y, w, h;
+  WnckClassGroup    *class_group;
+  WnckWorkspace     *space;
+  WnckScreen        *screen;
+  WnckWindowActions  actions;
+
+  g_print ("Name: ");
+  if (wnck_window_has_name (window))
+    g_print ("%s\n", wnck_window_get_name (window));
+  else
+    g_print ("<unset>\n");
+
+  g_print ("Icon Name: ");
+  if (wnck_window_has_icon_name (window))
+    g_print ("%s\n", wnck_window_get_icon_name (window));
+  else
+    g_print ("<unset>\n");
+
+  g_print ("Icons: ");
+  if (!wnck_window_get_icon_is_fallback (window))
+    g_print ("set\n");
+  else
+    g_print ("<unset>\n");
+
+  space = wnck_window_get_workspace (window);
+  g_print ("On Workspace: ");
+  if (space)
+    g_print ("%d (\"%s\")\n", wnck_workspace_get_number (space),
+             wnck_workspace_get_name (space));
+  else if (wnck_window_is_pinned (window))
+      g_print ("all workspaces\n");
+  else
+      g_print ("none\n");
+
+  screen = wnck_window_get_screen (window);
+  g_print ("On Screen: %d", wnck_screen_get_number (screen));
+  if (wnck_screen_get_window_manager_name (screen) != NULL)
+    g_print (" (Window Manager: %s)",
+             wnck_screen_get_window_manager_name (screen));
+  else
+    g_print (" (Window Manager: <no EWMH-compliant window manager>)");
+  g_print ("\n");
+
+  type = wnck_window_get_window_type (window);
+  g_print ("Window Type: ");
+  switch (type)
+    {
+      case WNCK_WINDOW_NORMAL:
+        g_print ("normal window\n");
+        break;
+      case WNCK_WINDOW_DESKTOP:
+        g_print ("desktop\n");
+        break;
+      case WNCK_WINDOW_DOCK:
+        g_print ("dock or panel\n");
+        break;
+      case WNCK_WINDOW_DIALOG:
+        g_print ("dialog window\n");
+        break;
+      case WNCK_WINDOW_TOOLBAR:
+        g_print ("tearoff toolbar\n");
+        break;
+      case WNCK_WINDOW_MENU:
+        g_print ("tearoff menu\n");
+        break;
+      case WNCK_WINDOW_UTILITY:
+        g_print ("utility window\n");
+        break;
+      case WNCK_WINDOW_SPLASHSCREEN:
+        g_print ("splash screen\n");
+        break;
+    }
+
+  wnck_window_get_geometry (window, &x, &y, &w, &h);
+  g_print ("Geometry (x, y, width, height): %d, %d, %d, %d\n", x, y, w, h);
+
+  class_group = wnck_window_get_class_group (window);
+  g_print ("Class Group: ");
+  if (strcmp (wnck_class_group_get_res_class (class_group), ""))
+    g_print ("%s\n", wnck_class_group_get_res_class (class_group));
+  else
+    g_print ("<unset>\n");
+
+  g_print ("XID: %lu\n", wnck_window_get_xid (window));
+
+  g_print ("PID: ");
+  if (wnck_window_get_pid (window) != 0)
+    g_print ("%d\n", wnck_window_get_pid (window));
+  else
+    g_print ("<unset>\n");
+
+  g_print ("Session ID: ");
+  if (wnck_window_get_session_id (window))
+    g_print ("%s\n", wnck_window_get_session_id (window));
+  else
+    g_print ("<unset>\n");
+
+  if (wnck_window_get_group_leader (window) != wnck_window_get_xid (window))
+    g_print ("Group Leader: %lu\n", wnck_window_get_group_leader (window));
+
+  if (wnck_window_get_transient (window))
+    g_print ("Transient for: %lu\n",
+             wnck_window_get_xid (wnck_window_get_transient (window)));
+
+#define PRINT_LIST_ITEM(func, string)                           \
+  if (func (window))                                            \
+    {                                                           \
+      g_print ("%s%s", need_comma ? ", " : "", string);       \
+      need_comma = TRUE;                                        \
+    }
+  need_comma = FALSE;
+  g_print ("State: ");
+  PRINT_LIST_ITEM (wnck_window_is_minimized, "minimized");
+  PRINT_LIST_ITEM (wnck_window_is_maximized, "maximized");
+  if (!wnck_window_is_maximized (window))
+    {
+      PRINT_LIST_ITEM (wnck_window_is_maximized_horizontally,
+                       "maximized horizontally");
+      PRINT_LIST_ITEM (wnck_window_is_maximized_vertically,
+                       "maximized vertically");
+    }
+  PRINT_LIST_ITEM (wnck_window_is_shaded, "shaded");
+  PRINT_LIST_ITEM (wnck_window_is_pinned, "pinned");
+  PRINT_LIST_ITEM (wnck_window_is_sticky, "sticky");
+  PRINT_LIST_ITEM (wnck_window_is_above, "above");
+  PRINT_LIST_ITEM (wnck_window_is_fullscreen, "fullscreen");
+  PRINT_LIST_ITEM (wnck_window_needs_attention, "needs attention");
+  PRINT_LIST_ITEM (wnck_window_is_skip_pager, "skip pager");
+  PRINT_LIST_ITEM (wnck_window_is_skip_tasklist, "skip tasklist");
+  if (!need_comma)
+    g_print ("normal");
+  g_print ("\n");
+
+#define PRINT_FLAGS_ITEM(bitmask, flag, string)                 \
+  if (bitmask & flag)                                           \
+    {                                                           \
+      g_print ("%s%s", need_comma ? ", " : "", string);         \
+      need_comma = TRUE;                                        \
+    }
+  need_comma = FALSE;
+  g_print ("Possible Actions: ");
+  actions = wnck_window_get_actions (window);
+  PRINT_FLAGS_ITEM (actions, WNCK_WINDOW_ACTION_MOVE, "move");
+  PRINT_FLAGS_ITEM (actions, WNCK_WINDOW_ACTION_RESIZE, "resize");
+  PRINT_FLAGS_ITEM (actions, WNCK_WINDOW_ACTION_SHADE, "shade");
+  PRINT_FLAGS_ITEM (actions, WNCK_WINDOW_ACTION_UNSHADE, "unshade");
+  PRINT_FLAGS_ITEM (actions, WNCK_WINDOW_ACTION_STICK, "stick");
+  PRINT_FLAGS_ITEM (actions, WNCK_WINDOW_ACTION_UNSTICK, "unstick");
+  PRINT_FLAGS_ITEM (actions, WNCK_WINDOW_ACTION_MAXIMIZE_HORIZONTALLY,
+                    "maximize horizontally");
+  PRINT_FLAGS_ITEM (actions, WNCK_WINDOW_ACTION_UNMAXIMIZE_HORIZONTALLY,
+                    "unmaximize horizontally");
+  PRINT_FLAGS_ITEM (actions, WNCK_WINDOW_ACTION_MAXIMIZE_VERTICALLY,
+                    "maximize vertically");
+  PRINT_FLAGS_ITEM (actions, WNCK_WINDOW_ACTION_UNMAXIMIZE_VERTICALLY,
+                    "unmaximize vertically");
+  PRINT_FLAGS_ITEM (actions, WNCK_WINDOW_ACTION_CHANGE_WORKSPACE,
+                    "change workspace, pin, unpin");
+  PRINT_FLAGS_ITEM (actions, WNCK_WINDOW_ACTION_MINIMIZE, "minimize");
+  PRINT_FLAGS_ITEM (actions, WNCK_WINDOW_ACTION_UNMINIMIZE, "unminimize");
+  PRINT_FLAGS_ITEM (actions, WNCK_WINDOW_ACTION_MAXIMIZE, "maximize");
+  PRINT_FLAGS_ITEM (actions, WNCK_WINDOW_ACTION_UNMAXIMIZE, "unmaximize");
+  PRINT_FLAGS_ITEM (actions, WNCK_WINDOW_ACTION_FULLSCREEN,
+                    "change fullscreen mode");
+  PRINT_FLAGS_ITEM (actions, WNCK_WINDOW_ACTION_CLOSE, "close");
+  PRINT_FLAGS_ITEM (actions, WNCK_WINDOW_ACTION_ABOVE,
+                    "make above, unmake above");
+  PRINT_FLAGS_ITEM (actions, WNCK_WINDOW_ACTION_BELOW,
+                    "make below, unmake below");
+  if (!need_comma)
+    g_print ("no action possible");
+  g_print ("\n");
+
+}
+
+static gboolean
+wm_state_set (Window window)
+{
+  Atom    wm_state;
+  gulong  nitems;
+  gulong  bytes_after;
+  gulong *prop;
+  Atom    ret_type = None;
+  int     ret_format;
+  int     err, result;
+
+  wm_state = gdk_x11_get_xatom_by_name ("WM_STATE");
+
+  gdk_error_trap_push ();
+  result = XGetWindowProperty (gdk_display,
+                               window,
+                               wm_state,
+                               0, G_MAXLONG,
+                               False, wm_state, &ret_type, &ret_format, &nitems,
+                               &bytes_after, (gpointer) &prop);
+  err = gdk_error_trap_pop ();
+  if (err != Success ||
+      result != Success)
+    return FALSE;
+
+  XFree (prop);
+
+  if (ret_type != wm_state)
+    return FALSE;
+
+  return TRUE;
+}
+
+static WnckWindow *
+find_managed_window (Window window)
+{
+  Window      root;
+  Window      parent;
+  Window     *kids = NULL;
+  WnckWindow *retval;
+  guint       nkids;
+  int         i, result;
+
+  if (wm_state_set (window))
+    return wnck_window_get (window);
+
+  gdk_error_trap_push ();
+  result = XQueryTree (gdk_display, window, &root, &parent, &kids, &nkids);
+  if (gdk_error_trap_pop () || !result)
+    return NULL;
+
+  retval = NULL;
+
+  for (i = 0; i < nkids; i++)
+    {
+      if (wm_state_set (kids [i]))
+        {
+          retval = wnck_window_get (kids [i]);
+          break;
+        }
+
+      retval = find_managed_window (kids [i]);
+      if (retval != NULL)
+        break;
+    }
+
+  if (kids)
+    XFree (kids);
+
+  return retval;
+}
+
+static void 
+handle_button_press_event (XKeyEvent *event)
+{
+  WnckWindow *window;
+
+  if (event->subwindow == None)
+    return;
+
+  window = find_managed_window (event->subwindow);
+
+  if (window)
+    print_props (window);
+}
+
+static GdkFilterReturn
+target_filter (GdkXEvent *gdk_xevent,
+               GdkEvent  *event,
+               gpointer   data)
+{
+  XEvent *xevent = (XEvent *) gdk_xevent;
+
+  switch (xevent->type)
+    {
+      case ButtonPress:
+        handle_button_press_event (&xevent->xkey);
+        clean_up ();
+        return GDK_FILTER_REMOVE;
+      case KeyPress:
+        if (xevent->xkey.keycode == XKeysymToKeycode (gdk_display, XK_Escape))
+          {
+            clean_up ();
+            return GDK_FILTER_REMOVE;
+          }
+        break;
+      default:
+        break;
+    }
+
+  return GDK_FILTER_CONTINUE;
+}
+
+static gboolean
+get_target (gpointer data)
+{
+  GdkGrabStatus  status;
+  GdkCursor     *cross;
+  GdkWindow     *root;
+
+  root = gdk_get_default_root_window ();
+
+  gdk_window_add_filter (root, (GdkFilterFunc) target_filter, NULL);
+
+  cross = gdk_cursor_new (GDK_CROSS);
+  status = gdk_pointer_grab (root, FALSE, GDK_BUTTON_PRESS_MASK,
+                             NULL, cross, GDK_CURRENT_TIME);
+  gdk_cursor_unref (cross);
+
+  if (status != GDK_GRAB_SUCCESS)
+    {
+      g_warning ("Pointer grab failed.\n");
+      clean_up ();
+      return FALSE;
+    }
+
+  status = gdk_keyboard_grab (root, FALSE, GDK_CURRENT_TIME);
+  if (status != GDK_GRAB_SUCCESS)
+    {
+      g_warning ("Keyboard grab failed.\n");
+      clean_up ();
+      return FALSE;
+    }
+
+  gdk_flush ();
+
+  return FALSE;
+}
+
+static void
+clean_up (void)
+{
+  GdkWindow *root;
+
+  root = gdk_get_default_root_window ();
+  gdk_window_remove_filter (root, (GdkFilterFunc) target_filter, NULL);
+
+  gdk_pointer_ungrab (GDK_CURRENT_TIME);
+  gdk_keyboard_ungrab (GDK_CURRENT_TIME);
+
+  gtk_main_quit ();
+}
+
+int
+main (int argc, char **argv)
+{
+  GOptionContext *ctxt;
+  WnckScreen     *screen;
+  
+  ctxt = g_option_context_new ("");
+  g_option_context_add_main_entries (ctxt, entries, NULL);
+  g_option_context_add_group (ctxt, gtk_get_option_group (TRUE));
+  g_option_context_parse (ctxt, &argc, &argv, NULL);
+  g_option_context_free (ctxt);
+  ctxt = NULL;
+
+  gtk_init (&argc, &argv);
+
+  screen = wnck_screen_get_default ();
+
+  /* because we don't respond to signals at the moment */
+  wnck_screen_force_update (screen);
+  
+  if (xid != 0)
+    {
+      WnckWindow *window;
+
+      window = wnck_window_get (xid);
+      if (window)
+        print_props (window);
+      else
+        g_print ("Cannot find window with XID %lu.\n", xid);
+    }
+  else
+    {
+      g_idle_add (get_target, NULL);
+      
+      gtk_main ();
+    }
+  
+  return 0;
+}
diff -Nur libwnck-2.19.3.1/libwnck/workspace-accessible.c libwnck-2.19.4/libwnck/workspace-accessible.c
--- libwnck-2.19.3.1/libwnck/workspace-accessible.c	2007-06-05 20:25:40.000000000 +0200
+++ libwnck-2.19.4/libwnck/workspace-accessible.c	2007-06-18 21:59:14.000000000 +0200
@@ -1,3 +1,4 @@
+/* vim: set sw=2 et: */
 /*
  * Copyright 2002 Sun Microsystems Inc.
  *
diff -Nur libwnck-2.19.3.1/libwnck/workspace-accessible-factory.c libwnck-2.19.4/libwnck/workspace-accessible-factory.c
--- libwnck-2.19.3.1/libwnck/workspace-accessible-factory.c	2007-06-05 20:25:40.000000000 +0200
+++ libwnck-2.19.4/libwnck/workspace-accessible-factory.c	2007-06-18 21:59:14.000000000 +0200
@@ -1,3 +1,4 @@
+/* vim: set sw=2 et: */
 /*
  * Copyright 2002 Sun Microsystems Inc.
  *
@@ -21,35 +22,12 @@
 #include "workspace-accessible-factory.h"
 #include "workspace-accessible.h"
 
-static void       wnck_workspace_accessible_factory_class_init        (WnckWorkspaceAccessibleFactoryClass *klass);
-static AtkObject* wnck_workspace_accessible_factory_create_accessible (GObject                          *obj);
+G_DEFINE_TYPE (WnckWorkspaceAccessibleFactory,
+               wnck_workspace_accessible_factory, ATK_TYPE_OBJECT_FACTORY);
 
-static GType wnck_workspace_accessible_factory_get_accessible_type (void);
-
-GType
-wnck_workspace_accessible_factory_get_type (void)
-{
-  static GType type = 0;
+static AtkObject* wnck_workspace_accessible_factory_create_accessible (GObject *obj);
 
-  if (!type) 
-    {
-      const GTypeInfo tinfo = 
-      {
-        sizeof (WnckWorkspaceAccessibleFactoryClass),
-        (GBaseInitFunc) NULL, /* base init */
-        (GBaseFinalizeFunc) NULL, /* base finalize */
-        (GClassInitFunc) wnck_workspace_accessible_factory_class_init,
-        (GClassFinalizeFunc) NULL, /* class finalize */
-        NULL, /* class data */
-        sizeof (WnckWorkspaceAccessibleFactory),
-        0, /* nb preallocs */
-        (GInstanceInitFunc) NULL, /* instance init */
-        NULL /* value table */
-      };
-      type = g_type_register_static (ATK_TYPE_OBJECT_FACTORY, "WnckWorkspaceAccessibleFactory" , &tinfo, 0);
-    }
-  return type;
-}
+static GType wnck_workspace_accessible_factory_get_accessible_type (void);
 
 static void
 wnck_workspace_accessible_factory_class_init (WnckWorkspaceAccessibleFactoryClass *klass)
@@ -60,6 +38,11 @@
   class->get_accessible_type = wnck_workspace_accessible_factory_get_accessible_type;
 }
 
+static void
+wnck_workspace_accessible_factory_init (WnckWorkspaceAccessibleFactory *factory)
+{
+}
+
 AtkObjectFactory*
 wnck_workspace_accessible_factory_new (void)
 {
diff -Nur libwnck-2.19.3.1/libwnck/workspace-accessible-factory.h libwnck-2.19.4/libwnck/workspace-accessible-factory.h
--- libwnck-2.19.3.1/libwnck/workspace-accessible-factory.h	2007-06-05 20:25:40.000000000 +0200
+++ libwnck-2.19.4/libwnck/workspace-accessible-factory.h	2007-06-18 21:59:14.000000000 +0200
@@ -1,3 +1,4 @@
+/* vim: set sw=2 et: */
 /*
  * Copyright 2002 Sun Microsystems Inc.
  *
diff -Nur libwnck-2.19.3.1/libwnck/workspace-accessible.h libwnck-2.19.4/libwnck/workspace-accessible.h
--- libwnck-2.19.3.1/libwnck/workspace-accessible.h	2007-06-05 20:25:40.000000000 +0200
+++ libwnck-2.19.4/libwnck/workspace-accessible.h	2007-06-18 21:59:14.000000000 +0200
@@ -1,3 +1,4 @@
+/* vim: set sw=2 et: */
 /*
  * Copyright 2002 Sun Microsystems Inc.
  *
diff -Nur libwnck-2.19.3.1/libwnck/workspace.c libwnck-2.19.4/libwnck/workspace.c
--- libwnck-2.19.3.1/libwnck/workspace.c	2007-06-05 20:25:40.000000000 +0200
+++ libwnck-2.19.4/libwnck/workspace.c	2007-06-18 21:59:14.000000000 +0200
@@ -1,4 +1,5 @@
 /* workspace object */
+/* vim: set sw=2 et: */
 
 /*
  * Copyright (C) 2001 Havoc Pennington
@@ -29,6 +30,39 @@
 #include "private.h"
 #include <string.h>
 
+/**
+ * SECTION:workspace
+ * @short_description: an object representing a workspace.
+ * @see_also: #WnckScreen
+ * @stability: Unstable
+ *
+ * The #WnckWorkspace represents what is called <ulink
+ * url="http://standards.freedesktop.org/wm-spec/wm-spec-latest.html&num;largedesks">virtual
+ * desktops</ulink> in the <ulink
+ * url="http://standards.freedesktop.org/wm-spec/wm-spec-latest.html">EWMH</ulink>.
+ * A workspace is a virtualization of a #WnckScreen<!-- -->: only one workspace
+ * can be shown on a #WnckScreen at a time. It makes it possible, for example,
+ * to put windows on different workspaces to organize them.
+ *
+ * If the #WnckWorkspace size is bigger that the #WnckScreen size, the
+ * workspace contains a viewport. Viewports are defined in the <ulink
+ * url="http://standards.freedesktop.org/wm-spec/wm-spec-latest.html&num;id2457064">large
+ * desktops</ulink> section of the <ulink
+ * url="http://standards.freedesktop.org/wm-spec/wm-spec-latest.html">EWMH</ulink>.
+ * The notion of workspaces and viewports are quite similar, and generally both
+ * are not used at the same time: there are generally either multiple
+ * workspaces with no viewport, or one workspace with a viewport. libwnck
+ * supports all situations, even multiple workspaces with viewports.
+ *
+ * Workspaces are organized according to a layout set on the #WnckScreen. See
+ * wnck_screen_calc_workspace_layout(), wnck_screen_try_set_workspace_layout(),
+ * wnck_screen_release_workspace_layout() and
+ * wnck_screen_free_workspace_layout() for more information about the layout.
+ *
+ * The #WnckWorkspace objects are always owned by libwnck and must not be
+ * referenced or unreferenced.
+ */
+
 struct _WnckWorkspacePrivate
 {
   WnckScreen *screen;
@@ -39,6 +73,8 @@
   gboolean is_virtual;
 };
 
+G_DEFINE_TYPE (WnckWorkspace, wnck_workspace, G_TYPE_OBJECT);
+
 enum {
   NAME_CHANGED,
   LAST_SIGNAL
@@ -51,40 +87,8 @@
 
 static void emit_name_changed (WnckWorkspace *space);
 
-static gpointer parent_class;
 static guint signals[LAST_SIGNAL] = { 0 };
 
-GType
-wnck_workspace_get_type (void)
-{
-  static GType object_type = 0;
-
-  g_type_init ();
-  
-  if (!object_type)
-    {
-      const GTypeInfo object_info =
-      {
-        sizeof (WnckWorkspaceClass),
-        (GBaseInitFunc) NULL,
-        (GBaseFinalizeFunc) NULL,
-        (GClassInitFunc) wnck_workspace_class_init,
-        NULL,           /* class_finalize */
-        NULL,           /* class_data */
-        sizeof (WnckWorkspace),
-        0,              /* n_preallocs */
-        (GInstanceInitFunc) wnck_workspace_init,
-        NULL            /* value_table */
-      };
-      
-      object_type = g_type_register_static (G_TYPE_OBJECT,
-                                            "WnckWorkspace",
-                                            &object_info, 0);
-    }
-  
-  return object_type;
-}
-
 static void
 wnck_workspace_init (WnckWorkspace *workspace)
 {
@@ -98,10 +102,14 @@
 {
   GObjectClass *object_class = G_OBJECT_CLASS (klass);
   
-  parent_class = g_type_class_peek_parent (klass);
-  
   object_class->finalize = wnck_workspace_finalize;
 
+  /**
+   * WnckWorkspace::name-changed:
+   * @space: the #WnckWorkspace which emitted the signal.
+   *
+   * Emitted when the name of @space changes.
+   */
   signals[NAME_CHANGED] =
     g_signal_new ("name_changed",
                   G_OBJECT_CLASS_TYPE (object_class),
@@ -123,35 +131,35 @@
   
   g_free (workspace->priv);
   
-  G_OBJECT_CLASS (parent_class)->finalize (object);
+  G_OBJECT_CLASS (wnck_workspace_parent_class)->finalize (object);
 }
 
 /**
  * wnck_workspace_get_number:
- * @space: a #WnckWorkspace
- * 
+ * @space: a #WnckWorkspace.
  * 
+ * Returns the index of @space on the #WnckScreen to which it belongs. The
+ * first workspace has an index of 0.
  * 
- * Return value: get the index of the workspace
+ * Return value: the index of @space on its #WnckScreen, or -1 on errors.
  **/
 int
 wnck_workspace_get_number (WnckWorkspace *space)
 {
-  g_return_val_if_fail (WNCK_IS_WORKSPACE (space), 0);
+  g_return_val_if_fail (WNCK_IS_WORKSPACE (space), -1);
   
   return space->priv->number;
 }
 
 /**
  * wnck_workspace_get_name:
- * @space: a #WnckWorkspace
+ * @space: a #WnckWorkspace.
  * 
- * Gets the name that should be used to refer to the workspace
- * in the user interface. If the user hasn't set a special name,
- * will be something like "Workspace 3" - otherwise whatever name
- * the user set.
+ * Returns the human-readable name that should be used to refer to @space. If
+ * the user has not set a special name, a fallback like "Workspace 3" will be
+ * used.
  * 
- * Return value: workspace name, never %NULL 
+ * Return value: the name of @space.
  **/
 const char*
 wnck_workspace_get_name (WnckWorkspace *space)
@@ -163,11 +171,12 @@
 
 /**
  * wnck_workspace_change_name:
- * @space: a #WnckWorkspace
- * @name: new workspace name
+ * @space: a #WnckWorkspace.
+ * @name: new name for @space.
  *
- * Try changing the name of the workspace.
+ * Changes the name of @space.
  * 
+ * Since: 2.2
  **/
 void
 wnck_workspace_change_name (WnckWorkspace *space,
@@ -183,10 +192,15 @@
 
 /**
  * wnck_workspace_activate:
- * @space: a #WnckWorkspace
+ * @space: a #WnckWorkspace.
+ * @timestamp: the X server timestamp of the user interaction event that caused
+ * this call to occur.
  * 
- * Ask window manager to make @space the active workspace.
+ * Asks the window manager to make @space the active workspace. The window
+ * manager may decide to refuse the request (to not steal the focus if there is
+ * a more recent user activity, for example).
  * 
+ * Since: 2.10 (@timestamp argument was missing in earlier versions)
  **/
 void
 wnck_workspace_activate (WnckWorkspace *space,
@@ -288,32 +302,94 @@
     return FALSE;
 }
 
+/**
+ * wnck_workspace_get_width:
+ * @space: a #WnckWorkspace.
+ *
+ * Returns the width of @space.
+ *
+ * Returns: the width of @space.
+ *
+ * Since: 2.4
+ */
 int
 wnck_workspace_get_width (WnckWorkspace *space)
 {
+  g_return_val_if_fail (WNCK_IS_WORKSPACE (space), 0);
+
   return space->priv->width;
 }
 
+/**
+ * wnck_workspace_get_height:
+ * @space: a #WnckWorkspace.
+ *
+ * Returns the height of @space.
+ *
+ * Returns: the height of @space.
+ *
+ * Since: 2.4
+ */
 int
 wnck_workspace_get_height (WnckWorkspace *space)
 {
+  g_return_val_if_fail (WNCK_IS_WORKSPACE (space), 0);
+
   return space->priv->height;
 }
 
+/**
+ * wnck_workspace_get_viewport_x:
+ * @space: a #WnckWorkspace.
+ *
+ * Returns the X coordinate of the viewport in @space.
+ *
+ * Returns: the X coordinate of the viewport in @space, or 0 if @space does not
+ * contain a viewport.
+ *
+ * Since: 2.4
+ */
 int
 wnck_workspace_get_viewport_x (WnckWorkspace *space)
 {
+  g_return_val_if_fail (WNCK_IS_WORKSPACE (space), 0);
+
   return space->priv->viewport_x;
 }
 
+/**
+ * wnck_workspace_get_viewport_y:
+ * @space: a #WnckWorkspace.
+ *
+ * Returns the Y coordinate of the viewport in @space.
+ *
+ * Returns: the Y coordinate of the viewport in @space, or 0 if @space does not
+ * contain a viewport.
+ *
+ * Since: 2.4
+ */
 int
 wnck_workspace_get_viewport_y (WnckWorkspace *space)
 {
+  g_return_val_if_fail (WNCK_IS_WORKSPACE (space), 0);
+
   return space->priv->viewport_y;
 }
 
+/**
+ * wnck_workspace_is_virtual:
+ * @space: a #WnckWorkspace.
+ *
+ * Returns whether @space contains a viewport.
+ *
+ * Returns: %TRUE if @space contains a viewport, %FALSE otherwise.
+ *
+ * Since: 2.4
+ */
 gboolean
 wnck_workspace_is_virtual (WnckWorkspace *space)
 {
+  g_return_val_if_fail (WNCK_IS_WORKSPACE (space), FALSE);
+
   return space->priv->is_virtual;
 }
diff -Nur libwnck-2.19.3.1/libwnck/workspace.h libwnck-2.19.4/libwnck/workspace.h
--- libwnck-2.19.3.1/libwnck/workspace.h	2007-06-05 20:25:40.000000000 +0200
+++ libwnck-2.19.4/libwnck/workspace.h	2007-06-18 21:59:14.000000000 +0200
@@ -1,4 +1,5 @@
 /* workspace object */
+/* vim: set sw=2 et: */
 
 /*
  * Copyright (C) 2001 Havoc Pennington
@@ -37,6 +38,12 @@
 typedef struct _WnckWorkspaceClass   WnckWorkspaceClass;
 typedef struct _WnckWorkspacePrivate WnckWorkspacePrivate;
 
+/**
+ * WnckWorkspace:
+ *
+ * The #WnckWorkspace struct contains only private fields and should not be
+ * directly accessed.
+ */
 struct _WnckWorkspace
 {
   GObject parent_instance;
diff -Nur libwnck-2.19.3.1/libwnck/xutils.c libwnck-2.19.4/libwnck/xutils.c
--- libwnck-2.19.3.1/libwnck/xutils.c	2007-06-05 20:25:40.000000000 +0200
+++ libwnck-2.19.4/libwnck/xutils.c	2007-06-18 21:59:14.000000000 +0200
@@ -1,4 +1,5 @@
 /* Xlib utils */
+/* vim: set sw=2 et: */
 
 /*
  * Copyright (C) 2001 Havoc Pennington
@@ -1140,6 +1141,25 @@
   return name;
 }
 
+char*
+_wnck_get_icon_name (Window xwindow)
+{
+  char *name;
+  
+  name = _wnck_get_utf8_property (xwindow,
+                                  _wnck_atom_get ("_NET_WM_VISIBLE_ICON_NAME"));
+
+  if (name == NULL)
+    name = _wnck_get_utf8_property (xwindow,
+                                    _wnck_atom_get ("_NET_WM_ICON_NAME"));
+
+  if (name == NULL)
+    name = _wnck_get_text_property (xwindow,
+                                    XA_WM_ICON_NAME);
+
+  return name;
+}
+
 static char*
 latin1_to_utf8 (const char *latin1)
 {
@@ -1211,6 +1231,41 @@
     }
 }
 
+gboolean
+_wnck_get_frame_extents (Window  xwindow,
+                         int    *left_frame,
+                         int    *right_frame,
+                         int    *top_frame,
+                         int    *bottom_frame)
+{
+  gulong   *p_size;
+  int       n_size;
+  gboolean  retval;
+
+  retval = FALSE;
+  p_size = NULL;
+  n_size = 0;
+
+  _wnck_get_cardinal_list (xwindow,
+                           _wnck_atom_get ("_NET_FRAME_EXTENTS"),
+                           &p_size, &n_size);
+
+  if (p_size != NULL && n_size == 4)
+    {
+      *left_frame   = p_size[0];
+      *right_frame  = p_size[1];
+      *top_frame    = p_size[2];
+      *bottom_frame = p_size[3];
+
+      retval = TRUE;
+    }
+
+  if (p_size != NULL)
+    g_free (p_size);
+
+  return retval;
+}
+
 void
 _wnck_select_input (Window xwindow,
                     int    mask)
@@ -2321,24 +2376,6 @@
   _wnck_error_trap_pop ();
 }
 
-void
-_wnck_set_dock_type_hint (Window xwindow)
-{
-  Atom atom;
-
-  atom = _wnck_atom_get ("_NET_WM_WINDOW_TYPE_DOCK");
-  
-  _wnck_error_trap_push ();
-
-  XChangeProperty (gdk_display,
-                   xwindow, 
-                   _wnck_atom_get ("_NET_WM_WINDOW_TYPE"),
-		   XA_ATOM, 32, PropModeReplace,
-		   (guchar *)&atom, 1);
-
-  _wnck_error_trap_pop ();
-}
-
 /* orientation of pager */
 #define _NET_WM_ORIENTATION_HORZ 0
 #define _NET_WM_ORIENTATION_VERT 1
@@ -2413,21 +2450,20 @@
  * Return value: the time stamp.
  **/
 static Time
-get_server_time (Display *display,
-		 Window   window)
+get_server_time (Window window)
 {
   unsigned char c = 'a';
   XEvent xevent;
   TimeStampInfo info;
 
-  info.timestamp_prop_atom = XInternAtom  (display, "_TIMESTAMP_PROP", False);
+  info.timestamp_prop_atom = _wnck_atom_get ("_TIMESTAMP_PROP");
   info.window = window;
 
-  XChangeProperty (display, window,
+  XChangeProperty (gdk_display, window,
 		   info.timestamp_prop_atom, info.timestamp_prop_atom,
 		   8, PropModeReplace, &c, 1);
 
-  XIfEvent (display, &xevent,
+  XIfEvent (gdk_display, &xevent,
 	    timestamp_predicate, (XPointer)&info);
 
   return xevent.xproperty.time;
@@ -2445,19 +2481,35 @@
 static GSList *layout_managers = NULL;
 static int next_token = 1;
 
+static void
+_wnck_free_layout_manager (LayoutManager *lm)
+{
+  XDestroyWindow (gdk_display, lm->window);
+  g_free (lm);
+
+  layout_managers = g_slist_remove (layout_managers, lm);
+}
+
 int
 _wnck_try_desktop_layout_manager (Screen *xscreen,
                                   int     current_token)
 {
+  Atom selection_atom;
+  Window owner;
   GSList *tmp;
   int number;
   Time timestamp;
   XClientMessageEvent xev;  
   char buffer[256];
   LayoutManager *lm;
-  
+
   number = XScreenNumberOfScreen (xscreen);
   
+  sprintf (buffer, "_NET_DESKTOP_LAYOUT_S%d", number);
+  selection_atom = _wnck_atom_get (buffer);
+
+  owner = XGetSelectionOwner (gdk_display, selection_atom);
+  
   tmp = layout_managers;
   while (tmp != NULL)
     {
@@ -2466,7 +2518,15 @@
       if (number == lm->screen_number)
         {
           if (current_token == lm->token)
-            return current_token; /* we still have the selection */
+            {
+              if (owner == lm->window)
+                return current_token; /* we still have the selection */
+              else
+                { /* we lost the selection */
+                  _wnck_free_layout_manager (lm);
+                  break;
+                }
+            }
           else
             return WNCK_NO_MANAGER_TOKEN; /* someone else has it */
         }
@@ -2474,7 +2534,10 @@
       tmp = tmp->next;
     }
   
-  /* No one in-process has the selection at the moment */
+  if (owner != None)
+    return WNCK_NO_MANAGER_TOKEN; /* someone else has the selection */
+
+  /* No one has the selection at the moment */
 
   lm = g_new0 (LayoutManager, 1);
 
@@ -2482,9 +2545,8 @@
   lm->token = next_token;
   ++next_token;
 
-  sprintf (buffer, "_NET_DESKTOP_LAYOUT_S%d", number);
-  lm->selection_atom = XInternAtom (gdk_display, buffer, False);
-  lm->manager_atom = XInternAtom (gdk_display, "MANAGER", False);
+  lm->selection_atom = selection_atom;
+  lm->manager_atom = _wnck_atom_get ("MANAGER");
 
   lm->window = XCreateSimpleWindow (gdk_display,
                                     RootWindowOfScreen (xscreen),
@@ -2493,7 +2555,7 @@
                                     WhitePixel (gdk_display, number));
 
   XSelectInput (gdk_display, lm->window, PropertyChangeMask);
-  timestamp = get_server_time (gdk_display, lm->window);
+  timestamp = get_server_time (lm->window);
 
   XSetSelectionOwner (gdk_display, lm->selection_atom,
 		      lm->window, timestamp);
@@ -2545,12 +2607,18 @@
         {
           if (current_token == lm->token)
             {
-              XDestroyWindow (gdk_display,
-                              lm->window);
+              /* release selection ownership */
+              if (XGetSelectionOwner (gdk_display, lm->selection_atom) !=
+                  lm->window)
+                {
+                  Time timestamp;
+
+                  timestamp = get_server_time (lm->window);
+                  XSetSelectionOwner (gdk_display, lm->selection_atom,
+                                      None, timestamp);
+                }
 
-              g_free (lm);
-              layout_managers = g_slist_remove (layout_managers, lm);
-              
+              _wnck_free_layout_manager (lm);
               return;
             }
         }
@@ -2576,12 +2644,7 @@
       if (xev->xany.window == lm->window &&
           xev->xselectionclear.selection == lm->selection_atom)
         {
-          XDestroyWindow (gdk_display,
-                          lm->window);
-          
-          g_free (lm);
-          layout_managers = g_slist_remove (layout_managers, lm);
-          
+          _wnck_free_layout_manager (lm);
           return TRUE;
         }
       
@@ -2590,51 +2653,3 @@
 
   return FALSE;
 }
-
-/* stock icon code Copyright (C) 2002 Jorn Baayen <jorn@nl.linux.org> */
-typedef struct
-{
-  char *stock_id;
-  const guint8 *icon_data;
-} StockIcon;
-
-void
-_wnck_stock_icons_init (void)
-{
-  GtkIconFactory *factory;
-  int i;
-  static gboolean done = FALSE;
-
-  StockIcon items[] =
-  {
-    { WNCK_STOCK_DELETE,   stock_delete_data   },
-    { WNCK_STOCK_MINIMIZE, stock_minimize_data },
-    { WNCK_STOCK_MAXIMIZE, stock_maximize_data }
-  };
-
-  if (done)
-    return;
-
-  done = TRUE;
-  
-  factory = gtk_icon_factory_new ();
-  gtk_icon_factory_add_default (factory);
-
-  for (i = 0; i < (gint) G_N_ELEMENTS (items); i++)
-    {
-      GtkIconSet *icon_set;
-      GdkPixbuf *pixbuf;
-
-      pixbuf = gdk_pixbuf_new_from_inline (-1, items[i].icon_data,
-					   FALSE,
-					   NULL);
-
-      icon_set = gtk_icon_set_new_from_pixbuf (pixbuf);
-      gtk_icon_factory_add (factory, items[i].stock_id, icon_set);
-      gtk_icon_set_unref (icon_set);
-		
-      g_object_unref (G_OBJECT (pixbuf));
-    }
-
-  g_object_unref (G_OBJECT (factory));
-}
diff -Nur libwnck-2.19.3.1/libwnck/xutils.h libwnck-2.19.4/libwnck/xutils.h
--- libwnck-2.19.3.1/libwnck/xutils.h	2007-06-05 20:25:40.000000000 +0200
+++ libwnck-2.19.4/libwnck/xutils.h	2007-06-18 21:59:14.000000000 +0200
@@ -1,4 +1,5 @@
 /* Xlib utilities */
+/* vim: set sw=2 et: */
 
 /*
  * Copyright (C) 2001 Havoc Pennington
@@ -112,10 +113,16 @@
 char*  _wnck_get_session_id     (Window xwindow);
 int    _wnck_get_pid            (Window xwindow);
 char*  _wnck_get_name           (Window xwindow);
+char*  _wnck_get_icon_name      (Window xwindow);
 char*  _wnck_get_res_class_utf8 (Window xwindow);
 void   _wnck_get_wmclass        (Window xwindow,
                                  char **res_class,
                                  char **res_name);
+gboolean _wnck_get_frame_extents  (Window  xwindow,
+                                   int    *left_frame,
+                                   int    *right_frame,
+                                   int    *top_frame,
+                                   int    *bottom_frame);
 
 void   _wnck_select_input     (Window xwindow,
                                int    mask);
@@ -182,8 +189,6 @@
 			       int    width,
 			       int    height);
 
-void _wnck_set_dock_type_hint (Window xwindow);
-
 void _wnck_set_desktop_layout (Screen *xscreen,
                                int     rows,
                                int     columns);
@@ -205,8 +210,6 @@
                                                      int     current_token);
 gboolean _wnck_desktop_layout_manager_process_event (XEvent *xev);
 
-void _wnck_stock_icons_init (void);
-
 G_END_DECLS
 
 #endif /* WNCK_XUTILS_H */