use shaped window for taskbar icon, so that background shows correctly behind icons with mask

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@27505 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Václav Slavík
2004-05-29 17:01:57 +00:00
parent a98ca1ae26
commit ac258944bc
2 changed files with 65 additions and 52 deletions

View File

@@ -20,7 +20,9 @@ class WXDLLEXPORT wxIcon;
class WXDLLEXPORT wxFrame; class WXDLLEXPORT wxFrame;
class WXDLLEXPORT wxWindow; class WXDLLEXPORT wxWindow;
class WXDLLEXPORT wxTaskBarIcon: public wxTaskBarIconBase class WXDLLIMPEXP_ADV wxTaskBarIconArea;
class WXDLLIMPEXP_ADV wxTaskBarIcon: public wxTaskBarIconBase
{ {
public: public:
wxTaskBarIcon(); wxTaskBarIcon();
@@ -36,8 +38,7 @@ public:
bool PopupMenu(wxMenu *menu); bool PopupMenu(wxMenu *menu);
protected: protected:
wxFrame *m_iconWnd; wxTaskBarIconArea *m_iconWnd;
wxWindow *m_iconArea;
DECLARE_DYNAMIC_CLASS(wxTaskBarIcon) DECLARE_DYNAMIC_CLASS(wxTaskBarIcon)
}; };

View File

@@ -13,7 +13,6 @@
#pragma implementation "taskbarx11.h" #pragma implementation "taskbarx11.h"
#endif #endif
// NB: This implementation does *not* work with every X11 window manager. // NB: This implementation does *not* work with every X11 window manager.
// Currently only GNOME 1.2 and KDE 1,2,3 methods are implemented. // Currently only GNOME 1.2 and KDE 1,2,3 methods are implemented.
// //
@@ -21,7 +20,7 @@
// - GNOME 2 support (see www.freedesktop.org for specification; // - GNOME 2 support (see www.freedesktop.org for specification;
// KDE 3 uses this method as well, even though legacy KDE // KDE 3 uses this method as well, even though legacy KDE
// method we implement works as well) // method we implement works as well)
// - IceWM and XFCE support (?) // - IceWM support (?)
// //
// Thanks to Ian Campbell, author of XMMS Status Docklet, for publishing // Thanks to Ian Campbell, author of XMMS Status Docklet, for publishing
// KDE and GNOME 1.2 methods. // KDE and GNOME 1.2 methods.
@@ -35,6 +34,7 @@
#include "wx/bitmap.h" #include "wx/bitmap.h"
#include "wx/statbmp.h" #include "wx/statbmp.h"
#include "wx/sizer.h" #include "wx/sizer.h"
#include "wx/dcclient.h"
#ifdef __VMS #ifdef __VMS
#pragma message disable nosimpint #pragma message disable nosimpint
@@ -63,14 +63,54 @@
#error "You must define X11 accessors for this port!" #error "You must define X11 accessors for this port!"
#endif #endif
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// code for making wxFrame a toolbar icon by setting appropriate properties: // wxTaskBarIconArea is the real window that shows the icon:
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
static bool wxMakeTaskBarIcon(wxFrame *wnd) class WXDLLIMPEXP_ADV wxTaskBarIconArea : public wxFrame
{
public:
wxTaskBarIconArea(wxTaskBarIcon *icon, const wxBitmap &bmp)
: wxFrame(NULL, -1, wxT("taskbar icon"),
wxDefaultPosition, wxDefaultSize,
wxDEFAULT_FRAME_STYLE | wxFRAME_NO_TASKBAR |
wxSIMPLE_BORDER | wxFRAME_SHAPED),
m_icon(icon), m_bmp(bmp)
{
SetWMProperties();
SetSize(wxSize(bmp.GetWidth(), bmp.GetHeight()));
}
bool IsOk() { return true; }
protected:
void SetWMProperties();
void OnPaint(wxPaintEvent& evt);
void OnWindowCreate(wxWindowCreateEvent& event);
void OnMouseEvent(wxMouseEvent& event);
void OnMenuEvent(wxCommandEvent& event);
wxTaskBarIcon *m_icon;
wxBitmap m_bmp;
DECLARE_EVENT_TABLE()
};
BEGIN_EVENT_TABLE(wxTaskBarIconArea, wxFrame)
EVT_MOUSE_EVENTS(wxTaskBarIconArea::OnMouseEvent)
EVT_MENU(-1, wxTaskBarIconArea::OnMenuEvent)
EVT_PAINT(wxTaskBarIconArea::OnPaint)
#ifdef __WXGTK__
EVT_WINDOW_CREATE(wxTaskBarIconArea::OnWindowCreate)
#endif
END_EVENT_TABLE()
void wxTaskBarIconArea::SetWMProperties()
{ {
#ifdef __WXGTK__ #ifdef __WXGTK__
gtk_widget_realize(wnd->m_widget); gtk_widget_realize(m_widget);
#endif #endif
long data[1]; long data[1];
@@ -79,7 +119,7 @@ static bool wxMakeTaskBarIcon(wxFrame *wnd)
Atom _KDE_NET_WM_SYSTEM_TRAY_WINDOW_FOR = Atom _KDE_NET_WM_SYSTEM_TRAY_WINDOW_FOR =
XInternAtom(GetDisplay(), "_KDE_NET_WM_SYSTEM_TRAY_WINDOW_FOR", False); XInternAtom(GetDisplay(), "_KDE_NET_WM_SYSTEM_TRAY_WINDOW_FOR", False);
data[0] = 0; data[0] = 0;
XChangeProperty(GetDisplay(), GetXWindow(wnd), XChangeProperty(GetDisplay(), GetXWindow(this),
_KDE_NET_WM_SYSTEM_TRAY_WINDOW_FOR, _KDE_NET_WM_SYSTEM_TRAY_WINDOW_FOR,
XA_WINDOW, 32, XA_WINDOW, 32,
PropModeReplace, (unsigned char*)data, 1); PropModeReplace, (unsigned char*)data, 1);
@@ -88,38 +128,22 @@ static bool wxMakeTaskBarIcon(wxFrame *wnd)
Atom KWM_DOCKWINDOW = Atom KWM_DOCKWINDOW =
XInternAtom(GetDisplay(), "KWM_DOCKWINDOW", False); XInternAtom(GetDisplay(), "KWM_DOCKWINDOW", False);
data[0] = 1; data[0] = 1;
XChangeProperty(GetDisplay(), GetXWindow(wnd), XChangeProperty(GetDisplay(), GetXWindow(this),
KWM_DOCKWINDOW, KWM_DOCKWINDOW,
KWM_DOCKWINDOW, 32, KWM_DOCKWINDOW, 32,
PropModeReplace, (unsigned char*)data, 1); PropModeReplace, (unsigned char*)data, 1);
return true;
} }
// ---------------------------------------------------------------------------- void wxTaskBarIconArea::OnWindowCreate(wxWindowCreateEvent& WXUNUSED(event))
// wxTaskBarIconArea is the real window that shows the icon:
// ----------------------------------------------------------------------------
class wxTaskBarIconArea : public wxStaticBitmap
{ {
public: SetShape(wxRegion(m_bmp));
wxTaskBarIconArea(wxTaskBarIcon *icon, }
wxWindow *parent, const wxBitmap &bmp)
: wxStaticBitmap(parent, -1, bmp), m_icon(icon) {}
protected: void wxTaskBarIconArea::OnPaint(wxPaintEvent& WXUNUSED(event))
void OnMouseEvent(wxMouseEvent& event); {
void OnMenuEvent(wxCommandEvent& event); wxPaintDC dc(this);
dc.DrawBitmap(m_bmp, 0, 0, true);
wxTaskBarIcon *m_icon; }
DECLARE_EVENT_TABLE()
};
BEGIN_EVENT_TABLE(wxTaskBarIconArea, wxStaticBitmap)
EVT_MOUSE_EVENTS(wxTaskBarIconArea::OnMouseEvent)
EVT_MENU(-1, wxTaskBarIconArea::OnMenuEvent)
END_EVENT_TABLE()
void wxTaskBarIconArea::OnMouseEvent(wxMouseEvent& event) void wxTaskBarIconArea::OnMouseEvent(wxMouseEvent& event)
{ {
@@ -183,30 +207,18 @@ bool wxTaskBarIcon::SetIcon(const wxIcon& icon, const wxString& tooltip)
if (m_iconWnd) if (m_iconWnd)
RemoveIcon(); RemoveIcon();
m_iconWnd = new wxFrame(NULL, -1, wxT("taskbar icon"),
wxDefaultPosition, wxDefaultSize,
wxDEFAULT_FRAME_STYLE | wxFRAME_NO_TASKBAR);
wxBitmap bmp; wxBitmap bmp;
bmp.CopyFromIcon(icon); bmp.CopyFromIcon(icon);
wxTaskBarIconArea *area = new wxTaskBarIconArea(this, m_iconWnd, bmp);
// make a sizer to keep the icon centered, in case it is smaller than the m_iconWnd = new wxTaskBarIconArea(this, bmp);
// alotted space.
wxBoxSizer* sizer = new wxBoxSizer(wxVERTICAL);
sizer->Add(0,0,1);
sizer->Add(area, 0, wxALIGN_CENTER);
sizer->Add(0,0,1);
m_iconWnd->SetSizer(sizer);
m_iconWnd->SetClientSize(area->GetSize());
#if wxUSE_TOOLTIPS #if wxUSE_TOOLTIPS
if (!tooltip.empty()) if (!tooltip.empty())
area->SetToolTip(tooltip); m_iconWnd->SetToolTip(tooltip);
#endif #endif
if (wxMakeTaskBarIcon(m_iconWnd)) if (m_iconWnd->IsOk())
{ {
m_iconWnd->Show(); m_iconWnd->Show();
m_iconArea = area;
return true; return true;
} }
else else
@@ -230,7 +242,7 @@ bool wxTaskBarIcon::PopupMenu(wxMenu *menu)
{ {
if (!m_iconWnd) if (!m_iconWnd)
return false; return false;
wxSize size(m_iconArea->GetSize()); wxSize size(m_iconWnd->GetClientSize());
m_iconArea->PopupMenu(menu, size.x/2, size.y/2); m_iconWnd->PopupMenu(menu, size.x/2, size.y/2);
return true; return true;
} }