|
Packit |
4e910c |
/* util header */
|
|
Packit |
4e910c |
/* vim: set sw=2 et: */
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
/*
|
|
Packit |
4e910c |
* Copyright (C) 2001 Havoc Pennington
|
|
Packit |
4e910c |
* Copyright (C) 2006-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 "util.h"
|
|
Packit |
4e910c |
#include "xutils.h"
|
|
Packit |
4e910c |
#include "private.h"
|
|
Packit |
4e910c |
#include <gdk/gdkx.h>
|
|
Packit |
4e910c |
#include <string.h>
|
|
Packit |
4e910c |
#ifdef HAVE_XRES
|
|
Packit |
4e910c |
#include <X11/extensions/XRes.h>
|
|
Packit |
4e910c |
#endif
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
/**
|
|
Packit |
4e910c |
* SECTION:resource
|
|
Packit |
4e910c |
* @short_description: reading resource usage of X clients.
|
|
Packit |
4e910c |
* @see_also: wnck_window_get_xid(), wnck_application_get_xid(), wnck_window_get_pid(), wnck_application_get_pid()
|
|
Packit |
4e910c |
* @stability: Unstable
|
|
Packit |
4e910c |
*
|
|
Packit |
4e910c |
* libwnck provides an easy-to-use interface to the XRes X server extension to
|
|
Packit |
4e910c |
* read resource usage of X clients, which can be defined either by the X
|
|
Packit |
4e910c |
* window ID of one of their windows or by the process ID of their process.
|
|
Packit |
4e910c |
*/
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
/**
|
|
Packit |
4e910c |
* SECTION:misc
|
|
Packit |
4e910c |
* @short_description: other additional features.
|
|
Packit |
4e910c |
* @stability: Unstable
|
|
Packit |
4e910c |
*
|
|
Packit |
4e910c |
* These functions are utility functions providing some additional features to
|
|
Packit |
4e910c |
* libwnck users.
|
|
Packit |
4e910c |
*/
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
/**
|
|
Packit |
4e910c |
* SECTION:icons
|
|
Packit |
4e910c |
* @short_description: icons related functions.
|
|
Packit |
4e910c |
* @stability: Unstable
|
|
Packit |
4e910c |
*
|
|
Packit |
4e910c |
* These functions are utility functions to manage icons for #WnckWindow and
|
|
Packit |
4e910c |
* #WnckApplication.
|
|
Packit |
4e910c |
*/
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
typedef enum
|
|
Packit |
4e910c |
{
|
|
Packit |
4e910c |
WNCK_EXT_UNKNOWN = 0,
|
|
Packit |
4e910c |
WNCK_EXT_FOUND = 1,
|
|
Packit |
4e910c |
WNCK_EXT_MISSING = 2
|
|
Packit |
4e910c |
} WnckExtStatus;
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
#if 0
|
|
Packit |
4e910c |
/* useful for debugging */
|
|
Packit |
4e910c |
static void
|
|
Packit |
4e910c |
_wnck_print_resource_usage (WnckResourceUsage *usage)
|
|
Packit |
4e910c |
{
|
|
Packit |
4e910c |
if (!usage)
|
|
Packit |
4e910c |
return;
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
g_print ("\twindows : %d\n"
|
|
Packit |
4e910c |
"\tGCs : %d\n"
|
|
Packit |
4e910c |
"\tfonts : %d\n"
|
|
Packit |
4e910c |
"\tpixmaps : %d\n"
|
|
Packit |
4e910c |
"\tpictures : %d\n"
|
|
Packit |
4e910c |
"\tglyphsets : %d\n"
|
|
Packit |
4e910c |
"\tcolormaps : %d\n"
|
|
Packit |
4e910c |
"\tpassive grabs : %d\n"
|
|
Packit |
4e910c |
"\tcursors : %d\n"
|
|
Packit |
4e910c |
"\tunknowns : %d\n"
|
|
Packit |
4e910c |
"\tpixmap bytes : %ld\n"
|
|
Packit |
4e910c |
"\ttotal bytes : ~%ld\n",
|
|
Packit |
4e910c |
usage->n_windows,
|
|
Packit |
4e910c |
usage->n_gcs,
|
|
Packit |
4e910c |
usage->n_fonts,
|
|
Packit |
4e910c |
usage->n_pixmaps,
|
|
Packit |
4e910c |
usage->n_pictures,
|
|
Packit |
4e910c |
usage->n_glyphsets,
|
|
Packit |
4e910c |
usage->n_colormap_entries,
|
|
Packit |
4e910c |
usage->n_passive_grabs,
|
|
Packit |
4e910c |
usage->n_cursors,
|
|
Packit |
4e910c |
usage->n_other,
|
|
Packit |
4e910c |
usage->pixmap_bytes,
|
|
Packit |
4e910c |
usage->total_bytes_estimate);
|
|
Packit |
4e910c |
}
|
|
Packit |
4e910c |
#endif
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
static WnckExtStatus
|
|
Packit |
4e910c |
wnck_init_resource_usage (GdkDisplay *gdisplay)
|
|
Packit |
4e910c |
{
|
|
Packit |
4e910c |
WnckExtStatus status;
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
status = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (gdisplay),
|
|
Packit |
4e910c |
"wnck-xres-status"));
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
if (status == WNCK_EXT_UNKNOWN)
|
|
Packit |
4e910c |
{
|
|
Packit |
4e910c |
#ifdef HAVE_XRES
|
|
Packit |
4e910c |
Display *xdisplay = GDK_DISPLAY_XDISPLAY (gdisplay);
|
|
Packit |
4e910c |
int event, error;
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
if (!XResQueryExtension (xdisplay, &event, &error))
|
|
Packit |
4e910c |
status = WNCK_EXT_MISSING;
|
|
Packit |
4e910c |
else
|
|
Packit |
4e910c |
status = WNCK_EXT_FOUND;
|
|
Packit |
4e910c |
#else
|
|
Packit |
4e910c |
status = WNCK_EXT_MISSING;
|
|
Packit |
4e910c |
#endif
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
g_object_set_data (G_OBJECT (gdisplay),
|
|
Packit |
4e910c |
"wnck-xres-status",
|
|
Packit |
4e910c |
GINT_TO_POINTER (status));
|
|
Packit |
4e910c |
}
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
g_assert (status != WNCK_EXT_UNKNOWN);
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
return status;
|
|
Packit |
4e910c |
}
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
/**
|
|
Packit |
4e910c |
* wnck_xid_read_resource_usage:
|
|
Packit |
4e910c |
* @gdk_display: a <classname>GdkDisplay</classname>.
|
|
Packit |
4e910c |
* @xid: an X window ID.
|
|
Packit |
4e910c |
* @usage: return location for the X resource usage of the application owning
|
|
Packit |
4e910c |
* the X window ID @xid.
|
|
Packit |
4e910c |
*
|
|
Packit |
4e910c |
* Looks for the X resource usage of the application owning the X window ID
|
|
Packit |
4e910c |
* @xid on display @gdisplay. If no resource usage can be found, then all
|
|
Packit |
4e910c |
* fields of @usage are set to 0.
|
|
Packit |
4e910c |
*
|
|
Packit |
4e910c |
* To properly work, this function requires the XRes extension on the X server.
|
|
Packit |
4e910c |
*
|
|
Packit |
4e910c |
* Since: 2.6
|
|
Packit |
4e910c |
*/
|
|
Packit |
4e910c |
void
|
|
Packit |
4e910c |
wnck_xid_read_resource_usage (GdkDisplay *gdisplay,
|
|
Packit |
4e910c |
gulong xid,
|
|
Packit |
4e910c |
WnckResourceUsage *usage)
|
|
Packit |
4e910c |
{
|
|
Packit |
4e910c |
g_return_if_fail (usage != NULL);
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
memset (usage, '\0', sizeof (*usage));
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
if (wnck_init_resource_usage (gdisplay) == WNCK_EXT_MISSING)
|
|
Packit |
4e910c |
return;
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
#ifdef HAVE_XRES
|
|
Packit |
4e910c |
{
|
|
Packit |
4e910c |
Display *xdisplay;
|
|
Packit |
4e910c |
XResType *types;
|
|
Packit |
4e910c |
int n_types;
|
|
Packit |
4e910c |
unsigned long pixmap_bytes;
|
|
Packit |
4e910c |
int i;
|
|
Packit |
4e910c |
Atom pixmap_atom;
|
|
Packit |
4e910c |
Atom window_atom;
|
|
Packit |
4e910c |
Atom gc_atom;
|
|
Packit |
4e910c |
Atom picture_atom;
|
|
Packit |
4e910c |
Atom glyphset_atom;
|
|
Packit |
4e910c |
Atom font_atom;
|
|
Packit |
4e910c |
Atom colormap_entry_atom;
|
|
Packit |
4e910c |
Atom passive_grab_atom;
|
|
Packit |
4e910c |
Atom cursor_atom;
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
types = NULL;
|
|
Packit |
4e910c |
n_types = 0;
|
|
Packit |
4e910c |
pixmap_bytes = 0;
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
xdisplay = GDK_DISPLAY_XDISPLAY (gdisplay);
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
_wnck_error_trap_push (xdisplay);
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
XResQueryClientResources (xdisplay,
|
|
Packit |
4e910c |
xid, &n_types,
|
|
Packit |
4e910c |
&types);
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
XResQueryClientPixmapBytes (xdisplay,
|
|
Packit |
4e910c |
xid, &pixmap_bytes);
|
|
Packit |
4e910c |
_wnck_error_trap_pop (xdisplay);
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
usage->pixmap_bytes = pixmap_bytes;
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
pixmap_atom = _wnck_atom_get ("PIXMAP");
|
|
Packit |
4e910c |
window_atom = _wnck_atom_get ("WINDOW");
|
|
Packit |
4e910c |
gc_atom = _wnck_atom_get ("GC");
|
|
Packit |
4e910c |
font_atom = _wnck_atom_get ("FONT");
|
|
Packit |
4e910c |
glyphset_atom = _wnck_atom_get ("GLYPHSET");
|
|
Packit |
4e910c |
picture_atom = _wnck_atom_get ("PICTURE");
|
|
Packit |
4e910c |
colormap_entry_atom = _wnck_atom_get ("COLORMAP ENTRY");
|
|
Packit |
4e910c |
passive_grab_atom = _wnck_atom_get ("PASSIVE GRAB");
|
|
Packit |
4e910c |
cursor_atom = _wnck_atom_get ("CURSOR");
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
i = 0;
|
|
Packit |
4e910c |
while (i < n_types)
|
|
Packit |
4e910c |
{
|
|
Packit |
4e910c |
guint t = types[i].resource_type;
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
if (t == pixmap_atom)
|
|
Packit |
4e910c |
usage->n_pixmaps += types[i].count;
|
|
Packit |
4e910c |
else if (t == window_atom)
|
|
Packit |
4e910c |
usage->n_windows += types[i].count;
|
|
Packit |
4e910c |
else if (t == gc_atom)
|
|
Packit |
4e910c |
usage->n_gcs += types[i].count;
|
|
Packit |
4e910c |
else if (t == picture_atom)
|
|
Packit |
4e910c |
usage->n_pictures += types[i].count;
|
|
Packit |
4e910c |
else if (t == glyphset_atom)
|
|
Packit |
4e910c |
usage->n_glyphsets += types[i].count;
|
|
Packit |
4e910c |
else if (t == font_atom)
|
|
Packit |
4e910c |
usage->n_fonts += types[i].count;
|
|
Packit |
4e910c |
else if (t == colormap_entry_atom)
|
|
Packit |
4e910c |
usage->n_colormap_entries += types[i].count;
|
|
Packit |
4e910c |
else if (t == passive_grab_atom)
|
|
Packit |
4e910c |
usage->n_passive_grabs += types[i].count;
|
|
Packit |
4e910c |
else if (t == cursor_atom)
|
|
Packit |
4e910c |
usage->n_cursors += types[i].count;
|
|
Packit |
4e910c |
else
|
|
Packit |
4e910c |
usage->n_other += types[i].count;
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
++i;
|
|
Packit |
4e910c |
}
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
XFree(types);
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
usage->total_bytes_estimate = usage->pixmap_bytes;
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
/* FIXME look in the X server source and come up with better
|
|
Packit |
4e910c |
* answers here. Ideally we change XRes to return a number
|
|
Packit |
4e910c |
* like this since it can do things like divide the cost of
|
|
Packit |
4e910c |
* a shared resource among those sharing it.
|
|
Packit |
4e910c |
*/
|
|
Packit |
4e910c |
usage->total_bytes_estimate += usage->n_windows * 24;
|
|
Packit |
4e910c |
usage->total_bytes_estimate += usage->n_gcs * 24;
|
|
Packit |
4e910c |
usage->total_bytes_estimate += usage->n_pictures * 24;
|
|
Packit |
4e910c |
usage->total_bytes_estimate += usage->n_glyphsets * 24;
|
|
Packit |
4e910c |
usage->total_bytes_estimate += usage->n_fonts * 1024;
|
|
Packit |
4e910c |
usage->total_bytes_estimate += usage->n_colormap_entries * 24;
|
|
Packit |
4e910c |
usage->total_bytes_estimate += usage->n_passive_grabs * 24;
|
|
Packit |
4e910c |
usage->total_bytes_estimate += usage->n_cursors * 24;
|
|
Packit |
4e910c |
usage->total_bytes_estimate += usage->n_other * 24;
|
|
Packit |
4e910c |
}
|
|
Packit |
4e910c |
#else /* HAVE_XRES */
|
|
Packit |
4e910c |
g_assert_not_reached ();
|
|
Packit |
4e910c |
#endif /* HAVE_XRES */
|
|
Packit |
4e910c |
}
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
#ifdef HAVE_XRES
|
|
Packit |
4e910c |
static void
|
|
Packit |
4e910c |
wnck_pid_read_resource_usage_free_hash (gpointer data)
|
|
Packit |
4e910c |
{
|
|
Packit |
4e910c |
g_slice_free (gulong, data);
|
|
Packit |
4e910c |
}
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
static guint
|
|
Packit |
4e910c |
wnck_gulong_hash (gconstpointer v)
|
|
Packit |
4e910c |
{
|
|
Packit |
4e910c |
/* FIXME: this is obvioulsy wrong, but nearly 100% of the time, the gulong
|
|
Packit |
4e910c |
* only contains guint values */
|
|
Packit |
4e910c |
return *(const guint *) v;
|
|
Packit |
4e910c |
}
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
static gboolean
|
|
Packit |
4e910c |
wnck_gulong_equal (gconstpointer a,
|
|
Packit |
4e910c |
gconstpointer b)
|
|
Packit |
4e910c |
{
|
|
Packit |
4e910c |
return *((const gulong *) a) == *((const gulong *) b);
|
|
Packit |
4e910c |
}
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
static gulong
|
|
Packit |
4e910c |
wnck_check_window_for_pid (Screen *screen,
|
|
Packit |
4e910c |
Window win,
|
|
Packit |
4e910c |
XID match_xid,
|
|
Packit |
4e910c |
XID mask)
|
|
Packit |
4e910c |
{
|
|
Packit |
4e910c |
if ((win & ~mask) == match_xid) {
|
|
Packit |
4e910c |
return _wnck_get_pid (screen, win);
|
|
Packit |
4e910c |
}
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
return 0;
|
|
Packit |
4e910c |
}
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
static void
|
|
Packit |
4e910c |
wnck_find_pid_for_resource_r (Display *xdisplay,
|
|
Packit |
4e910c |
Screen *screen,
|
|
Packit |
4e910c |
Window win_top,
|
|
Packit |
4e910c |
XID match_xid,
|
|
Packit |
4e910c |
XID mask,
|
|
Packit |
4e910c |
gulong *xid,
|
|
Packit |
4e910c |
gulong *pid)
|
|
Packit |
4e910c |
{
|
|
Packit |
4e910c |
Status qtres;
|
|
Packit |
4e910c |
int err;
|
|
Packit |
4e910c |
Window dummy;
|
|
Packit |
4e910c |
Window *children;
|
|
Packit |
4e910c |
guint n_children;
|
|
Packit |
4e910c |
guint i;
|
|
Packit |
4e910c |
gulong found_pid = 0;
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
while (gtk_events_pending ())
|
|
Packit |
4e910c |
gtk_main_iteration ();
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
found_pid = wnck_check_window_for_pid (screen, win_top, match_xid, mask);
|
|
Packit |
4e910c |
if (found_pid != 0)
|
|
Packit |
4e910c |
{
|
|
Packit |
4e910c |
*xid = win_top;
|
|
Packit |
4e910c |
*pid = found_pid;
|
|
Packit |
4e910c |
}
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
_wnck_error_trap_push (xdisplay);
|
|
Packit |
4e910c |
qtres = XQueryTree (xdisplay, win_top, &dummy, &dummy,
|
|
Packit |
4e910c |
&children, &n_children);
|
|
Packit |
4e910c |
err = _wnck_error_trap_pop (xdisplay);
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
if (!qtres || err != Success)
|
|
Packit |
4e910c |
return;
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
for (i = 0; i < n_children; i++)
|
|
Packit |
4e910c |
{
|
|
Packit |
4e910c |
wnck_find_pid_for_resource_r (xdisplay, screen, children[i],
|
|
Packit |
4e910c |
match_xid, mask, xid, pid);
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
if (*pid != 0)
|
|
Packit |
4e910c |
break;
|
|
Packit |
4e910c |
}
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
if (children)
|
|
Packit |
4e910c |
XFree ((char *)children);
|
|
Packit |
4e910c |
}
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
struct xresclient_state
|
|
Packit |
4e910c |
{
|
|
Packit |
4e910c |
XResClient *clients;
|
|
Packit |
4e910c |
int n_clients;
|
|
Packit |
4e910c |
int next;
|
|
Packit |
4e910c |
Display *xdisplay;
|
|
Packit |
4e910c |
GHashTable *hashtable_pid;
|
|
Packit |
4e910c |
};
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
static struct xresclient_state xres_state = { NULL, 0, -1, NULL, NULL };
|
|
Packit |
4e910c |
static guint xres_idleid = 0;
|
|
Packit |
4e910c |
static GHashTable *xres_hashtable = NULL;
|
|
Packit |
4e910c |
static time_t start_update = 0;
|
|
Packit |
4e910c |
static time_t end_update = 0;
|
|
Packit |
4e910c |
static guint xres_removeid = 0;
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
static void
|
|
Packit |
4e910c |
wnck_pid_read_resource_usage_xres_state_free (gpointer data)
|
|
Packit |
4e910c |
{
|
|
Packit |
4e910c |
struct xresclient_state *state;
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
state = (struct xresclient_state *) data;
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
if (state->clients)
|
|
Packit |
4e910c |
XFree (state->clients);
|
|
Packit |
4e910c |
state->clients = NULL;
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
state->n_clients = 0;
|
|
Packit |
4e910c |
state->next = -1;
|
|
Packit |
4e910c |
state->xdisplay = NULL;
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
if (state->hashtable_pid)
|
|
Packit |
4e910c |
g_hash_table_destroy (state->hashtable_pid);
|
|
Packit |
4e910c |
state->hashtable_pid = NULL;
|
|
Packit |
4e910c |
}
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
static gboolean
|
|
Packit |
4e910c |
wnck_pid_read_resource_usage_fill_cache (struct xresclient_state *state)
|
|
Packit |
4e910c |
{
|
|
Packit |
4e910c |
int i;
|
|
Packit |
4e910c |
gulong pid;
|
|
Packit |
4e910c |
gulong xid;
|
|
Packit |
4e910c |
XID match_xid;
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
if (state->next >= state->n_clients)
|
|
Packit |
4e910c |
{
|
|
Packit |
4e910c |
if (xres_hashtable)
|
|
Packit |
4e910c |
g_hash_table_destroy (xres_hashtable);
|
|
Packit |
4e910c |
xres_hashtable = state->hashtable_pid;
|
|
Packit |
4e910c |
state->hashtable_pid = NULL;
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
time (&end_update);
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
xres_idleid = 0;
|
|
Packit |
4e910c |
return FALSE;
|
|
Packit |
4e910c |
}
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
match_xid = (state->clients[state->next].resource_base &
|
|
Packit |
4e910c |
~state->clients[state->next].resource_mask);
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
pid = 0;
|
|
Packit |
4e910c |
xid = 0;
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
for (i = 0; i < ScreenCount (state->xdisplay); i++)
|
|
Packit |
4e910c |
{
|
|
Packit |
4e910c |
Screen *screen;
|
|
Packit |
4e910c |
Window root;
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
screen = ScreenOfDisplay (state->xdisplay, i);
|
|
Packit |
4e910c |
root = RootWindow (state->xdisplay, i);
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
if (root == None)
|
|
Packit |
4e910c |
continue;
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
wnck_find_pid_for_resource_r (state->xdisplay, screen, root, match_xid,
|
|
Packit |
4e910c |
state->clients[state->next].resource_mask,
|
|
Packit |
4e910c |
&xid, &pid;;
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
if (pid != 0 && xid != 0)
|
|
Packit |
4e910c |
break;
|
|
Packit |
4e910c |
}
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
if (pid != 0 && xid != 0)
|
|
Packit |
4e910c |
{
|
|
Packit |
4e910c |
gulong *key;
|
|
Packit |
4e910c |
gulong *value;
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
key = g_slice_new (gulong);
|
|
Packit |
4e910c |
value = g_slice_new (gulong);
|
|
Packit |
4e910c |
*key = pid;
|
|
Packit |
4e910c |
*value = xid;
|
|
Packit |
4e910c |
g_hash_table_insert (state->hashtable_pid, key, value);
|
|
Packit |
4e910c |
}
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
state->next++;
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
return TRUE;
|
|
Packit |
4e910c |
}
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
static void
|
|
Packit |
4e910c |
wnck_pid_read_resource_usage_start_build_cache (GdkDisplay *gdisplay)
|
|
Packit |
4e910c |
{
|
|
Packit |
4e910c |
Display *xdisplay;
|
|
Packit |
4e910c |
int err;
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
if (xres_idleid != 0)
|
|
Packit |
4e910c |
return;
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
time (&start_update);
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
xdisplay = GDK_DISPLAY_XDISPLAY (gdisplay);
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
_wnck_error_trap_push (xdisplay);
|
|
Packit |
4e910c |
XResQueryClients (xdisplay, &xres_state.n_clients, &xres_state.clients);
|
|
Packit |
4e910c |
err = _wnck_error_trap_pop (xdisplay);
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
if (err != Success)
|
|
Packit |
4e910c |
return;
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
xres_state.next = (xres_state.n_clients > 0) ? 0 : -1;
|
|
Packit |
4e910c |
xres_state.xdisplay = xdisplay;
|
|
Packit |
4e910c |
xres_state.hashtable_pid = g_hash_table_new_full (
|
|
Packit |
4e910c |
wnck_gulong_hash,
|
|
Packit |
4e910c |
wnck_gulong_equal,
|
|
Packit |
4e910c |
wnck_pid_read_resource_usage_free_hash,
|
|
Packit |
4e910c |
wnck_pid_read_resource_usage_free_hash);
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
xres_idleid = g_idle_add_full (
|
|
Packit |
4e910c |
G_PRIORITY_HIGH_IDLE,
|
|
Packit |
4e910c |
(GSourceFunc) wnck_pid_read_resource_usage_fill_cache,
|
|
Packit |
4e910c |
&xres_state, wnck_pid_read_resource_usage_xres_state_free);
|
|
Packit |
4e910c |
}
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
static gboolean
|
|
Packit |
4e910c |
wnck_pid_read_resource_usage_destroy_hash_table (gpointer data)
|
|
Packit |
4e910c |
{
|
|
Packit |
4e910c |
xres_removeid = 0;
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
if (xres_hashtable)
|
|
Packit |
4e910c |
g_hash_table_destroy (xres_hashtable);
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
xres_hashtable = NULL;
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
return FALSE;
|
|
Packit |
4e910c |
}
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
#define XRES_UPDATE_RATE_SEC 30
|
|
Packit |
4e910c |
static gboolean
|
|
Packit |
4e910c |
wnck_pid_read_resource_usage_from_cache (GdkDisplay *gdisplay,
|
|
Packit |
4e910c |
gulong pid,
|
|
Packit |
4e910c |
WnckResourceUsage *usage)
|
|
Packit |
4e910c |
{
|
|
Packit |
4e910c |
gboolean need_rebuild;
|
|
Packit |
4e910c |
gulong *xid_p;
|
|
Packit |
4e910c |
int cache_validity;
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
if (end_update == 0)
|
|
Packit |
4e910c |
time (&end_update);
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
cache_validity = MAX (XRES_UPDATE_RATE_SEC, (end_update - start_update) * 2);
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
/* we rebuild the cache if it was never built or if it's old */
|
|
Packit |
4e910c |
need_rebuild = (xres_hashtable == NULL ||
|
|
Packit |
4e910c |
(end_update < time (NULL) - cache_validity));
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
if (xres_hashtable)
|
|
Packit |
4e910c |
{
|
|
Packit |
4e910c |
/* clear the cache after quite some time, because it might not be used
|
|
Packit |
4e910c |
* anymore */
|
|
Packit |
4e910c |
if (xres_removeid != 0)
|
|
Packit |
4e910c |
g_source_remove (xres_removeid);
|
|
Packit |
4e910c |
xres_removeid = g_timeout_add_seconds (cache_validity * 2,
|
|
Packit |
4e910c |
wnck_pid_read_resource_usage_destroy_hash_table,
|
|
Packit |
4e910c |
NULL);
|
|
Packit |
4e910c |
}
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
if (need_rebuild)
|
|
Packit |
4e910c |
wnck_pid_read_resource_usage_start_build_cache (gdisplay);
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
if (xres_hashtable)
|
|
Packit |
4e910c |
xid_p = g_hash_table_lookup (xres_hashtable, &pid;;
|
|
Packit |
4e910c |
else
|
|
Packit |
4e910c |
xid_p = NULL;
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
if (xid_p)
|
|
Packit |
4e910c |
{
|
|
Packit |
4e910c |
wnck_xid_read_resource_usage (gdisplay, *xid_p, usage);
|
|
Packit |
4e910c |
return TRUE;
|
|
Packit |
4e910c |
}
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
return FALSE;
|
|
Packit |
4e910c |
}
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
static void
|
|
Packit |
4e910c |
wnck_pid_read_resource_usage_no_cache (GdkDisplay *gdisplay,
|
|
Packit |
4e910c |
gulong pid,
|
|
Packit |
4e910c |
WnckResourceUsage *usage)
|
|
Packit |
4e910c |
{
|
|
Packit |
4e910c |
Display *xdisplay;
|
|
Packit |
4e910c |
int i;
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
xdisplay = GDK_DISPLAY_XDISPLAY (gdisplay);
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
i = 0;
|
|
Packit |
4e910c |
while (i < ScreenCount (xdisplay))
|
|
Packit |
4e910c |
{
|
|
Packit |
4e910c |
WnckScreen *screen;
|
|
Packit |
4e910c |
GList *windows;
|
|
Packit |
4e910c |
GList *tmp;
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
screen = wnck_screen_get (i);
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
g_assert (screen != NULL);
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
windows = wnck_screen_get_windows (screen);
|
|
Packit |
4e910c |
tmp = windows;
|
|
Packit |
4e910c |
while (tmp != NULL)
|
|
Packit |
4e910c |
{
|
|
Packit |
4e910c |
if (wnck_window_get_pid (tmp->data) == (int) pid)
|
|
Packit |
4e910c |
{
|
|
Packit |
4e910c |
wnck_xid_read_resource_usage (gdisplay,
|
|
Packit |
4e910c |
wnck_window_get_xid (tmp->data),
|
|
Packit |
4e910c |
usage);
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
/* stop on first window found */
|
|
Packit |
4e910c |
return;
|
|
Packit |
4e910c |
}
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
tmp = tmp->next;
|
|
Packit |
4e910c |
}
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
++i;
|
|
Packit |
4e910c |
}
|
|
Packit |
4e910c |
}
|
|
Packit |
4e910c |
#endif /* HAVE_XRES */
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
/**
|
|
Packit |
4e910c |
* wnck_pid_read_resource_usage:
|
|
Packit |
4e910c |
* @gdk_display: a <classname>GdkDisplay</classname>.
|
|
Packit |
4e910c |
* @pid: a process ID.
|
|
Packit |
4e910c |
* @usage: return location for the X resource usage of the application with
|
|
Packit |
4e910c |
* process ID @pid.
|
|
Packit |
4e910c |
*
|
|
Packit |
4e910c |
* Looks for the X resource usage of the application with process ID @pid on
|
|
Packit |
4e910c |
* display @gdisplay. If no resource usage can be found, then all fields of
|
|
Packit |
4e910c |
* @usage are set to 0.
|
|
Packit |
4e910c |
*
|
|
Packit |
4e910c |
* In order to find the resource usage of an application that does not have an
|
|
Packit |
4e910c |
* X window visible to libwnck (panel applets do not have any toplevel windows,
|
|
Packit |
4e910c |
* for example), wnck_pid_read_resource_usage() walks through the whole tree of
|
|
Packit |
4e910c |
* X windows. Since this walk is expensive in CPU, a cache is created. This
|
|
Packit |
4e910c |
* cache is updated in the background. This means there is a non-null
|
|
Packit |
4e910c |
* probability that no resource usage will be found for an application, even if
|
|
Packit |
4e910c |
* it is an X client. If this happens, calling wnck_pid_read_resource_usage()
|
|
Packit |
4e910c |
* again after a few seconds should work.
|
|
Packit |
4e910c |
*
|
|
Packit |
4e910c |
* To properly work, this function requires the XRes extension on the X server.
|
|
Packit |
4e910c |
*
|
|
Packit |
4e910c |
* Since: 2.6
|
|
Packit |
4e910c |
*/
|
|
Packit |
4e910c |
void
|
|
Packit |
4e910c |
wnck_pid_read_resource_usage (GdkDisplay *gdisplay,
|
|
Packit |
4e910c |
gulong pid,
|
|
Packit |
4e910c |
WnckResourceUsage *usage)
|
|
Packit |
4e910c |
{
|
|
Packit |
4e910c |
g_return_if_fail (usage != NULL);
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
memset (usage, '\0', sizeof (*usage));
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
if (wnck_init_resource_usage (gdisplay) == WNCK_EXT_MISSING)
|
|
Packit |
4e910c |
return;
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
#ifdef HAVE_XRES
|
|
Packit |
4e910c |
if (!wnck_pid_read_resource_usage_from_cache (gdisplay, pid, usage))
|
|
Packit |
4e910c |
/* the cache might not be built, might be outdated or might not contain
|
|
Packit |
4e910c |
* data for a new X client, so try to fallback to something else */
|
|
Packit |
4e910c |
wnck_pid_read_resource_usage_no_cache (gdisplay, pid, usage);
|
|
Packit |
4e910c |
#endif /* HAVE_XRES */
|
|
Packit |
4e910c |
}
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
static WnckClientType client_type = 0;
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
/**
|
|
Packit |
4e910c |
* wnck_set_client_type:
|
|
Packit |
4e910c |
* @ewmh_sourceindication_client_type: a role for the client.
|
|
Packit |
4e910c |
*
|
|
Packit |
4e910c |
* Sets the role of the libwnck user.
|
|
Packit |
4e910c |
*
|
|
Packit |
4e910c |
* The default role is %WNCK_CLIENT_TYPE_APPLICATION. Therefore, for
|
|
Packit |
4e910c |
* applications providing some window management features, like pagers or
|
|
Packit |
4e910c |
* tasklists, it is important to set the role to %WNCK_CLIENT_TYPE_PAGER for
|
|
Packit |
4e910c |
* libwnck to properly work.
|
|
Packit |
4e910c |
*
|
|
Packit |
4e910c |
* Since: 2.14
|
|
Packit |
4e910c |
*/
|
|
Packit |
4e910c |
void
|
|
Packit |
4e910c |
wnck_set_client_type (WnckClientType ewmh_sourceindication_client_type)
|
|
Packit |
4e910c |
{
|
|
Packit |
4e910c |
/* Clients constantly switching types makes no sense; this should only be
|
|
Packit |
4e910c |
* set once.
|
|
Packit |
4e910c |
*/
|
|
Packit |
4e910c |
if (client_type != 0)
|
|
Packit |
4e910c |
g_critical ("wnck_set_client_type got called multiple times.\n");
|
|
Packit |
4e910c |
else
|
|
Packit |
4e910c |
client_type = ewmh_sourceindication_client_type;
|
|
Packit |
4e910c |
}
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
WnckClientType
|
|
Packit |
4e910c |
_wnck_get_client_type (void)
|
|
Packit |
4e910c |
{
|
|
Packit |
4e910c |
/* If the type hasn't been set yet, use the default--treat it as a
|
|
Packit |
4e910c |
* normal application.
|
|
Packit |
4e910c |
*/
|
|
Packit |
4e910c |
if (client_type == 0)
|
|
Packit |
4e910c |
client_type = WNCK_CLIENT_TYPE_APPLICATION;
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
return client_type;
|
|
Packit |
4e910c |
}
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
static gsize default_icon_size = WNCK_DEFAULT_ICON_SIZE;
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
/**
|
|
Packit |
4e910c |
* wnck_set_default_icon_size:
|
|
Packit |
4e910c |
* @size: the default size for windows and application standard icons.
|
|
Packit |
4e910c |
*
|
|
Packit |
4e910c |
* The default main icon size is %WNCK_DEFAULT_ICON_SIZE. This function allows
|
|
Packit |
4e910c |
* to change this value.
|
|
Packit |
4e910c |
*
|
|
Packit |
4e910c |
* Since: 2.4.6
|
|
Packit |
4e910c |
*/
|
|
Packit |
4e910c |
void
|
|
Packit |
4e910c |
wnck_set_default_icon_size (gsize size)
|
|
Packit |
4e910c |
{
|
|
Packit |
4e910c |
default_icon_size = size;
|
|
Packit |
4e910c |
}
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
gsize
|
|
Packit |
4e910c |
_wnck_get_default_icon_size (void)
|
|
Packit |
4e910c |
{
|
|
Packit |
4e910c |
return default_icon_size;
|
|
Packit |
4e910c |
}
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
static gsize default_mini_icon_size = WNCK_DEFAULT_MINI_ICON_SIZE;
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
/**
|
|
Packit |
4e910c |
* wnck_set_default_mini_icon_size:
|
|
Packit |
4e910c |
* @size: the default size for windows and application mini icons.
|
|
Packit |
4e910c |
*
|
|
Packit |
4e910c |
* The default main icon size is %WNCK_DEFAULT_MINI_ICON_SIZE. This function
|
|
Packit |
4e910c |
* allows to change this value.
|
|
Packit |
4e910c |
*
|
|
Packit |
4e910c |
* Since: 2.4.6
|
|
Packit |
4e910c |
*/
|
|
Packit |
4e910c |
void
|
|
Packit |
4e910c |
wnck_set_default_mini_icon_size (gsize size)
|
|
Packit |
4e910c |
{
|
|
Packit |
4e910c |
int default_screen;
|
|
Packit |
4e910c |
WnckScreen *screen;
|
|
Packit |
4e910c |
GList *l;
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
default_mini_icon_size = size;
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
default_screen = DefaultScreen (_wnck_get_default_display ());
|
|
Packit |
4e910c |
screen = _wnck_screen_get_existing (default_screen);
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
if (WNCK_IS_SCREEN (screen))
|
|
Packit |
4e910c |
{
|
|
Packit |
4e910c |
/* Make applications and icons to reload their icons */
|
|
Packit |
4e910c |
for (l = wnck_screen_get_windows (screen); l; l = l->next)
|
|
Packit |
4e910c |
{
|
|
Packit |
4e910c |
WnckWindow *window = WNCK_WINDOW (l->data);
|
|
Packit |
4e910c |
WnckApplication *application = wnck_window_get_application (window);
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
_wnck_window_load_icons (window);
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
if (WNCK_IS_APPLICATION (application))
|
|
Packit |
4e910c |
_wnck_application_load_icons (application);
|
|
Packit |
4e910c |
}
|
|
Packit |
4e910c |
}
|
|
Packit |
4e910c |
}
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
gsize
|
|
Packit |
4e910c |
_wnck_get_default_mini_icon_size (void)
|
|
Packit |
4e910c |
{
|
|
Packit |
4e910c |
return default_mini_icon_size;
|
|
Packit |
4e910c |
}
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
/**
|
|
Packit |
4e910c |
* _make_gtk_label_bold:
|
|
Packit |
4e910c |
* @label: The label.
|
|
Packit |
4e910c |
*
|
|
Packit |
4e910c |
* Switches the font of label to a bold equivalent.
|
|
Packit |
4e910c |
**/
|
|
Packit |
4e910c |
void
|
|
Packit |
4e910c |
_make_gtk_label_bold (GtkLabel *label)
|
|
Packit |
4e910c |
{
|
|
Packit |
4e910c |
GtkStyleContext *context;
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
_wnck_ensure_fallback_style ();
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
context = gtk_widget_get_style_context (GTK_WIDGET (label));
|
|
Packit |
4e910c |
gtk_style_context_add_class (context, "wnck-needs-attention");
|
|
Packit |
4e910c |
}
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
void
|
|
Packit |
4e910c |
_make_gtk_label_normal (GtkLabel *label)
|
|
Packit |
4e910c |
{
|
|
Packit |
4e910c |
GtkStyleContext *context;
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
context = gtk_widget_get_style_context (GTK_WIDGET (label));
|
|
Packit |
4e910c |
gtk_style_context_remove_class (context, "wnck-needs-attention");
|
|
Packit |
4e910c |
}
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
#ifdef HAVE_STARTUP_NOTIFICATION
|
|
Packit |
4e910c |
static gboolean
|
|
Packit |
4e910c |
_wnck_util_sn_utf8_validator (const char *str,
|
|
Packit |
4e910c |
int max_len)
|
|
Packit |
4e910c |
{
|
|
Packit |
4e910c |
return g_utf8_validate (str, max_len, NULL);
|
|
Packit |
4e910c |
}
|
|
Packit |
4e910c |
#endif /* HAVE_STARTUP_NOTIFICATION */
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
void
|
|
Packit |
4e910c |
_wnck_init (void)
|
|
Packit |
4e910c |
{
|
|
Packit |
4e910c |
static gboolean done = FALSE;
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
if (!done)
|
|
Packit |
4e910c |
{
|
|
Packit |
4e910c |
bindtextdomain (GETTEXT_PACKAGE, WNCK_LOCALEDIR);
|
|
Packit |
4e910c |
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
#ifdef HAVE_STARTUP_NOTIFICATION
|
|
Packit |
4e910c |
sn_set_utf8_validator (_wnck_util_sn_utf8_validator);
|
|
Packit |
4e910c |
#endif /* HAVE_STARTUP_NOTIFICATION */
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
done = TRUE;
|
|
Packit |
4e910c |
}
|
|
Packit |
4e910c |
}
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
Display *
|
|
Packit |
4e910c |
_wnck_get_default_display (void)
|
|
Packit |
4e910c |
{
|
|
Packit |
4e910c |
GdkDisplay *display = gdk_display_get_default ();
|
|
Packit |
4e910c |
/* FIXME: when we fix libwnck to not use the GDK default display, we will
|
|
Packit |
4e910c |
* need to fix wnckprop accordingly. */
|
|
Packit |
4e910c |
if (!GDK_IS_X11_DISPLAY (display))
|
|
Packit |
4e910c |
{
|
|
Packit |
4e910c |
g_warning ("libwnck is designed to work in X11 only, no valid display found");
|
|
Packit |
4e910c |
return NULL;
|
|
Packit |
4e910c |
}
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
return GDK_DISPLAY_XDISPLAY (display);
|
|
Packit |
4e910c |
}
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
/**
|
|
Packit |
4e910c |
* wnck_shutdown:
|
|
Packit |
4e910c |
*
|
|
Packit |
4e910c |
* Makes libwnck stop listening to events and tear down all resources from
|
|
Packit |
4e910c |
* libwnck. This should be done if you are not going to need the state change
|
|
Packit |
4e910c |
* notifications for an extended period of time, to avoid wakeups with every
|
|
Packit |
4e910c |
* key and focus event.
|
|
Packit |
4e910c |
*
|
|
Packit |
4e910c |
* After this, all pointers to Wnck object you might still hold are invalid.
|
|
Packit |
4e910c |
*
|
|
Packit |
4e910c |
* Due to the fact that
|
|
Packit |
4e910c |
* linkend="getting-started.pitfalls.memory-management">Wnck objects are all
|
|
Packit |
4e910c |
* owned by libwnck</link>, users of this API through introspection should be
|
|
Packit |
4e910c |
* extremely careful: they must explicitly clear variables referencing objects
|
|
Packit |
4e910c |
* before this call. Failure to do so might result in crashes.
|
|
Packit |
4e910c |
*
|
|
Packit |
4e910c |
* Since: 3.4
|
|
Packit |
4e910c |
*/
|
|
Packit |
4e910c |
void
|
|
Packit |
4e910c |
wnck_shutdown (void)
|
|
Packit |
4e910c |
{
|
|
Packit |
4e910c |
_wnck_event_filter_shutdown ();
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
/* Warning: this is hacky :-)
|
|
Packit |
4e910c |
*
|
|
Packit |
4e910c |
* Shutting down all WnckScreen objects will automatically unreference (and
|
|
Packit |
4e910c |
* finalize) all WnckWindow objects, but not the WnckClassGroup and
|
|
Packit |
4e910c |
* WnckApplication objects.
|
|
Packit |
4e910c |
* Therefore we need to manually shut down all WnckClassGroup and
|
|
Packit |
4e910c |
* WnckApplication objects first, since they reference the WnckScreen they're
|
|
Packit |
4e910c |
* on.
|
|
Packit |
4e910c |
* On the other side, shutting down the WnckScreen objects will results in
|
|
Packit |
4e910c |
* all WnckWindow objects getting unreferenced and finalized, and must
|
|
Packit |
4e910c |
* actually be done before shutting down global WnckWindow structures
|
|
Packit |
4e910c |
* (because the WnckScreen has a list of WnckWindow that will get mis-used
|
|
Packit |
4e910c |
* otherwise). */
|
|
Packit |
4e910c |
_wnck_class_group_shutdown_all ();
|
|
Packit |
4e910c |
_wnck_application_shutdown_all ();
|
|
Packit |
4e910c |
_wnck_screen_shutdown_all ();
|
|
Packit |
4e910c |
_wnck_window_shutdown_all ();
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
#ifdef HAVE_XRES
|
|
Packit |
4e910c |
if (xres_removeid != 0)
|
|
Packit |
4e910c |
g_source_remove (xres_removeid);
|
|
Packit |
4e910c |
xres_removeid = 0;
|
|
Packit |
4e910c |
wnck_pid_read_resource_usage_destroy_hash_table (NULL);
|
|
Packit |
4e910c |
#endif
|
|
Packit |
4e910c |
}
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
void
|
|
Packit |
4e910c |
_wnck_ensure_fallback_style (void)
|
|
Packit |
4e910c |
{
|
|
Packit |
4e910c |
static gboolean css_loaded = FALSE;
|
|
Packit |
4e910c |
GtkCssProvider *provider;
|
|
Packit |
4e910c |
guint priority;
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
if (css_loaded)
|
|
Packit |
4e910c |
return;
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
provider = gtk_css_provider_new ();
|
|
Packit |
4e910c |
gtk_css_provider_load_from_resource (provider, "/org/gnome/libwnck/wnck.css");
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
priority = GTK_STYLE_PROVIDER_PRIORITY_FALLBACK;
|
|
Packit |
4e910c |
gtk_style_context_add_provider_for_screen (gdk_screen_get_default (),
|
|
Packit |
4e910c |
GTK_STYLE_PROVIDER (provider),
|
|
Packit |
4e910c |
priority);
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
g_object_unref (provider);
|
|
Packit |
4e910c |
|
|
Packit |
4e910c |
css_loaded = TRUE;
|
|
Packit |
4e910c |
}
|