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 !!!
50
void update_visibility_state (win_struct *win, gboolean new_state)
53
win->parent_is_visible=new_state;
57
static GdkFilterReturn
58
root_filter_manager_window (GdkXEvent *xevent,
59
GdkEvent *event, gpointer user_data)
62
XEvent *xev = (XEvent *)xevent;
64
//win_struct *win= (win_struct *) user_data;
66
if (debug) printf ("root_filter_manager_window event\n");
68
if (xev->xany.type == ClientMessage &&
69
xev->xclient.message_type == manager_atom &&
70
xev->xclient.data.l[1] == selection_atom) {
72
display_window_id (GDK_DISPLAY(), xev->xclient.window);
74
if (debug) printf ("manager: here i am\n");
80
return GDK_FILTER_CONTINUE;
83
void wait_for_manager(win_struct *win)
86
win->manager_window=get_manager_window();
88
if (win->manager_window == None) {
90
printf ("\nAlltray: no system tray/notification area found.\n"\
91
"I will wait..... I have time....\n\n"\
92
"In the meantime you may add a system tray applet\n"\
95
gdk_window_add_filter(win->root_gdk, root_filter_manager_window, (gpointer) win);
97
gdk_window_remove_filter(win->root_gdk, root_filter_manager_window, (gpointer) win);
100
else { if (debug) printf ("HAVE MANAGER WINDOW\n");};
103
GdkFilterReturn parent_window_filter (GdkXEvent *xevent,
104
GdkEvent *event, gpointer user_data)
106
XEvent *xev = (XEvent *)xevent;
107
XConfigureEvent *xconfigure;
108
XVisibilityEvent *xvisibilty;
109
XConfigureRequestEvent *xconfigurerequest;
111
gint return_type=GDK_FILTER_CONTINUE;
113
win_struct *win= (win_struct*) user_data;
115
switch (xev->xany.type) {
120
if (debug) printf ("map notify\n");
122
update_visibility_state (win, window_is_visible);
128
if (debug) printf ("unmap notify\n");
130
update_visibility_state (win, window_is_hidden);
135
case ConfigureNotify:
137
//if (debug) printf ("configure notify\n");
139
xconfigure = (XConfigureEvent*) xev;
141
static gint old_width=0;
142
static gint old_height=0;
144
if (old_width == xconfigure->width && old_height == xconfigure->height)
147
old_width=xconfigure->width;
148
old_height=xconfigure->height;
150
gdk_window_resize (win->child_gdk, old_width, old_height);
156
if (xev->xclient.data.l[0] == wm_delete_window) {
157
if (debug) printf ("delete event!\n");
159
show_hide_window (win, force_hide, FALSE);
163
if (xev->xclient.data.l[0] == wm_take_focus) {
164
if (debug) printf ("wm take focus !!!\n");
166
if (!assert_window(win->child_xlib)) {
167
if (debug) printf ("can not set focus to child ! assert(window) failed\n");
171
while (!xlib_window_is_viewable (win->child_xlib))
174
XSetInputFocus (win->display, win->child_xlib,
175
RevertToParent, xev->xclient.data.l[1]);
180
if (xev->xclient.data.l[0] == net_wm_ping) {
181
if (debug) printf ("net wm ping!\n");
185
xe.xclient.window = win->root_xlib;
186
XSendEvent (win->display, win->root_xlib, False,
187
SubstructureRedirectMask | SubstructureNotifyMask, &xe);
194
case VisibilityNotify:
196
xvisibilty = (XVisibilityEvent*) xev;
198
win->visibility=xvisibilty->state;
200
if (debug) printf ("visibility notify state: %d\n", win->visibility);
204
/*bad child wanted to move inside parent -> deny*/
205
case ConfigureRequest:
207
xconfigurerequest = (XConfigureRequestEvent*) xev;
209
if (debug) printf ("child configure request\n");
211
if (xconfigurerequest->x !=0 || xconfigurerequest->y != 0) {
213
if (debug) printf ("deny configure request\n");
214
return_type=GDK_FILTER_REMOVE;
225
gboolean parse_arguments(int argc, char **argv, gchar **icon,
226
gchar **rest, gboolean *show, gboolean *debug, gboolean *borderless, gboolean *sticky,
227
gboolean *skip_tasklist, gboolean *no_title, gboolean *configure, gboolean *large_icons,
228
GArray *command_menu, gint *title_time, gchar **geometry,
229
unsigned int *shortcut_key, unsigned int *shortcut_modifier, gboolean *notray, gboolean *nomini)
232
gchar *rest_buf=NULL;
234
gchar *shortcut=NULL;
244
for (i = 1; i < argc; i++) {
248
if (!strcmp(argv[i], "--help") || !strcmp(argv[i], "-h")) {
253
if (!strcmp(argv[i], "--version") || !strcmp(argv[i], "-v")) {
258
if (!strcmp(argv[i], "--show") || !strcmp(argv[i], "-s")) {
263
if (!strcmp(argv[i], "--borderless") || !strcmp(argv[i], "-x")) {
268
if (!strcmp(argv[i], "--notray") || !strcmp(argv[i], "-nt")) {
273
if (!strcmp(argv[i], "--nominimize") || !strcmp(argv[i], "-nm")) {
278
if (!strcmp(argv[i], "--sticky") || !strcmp(argv[i], "-st")) {
283
if (!strcmp(argv[i], "--skip-taskbar") || !strcmp(argv[i], "-stask")) {
288
if (!strcmp(argv[i], "--no-alltray") || !strcmp(argv[i], "-na")) {
293
if (!strcmp(argv[i], "--configure") || !strcmp(argv[i], "-conf")) {
298
if (!strcmp(argv[i], "--large_icons") || !strcmp(argv[i], "-l")) {
304
if (!strcmp(argv[i], "--icon") || !strcmp(argv[i], "-i")) {
310
*icon=g_strdup (argv[i+1]);
315
if (!strcmp(argv[i], "--key") || !strcmp(argv[i], "-k")) {
321
shortcut=g_strdup (argv[i+1]);
323
if (!parse_shortcut (shortcut, shortcut_key, shortcut_modifier))
332
if (!strcmp(argv[i], "--geometry") || !strcmp(argv[i], "-g")) {
338
*geometry=g_strdup (argv[i+1]);
340
if (XParseGeometry(*geometry, &x, &y, (unsigned int *) &w, (unsigned int *) &h) == 0) {
349
if (!strcmp(argv[i], "--title") || !strcmp(argv[i], "-t")) {
355
*title_time=atoi (argv[i+1]);
357
if (*title_time == 0) {
366
if (!strcmp(argv[i], "--menu") || !strcmp(argv[i], "-m")) {
372
if (!append_command_to_menu(command_menu, argv[i+1])) {
373
printf ("\nAllTray: \"%s\" is not a valid menu entry !\n"\
374
" Syntax: -m \"menu text:command\"\n", argv[i+1]);
382
if (!strcmp(argv[i], "--debug") || !strcmp(argv[i], "-d")) {
387
/*if (g_str_has_prefix (argv[i],"-")) {
388
printf ("\nAlltray: Unknown option '%s'\n\n", argv[i]);
392
if (rest_buf == NULL) {
393
rest_buf=g_strdup (argv[i]);
396
rest_buf=g_strconcat (rest_buf, " ", argv[i], NULL);
404
if (rest_buf && strlen (rest_buf) == 0 && !*configure) {
414
gboolean append_command_to_menu(GArray *command_menu, gchar *string)
417
command_menu_struct new;
425
tmp=g_strdup (string);
430
command = g_strrstr (tmp,":");
432
if (debug) printf ("command: %s\n", command);
439
new.command=g_strdup(++command);
441
if (strlen (new.command) == 0) {
443
g_free (new.command);
447
if (debug) printf ("new.command: %s\n", new.command);
451
if (strlen (tmp) == 0) {
453
g_free (new.command);
459
if (debug) printf ("new.entry: %s\n", new.entry);
461
g_array_append_val(command_menu, new);
466
gchar *strip_command (win_struct *win)
469
gchar *command_copy=NULL;
471
gchar *basename=NULL;
473
command_copy=g_strdup (win->command);
475
space=g_strstr_len (command_copy,
476
strlen (command_copy) , " ");
481
if (debug) printf ("command without args: %s\n", command_copy);
483
basename=g_path_get_basename (command_copy);
485
if (debug) printf ("basename: %s\n", basename);
487
g_free (command_copy);
495
printf ("\nAllTray Version %s\n\n" \
497
"Dock any program into the system tray.\n\n" \
499
"usage: alltray [options] [\"] <program_name> [program parameter] [\"]\n\n" \
500
" where options include:\n"\
501
" --help; -h: print this message\n"\
502
" --version; -v: print version\n"\
503
" --debug; -d: show debug messages\n"\
504
" --show; -s: do not hide window after start\n"\
505
" --icon; -i <path to png>: use this icon\n"\
506
" --large_icons; -l: allow large icons (> 24x24)\n"\
507
" --sticky; -st: visible on all workspaces\n"\
508
" --skip-taskbar; -stask: not visible in taskbar\n"\
509
" --no-alltray; -na: no \"(Alltray)\" in window title\n"\
510
" --borderless; -x: remove border, title, frame (if not supported native)\n"\
511
" --menu; -m: \"menu text:command\": add entry to popdown menu\n" \
512
" --title; -t <sec>: show tooltip with title for <sec> seconds after song change\n"\
513
" --geometry; -g [<width>x<height>][{+-}<x>{+-}<y>]: initial position (if not supported native)\n"\
514
" --key; -k [Modifier:]Key: Keyboard shortcut:\n"\
515
" Modifier=\"Shift\", \"Control\", \"Alt\", \"AltGr\"\n"\
516
" Key (Examples) = \"a\", \"F1\", \"End\" ...\n"\
517
" or \"Keycode\" (Number) returned by the program \"xev\"\n"\
518
" --notray; -nt: display no tray icon (usefull only with the \"--key\" option)\n"\
519
" --nominimize; -nm: click on window close button: do not minimize back to system tray, close\n"\
520
" --configure; -conf: show KDE configuration dialog\n\n"\
521
"usage: alltray\n\n"\
522
" Click-Mode: Click on the window you would like to dock.\n\n"\
528
void show_version (void)
530
printf ("\nAlltray version %s\n\n", VERSION);