~ubuntu-branches/ubuntu/wily/alltray/wily

« back to all changes in this revision

Viewing changes to src/parent.c

  • Committer: Bazaar Package Importer
  • Author(s): Raphael Hertzog
  • Date: 2007-01-14 18:36:56 UTC
  • Revision ID: james.westby@ubuntu.com-20070114183656-tutd3t7x0kifep7a
Tags: upstream-0.69
ImportĀ upstreamĀ versionĀ 0.69

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * GPL Notice:
 
3
 *
 
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.
 
8
 *
 
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.
 
13
 *
 
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.
 
17
 *
 
18
 *
 
19
 * Name:
 
20
 *
 
21
 *    alltray
 
22
 *
 
23
 *
 
24
 * Copyright:
 
25
 * 
 
26
 *    Jochen Baier, 2004, 2005, 2006 (email@Jochen-Baier.de)
 
27
 *
 
28
 *
 
29
 * Based on code from:
 
30
 *
 
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 !!!
 
39
 *    
 
40
*/
 
41
 
 
42
 
 
43
#include "config.h"
 
44
#include "common.h"
 
45
#include "parent.h"
 
46
#include "utils.h"
 
47
#include "trayicon.h"
 
48
#include "shortcut.h"
 
49
 
 
50
void update_visibility_state (win_struct *win, gboolean new_state)
 
51
{
 
52
 
 
53
  win->parent_is_visible=new_state;
 
54
    
 
55
}
 
56
 
 
57
static GdkFilterReturn
 
58
root_filter_manager_window (GdkXEvent *xevent, 
 
59
  GdkEvent *event, gpointer user_data)
 
60
{
 
61
  
 
62
  XEvent *xev = (XEvent *)xevent;
 
63
  
 
64
  //win_struct *win= (win_struct *) user_data;
 
65
  
 
66
  if (debug) printf ("root_filter_manager_window event\n");
 
67
  
 
68
  if (xev->xany.type == ClientMessage &&
 
69
    xev->xclient.message_type == manager_atom &&
 
70
    xev->xclient.data.l[1] == selection_atom) {
 
71
  
 
72
    display_window_id (GDK_DISPLAY(), xev->xclient.window);
 
73
  
 
74
    if (debug) printf ("manager: here i am\n");
 
75
  
 
76
    gtk_main_quit ();
 
77
 
 
78
  }
 
79
  
 
80
  return GDK_FILTER_CONTINUE;
 
81
}
 
82
 
 
83
void wait_for_manager(win_struct *win)
 
84
{
 
85
 
 
86
  win->manager_window=get_manager_window();
 
87
 
 
88
  if (win->manager_window == None) {
 
89
   
 
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"\
 
93
             "to the panel.\n");
 
94
               
 
95
     gdk_window_add_filter(win->root_gdk, root_filter_manager_window, (gpointer) win);
 
96
     gtk_main ();
 
97
     gdk_window_remove_filter(win->root_gdk, root_filter_manager_window, (gpointer) win);
 
98
   }
 
99
 
 
100
  else { if (debug) printf ("HAVE MANAGER WINDOW\n");};
 
101
}
 
102
 
 
103
GdkFilterReturn parent_window_filter (GdkXEvent *xevent, 
 
104
  GdkEvent *event, gpointer user_data)
 
105
{
 
106
  XEvent *xev = (XEvent *)xevent;
 
107
  XConfigureEvent *xconfigure;
 
108
  XVisibilityEvent *xvisibilty;
 
109
  XConfigureRequestEvent *xconfigurerequest;
 
110
  
 
111
  gint return_type=GDK_FILTER_CONTINUE;
 
112
    
 
113
  win_struct *win= (win_struct*) user_data;
 
114
 
 
115
  switch (xev->xany.type) {
 
116
    
 
117
    
 
118
    case MapNotify:
 
119
      
 
120
     if (debug) printf ("map notify\n");
 
121
    
 
122
     update_visibility_state (win, window_is_visible);
 
123
    
 
124
    break;
 
125
    
 
126
    case UnmapNotify:
 
127
      
 
128
     if (debug) printf ("unmap notify\n");
 
129
    
 
130
     update_visibility_state (win, window_is_hidden);
 
131
       
 
132
    
 
133
    break;
 
134
     
 
135
    case ConfigureNotify:
 
136
    
 
137
      //if (debug) printf ("configure notify\n");  
 
138
      
 
139
      xconfigure = (XConfigureEvent*) xev;
 
140
      
 
141
      static gint old_width=0;
 
142
      static gint old_height=0;
 
143
      
 
144
      if (old_width == xconfigure->width && old_height == xconfigure->height)
 
145
        break;
 
146
 
 
147
      old_width=xconfigure->width;
 
148
      old_height=xconfigure->height;
 
149
      
 
150
      gdk_window_resize (win->child_gdk, old_width, old_height);
 
151
 
 
152
    break;
 
153
      
 
154
    case ClientMessage:
 
155
 
 
156
      if (xev->xclient.data.l[0] == wm_delete_window) {
 
157
        if (debug) printf ("delete event!\n");
 
158
        
 
159
        show_hide_window (win, force_hide, FALSE);
 
160
        break;
 
161
      }
 
162
      
 
163
      if (xev->xclient.data.l[0] == wm_take_focus) {
 
164
        if (debug) printf ("wm take focus !!!\n");
 
165
          
 
166
        if (!assert_window(win->child_xlib)) {
 
167
          if (debug) printf ("can not set focus to child ! assert(window) failed\n");
 
168
          break;
 
169
        }
 
170
        
 
171
        while (!xlib_window_is_viewable (win->child_xlib))
 
172
          gtk_sleep (10);
 
173
                
 
174
        XSetInputFocus (win->display, win->child_xlib, 
 
175
          RevertToParent, xev->xclient.data.l[1]);
 
176
        
 
177
        break;
 
178
      }   
 
179
      
 
180
      if (xev->xclient.data.l[0] == net_wm_ping) {
 
181
        if (debug) printf ("net wm ping!\n");
 
182
        
 
183
        XEvent xe = *xev;
 
184
        
 
185
        xe.xclient.window = win->root_xlib;
 
186
        XSendEvent (win->display, win->root_xlib, False, 
 
187
          SubstructureRedirectMask | SubstructureNotifyMask, &xe);
 
188
        
 
189
        break;
 
190
      }   
 
191
     
 
192
      break;
 
193
     
 
194
      case VisibilityNotify:
 
195
        
 
196
        xvisibilty = (XVisibilityEvent*) xev;
 
197
      
 
198
        win->visibility=xvisibilty->state;
 
199
              
 
200
        if (debug) printf ("visibility notify state: %d\n", win->visibility);
 
201
      break;
 
202
 
 
203
        
 
204
      /*bad child wanted to move inside parent -> deny*/
 
205
      case ConfigureRequest:
 
206
        
 
207
      xconfigurerequest = (XConfigureRequestEvent*) xev;
 
208
              
 
209
      if (debug) printf ("child configure request\n");
 
210
 
 
211
      if (xconfigurerequest->x !=0  || xconfigurerequest->y != 0) {
 
212
        
 
213
        if (debug) printf ("deny configure request\n");
 
214
        return_type=GDK_FILTER_REMOVE;
 
215
      }
 
216
      
 
217
      break;
 
218
      
 
219
      
 
220
  }
 
221
  
 
222
   return return_type;
 
223
}
 
224
 
 
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)
 
230
{
 
231
  int i;
 
232
  gchar *rest_buf=NULL;
 
233
  gchar *tmp=NULL;
 
234
  gchar *shortcut=NULL;
 
235
 
 
236
 
 
237
  int x, y, w, h;
 
238
  
 
239
  if (argc == 1) {
 
240
    show_help();
 
241
    return FALSE;
 
242
  }  
 
243
  
 
244
  for (i = 1; i < argc; i++) {
 
245
  
 
246
    do {
 
247
    
 
248
      if (!strcmp(argv[i], "--help") || !strcmp(argv[i], "-h")) {
 
249
        show_help();
 
250
        return FALSE;
 
251
      }
 
252
      
 
253
      if (!strcmp(argv[i], "--version") || !strcmp(argv[i], "-v")) {
 
254
        show_version();
 
255
        return FALSE;
 
256
      }
 
257
        
 
258
      if (!strcmp(argv[i], "--show") || !strcmp(argv[i], "-s")) {
 
259
        *show=TRUE;
 
260
        break;
 
261
      }  
 
262
     
 
263
      if (!strcmp(argv[i], "--borderless") || !strcmp(argv[i], "-x")) {
 
264
        *borderless=TRUE;
 
265
        break;
 
266
      }
 
267
 
 
268
      if (!strcmp(argv[i], "--notray") || !strcmp(argv[i], "-nt")) {
 
269
        *notray=TRUE;
 
270
        break;
 
271
      }    
 
272
 
 
273
      if (!strcmp(argv[i], "--nominimize") || !strcmp(argv[i], "-nm")) {
 
274
        *nomini=TRUE;
 
275
        break;
 
276
      }    
 
277
 
 
278
      if (!strcmp(argv[i], "--sticky") || !strcmp(argv[i], "-st")) {
 
279
        *sticky=TRUE;
 
280
        break;
 
281
      }
 
282
    
 
283
      if (!strcmp(argv[i], "--skip-taskbar") || !strcmp(argv[i], "-stask")) {
 
284
        *skip_tasklist=TRUE;
 
285
        break;
 
286
      }
 
287
    
 
288
      if (!strcmp(argv[i], "--no-alltray") || !strcmp(argv[i], "-na")) {
 
289
        *no_title=TRUE;
 
290
        break;
 
291
      }
 
292
 
 
293
      if (!strcmp(argv[i], "--configure") || !strcmp(argv[i], "-conf")) {
 
294
        *configure=TRUE;
 
295
        break;
 
296
      } 
 
297
      
 
298
      if (!strcmp(argv[i], "--large_icons") || !strcmp(argv[i], "-l")) {
 
299
        *large_icons=TRUE;
 
300
        break;
 
301
      }  
 
302
    
 
303
         
 
304
      if (!strcmp(argv[i], "--icon") || !strcmp(argv[i], "-i")) {
 
305
        if ((i+1) ==  argc) {
 
306
          show_help();
 
307
          return FALSE;
 
308
        }
 
309
      
 
310
        *icon=g_strdup (argv[i+1]);
 
311
        i++;
 
312
        break;
 
313
      }
 
314
 
 
315
      if (!strcmp(argv[i], "--key") || !strcmp(argv[i], "-k")) {
 
316
          if ((i+1) ==  argc) {
 
317
            show_help();
 
318
            return FALSE;
 
319
          }
 
320
        
 
321
          shortcut=g_strdup (argv[i+1]);
 
322
        
 
323
          if (!parse_shortcut (shortcut, shortcut_key, shortcut_modifier))
 
324
            return FALSE;
 
325
          
 
326
          g_free (shortcut);
 
327
                               
 
328
          i++;
 
329
          break;
 
330
     }            
 
331
      
 
332
     if (!strcmp(argv[i], "--geometry") || !strcmp(argv[i], "-g")) {
 
333
        if ((i+1) ==  argc) {
 
334
          show_help();
 
335
          return FALSE;
 
336
        }
 
337
      
 
338
        *geometry=g_strdup (argv[i+1]);
 
339
        
 
340
        if (XParseGeometry(*geometry, &x, &y, (unsigned int *) &w, (unsigned int *) &h) == 0) {
 
341
          show_help();
 
342
          return FALSE;
 
343
        }
 
344
        
 
345
        i++;
 
346
        break;
 
347
     } 
 
348
      
 
349
     if (!strcmp(argv[i], "--title") || !strcmp(argv[i], "-t")) {
 
350
      if ((i+1) ==  argc) {
 
351
        show_help();
 
352
        return FALSE;
 
353
      }
 
354
    
 
355
      *title_time=atoi (argv[i+1]);
 
356
      
 
357
      if (*title_time == 0) {
 
358
        show_help ();
 
359
        return FALSE;
 
360
      }
 
361
      
 
362
      i++;
 
363
      break;
 
364
    }
 
365
      
 
366
    if (!strcmp(argv[i], "--menu") || !strcmp(argv[i], "-m")) {
 
367
      if ((i+1) ==  argc) {
 
368
        show_help();
 
369
        return FALSE;
 
370
      }
 
371
      
 
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]);
 
375
        return FALSE;
 
376
      }
 
377
                      
 
378
      i++;
 
379
      break;
 
380
    }
 
381
 
 
382
    if (!strcmp(argv[i], "--debug") || !strcmp(argv[i], "-d")) {
 
383
      *debug=TRUE;
 
384
      break;
 
385
    }  
 
386
 
 
387
  /*if (g_str_has_prefix (argv[i],"-")) {
 
388
      printf ("\nAlltray: Unknown option '%s'\n\n", argv[i]);
 
389
      return FALSE;
 
390
    }*/
 
391
    
 
392
    if (rest_buf == NULL) {
 
393
      rest_buf=g_strdup (argv[i]);
 
394
    } else {
 
395
      tmp=rest_buf;
 
396
      rest_buf=g_strconcat (rest_buf, " ", argv[i], NULL);
 
397
      g_free (tmp);
 
398
    }
 
399
        
 
400
    } until;
 
401
    
 
402
  }
 
403
  
 
404
  if (rest_buf && strlen (rest_buf) == 0 && !*configure) {
 
405
    show_help();
 
406
    return FALSE;
 
407
  }
 
408
 
 
409
  *rest=rest_buf;
 
410
 
 
411
  return TRUE;
 
412
}
 
413
 
 
414
gboolean append_command_to_menu(GArray *command_menu, gchar *string)
 
415
{
 
416
  
 
417
  command_menu_struct new;
 
418
  
 
419
  new.entry=NULL;
 
420
  new.command=NULL;
 
421
    
 
422
  gchar *tmp=NULL;
 
423
  gchar *command=NULL;
 
424
  
 
425
  tmp=g_strdup (string);
 
426
  
 
427
  if (!tmp)
 
428
    return FALSE;
 
429
        
 
430
  command = g_strrstr (tmp,":");
 
431
  
 
432
  if (debug) printf ("command: %s\n", command);
 
433
    
 
434
  if (!command) {
 
435
    g_free (tmp);
 
436
    return FALSE;
 
437
  }
 
438
  
 
439
  new.command=g_strdup(++command);
 
440
  
 
441
  if (strlen (new.command) == 0) {
 
442
    g_free (tmp);
 
443
    g_free (new.command);
 
444
    return FALSE;
 
445
  }
 
446
   
 
447
  if (debug) printf ("new.command: %s\n", new.command);
 
448
  
 
449
  *(--command)=0;
 
450
  
 
451
  if (strlen (tmp) == 0) {
 
452
    g_free (tmp);
 
453
    g_free (new.command);
 
454
    return FALSE;
 
455
  }
 
456
  
 
457
  new.entry=tmp;
 
458
    
 
459
  if (debug) printf ("new.entry: %s\n", new.entry);
 
460
    
 
461
  g_array_append_val(command_menu, new);
 
462
  
 
463
  return TRUE;
 
464
}
 
465
 
 
466
gchar *strip_command (win_struct *win)
 
467
{
 
468
 
 
469
  gchar *command_copy=NULL;
 
470
  gchar *space=NULL;
 
471
  gchar *basename=NULL;
 
472
 
 
473
  command_copy=g_strdup (win->command);
 
474
 
 
475
  space=g_strstr_len (command_copy, 
 
476
      strlen (command_copy) , " ");
 
477
  
 
478
  if (space)
 
479
    *space=0;
 
480
  
 
481
  if (debug) printf ("command without args: %s\n", command_copy);
 
482
 
 
483
  basename=g_path_get_basename (command_copy);
 
484
  
 
485
  if (debug) printf ("basename: %s\n", basename);
 
486
  
 
487
  g_free (command_copy);
 
488
  
 
489
  return basename;
 
490
 
 
491
}
 
492
 
 
493
void show_help(void)
 
494
{
 
495
  printf ("\nAllTray Version %s\n\n" \
 
496
  
 
497
             "Dock any program into the system tray.\n\n"  \
 
498
 
 
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"\
 
523
 
 
524
  , VERSION);
 
525
 
 
526
}
 
527
 
 
528
void show_version (void)
 
529
{
 
530
  printf ("\nAlltray version %s\n\n", VERSION);
 
531
}