Apple #pragma implementation fix (Yes, some of us do compile wxGTK on OS X)
[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(__APPLE__)
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
38 #ifdef __VMS
39 #pragma message disable nosimpint
40 #endif
41 #include <X11/Xlib.h>
42 #include <X11/Xatom.h>
43 #ifdef __VMS
44 #pragma message enable nosimpint
45 #endif
46
47 // ----------------------------------------------------------------------------
48 // toolkit dependent methods to set properties on helper window:
49 // ----------------------------------------------------------------------------
50
51 #if defined(__WXGTK__)
52 #include <gdk/gdk.h>
53 #include <gdk/gdkx.h>
54 #include <gtk/gtk.h>
55 #define GetDisplay() GDK_DISPLAY()
56 #define GetXWindow(wxwin) GDK_WINDOW_XWINDOW((wxwin)->m_widget->window)
57 #elif defined(__WXX11__) || defined(__WXMOTIF__)
58 #include "wx/x11/privx.h"
59 #define GetDisplay() ((Display*)wxGlobalDisplay())
60 #define GetXWindow(wxwin) ((Window)(wxwin)->GetHandle())
61 #else
62 #error "You must define X11 accessors for this port!"
63 #endif
64
65 // ----------------------------------------------------------------------------
66 // code for making wxFrame a toolbar icon by setting appropriate properties:
67 // ----------------------------------------------------------------------------
68
69 static bool wxMakeTaskBarIcon(wxFrame *wnd)
70 {
71 #ifdef __WXGTK__
72 gtk_widget_realize(wnd->m_widget);
73 #endif
74
75 long data[1];
76
77 // KDE 2 & KDE 3:
78 Atom _KDE_NET_WM_SYSTEM_TRAY_WINDOW_FOR =
79 XInternAtom(GetDisplay(), "_KDE_NET_WM_SYSTEM_TRAY_WINDOW_FOR", False);
80 data[0] = 0;
81 XChangeProperty(GetDisplay(), GetXWindow(wnd),
82 _KDE_NET_WM_SYSTEM_TRAY_WINDOW_FOR,
83 XA_WINDOW, 32,
84 PropModeReplace, (unsigned char*)data, 1);
85
86 // GNOME 1.2 & KDE 1:
87 Atom KWM_DOCKWINDOW =
88 XInternAtom(GetDisplay(), "KWM_DOCKWINDOW", False);
89 data[0] = 1;
90 XChangeProperty(GetDisplay(), GetXWindow(wnd),
91 KWM_DOCKWINDOW,
92 KWM_DOCKWINDOW, 32,
93 PropModeReplace, (unsigned char*)data, 1);
94
95 return true;
96 }
97
98 // ----------------------------------------------------------------------------
99 // wxTaskBarIconArea is the real window that shows the icon:
100 // ----------------------------------------------------------------------------
101
102 class wxTaskBarIconArea : public wxStaticBitmap
103 {
104 public:
105 wxTaskBarIconArea(wxTaskBarIcon *icon,
106 wxWindow *parent, const wxBitmap &bmp)
107 : wxStaticBitmap(parent, -1, bmp), m_icon(icon) {}
108
109 protected:
110 void OnMouseEvent(wxMouseEvent& event);
111 void OnMenuEvent(wxCommandEvent& event);
112
113 wxTaskBarIcon *m_icon;
114
115 DECLARE_EVENT_TABLE()
116 };
117
118 BEGIN_EVENT_TABLE(wxTaskBarIconArea, wxStaticBitmap)
119 EVT_MOUSE_EVENTS(wxTaskBarIconArea::OnMouseEvent)
120 EVT_MENU(-1, wxTaskBarIconArea::OnMenuEvent)
121 END_EVENT_TABLE()
122
123 void wxTaskBarIconArea::OnMouseEvent(wxMouseEvent& event)
124 {
125 wxEventType type = 0;
126 wxEventType mtype = event.GetEventType();
127
128 if (mtype == wxEVT_LEFT_DOWN)
129 type = wxEVT_TASKBAR_LEFT_DOWN;
130 else if (mtype == wxEVT_LEFT_UP)
131 type = wxEVT_TASKBAR_LEFT_UP;
132 else if (mtype == wxEVT_LEFT_DCLICK)
133 type = wxEVT_TASKBAR_LEFT_DCLICK;
134 else if (mtype == wxEVT_RIGHT_DOWN)
135 type = wxEVT_TASKBAR_RIGHT_DOWN;
136 else if (mtype == wxEVT_RIGHT_UP)
137 type = wxEVT_TASKBAR_RIGHT_UP;
138 else if (mtype == wxEVT_RIGHT_DCLICK)
139 type = wxEVT_TASKBAR_RIGHT_DCLICK;
140 else if (mtype == wxEVT_MOTION)
141 type = wxEVT_TASKBAR_MOVE;
142 else
143 return;
144
145 wxTaskBarIconEvent e(type, m_icon);
146 m_icon->ProcessEvent(e);
147 }
148
149 void wxTaskBarIconArea::OnMenuEvent(wxCommandEvent& event)
150 {
151 m_icon->ProcessEvent(event);
152 }
153
154 // ----------------------------------------------------------------------------
155 // wxTaskBarIcon class:
156 // ----------------------------------------------------------------------------
157
158 IMPLEMENT_DYNAMIC_CLASS(wxTaskBarIcon, wxEvtHandler)
159
160 wxTaskBarIcon::wxTaskBarIcon() : m_iconWnd(NULL)
161 {
162 }
163
164 wxTaskBarIcon::~wxTaskBarIcon()
165 {
166 if (m_iconWnd)
167 RemoveIcon();
168 }
169
170 bool wxTaskBarIcon::IsOk() const
171 {
172 return true;
173 }
174
175 bool wxTaskBarIcon::IsIconInstalled() const
176 {
177 return m_iconWnd != NULL;
178 }
179
180 bool wxTaskBarIcon::SetIcon(const wxIcon& icon, const wxString& tooltip)
181 {
182 if (m_iconWnd)
183 RemoveIcon();
184
185 m_iconWnd = new wxFrame(NULL, -1, wxT("taskbar icon"),
186 wxDefaultPosition, wxDefaultSize,
187 wxDEFAULT_FRAME_STYLE | wxFRAME_NO_TASKBAR);
188 wxBitmap bmp;
189 bmp.CopyFromIcon(icon);
190 wxTaskBarIconArea *area = new wxTaskBarIconArea(this, m_iconWnd, bmp);
191 m_iconWnd->SetClientSize(area->GetSize());
192 #if wxUSE_TOOLTIPS
193 if (!tooltip.empty())
194 area->SetToolTip(tooltip);
195 #endif
196 if (wxMakeTaskBarIcon(m_iconWnd))
197 {
198 m_iconWnd->Show();
199 m_iconArea = area;
200 return true;
201 }
202 else
203 {
204 m_iconWnd->Destroy();
205 m_iconWnd = NULL;
206 return false;
207 }
208 }
209
210 bool wxTaskBarIcon::RemoveIcon()
211 {
212 if (!m_iconWnd)
213 return false;
214 m_iconWnd->Destroy();
215 m_iconWnd = NULL;
216 return true;
217 }
218
219 bool wxTaskBarIcon::PopupMenu(wxMenu *menu)
220 {
221 if (!m_iconWnd)
222 return false;
223 wxSize size(m_iconArea->GetSize());
224 m_iconArea->PopupMenu(menu, size.x/2, size.y/2);
225 return true;
226 }