2
* Copyright © 2006 Novell, Inc.
4
* This library is free software; you can redistribute it and/or
5
* modify it under the terms of the GNU Lesser General Public
6
* License as published by the Free Software Foundation; either
7
* version 2 of the License, or (at your option) any later version.
9
* This library is distributed in the hope that it will be useful,
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
* Lesser General Public License for more details.
14
* You should have received a copy of the GNU Lesser General Public
15
* License along with this library; if not, write to the
16
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17
* Boston, MA 02111-1307, USA.
19
* Author: David Reveman <davidr@novell.com>
22
#include "gtk-window-decorator.h"
24
gboolean minimal = FALSE;
26
double decoration_alpha = 0.5;
28
#define SWITCHER_SPACE 40
30
decor_extents_t _shadow_extents = { 0, 0, 0, 0 };
31
decor_extents_t _win_extents = { 6, 6, 6, 6 };
32
decor_extents_t _max_win_extents = { 6, 6, 4, 6 };
33
decor_extents_t _default_win_extents = { 6, 6, 6, 6 };
34
decor_extents_t _switcher_extents = { 6, 6, 6, 6 + SWITCHER_SPACE };
36
int titlebar_height = 17;
37
int max_titlebar_height = 17;
39
decor_context_t window_active_context = {
45
decor_context_t max_window_active_context = {
51
decor_context_t window_inactive_context = {
57
decor_context_t max_window_inactive_context = {
63
decor_context_t window_context_no_shadow = {
69
decor_context_t max_window_context_no_shadow = {
75
decor_context_t switcher_context = {
77
6, 6, 6, 6 + SWITCHER_SPACE,
81
decor_context_t shadow_context = {
87
gdouble shadow_radius = SHADOW_RADIUS;
88
gdouble shadow_opacity = SHADOW_OPACITY;
89
gushort shadow_color[3] = {
94
gint shadow_offset_x = SHADOW_OFFSET_X;
95
gint shadow_offset_y = SHADOW_OFFSET_Y;
97
guint cmdline_options = 0;
99
decor_shadow_t *no_border_shadow = NULL;
100
decor_shadow_t *border_active_shadow = NULL;
101
decor_shadow_t *border_inactive_shadow = NULL;
102
decor_shadow_t *max_border_active_shadow = NULL;
103
decor_shadow_t *max_border_inactive_shadow = NULL;
104
decor_shadow_t *border_no_shadow = NULL;
105
decor_shadow_t *max_border_no_shadow = NULL;
106
decor_shadow_t *switcher_shadow = NULL;
108
GdkPixmap *decor_normal_pixmap = NULL;
109
GdkPixmap *decor_active_pixmap = NULL;
111
Atom frame_input_window_atom;
112
Atom frame_output_window_atom;
114
Atom win_blur_decor_atom;
115
Atom wm_move_resize_atom;
116
Atom restack_window_atom;
117
Atom select_window_atom;
119
Atom switcher_fg_atom;
121
Atom compiz_shadow_info_atom;
122
Atom compiz_shadow_color_atom;
124
Atom toolkit_action_atom;
125
Atom toolkit_action_window_menu_atom;
126
Atom toolkit_action_force_quit_dialog_atom;
128
Time dm_sn_timestamp;
130
struct _cursor cursor[3][3] = {
131
{ C (top_left_corner), C (top_side), C (top_right_corner) },
132
{ C (left_side), C (left_ptr), C (right_side) },
133
{ C (bottom_left_corner), C (bottom_side), C (bottom_right_corner) }
136
struct _pos pos[3][3] = {
138
{ 0, 0, 10, 21, 0, 0, 0, 0, 0, 1 },
139
{ 10, 0, -8, 6, 0, 0, 1, 0, 0, 1 },
140
{ 2, 0, 10, 21, 1, 0, 0, 0, 0, 1 }
142
{ 0, 10, 6, 11, 0, 0, 0, 1, 1, 0 },
143
{ 6, 6, 0, 15, 0, 0, 1, 0, 0, 1 },
144
{ 6, 10, 6, 11, 1, 0, 0, 1, 1, 0 }
146
{ 0, 17, 10, 10, 0, 1, 0, 0, 1, 0 },
147
{ 10, 21, -8, 6, 0, 1, 1, 0, 1, 0 },
148
{ 2, 17, 10, 10, 1, 1, 0, 0, 1, 0 }
151
{ 0, 6, 16, 16, 1, 0, 0, 0, 0, 0 },
152
{ 0, 6, 16, 16, 1, 0, 0, 0, 0, 0 },
153
{ 0, 6, 16, 16, 1, 0, 0, 0, 0, 0 },
154
{ 6, 2, 16, 16, 0, 0, 0, 0, 0, 0 }
159
GtkWidget *style_window_rgba;
160
GtkWidget *style_window_rgb;
161
GtkWidget *switcher_label;
163
GHashTable *frame_table;
164
GtkWidget *action_menu = NULL;
165
gboolean action_menu_mapped = FALSE;
166
decor_color_t _title_color[2];
167
PangoContext *pango_context;
168
gint double_click_timeout = 250;
170
GSList *draw_list = NULL;
171
guint draw_idle_id = 0;
173
PangoFontDescription *titlebar_font = NULL;
174
gboolean use_system_font = FALSE;
177
gint blur_type = BLUR_TYPE_NONE;
179
GdkPixmap *switcher_pixmap = NULL;
180
GdkPixmap *switcher_buffer_pixmap = NULL;
182
gint switcher_height;
183
Window switcher_selected_window = None;
184
decor_t *switcher_window = NULL;
186
XRenderPictFormat *xformat_rgba;
187
XRenderPictFormat *xformat_rgb;
190
main (int argc, char *argv[])
192
GdkDisplay *gdkdisplay;
194
GdkScreen *gdkscreen;
197
unsigned int nchildren;
198
Window root_ret, parent_ret;
199
Window *children = NULL;
200
gboolean replace = FALSE;
203
char *meta_theme = NULL;
206
program_name = argv[0];
208
gtk_init (&argc, &argv);
210
bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
211
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
212
textdomain (GETTEXT_PACKAGE);
214
for (i = 0; i < argc; i++)
216
if (strcmp (argv[i], "--minimal") == 0)
220
else if (strcmp (argv[i], "--replace") == 0)
224
else if (strcmp (argv[i], "--blur") == 0)
228
if (strcmp (argv[i], "titlebar") == 0)
229
blur_type = BLUR_TYPE_TITLEBAR;
230
else if (strcmp (argv[i], "all") == 0)
231
blur_type = BLUR_TYPE_ALL;
233
cmdline_options |= CMDLINE_BLUR;
237
else if (strcmp (argv[i], "--opacity") == 0)
240
meta_opacity = atof (argv[i]);
241
cmdline_options |= CMDLINE_OPACITY;
243
else if (strcmp (argv[i], "--no-opacity-shade") == 0)
245
meta_shade_opacity = FALSE;
246
cmdline_options |= CMDLINE_OPACITY_SHADE;
248
else if (strcmp (argv[i], "--active-opacity") == 0)
251
meta_active_opacity = atof (argv[i]);
252
cmdline_options |= CMDLINE_ACTIVE_OPACITY;
254
else if (strcmp (argv[i], "--no-active-opacity-shade") == 0)
256
meta_active_shade_opacity = FALSE;
257
cmdline_options |= CMDLINE_ACTIVE_OPACITY_SHADE;
259
else if (strcmp (argv[i], "--metacity-theme") == 0)
262
meta_theme = argv[i];
263
cmdline_options |= CMDLINE_THEME;
267
else if (strcmp (argv[i], "--help") == 0)
269
fprintf (stderr, "%s "
272
"[--blur none|titlebar|all] "
275
"[--opacity OPACITY] "
276
"[--no-opacity-shade] "
277
"[--active-opacity OPACITY] "
278
"[--no-active-opacity-shade] "
279
"[--metacity-theme THEME] "
289
theme_draw_window_decoration = draw_window_decoration;
290
theme_calc_decoration_size = calc_decoration_size;
291
theme_update_border_extents = update_border_extents;
292
theme_get_event_window_position = get_event_window_position;
293
theme_get_button_position = get_button_position;
294
theme_update_shadow = cairo_update_shadow;
295
theme_get_shadow = get_shadow;
296
theme_get_border_extents = get_border_extents;
301
meta_theme_set_current (meta_theme, TRUE);
302
if (meta_theme_get_current ())
304
theme_draw_window_decoration = meta_draw_window_decoration;
305
theme_calc_decoration_size = meta_calc_decoration_size;
306
theme_update_border_extents = meta_update_border_extents;
307
theme_get_event_window_position = meta_get_event_window_position;
308
theme_get_button_position = meta_get_button_position;
309
theme_update_shadow = meta_update_shadow;
310
theme_get_shadow = meta_get_shadow;
311
theme_get_border_extents = meta_get_border_extents;
316
gdkdisplay = gdk_display_get_default ();
317
xdisplay = gdk_x11_display_get_xdisplay (gdkdisplay);
318
gdkscreen = gdk_display_get_default_screen (gdkdisplay);
320
frame_input_window_atom = XInternAtom (xdisplay,
321
DECOR_INPUT_FRAME_ATOM_NAME, FALSE);
322
frame_output_window_atom = XInternAtom (xdisplay,
323
DECOR_OUTPUT_FRAME_ATOM_NAME, FALSE);
325
win_decor_atom = XInternAtom (xdisplay, DECOR_WINDOW_ATOM_NAME, FALSE);
326
win_blur_decor_atom = XInternAtom (xdisplay, DECOR_BLUR_ATOM_NAME, FALSE);
327
wm_move_resize_atom = XInternAtom (xdisplay, "_NET_WM_MOVERESIZE", FALSE);
328
restack_window_atom = XInternAtom (xdisplay, "_NET_RESTACK_WINDOW", FALSE);
329
select_window_atom = XInternAtom (xdisplay, DECOR_SWITCH_WINDOW_ATOM_NAME,
331
mwm_hints_atom = XInternAtom (xdisplay, "_MOTIF_WM_HINTS", FALSE);
332
switcher_fg_atom = XInternAtom (xdisplay,
333
DECOR_SWITCH_FOREGROUND_COLOR_ATOM_NAME,
336
compiz_shadow_info_atom = XInternAtom (xdisplay, "_COMPIZ_NET_CM_SHADOW_PROPERTIES", FALSE);
337
compiz_shadow_color_atom = XInternAtom (xdisplay, "_COMPIZ_NET_CM_SHADOW_COLOR", FALSE);
339
toolkit_action_atom =
340
XInternAtom (xdisplay, "_COMPIZ_TOOLKIT_ACTION", FALSE);
341
toolkit_action_window_menu_atom =
342
XInternAtom (xdisplay, "_COMPIZ_TOOLKIT_ACTION_WINDOW_MENU", FALSE);
343
toolkit_action_force_quit_dialog_atom =
344
XInternAtom (xdisplay, "_COMPIZ_TOOLKIT_ACTION_FORCE_QUIT_DIALOG",
347
status = decor_acquire_dm_session (xdisplay,
348
gdk_screen_get_number (gdkscreen),
349
"gwd", replace, &dm_sn_timestamp);
350
if (status != DECOR_ACQUIRE_STATUS_SUCCESS)
352
if (status == DECOR_ACQUIRE_STATUS_FAILED)
355
"%s: Could not acquire decoration manager "
356
"selection on screen %d display \"%s\"\n",
357
program_name, gdk_screen_get_number (gdkscreen),
358
DisplayString (xdisplay));
360
else if (status == DECOR_ACQUIRE_STATUS_OTHER_DM_RUNNING)
363
"%s: Screen %d on display \"%s\" already "
364
"has a decoration manager; try using the "
365
"--replace option to replace the current "
366
"decoration manager.\n",
367
program_name, gdk_screen_get_number (gdkscreen),
368
DisplayString (xdisplay));
374
for (i = 0; i < 3; i++)
376
for (j = 0; j < 3; j++)
378
if (cursor[i][j].shape != XC_left_ptr)
379
cursor[i][j].cursor =
380
XCreateFontCursor (xdisplay, cursor[i][j].shape);
384
xformat_rgba = XRenderFindStandardFormat (xdisplay, PictStandardARGB32);
385
xformat_rgb = XRenderFindStandardFormat (xdisplay, PictStandardRGB24);
387
frame_table = g_hash_table_new (NULL, NULL);
389
screen = wnck_screen_get_default ();
390
wnck_set_client_type (WNCK_CLIENT_TYPE_PAGER);
392
gdk_window_add_filter (NULL,
393
selection_event_filter_func,
398
GdkWindow *root = create_foreign_window (gdk_x11_get_default_root_xwindow ());
400
gdk_window_add_filter (NULL,
404
XQueryTree (xdisplay, gdk_x11_get_default_root_xwindow (),
405
&root_ret, &parent_ret, &children, &nchildren);
407
for (i = 0; i < nchildren; i++)
409
GdkWindow *toplevel = create_foreign_window (children[i]);
411
/* Need property notify on all windows */
413
gdk_window_set_events (toplevel,
414
gdk_window_get_events (toplevel) |
415
GDK_PROPERTY_CHANGE_MASK);
418
/* Need MapNotify on new windows */
419
gdk_window_set_events (root, gdk_window_get_events (root) |
421
GDK_PROPERTY_CHANGE_MASK |
422
GDK_VISIBILITY_NOTIFY_MASK |
423
GDK_SUBSTRUCTURE_MASK);
425
connect_screen (screen);
428
if (!init_settings (screen))
430
fprintf (stderr, "%s: Failed to get necessary gtk settings\n", argv[0]);
434
decor_set_dm_check_hint (xdisplay, gdk_screen_get_number (gdkscreen),
435
WINDOW_DECORATION_TYPE_PIXMAP |
436
WINDOW_DECORATION_TYPE_WINDOW);
438
update_default_decorations (gdkscreen);