1
#include "gtk-window-decorator.h"
4
draw_switcher_background (decor_t *d)
6
Display *xdisplay = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
10
double alpha = SWITCHER_ALPHA / 65535.0;
11
double x1, y1, x2, y2, h;
14
ushort a = SWITCHER_ALPHA;
16
if (!d->buffer_pixmap)
19
style = gtk_widget_get_style (style_window_rgba);
21
color.r = style->bg[GTK_STATE_NORMAL].red / 65535.0;
22
color.g = style->bg[GTK_STATE_NORMAL].green / 65535.0;
23
color.b = style->bg[GTK_STATE_NORMAL].blue / 65535.0;
25
cr = gdk_cairo_create (GDK_DRAWABLE (d->buffer_pixmap));
27
cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
29
top = _switcher_extents.top;
31
x1 = switcher_context.left_space - _switcher_extents.left;
32
y1 = switcher_context.top_space - _switcher_extents.top;
33
x2 = d->width - switcher_context.right_space + _switcher_extents.right;
34
y2 = d->height - switcher_context.bottom_space + _switcher_extents.bottom;
36
h = y2 - y1 - _switcher_extents.top - _switcher_extents.top;
38
cairo_set_line_width (cr, 1.0);
40
cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
42
draw_shadow_background (d, cr, switcher_shadow, &switcher_context);
44
fill_rounded_rectangle (cr,
47
_switcher_extents.left - 0.5,
50
&color, alpha, &color, alpha * 0.75,
51
SHADE_TOP | SHADE_LEFT);
53
fill_rounded_rectangle (cr,
54
x1 + _switcher_extents.left,
56
x2 - x1 - _switcher_extents.left -
57
_switcher_extents.right,
60
&color, alpha, &color, alpha * 0.75,
63
fill_rounded_rectangle (cr,
64
x2 - _switcher_extents.right,
66
_switcher_extents.right - 0.5,
69
&color, alpha, &color, alpha * 0.75,
70
SHADE_TOP | SHADE_RIGHT);
72
fill_rounded_rectangle (cr,
75
_switcher_extents.left - 0.5,
78
&color, alpha, &color, alpha * 0.75,
81
fill_rounded_rectangle (cr,
82
x2 - _switcher_extents.right,
84
_switcher_extents.right - 0.5,
87
&color, alpha, &color, alpha * 0.75,
90
fill_rounded_rectangle (cr,
92
y2 - _switcher_extents.top,
93
_switcher_extents.left - 0.5,
94
_switcher_extents.top - 0.5,
95
5.0, CORNER_BOTTOMLEFT,
96
&color, alpha, &color, alpha * 0.75,
97
SHADE_BOTTOM | SHADE_LEFT);
99
fill_rounded_rectangle (cr,
100
x1 + _switcher_extents.left,
101
y2 - _switcher_extents.top,
102
x2 - x1 - _switcher_extents.left -
103
_switcher_extents.right,
104
_switcher_extents.top - 0.5,
106
&color, alpha, &color, alpha * 0.75,
109
fill_rounded_rectangle (cr,
110
x2 - _switcher_extents.right,
111
y2 - _switcher_extents.top,
112
_switcher_extents.right - 0.5,
113
_switcher_extents.top - 0.5,
114
5.0, CORNER_BOTTOMRIGHT,
115
&color, alpha, &color, alpha * 0.75,
116
SHADE_BOTTOM | SHADE_RIGHT);
118
cairo_rectangle (cr, x1 + _switcher_extents.left,
120
x2 - x1 - _switcher_extents.left - _switcher_extents.right,
122
gdk_cairo_set_source_color_alpha (cr,
123
&style->bg[GTK_STATE_NORMAL],
127
cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
129
rounded_rectangle (cr,
131
x2 - x1 - 1.0, y2 - y1 - 1.0,
133
CORNER_TOPLEFT | CORNER_TOPRIGHT | CORNER_BOTTOMLEFT |
138
cairo_translate (cr, 1.0, 1.0);
140
rounded_rectangle (cr,
142
x2 - x1 - 1.0, y2 - y1 - 1.0,
144
CORNER_TOPLEFT | CORNER_TOPRIGHT | CORNER_BOTTOMLEFT |
147
cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.4);
150
cairo_translate (cr, -2.0, -2.0);
152
rounded_rectangle (cr,
154
x2 - x1 - 1.0, y2 - y1 - 1.0,
156
CORNER_TOPLEFT | CORNER_TOPRIGHT | CORNER_BOTTOMLEFT |
159
cairo_set_source_rgba (cr, 0.0, 0.0, 0.0, 0.1);
162
cairo_translate (cr, 1.0, 1.0);
164
cairo_reset_clip (cr);
166
rounded_rectangle (cr,
168
x2 - x1 - 1.0, y2 - y1 - 1.0,
170
CORNER_TOPLEFT | CORNER_TOPRIGHT | CORNER_BOTTOMLEFT |
173
gdk_cairo_set_source_color_alpha (cr,
174
&style->fg[GTK_STATE_NORMAL],
181
copy_to_front_buffer (d);
183
pixel = ((((a * style->bg[GTK_STATE_NORMAL].blue ) >> 24) & 0x0000ff) |
184
(((a * style->bg[GTK_STATE_NORMAL].green) >> 16) & 0x00ff00) |
185
(((a * style->bg[GTK_STATE_NORMAL].red ) >> 8) & 0xff0000) |
186
(((a & 0xff00) << 16)));
188
decor_update_switcher_property (d);
190
gdk_error_trap_push ();
191
XSetWindowBackground (xdisplay, d->prop_xid, pixel);
192
XClearWindow (xdisplay, d->prop_xid);
194
gdk_display_sync (gdk_display_get_default ());
195
gdk_error_trap_pop ();
201
draw_switcher_foreground (decor_t *d)
205
double alpha = SWITCHER_ALPHA / 65535.0;
207
if (!d->pixmap || !d->buffer_pixmap)
210
style = gtk_widget_get_style (style_window_rgba);
212
cr = gdk_cairo_create (GDK_DRAWABLE (d->buffer_pixmap));
214
cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
216
cairo_rectangle (cr, switcher_context.left_space,
217
d->height - switcher_context.bottom_space,
218
d->width - switcher_context.left_space -
219
switcher_context.right_space,
222
gdk_cairo_set_source_color_alpha (cr,
223
&style->bg[GTK_STATE_NORMAL],
231
cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
233
gdk_cairo_set_source_color_alpha (cr,
234
&style->fg[GTK_STATE_NORMAL],
237
pango_layout_get_pixel_size (d->layout, &w, NULL);
239
cairo_move_to (cr, d->width / 2 - w / 2,
240
d->height - switcher_context.bottom_space +
241
SWITCHER_SPACE / 2 - text_height / 2);
243
pango_cairo_show_layout (cr, d->layout);
248
copy_to_front_buffer (d);
252
draw_switcher_decoration (decor_t *d)
255
draw_switcher_background (d);
257
draw_switcher_foreground (d);
261
switcher_window_closed ()
263
g_free (switcher_window);
264
switcher_window = NULL;
267
/* Switcher is override-redirect now, we need to track
270
switcher_window_opened (Window popup, Window window)
274
d = switcher_window = calloc (1, sizeof (decor_t));
282
update_switcher_window (Window popup,
285
decor_t *d = switcher_window;
286
GdkPixmap *pixmap, *buffer_pixmap = NULL;
287
unsigned int height, width = 0, border, depth;
290
WnckWindow *selected_win;
292
XRenderPictFormat *format;
295
d = switcher_window_opened (popup, selected);
297
xdisplay = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
299
/* Thats a round-trip */
300
XGetGeometry (gdk_x11_get_default_xdisplay (), popup, &root_return,
301
&x, &y, &width, &height, &border, &depth);
303
decor_get_default_layout (&switcher_context, width, 1, &d->border_layout);
305
width = d->border_layout.width;
306
height = d->border_layout.height;
308
d->decorated = FALSE;
309
d->draw = draw_switcher_decoration;
311
if (!d->pixmap && switcher_pixmap)
313
g_object_ref (G_OBJECT (switcher_pixmap));
315
d->pixmap = switcher_pixmap;
318
if (!d->buffer_pixmap && switcher_buffer_pixmap)
320
g_object_ref (G_OBJECT (switcher_buffer_pixmap));
321
d->buffer_pixmap = switcher_buffer_pixmap;
325
d->width = switcher_width;
328
d->height = switcher_height;
330
selected_win = wnck_window_get (selected);
334
PangoLayoutLine *line;
343
name = wnck_window_get_name (selected_win);
344
if (name && (name_length = strlen (name)))
348
d->layout = pango_layout_new (pango_context);
350
pango_layout_set_wrap (d->layout, PANGO_WRAP_CHAR);
357
tw = width - switcher_context.left_space -
358
switcher_context.right_space - 64;
359
pango_layout_set_auto_dir (d->layout, FALSE);
360
pango_layout_set_width (d->layout, tw * PANGO_SCALE);
361
pango_layout_set_text (d->layout, name, name_length);
363
line = pango_layout_get_line (d->layout, 0);
365
name_length = line->length;
366
if (pango_layout_get_line_count (d->layout) > 1)
370
g_object_unref (G_OBJECT (d->layout));
375
d->name = g_strndup (name, name_length);
376
strcpy (d->name + name_length - 3, "...");
380
d->name = g_strndup (name, name_length);
383
pango_layout_set_text (d->layout, d->name, name_length);
388
g_object_unref (G_OBJECT (d->layout));
393
if (selected != switcher_selected_window)
395
gtk_label_set_text (GTK_LABEL (switcher_label), "");
396
if (selected_win && d->name)
397
gtk_label_set_text (GTK_LABEL (switcher_label), d->name);
398
switcher_selected_window = selected;
401
pixmap = create_pixmap (width, height, 32);
405
buffer_pixmap = create_pixmap (width, height, 32);
408
g_object_unref (G_OBJECT (pixmap));
413
g_object_unref (G_OBJECT (switcher_pixmap));
415
if (switcher_buffer_pixmap)
416
g_object_unref (G_OBJECT (switcher_buffer_pixmap));
419
g_object_unref (G_OBJECT (d->pixmap));
421
if (d->buffer_pixmap)
422
g_object_unref (G_OBJECT (d->buffer_pixmap));
425
cairo_destroy (d->cr);
428
XRenderFreePicture (xdisplay, d->picture);
430
switcher_pixmap = pixmap;
431
switcher_buffer_pixmap = buffer_pixmap;
433
switcher_width = width;
434
switcher_height = height;
436
g_object_ref (G_OBJECT (pixmap));
437
g_object_ref (G_OBJECT (buffer_pixmap));
440
d->buffer_pixmap = buffer_pixmap;
441
d->cr = gdk_cairo_create (pixmap);
443
format = get_format_for_drawable (d, GDK_DRAWABLE (d->buffer_pixmap));
444
d->picture = XRenderCreatePicture (xdisplay, GDK_PIXMAP_XID (buffer_pixmap),
452
queue_decor_draw (d);