1 ///////////////////////////////////////////////////////////////////////// 
   2 // File:        src/unix/taskbarx11.cpp 
   3 // Purpose:     wxTaskBarIcon class for common Unix desktops 
   4 // Author:      Vaclav Slavik 
   8 // Copyright:   (c) Vaclav Slavik, 2003 
   9 // Licence:     wxWindows licence 
  10 ///////////////////////////////////////////////////////////////////////// 
  12 // NB: This implementation does *not* work with every X11 window manager. 
  13 //     Currently only GNOME 1.2 and KDE 1,2,3 methods are implemented here. 
  14 //     Freedesktop.org's System Tray specification is implemented in 
  15 //     src/gtk/taskbar.cpp and used from here under wxGTK. 
  17 //     Thanks to Ian Campbell, author of XMMS Status Docklet, for publishing 
  18 //     KDE and GNOME 1.2 methods. 
  21 // For compilers that support precompilation, includes "wx.h". 
  22 #include "wx/wxprec.h" 
  26 #include "wx/taskbar.h" 
  31     #include "wx/dcclient.h" 
  32     #include "wx/statbmp.h" 
  34     #include "wx/bitmap.h" 
  39 #pragma message disable nosimpint 
  42 #include <X11/Xatom.h> 
  44 #pragma message enable nosimpint 
  47 // ---------------------------------------------------------------------------- 
  48 // base class that implements toolkit-specific method: 
  49 // ---------------------------------------------------------------------------- 
  53     #if GTK_CHECK_VERSION(2,1,0) 
  54         #include "wx/gtk/taskbarpriv.h" 
  55         #define TASKBAR_ICON_AREA_BASE_INCLUDED 
  59 #ifndef TASKBAR_ICON_AREA_BASE_INCLUDED 
  60     class WXDLLIMPEXP_ADV wxTaskBarIconAreaBase 
: public wxFrame
 
  63         wxTaskBarIconAreaBase() 
  64             : wxFrame(NULL
, wxID_ANY
, _T("systray icon"), 
  65                       wxDefaultPosition
, wxDefaultSize
, 
  66                       wxDEFAULT_FRAME_STYLE 
| wxFRAME_NO_TASKBAR 
| 
  67                       wxSIMPLE_BORDER 
| wxFRAME_SHAPED
) {} 
  69         bool IsProtocolSupported() const { return false; } 
  74 // ---------------------------------------------------------------------------- 
  75 // toolkit dependent methods to set properties on helper window: 
  76 // ---------------------------------------------------------------------------- 
  78 #if defined(__WXGTK__) 
  82     #define GetDisplay()        GDK_DISPLAY() 
  83     #define GetXWindow(wxwin)   GDK_WINDOW_XWINDOW((wxwin)->m_widget->window) 
  84 #elif defined(__WXX11__) || defined(__WXMOTIF__) 
  85     #include "wx/x11/privx.h" 
  86     #define GetDisplay()        ((Display*)wxGlobalDisplay()) 
  87     #define GetXWindow(wxwin)   ((Window)(wxwin)->GetHandle()) 
  89     #error "You must define X11 accessors for this port!" 
  93 // ---------------------------------------------------------------------------- 
  94 // wxTaskBarIconArea is the real window that shows the icon: 
  95 // ---------------------------------------------------------------------------- 
  97 class WXDLLIMPEXP_ADV wxTaskBarIconArea 
: public wxTaskBarIconAreaBase
 
 100     wxTaskBarIconArea(wxTaskBarIcon 
*icon
, const wxBitmap 
&bmp
); 
 101     void SetTrayIcon(const wxBitmap
& bmp
); 
 102     bool IsOk() { return true; } 
 105     void SetLegacyWMProperties(); 
 107     void OnSizeChange(wxSizeEvent
& event
); 
 108     void OnPaint(wxPaintEvent
& evt
); 
 109     void OnMouseEvent(wxMouseEvent
& event
); 
 110     void OnMenuEvent(wxCommandEvent
& event
); 
 112     wxTaskBarIcon 
*m_icon
; 
 116     DECLARE_EVENT_TABLE() 
 119 BEGIN_EVENT_TABLE(wxTaskBarIconArea
, wxTaskBarIconAreaBase
) 
 120     EVT_SIZE(wxTaskBarIconArea::OnSizeChange
) 
 121     EVT_MOUSE_EVENTS(wxTaskBarIconArea::OnMouseEvent
) 
 122     EVT_MENU(wxID_ANY
, wxTaskBarIconArea::OnMenuEvent
) 
 123     EVT_PAINT(wxTaskBarIconArea::OnPaint
) 
 126 wxTaskBarIconArea::wxTaskBarIconArea(wxTaskBarIcon 
*icon
, const wxBitmap 
&bmp
) 
 127     : wxTaskBarIconAreaBase(), m_icon(icon
), m_bmp(bmp
) 
 129 #if defined(__WXGTK20__) && defined(TASKBAR_ICON_AREA_BASE_INCLUDED) 
 130     m_invokingWindow 
= icon
; 
 133     // Set initial size to bitmap size (tray manager may and often will 
 135     SetClientSize(wxSize(bmp
.GetWidth(), bmp
.GetHeight())); 
 139     if (!IsProtocolSupported()) 
 141         wxLogTrace(_T("systray"), 
 142                    _T("using legacy KDE1,2 and GNOME 1.2 methods")); 
 143         SetLegacyWMProperties(); 
 147 void wxTaskBarIconArea::SetTrayIcon(const wxBitmap
& bmp
) 
 151     // determine suitable bitmap size: 
 152     wxSize 
winsize(GetClientSize()); 
 153     wxSize 
bmpsize(m_bmp
.GetWidth(), m_bmp
.GetHeight()); 
 154     wxSize 
iconsize(wxMin(winsize
.x
, bmpsize
.x
), wxMin(winsize
.y
, bmpsize
.y
)); 
 156     // rescale the bitmap to fit into the tray icon window: 
 157     if (bmpsize 
!= iconsize
) 
 159         wxImage img 
= m_bmp
.ConvertToImage(); 
 160         img
.Rescale(iconsize
.x
, iconsize
.y
); 
 161         m_bmp 
= wxBitmap(img
); 
 167     // if the bitmap is smaller than the window, offset it: 
 168     if (winsize 
!= iconsize
) 
 170         m_pos
.x 
= (winsize
.x 
- iconsize
.x
) / 2; 
 171         m_pos
.y 
= (winsize
.y 
- iconsize
.y
) / 2; 
 172         region
.Offset(m_pos
.x
, m_pos
.y
); 
 175     // set frame's shape to correct value and redraw: 
 180 void wxTaskBarIconArea::SetLegacyWMProperties() 
 183     gtk_widget_realize(m_widget
); 
 189     Atom _KDE_NET_WM_SYSTEM_TRAY_WINDOW_FOR 
= 
 190         XInternAtom(GetDisplay(), "_KDE_NET_WM_SYSTEM_TRAY_WINDOW_FOR", False
); 
 192     XChangeProperty(GetDisplay(), GetXWindow(this), 
 193                     _KDE_NET_WM_SYSTEM_TRAY_WINDOW_FOR
, 
 195                     PropModeReplace
, (unsigned char*)data
, 1); 
 197     // GNOME 1.2 & KDE 1: 
 198     Atom KWM_DOCKWINDOW 
= 
 199         XInternAtom(GetDisplay(), "KWM_DOCKWINDOW", False
); 
 201     XChangeProperty(GetDisplay(), GetXWindow(this), 
 204                     PropModeReplace
, (unsigned char*)data
, 1); 
 207 void wxTaskBarIconArea::OnSizeChange(wxSizeEvent
& WXUNUSED(event
)) 
 209     wxLogTrace(_T("systray"), _T("icon size changed to %i x %i"), 
 210                GetSize().x
, GetSize().y
); 
 211     // rescale or reposition the icon as needed: 
 216 void wxTaskBarIconArea::OnPaint(wxPaintEvent
& WXUNUSED(event
)) 
 219     dc
.DrawBitmap(m_bmp
, m_pos
.x
, m_pos
.y
, true); 
 222 void wxTaskBarIconArea::OnMouseEvent(wxMouseEvent
& event
) 
 224     wxEventType type 
= 0; 
 225     wxEventType mtype 
= event
.GetEventType(); 
 227     if (mtype 
== wxEVT_LEFT_DOWN
) 
 228         type 
= wxEVT_TASKBAR_LEFT_DOWN
; 
 229     else if (mtype 
== wxEVT_LEFT_UP
) 
 230         type 
= wxEVT_TASKBAR_LEFT_UP
; 
 231     else if (mtype 
== wxEVT_LEFT_DCLICK
) 
 232         type 
= wxEVT_TASKBAR_LEFT_DCLICK
; 
 233     else if (mtype 
== wxEVT_RIGHT_DOWN
) 
 234         type 
= wxEVT_TASKBAR_RIGHT_DOWN
; 
 235     else if (mtype 
== wxEVT_RIGHT_UP
) 
 236         type 
= wxEVT_TASKBAR_RIGHT_UP
; 
 237     else if (mtype 
== wxEVT_RIGHT_DCLICK
) 
 238         type 
= wxEVT_TASKBAR_RIGHT_DCLICK
; 
 239     else if (mtype 
== wxEVT_MOTION
) 
 240         type 
= wxEVT_TASKBAR_MOVE
; 
 244    wxTaskBarIconEvent 
e(type
, m_icon
); 
 245    m_icon
->ProcessEvent(e
); 
 248 void wxTaskBarIconArea::OnMenuEvent(wxCommandEvent
& event
) 
 250     m_icon
->ProcessEvent(event
); 
 253 // ---------------------------------------------------------------------------- 
 254 // wxTaskBarIcon class: 
 255 // ---------------------------------------------------------------------------- 
 257 IMPLEMENT_DYNAMIC_CLASS(wxTaskBarIcon
, wxEvtHandler
) 
 259 wxTaskBarIcon::wxTaskBarIcon() : m_iconWnd(NULL
) 
 263 wxTaskBarIcon::~wxTaskBarIcon() 
 269 bool wxTaskBarIcon::IsOk() const 
 274 bool wxTaskBarIcon::IsIconInstalled() const 
 276     return m_iconWnd 
!= NULL
; 
 279 bool wxTaskBarIcon::SetIcon(const wxIcon
& icon
, const wxString
& tooltip
) 
 282     bmp
.CopyFromIcon(icon
); 
 286         m_iconWnd 
= new wxTaskBarIconArea(this, bmp
); 
 287         if (m_iconWnd
->IsOk()) 
 293             m_iconWnd
->Destroy(); 
 300         m_iconWnd
->SetTrayIcon(bmp
); 
 304     if (!tooltip
.empty()) 
 305         m_iconWnd
->SetToolTip(tooltip
); 
 307         m_iconWnd
->SetToolTip(NULL
); 
 309     wxUnusedVar(tooltip
); 
 314 bool wxTaskBarIcon::RemoveIcon() 
 318     m_iconWnd
->Destroy(); 
 323 bool wxTaskBarIcon::PopupMenu(wxMenu 
*menu
) 
 327     m_iconWnd
->PopupMenu(menu
); 
 331 #endif // wxUSE_TASKBARICON