summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libmdock/Makefile.am2
-rw-r--r--libmdock/mdock-item.c15
-rw-r--r--libmdock/mdock-widget.c1
-rw-r--r--libmdock/thumbnailer.c135
-rw-r--r--libmdock/thumbnailer.h32
5 files changed, 182 insertions, 3 deletions
diff --git a/libmdock/Makefile.am b/libmdock/Makefile.am
index dedf339..2d46925 100644
--- a/libmdock/Makefile.am
+++ b/libmdock/Makefile.am
@@ -1,5 +1,5 @@
lib_LTLIBRARIES = libmdock.la
-libmdock_la_SOURCES = mdock-widget.h mdock-widget.c mdock-enums.h mdock-enums.c mdock-item.h mdock-item.c matcher.h matcher.c app-id.h app-id.c
+libmdock_la_SOURCES = mdock-widget.h mdock-widget.c mdock-enums.h mdock-enums.c mdock-item.h mdock-item.c matcher.h matcher.c app-id.h app-id.c thumbnailer.h thumbnailer.c
libmdock_la_CPPFLAGS = $(GTK_CFLAGS) $(GIO_CFLAGS) $(WNCK_CFLAGS) $(GTOP_CFLAGS) -D_GNU_SOURCE -DG_LOG_DOMAIN=\"libmdock\"
libmdock_la_LIBADD = $(GTK_LIBS) $(GIO_LIBS) $(WNCK_LIBS) $(GTOP_LIBS)
diff --git a/libmdock/mdock-item.c b/libmdock/mdock-item.c
index 43dcdca..9a0572b 100644
--- a/libmdock/mdock-item.c
+++ b/libmdock/mdock-item.c
@@ -19,6 +19,7 @@
#include "mdock-enums.h"
#include "mdock-item.h"
+#include "thumbnailer.h"
#define MDOCK_ITEM_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE((object), MDOCK_TYPE_ITEM, MDockItemPrivate))
@@ -238,8 +239,15 @@ static gboolean mdock_item_expose(GtkWidget *widget, GdkEventExpose *event)
cairo_t *cr = gdk_cairo_create(widget->window);
if (self->priv->icon) {
- gdk_cairo_set_source_pixbuf(cr, self->priv->icon, 0, 0);
- cairo_paint(cr);
+ if (self->priv->windows) {
+ GdkPixmap *pix = thumbnailer_get_thumbnail(self->priv->windows->data);
+ if (pix) {
+ gdk_cairo_set_source_pixmap(cr, pix, 0, 0);
+ cairo_paint(cr);
+ }
+ }
+ //gdk_cairo_set_source_pixbuf(cr, self->priv->icon, 0, 0);
+ //cairo_paint(cr);
}
cairo_destroy(cr);
@@ -408,6 +416,7 @@ void mdock_item_set_desktop_app_info(MDockItem *self, GDesktopAppInfo *app_info)
void mdock_item_add_window(MDockItem *self, WnckWindow *window)
{
+ thumbnailer_enable_for_window(window);
self->priv->windows = g_list_append(self->priv->windows, window);
if (!self->priv->icon) {
mdock_item_update_icon(self);
@@ -437,6 +446,8 @@ void mdock_item_set_last_active_window(MDockItem *self, WnckWindow *window)
self->priv->windows = g_list_remove_link(self->priv->windows, l);
self->priv->windows = g_list_concat(l, self->priv->windows);
#endif
+ thumbnailer_update_thumbnail(window);
+ gtk_widget_queue_draw(GTK_WIDGET(self));
}
gint mdock_item_get_num_windows(MDockItem *self)
diff --git a/libmdock/mdock-widget.c b/libmdock/mdock-widget.c
index ff2a7fd..81e492d 100644
--- a/libmdock/mdock-widget.c
+++ b/libmdock/mdock-widget.c
@@ -124,6 +124,7 @@ static void handle_window_opened(MDockWidget *self, WnckWindow *window, WnckScre
g_settings_bind(self->priv->settings, "icon-size",
item, "icon-size",
G_SETTINGS_BIND_GET | G_SETTINGS_BIND_NO_SENSITIVITY);
+ g_settings_set_uint(self->priv->settings, "icon-size", 128);
mdock_item_add_window(item, window);
diff --git a/libmdock/thumbnailer.c b/libmdock/thumbnailer.c
new file mode 100644
index 0000000..774d04c
--- /dev/null
+++ b/libmdock/thumbnailer.c
@@ -0,0 +1,135 @@
+/*
+ * Copyright 2015 Javier S. Pedro <dev.git@javispedro.com>
+ *
+ * This file is part of MDock.
+ *
+ * MDock is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * MDock 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 General Public License
+ * along with MDock. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <gdk/gdkx.h>
+#include "thumbnailer.h"
+
+#define THUMBNAIL_MAX_WIDTH 128
+#define THUMBNAIL_MAX_HEIGHT 128
+
+typedef struct _ThumbnailData
+{
+ GdkPixmap * pix;
+ guint update_source;
+ time_t timestamp;
+} ThumbnailData;
+
+G_DEFINE_QUARK(mdock-thumbnail-data, mdock_thumbnail_data)
+
+static inline ThumbnailData * thumbnail_data_new()
+{
+ return g_slice_new0(ThumbnailData);
+}
+
+static void thumbnail_data_destroy(ThumbnailData *tdata)
+{
+ g_clear_object(&tdata->pix);
+ if (tdata->update_source) g_source_remove(tdata->update_source);
+ g_slice_free(ThumbnailData, tdata);
+}
+
+static void thumbnail_size(WnckWindow *window, int *thumb_w, int *thumb_h)
+{
+ int win_x, win_y, win_w, win_h;
+
+}
+
+void thumbnailer_enable_for_window(WnckWindow *window)
+{
+ g_object_set_qdata_full(G_OBJECT(window),
+ mdock_thumbnail_data_quark(),
+ thumbnail_data_new(),
+ (GDestroyNotify)thumbnail_data_destroy);
+}
+
+static gboolean thumbnailer_do_update(gpointer data)
+{
+ ThumbnailData *tdata = g_object_get_qdata(G_OBJECT(data), mdock_thumbnail_data_quark());
+ g_return_if_fail(tdata);
+ thumbnailer_update_thumbnail(WNCK_WINDOW(data));
+ tdata->update_source = 0;
+ return G_SOURCE_REMOVE;
+}
+
+void thumbnailer_schedule_update(WnckWindow *window)
+{
+ ThumbnailData *tdata = g_object_get_qdata(G_OBJECT(window), mdock_thumbnail_data_quark());
+ g_return_if_fail(tdata);
+ if (!tdata->update_source) {
+ tdata->update_source = g_timeout_add(500, thumbnailer_do_update, window);
+ }
+}
+
+void thumbnailer_update_thumbnail(WnckWindow *window)
+{
+ GdkDisplay *display = gdk_display_get_default();
+ ThumbnailData *tdata = g_object_get_qdata(G_OBJECT(window), mdock_thumbnail_data_quark());
+ g_return_if_fail(tdata);
+
+ g_return_if_fail(wnck_window_is_active(window));
+
+ GdkWindow *root = gdk_get_default_root_window();
+
+ int screen_x, screen_y, win_x, win_y, win_w, win_h, thumb_w, thumb_h, cur_w, cur_h;
+ gdk_window_get_origin(root, &screen_x, &screen_y);
+ wnck_window_get_client_window_geometry(window, &win_x, &win_y, &win_w, &win_h);
+
+ if (win_w > THUMBNAIL_MAX_WIDTH || win_h > THUMBNAIL_MAX_HEIGHT) {
+ if (win_h > win_w) {
+ thumb_w = (THUMBNAIL_MAX_HEIGHT * win_w) / win_h;
+ thumb_h = THUMBNAIL_MAX_HEIGHT;
+ } else {
+ thumb_w = THUMBNAIL_MAX_WIDTH;
+ thumb_h = (THUMBNAIL_MAX_WIDTH * win_h) / win_w;
+ }
+ } else {
+ thumb_w = win_w;
+ thumb_h = win_h;
+ }
+
+ if (tdata->pix) {
+ gdk_pixmap_get_size(tdata->pix, &cur_w, &cur_h);
+ }
+ if (!tdata->pix || cur_w != thumb_w || cur_h != thumb_h) {
+ g_clear_object(&tdata->pix);
+ g_debug("Recreating pixmap for %s (%dx%d)", wnck_window_get_name(window), thumb_w, thumb_h);
+ tdata->pix = gdk_pixmap_new(root, thumb_w, thumb_h, -1);
+ }
+
+ g_return_if_fail(tdata->pix);
+
+ g_debug("Updating thumbnail for %s (%dx%d)", wnck_window_get_name(window), thumb_w, thumb_h);
+
+ double scale_w = thumb_w / (double)win_w, scale_h = thumb_h / (double)win_h;
+ cairo_t *cr = gdk_cairo_create(GDK_DRAWABLE(tdata->pix));
+ cairo_scale(cr, scale_w, scale_h);
+ gdk_cairo_set_source_window(cr, root, -(win_x - screen_x), -(win_y - screen_y));
+ cairo_pattern_set_filter(cairo_get_source (cr), CAIRO_FILTER_FAST);
+ cairo_paint(cr);
+ cairo_destroy(cr);
+
+ time(&tdata->timestamp);
+}
+
+GdkPixmap * thumbnailer_get_thumbnail(WnckWindow *window)
+{
+ ThumbnailData *tdata = g_object_get_qdata(G_OBJECT(window), mdock_thumbnail_data_quark());
+ g_return_val_if_fail(tdata, NULL);
+ return tdata->pix;
+}
diff --git a/libmdock/thumbnailer.h b/libmdock/thumbnailer.h
new file mode 100644
index 0000000..d5c4c52
--- /dev/null
+++ b/libmdock/thumbnailer.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2015 Javier S. Pedro <dev.git@javispedro.com>
+ *
+ * This file is part of MDock.
+ *
+ * MDock is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * MDock 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 General Public License
+ * along with MDock. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _THUMBNAILER_H_
+#define _THUMBNAILER_H_
+
+#define WNCK_I_KNOW_THIS_IS_UNSTABLE 1
+#include <libwnck/libwnck.h>
+
+void thumbnailer_enable_for_window(WnckWindow *window);
+
+void thumbnailer_schedule_update(WnckWindow *window);
+void thumbnailer_update_thumbnail(WnckWindow *window);
+GdkPixmap * thumbnailer_get_thumbnail(WnckWindow *window);
+
+#endif