[gtk+/client-side-decorations: 46/50] add support for window icons
- From: Cody Russell <bratsche src gnome org>
- To: svn-commits-list gnome org
- Subject: [gtk+/client-side-decorations: 46/50] add support for window icons
- Date: Wed, 8 Jul 2009 15:32:01 +0000 (UTC)
commit d4066fdd80d1a888c0326ed84a270854014f4eb6
Author: Cody Russell <crussell canonical com>
Date: Wed Jul 8 02:22:42 2009 +0100
add support for window icons
gtk/gtkwindow.c | 156 ++++++++++++++++++++++++++++++++++++++++++++++---------
1 files changed, 131 insertions(+), 25 deletions(-)
---
diff --git a/gtk/gtkwindow.c b/gtk/gtkwindow.c
index 12aa066..6358561 100644
--- a/gtk/gtkwindow.c
+++ b/gtk/gtkwindow.c
@@ -128,6 +128,7 @@ typedef struct
GdkPixmap *icon_pixmap;
GdkPixmap *icon_mask;
gchar *icon_name;
+ GdkPixbuf *icon_pixbuf;
guint realized : 1;
guint using_default_icon : 1;
guint using_parent_icon : 1;
@@ -214,6 +215,7 @@ struct _GtkWindowPrivate
gchar *startup_id;
GtkWidget *title_label;
+ GtkWidget *title_icon;
GtkWidget *min_button;
GtkWidget *max_button;
GtkWidget *close_button;
@@ -1489,22 +1491,28 @@ update_window_buttons (GtkWindow *window)
if (is_client_side_decorated (window))
{
// XXX: should this be using GdkWMFunction instead?
- if (priv->client_side_decorations & GDK_DECOR_MINIMIZE)
+ if (priv->min_button)
{
- gtk_widget_show_all (priv->min_button);
- }
- else
- {
- gtk_widget_hide (priv->min_button);
+ if (priv->client_side_decorations & GDK_DECOR_MINIMIZE)
+ {
+ gtk_widget_show_all (priv->min_button);
+ }
+ else
+ {
+ gtk_widget_hide (priv->min_button);
+ }
}
- if (priv->client_side_decorations & GDK_DECOR_MAXIMIZE)
- {
- gtk_widget_show_all (priv->max_button);
- }
- else
+ if (priv->max_button)
{
- gtk_widget_hide (priv->max_button);
+ if (priv->client_side_decorations & GDK_DECOR_MAXIMIZE)
+ {
+ gtk_widget_show_all (priv->max_button);
+ }
+ else
+ {
+ gtk_widget_hide (priv->max_button);
+ }
}
// close?
@@ -3375,6 +3383,7 @@ typedef struct {
guint serial;
GdkPixmap *pixmap;
GdkPixmap *mask;
+ GdkPixbuf *pixbuf;
} ScreenIconInfo;
static ScreenIconInfo *
@@ -3415,7 +3424,8 @@ get_pixmap_and_mask (GdkWindow *window,
gboolean is_default_list,
GList *icon_list,
GdkPixmap **pmap_return,
- GdkBitmap **mask_return)
+ GdkBitmap **mask_return,
+ GdkPixbuf **pixbuf_return)
{
GdkScreen *screen = gdk_drawable_get_screen (window);
ScreenIconInfo *default_icon_info = get_screen_icon_info (screen);
@@ -3425,6 +3435,7 @@ get_pixmap_and_mask (GdkWindow *window,
*pmap_return = NULL;
*mask_return = NULL;
+ *pixbuf_return = NULL;
if (is_default_list &&
default_icon_info->pixmap != NULL)
@@ -3435,9 +3446,12 @@ get_pixmap_and_mask (GdkWindow *window,
g_object_ref (default_icon_info->pixmap);
if (default_icon_info->mask)
g_object_ref (default_icon_info->mask);
+ if (default_icon_info->pixbuf)
+ g_object_ref (default_icon_info->pixbuf);
*pmap_return = default_icon_info->pixmap;
*mask_return = default_icon_info->mask;
+ *pixbuf_return = default_icon_info->pixbuf;
}
else if (parent_info && parent_info->icon_pixmap)
{
@@ -3445,9 +3459,12 @@ get_pixmap_and_mask (GdkWindow *window,
g_object_ref (parent_info->icon_pixmap);
if (parent_info->icon_mask)
g_object_ref (parent_info->icon_mask);
-
+ if (parent_info->icon_pixbuf)
+ g_object_ref (parent_info->icon_pixbuf);
+
*pmap_return = parent_info->icon_pixmap;
*mask_return = parent_info->icon_mask;
+ *pixbuf_return = parent_info->icon_pixbuf;
}
else
{
@@ -3490,27 +3507,38 @@ get_pixmap_and_mask (GdkWindow *window,
}
if (best_icon)
- gdk_pixbuf_render_pixmap_and_mask_for_colormap (best_icon,
- gdk_screen_get_system_colormap (screen),
- pmap_return,
- mask_return,
- 128);
+ {
+ // XXX - should probably scale based on the height of the label?
+ best_icon = gdk_pixbuf_scale_simple (best_icon, 24, 24, GDK_INTERP_HYPER);
+
+ *pixbuf_return = best_icon;
+
+ gdk_pixbuf_render_pixmap_and_mask_for_colormap (best_icon,
+ gdk_screen_get_system_colormap (screen),
+ pmap_return,
+ mask_return,
+ 128);
+ }
/* Save pmap/mask for others to use if appropriate */
if (parent_info)
{
parent_info->icon_pixmap = *pmap_return;
parent_info->icon_mask = *mask_return;
+ parent_info->icon_pixbuf = *pixbuf_return;
if (parent_info->icon_pixmap)
g_object_ref (parent_info->icon_pixmap);
if (parent_info->icon_mask)
g_object_ref (parent_info->icon_mask);
+ if (parent_info->icon_pixbuf)
+ g_object_ref (parent_info->icon_pixbuf);
}
else if (is_default_list)
{
default_icon_info->pixmap = *pmap_return;
default_icon_info->mask = *mask_return;
+ default_icon_info->pixbuf = *pixbuf_return;
if (default_icon_info->pixmap)
g_object_add_weak_pointer (G_OBJECT (default_icon_info->pixmap),
@@ -3518,6 +3546,9 @@ get_pixmap_and_mask (GdkWindow *window,
if (default_icon_info->mask)
g_object_add_weak_pointer (G_OBJECT (default_icon_info->mask),
(gpointer*)&default_icon_info->mask);
+ if (default_icon_info->pixbuf)
+ g_object_add_weak_pointer (G_OBJECT (default_icon_info->pixbuf),
+ (gpointer*)&default_icon_info->pixbuf);
}
}
}
@@ -3560,6 +3591,37 @@ icon_list_from_theme (GtkWidget *widget,
return list;
}
+static void
+ensure_title_icon (GtkWindow *window)
+{
+ GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (window);
+
+ ensure_title_box (window);
+
+ if (!priv->title_icon)
+ {
+ priv->title_icon = gtk_image_new ();
+ }
+
+ gtk_widget_set_parent (priv->title_icon, GTK_WIDGET (window));
+
+ gtk_widget_show (priv->title_icon);
+
+ if (GTK_WIDGET_VISIBLE (window))
+ {
+ gtk_widget_queue_resize (GTK_WIDGET (window));
+ }
+}
+
+static void
+set_title_icon (GtkWindow *window, GdkPixbuf *pixbuf)
+{
+ GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (window);
+
+ ensure_title_icon (window);
+
+ gtk_image_set_from_pixbuf (GTK_IMAGE (priv->title_icon), pixbuf);
+}
static void
gtk_window_realize_icon (GtkWindow *window)
@@ -3631,8 +3693,9 @@ gtk_window_realize_icon (GtkWindow *window)
info->using_default_icon,
icon_list,
&info->icon_pixmap,
- &info->icon_mask);
-
+ &info->icon_mask,
+ &info->icon_pixbuf);
+
/* This is a slight ICCCM violation since it's a color pixmap not
* a bitmap, but everyone does it.
*/
@@ -3641,6 +3704,10 @@ gtk_window_realize_icon (GtkWindow *window)
info->icon_pixmap,
info->icon_mask);
+ /* This is not an ICCCM violation. ;-)
+ */
+ set_title_icon (window, info->icon_pixbuf);
+
info->realized = TRUE;
if (info->using_themed_icon)
@@ -3689,7 +3756,6 @@ gtk_window_unrealize_icon (GtkWindow *window)
*/
info->realized = FALSE;
-
}
/**
@@ -4908,6 +4974,13 @@ gtk_window_map (GtkWidget *widget)
gtk_widget_map (priv->title_label);
}
+ if (priv->title_icon &&
+ GTK_WIDGET_VISIBLE (priv->title_icon) &&
+ !GTK_WIDGET_MAPPED (priv->title_icon))
+ {
+ gtk_widget_map (priv->title_icon);
+ }
+
if (priv->button_box &&
GTK_WIDGET_VISIBLE (priv->button_box) &&
!GTK_WIDGET_MAPPED (priv->button_box))
@@ -5048,7 +5121,9 @@ is_client_side_decorated (GtkWindow *window)
"client-side-decorated", &client_side_decorated,
NULL);
- return client_side_decorated && window->decorated && !priv->disable_client_side_decorations;
+ return 1 && window->decorated && !priv->disable_client_side_decorations; // XXX - remove this :)
+
+ return client_side_decorated && window->decorated && priv->disable_client_side_decorations;
}
static void
@@ -5286,6 +5361,7 @@ gtk_window_size_request (GtkWidget *widget,
if (is_client_side_decorated (window) && window->type != GTK_WINDOW_POPUP)
{
GtkRequisition box_requisition;
+ GtkRequisition icon_requisition;
gint child_height = 0;
if (priv->title_label && GTK_WIDGET_VISIBLE (priv->title_label))
@@ -5294,6 +5370,12 @@ gtk_window_size_request (GtkWidget *widget,
child_height = child_requisition.height;
}
+ if (priv->title_icon && GTK_WIDGET_VISIBLE (priv->title_icon))
+ {
+ gtk_widget_size_request (priv->title_icon, &icon_requisition);
+ child_height = MAX (child_height, icon_requisition.height);
+ }
+
if (priv->button_box && GTK_WIDGET_VISIBLE (priv->button_box))
{
gtk_widget_size_request (priv->button_box, &box_requisition);
@@ -5330,6 +5412,7 @@ gtk_window_size_allocate (GtkWidget *widget,
GtkAllocation box_allocation;
gint frame_left = 0, frame_right = 0, frame_top = 0, frame_bottom = 0;
gint title_width = 0;
+ gint icon_width = 0;
GdkRectangle rect;
window = GTK_WINDOW (widget);
@@ -5349,11 +5432,25 @@ gtk_window_size_allocate (GtkWidget *widget,
NULL);
}
+ if (is_client_side_decorated (window) && priv->title_icon && GTK_WIDGET_VISIBLE (priv->title_icon))
+ {
+ gtk_widget_get_child_requisition (priv->title_icon, &deco_requisition);
+
+ deco_allocation.x = frame_left;
+ deco_allocation.y = frame_top;
+ deco_allocation.width = deco_requisition.width;
+ deco_allocation.height = deco_requisition.height;
+
+ icon_width = deco_allocation.width;
+
+ gtk_widget_size_allocate (priv->title_icon, &deco_allocation);
+ }
+
if (is_client_side_decorated (window) && priv->title_label && GTK_WIDGET_VISIBLE (priv->title_label))
{
gtk_widget_get_child_requisition (priv->title_label, &deco_requisition);
- deco_allocation.x = frame_left;
+ deco_allocation.x = 2 * frame_left + icon_width;
deco_allocation.y = frame_top;
deco_allocation.width = deco_requisition.width;
deco_allocation.height = deco_requisition.height;
@@ -5966,6 +6063,9 @@ gtk_window_forall (GtkContainer *container,
if (bin->child)
(* callback) (bin->child, callback_data);
+ if (priv->title_icon)
+ (* callback) (priv->title_icon, callback_data);
+
if (priv->title_label)
(* callback) (priv->title_label, callback_data);
@@ -5980,7 +6080,13 @@ gtk_window_remove (GtkContainer *container,
GtkWindow *window = GTK_WINDOW (container);
GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (window);
- if (priv->title_label && priv->title_label == child)
+ if (priv->title_icon && priv->title_icon == child)
+ {
+ gtk_widget_unparent (priv->title_icon);
+ gtk_widget_destroy (priv->title_icon);
+ priv->title_icon = NULL;
+ }
+ else if (priv->title_label && priv->title_label == child)
{
gtk_widget_unparent (priv->title_label);
gtk_widget_destroy (priv->title_label);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]