summaryrefslogtreecommitdiff
path: root/gtk/window-decorator
diff options
context:
space:
mode:
authorSam Spilsbury <sam.spilsbury@canonical.com>2011-02-18 17:26:27 +0800
committerSam Spilsbury <sam.spilsbury@canonical.com>2011-02-18 17:26:27 +0800
commit6e84b89fbcd93997dd6e80cdc9b318c3c8e07059 (patch)
tree17d603bc117d155445dba6a0cebf45a0299b45b6 /gtk/window-decorator
parentcdcec665a4fc7e340282bd1d8eaeac8e76b2ef43 (diff)
downloadcompiz-with-glib-mainloop-6e84b89fbcd93997dd6e80cdc9b318c3c8e07059.tar.gz
compiz-with-glib-mainloop-6e84b89fbcd93997dd6e80cdc9b318c3c8e07059.tar.bz2
Add memory management to frames
We don't need to keep all the frame definitions around in memory all the time, so refcount them and only add them if we actually need them.
Diffstat (limited to 'gtk/window-decorator')
-rw-r--r--gtk/window-decorator/cairo.c22
-rw-r--r--gtk/window-decorator/decorator.c223
-rw-r--r--gtk/window-decorator/frames.c355
-rw-r--r--gtk/window-decorator/gtk-window-decorator.c4
-rw-r--r--gtk/window-decorator/gtk-window-decorator.h73
-rw-r--r--gtk/window-decorator/metacity.c137
-rw-r--r--gtk/window-decorator/settings.c61
-rw-r--r--gtk/window-decorator/switcher.c37
-rw-r--r--gtk/window-decorator/wnck.c36
9 files changed, 624 insertions, 324 deletions
diff --git a/gtk/window-decorator/cairo.c b/gtk/window-decorator/cairo.c
index 8f56d0c..27c2790 100644
--- a/gtk/window-decorator/cairo.c
+++ b/gtk/window-decorator/cairo.c
@@ -874,21 +874,17 @@ get_title_scale (decor_frame_t *frame)
}
void
-update_border_extents ()
+update_border_extents (decor_frame_t *frame)
{
- unsigned int i;
+ decor_frame_t *default_frame = gwd_get_decor_frame ("default");
- for (i = 0; i < DECOR_FRAME_TYPE_SWITCHER; i++)
- {
- decor_frame_t *frame = gwd_get_decor_frame (i);
- decor_frame_t *default_frame = gwd_get_decor_frame (DECOR_FRAME_TYPE_DEFAULT);
+ frame = gwd_decor_frame_ref (frame);
- frame->win_extents = default_frame->win_extents;
- frame->max_win_extents = default_frame->win_extents;
- frame->titlebar_height = frame->max_titlebar_height =
- (frame->text_height < 17) ? 17 : frame->text_height;
+ frame->win_extents = default_frame->win_extents;
+ frame->max_win_extents = default_frame->win_extents;
+ frame->titlebar_height = frame->max_titlebar_height =
+ (frame->text_height < 17) ? 17 : frame->text_height;
- gwd_decor_frame_unref (frame);
- gwd_decor_frame_unref (default_frame);
- }
+ gwd_decor_frame_unref (frame);
+ gwd_decor_frame_unref (default_frame);
}
diff --git a/gtk/window-decorator/decorator.c b/gtk/window-decorator/decorator.c
index f35c40f..a6db744 100644
--- a/gtk/window-decorator/decorator.c
+++ b/gtk/window-decorator/decorator.c
@@ -1,55 +1,136 @@
#include "gtk-window-decorator.h"
-struct _decor_shadow_info
+decor_frame_t *
+create_normal_frame (const gchar *type)
{
- decor_frame_t *frame;
- unsigned int state;
-};
+ decor_frame_t *frame = decor_frame_new (type);
+
+ decor_context_t _window_context = {
+ { 0, 0, 0, 0 },
+ 6, 6, 4, 6,
+ 0, 0, 0, 0
+ };
+
+ decor_context_t _max_window_context = {
+ { 0, 0, 0, 0 },
+ 6, 6, 4, 6,
+ 0, 0, 0, 0
+ };
+
+ decor_context_t _window_context_no_shadow = {
+ { 0, 0, 0, 0 },
+ 6, 6, 4, 6,
+ 0, 0, 0, 0
+ };
+
+ decor_context_t _max_window_context_no_shadow = {
+ { 0, 0, 0, 0 },
+ 6, 6, 4, 6,
+ 0, 0, 0, 0
+ };
+
+ decor_extents_t _win_extents = { 6, 6, 6, 6 };
+ decor_extents_t _max_win_extents = { 6, 6, 4, 6 };
+
+ frame->win_extents = _win_extents;
+ frame->max_win_extents = _max_win_extents;
+ frame->update_shadow = decor_frame_update_shadow;
+ frame->window_context = _window_context;
+ frame->window_context_no_shadow = _window_context_no_shadow;
+ frame->max_window_context = _max_window_context;
+ frame->max_window_context_no_shadow = _max_window_context_no_shadow;
+
+ return frame;
+}
+
+void
+destroy_normal_frame (decor_frame_t *frame)
+{
+ decor_frame_destroy (frame);
+}
+
+decor_frame_t *
+create_bare_frame (const gchar *type)
+{
+ decor_frame_t *frame = decor_frame_new (type);
+ decor_context_t _shadow_context = {
+ { 0, 0, 0, 0 },
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ };
+
+ decor_extents_t _shadow_extents = { 0, 0, 0, 0 };
+
+ frame->win_extents = _shadow_extents;
+ frame->max_win_extents = _shadow_extents;
+ frame->win_extents = _shadow_extents;
+ frame->window_context = _shadow_context;
+ frame->window_context_no_shadow = _shadow_context;
+ frame->max_window_context = _shadow_context;
+ frame->max_window_context_no_shadow = _shadow_context;
+ frame->update_shadow = bare_frame_update_shadow;
+
+ return frame;
+}
+
+void
+destroy_bare_frame (decor_frame_t *frame)
+{
+ decor_frame_destroy (frame);
+}
static const PangoFontDescription *
get_titlebar_font (decor_frame_t *frame)
{
if (use_system_font)
- {
return NULL;
- }
else
return frame->titlebar_font;
}
void
-update_titlebar_font ()
+frame_update_titlebar_font (decor_frame_t *frame)
{
const PangoFontDescription *font_desc;
PangoFontMetrics *metrics;
PangoLanguage *lang;
- unsigned int i = 0;
- for (i = 0; i < NUM_DECOR_FRAMES; i++)
+ frame = gwd_decor_frame_ref (frame);
+
+ font_desc = get_titlebar_font (frame);
+ if (!font_desc)
{
- decor_frame_t *frame = gwd_get_decor_frame (i);
- font_desc = get_titlebar_font (frame);
- if (!font_desc)
- {
- GtkStyle *default_style;
+ GtkStyle *default_style;
- default_style = gtk_widget_get_default_style ();
- font_desc = default_style->font_desc;
- }
+ default_style = gtk_widget_get_default_style ();
+ font_desc = default_style->font_desc;
+ }
+
+ pango_context_set_font_description (frame->pango_context, font_desc);
- pango_context_set_font_description (frame->pango_context, font_desc);
+ lang = pango_context_get_language (frame->pango_context);
+ metrics = pango_context_get_metrics (frame->pango_context, font_desc, lang);
- lang = pango_context_get_language (frame->pango_context);
- metrics = pango_context_get_metrics (frame->pango_context, font_desc, lang);
+ frame->text_height = PANGO_PIXELS (pango_font_metrics_get_ascent (metrics) +
+ pango_font_metrics_get_descent (metrics));
- frame->text_height = PANGO_PIXELS (pango_font_metrics_get_ascent (metrics) +
- pango_font_metrics_get_descent (metrics));
+ gwd_decor_frame_unref (frame);
- gwd_decor_frame_unref (frame);
+ pango_font_metrics_unref (metrics);
+}
- pango_font_metrics_unref (metrics);
- }
+void
+update_frames_titlebar_fonts (gpointer key,
+ gpointer value,
+ gpointer user_data)
+{
+ frame_update_titlebar_font ((decor_frame_t *) value);
+}
+void
+update_titlebar_font ()
+{
+ gwd_frames_foreach (update_frames_titlebar_fonts, NULL);
}
void
@@ -446,7 +527,7 @@ draw_border_shape (Display *xdisplay,
if (info)
d.frame = info->frame;
else
- d.frame = gwd_get_decor_frame (DECOR_FRAME_TYPE_DEFAULT);
+ d.frame = gwd_get_decor_frame ("default");
d.pixmap = gdk_pixmap_foreign_new_for_display (gdk_display_get_default (),
pixmap);
@@ -662,15 +743,65 @@ decor_frame_update_shadow (Display *xdisplay,
(void *) info);
}
+typedef struct _tdtd_shadow_options
+{
+ decor_shadow_options_t *shadow;
+ decor_shadow_options_t *no_shadow;
+} tdtd_shadow_options_t;
+
+void
+frame_update_shadow (decor_frame_t *frame,
+ decor_shadow_info_t *info,
+ decor_shadow_options_t *opt_shadow,
+ decor_shadow_options_t *opt_no_shadow)
+{
+ gwd_decor_frame_ref (frame);
+
+ (*frame->update_shadow) (gdk_x11_get_default_xdisplay (),
+ gdk_x11_screen_get_xscreen (gdk_screen_get_default ()),
+ frame, info, opt_shadow, opt_no_shadow);
+
+ gwd_decor_frame_unref (frame);
+}
+
+void
+update_frames_shadows (gpointer key,
+ gpointer value,
+ gpointer user_data)
+{
+ decor_frame_t *frame = (decor_frame_t *) value;
+ tdtd_shadow_options_t *opts = (tdtd_shadow_options_t *) user_data;
+
+ gwd_decor_frame_ref (frame);
+
+ decor_shadow_info_t *info = malloc (sizeof (decor_shadow_info_t));
+
+ if (!info)
+ return;
+
+ info->frame = frame;
+ info->state = 0;
+
+ frame_update_shadow (frame, info, opts->shadow, opts->no_shadow);
+
+ gwd_decor_frame_unref (frame);
+
+ free (info);
+ info = NULL;
+
+}
+
int
update_shadow (void)
{
decor_shadow_options_t opt_shadow;
decor_shadow_options_t opt_no_shadow;
- Display *xdisplay = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
- GdkDisplay *display = gdk_display_get_default ();
- GdkScreen *screen = gdk_display_get_default_screen (display);
- unsigned int i;
+ tdtd_shadow_options_t *opts;
+
+ opts = malloc (sizeof (tdtd_shadow_options_t));
+
+ if (!opts)
+ return 0;
opt_shadow.shadow_radius = shadow_radius;
opt_shadow.shadow_opacity = shadow_opacity;
@@ -686,25 +817,13 @@ update_shadow (void)
opt_no_shadow.shadow_offset_x = 0;
opt_no_shadow.shadow_offset_y = 0;
- for (i = 0; i < NUM_DECOR_FRAMES; i++)
- {
- decor_frame_t *frame = gwd_get_decor_frame (i);
- decor_shadow_info_t *info = malloc (sizeof (decor_shadow_info_t));
-
- if (!info)
- return 0;
-
- info->frame = frame;
- info->state = 0;
+ opts->shadow = &opt_shadow;
+ opts->no_shadow = &opt_no_shadow;
- (*frame->update_shadow) (xdisplay, gdk_x11_screen_get_xscreen (screen),
- frame, info, &opt_shadow, &opt_no_shadow);
+ gwd_frames_foreach (update_frames_shadows, (gpointer ) opts);
- gwd_decor_frame_unref (frame);
-
- free (info);
- info = NULL;
- }
+ if (opts)
+ free (opts);
return 1;
}
@@ -784,9 +903,9 @@ update_default_decorations (GdkScreen *screen)
decor_t d;
gint nQuad;
decor_quad_t quads[N_QUADS_MAX];
- decor_frame_t *frame = gwd_get_decor_frame (DECOR_FRAME_TYPE_DEFAULT);
- decor_frame_t *bare_frame = gwd_get_decor_frame (DECOR_FRAME_TYPE_BARE);
- decor_extents_t extents = frame->win_extents;
+ decor_frame_t *frame;
+ decor_frame_t *bare_frame = gwd_get_decor_frame ("bare");
+ decor_extents_t extents;
xroot = RootWindowOfScreen (gdk_x11_screen_get_xscreen (screen));
@@ -841,13 +960,15 @@ update_default_decorations (GdkScreen *screen)
if (minimal)
{
- gwd_decor_frame_unref (frame);
gwd_decor_frame_unref (bare_frame);
return;
}
memset (&d, 0, sizeof (d));
+ frame = gwd_get_decor_frame ("default");
+ extents = frame->win_extents;
+
d.context = &frame->window_context;
d.shadow = frame->border_shadow;
d.layout = pango_layout_new (frame->pango_context);
diff --git a/gtk/window-decorator/frames.c b/gtk/window-decorator/frames.c
index 7ce3107..40f5e3f 100644
--- a/gtk/window-decorator/frames.c
+++ b/gtk/window-decorator/frames.c
@@ -2,18 +2,44 @@
typedef struct _decor_frame_type_info
{
- create_frame_proc *create_func;
- destroy_frame_proc *destroy_func;
+ create_frame_proc create_func;
+ destroy_frame_proc destroy_func;
} decor_frame_type_info_t;
decor_frame_t decor_frames[NUM_DECOR_FRAMES];
GHashTable *frame_info_table;
+GHashTable *frames_table;
decor_frame_t *
-gwd_get_decor_frame (decor_frame_type type)
+gwd_get_decor_frame (const gchar *frame_name)
{
- decor_frames[type].refcount++;
- return &decor_frames[type];
+ decor_frame_t *frame = g_hash_table_lookup (frames_table, frame_name);
+
+ if (!frame)
+ {
+ /* Frame not found, look up frame type in the frame types
+ * hash table and create a new one */
+
+ decor_frame_type_info_t *info = g_hash_table_lookup (frame_info_table, frame_name);
+
+ if (!info)
+ g_critical ("Could not find frame info %s in frame type table", frame_name);
+
+ frame = (*info->create_func) (frame_name);
+
+ if (!frame)
+ g_critical ("Could not allocate frame %s", frame_name);
+
+ g_hash_table_insert (frames_table, frame->type, frame);
+
+ gwd_decor_frame_ref (frame);
+
+ decor_frame_refresh (frame);
+ }
+ else
+ gwd_decor_frame_ref (frame);
+
+ return frame;
}
decor_frame_t *
@@ -27,20 +53,37 @@ decor_frame_t *
gwd_decor_frame_unref (decor_frame_t *frame)
{
frame->refcount--;
+
+ if (frame->refcount == 0)
+ {
+ decor_frame_type_info_t *info = g_hash_table_lookup (frame_info_table, frame->type);
+ GList *list;
+
+ if (!info)
+ g_critical ("Couldn't find %s in frame info table", frame->type);
+
+ if(!g_hash_table_remove (frames_table, frame->type))
+ g_critical ("Could not remove frame type %s from hash_table!", frame->type);
+
+ (*info->destroy_func) (frame);
+ }
return frame;
}
gboolean
gwd_decor_frame_add_type (const gchar *name,
- create_frame_proc *create_func,
- destroy_frame_proc *destroy_func)
+ create_frame_proc create_func,
+ destroy_frame_proc destroy_func)
{
decor_frame_type_info_t *frame_type = malloc (sizeof (decor_frame_type_info_t));
if (!frame_type)
return FALSE;
- g_hash_table_replace (frame_info_table, strdup (name), frame_type);
+ frame_type->create_func = create_func;
+ frame_type->destroy_func = destroy_func;
+
+ g_hash_table_insert (frame_info_table, strdup (name), frame_type);
return TRUE;
}
@@ -52,6 +95,32 @@ gwd_decor_frame_remove_type (const gchar *name)
}
void
+gwd_frames_foreach (GHFunc foreach_func,
+ gpointer user_data)
+{
+ g_hash_table_foreach (frames_table, foreach_func, user_data);
+}
+
+void
+gwd_process_frames (GHFunc foreach_func,
+ const gchar *frame_keys[],
+ gint frame_keys_num,
+ gpointer user_data)
+{
+ gint i = 0;
+
+ for (; i < frame_keys_num; i++)
+ {
+ gpointer frame = g_hash_table_lookup (frames_table, frame_keys[i]);
+
+ if (!frame)
+ continue;
+
+ (*foreach_func) ((gpointer) frame_keys[i], frame, user_data);
+ }
+}
+
+void
destroy_frame_type (gpointer data)
{
decor_frame_type_info_t *info = (decor_frame_type_info_t *) data;
@@ -66,134 +135,150 @@ destroy_frame_type (gpointer data)
}
void
-initialize_decorations ()
+decor_frame_refresh (decor_frame_t *frame)
{
- GdkScreen *gdkscreen = gdk_screen_get_default ();
- GdkColormap *colormap;
- decor_extents_t _win_extents = { 6, 6, 6, 6 };
- decor_extents_t _max_win_extents = { 6, 6, 4, 6 };
- decor_extents_t _switcher_extents = { 6, 6, 6, 6 + SWITCHER_SPACE };
- decor_context_t _window_context = {
- { 0, 0, 0, 0 },
- 6, 6, 4, 6,
- 0, 0, 0, 0
- };
-
- decor_context_t _max_window_context = {
- { 0, 0, 0, 0 },
- 6, 6, 4, 6,
- 0, 0, 0, 0
- };
-
- decor_context_t _window_context_no_shadow = {
- { 0, 0, 0, 0 },
- 6, 6, 4, 6,
- 0, 0, 0, 0
- };
-
- decor_context_t _max_window_context_no_shadow = {
- { 0, 0, 0, 0 },
- 6, 6, 4, 6,
- 0, 0, 0, 0
- };
-
- decor_context_t _switcher_context = {
- { 0, 0, 0, 0 },
- 6, 6, 6, 6 + SWITCHER_SPACE,
- 0, 0, 0, 0
- };
-
- decor_context_t _shadow_context = {
- { 0, 0, 0, 0 },
- 0, 0, 0, 0,
- 0, 0, 0, 0,
- };
-
- decor_extents_t _shadow_extents = { 0, 0, 0, 0 };
-
- frame_info_table = g_hash_table_new_full (NULL, NULL, NULL, destroy_frame_type);
-
- unsigned int i;
-
- for (i = 0; i < NUM_DECOR_FRAMES; i++)
+ decor_shadow_options_t opt_shadow;
+ decor_shadow_options_t opt_no_shadow;
+ decor_shadow_info_t *info;
+
+ update_style (frame->style_window_rgba);
+ update_style (frame->style_window_rgb);
+
+ /* Should really read gconf for that */
+
+ gchar *str = NULL;
+
+#ifdef USE_GCONF
+
+ GConfClient *client = gconf_client_get_default ();
+
+ str = gconf_client_get_string (client,
+ COMPIZ_TITLEBAR_FONT_KEY,
+ NULL);
+#endif
+ if (!str)
+ str = g_strdup ("Sans Bold 12");
+
+ set_frame_scale (frame, str);
+
+ str = NULL;
+
+ frame_update_titlebar_font (frame);
+
+ /* FIXME */
+ if (strcmp (frame->type, "bare") &&
+ strcmp (frame->type, "switcher"))
+ (*theme_update_border_extents) (frame);
+
+ opt_shadow.shadow_radius = shadow_radius;
+ opt_shadow.shadow_opacity = shadow_opacity;
+
+ memcpy (opt_shadow.shadow_color, shadow_color, sizeof (shadow_color));
+
+ opt_shadow.shadow_offset_x = shadow_offset_x;
+ opt_shadow.shadow_offset_y = shadow_offset_y;
+
+ opt_no_shadow.shadow_radius = 0;
+ opt_no_shadow.shadow_opacity = 0;
+
+ opt_no_shadow.shadow_offset_x = 0;
+ opt_no_shadow.shadow_offset_y = 0;
+
+ info = malloc (sizeof (decor_shadow_info_t));
+
+ if (!info)
+ return;
+
+ info->frame = frame;
+ info->state = 0;
+
+ frame_update_shadow (frame, info, &opt_shadow, &opt_no_shadow);
+
+ free (info);
+ info = NULL;
+}
+
+decor_frame_t *
+decor_frame_new (const gchar *type)
+{
+ GdkScreen *gdkscreen = gdk_screen_get_default ();
+ GdkColormap *colormap;
+ decor_frame_t *frame = malloc (sizeof (decor_frame_t));
+
+ if (!frame)
{
- if (i == DECOR_FRAME_TYPE_SWITCHER)
- {
- decor_frames[i].win_extents = _switcher_extents;
- decor_frames[i].max_win_extents = _switcher_extents;
- decor_frames[i].win_extents = _switcher_extents;
- decor_frames[i].window_context = _switcher_context;
- decor_frames[i].window_context_no_shadow = _switcher_context;
- decor_frames[i].max_window_context = _switcher_context;
- decor_frames[i].max_window_context_no_shadow = _switcher_context;
- decor_frames[i].update_shadow = switcher_frame_update_shadow;
- }
- else if (i == DECOR_FRAME_TYPE_BARE)
- {
- decor_frames[i].win_extents = _shadow_extents;
- decor_frames[i].max_win_extents = _shadow_extents;
- decor_frames[i].win_extents = _shadow_extents;
- decor_frames[i].window_context = _shadow_context;
- decor_frames[i].window_context_no_shadow = _shadow_context;
- decor_frames[i].max_window_context = _shadow_context;
- decor_frames[i].max_window_context_no_shadow = _shadow_context;
- decor_frames[i].update_shadow = bare_frame_update_shadow;
- }
- else
- {
- decor_frames[i].win_extents = _win_extents;
- decor_frames[i].max_win_extents = _max_win_extents;
- decor_frames[i].update_shadow = decor_frame_update_shadow;
- decor_frames[i].window_context = _window_context;
- decor_frames[i].window_context_no_shadow = _window_context_no_shadow;
- decor_frames[i].max_window_context = _max_window_context;
- decor_frames[i].max_window_context_no_shadow = _max_window_context_no_shadow;
- }
-
- decor_frames[i].titlebar_height = 17;
- decor_frames[i].max_titlebar_height = 17;
- decor_frames[i].border_shadow = NULL;
- decor_frames[i].border_no_shadow = NULL;
- decor_frames[i].max_border_no_shadow = NULL;
- decor_frames[i].max_border_shadow = NULL;
- decor_frames[i].titlebar_font = NULL;
- decor_frames[i].type = i;
-
- decor_frames[i].style_window_rgba = gtk_window_new (GTK_WINDOW_POPUP);
-
- colormap = gdk_screen_get_rgba_colormap (gdkscreen);
- if (colormap)
- gtk_widget_set_colormap (decor_frames[i].style_window_rgba, colormap);
-
- gtk_widget_realize (decor_frames[i].style_window_rgba);
-
- gtk_widget_set_size_request (decor_frames[i].style_window_rgba, 0, 0);
- gtk_window_move (GTK_WINDOW (decor_frames[i].style_window_rgba), -100, -100);
- gtk_widget_show_all (decor_frames[i].style_window_rgba);
-
- decor_frames[i].pango_context = gtk_widget_create_pango_context (decor_frames[i].style_window_rgba);
-
- g_signal_connect_data (decor_frames[i].style_window_rgba, "style-set",
- G_CALLBACK (style_changed),
- (gpointer) decor_frames[i].pango_context, 0, 0);
-
- decor_frames[i].style_window_rgb = gtk_window_new (GTK_WINDOW_POPUP);
-
- colormap = gdk_screen_get_rgb_colormap (gdkscreen);
- if (colormap)
- gtk_widget_set_colormap (decor_frames[i].style_window_rgb, colormap);
-
- gtk_widget_realize (decor_frames[i].style_window_rgb);
-
- gtk_widget_set_size_request (decor_frames[i].style_window_rgb, 0, 0);
- gtk_window_move (GTK_WINDOW (decor_frames[i].style_window_rgb), -100, -100);
- gtk_widget_show_all (decor_frames[i].style_window_rgb);
-
- g_signal_connect_data (decor_frames[i].style_window_rgb, "style-set",
- G_CALLBACK (style_changed),
- (gpointer) decor_frames[i].pango_context, 0, 0);
-
- update_style (decor_frames[i].style_window_rgba);
- update_style (decor_frames[i].style_window_rgb);
+ g_critical ("Couldn't allocate frame!");
+ return NULL;
}
+
+ frame->type = strdup (type);
+ frame->refcount = 0;
+ frame->titlebar_height = 17;
+ frame->max_titlebar_height = 17;
+ frame->border_shadow = NULL;
+ frame->border_no_shadow = NULL;
+ frame->max_border_no_shadow = NULL;
+ frame->max_border_shadow = NULL;
+ frame->titlebar_font = NULL;
+
+ frame->style_window_rgba = gtk_window_new (GTK_WINDOW_POPUP);
+
+ colormap = gdk_screen_get_rgba_colormap (gdkscreen);
+ if (colormap)
+ gtk_widget_set_colormap (frame->style_window_rgba, colormap);
+
+ gtk_widget_realize (frame->style_window_rgba);
+
+ gtk_widget_set_size_request (frame->style_window_rgba, 0, 0);
+ gtk_window_move (GTK_WINDOW (frame->style_window_rgba), -100, -100);
+ gtk_widget_show_all (frame->style_window_rgba);
+
+ frame->pango_context = gtk_widget_create_pango_context (frame->style_window_rgba);
+
+ g_signal_connect_data (frame->style_window_rgba, "style-set",
+ G_CALLBACK (style_changed),
+ (gpointer) frame->pango_context, 0, 0);
+
+ frame->style_window_rgb = gtk_window_new (GTK_WINDOW_POPUP);
+
+ colormap = gdk_screen_get_rgb_colormap (gdkscreen);
+ if (colormap)
+ gtk_widget_set_colormap (frame->style_window_rgb, colormap);
+
+ gtk_widget_realize (frame->style_window_rgb);
+
+ gtk_widget_set_size_request (frame->style_window_rgb, 0, 0);
+ gtk_window_move (GTK_WINDOW (frame->style_window_rgb), -100, -100);
+ gtk_widget_show_all (frame->style_window_rgb);
+
+ g_signal_connect_data (frame->style_window_rgb, "style-set",
+ G_CALLBACK (style_changed),
+ (gpointer) frame->pango_context, 0, 0);
+
+ return frame;
+}
+
+void
+decor_frame_destroy (decor_frame_t *frame)
+{
+ if (frame)
+ free (frame->type);
+
+ free (frame);
+}
+
+void
+initialize_decorations ()
+{
+ frame_info_table = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, destroy_frame_type);
+
+ gwd_decor_frame_add_type ("default", create_normal_frame, destroy_normal_frame);
+ gwd_decor_frame_add_type ("normal", create_normal_frame, destroy_normal_frame);
+ gwd_decor_frame_add_type ("dialog", create_normal_frame, destroy_normal_frame);
+ gwd_decor_frame_add_type ("menu", create_normal_frame, destroy_normal_frame);
+ gwd_decor_frame_add_type ("utility", create_normal_frame, destroy_normal_frame);
+ gwd_decor_frame_add_type ("switcher", create_switcher_frame, destroy_switcher_frame);
+ gwd_decor_frame_add_type ("bare", create_bare_frame, destroy_bare_frame);
+
+ frames_table = g_hash_table_new (g_str_hash, g_str_equal);
}
diff --git a/gtk/window-decorator/gtk-window-decorator.c b/gtk/window-decorator/gtk-window-decorator.c
index d748d07..8152277 100644
--- a/gtk/window-decorator/gtk-window-decorator.c
+++ b/gtk/window-decorator/gtk-window-decorator.c
@@ -92,6 +92,10 @@ struct _pos pos[3][3] = {
{ 6, 2, 16, 16, 0, 0, 0, 0, 0, 0 }
};
+const gchar * window_type_frames[WINDOW_TYPE_FRAMES_NUM] = {
+ "normal", "dialog", "menu", "utility"
+};
+
char *program_name;
GtkWidget *switcher_style_window_rgba;
diff --git a/gtk/window-decorator/gtk-window-decorator.h b/gtk/window-decorator/gtk-window-decorator.h
index ed79554..1244688 100644
--- a/gtk/window-decorator/gtk-window-decorator.h
+++ b/gtk/window-decorator/gtk-window-decorator.h
@@ -349,6 +349,12 @@ typedef enum _decor_frame_type {
typedef struct _decor_frame decor_frame_t;
typedef struct _decor_shadow_info decor_shadow_info_t;
+struct _decor_shadow_info
+{
+ decor_frame_t *frame;
+ unsigned int state;
+};
+
void
switcher_frame_update_shadow (Display *xdisplay,
Screen *screen,
@@ -380,11 +386,32 @@ typedef void (*frame_update_shadow_proc) (Display *display,
decor_shadow_options_t *opt_shadow,
decor_shadow_options_t *opt_no_shadow);
-typedef decor_frame_t (*create_frame_proc) ();
+typedef decor_frame_t * (*create_frame_proc) (const gchar *);
typedef void (*destroy_frame_proc) (decor_frame_t *);
+#define WINDOW_TYPE_FRAMES_NUM 4
+const gchar * window_type_frames[WINDOW_TYPE_FRAMES_NUM];
+
+void
+frame_update_titlebar_font (decor_frame_t *frame);
+
+void
+set_frame_scale (decor_frame_t *frame,
+ gchar *font_str);
+
+void
+frame_update_shadow (decor_frame_t *frame,
+ decor_shadow_info_t *info,
+ decor_shadow_options_t *opt_shadow,
+ decor_shadow_options_t *opt_no_shadow);
+
+void
+update_frames_border_extents (gpointer key,
+ gpointer value,
+ gpointer user_data);
+
decor_frame_t *
-gwd_get_decor_frame (decor_frame_type type);
+gwd_get_decor_frame (const gchar *);
decor_frame_t *
gwd_decor_frame_ref (decor_frame_t *);
@@ -392,6 +419,22 @@ gwd_decor_frame_ref (decor_frame_t *);
decor_frame_t *
gwd_decor_frame_unref (decor_frame_t *);
+void
+gwd_frames_foreach (GHFunc foreach_func,
+ gpointer user_data);
+
+void
+gwd_process_frames (GHFunc foreach_func,
+ const gchar *frame_keys[],
+ gint frame_keys_num,
+ gpointer user_data);
+
+decor_frame_t *
+decor_frame_new (const gchar *type);
+
+void
+decor_frame_destroy (decor_frame_t *);
+
struct _decor_frame {
decor_extents_t win_extents;
decor_extents_t max_win_extents;
@@ -410,7 +453,7 @@ struct _decor_frame {
GtkWidget *style_window_rgba;
GtkWidget *style_window_rgb;
gint text_height;
- decor_frame_type type;
+ gchar *type;
frame_update_shadow_proc update_shadow;
gint refcount;
@@ -461,7 +504,7 @@ gboolean (*theme_calc_decoration_size) (decor_t *d,
int text_width,
int *width,
int *height);
-void (*theme_update_border_extents) ();
+void (*theme_update_border_extents) (decor_frame_t *frame);
void (*theme_get_event_window_position) (decor_t *d,
gint i,
gint j,
@@ -528,6 +571,18 @@ initialize_decorations ();
/* decorator.c */
+decor_frame_t *
+create_normal_frame (const gchar *type);
+
+void
+destroy_normal_frame ();
+
+decor_frame_t *
+create_bare_frame (const gchar *type);
+
+void
+destroy_bare_frame ();
+
gboolean
update_window_decoration_size (WnckWindow *win);
@@ -575,7 +630,7 @@ copy_to_front_buffer (decor_t *d);
/* wnck.c*/
-decor_frame_type
+const gchar *
get_frame_type (WnckWindowType type);
void
@@ -730,7 +785,7 @@ pixmap_new_from_pixbuf (GdkPixbuf *pixbuf, GtkWidget *parent);
#ifdef USE_METACITY
MetaFrameType
-meta_get_frame_type_for_decor_type (decor_frame_type frame_type);
+meta_get_frame_type_for_decor_type (const gchar *frame_type);
void
meta_draw_window_decoration (decor_t *d);
@@ -793,6 +848,12 @@ meta_update_button_layout (const char *value);
#define SWITCHER_ALPHA 0xa0a0
+decor_frame_t *
+create_switcher_frame (const gchar *);
+
+void
+destroy_switcher_frame ();
+
void
draw_switcher_decoration (decor_t *d);
diff --git a/gtk/window-decorator/metacity.c b/gtk/window-decorator/metacity.c
index 42f03ad..1e9e451 100644
--- a/gtk/window-decorator/metacity.c
+++ b/gtk/window-decorator/metacity.c
@@ -410,6 +410,9 @@ meta_get_decoration_geometry (decor_t *d,
{
gint left_width, right_width, top_height, bottom_height;
+ if (!(frame_type < META_FRAME_TYPE_LAST))
+ frame_type = META_FRAME_TYPE_NORMAL;
+
if (meta_button_layout_set)
{
*button_layout = meta_button_layout;
@@ -514,33 +517,6 @@ meta_get_decoration_geometry (decor_t *d,
clip->height += top_height + bottom_height;
}
-MetaFrameType
-meta_get_frame_type_for_decor_type (decor_frame_type frame_type)
-{
- MetaFrameType type;
-
- switch (frame_type)
- {
- case DECOR_FRAME_TYPE_NORMAL:
- type = META_FRAME_TYPE_NORMAL;
- break;
- case DECOR_FRAME_TYPE_DIALOG:
- type = META_FRAME_TYPE_DIALOG;
- break;
- case DECOR_FRAME_TYPE_MENU:
- type = META_FRAME_TYPE_MENU;
- break;
- case DECOR_FRAME_TYPE_UTILITY:
- type = META_FRAME_TYPE_UTILITY;
- break;
- default:
- type = META_FRAME_TYPE_LAST;
- break;
- }
-
- return type;
-}
-
void
meta_draw_window_decoration (decor_t *d)
{
@@ -605,9 +581,9 @@ meta_draw_window_decoration (decor_t *d)
theme = meta_theme_get_current ();
- if (d->frame->type < DECOR_FRAME_TYPE_SWITCHER)
- frame_type = meta_get_frame_type_for_decor_type (d->frame->type);
- else
+ frame_type = meta_frame_type_from_string (d->frame->type);
+
+ if (frame_type == META_FRAME_TYPE_LAST)
frame_type = META_FRAME_TYPE_NORMAL;
meta_get_decoration_geometry (d, theme, &flags, &fgeom, &button_layout,
@@ -983,7 +959,7 @@ meta_get_button_position (decor_t *d,
theme = meta_theme_get_current ();
meta_get_decoration_geometry (d, theme, &flags, &fgeom, &button_layout,
- meta_get_frame_type_for_decor_type (d->frame->type),
+ meta_frame_type_from_string (d->frame->type),
&clip);
switch (i) {
@@ -1089,12 +1065,12 @@ meta_get_title_scale (decor_frame_t *frame)
{
MetaTheme *theme = meta_theme_get_current ();
MetaFrameType type;
- MetaFrameFlags flags = 0xc33;
+ MetaFrameFlags flags = 0xc33; /* fixme */
- if (frame->type >= DECOR_FRAME_TYPE_SWITCHER)
- return 1.0f;
+ type = meta_frame_type_from_string (frame->type);
- type = meta_get_frame_type_for_decor_type (frame->type);
+ if (type == META_FRAME_TYPE_LAST)
+ return 1.0f;
gfloat scale = meta_theme_get_title_scale (theme, type, flags);
@@ -1226,7 +1202,7 @@ meta_get_event_window_position (decor_t *d,
win_type = wnck_window_get_window_type (d->win);
meta_get_decoration_geometry (d, theme, &flags, &fgeom, &button_layout,
- meta_get_frame_type_for_decor_type (d->frame->type),
+ meta_frame_type_from_string (d->frame->type),
&clip);
width += fgeom.right_width + fgeom.left_width;
@@ -1590,59 +1566,52 @@ meta_update_button_layout (const char *value)
}
void
-meta_update_border_extents ()
+meta_update_border_extents (decor_frame_t *frame)
{
- MetaTheme *theme;
- MetaFrameType frame_type;
- decor_frame_t *frame, *default_frame;
+ MetaTheme *theme = meta_theme_get_current ();
- gint top_height, bottom_height, left_width, right_width;
- unsigned int i;
+ gwd_decor_frame_ref (frame);
+ decor_frame_t *default_frame = gwd_get_decor_frame ("default");
+ MetaFrameType frame_type = meta_frame_type_from_string (frame->type);
+ gint top_height, bottom_height, left_width, right_width;
- theme = meta_theme_get_current ();
+ if (!(frame_type < META_FRAME_TYPE_LAST))
+ frame_type = META_FRAME_TYPE_NORMAL;
- for (i = 0; i < DECOR_FRAME_TYPE_SWITCHER; i++)
- {
- frame = gwd_get_decor_frame (i);
- default_frame = gwd_get_decor_frame (DECOR_FRAME_TYPE_DEFAULT);
- frame_type = meta_get_frame_type_for_decor_type (i);
-
- meta_theme_get_frame_borders (theme,
- frame_type,
- frame->text_height,
- 0,
- &top_height,
- &bottom_height,
- &left_width,
- &right_width);
-
- frame->win_extents.top = default_frame->win_extents.top;
- frame->win_extents.bottom = bottom_height;
- frame->win_extents.left = left_width;
- frame->win_extents.right = right_width;
-
- frame->titlebar_height = top_height - frame->win_extents.top;
-
- meta_theme_get_frame_borders (theme,
- frame_type,
- frame->text_height,
- META_FRAME_MAXIMIZED,
- &top_height,
- &bottom_height,
- &left_width,
- &right_width);
-
- frame->max_win_extents.top = default_frame->win_extents.top;
- frame->max_win_extents.bottom = bottom_height;
- frame->max_win_extents.left = left_width;
- frame->max_win_extents.right = right_width;
-
- frame->max_titlebar_height = top_height - frame->max_win_extents.top;
-
- gwd_decor_frame_unref (frame);
- gwd_decor_frame_unref (default_frame);
+ meta_theme_get_frame_borders (theme,
+ frame_type,
+ frame->text_height,
+ 0,
+ &top_height,
+ &bottom_height,
+ &left_width,
+ &right_width);
- }
+ frame->win_extents.top = default_frame->win_extents.top;
+ frame->win_extents.bottom = bottom_height;
+ frame->win_extents.left = left_width;
+ frame->win_extents.right = right_width;
+
+ frame->titlebar_height = top_height - frame->win_extents.top;
+
+ meta_theme_get_frame_borders (theme,
+ frame_type,
+ frame->text_height,
+ META_FRAME_MAXIMIZED,
+ &top_height,
+ &bottom_height,
+ &left_width,
+ &right_width);
+
+ frame->max_win_extents.top = default_frame->win_extents.top;
+ frame->max_win_extents.bottom = bottom_height;
+ frame->max_win_extents.left = left_width;
+ frame->max_win_extents.right = right_width;
+
+ frame->max_titlebar_height = top_height - frame->max_win_extents.top;
+
+ gwd_decor_frame_unref (frame);
+ gwd_decor_frame_unref (default_frame);
}
#endif
diff --git a/gtk/window-decorator/settings.c b/gtk/window-decorator/settings.c
index dc9dc07..617f30f 100644
--- a/gtk/window-decorator/settings.c
+++ b/gtk/window-decorator/settings.c
@@ -287,11 +287,46 @@ button_layout_changed (GConfClient *client)
return FALSE;
}
+void
+set_frame_scale (decor_frame_t *frame,
+ gchar *font_str)
+{
+ gfloat scale = 1.0f;
+
+ gwd_decor_frame_ref (frame);
+
+ if (frame->titlebar_font)
+ pango_font_description_free (frame->titlebar_font);
+
+ frame->titlebar_font = pango_font_description_from_string (font_str);
+
+ scale = (*theme_get_title_scale) (frame);
+
+ pango_font_description_set_size (frame->titlebar_font,
+ MAX (pango_font_description_get_size (frame->titlebar_font) * scale, 1));
+
+ gwd_decor_frame_unref (frame);
+}
+
+void
+set_frames_scales (gpointer key,
+ gpointer value,
+ gpointer user_data)
+{
+ decor_frame_t *frame = (decor_frame_t *) value;
+ gchar *font_str = (gchar *) user_data;
+
+ gwd_decor_frame_ref (frame);
+
+ set_frame_scale (frame, font_str);
+
+ gwd_decor_frame_unref (frame);
+}
+
static void
titlebar_font_changed (GConfClient *client)
{
gchar *str;
- gint i;
str = gconf_client_get_string (client,
COMPIZ_TITLEBAR_FONT_KEY,
@@ -299,22 +334,7 @@ titlebar_font_changed (GConfClient *client)
if (!str)
str = g_strdup ("Sans Bold 12");
- for (i = 0; i < NUM_DECOR_FRAMES; i++)
- {
- decor_frame_t *frame = gwd_get_decor_frame (i);
- gfloat scale = 1.0f;
- if (frame->titlebar_font)
- pango_font_description_free (frame->titlebar_font);
-
- frame->titlebar_font = pango_font_description_from_string (str);
-
- scale = (*theme_get_title_scale) (frame);
-
- pango_font_description_set_size (frame->titlebar_font,
- MAX (pango_font_description_get_size (frame->titlebar_font) * scale, 1));
-
- gwd_decor_frame_unref (frame);
- }
+ gwd_frames_foreach (set_frames_scales, (gpointer) str);
g_free (str);
}
@@ -449,7 +469,7 @@ gboolean
init_settings (WnckScreen *screen)
{
AtkObject *switcher_label_obj;
- decor_frame_t *switcher_frame = gwd_get_decor_frame (DECOR_FRAME_TYPE_SWITCHER);
+ decor_frame_t *switcher_frame = gwd_get_decor_frame ("switcher");
#ifdef USE_GCONF
GConfClient *gconf;
@@ -510,7 +530,10 @@ init_settings (WnckScreen *screen)
blur_settings_changed (gconf);
#endif
- (*theme_update_border_extents) ();
+ gwd_process_frames (update_frames_border_extents,
+ window_type_frames,
+ WINDOW_TYPE_FRAMES_NUM,
+ NULL);
shadow_property_changed (screen);
diff --git a/gtk/window-decorator/switcher.c b/gtk/window-decorator/switcher.c
index 102678d..1c4254e 100644
--- a/gtk/window-decorator/switcher.c
+++ b/gtk/window-decorator/switcher.c
@@ -1,5 +1,40 @@
#include "gtk-window-decorator.h"
+decor_frame_t *
+create_switcher_frame (const gchar *type)
+{
+ decor_frame_t *frame = decor_frame_new (type);
+ decor_extents_t _switcher_extents = { 6, 6, 6, 6 + SWITCHER_SPACE };
+
+ decor_context_t _switcher_context = {
+ { 0, 0, 0, 0 },
+ 6, 6, 6, 6 + SWITCHER_SPACE,
+ 0, 0, 0, 0
+ };
+
+ frame->win_extents = _switcher_extents;
+ frame->max_win_extents = _switcher_extents;
+ frame->win_extents = _switcher_extents;
+ frame->window_context = _switcher_context;
+ frame->window_context_no_shadow = _switcher_context;
+ frame->max_window_context = _switcher_context;
+ frame->max_window_context_no_shadow = _switcher_context;
+ frame->update_shadow = switcher_frame_update_shadow;
+
+ /* keep the switcher frame around since we need to keep its
+ * contents */
+
+ gwd_decor_frame_ref (frame);
+
+ return frame;
+}
+
+void
+destroy_switcher_frame (decor_frame_t *frame)
+{
+ decor_frame_destroy (frame);
+}
+
static void
draw_switcher_background (decor_t *d)
{
@@ -308,7 +343,7 @@ update_switcher_window (Window popup,
d->decorated = FALSE;
d->draw = draw_switcher_decoration;
- d->frame = gwd_get_decor_frame (DECOR_FRAME_TYPE_SWITCHER);
+ d->frame = gwd_get_decor_frame ("switcher");
decor_get_default_layout (&d->frame->window_context, width, 1, &d->border_layout);
diff --git a/gtk/window-decorator/wnck.c b/gtk/window-decorator/wnck.c
index 321f7fe..166eeb4 100644
--- a/gtk/window-decorator/wnck.c
+++ b/gtk/window-decorator/wnck.c
@@ -1,30 +1,23 @@
#include "gtk-window-decorator.h"
-decor_frame_type
+const gchar *
get_frame_type (WnckWindowType wnck_type)
{
- decor_frame_type frame_type;
-
switch (wnck_type)
{
case WNCK_WINDOW_NORMAL:
- frame_type = DECOR_FRAME_TYPE_NORMAL;
- break;
+ return "normal";
case WNCK_WINDOW_DIALOG:
- frame_type = DECOR_FRAME_TYPE_DIALOG;
- break;
+ return "dialog";
case WNCK_WINDOW_MENU:
- frame_type = DECOR_FRAME_TYPE_MENU;
- break;
+ return "menu";
case WNCK_WINDOW_UTILITY:
- frame_type = DECOR_FRAME_TYPE_UTILITY;
- break;
+ return "utility";
default:
- frame_type = DECOR_FRAME_TYPE_UNDECORATED;
- break;
+ return "bare";
}
- return frame_type;
+ return "normal";
}
static void
@@ -105,6 +98,16 @@ window_actions_changed (WnckWindow *win)
}
void
+update_frames_border_extents (gpointer key,
+ gpointer value,
+ gpointer user_data)
+{
+ decor_frame_t *frame = (decor_frame_t *) value;
+
+ (*theme_update_border_extents) (frame);
+}
+
+void
decorations_changed (WnckScreen *screen)
{
GdkDisplay *gdkdisplay;
@@ -116,7 +119,10 @@ decorations_changed (WnckScreen *screen)
gdkscreen = gdk_display_get_default_screen (gdkdisplay);
update_titlebar_font ();
- (*theme_update_border_extents) ();
+ gwd_process_frames (update_frames_border_extents,
+ window_type_frames,
+ WINDOW_TYPE_FRAMES_NUM,
+ NULL);
update_shadow ();
update_default_decorations (gdkscreen);