If the icon is smaller than the allotted space then center it.
[wxWidgets.git] / src / unix / taskbarx11.cpp
1 /////////////////////////////////////////////////////////////////////////
2 // File: taskbar.cpp
3 // Purpose: wxTaskBarIcon class for common Unix desktops
4 // Author: Vaclav Slavik
5 // Modified by:
6 // Created: 04/04/2003
7 // RCS-ID: $Id$
8 // Copyright: (c) Vaclav Slavik, 2003
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////
11
12 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
13 #pragma implementation "taskbarx11.h"
14 #endif
15
16
17 // NB: This implementation does *not* work with every X11 window manager.
18 // Currently only GNOME 1.2 and KDE 1,2,3 methods are implemented.
19 //
20 // FIXME: implement:
21 // - GNOME 2 support (see www.freedesktop.org for specification;
22 // KDE 3 uses this method as well, even though legacy KDE
23 // method we implement works as well)
24 // - IceWM and XFCE support (?)
25 //
26 // Thanks to Ian Campbell, author of XMMS Status Docklet, for publishing
27 // KDE and GNOME 1.2 methods.
28
29
30 // For compilers that support precompilation, includes "wx.h".
31 #include "wx/wxprec.h"
32
33 #include "wx/taskbar.h"
34 #include "wx/frame.h"
35 #include "wx/bitmap.h"
36 #include "wx/statbmp.h"
37 #include "wx/sizer.h"
38
39 #ifdef __VMS
40 #pragma message disable nosimpint
41 #endif
42 #include <X11/Xlib.h>
43 #include <X11/Xatom.h>
44 #ifdef __VMS
45 #pragma message enable nosimpint
46 #endif
47
48 // ----------------------------------------------------------------------------
49 // toolkit dependent methods to set properties on helper window:
50 // ----------------------------------------------------------------------------
51
52 #if defined(__WXGTK__)
53 #include <gdk/gdk.h>
54 #include <gdk/gdkx.h>
55 #include <gtk/gtk.h>
56 #define GetDisplay() GDK_DISPLAY()
57 #define GetXWindow(wxwin) GDK_WINDOW_XWINDOW((wxwin)->m_widget->window)
58 #elif defined(__WXX11__) || defined(__WXMOTIF__)
59 #include "wx/x11/privx.h"
60 #define GetDisplay() ((Display*)wxGlobalDisplay())
61 #define GetXWindow(wxwin) ((Window)(wxwin)->GetHandle())
62 #else
63 #error "You must define X11 accessors for this port!"
64 #endif
65
66 // ----------------------------------------------------------------------------
67 // code for making wxFrame a toolbar icon by setting appropriate properties:
68 // ----------------------------------------------------------------------------
69
70 static bool wxMakeTaskBarIcon(wxFrame *wnd)
71 {
72 #ifdef __WXGTK__
73 gtk_widget_realize(wnd->m_widget);
74 #endif
75
76 long data[1];
77
78 // KDE 2 & KDE 3:
79 Atom _KDE_NET_WM_SYSTEM_TRAY_WINDOW_FOR =
80 XInternAtom(GetDisplay(), "_KDE_NET_WM_SYSTEM_TRAY_WINDOW_FOR", False);
81 data[0] = 0;
82 XChangeProperty(GetDisplay(), GetXWindow(wnd),
83 _KDE_NET_WM_SYSTEM_TRAY_WINDOW_FOR,
84 XA_WINDOW, 32,
85 PropModeReplace, (unsigned char*)data, 1);
86
87 // GNOME 1.2 & KDE 1:
88 Atom KWM_DOCKWINDOW =
89 XInternAtom(GetDisplay(), "KWM_DOCKWINDOW", False);
90 data[0] = 1;
91 XChangeProperty(GetDisplay(), GetXWindow(wnd),
92 KWM_DOCKWINDOW,
93 KWM_DOCKWINDOW, 32,
94 PropModeReplace, (unsigned char*)data, 1);
95
96 return true;
97 }
98
99 // ----------------------------------------------------------------------------
100 // wxTaskBarIconArea is the real window that shows the icon:
101 // ----------------------------------------------------------------------------
102
103 class wxTaskBarIconArea : public wxStaticBitmap
104 {
105 public:
106 wxTaskBarIconArea(wxTaskBarIcon *icon,
107 wxWindow *parent, const wxBitmap &bmp)
108 : wxStaticBitmap(parent, -1, bmp), m_icon(icon) {}
109
110 protected:
111 void OnMouseEvent(wxMouseEvent& event);
112 void OnMenuEvent(wxCommandEvent& event);
113
114 wxTaskBarIcon *m_icon;
115
116 DECLARE_EVENT_TABLE()
117 };
118
119 BEGIN_EVENT_TABLE(wxTaskBarIconArea, wxStaticBitmap)
120 EVT_MOUSE_EVENTS(wxTaskBarIconArea::OnMouseEvent)
121 EVT_MENU(-1, wxTaskBarIconArea::OnMenuEvent)
122 END_EVENT_TABLE()
123
124 void wxTaskBarIconArea::OnMouseEvent(wxMouseEvent& event)
125 {
126 wxEventType type = 0;
127 wxEventType mtype = event.GetEventType();
128
129 if (mtype == wxEVT_LEFT_DOWN)
130 type = wxEVT_TASKBAR_LEFT_DOWN;
131 else if (mtype == wxEVT_LEFT_UP)
132 type = wxEVT_TASKBAR_LEFT_UP;
133 else if (mtype == wxEVT_LEFT_DCLICK)
134 type = wxEVT_TASKBAR_LEFT_DCLICK;
135 else if (mtype == wxEVT_RIGHT_DOWN)
136 type = wxEVT_TASKBAR_RIGHT_DOWN;
137 else if (mtype == wxEVT_RIGHT_UP)
138 type = wxEVT_TASKBAR_RIGHT_UP;
139 else if (mtype == wxEVT_RIGHT_DCLICK)
140 type = wxEVT_TASKBAR_RIGHT_DCLICK;
141 else if (mtype == wxEVT_MOTION)
142 type = wxEVT_TASKBAR_MOVE;
143 else
144 return;
145
146 wxTaskBarIconEvent e(type, m_icon);
147 m_icon->ProcessEvent(e);
148 }
149
150 void wxTaskBarIconArea::OnMenuEvent(wxCommandEvent& event)
151 {
152 m_icon->ProcessEvent(event);
153 }
154
155 // ----------------------------------------------------------------------------
156 // wxTaskBarIcon class:
157 // ----------------------------------------------------------------------------
158
159 IMPLEMENT_DYNAMIC_CLASS(wxTaskBarIcon, wxEvtHandler)
160
161 wxTaskBarIcon::wxTaskBarIcon() : m_iconWnd(NULL)
162 {
163 }
164
165 wxTaskBarIcon::~wxTaskBarIcon()
166 {
167 if (m_iconWnd)
168 RemoveIcon();
169 }
170
171 bool wxTaskBarIcon::IsOk() const
172 {
173 return true;
174 }
175
176 bool wxTaskBarIcon::IsIconInstalled() const
177 {
178 return m_iconWnd != NULL;
179 }
180
181 bool wxTaskBarIcon::SetIcon(const wxIcon& icon, const wxString& tooltip)
182 {
183 if (m_iconWnd)
184 RemoveIcon();
185
186 m_iconWnd = new wxFrame(NULL, -1, wxT("taskbar icon"),
187 wxDefaultPosition, wxDefaultSize,
188 wxDEFAULT_FRAME_STYLE | wxFRAME_NO_TASKBAR);
189 wxBitmap bmp;
190 bmp.CopyFromIcon(icon);
191 wxTaskBarIconArea *area = new wxTaskBarIconArea(this, m_iconWnd, bmp);
192
193 // make a sizer to keep the icon centered, in case it is smaller than the
194 // alotted space.
195 wxBoxSizer* sizer = new wxBoxSizer(wxVERTICAL);
196 sizer->Add(0,0,1);
197 sizer->Add(area, 0, wxALIGN_CENTER);
198 sizer->Add(0,0,1);
199 m_iconWnd->SetSizer(sizer);
200
201 m_iconWnd->SetClientSize(area->GetSize());
202 #if wxUSE_TOOLTIPS
203 if (!tooltip.empty())
204 area->SetToolTip(tooltip);
205 #endif
206 if (wxMakeTaskBarIcon(m_iconWnd))
207 {
208 m_iconWnd->Show();
209 m_iconArea = area;
210 return true;
211 }
212 else
213 {
214 m_iconWnd->Destroy();
215 m_iconWnd = NULL;
216 return false;
217 }
218 }
219
220 bool wxTaskBarIcon::RemoveIcon()
221 {
222 if (!m_iconWnd)
223 return false;
224 m_iconWnd->Destroy();
225 m_iconWnd = NULL;
226 return true;
227 }
228
229 bool wxTaskBarIcon::PopupMenu(wxMenu *menu)
230 {
231 if (!m_iconWnd)
232 return false;
233 wxSize size(m_iconArea->GetSize());
234 m_iconArea->PopupMenu(menu, size.x/2, size.y/2);
235 return true;
236 }