4
* This program is free software; you can redistribute it and/or modify
5
* it under the terms of the GNU General Public License as published by
6
* the Free Software Foundation; either version 2 of the License, or
7
* (at your option) any later version.
9
* This program 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
12
* GNU Library General Public License for more details.
14
* You should have received a copy of the GNU General Public License
15
* along with this program; if not, write to the Free Software
16
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
26
* Jochen Baier, 2004, 2005, 2006 (email@Jochen-Baier.de)
31
* steal-xwin.c (acano@systec.com)
32
* xswallow (Caolan McNamara ?)
33
* kdocker (Girish Ramakrishnan)
34
* libwnck (Havoc Pennington <hp@redhat.com>)
35
* eggtrayicon (Anders Carlsson <andersca@gnu.org>)
36
* dsimple.c ("The Open Group")
37
* xfwm4 (Olivier Fourdan <fourdan@xfce.org>)
38
* .....lot more, THANX !!!
46
#include "balloon_message.h"
49
#define SYSTEM_TRAY_REQUEST_DOCK 0
51
GtkWidget *menu = NULL;
54
GtkWidget *undock_item;
56
void tray_done (win_struct *win)
59
gdk_window_remove_filter (win->root_gdk, manager_filter, (gpointer) win);
60
gdk_window_remove_filter (win->manager_window_gdk, manager_filter, NULL);
63
gtk_widget_destroy (menu);
66
gtk_widget_destroy (win->plug);
70
void exit_call(GtkWidget * button, gpointer user_data)
73
win_struct *win= (win_struct*) user_data;
75
if (debug) printf ("exit_call\n");
77
destroy_all_and_exit (win, TRUE);
81
void undock_call(GtkWidget * button, gpointer user_data)
84
win_struct *win= (win_struct*) user_data;
86
if (debug) printf ("undock_call\n");
88
destroy_all_and_exit (win, FALSE);
92
void show_hide_call (GtkWidget * button, gpointer user_data)
95
win_struct *win= (win_struct*) user_data;
97
show_hide_window (win, force_disabled, FALSE);
100
void command_menu_call (GtkWidget * button, gpointer user_data)
103
gchar *command= (gchar*) user_data;
105
if (debug) printf ("command_menu_call: %s\n", command);
107
if (!strcmp (command, "xmmsnext"))
108
system ("xmms -f && xmms -p &");
110
exec_command (command);
114
void menu_init (win_struct *win)
117
menu = gtk_menu_new();
119
command_menu_struct command;
123
GtkWidget *title = gtk_menu_item_new_with_label(" AllTray");
124
gtk_menu_shell_append(GTK_MENU_SHELL(menu), title);
125
gtk_widget_set_sensitive(title, FALSE);
127
GtkWidget *separator1 = gtk_menu_item_new();
128
gtk_widget_show(separator1);
129
gtk_menu_shell_append(GTK_MENU_SHELL(menu), separator1);
132
if (debug) printf ("command_menu->len: %d\n", win->command_menu->len);
134
if (win->command_menu->len >0) {
136
for (i=0; i < win->command_menu->len; i++) {
138
command=g_array_index (win->command_menu, command_menu_struct, i);
140
if (debug) printf ("found command.entry: %s\n", command.entry);
142
GtkWidget *item = gtk_menu_item_new_with_label(command.entry);
143
g_signal_connect(G_OBJECT(item), "activate",
144
G_CALLBACK(command_menu_call), (gpointer) command.command);
145
gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
149
GtkWidget *separator2 = gtk_menu_item_new();
150
gtk_widget_show(separator2);
151
gtk_menu_shell_append(GTK_MENU_SHELL(menu), separator2);
152
gtk_widget_set_sensitive(separator2, FALSE);
156
show_item = gtk_menu_item_new_with_label("Show/Hide");
157
g_signal_connect(G_OBJECT(show_item), "activate",
158
G_CALLBACK(show_hide_call), (gpointer) win);
159
gtk_menu_shell_append(GTK_MENU_SHELL(menu), show_item);
161
GtkWidget *separator4 = gtk_menu_item_new();
162
gtk_widget_show(separator4);
163
gtk_menu_shell_append(GTK_MENU_SHELL(menu), separator4);
164
gtk_widget_set_sensitive(separator4, FALSE);
166
undock_item = gtk_menu_item_new_with_label("Undock");
167
g_signal_connect(G_OBJECT(undock_item), "activate",
168
G_CALLBACK(undock_call), (gpointer) win);
169
gtk_menu_shell_append(GTK_MENU_SHELL(menu), undock_item);
171
GtkWidget *separator3 = gtk_menu_item_new();
172
gtk_widget_show(separator3);
173
gtk_menu_shell_append(GTK_MENU_SHELL(menu), separator3);
174
gtk_widget_set_sensitive(separator3, FALSE);
176
exit_item = gtk_menu_item_new_with_label("Exit");
177
g_signal_connect(G_OBJECT(exit_item), "activate",
178
G_CALLBACK(exit_call), (gpointer) win);
179
gtk_menu_shell_append(GTK_MENU_SHELL(menu), exit_item);
182
gtk_widget_show_all(menu);
185
void update_tray_icon(win_struct *win)
191
XWindowAttributes wa;
192
gboolean resize=FALSE;
199
gdk_error_trap_push();
200
XGetWindowAttributes (GDK_DISPLAY(), win->plug_xlib, &wa);
201
if (gdk_error_trap_pop())
204
if (debug) printf ("update_tray_icon: real plug size: %dx%d\n", wa.width, wa.height);
206
if (wa.width <=1 || wa.height <= 1)
209
if ((wa.height > 24 && win->large_icons) || wa.height < 24 ) {
211
if (debug) printf ("resize = TRUE\n");
222
if (win->user_icon_path)
223
tmp=get_user_icon (win->user_icon_path, req_w, req_h);
228
tmp=get_xmms_icon (req_w, req_h);
230
tmp=get_window_icon (win->child_xlib, req_w, req_h);
234
g_object_unref(win->tray_icon);
238
if (GTK_IS_WIDGET (win->image_icon))
239
gtk_image_set_from_pixbuf(GTK_IMAGE(win->image_icon), win->tray_icon);
243
void dock_window(Window manager_window, Window window)
246
XClientMessageEvent ev;
248
ev.type = ClientMessage;
249
ev.window = manager_window;
250
ev.message_type =system_tray_opcode_atom;
252
ev.data.l[0] = CurrentTime;
253
ev.data.l[1] = SYSTEM_TRAY_REQUEST_DOCK;
254
ev.data.l[2] = window;
258
gdk_error_trap_push ();
259
XSendEvent (GDK_DISPLAY(), manager_window, False, NoEventMask, (XEvent *)&ev);
260
XSync (GDK_DISPLAY(), False);
261
gdk_error_trap_pop ();
265
Window get_manager_window (void)
268
Window manager_window=None;
270
gdk_error_trap_push();
272
XGrabServer (GDK_DISPLAY());
274
manager_window = XGetSelectionOwner (GDK_DISPLAY(), selection_atom);
276
XUngrabServer (GDK_DISPLAY());
277
XFlush (GDK_DISPLAY());
279
if (gdk_error_trap_pop())
282
// display_window_id(GDK_DISPLAY(), manager_window);
284
return manager_window;
288
manager_filter (GdkXEvent *xevent, GdkEvent *event, gpointer user_data)
291
XEvent *xev = (XEvent *)xevent;
292
XWindowAttributes wa;
294
win_struct *win= (win_struct *) user_data;
296
if (xev->xany.type == ClientMessage &&
297
xev->xclient.message_type == manager_atom &&
298
xev->xclient.data.l[1] == selection_atom)
302
if (debug) printf ("manager: here i am\n");
304
create_tray_and_dock(win);
307
else if (xev->xany.window == win->manager_window)
309
if (xev->xany.type == DestroyNotify)
312
if (debug) printf ("manger destroy notfiy\n");
315
gdk_error_trap_push ();
317
XGetWindowAttributes (GDK_DISPLAY(), win->manager_window, &wa);
319
if (gdk_error_trap_pop()) {
321
gdk_window_remove_filter (win->manager_window_gdk, manager_filter, NULL);
326
if (GTK_IS_WIDGET(win->plug))
327
gtk_widget_destroy (win->plug);
337
return GDK_FILTER_CONTINUE;
340
gboolean on_icon_window_press_event(GtkWidget *widget, GdkEventButton * event,
344
win_struct *win= (win_struct*) user_data;
346
if (debug) printf ("icon window press event\n");
350
destroy_balloon (win);
353
if (event->button == 1) {
355
show_hide_window (win, force_disabled, FALSE);
361
if (event->button == 3) {
363
gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, 0,
364
gtk_get_current_event_time());
370
gboolean icon_window_configure_event (GtkWidget *widget,
371
GdkEventConfigure * event, gpointer user_data)
374
win_struct *win = (win_struct*) user_data;
376
if (debug) printf ("icon_window_configure_event: %dx%d\n",
377
event->width, event->height);
379
if (event->width <= 1 || event->height <= 1)
382
update_tray_icon(win);
388
gboolean icon_window_enter_event(GtkWidget *widget, GdkEventButton * event,
392
win_struct *win= (win_struct*) user_data;
394
if (debug) printf ("icon window enter event\n");
396
win->balloon_message_allowed=TRUE;
398
show_balloon (win, win->title, 0);
404
void create_tray_and_dock (win_struct *win)
411
if (win->manager_window==None)
412
win->manager_window=get_manager_window();
414
if (win->manager_window==None)
417
/*too lazy to fix that now*/
418
if (!assert_window (win->manager_window)) {
420
printf ("Alltray: Can not dock!.\nPlease remove system tray applet\n"\
421
"and add it again.\n");
425
win->manager_window_gdk=NULL;
426
win->manager_window_gdk=gdk_window_foreign_new(win->manager_window);
428
gdk_window_set_events (win->manager_window_gdk, GDK_SUBSTRUCTURE_MASK);
429
gdk_window_add_filter (win->manager_window_gdk, manager_filter, (gpointer) win);
431
if (win->plug && GTK_IS_WIDGET (win->plug)) {
432
if (debug) printf ("plug is still alive\n");
433
gtk_widget_destroy(win->plug);
436
win->plug= gtk_plug_new (0);
437
gtk_container_set_border_width (GTK_CONTAINER (win->plug), 0);
438
win->image_icon=gtk_image_new ();
439
gtk_container_add (GTK_CONTAINER(win->plug), win->image_icon);
440
gtk_widget_show (win->image_icon);
441
gtk_widget_show (win->plug);
442
gtk_widget_realize (win->plug);
444
gtk_widget_set_double_buffered (win->plug, FALSE);
445
style = gtk_style_copy (win->plug->style);
446
style->bg_pixmap[GTK_STATE_NORMAL] = (GdkPixmap*) GDK_PARENT_RELATIVE;
447
gtk_widget_set_style (win->plug, style);
448
g_object_unref (style);
449
gtk_style_set_background (win->plug->style, win->plug->window, GTK_STATE_NORMAL);
451
win->plug_xlib=gtk_plug_get_id (GTK_PLUG(win->plug));
454
g_object_unref(win->tray_icon);
457
icon_width=24; icon_height=24;
459
if (win->user_icon_path)
460
win->tray_icon=get_user_icon (win->user_icon_path, icon_width, icon_height);
462
if (!win->tray_icon) {
465
win->tray_icon=get_xmms_icon (icon_width, icon_height);
467
win->tray_icon=get_window_icon (win->child_xlib, icon_width, icon_height);
470
gtk_image_set_from_pixbuf(GTK_IMAGE(win->image_icon), win->tray_icon);
472
gtk_widget_add_events (win->plug, GDK_BUTTON_PRESS_MASK);
474
g_signal_connect ((gpointer) win->plug, "button_press_event",
475
G_CALLBACK (on_icon_window_press_event),
479
g_signal_connect ((gpointer) win->plug, "configure_event",
480
G_CALLBACK (icon_window_configure_event),
484
g_signal_connect ((gpointer) win->plug, "enter_notify_event",
485
G_CALLBACK (icon_window_enter_event),
489
dock_window (win->manager_window, win->plug_xlib);
493
void tray_init (win_struct *win)
498
win->manager_window=get_manager_window();
500
if (win->manager_window) {
502
if (debug) printf ("have manager window.... now creat_tray.....\n");
503
create_tray_and_dock(win);
506
printf ("Alltray: no system tray/notification area found. I will wait..... I have time....\n");
509
gdk_window_add_filter (win->root_gdk, manager_filter, (gpointer) win);