|
Packit |
4e910c |
/* application object */
|
|
Packit |
4e910c |
/* vim: set sw=2 et: */
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
/*
|
|
Packit |
4e910c |
* Copyright (C) 2001 Havoc Pennington
|
|
Packit |
4e910c |
* Copyright (C) 2003 Red Hat, Inc.
|
|
Packit |
4e910c |
* Copyright (C) 2005-2007 Vincent Untz
|
|
Packit |
4e910c |
*
|
|
Packit |
4e910c |
* This library is free software; you can redistribute it and/or
|
|
Packit |
4e910c |
* modify it under the terms of the GNU Library General Public
|
|
Packit |
4e910c |
* License as published by the Free Software Foundation; either
|
|
Packit |
4e910c |
* version 2 of the License, or (at your option) any later version.
|
|
Packit |
4e910c |
*
|
|
Packit |
4e910c |
* This library is distributed in the hope that it will be useful,
|
|
Packit |
4e910c |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
4e910c |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit |
4e910c |
* Library General Public License for more details.
|
|
Packit |
4e910c |
*
|
|
Packit |
4e910c |
* You should have received a copy of the GNU Library General Public
|
|
Packit |
4e910c |
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
|
Packit |
4e910c |
*/
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
#include <config.h>
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
#include <glib/gi18n-lib.h>
|
|
Packit |
4e910c |
#include "application.h"
|
|
Packit |
4e910c |
#include "private.h"
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
/**
|
|
Packit |
4e910c |
* SECTION:application
|
|
Packit |
4e910c |
* @short_description: an object representing a group of windows of the same
|
|
Packit |
4e910c |
* application.
|
|
Packit |
4e910c |
* @see_also: wnck_window_get_application()
|
|
Packit |
4e910c |
* @stability: Unstable
|
|
Packit |
4e910c |
*
|
|
Packit |
4e910c |
* The #WnckApplication is a group of #WnckWindow that are all in the same
|
|
Packit |
4e910c |
* application. It can be used to represent windows by applications, group
|
|
Packit |
4e910c |
* windows by applications or to manipulate all windows of a particular
|
|
Packit |
4e910c |
* application.
|
|
Packit |
4e910c |
*
|
|
Packit |
4e910c |
* A #WnckApplication is identified by the group leader of the #WnckWindow
|
|
Packit |
4e910c |
* belonging to it, and new #WnckWindow are added to a #WnckApplication if and
|
|
Packit |
4e910c |
* only if they have the group leader of the #WnckApplication.
|
|
Packit |
4e910c |
*
|
|
Packit |
4e910c |
* The #WnckApplication objects are always owned by libwnck and must not be
|
|
Packit |
4e910c |
* referenced or unreferenced.
|
|
Packit |
4e910c |
*/
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
#define FALLBACK_NAME _("Untitled application")
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
static GHashTable *app_hash = NULL;
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
struct _WnckApplicationPrivate
|
|
Packit |
4e910c |
{
|
|
Packit |
4e910c |
Window xwindow; /* group leader */
|
|
Packit |
4e910c |
WnckScreen *screen;
|
|
Packit |
4e910c |
GList *windows;
|
|
Packit |
4e910c |
int pid;
|
|
Packit |
4e910c |
char *name;
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
int orig_event_mask;
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
WnckWindow *name_window; /* window we are using name of */
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
GdkPixbuf *icon;
|
|
Packit |
4e910c |
GdkPixbuf *mini_icon;
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
WnckIconCache *icon_cache;
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
WnckWindow *icon_window;
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
char *startup_id;
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
guint name_from_leader : 1; /* name is from group leader */
|
|
Packit |
4e910c |
guint icon_from_leader : 1;
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
guint need_emit_icon_changed : 1;
|
|
Packit |
4e910c |
};
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
G_DEFINE_TYPE (WnckApplication, wnck_application, G_TYPE_OBJECT);
|
|
Packit |
4e910c |
#define WNCK_APPLICATION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), WNCK_TYPE_APPLICATION, WnckApplicationPrivate))
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
enum {
|
|
Packit |
4e910c |
NAME_CHANGED,
|
|
Packit |
4e910c |
ICON_CHANGED,
|
|
Packit |
4e910c |
LAST_SIGNAL
|
|
Packit |
4e910c |
};
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
static void emit_name_changed (WnckApplication *app);
|
|
Packit |
4e910c |
static void emit_icon_changed (WnckApplication *app);
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
static void reset_name (WnckApplication *app);
|
|
Packit |
4e910c |
static void update_name (WnckApplication *app);
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
static void wnck_application_finalize (GObject *object);
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
static guint signals[LAST_SIGNAL] = { 0 };
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
void
|
|
Packit |
4e910c |
_wnck_application_shutdown_all (void)
|
|
Packit |
4e910c |
{
|
|
Packit |
4e910c |
if (app_hash != NULL)
|
|
Packit |
4e910c |
{
|
|
Packit |
4e910c |
g_hash_table_destroy (app_hash);
|
|
Packit |
4e910c |
app_hash = NULL;
|
|
Packit |
4e910c |
}
|
|
Packit |
4e910c |
}
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
static void
|
|
Packit |
4e910c |
wnck_application_init (WnckApplication *application)
|
|
Packit |
4e910c |
{
|
|
Packit |
4e910c |
application->priv = WNCK_APPLICATION_GET_PRIVATE (application);
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
application->priv->icon_cache = _wnck_icon_cache_new ();
|
|
Packit |
4e910c |
_wnck_icon_cache_set_want_fallback (application->priv->icon_cache, FALSE);
|
|
Packit |
4e910c |
}
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
static void
|
|
Packit |
4e910c |
wnck_application_class_init (WnckApplicationClass *klass)
|
|
Packit |
4e910c |
{
|
|
Packit |
4e910c |
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
g_type_class_add_private (klass, sizeof (WnckApplicationPrivate));
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
object_class->finalize = wnck_application_finalize;
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
/**
|
|
Packit |
4e910c |
* WnckApplication::name-changed:
|
|
Packit |
4e910c |
* @app: the #WnckApplication which emitted the signal.
|
|
Packit |
4e910c |
*
|
|
Packit |
4e910c |
* Emitted when the name of @app changes.
|
|
Packit |
4e910c |
*/
|
|
Packit |
4e910c |
signals[NAME_CHANGED] =
|
|
Packit |
4e910c |
g_signal_new ("name_changed",
|
|
Packit |
4e910c |
G_OBJECT_CLASS_TYPE (object_class),
|
|
Packit |
4e910c |
G_SIGNAL_RUN_LAST,
|
|
Packit |
4e910c |
G_STRUCT_OFFSET (WnckApplicationClass, name_changed),
|
|
Packit |
4e910c |
NULL, NULL, NULL,
|
|
Packit |
4e910c |
G_TYPE_NONE, 0);
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
/**
|
|
Packit |
4e910c |
* WnckApplication::icon-changed:
|
|
Packit |
4e910c |
* @app: the #WnckApplication which emitted the signal.
|
|
Packit |
4e910c |
*
|
|
Packit |
4e910c |
* Emitted when the icon of @app changes.
|
|
Packit |
4e910c |
*/
|
|
Packit |
4e910c |
signals[ICON_CHANGED] =
|
|
Packit |
4e910c |
g_signal_new ("icon_changed",
|
|
Packit |
4e910c |
G_OBJECT_CLASS_TYPE (object_class),
|
|
Packit |
4e910c |
G_SIGNAL_RUN_LAST,
|
|
Packit |
4e910c |
G_STRUCT_OFFSET (WnckApplicationClass, icon_changed),
|
|
Packit |
4e910c |
NULL, NULL, NULL,
|
|
Packit |
4e910c |
G_TYPE_NONE, 0);
|
|
Packit |
4e910c |
}
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
static void
|
|
Packit |
4e910c |
wnck_application_finalize (GObject *object)
|
|
Packit |
4e910c |
{
|
|
Packit |
4e910c |
WnckApplication *application;
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
application = WNCK_APPLICATION (object);
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
_wnck_select_input (WNCK_SCREEN_XSCREEN (application->priv->screen),
|
|
Packit |
4e910c |
application->priv->xwindow,
|
|
Packit |
4e910c |
application->priv->orig_event_mask,
|
|
Packit |
4e910c |
FALSE);
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
application->priv->xwindow = None;
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
g_list_free (application->priv->windows);
|
|
Packit |
4e910c |
application->priv->windows = NULL;
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
g_free (application->priv->name);
|
|
Packit |
4e910c |
application->priv->name = NULL;
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
if (application->priv->icon)
|
|
Packit |
4e910c |
g_object_unref (G_OBJECT (application->priv->icon));
|
|
Packit |
4e910c |
application->priv->icon = NULL;
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
if (application->priv->mini_icon)
|
|
Packit |
4e910c |
g_object_unref (G_OBJECT (application->priv->mini_icon));
|
|
Packit |
4e910c |
application->priv->mini_icon = NULL;
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
_wnck_icon_cache_free (application->priv->icon_cache);
|
|
Packit |
4e910c |
application->priv->icon_cache = NULL;
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
g_free (application->priv->startup_id);
|
|
Packit |
4e910c |
application->priv->startup_id = NULL;
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
G_OBJECT_CLASS (wnck_application_parent_class)->finalize (object);
|
|
Packit |
4e910c |
}
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
/**
|
|
Packit |
4e910c |
* wnck_application_get:
|
|
Packit |
4e910c |
* @xwindow: the X window ID of a group leader.
|
|
Packit |
4e910c |
*
|
|
Packit |
4e910c |
* Gets the #WnckApplication corresponding to the group leader with @xwindow
|
|
Packit |
4e910c |
* as X window ID.
|
|
Packit |
4e910c |
*
|
|
Packit |
4e910c |
* Return value: (transfer none): the #WnckApplication corresponding to
|
|
Packit |
4e910c |
* @xwindow, or %NULL if there no such #WnckApplication could be found. The
|
|
Packit |
4e910c |
* returned #WnckApplication is owned by libwnck and must not be referenced or
|
|
Packit |
4e910c |
* unreferenced.
|
|
Packit |
4e910c |
*/
|
|
Packit |
4e910c |
WnckApplication*
|
|
Packit |
4e910c |
wnck_application_get (gulong xwindow)
|
|
Packit |
4e910c |
{
|
|
Packit |
4e910c |
if (app_hash == NULL)
|
|
Packit |
4e910c |
return NULL;
|
|
Packit |
4e910c |
else
|
|
Packit |
4e910c |
return g_hash_table_lookup (app_hash, &xwindow);
|
|
Packit |
4e910c |
}
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
/**
|
|
Packit |
4e910c |
* wnck_application_get_xid:
|
|
Packit |
4e910c |
* @app: a #WnckApplication.
|
|
Packit |
4e910c |
*
|
|
Packit |
4e910c |
* Gets the X window ID of the group leader window for @app.
|
|
Packit |
4e910c |
*
|
|
Packit |
4e910c |
* Return value: the X window ID of the group leader window for @app.
|
|
Packit |
4e910c |
**/
|
|
Packit |
4e910c |
gulong
|
|
Packit |
4e910c |
wnck_application_get_xid (WnckApplication *app)
|
|
Packit |
4e910c |
{
|
|
Packit |
4e910c |
g_return_val_if_fail (WNCK_IS_APPLICATION (app), 0);
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
return app->priv->xwindow;
|
|
Packit |
4e910c |
}
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
/**
|
|
Packit |
4e910c |
* wnck_application_get_windows:
|
|
Packit |
4e910c |
* @app: a #WnckApplication.
|
|
Packit |
4e910c |
*
|
|
Packit |
4e910c |
* Gets the list of #WnckWindow belonging to @app.
|
|
Packit |
4e910c |
*
|
|
Packit |
4e910c |
* Return value: (element-type WnckWindow) (transfer none): the list of
|
|
Packit |
4e910c |
* #WnckWindow belonging to @app, or %NULL if the application contains no
|
|
Packit |
4e910c |
* window. The list should not be modified nor freed, as it is owned by @app.
|
|
Packit |
4e910c |
**/
|
|
Packit |
4e910c |
GList*
|
|
Packit |
4e910c |
wnck_application_get_windows (WnckApplication *app)
|
|
Packit |
4e910c |
{
|
|
Packit |
4e910c |
g_return_val_if_fail (WNCK_IS_APPLICATION (app), NULL);
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
return app->priv->windows;
|
|
Packit |
4e910c |
}
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
/**
|
|
Packit |
4e910c |
* wnck_application_get_n_windows:
|
|
Packit |
4e910c |
* @app: a #WnckApplication.
|
|
Packit |
4e910c |
*
|
|
Packit |
4e910c |
* Gets the number of #WnckWindow belonging to @app.
|
|
Packit |
4e910c |
*
|
|
Packit |
4e910c |
* Return value: the number of #WnckWindow belonging to @app.
|
|
Packit |
4e910c |
**/
|
|
Packit |
4e910c |
int
|
|
Packit |
4e910c |
wnck_application_get_n_windows (WnckApplication *app)
|
|
Packit |
4e910c |
{
|
|
Packit |
4e910c |
g_return_val_if_fail (WNCK_IS_APPLICATION (app), 0);
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
return g_list_length (app->priv->windows);
|
|
Packit |
4e910c |
}
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
/**
|
|
Packit |
4e910c |
* wnck_application_get_name:
|
|
Packit |
4e910c |
* @app: a #WnckApplication.
|
|
Packit |
4e910c |
*
|
|
Packit |
4e910c |
* Gets the name of @app. Since there is no way to properly find this name,
|
|
Packit |
4e910c |
* various suboptimal heuristics are used to find it. GTK+ should probably have
|
|
Packit |
4e910c |
* a function to allow applications to set the _NET_WM_NAME property on the
|
|
Packit |
4e910c |
* group leader as the application name, and the
|
|
Packit |
4e910c |
* url="http://standards.freedesktop.org/wm-spec/wm-spec-latest.html">EWMH</ulink>
|
|
Packit |
4e910c |
* should say that this is where the application name goes.
|
|
Packit |
4e910c |
*
|
|
Packit |
4e910c |
* Return value: the name of @app, or a fallback name if no name is available.
|
|
Packit |
4e910c |
**/
|
|
Packit |
4e910c |
const char*
|
|
Packit |
4e910c |
wnck_application_get_name (WnckApplication *app)
|
|
Packit |
4e910c |
{
|
|
Packit |
4e910c |
g_return_val_if_fail (WNCK_IS_APPLICATION (app), NULL);
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
if (app->priv->name)
|
|
Packit |
4e910c |
return app->priv->name;
|
|
Packit |
4e910c |
else
|
|
Packit |
4e910c |
return FALLBACK_NAME;
|
|
Packit |
4e910c |
}
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
/**
|
|
Packit |
4e910c |
* wnck_application_get_icon_name:
|
|
Packit |
4e910c |
* @app: a #WnckApplication
|
|
Packit |
4e910c |
*
|
|
Packit |
4e910c |
* Gets the icon name of @app (to be used when @app is minimized). Since
|
|
Packit |
4e910c |
* there is no way to properly find this name, various suboptimal heuristics
|
|
Packit |
4e910c |
* are used to find it.
|
|
Packit |
4e910c |
*
|
|
Packit |
4e910c |
* Return value: the icon name of @app, or a fallback icon name if no icon name
|
|
Packit |
4e910c |
* is available.
|
|
Packit |
4e910c |
**/
|
|
Packit |
4e910c |
const char*
|
|
Packit |
4e910c |
wnck_application_get_icon_name (WnckApplication *app)
|
|
Packit |
4e910c |
{
|
|
Packit |
4e910c |
g_return_val_if_fail (WNCK_IS_APPLICATION (app), NULL);
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
/* FIXME this isn't actually implemented, should be different
|
|
Packit |
4e910c |
* from regular name
|
|
Packit |
4e910c |
*/
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
if (app->priv->name)
|
|
Packit |
4e910c |
return app->priv->name;
|
|
Packit |
4e910c |
else
|
|
Packit |
4e910c |
return FALLBACK_NAME;
|
|
Packit |
4e910c |
}
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
/**
|
|
Packit |
4e910c |
* wnck_application_get_pid:
|
|
Packit |
4e910c |
* @app: a #WnckApplication.
|
|
Packit |
4e910c |
*
|
|
Packit |
4e910c |
* Gets the process ID of @app.
|
|
Packit |
4e910c |
*
|
|
Packit |
4e910c |
* Return value: the process ID of @app, or 0 if none is available.
|
|
Packit |
4e910c |
**/
|
|
Packit |
4e910c |
int
|
|
Packit |
4e910c |
wnck_application_get_pid (WnckApplication *app)
|
|
Packit |
4e910c |
{
|
|
Packit |
4e910c |
g_return_val_if_fail (WNCK_IS_APPLICATION (app), 0);
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
return app->priv->pid;
|
|
Packit |
4e910c |
}
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
static void
|
|
Packit |
4e910c |
get_icons (WnckApplication *app)
|
|
Packit |
4e910c |
{
|
|
Packit |
4e910c |
GdkPixbuf *icon;
|
|
Packit |
4e910c |
GdkPixbuf *mini_icon;
|
|
Packit |
4e910c |
gsize normal_size;
|
|
Packit |
4e910c |
gsize mini_size;
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
icon = NULL;
|
|
Packit |
4e910c |
mini_icon = NULL;
|
|
Packit |
4e910c |
normal_size = _wnck_get_default_icon_size ();
|
|
Packit |
4e910c |
mini_size = _wnck_get_default_mini_icon_size ();
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
if (_wnck_read_icons (WNCK_SCREEN_XSCREEN (app->priv->screen),
|
|
Packit |
4e910c |
app->priv->xwindow,
|
|
Packit |
4e910c |
app->priv->icon_cache,
|
|
Packit |
4e910c |
&icon, normal_size, normal_size,
|
|
Packit |
4e910c |
&mini_icon, mini_size, mini_size))
|
|
Packit |
4e910c |
{
|
|
Packit |
4e910c |
app->priv->need_emit_icon_changed = TRUE;
|
|
Packit |
4e910c |
app->priv->icon_from_leader = TRUE;
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
if (app->priv->icon)
|
|
Packit |
4e910c |
g_object_unref (G_OBJECT (app->priv->icon));
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
if (app->priv->mini_icon)
|
|
Packit |
4e910c |
g_object_unref (G_OBJECT (app->priv->mini_icon));
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
app->priv->icon = icon;
|
|
Packit |
4e910c |
app->priv->mini_icon = mini_icon;
|
|
Packit |
4e910c |
}
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
/* FIXME we should really fall back to using the icon
|
|
Packit |
4e910c |
* for one of the windows. But then we need to be more
|
|
Packit |
4e910c |
* complicated about icon_changed and when the icon
|
|
Packit |
4e910c |
* needs updating and all that.
|
|
Packit |
4e910c |
*/
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
g_assert ((app->priv->icon && app->priv->mini_icon) ||
|
|
Packit |
4e910c |
!(app->priv->icon || app->priv->mini_icon));
|
|
Packit |
4e910c |
}
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
void
|
|
Packit |
4e910c |
_wnck_application_load_icons (WnckApplication *app)
|
|
Packit |
4e910c |
{
|
|
Packit |
4e910c |
g_return_if_fail (WNCK_IS_APPLICATION (app));
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
get_icons (app);
|
|
Packit |
4e910c |
if (app->priv->need_emit_icon_changed)
|
|
Packit |
4e910c |
emit_icon_changed (app);
|
|
Packit |
4e910c |
}
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
/* Prefer to get group icon from a window of type "normal" */
|
|
Packit |
4e910c |
static WnckWindow*
|
|
Packit |
4e910c |
find_icon_window (WnckApplication *app)
|
|
Packit |
4e910c |
{
|
|
Packit |
4e910c |
GList *tmp;
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
tmp = app->priv->windows;
|
|
Packit |
4e910c |
while (tmp != NULL)
|
|
Packit |
4e910c |
{
|
|
Packit |
4e910c |
WnckWindow *w = tmp->data;
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
if (wnck_window_get_window_type (w) == WNCK_WINDOW_NORMAL)
|
|
Packit |
4e910c |
return w;
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
tmp = tmp->next;
|
|
Packit |
4e910c |
}
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
if (app->priv->windows)
|
|
Packit |
4e910c |
return app->priv->windows->data;
|
|
Packit |
4e910c |
else
|
|
Packit |
4e910c |
return NULL;
|
|
Packit |
4e910c |
}
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
/**
|
|
Packit |
4e910c |
* wnck_application_get_icon:
|
|
Packit |
4e910c |
* @app: a #WnckApplication.
|
|
Packit |
4e910c |
*
|
|
Packit |
4e910c |
* Gets the icon to be used for @app. If no icon is set for @app, a
|
|
Packit |
4e910c |
* suboptimal heuristic is used to find an appropriate icon. If no icon was
|
|
Packit |
4e910c |
* found, a fallback icon is used.
|
|
Packit |
4e910c |
*
|
|
Packit |
4e910c |
* Return value: (transfer none): the icon for @app. The caller should
|
|
Packit |
4e910c |
* reference the returned <classname>GdkPixbuf</classname> if it needs to keep
|
|
Packit |
4e910c |
* the icon around.
|
|
Packit |
4e910c |
**/
|
|
Packit |
4e910c |
GdkPixbuf*
|
|
Packit |
4e910c |
wnck_application_get_icon (WnckApplication *app)
|
|
Packit |
4e910c |
{
|
|
Packit |
4e910c |
g_return_val_if_fail (WNCK_IS_APPLICATION (app), NULL);
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
_wnck_application_load_icons (app);
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
if (app->priv->icon)
|
|
Packit |
4e910c |
return app->priv->icon;
|
|
Packit |
4e910c |
else
|
|
Packit |
4e910c |
{
|
|
Packit |
4e910c |
WnckWindow *w = find_icon_window (app);
|
|
Packit |
4e910c |
if (w)
|
|
Packit |
4e910c |
return wnck_window_get_icon (w);
|
|
Packit |
4e910c |
else
|
|
Packit |
4e910c |
return NULL;
|
|
Packit |
4e910c |
}
|
|
Packit |
4e910c |
}
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
/**
|
|
Packit |
4e910c |
* wnck_application_get_mini_icon:
|
|
Packit |
4e910c |
* @app: a #WnckApplication.
|
|
Packit |
4e910c |
*
|
|
Packit |
4e910c |
* Gets the mini-icon to be used for @app. If no mini-icon is set for @app,
|
|
Packit |
4e910c |
* a suboptimal heuristic is used to find an appropriate icon. If no mini-icon
|
|
Packit |
4e910c |
* was found, a fallback mini-icon is used.
|
|
Packit |
4e910c |
*
|
|
Packit |
4e910c |
* Return value: (transfer none): the mini-icon for @app. The caller should
|
|
Packit |
4e910c |
* reference the returned <classname>GdkPixbuf</classname> if it needs to keep
|
|
Packit |
4e910c |
* the mini-icon around.
|
|
Packit |
4e910c |
**/
|
|
Packit |
4e910c |
GdkPixbuf*
|
|
Packit |
4e910c |
wnck_application_get_mini_icon (WnckApplication *app)
|
|
Packit |
4e910c |
{
|
|
Packit |
4e910c |
g_return_val_if_fail (WNCK_IS_APPLICATION (app), NULL);
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
_wnck_application_load_icons (app);
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
if (app->priv->mini_icon)
|
|
Packit |
4e910c |
return app->priv->mini_icon;
|
|
Packit |
4e910c |
else
|
|
Packit |
4e910c |
{
|
|
Packit |
4e910c |
WnckWindow *w = find_icon_window (app);
|
|
Packit |
4e910c |
if (w)
|
|
Packit |
4e910c |
return wnck_window_get_mini_icon (w);
|
|
Packit |
4e910c |
else
|
|
Packit |
4e910c |
return NULL;
|
|
Packit |
4e910c |
}
|
|
Packit |
4e910c |
}
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
/**
|
|
Packit |
4e910c |
* wnck_application_get_icon_is_fallback:
|
|
Packit |
4e910c |
* @app: a #WnckApplication
|
|
Packit |
4e910c |
*
|
|
Packit |
4e910c |
* Gets whether a default fallback icon is used for @app (because none
|
|
Packit |
4e910c |
* was set on @app).
|
|
Packit |
4e910c |
*
|
|
Packit |
4e910c |
* Return value: %TRUE if the icon for @app is a fallback, %FALSE otherwise.
|
|
Packit |
4e910c |
**/
|
|
Packit |
4e910c |
gboolean
|
|
Packit |
4e910c |
wnck_application_get_icon_is_fallback (WnckApplication *app)
|
|
Packit |
4e910c |
{
|
|
Packit |
4e910c |
g_return_val_if_fail (WNCK_IS_APPLICATION (app), FALSE);
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
if (app->priv->icon)
|
|
Packit |
4e910c |
return FALSE;
|
|
Packit |
4e910c |
else
|
|
Packit |
4e910c |
{
|
|
Packit |
4e910c |
WnckWindow *w = find_icon_window (app);
|
|
Packit |
4e910c |
if (w)
|
|
Packit |
4e910c |
return wnck_window_get_icon_is_fallback (w);
|
|
Packit |
4e910c |
else
|
|
Packit |
4e910c |
return TRUE;
|
|
Packit |
4e910c |
}
|
|
Packit |
4e910c |
}
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
/**
|
|
Packit |
4e910c |
* wnck_application_get_startup_id:
|
|
Packit |
4e910c |
* @app: a #WnckApplication.
|
|
Packit |
4e910c |
*
|
|
Packit |
4e910c |
* Gets the startup sequence ID used for startup notification of @app.
|
|
Packit |
4e910c |
*
|
|
Packit |
4e910c |
* Return value: the startup sequence ID used for startup notification of @app,
|
|
Packit |
4e910c |
* or %NULL if none is available.
|
|
Packit |
4e910c |
*
|
|
Packit |
4e910c |
* Since: 2.2
|
|
Packit |
4e910c |
*/
|
|
Packit |
4e910c |
const char*
|
|
Packit |
4e910c |
wnck_application_get_startup_id (WnckApplication *app)
|
|
Packit |
4e910c |
{
|
|
Packit |
4e910c |
g_return_val_if_fail (WNCK_IS_APPLICATION (app), NULL);
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
return app->priv->startup_id;
|
|
Packit |
4e910c |
}
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
/* xwindow is a group leader */
|
|
Packit |
4e910c |
WnckApplication*
|
|
Packit |
4e910c |
_wnck_application_create (Window xwindow,
|
|
Packit |
4e910c |
WnckScreen *screen)
|
|
Packit |
4e910c |
{
|
|
Packit |
4e910c |
WnckApplication *application;
|
|
Packit |
4e910c |
Screen *xscreen;
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
if (app_hash == NULL)
|
|
Packit |
4e910c |
app_hash = g_hash_table_new_full (_wnck_xid_hash, _wnck_xid_equal,
|
|
Packit |
4e910c |
NULL, g_object_unref);
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
g_return_val_if_fail (g_hash_table_lookup (app_hash, &xwindow) == NULL,
|
|
Packit |
4e910c |
NULL);
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
xscreen = WNCK_SCREEN_XSCREEN (screen);
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
application = g_object_new (WNCK_TYPE_APPLICATION, NULL);
|
|
Packit |
4e910c |
application->priv->xwindow = xwindow;
|
|
Packit |
4e910c |
application->priv->screen = screen;
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
application->priv->name = _wnck_get_name (xscreen, xwindow);
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
if (application->priv->name == NULL)
|
|
Packit |
4e910c |
application->priv->name = _wnck_get_res_class_utf8 (xscreen, xwindow);
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
if (application->priv->name)
|
|
Packit |
4e910c |
application->priv->name_from_leader = TRUE;
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
application->priv->pid = _wnck_get_pid (xscreen,
|
|
Packit |
4e910c |
application->priv->xwindow);
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
application->priv->startup_id = _wnck_get_utf8_property (xscreen,
|
|
Packit |
4e910c |
application->priv->xwindow,
|
|
Packit |
4e910c |
_wnck_atom_get ("_NET_STARTUP_ID"));
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
g_hash_table_insert (app_hash, &application->priv->xwindow, application);
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
/* Hash now owns one ref, caller gets none */
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
/* Note that xwindow may correspond to a WnckWindow's xwindow,
|
|
Packit |
4e910c |
* so we select events needed by either
|
|
Packit |
4e910c |
*/
|
|
Packit |
4e910c |
application->priv->orig_event_mask = _wnck_select_input (xscreen,
|
|
Packit |
4e910c |
application->priv->xwindow,
|
|
Packit |
4e910c |
WNCK_APP_WINDOW_EVENT_MASK,
|
|
Packit |
4e910c |
TRUE);
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
return application;
|
|
Packit |
4e910c |
}
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
void
|
|
Packit |
4e910c |
_wnck_application_destroy (WnckApplication *application)
|
|
Packit |
4e910c |
{
|
|
Packit |
4e910c |
Window xwindow = application->priv->xwindow;
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
g_return_if_fail (wnck_application_get (xwindow) == application);
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
g_hash_table_remove (app_hash, &xwindow);
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
/* Removing from hash also removes the only ref WnckApplication had */
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
g_return_if_fail (wnck_application_get (xwindow) == NULL);
|
|
Packit |
4e910c |
}
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
static void
|
|
Packit |
4e910c |
window_name_changed (WnckWindow *window,
|
|
Packit |
4e910c |
WnckApplication *app)
|
|
Packit |
4e910c |
{
|
|
Packit |
4e910c |
if (window == app->priv->name_window)
|
|
Packit |
4e910c |
{
|
|
Packit |
4e910c |
reset_name (app);
|
|
Packit |
4e910c |
update_name (app);
|
|
Packit |
4e910c |
}
|
|
Packit |
4e910c |
}
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
void
|
|
Packit |
4e910c |
_wnck_application_add_window (WnckApplication *app,
|
|
Packit |
4e910c |
WnckWindow *window)
|
|
Packit |
4e910c |
{
|
|
Packit |
4e910c |
g_return_if_fail (WNCK_IS_APPLICATION (app));
|
|
Packit |
4e910c |
g_return_if_fail (WNCK_IS_WINDOW (window));
|
|
Packit |
4e910c |
g_return_if_fail (wnck_window_get_application (window) == NULL);
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
app->priv->windows = g_list_prepend (app->priv->windows, window);
|
|
Packit |
4e910c |
_wnck_window_set_application (window, app);
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
g_signal_connect (G_OBJECT (window), "name_changed",
|
|
Packit |
4e910c |
G_CALLBACK (window_name_changed), app);
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
/* emits signals, so do it last */
|
|
Packit |
4e910c |
reset_name (app);
|
|
Packit |
4e910c |
update_name (app);
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
/* see if we're using icon from a window */
|
|
Packit |
4e910c |
if (app->priv->icon == NULL ||
|
|
Packit |
4e910c |
app->priv->mini_icon == NULL)
|
|
Packit |
4e910c |
emit_icon_changed (app);
|
|
Packit |
4e910c |
}
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
void
|
|
Packit |
4e910c |
_wnck_application_remove_window (WnckApplication *app,
|
|
Packit |
4e910c |
WnckWindow *window)
|
|
Packit |
4e910c |
{
|
|
Packit |
4e910c |
g_return_if_fail (WNCK_IS_APPLICATION (app));
|
|
Packit |
4e910c |
g_return_if_fail (WNCK_IS_WINDOW (window));
|
|
Packit |
4e910c |
g_return_if_fail (wnck_window_get_application (window) == app);
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
app->priv->windows = g_list_remove (app->priv->windows, window);
|
|
Packit |
4e910c |
_wnck_window_set_application (window, NULL);
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
g_signal_handlers_disconnect_by_func (G_OBJECT (window),
|
|
Packit |
4e910c |
window_name_changed, app);
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
/* emits signals, so do it last */
|
|
Packit |
4e910c |
reset_name (app);
|
|
Packit |
4e910c |
update_name (app);
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
/* see if we're using icon from a window */
|
|
Packit |
4e910c |
if (app->priv->icon == NULL ||
|
|
Packit |
4e910c |
app->priv->mini_icon == NULL)
|
|
Packit |
4e910c |
emit_icon_changed (app);
|
|
Packit |
4e910c |
}
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
void
|
|
Packit |
4e910c |
_wnck_application_process_property_notify (WnckApplication *app,
|
|
Packit |
4e910c |
XEvent *xevent)
|
|
Packit |
4e910c |
{
|
|
Packit |
4e910c |
/* This prop notify is on the leader window */
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
if (xevent->xproperty.atom == XA_WM_NAME ||
|
|
Packit |
4e910c |
xevent->xproperty.atom ==
|
|
Packit |
4e910c |
_wnck_atom_get ("_NET_WM_NAME") ||
|
|
Packit |
4e910c |
xevent->xproperty.atom ==
|
|
Packit |
4e910c |
_wnck_atom_get ("_NET_WM_VISIBLE_NAME"))
|
|
Packit |
4e910c |
{
|
|
Packit |
4e910c |
/* FIXME should change the name */
|
|
Packit |
4e910c |
}
|
|
Packit |
4e910c |
else if (xevent->xproperty.atom ==
|
|
Packit |
4e910c |
XA_WM_ICON_NAME ||
|
|
Packit |
4e910c |
xevent->xproperty.atom ==
|
|
Packit |
4e910c |
_wnck_atom_get ("_NET_WM_ICON_NAME") ||
|
|
Packit |
4e910c |
xevent->xproperty.atom ==
|
|
Packit |
4e910c |
_wnck_atom_get ("_NET_WM_VISIBLE_ICON_NAME"))
|
|
Packit |
4e910c |
{
|
|
Packit |
4e910c |
/* FIXME */
|
|
Packit |
4e910c |
}
|
|
Packit |
4e910c |
else if (xevent->xproperty.atom ==
|
|
Packit |
4e910c |
_wnck_atom_get ("_NET_WM_ICON") ||
|
|
Packit |
4e910c |
xevent->xproperty.atom ==
|
|
Packit |
4e910c |
_wnck_atom_get ("KWM_WIN_ICON") ||
|
|
Packit |
4e910c |
xevent->xproperty.atom ==
|
|
Packit |
4e910c |
_wnck_atom_get ("WM_NORMAL_HINTS"))
|
|
Packit |
4e910c |
{
|
|
Packit |
4e910c |
_wnck_icon_cache_property_changed (app->priv->icon_cache,
|
|
Packit |
4e910c |
xevent->xproperty.atom);
|
|
Packit |
4e910c |
emit_icon_changed (app);
|
|
Packit |
4e910c |
}
|
|
Packit |
4e910c |
else if (xevent->xproperty.atom ==
|
|
Packit |
4e910c |
_wnck_atom_get ("_NET_STARTUP_ID"))
|
|
Packit |
4e910c |
{
|
|
Packit |
4e910c |
/* FIXME update startup id */
|
|
Packit |
4e910c |
}
|
|
Packit |
4e910c |
}
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
static void
|
|
Packit |
4e910c |
emit_name_changed (WnckApplication *app)
|
|
Packit |
4e910c |
{
|
|
Packit |
4e910c |
g_signal_emit (G_OBJECT (app),
|
|
Packit |
4e910c |
signals[NAME_CHANGED],
|
|
Packit |
4e910c |
0);
|
|
Packit |
4e910c |
}
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
static void
|
|
Packit |
4e910c |
emit_icon_changed (WnckApplication *app)
|
|
Packit |
4e910c |
{
|
|
Packit |
4e910c |
app->priv->need_emit_icon_changed = FALSE;
|
|
Packit |
4e910c |
g_signal_emit (G_OBJECT (app),
|
|
Packit |
4e910c |
signals[ICON_CHANGED],
|
|
Packit |
4e910c |
0);
|
|
Packit |
4e910c |
}
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
static void
|
|
Packit |
4e910c |
reset_name (WnckApplication *app)
|
|
Packit |
4e910c |
{
|
|
Packit |
4e910c |
if (!app->priv->name_from_leader)
|
|
Packit |
4e910c |
{
|
|
Packit |
4e910c |
g_free (app->priv->name);
|
|
Packit |
4e910c |
app->priv->name = NULL;
|
|
Packit |
4e910c |
app->priv->name_window = NULL;
|
|
Packit |
4e910c |
}
|
|
Packit |
4e910c |
}
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
static void
|
|
Packit |
4e910c |
update_name (WnckApplication *app)
|
|
Packit |
4e910c |
{
|
|
Packit |
4e910c |
g_assert (app->priv->name_from_leader || app->priv->name == NULL);
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
if (app->priv->name == NULL)
|
|
Packit |
4e910c |
{
|
|
Packit |
4e910c |
/* if only one window, get name from there. If more than one and
|
|
Packit |
4e910c |
* they all have the same res_class, use that. Else we want to
|
|
Packit |
4e910c |
* use the fallback name, since using the title of one of the
|
|
Packit |
4e910c |
* windows would look wrong.
|
|
Packit |
4e910c |
*/
|
|
Packit |
4e910c |
if (app->priv->windows &&
|
|
Packit |
4e910c |
app->priv->windows->next == NULL)
|
|
Packit |
4e910c |
{
|
|
Packit |
4e910c |
app->priv->name =
|
|
Packit |
4e910c |
g_strdup (wnck_window_get_name (app->priv->windows->data));
|
|
Packit |
4e910c |
app->priv->name_window = app->priv->windows->data;
|
|
Packit |
4e910c |
emit_name_changed (app);
|
|
Packit |
4e910c |
}
|
|
Packit |
4e910c |
else if (app->priv->windows)
|
|
Packit |
4e910c |
{
|
|
Packit |
4e910c |
/* more than one */
|
|
Packit |
4e910c |
app->priv->name =
|
|
Packit |
4e910c |
_wnck_get_res_class_utf8 (WNCK_SCREEN_XSCREEN (app->priv->screen),
|
|
Packit |
4e910c |
wnck_window_get_xid (app->priv->windows->data));
|
|
Packit |
4e910c |
if (app->priv->name)
|
|
Packit |
4e910c |
{
|
|
Packit |
4e910c |
app->priv->name_window = app->priv->windows->data;
|
|
Packit |
4e910c |
emit_name_changed (app);
|
|
Packit |
4e910c |
}
|
|
Packit |
4e910c |
}
|
|
Packit |
4e910c |
}
|
|
Packit |
4e910c |
}
|