Show
Ignore:
Timestamp:
05/16/06 10:51:48 (3 years ago)
Author:
dkirov
Message:

added eggtrayicon from mail-notification.
This should make tray icon transparent for non-
gnome desktops.

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • trunk/src/eggtrayicon.c

    r1063 r6333  
    1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ 
    21/* eggtrayicon.c 
    32 * Copyright (C) 2002 Anders Carlsson <andersca@gnu.org> 
     
    1918 */ 
    2019 
    21 //#include <config.h> 
    2220#include <string.h> 
     21#include <glib/gi18n.h> 
    2322#include <libintl.h> 
    2423 
    2524#include "eggtrayicon.h" 
    2625 
     26#include <gdkconfig.h> 
     27#if defined (GDK_WINDOWING_X11) 
    2728#include <gdk/gdkx.h> 
    2829#include <X11/Xatom.h> 
    29  
    30 /*#ifndef EGG_COMPILATION 
     30#elif defined (GDK_WINDOWING_WIN32) 
     31#include <gdk/gdkwin32.h> 
     32#endif 
     33 
     34#ifndef EGG_COMPILATION 
    3135#ifndef _ 
    32 #define _(x) dgettext ('gajim', x) 
     36#define _(x) dgettext (GETTEXT_PACKAGE, x) 
    3337#define N_(x) x 
    3438#endif 
     
    3741#define N_(x) x 
    3842#endif 
    39 */ 
     43 
    4044#define SYSTEM_TRAY_REQUEST_DOCK    0 
    4145#define SYSTEM_TRAY_BEGIN_MESSAGE   1 
     
    4953  PROP_ORIENTATION 
    5054}; 
    51           
     55 
    5256static GtkPlugClass *parent_class = NULL; 
    5357 
     
    6064                                        GParamSpec *pspec); 
    6165 
     66static void egg_tray_icon_add (GtkContainer *container, GtkWidget *widget); 
     67 
    6268static void egg_tray_icon_realize   (GtkWidget *widget); 
    6369static void egg_tray_icon_unrealize (GtkWidget *widget); 
    6470 
    65 static void egg_tray_icon_update_manager_window (EggTrayIcon *icon); 
     71#ifdef GDK_WINDOWING_X11 
     72static void egg_tray_icon_update_manager_window    (EggTrayIcon *icon, 
     73                                                    gboolean     dock_if_realized); 
     74static void egg_tray_icon_manager_window_destroyed (EggTrayIcon *icon); 
     75#endif 
    6676 
    6777GType 
     
    96106  icon->stamp = 1; 
    97107  icon->orientation = GTK_ORIENTATION_HORIZONTAL; 
    98    
     108 
    99109  gtk_widget_add_events (GTK_WIDGET (icon), GDK_PROPERTY_CHANGE_MASK); 
    100110} 
     
    105115  GObjectClass *gobject_class = (GObjectClass *)klass; 
    106116  GtkWidgetClass *widget_class = (GtkWidgetClass *)klass; 
     117  GtkContainerClass *container_class = (GtkContainerClass *)klass; 
    107118 
    108119  parent_class = g_type_class_peek_parent (klass); 
     
    112123  widget_class->realize   = egg_tray_icon_realize; 
    113124  widget_class->unrealize = egg_tray_icon_unrealize; 
     125 
     126  container_class->add = egg_tray_icon_add; 
    114127 
    115128  g_object_class_install_property (gobject_class, 
    116129                                   PROP_ORIENTATION, 
    117130                                   g_param_spec_enum ("orientation", 
    118                                                       "Orientation", 
    119                                                       "The orientation of the tray.", 
    120 //                                                    _("Orientation"), 
    121 //                                                    _("The orientation of the tray."), 
     131                                                      _("Orientation"), 
     132                                                      _("The orientation of the tray."), 
    122133                                                      GTK_TYPE_ORIENTATION, 
    123134                                                      GTK_ORIENTATION_HORIZONTAL, 
    124135                                                      G_PARAM_READABLE)); 
     136 
     137#if defined (GDK_WINDOWING_X11) 
     138  /* Nothing */ 
     139#elif defined (GDK_WINDOWING_WIN32) 
     140  g_warning ("Port eggtrayicon to Win32"); 
     141#else 
     142  g_warning ("Port eggtrayicon to this GTK+ backend"); 
     143#endif 
    125144} 
    126145 
     
    143162    } 
    144163} 
     164 
     165#ifdef GDK_WINDOWING_X11 
    145166 
    146167static void 
     
    159180 
    160181  g_assert (icon->manager_window != None); 
    161    
     182 
    162183  xdisplay = GDK_DISPLAY_XDISPLAY (gtk_widget_get_display (GTK_WIDGET (icon))); 
    163184 
     
    206227      xev->xclient.data.l[1] == icon->selection_atom) 
    207228    { 
    208       egg_tray_icon_update_manager_window (icon); 
     229      egg_tray_icon_update_manager_window (icon, TRUE); 
    209230    } 
    210231  else if (xev->xany.window == icon->manager_window) 
     
    217238      if (xev->xany.type == DestroyNotify) 
    218239        { 
    219           egg_tray_icon_update_manager_window (icon); 
     240          egg_tray_icon_manager_window_destroyed (icon); 
    220241        } 
    221242    } 
    222    
    223243  return GDK_FILTER_CONTINUE; 
    224244} 
    225245 
     246#endif   
     247 
    226248static void 
    227249egg_tray_icon_unrealize (GtkWidget *widget) 
    228250{ 
     251#ifdef GDK_WINDOWING_X11 
    229252  EggTrayIcon *icon = EGG_TRAY_ICON (widget); 
    230253  GdkWindow *root_window; 
     
    246269  if (GTK_WIDGET_CLASS (parent_class)->unrealize) 
    247270    (* GTK_WIDGET_CLASS (parent_class)->unrealize) (widget); 
    248 } 
     271#endif 
     272} 
     273 
     274#ifdef GDK_WINDOWING_X11 
    249275 
    250276static void 
     
    258284  XClientMessageEvent ev; 
    259285  Display *display; 
    260    
     286 
    261287  ev.type = ClientMessage; 
    262288  ev.window = window; 
     
    270296 
    271297  display = GDK_DISPLAY_XDISPLAY (gtk_widget_get_display (GTK_WIDGET (icon))); 
    272    
     298 
    273299  gdk_error_trap_push (); 
    274300  XSendEvent (display, 
     
    289315 
    290316static void 
    291 egg_tray_icon_update_manager_window (EggTrayIcon *icon) 
     317egg_tray_icon_update_manager_window (EggTrayIcon *icon, 
     318                                     gboolean     dock_if_realized) 
    292319{ 
    293320  Display *xdisplay; 
    294    
     321 
     322  if (icon->manager_window != None) 
     323    return; 
     324 
    295325  xdisplay = GDK_DISPLAY_XDISPLAY (gtk_widget_get_display (GTK_WIDGET (icon))); 
    296    
    297   if (icon->manager_window != None) 
    298     { 
    299       GdkWindow *gdkwin; 
    300  
    301       gdkwin = gdk_window_lookup_for_display (gtk_widget_get_display (GTK_WIDGET (icon)), 
    302                                               icon->manager_window); 
    303        
    304       gdk_window_remove_filter (gdkwin, egg_tray_icon_manager_filter, icon); 
    305     } 
    306    
     326 
    307327  XGrabServer (xdisplay); 
    308    
     328 
    309329  icon->manager_window = XGetSelectionOwner (xdisplay, 
    310330                                             icon->selection_atom); 
     
    316336  XUngrabServer (xdisplay); 
    317337  XFlush (xdisplay); 
    318    
     338 
    319339  if (icon->manager_window != None) 
    320340    { 
     
    323343      gdkwin = gdk_window_lookup_for_display (gtk_widget_get_display (GTK_WIDGET (icon)), 
    324344                                              icon->manager_window); 
    325        
     345 
    326346      gdk_window_add_filter (gdkwin, egg_tray_icon_manager_filter, icon); 
    327347 
    328       /* Send a request that we'd like to dock */ 
    329       egg_tray_icon_send_dock_request (icon); 
     348      if (dock_if_realized && GTK_WIDGET_REALIZED (icon)) 
     349        egg_tray_icon_send_dock_request (icon); 
    330350 
    331351      egg_tray_icon_get_orientation_property (icon); 
     
    333353} 
    334354 
     355static gboolean 
     356transparent_expose_event (GtkWidget *widget, GdkEventExpose *event, gpointer user_data) 
     357{ 
     358  gdk_window_clear_area (widget->window, event->area.x, event->area.y, 
     359                         event->area.width, event->area.height); 
     360  return FALSE; 
     361} 
     362 
     363static void 
     364make_transparent_again (GtkWidget *widget, GtkStyle *previous_style, 
     365                        gpointer user_data) 
     366{ 
     367  gdk_window_set_back_pixmap (widget->window, NULL, TRUE); 
     368} 
     369 
     370static void 
     371make_transparent (GtkWidget *widget, gpointer user_data) 
     372{ 
     373  if (GTK_WIDGET_NO_WINDOW (widget) || GTK_WIDGET_APP_PAINTABLE (widget)) 
     374    return; 
     375 
     376  gtk_widget_set_app_paintable (widget, TRUE); 
     377  gtk_widget_set_double_buffered (widget, FALSE); 
     378  gdk_window_set_back_pixmap (widget->window, NULL, TRUE); 
     379  g_signal_connect (widget, "expose_event", 
     380                    G_CALLBACK (transparent_expose_event), NULL); 
     381  g_signal_connect_after (widget, "style_set", 
     382                          G_CALLBACK (make_transparent_again), NULL); 
     383} 
     384 
     385static void 
     386egg_tray_icon_manager_window_destroyed (EggTrayIcon *icon) 
     387{ 
     388  GdkWindow *gdkwin; 
     389 
     390  g_return_if_fail (icon->manager_window != None); 
     391 
     392  gdkwin = gdk_window_lookup_for_display (gtk_widget_get_display (GTK_WIDGET (icon)), 
     393                                          icon->manager_window); 
     394 
     395  gdk_window_remove_filter (gdkwin, egg_tray_icon_manager_filter, icon); 
     396 
     397  icon->manager_window = None; 
     398 
     399  egg_tray_icon_update_manager_window (icon, TRUE); 
     400} 
     401 
     402#endif 
     403 
    335404static void 
    336405egg_tray_icon_realize (GtkWidget *widget) 
    337406{ 
     407#ifdef GDK_WINDOWING_X11 
    338408  EggTrayIcon *icon = EGG_TRAY_ICON (widget); 
    339409  GdkScreen *screen; 
     
    346416    GTK_WIDGET_CLASS (parent_class)->realize (widget); 
    347417 
     418  make_transparent (widget, NULL); 
     419 
    348420  screen = gtk_widget_get_screen (widget); 
    349421  display = gdk_screen_get_display (screen); 
     
    356428 
    357429  icon->selection_atom = XInternAtom (xdisplay, buffer, False); 
    358    
     430 
    359431  icon->manager_atom = XInternAtom (xdisplay, "MANAGER", False); 
    360    
     432 
    361433  icon->system_tray_opcode_atom = XInternAtom (xdisplay, 
    362434                                                   "_NET_SYSTEM_TRAY_OPCODE", 
     
    367439                                        False); 
    368440 
    369   egg_tray_icon_update_manager_window (icon); 
     441  egg_tray_icon_update_manager_window (icon, FALSE); 
     442  egg_tray_icon_send_dock_request (icon); 
    370443 
    371444  root_window = gdk_screen_get_root_window (screen); 
    372    
     445 
    373446  /* Add a root window filter so that we get changes on MANAGER */ 
    374447  gdk_window_add_filter (root_window, 
    375448                         egg_tray_icon_manager_filter, icon); 
     449#endif 
     450} 
     451 
     452static void 
     453egg_tray_icon_add (GtkContainer *container, GtkWidget *widget) 
     454{ 
     455  g_signal_connect (widget, "realize", 
     456                    G_CALLBACK (make_transparent), NULL); 
     457  GTK_CONTAINER_CLASS (parent_class)->add (container, widget); 
    376458} 
    377459 
     
    397479{ 
    398480  guint stamp; 
    399    
     481 
    400482  g_return_val_if_fail (EGG_IS_TRAY_ICON (icon), 0); 
    401483  g_return_val_if_fail (timeout >= 0, 0); 
    402484  g_return_val_if_fail (message != NULL, 0); 
    403                       
     485 
     486#ifdef GDK_WINDOWING_X11 
    404487  if (icon->manager_window == None) 
    405488    return 0; 
     489#endif 
    406490 
    407491  if (len < 0) 
     
    409493 
    410494  stamp = icon->stamp++; 
    411    
     495 
     496#ifdef GDK_WINDOWING_X11 
    412497  /* Get ready to send the message */ 
    413498  egg_tray_icon_send_manager_message (icon, SYSTEM_TRAY_BEGIN_MESSAGE, 
     
    423508 
    424509      xdisplay = GDK_DISPLAY_XDISPLAY (gtk_widget_get_display (GTK_WIDGET (icon))); 
    425        
     510 
    426511      ev.type = ClientMessage; 
    427512      ev.window = (Window)gtk_plug_get_id (GTK_PLUG (icon)); 
     
    446531    } 
    447532  gdk_error_trap_pop (); 
     533#endif 
    448534 
    449535  return stamp; 
     
    456542  g_return_if_fail (EGG_IS_TRAY_ICON (icon)); 
    457543  g_return_if_fail (id > 0); 
    458    
     544#ifdef GDK_WINDOWING_X11   
    459545  egg_tray_icon_send_manager_message (icon, SYSTEM_TRAY_CANCEL_MESSAGE, 
    460546                                      (Window)gtk_plug_get_id (GTK_PLUG (icon)), 
    461547                                      id, 0, 0); 
     548#endif 
    462549} 
    463550