]> git.saurik.com Git - wxWidgets.git/blame - src/unix/taskbarx11.cpp
Do not check for Xinerama when building wxCocoa
[wxWidgets.git] / src / unix / taskbarx11.cpp
CommitLineData
fb29dcac
VS
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
65571936 9// Licence: wxWindows licence
fb29dcac
VS
10/////////////////////////////////////////////////////////////////////////
11
14f355c2 12#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
fb29dcac
VS
13#pragma implementation "taskbarx11.h"
14#endif
15
fb29dcac 16// NB: This implementation does *not* work with every X11 window manager.
33d4eef0
VS
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.
fb29dcac
VS
20//
21// Thanks to Ian Campbell, author of XMMS Status Docklet, for publishing
22// KDE and GNOME 1.2 methods.
23
24
25// For compilers that support precompilation, includes "wx.h".
26#include "wx/wxprec.h"
27
28#include "wx/taskbar.h"
29#include "wx/frame.h"
30#include "wx/bitmap.h"
31#include "wx/statbmp.h"
71a0c62f 32#include "wx/sizer.h"
ac258944 33#include "wx/dcclient.h"
33d4eef0 34#include "wx/log.h"
fb29dcac
VS
35
36#ifdef __VMS
37#pragma message disable nosimpint
38#endif
39#include <X11/Xlib.h>
40#include <X11/Xatom.h>
41#ifdef __VMS
42#pragma message enable nosimpint
43#endif
44
33d4eef0
VS
45// ----------------------------------------------------------------------------
46// base class that implements toolkit-specific method:
47// ----------------------------------------------------------------------------
48
49#ifdef __WXGTK20__
50 #include "wx/gtk/taskbarpriv.h"
51#else
52 class WXDLLIMPEXP_ADV wxTaskBarIconAreaBase : public wxFrame
53 {
54 public:
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) {}
60
61 bool IsProtocolSupported() const { return false; }
62 };
63#endif
64
65
fb29dcac
VS
66// ----------------------------------------------------------------------------
67// toolkit dependent methods to set properties on helper window:
68// ----------------------------------------------------------------------------
69
70#if defined(__WXGTK__)
71 #include <gdk/gdk.h>
72 #include <gdk/gdkx.h>
73 #include <gtk/gtk.h>
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())
80#else
81 #error "You must define X11 accessors for this port!"
82#endif
83
ac258944 84
fb29dcac 85// ----------------------------------------------------------------------------
ac258944 86// wxTaskBarIconArea is the real window that shows the icon:
fb29dcac
VS
87// ----------------------------------------------------------------------------
88
33d4eef0 89class WXDLLIMPEXP_ADV wxTaskBarIconArea : public wxTaskBarIconAreaBase
ac258944
VS
90{
91public:
33d4eef0
VS
92 wxTaskBarIconArea(wxTaskBarIcon *icon, const wxBitmap &bmp);
93 void SetTrayIcon(const wxBitmap& bmp);
ac258944
VS
94 bool IsOk() { return true; }
95
96protected:
33d4eef0 97 void SetLegacyWMProperties();
ac258944 98
33d4eef0 99 void OnSizeChange(wxSizeEvent& event);
ac258944 100 void OnPaint(wxPaintEvent& evt);
ac258944
VS
101 void OnMouseEvent(wxMouseEvent& event);
102 void OnMenuEvent(wxCommandEvent& event);
103
104 wxTaskBarIcon *m_icon;
33d4eef0
VS
105 wxPoint m_pos;
106 wxBitmap m_bmp;
ac258944
VS
107
108 DECLARE_EVENT_TABLE()
109};
110
33d4eef0
VS
111BEGIN_EVENT_TABLE(wxTaskBarIconArea, wxTaskBarIconAreaBase)
112 EVT_SIZE(wxTaskBarIconArea::OnSizeChange)
ac258944
VS
113 EVT_MOUSE_EVENTS(wxTaskBarIconArea::OnMouseEvent)
114 EVT_MENU(-1, wxTaskBarIconArea::OnMenuEvent)
115 EVT_PAINT(wxTaskBarIconArea::OnPaint)
ac258944 116END_EVENT_TABLE()
33d4eef0
VS
117
118wxTaskBarIconArea::wxTaskBarIconArea(wxTaskBarIcon *icon, const wxBitmap &bmp)
119 : wxTaskBarIconAreaBase(), m_icon(icon), m_pos(0,0)
120{
121 if (!IsProtocolSupported())
122 {
123 wxLogTrace(_T("systray"),
124 _T("using legacy KDE1,2 and GNOME 1.2 methods"));
125 SetLegacyWMProperties();
126 }
127
128 // Set initial size to bitmap size (tray manager may and often will
129 // change it):
130 SetSize(wxSize(bmp.GetWidth(), bmp.GetHeight()));
131
132 SetTrayIcon(bmp);
133}
134
135void wxTaskBarIconArea::SetTrayIcon(const wxBitmap& bmp)
136{
137 m_bmp = bmp;
138
139 // determine suitable bitmap size:
140 wxSize winsize(GetSize());
141 wxSize bmpsize(m_bmp.GetWidth(), m_bmp.GetHeight());
eb03e0e7 142 wxSize iconsize(wxMin(winsize.x-2, bmpsize.x), wxMin(winsize.y-2, bmpsize.y));
33d4eef0
VS
143
144 // rescale the bitmap to fit into the tray icon window:
145 if (bmpsize != iconsize)
146 {
147 wxImage img = m_bmp.ConvertToImage();
148 img.Rescale(iconsize.x, iconsize.y);
149 m_bmp = wxBitmap(img);
150 }
ac258944 151
eb03e0e7
RD
152 wxRegion region;
153 if (m_bmp.GetMask())
154 region.Union(m_bmp);
155 else
156 region.Union(0,0, iconsize.x, iconsize.y);
33d4eef0
VS
157
158 // if the bitmap is smaller than the window, offset it:
159 if (winsize != iconsize)
160 {
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);
164 }
165
166 // set frame's shape to correct value and redraw:
167 SetShape(region);
168 Refresh();
169}
170
171void wxTaskBarIconArea::SetLegacyWMProperties()
fb29dcac
VS
172{
173#ifdef __WXGTK__
ac258944 174 gtk_widget_realize(m_widget);
fb29dcac
VS
175#endif
176
177 long data[1];
178
179 // KDE 2 & KDE 3:
180 Atom _KDE_NET_WM_SYSTEM_TRAY_WINDOW_FOR =
181 XInternAtom(GetDisplay(), "_KDE_NET_WM_SYSTEM_TRAY_WINDOW_FOR", False);
182 data[0] = 0;
ac258944 183 XChangeProperty(GetDisplay(), GetXWindow(this),
fb29dcac
VS
184 _KDE_NET_WM_SYSTEM_TRAY_WINDOW_FOR,
185 XA_WINDOW, 32,
186 PropModeReplace, (unsigned char*)data, 1);
187
188 // GNOME 1.2 & KDE 1:
189 Atom KWM_DOCKWINDOW =
190 XInternAtom(GetDisplay(), "KWM_DOCKWINDOW", False);
191 data[0] = 1;
ac258944 192 XChangeProperty(GetDisplay(), GetXWindow(this),
fb29dcac
VS
193 KWM_DOCKWINDOW,
194 KWM_DOCKWINDOW, 32,
195 PropModeReplace, (unsigned char*)data, 1);
fb29dcac
VS
196}
197
33d4eef0 198void wxTaskBarIconArea::OnSizeChange(wxSizeEvent& event)
fb29dcac 199{
33d4eef0
VS
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:
203 wxBitmap bmp(m_bmp);
204 SetTrayIcon(bmp);
ac258944 205}
fb29dcac 206
ac258944
VS
207void wxTaskBarIconArea::OnPaint(wxPaintEvent& WXUNUSED(event))
208{
209 wxPaintDC dc(this);
33d4eef0 210 dc.DrawBitmap(m_bmp, m_pos.x, m_pos.y, true);
ac258944 211}
fb29dcac
VS
212
213void wxTaskBarIconArea::OnMouseEvent(wxMouseEvent& event)
214{
215 wxEventType type = 0;
216 wxEventType mtype = event.GetEventType();
33d4eef0 217
fb29dcac
VS
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;
232 else
233 return;
234
235 wxTaskBarIconEvent e(type, m_icon);
236 m_icon->ProcessEvent(e);
237}
238
239void wxTaskBarIconArea::OnMenuEvent(wxCommandEvent& event)
240{
241 m_icon->ProcessEvent(event);
242}
243
244// ----------------------------------------------------------------------------
245// wxTaskBarIcon class:
246// ----------------------------------------------------------------------------
247
248IMPLEMENT_DYNAMIC_CLASS(wxTaskBarIcon, wxEvtHandler)
249
250wxTaskBarIcon::wxTaskBarIcon() : m_iconWnd(NULL)
251{
252}
253
254wxTaskBarIcon::~wxTaskBarIcon()
255{
256 if (m_iconWnd)
257 RemoveIcon();
258}
259
260bool wxTaskBarIcon::IsOk() const
261{
262 return true;
263}
264
265bool wxTaskBarIcon::IsIconInstalled() const
266{
267 return m_iconWnd != NULL;
268}
269
270bool wxTaskBarIcon::SetIcon(const wxIcon& icon, const wxString& tooltip)
271{
fb29dcac
VS
272 wxBitmap bmp;
273 bmp.CopyFromIcon(icon);
ac258944 274
33d4eef0 275 if (!m_iconWnd)
fb29dcac 276 {
33d4eef0
VS
277 m_iconWnd = new wxTaskBarIconArea(this, bmp);
278 if (m_iconWnd->IsOk())
279 {
280 m_iconWnd->Show();
281 }
282 else
283 {
284 m_iconWnd->Destroy();
285 m_iconWnd = NULL;
286 return false;
287 }
fb29dcac
VS
288 }
289 else
290 {
33d4eef0
VS
291 m_iconWnd->SetTrayIcon(bmp);
292 }
293
294#if wxUSE_TOOLTIPS
295 if (!tooltip.empty())
296 m_iconWnd->SetToolTip(tooltip);
297 else
298 m_iconWnd->SetToolTip(NULL);
299#endif
300 return true;
fb29dcac
VS
301}
302
303bool wxTaskBarIcon::RemoveIcon()
304{
305 if (!m_iconWnd)
306 return false;
307 m_iconWnd->Destroy();
308 m_iconWnd = NULL;
309 return true;
310}
311
312bool wxTaskBarIcon::PopupMenu(wxMenu *menu)
313{
314 if (!m_iconWnd)
315 return false;
ac258944
VS
316 wxSize size(m_iconWnd->GetClientSize());
317 m_iconWnd->PopupMenu(menu, size.x/2, size.y/2);
fb29dcac
VS
318 return true;
319}