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>
21
* 2D Mode: Copyright © 2009 Sam Spilsbury <smspillaz@gmail.com>
22
* Frames Management: Copright © 2010 Canonical Ltd.
23
* Authored By: Sam Spilsbury <sam.spilsbury@canonical.com>
26
#include "gtk-window-decorator.h"
28
gboolean minimal = FALSE;
30
#define SWITCHER_SPACE 40
32
guint cmdline_options = 0;
34
GdkPixmap *decor_normal_pixmap = NULL;
35
GdkPixmap *decor_active_pixmap = NULL;
37
Atom frame_input_window_atom;
38
Atom frame_output_window_atom;
40
Atom win_blur_decor_atom;
41
Atom wm_move_resize_atom;
42
Atom restack_window_atom;
43
Atom select_window_atom;
45
Atom switcher_fg_atom;
46
Atom compiz_shadow_info_atom;
47
Atom compiz_shadow_color_atom;
48
Atom toolkit_action_atom;
49
Atom toolkit_action_window_menu_atom;
50
Atom toolkit_action_force_quit_dialog_atom;
54
struct _cursor cursor[3][3] = {
55
{ C (top_left_corner), C (top_side), C (top_right_corner) },
56
{ C (left_side), C (left_ptr), C (right_side) },
57
{ C (bottom_left_corner), C (bottom_side), C (bottom_right_corner) }
60
struct _pos pos[3][3] = {
62
{ 0, 0, 10, 21, 0, 0, 0, 0, 0, 1 },
63
{ 10, 0, -8, 6, 0, 0, 1, 0, 0, 1 },
64
{ 2, 0, 10, 21, 1, 0, 0, 0, 0, 1 }
66
{ 0, 10, 6, 11, 0, 0, 0, 1, 1, 0 },
67
{ 6, 6, 0, 15, 0, 0, 1, 0, 0, 1 },
68
{ 6, 10, 6, 11, 1, 0, 0, 1, 1, 0 }
70
{ 0, 17, 10, 10, 0, 1, 0, 0, 1, 0 },
71
{ 10, 21, -8, 6, 0, 1, 1, 0, 1, 0 },
72
{ 2, 17, 10, 10, 1, 1, 0, 0, 1, 0 }
75
{ 0, 6, 16, 16, 1, 0, 0, 0, 0, 0 },
76
{ 0, 6, 16, 16, 1, 0, 0, 0, 0, 0 },
77
{ 0, 6, 16, 16, 1, 0, 0, 0, 0, 0 },
78
{ 6, 2, 16, 16, 0, 0, 0, 0, 0, 0 }
81
const gchar * window_type_frames[WINDOW_TYPE_FRAMES_NUM] = {
82
"normal", "dialog", "menu", "utility"
87
GtkWidget *switcher_label;
89
GHashTable *frame_table;
90
GtkWidget *action_menu = NULL;
91
gboolean action_menu_mapped = FALSE;
92
decor_color_t _title_color[2];
93
gint double_click_timeout = 250;
95
GtkWidget *tip_window;
97
GTimeVal tooltip_last_popdown = { 0, 0 };
98
gint tooltip_timer_tag = 0;
100
GSList *draw_list = NULL;
101
guint draw_idle_id = 0;
103
Window switcher_selected_window = None;
104
decor_t *switcher_window = NULL;
106
XRenderPictFormat *xformat_rgba;
107
XRenderPictFormat *xformat_rgb;
109
decor_settings_t *settings;
112
main (int argc, char *argv[])
114
GdkDisplay *gdkdisplay;
116
GdkScreen *gdkscreen;
119
gboolean replace = FALSE;
120
unsigned int nchildren;
121
Window root_ret, parent_ret;
122
Window *children = NULL;
123
GList *windows, *win;
124
decor_frame_t *default_p, *bare_p, *switcher_p;
127
char *meta_theme = NULL;
128
MetaTheme *theme = NULL;
131
program_name = argv[0];
133
settings = malloc (sizeof (decor_settings_t));
138
gtk_init (&argc, &argv);
140
bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
141
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
142
textdomain (GETTEXT_PACKAGE);
144
settings->blur_type = BLUR_TYPE_NONE;
145
settings->use_system_font = FALSE;
147
settings->shadow_radius = SHADOW_RADIUS;
148
settings->shadow_opacity = SHADOW_OPACITY;
149
settings->shadow_color[0] = SHADOW_COLOR_RED;
150
settings->shadow_color[1] = SHADOW_COLOR_GREEN;
151
settings->shadow_color[2] = SHADOW_COLOR_BLUE;
152
settings->shadow_offset_x = SHADOW_OFFSET_X;
153
settings->shadow_offset_y = SHADOW_OFFSET_Y;
154
settings->decoration_alpha = 0.5;
158
settings->meta_opacity = META_OPACITY;
159
settings->meta_shade_opacity = META_SHADE_OPACITY;
160
settings->meta_active_opacity = META_ACTIVE_OPACITY;
161
settings->meta_active_shade_opacity = META_ACTIVE_SHADE_OPACITY;
163
settings->meta_button_layout_set = FALSE;
166
settings->font = strdup ("Sans Bold 12");
168
for (i = 0; i < argc; i++)
170
if (strcmp (argv[i], "--minimal") == 0)
174
else if (strcmp (argv[i], "--replace") == 0)
178
else if (strcmp (argv[i], "--blur") == 0)
182
if (strcmp (argv[i], "titlebar") == 0)
183
settings->blur_type = BLUR_TYPE_TITLEBAR;
184
else if (strcmp (argv[i], "all") == 0)
185
settings->blur_type = BLUR_TYPE_ALL;
187
cmdline_options |= CMDLINE_BLUR;
191
else if (strcmp (argv[i], "--opacity") == 0)
194
settings->meta_opacity = atof (argv[i]);
195
cmdline_options |= CMDLINE_OPACITY;
197
else if (strcmp (argv[i], "--no-opacity-shade") == 0)
199
settings->meta_shade_opacity = FALSE;
200
cmdline_options |= CMDLINE_OPACITY_SHADE;
202
else if (strcmp (argv[i], "--active-opacity") == 0)
205
settings->meta_active_opacity = atof (argv[i]);
206
cmdline_options |= CMDLINE_ACTIVE_OPACITY;
208
else if (strcmp (argv[i], "--no-active-opacity-shade") == 0)
210
settings->meta_active_shade_opacity = FALSE;
211
cmdline_options |= CMDLINE_ACTIVE_OPACITY_SHADE;
213
else if (strcmp (argv[i], "--metacity-theme") == 0)
216
meta_theme = argv[i];
217
cmdline_options |= CMDLINE_THEME;
221
else if (strcmp (argv[i], "--help") == 0)
223
fprintf (stderr, "%s "
226
"[--blur none|titlebar|all] "
229
"[--opacity OPACITY] "
230
"[--no-opacity-shade] "
231
"[--active-opacity OPACITY] "
232
"[--no-active-opacity-shade] "
233
"[--metacity-theme THEME] "
243
gdkdisplay = gdk_display_get_default ();
244
xdisplay = gdk_x11_display_get_xdisplay (gdkdisplay);
245
gdkscreen = gdk_display_get_default_screen (gdkdisplay);
247
frame_input_window_atom = XInternAtom (xdisplay,
248
DECOR_INPUT_FRAME_ATOM_NAME, FALSE);
249
frame_output_window_atom = XInternAtom (xdisplay,
250
DECOR_OUTPUT_FRAME_ATOM_NAME, FALSE);
252
win_decor_atom = XInternAtom (xdisplay, DECOR_WINDOW_ATOM_NAME, FALSE);
253
win_blur_decor_atom = XInternAtom (xdisplay, DECOR_BLUR_ATOM_NAME, FALSE);
254
wm_move_resize_atom = XInternAtom (xdisplay, "_NET_WM_MOVERESIZE", FALSE);
255
restack_window_atom = XInternAtom (xdisplay, "_NET_RESTACK_WINDOW", FALSE);
256
select_window_atom = XInternAtom (xdisplay, DECOR_SWITCH_WINDOW_ATOM_NAME,
258
mwm_hints_atom = XInternAtom (xdisplay, "_MOTIF_WM_HINTS", FALSE);
259
switcher_fg_atom = XInternAtom (xdisplay,
260
DECOR_SWITCH_FOREGROUND_COLOR_ATOM_NAME,
263
compiz_shadow_info_atom = XInternAtom (xdisplay, "_COMPIZ_NET_CM_SHADOW_PROPERTIES", FALSE);
264
compiz_shadow_color_atom = XInternAtom (xdisplay, "_COMPIZ_NET_CM_SHADOW_COLOR", FALSE);
266
toolkit_action_atom =
267
XInternAtom (xdisplay, "_COMPIZ_TOOLKIT_ACTION", FALSE);
268
toolkit_action_window_menu_atom =
269
XInternAtom (xdisplay, "_COMPIZ_TOOLKIT_ACTION_WINDOW_MENU", FALSE);
270
toolkit_action_force_quit_dialog_atom =
271
XInternAtom (xdisplay, "_COMPIZ_TOOLKIT_ACTION_FORCE_QUIT_DIALOG",
274
status = decor_acquire_dm_session (xdisplay,
275
gdk_screen_get_number (gdkscreen),
276
"gwd", replace, &dm_sn_timestamp);
277
if (status != DECOR_ACQUIRE_STATUS_SUCCESS)
279
if (status == DECOR_ACQUIRE_STATUS_FAILED)
282
"%s: Could not acquire decoration manager "
283
"selection on screen %d display \"%s\"\n",
284
program_name, gdk_screen_get_number (gdkscreen),
285
DisplayString (xdisplay));
287
else if (status == DECOR_ACQUIRE_STATUS_OTHER_DM_RUNNING)
290
"%s: Screen %d on display \"%s\" already "
291
"has a decoration manager; try using the "
292
"--replace option to replace the current "
293
"decoration manager.\n",
294
program_name, gdk_screen_get_number (gdkscreen),
295
DisplayString (xdisplay));
301
screen = wnck_screen_get_default ();
303
initialize_decorations ();
305
if (!init_settings (screen))
308
fprintf (stderr, "%s: Failed to get necessary gtk settings\n", argv[0]);
312
theme_draw_window_decoration = draw_window_decoration;
313
theme_calc_decoration_size = calc_decoration_size;
314
theme_update_border_extents = update_border_extents;
315
theme_get_event_window_position = get_event_window_position;
316
theme_get_button_position = get_button_position;
317
theme_get_title_scale = get_title_scale;
322
meta_theme_set_current (meta_theme, TRUE);
324
theme = meta_theme_get_current ();
327
g_warning ("specified a theme that does not exist! falling back to cairo decoration\n");
330
theme = meta_theme_get_current ();
334
theme_draw_window_decoration = meta_draw_window_decoration;
335
theme_calc_decoration_size = meta_calc_decoration_size;
336
theme_update_border_extents = meta_update_border_extents;
337
theme_get_event_window_position = meta_get_event_window_position;
338
theme_get_button_position = meta_get_button_position;
339
theme_get_title_scale = meta_get_title_scale;
343
for (i = 0; i < 3; i++)
345
for (j = 0; j < 3; j++)
347
if (cursor[i][j].shape != XC_left_ptr)
348
cursor[i][j].cursor =
349
XCreateFontCursor (xdisplay, cursor[i][j].shape);
353
xformat_rgba = XRenderFindStandardFormat (xdisplay, PictStandardARGB32);
354
xformat_rgb = XRenderFindStandardFormat (xdisplay, PictStandardRGB24);
356
frame_table = g_hash_table_new (NULL, NULL);
358
if (!create_tooltip_window ())
361
fprintf (stderr, "%s, Couldn't create tooltip window\n", argv[0]);
365
wnck_set_client_type (WNCK_CLIENT_TYPE_PAGER);
367
gdk_window_add_filter (NULL,
368
selection_event_filter_func,
373
GdkWindow *root = create_foreign_window (gdk_x11_get_default_root_xwindow ());
375
gdk_window_add_filter (NULL,
379
XQueryTree (xdisplay, gdk_x11_get_default_root_xwindow (),
380
&root_ret, &parent_ret, &children, &nchildren);
382
for (i = 0; i < nchildren; i++)
384
GdkWindow *toplevel = create_foreign_window (children[i]);
386
/* Need property notify on all windows */
388
gdk_window_set_events (toplevel,
389
gdk_window_get_events (toplevel) |
390
GDK_PROPERTY_CHANGE_MASK);
393
/* Need MapNotify on new windows */
394
gdk_window_set_events (root, gdk_window_get_events (root) |
396
GDK_PROPERTY_CHANGE_MASK |
397
GDK_VISIBILITY_NOTIFY_MASK |
398
GDK_SUBSTRUCTURE_MASK);
400
connect_screen (screen);
403
/* Keep the default, bare and switcher decorations around
404
* since otherwise they will be spuriously recreated */
406
default_p = gwd_get_decor_frame ("default");
407
bare_p = gwd_get_decor_frame ("bare");
408
switcher_p = gwd_get_decor_frame ("switcher");
410
decor_set_dm_check_hint (xdisplay, gdk_screen_get_number (gdkscreen),
411
WINDOW_DECORATION_TYPE_PIXMAP |
412
WINDOW_DECORATION_TYPE_WINDOW);
414
update_default_decorations (gdkscreen);
418
win = windows = wnck_screen_get_windows (screen);
422
WnckWindow *w = (WnckWindow *) win->data;
424
window_closed (screen, w);
426
win = g_list_next (win);
429
g_list_free (windows);
432
gtk_widget_destroy (GTK_WIDGET (tip_label));
435
gtk_widget_destroy (GTK_WIDGET (tip_window));
437
gwd_decor_frame_unref (default_p);
438
gwd_decor_frame_unref (bare_p);
439
gwd_decor_frame_unref (switcher_p);
441
g_free (settings->font);