summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOlivier Fourdan <fourdan@xfce.org>2015-01-22 22:50:39 +0100
committerOlivier Fourdan <fourdan@xfce.org>2015-01-22 22:52:28 +0100
commit4adad9fca2856ed0cd98522aac0b1ca13f1ee956 (patch)
tree46346a4aaf900f93e3feb55e08ebcf814353dfc5
parentf6d5236b887c062117ee504358e54e63a98e3a54 (diff)
downloadxfwm4-4adad9fca2856ed0cd98522aac0b1ca13f1ee956.tar.gz
Use window pixmap in tabwin
Signed-off-by: Olivier Fourdan <fourdan@xfce.org>
-rw-r--r--src/client.c2
-rw-r--r--src/icons.c141
-rw-r--r--src/icons.h8
-rw-r--r--src/tabwin.c19
4 files changed, 108 insertions, 62 deletions
diff --git a/src/client.c b/src/client.c
index 234206782..af90e03a4 100644
--- a/src/client.c
+++ b/src/client.c
@@ -1446,7 +1446,7 @@ clientUpdateIconPix (Client *c)
if (size > 1)
{
- icon = getAppIcon (display_info, c->window, size, size);
+ icon = getAppIcon (screen_info, c->window, size, size);
for (i = 0; i < STATE_TOGGLED; i++)
{
diff --git a/src/icons.c b/src/icons.c
index 60094bc99..64df23381 100644
--- a/src/icons.c
+++ b/src/icons.c
@@ -18,7 +18,7 @@
Metacity - (c) 2001 Havoc Pennington
libwnck - (c) 2001 Havoc Pennington
- xfwm4 - (c) 2002-2011 Olivier Fourdan
+ xfwm4 - (c) 2002-2015 Olivier Fourdan
*/
#ifdef HAVE_CONFIG_H
@@ -36,15 +36,41 @@
#include "inline-default-icon.h"
#include "icons.h"
#include "display.h"
+#include "screen.h"
+#include "client.h"
+#include "compositor.h"
#include "hints.h"
+static void
+downsize_ratio (int *width, int *height, int dest_w, int dest_h)
+{
+ gdouble ratio;
+ int size;
+
+ g_return_if_fail (width != NULL);
+ g_return_if_fail (height != NULL);
+ g_return_if_fail (dest_w > 0 && dest_w > 0);
+
+ size = MIN (dest_w, dest_h);
+ if (*width > *height)
+ {
+ ratio = ((gdouble) *width) / size;
+ *width = (int) size;
+ *height = (int) (((gdouble) *height) / ratio);
+ }
+ else
+ {
+ ratio = ((gdouble) *height) / size;
+ *height = (int) size;
+ *width = (int) (((gdouble) *width) / ratio);
+ }
+}
+
/*
* create a GdkPixbuf from inline data and scale it to a given size
*/
static GdkPixbuf *
-inline_icon_at_size (const guint8 *data,
- int width,
- int height)
+inline_icon_at_size (const guint8 *data, int width, int height)
{
GdkPixbuf *base;
@@ -52,23 +78,20 @@ inline_icon_at_size (const guint8 *data,
g_return_val_if_fail (base, NULL);
- if ((width < 0 && height < 0)
- || (gdk_pixbuf_get_width (base) == width
- && gdk_pixbuf_get_height (base) == height))
+ if ((width <= 0 || height <= 0) ||
+ (gdk_pixbuf_get_width (base) == width && gdk_pixbuf_get_height (base) == height))
{
return base;
}
else
{
GdkPixbuf *scaled;
+ int w, h;
- scaled = gdk_pixbuf_scale_simple (base,
- width >
- 0 ? width : gdk_pixbuf_get_width (base),
- height >
- 0 ? height :
- gdk_pixbuf_get_height (base),
- GDK_INTERP_BILINEAR);
+ w = gdk_pixbuf_get_width (base);
+ h = gdk_pixbuf_get_height (base);
+ downsize_ratio (&w, &h, width, height);
+ scaled = gdk_pixbuf_scale_simple (base, w, h, GDK_INTERP_NEAREST);
g_object_unref (G_OBJECT (base));
@@ -328,7 +351,7 @@ apply_mask (GdkPixbuf * pixbuf, GdkPixbuf * mask)
}
static GdkColormap *
-get_cmap (GdkPixmap * pixmap)
+get_cmap (GdkPixmap * pixmap, GdkScreen *gscreen)
{
GdkColormap *cmap;
@@ -337,6 +360,7 @@ get_cmap (GdkPixmap * pixmap)
cmap = gdk_drawable_get_colormap (pixmap);
if (cmap)
{
+ g_message ("Drawable colormap");
g_object_ref (G_OBJECT (cmap));
}
else
@@ -346,6 +370,12 @@ get_cmap (GdkPixmap * pixmap)
/* try null cmap */
cmap = NULL;
}
+ else if ((gdk_drawable_get_depth (pixmap) == 32) && (gscreen != NULL))
+ {
+ /* Try ARGB cmap */
+ cmap = gdk_screen_get_rgba_colormap(gscreen);
+ g_object_ref (G_OBJECT (cmap));
+ }
else
{
/* Try system cmap */
@@ -365,9 +395,8 @@ get_cmap (GdkPixmap * pixmap)
}
static GdkPixbuf *
-get_pixbuf_from_pixmap (GdkPixbuf * dest, Pixmap xpixmap,
- int src_x, int src_y, int dest_x,
- int dest_y, int width, int height)
+get_pixbuf_from_pixmap (GdkScreen *gscreen, Pixmap xpixmap, int src_x, int src_y,
+ int dest_x, int dest_y, int width, int height)
{
GdkDrawable *drawable;
GdkPixbuf *retval;
@@ -392,9 +421,9 @@ get_pixbuf_from_pixmap (GdkPixbuf * dest, Pixmap xpixmap,
return NULL;
}
- cmap = get_cmap (drawable);
+ cmap = get_cmap (drawable, gscreen);
- retval = gdk_pixbuf_get_from_drawable (dest, drawable, cmap, src_x, src_y,
+ retval = gdk_pixbuf_get_from_drawable (NULL, drawable, cmap, src_x, src_y,
dest_x, dest_y, width, height);
if (G_LIKELY(cmap))
@@ -407,7 +436,7 @@ get_pixbuf_from_pixmap (GdkPixbuf * dest, Pixmap xpixmap,
}
static GdkPixbuf *
-try_pixmap_and_mask (Display *dpy, Pixmap src_pixmap, Pixmap src_mask, int width, int height)
+try_pixmap_and_mask (ScreenInfo *screen_info, Pixmap src_pixmap, Pixmap src_mask, int width, int height)
{
GdkPixbuf *unscaled;
GdkPixbuf *icon;
@@ -420,15 +449,15 @@ try_pixmap_and_mask (Display *dpy, Pixmap src_pixmap, Pixmap src_mask, int width
}
gdk_error_trap_push ();
- get_pixmap_geometry (dpy, src_pixmap, &w, &h);
- unscaled = get_pixbuf_from_pixmap (NULL, src_pixmap, 0, 0, 0, 0, w, h);
+ get_pixmap_geometry (myScreenGetXDisplay(screen_info), src_pixmap, &w, &h);
+ unscaled = get_pixbuf_from_pixmap (screen_info->gscr, src_pixmap, 0, 0, 0, 0, w, h);
icon = NULL;
mask = NULL;
if (unscaled && src_mask)
{
- get_pixmap_geometry (dpy, src_mask, &w, &h);
- mask = get_pixbuf_from_pixmap (NULL, src_mask, 0, 0, 0, 0, w, h);
+ get_pixmap_geometry (myScreenGetXDisplay(screen_info), src_mask, &w, &h);
+ mask = get_pixbuf_from_pixmap (screen_info->gscr, src_mask, 0, 0, 0, 0, w, h);
}
gdk_error_trap_pop ();
@@ -446,7 +475,8 @@ try_pixmap_and_mask (Display *dpy, Pixmap src_pixmap, Pixmap src_mask, int width
if (unscaled)
{
- icon = gdk_pixbuf_scale_simple (unscaled, width, height, GDK_INTERP_BILINEAR);
+ downsize_ratio (&w, &h, width, height);
+ icon = gdk_pixbuf_scale_simple (unscaled, w, h, GDK_INTERP_BILINEAR);
g_object_unref (G_OBJECT (unscaled));
return icon;
}
@@ -461,7 +491,7 @@ free_pixels (guchar * pixels, gpointer data)
}
static GdkPixbuf *
-scaled_from_pixdata (guchar * pixdata, int w, int h, int new_w, int new_h)
+scaled_from_pixdata (guchar * pixdata, int w, int h, int dest_w, int dest_h)
{
GdkPixbuf *src;
GdkPixbuf *dest;
@@ -475,25 +505,10 @@ scaled_from_pixdata (guchar * pixdata, int w, int h, int new_w, int new_h)
return NULL;
}
- if (w != h)
- {
- size = MAX (w, h);
-
- tmp = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, size, size);
-
- if (G_LIKELY(tmp != NULL))
- {
- gdk_pixbuf_fill (tmp, 0);
- gdk_pixbuf_copy_area (src, 0, 0, w, h, tmp, (size - w) / 2, (size - h) / 2);
-
- g_object_unref (src);
- src = tmp;
- }
- }
-
- if (w != new_w || h != new_h)
+ if (w != dest_w || h != dest_h)
{
- dest = gdk_pixbuf_scale_simple (src, new_w, new_h, GDK_INTERP_BILINEAR);
+ downsize_ratio (&w, &h, dest_w, dest_h);
+ dest = gdk_pixbuf_scale_simple (src, w, h, GDK_INTERP_NEAREST);
g_object_unref (G_OBJECT (src));
}
else
@@ -505,7 +520,7 @@ scaled_from_pixdata (guchar * pixdata, int w, int h, int new_w, int new_h)
}
GdkPixbuf *
-getAppIcon (DisplayInfo *display_info, Window window, int width, int height)
+getAppIcon (ScreenInfo *screen_info, Window window, int width, int height)
{
XWMHints *hints;
Pixmap pixmap;
@@ -517,13 +532,13 @@ getAppIcon (DisplayInfo *display_info, Window window, int width, int height)
pixmap = None;
mask = None;
- if (read_rgb_icon (display_info, window, width, height, &w, &h, &pixdata))
+ if (read_rgb_icon (screen_info->display_info, window, width, height, &w, &h, &pixdata))
{
return scaled_from_pixdata (pixdata, w, h, width, height);
}
gdk_error_trap_push ();
- hints = XGetWMHints (display_info->dpy, window);
+ hints = XGetWMHints (myScreenGetXDisplay(screen_info), window);
gdk_error_trap_pop ();
if (hints)
@@ -543,17 +558,17 @@ getAppIcon (DisplayInfo *display_info, Window window, int width, int height)
if (pixmap != None)
{
- GdkPixbuf *icon = try_pixmap_and_mask (display_info->dpy, pixmap, mask, width, height);
+ GdkPixbuf *icon = try_pixmap_and_mask (screen_info, pixmap, mask, width, height);
if (icon)
{
return icon;
}
}
- getKDEIcon (display_info, window, &pixmap, &mask);
+ getKDEIcon (screen_info->display_info, window, &pixmap, &mask);
if (pixmap != None)
{
- GdkPixbuf *icon = try_pixmap_and_mask (display_info->dpy, pixmap, mask, width, height);
+ GdkPixbuf *icon = try_pixmap_and_mask (screen_info, pixmap, mask, width, height);
if (icon)
{
return icon;
@@ -562,3 +577,27 @@ getAppIcon (DisplayInfo *display_info, Window window, int width, int height)
return inline_icon_at_size (default_icon_data, width, height);
}
+
+GdkPixbuf *
+getClientIcon (Client *c, int width, int height)
+{
+ ScreenInfo *screen_info;
+ DisplayInfo *display_info;
+ Pixmap pixmap;
+
+ g_return_val_if_fail (c != NULL, NULL);
+
+ screen_info = c->screen_info;
+ display_info = screen_info->display_info;
+ pixmap = compositorGetWindowPixmap (display_info, c->frame);
+ if (pixmap != None)
+ {
+ GdkPixbuf *icon = try_pixmap_and_mask (screen_info, pixmap, None, width, height);
+ if (icon)
+ {
+ return icon;
+ }
+ }
+
+ return getAppIcon (screen_info, c->window, width, height);
+}
diff --git a/src/icons.h b/src/icons.h
index fce66c196..1476f16a7 100644
--- a/src/icons.h
+++ b/src/icons.h
@@ -32,11 +32,15 @@
#include <X11/Xutil.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
-#include "display.h"
+#include "screen.h"
+#include "client.h"
-GdkPixbuf *getAppIcon (DisplayInfo *,
+GdkPixbuf *getAppIcon (ScreenInfo *,
Window,
int,
int);
+GdkPixbuf *getClientIcon (Client *,
+ int width,
+ int height);
#endif /* INC_ICONS_H */
diff --git a/src/tabwin.c b/src/tabwin.c
index 56d2d4336..9ec6bb311 100644
--- a/src/tabwin.c
+++ b/src/tabwin.c
@@ -334,7 +334,7 @@ createWindowIcon (Client *c, gint icon_size)
g_return_val_if_fail (c, NULL);
TRACE ("entering createWindowIcon");
- icon_pixbuf = getAppIcon (c->screen_info->display_info, c->window, icon_size, icon_size);
+ icon_pixbuf = getClientIcon (c, icon_size, icon_size);
icon_pixbuf_stated = NULL;
icon = gtk_image_new ();
@@ -421,10 +421,10 @@ cb_window_button_enter (GtkWidget *widget, GdkEvent *event, gpointer user_data)
return FALSE;
}
- buttonbox = GTK_WIDGET( gtk_container_get_children(GTK_CONTAINER(widget))[0].data );
- buttonlabel = GTK_WIDGET( g_list_nth_data( gtk_container_get_children(GTK_CONTAINER(buttonbox)), 1) );
+ buttonbox = GTK_WIDGET (gtk_container_get_children(GTK_CONTAINER(widget))[0].data);
+ buttonlabel = GTK_WIDGET (g_list_nth_data( gtk_container_get_children(GTK_CONTAINER(buttonbox)), 1));
- classname = g_strdup(c->class.res_class);
+ classname = g_strdup (c->class.res_class);
tabwinSetLabel (tbw, buttonlabel, classname, c->name, c->win_workspace);
g_free (classname);
}
@@ -502,7 +502,7 @@ createWindowlist (ScreenInfo *screen_info, TabwinWidget *tbw)
if (screen_info->params->cycle_tabwin_mode == STANDARD_ICON_GRID)
{
- tbw->grid_cols = (monitor_width / (icon_size+app_label_height+10)) * 0.75;
+ tbw->grid_cols = (monitor_width / (icon_size + app_label_height + 10)) * 0.75;
tbw->grid_rows = screen_info->client_count / tbw->grid_cols + 1;
/* If we run out of space, halve the icon size to make more room. */
@@ -510,7 +510,7 @@ createWindowlist (ScreenInfo *screen_info, TabwinWidget *tbw)
{
icon_size = icon_size / 2;
/* recalculate with new icon size */
- tbw->grid_cols = (monitor_width / (icon_size+app_label_height+10)) * 0.75;
+ tbw->grid_cols = (monitor_width / (icon_size + app_label_height + 10)) * 0.75;
tbw->grid_rows = screen_info->client_count / tbw->grid_cols + 1;
/* Shrinking the icon too much makes it hard to see */
@@ -546,7 +546,9 @@ createWindowlist (ScreenInfo *screen_info, TabwinWidget *tbw)
if (screen_info->params->cycle_tabwin_mode == STANDARD_ICON_GRID)
{
- gtk_widget_set_size_request (GTK_WIDGET (window_button), icon_size+app_label_height+10, icon_size+app_label_height+10);
+ gtk_widget_set_size_request (GTK_WIDGET (window_button),
+ icon_size + app_label_height + 10,
+ icon_size+app_label_height + 10);
buttonbox = gtk_vbox_new (FALSE, 0);
buttonlabel = gtk_label_new ("");
gtk_misc_set_alignment (GTK_MISC (buttonlabel), 0.5, 1.0);
@@ -567,7 +569,8 @@ createWindowlist (ScreenInfo *screen_info, TabwinWidget *tbw)
gtk_container_add (GTK_CONTAINER (window_button), buttonbox);
icon = createWindowIcon (c, icon_size);
- gtk_box_pack_start (GTK_BOX (buttonbox), icon, FALSE, TRUE, 0);
+ gtk_misc_set_alignment (GTK_MISC (icon), 0.5, 1.0);
+ gtk_box_pack_start (GTK_BOX (buttonbox), icon, TRUE, TRUE, 0);
gtk_label_set_justify (GTK_LABEL (buttonlabel), GTK_JUSTIFY_CENTER);
gtk_label_set_ellipsize (GTK_LABEL (buttonlabel), PANGO_ELLIPSIZE_END);