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 EWMH + * 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 + * GdkPixbuf 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 GdkPixbuf 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 WM_CLASS Property + * section (section 4.1.2.5) of the ICCCM. + * + * 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 GdkPixbuf 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 GdkPixbuf 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 -#include -#include #include +#include +#include #include -#include +#include #include #include #include +#include +#include + +#include + #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 +/** + * 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 #include +/** + * 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 + * GdkScreen 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 GdkScreenGdkScreenpriv->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 EWMH + * 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 Extended + * Window Manager Hints specification (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 GdkPixbuf 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 #include 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 #include 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 #include 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 #include 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 #include #ifdef HAVE_XRES #include #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 GtkWindow. + * + * 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 GdkDisplay. + * @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 GdkDisplay. + * @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 */ +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 -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 also 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 GdkPixbuf 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 GdkPixbuf 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 + * + * 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 and + * copyrighted by Sun. Sun (through Glynn Foster ) + * agreed to relicense it from the GPL to the LGPL. + */ + +#include +#include + +#include +#include + +#include + +#include +#include + +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 ("\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 ("\n"); + + g_print ("Icons: "); + if (!wnck_window_get_icon_is_fallback (window)) + g_print ("set\n"); + else + g_print ("\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: )"); + 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 ("\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 ("\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 ("\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 +/** + * SECTION:workspace + * @short_description: an object representing a workspace. + * @see_also: #WnckScreen + * @stability: Unstable + * + * The #WnckWorkspace represents what is called virtual + * desktops in the EWMH. + * 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 large + * desktops section of the EWMH. + * 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 */ -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 */