1 ///////////////////////////////////////////////////////////////////////// 
   3 // Purpose:     wxTaskBarIcon class for common Unix desktops 
   4 // Author:      Vaclav Slavik 
   8 // Copyright:   (c) Vaclav Slavik, 2003 
   9 // Licence:     wxWindows licence 
  10 ///////////////////////////////////////////////////////////////////////// 
  12 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) 
  13 #pragma implementation "taskbarx11.h" 
  16 // NB: This implementation does *not* work with every X11 window manager. 
  17 //     Currently only GNOME 1.2 and KDE 1,2,3 methods are implemented here. 
  18 //     Freedesktop.org's System Tray specification is implemented in 
  19 //     src/gtk/taskbar.cpp and used from here under wxGTK. 
  21 //     Thanks to Ian Campbell, author of XMMS Status Docklet, for publishing 
  22 //     KDE and GNOME 1.2 methods. 
  25 // For compilers that support precompilation, includes "wx.h". 
  26 #include "wx/wxprec.h" 
  28 #include "wx/taskbar.h" 
  30 #include "wx/bitmap.h" 
  31 #include "wx/statbmp.h" 
  33 #include "wx/dcclient.h" 
  37 #pragma message disable nosimpint 
  40 #include <X11/Xatom.h> 
  42 #pragma message enable nosimpint 
  45 // ---------------------------------------------------------------------------- 
  46 // base class that implements toolkit-specific method: 
  47 // ---------------------------------------------------------------------------- 
  50     #include "wx/gtk/taskbarpriv.h" 
  52     class WXDLLIMPEXP_ADV wxTaskBarIconAreaBase 
: public wxFrame
 
  55         wxTaskBarIconAreaBase() 
  56             : wxFrame(NULL
, wxID_ANY
, _T("systray icon"), 
  57                       wxDefaultPosition
, wxDefaultSize
, 
  58                       wxDEFAULT_FRAME_STYLE 
| wxFRAME_NO_TASKBAR 
| 
  59                       wxSIMPLE_BORDER 
| wxFRAME_SHAPED
) {} 
  61         bool IsProtocolSupported() const { return false; } 
  66 // ---------------------------------------------------------------------------- 
  67 // toolkit dependent methods to set properties on helper window: 
  68 // ---------------------------------------------------------------------------- 
  70 #if defined(__WXGTK__) 
  74     #define GetDisplay()        GDK_DISPLAY() 
  75     #define GetXWindow(wxwin)   GDK_WINDOW_XWINDOW((wxwin)->m_widget->window) 
  76 #elif defined(__WXX11__) || defined(__WXMOTIF__) 
  77     #include "wx/x11/privx.h" 
  78     #define GetDisplay()        ((Display*)wxGlobalDisplay()) 
  79     #define GetXWindow(wxwin)   ((Window)(wxwin)->GetHandle()) 
  81     #error "You must define X11 accessors for this port!" 
  85 // ---------------------------------------------------------------------------- 
  86 // wxTaskBarIconArea is the real window that shows the icon: 
  87 // ---------------------------------------------------------------------------- 
  89 class WXDLLIMPEXP_ADV wxTaskBarIconArea 
: public wxTaskBarIconAreaBase
 
  92     wxTaskBarIconArea(wxTaskBarIcon 
*icon
, const wxBitmap 
&bmp
); 
  93     void SetTrayIcon(const wxBitmap
& bmp
); 
  94     bool IsOk() { return true; } 
  97     void SetLegacyWMProperties(); 
  99     void OnSizeChange(wxSizeEvent
& event
); 
 100     void OnPaint(wxPaintEvent
& evt
); 
 101     void OnMouseEvent(wxMouseEvent
& event
); 
 102     void OnMenuEvent(wxCommandEvent
& event
); 
 104     wxTaskBarIcon 
*m_icon
; 
 108     DECLARE_EVENT_TABLE() 
 111 BEGIN_EVENT_TABLE(wxTaskBarIconArea
, wxTaskBarIconAreaBase
) 
 112     EVT_SIZE(wxTaskBarIconArea::OnSizeChange
) 
 113     EVT_MOUSE_EVENTS(wxTaskBarIconArea::OnMouseEvent
) 
 114     EVT_MENU(-1, wxTaskBarIconArea::OnMenuEvent
) 
 115     EVT_PAINT(wxTaskBarIconArea::OnPaint
) 
 118 wxTaskBarIconArea::wxTaskBarIconArea(wxTaskBarIcon 
*icon
, const wxBitmap 
&bmp
) 
 119     : wxTaskBarIconAreaBase(), m_icon(icon
), m_pos(0,0) 
 121     if (!IsProtocolSupported()) 
 123         wxLogTrace(_T("systray"), 
 124                    _T("using legacy KDE1,2 and GNOME 1.2 methods")); 
 125         SetLegacyWMProperties(); 
 128     // Set initial size to bitmap size (tray manager may and often will 
 130     SetSize(wxSize(bmp
.GetWidth(), bmp
.GetHeight())); 
 135 void wxTaskBarIconArea::SetTrayIcon(const wxBitmap
& bmp
) 
 139     // determine suitable bitmap size: 
 140     wxSize 
winsize(GetSize()); 
 141     wxSize 
bmpsize(m_bmp
.GetWidth(), m_bmp
.GetHeight()); 
 142     wxSize 
iconsize(wxMin(winsize
.x
, bmpsize
.x
), wxMin(winsize
.y
, bmpsize
.y
)); 
 144     // rescale the bitmap to fit into the tray icon window: 
 145     if (bmpsize 
!= iconsize
) 
 147         wxImage img 
= m_bmp
.ConvertToImage(); 
 148         img
.Rescale(iconsize
.x
, iconsize
.y
); 
 149         m_bmp 
= wxBitmap(img
); 
 156         region
.Union(0,0, iconsize
.x
, iconsize
.y
); 
 158     // if the bitmap is smaller than the window, offset it: 
 159     if (winsize 
!= iconsize
) 
 161         m_pos
.x 
= (winsize
.x 
- iconsize
.x
) / 2; 
 162         m_pos
.y 
= (winsize
.y 
- iconsize
.y
) / 2; 
 163         region
.Offset(m_pos
.x
, m_pos
.y
); 
 166     // set frame's shape to correct value and redraw: 
 171 void wxTaskBarIconArea::SetLegacyWMProperties() 
 174     gtk_widget_realize(m_widget
); 
 180     Atom _KDE_NET_WM_SYSTEM_TRAY_WINDOW_FOR 
= 
 181         XInternAtom(GetDisplay(), "_KDE_NET_WM_SYSTEM_TRAY_WINDOW_FOR", False
); 
 183     XChangeProperty(GetDisplay(), GetXWindow(this), 
 184                     _KDE_NET_WM_SYSTEM_TRAY_WINDOW_FOR
, 
 186                     PropModeReplace
, (unsigned char*)data
, 1); 
 188     // GNOME 1.2 & KDE 1: 
 189     Atom KWM_DOCKWINDOW 
= 
 190         XInternAtom(GetDisplay(), "KWM_DOCKWINDOW", False
); 
 192     XChangeProperty(GetDisplay(), GetXWindow(this), 
 195                     PropModeReplace
, (unsigned char*)data
, 1); 
 198 void wxTaskBarIconArea::OnSizeChange(wxSizeEvent
& event
) 
 200     wxLogTrace(_T("systray"), _T("icon size changed to %i x %i"), 
 201                GetSize().x
, GetSize().y
); 
 202     // rescale or reposition the icon as needed: 
 207 void wxTaskBarIconArea::OnPaint(wxPaintEvent
& WXUNUSED(event
)) 
 210     dc
.DrawBitmap(m_bmp
, m_pos
.x
, m_pos
.y
, true); 
 213 void wxTaskBarIconArea::OnMouseEvent(wxMouseEvent
& event
) 
 215     wxEventType type 
= 0; 
 216     wxEventType mtype 
= event
.GetEventType(); 
 218     if (mtype 
== wxEVT_LEFT_DOWN
) 
 219         type 
= wxEVT_TASKBAR_LEFT_DOWN
; 
 220     else if (mtype 
== wxEVT_LEFT_UP
) 
 221         type 
= wxEVT_TASKBAR_LEFT_UP
; 
 222     else if (mtype 
== wxEVT_LEFT_DCLICK
) 
 223         type 
= wxEVT_TASKBAR_LEFT_DCLICK
; 
 224     else if (mtype 
== wxEVT_RIGHT_DOWN
) 
 225         type 
= wxEVT_TASKBAR_RIGHT_DOWN
; 
 226     else if (mtype 
== wxEVT_RIGHT_UP
) 
 227         type 
= wxEVT_TASKBAR_RIGHT_UP
; 
 228     else if (mtype 
== wxEVT_RIGHT_DCLICK
) 
 229         type 
= wxEVT_TASKBAR_RIGHT_DCLICK
; 
 230     else if (mtype 
== wxEVT_MOTION
) 
 231         type 
= wxEVT_TASKBAR_MOVE
; 
 235    wxTaskBarIconEvent 
e(type
, m_icon
); 
 236    m_icon
->ProcessEvent(e
); 
 239 void wxTaskBarIconArea::OnMenuEvent(wxCommandEvent
& event
) 
 241     m_icon
->ProcessEvent(event
); 
 244 // ---------------------------------------------------------------------------- 
 245 // wxTaskBarIcon class: 
 246 // ---------------------------------------------------------------------------- 
 248 IMPLEMENT_DYNAMIC_CLASS(wxTaskBarIcon
, wxEvtHandler
) 
 250 wxTaskBarIcon::wxTaskBarIcon() : m_iconWnd(NULL
) 
 254 wxTaskBarIcon::~wxTaskBarIcon() 
 260 bool wxTaskBarIcon::IsOk() const 
 265 bool wxTaskBarIcon::IsIconInstalled() const 
 267     return m_iconWnd 
!= NULL
; 
 270 bool wxTaskBarIcon::SetIcon(const wxIcon
& icon
, const wxString
& tooltip
) 
 273     bmp
.CopyFromIcon(icon
); 
 277         m_iconWnd 
= new wxTaskBarIconArea(this, bmp
); 
 278         if (m_iconWnd
->IsOk()) 
 284             m_iconWnd
->Destroy(); 
 291         m_iconWnd
->SetTrayIcon(bmp
); 
 295     if (!tooltip
.empty()) 
 296         m_iconWnd
->SetToolTip(tooltip
); 
 298         m_iconWnd
->SetToolTip(NULL
); 
 303 bool wxTaskBarIcon::RemoveIcon() 
 307     m_iconWnd
->Destroy(); 
 312 bool wxTaskBarIcon::PopupMenu(wxMenu 
*menu
) 
 316     wxSize 
size(m_iconWnd
->GetClientSize()); 
 317     m_iconWnd
->PopupMenu(menu
);