X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/0304adb195d7f41a54dcf35e4d440bf12201ab32..5abc0d2197b49d0ede5aac71c08c2fd693e56498:/src/unix/taskbarx11.cpp diff --git a/src/unix/taskbarx11.cpp b/src/unix/taskbarx11.cpp index cf94b21583..3b4ffeea54 100644 --- a/src/unix/taskbarx11.cpp +++ b/src/unix/taskbarx11.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// File: taskbar.cpp +// File: src/unix/taskbarx11.cpp // Purpose: wxTaskBarIcon class for common Unix desktops // Author: Vaclav Slavik // Modified by: @@ -9,10 +9,6 @@ // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////// -#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) -#pragma implementation "taskbarx11.h" -#endif - // NB: This implementation does *not* work with every X11 window manager. // Currently only GNOME 1.2 and KDE 1,2,3 methods are implemented here. // Freedesktop.org's System Tray specification is implemented in @@ -25,14 +21,19 @@ // For compilers that support precompilation, includes "wx.h". #include "wx/wxprec.h" +#if wxUSE_TASKBARICON && !defined(__WXGTK20__) + #include "wx/taskbar.h" -#include "wx/frame.h" -#include "wx/bitmap.h" -#include "wx/statbmp.h" -#include "wx/sizer.h" -#include "wx/dcclient.h" -#include "wx/log.h" -#include "wx/image.h" + +#ifndef WX_PRECOMP + #include "wx/log.h" + #include "wx/frame.h" + #include "wx/dcclient.h" + #include "wx/statbmp.h" + #include "wx/sizer.h" + #include "wx/bitmap.h" + #include "wx/image.h" +#endif #ifdef __VMS #pragma message disable nosimpint @@ -47,37 +48,25 @@ // base class that implements toolkit-specific method: // ---------------------------------------------------------------------------- -#ifdef __WXGTK20__ - #include - #if GTK_CHECK_VERSION(2,1,0) - #include "wx/gtk/taskbarpriv.h" - #define TASKBAR_ICON_AREA_BASE_INCLUDED - #endif -#endif - -#ifndef TASKBAR_ICON_AREA_BASE_INCLUDED class WXDLLIMPEXP_ADV wxTaskBarIconAreaBase : public wxFrame { public: wxTaskBarIconAreaBase() - : wxFrame(NULL, wxID_ANY, _T("systray icon"), + : wxFrame(NULL, wxID_ANY, wxT("systray icon"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_STYLE | wxFRAME_NO_TASKBAR | wxSIMPLE_BORDER | wxFRAME_SHAPED) {} - bool IsProtocolSupported() const { return false; } + static bool IsProtocolSupported() { return false; } }; -#endif - // ---------------------------------------------------------------------------- // toolkit dependent methods to set properties on helper window: // ---------------------------------------------------------------------------- #if defined(__WXGTK__) - #include - #include #include + #include #define GetDisplay() GDK_DISPLAY() #define GetXWindow(wxwin) GDK_WINDOW_XWINDOW((wxwin)->m_widget->window) #elif defined(__WXX11__) || defined(__WXMOTIF__) @@ -88,7 +77,7 @@ #error "You must define X11 accessors for this port!" #endif - + // ---------------------------------------------------------------------------- // wxTaskBarIconArea is the real window that shows the icon: // ---------------------------------------------------------------------------- @@ -99,10 +88,10 @@ public: wxTaskBarIconArea(wxTaskBarIcon *icon, const wxBitmap &bmp); void SetTrayIcon(const wxBitmap& bmp); bool IsOk() { return true; } - + protected: void SetLegacyWMProperties(); - + void OnSizeChange(wxSizeEvent& event); void OnPaint(wxPaintEvent& evt); void OnMouseEvent(wxMouseEvent& event); @@ -111,40 +100,40 @@ protected: wxTaskBarIcon *m_icon; wxPoint m_pos; wxBitmap m_bmp; - + DECLARE_EVENT_TABLE() }; BEGIN_EVENT_TABLE(wxTaskBarIconArea, wxTaskBarIconAreaBase) EVT_SIZE(wxTaskBarIconArea::OnSizeChange) EVT_MOUSE_EVENTS(wxTaskBarIconArea::OnMouseEvent) - EVT_MENU(-1, wxTaskBarIconArea::OnMenuEvent) + EVT_MENU(wxID_ANY, wxTaskBarIconArea::OnMenuEvent) EVT_PAINT(wxTaskBarIconArea::OnPaint) END_EVENT_TABLE() - + wxTaskBarIconArea::wxTaskBarIconArea(wxTaskBarIcon *icon, const wxBitmap &bmp) - : wxTaskBarIconAreaBase(), m_icon(icon), m_pos(0,0) + : wxTaskBarIconAreaBase(), m_icon(icon), m_bmp(bmp) { + // Set initial size to bitmap size (tray manager may and often will + // change it): + SetClientSize(wxSize(bmp.GetWidth(), bmp.GetHeight())); + + SetTrayIcon(bmp); + if (!IsProtocolSupported()) { - wxLogTrace(_T("systray"), - _T("using legacy KDE1,2 and GNOME 1.2 methods")); + wxLogTrace(wxT("systray"), + wxT("using legacy KDE1,2 and GNOME 1.2 methods")); SetLegacyWMProperties(); } - - // Set initial size to bitmap size (tray manager may and often will - // change it): - SetSize(wxSize(bmp.GetWidth(), bmp.GetHeight())); - - SetTrayIcon(bmp); } void wxTaskBarIconArea::SetTrayIcon(const wxBitmap& bmp) { m_bmp = bmp; - + // determine suitable bitmap size: - wxSize winsize(GetSize()); + wxSize winsize(GetClientSize()); wxSize bmpsize(m_bmp.GetWidth(), m_bmp.GetHeight()); wxSize iconsize(wxMin(winsize.x, bmpsize.x), wxMin(winsize.y, bmpsize.y)); @@ -173,13 +162,13 @@ void wxTaskBarIconArea::SetTrayIcon(const wxBitmap& bmp) } void wxTaskBarIconArea::SetLegacyWMProperties() -{ +{ #ifdef __WXGTK__ gtk_widget_realize(m_widget); #endif - + long data[1]; - + // KDE 2 & KDE 3: Atom _KDE_NET_WM_SYSTEM_TRAY_WINDOW_FOR = XInternAtom(GetDisplay(), "_KDE_NET_WM_SYSTEM_TRAY_WINDOW_FOR", False); @@ -198,10 +187,10 @@ void wxTaskBarIconArea::SetLegacyWMProperties() KWM_DOCKWINDOW, 32, PropModeReplace, (unsigned char*)data, 1); } - -void wxTaskBarIconArea::OnSizeChange(wxSizeEvent& event) + +void wxTaskBarIconArea::OnSizeChange(wxSizeEvent& WXUNUSED(event)) { - wxLogTrace(_T("systray"), _T("icon size changed to %i x %i"), + wxLogTrace(wxT("systray"), wxT("icon size changed to %i x %i"), GetSize().x, GetSize().y); // rescale or reposition the icon as needed: wxBitmap bmp(m_bmp); @@ -213,7 +202,7 @@ void wxTaskBarIconArea::OnPaint(wxPaintEvent& WXUNUSED(event)) wxPaintDC dc(this); dc.DrawBitmap(m_bmp, m_pos.x, m_pos.y, true); } - + void wxTaskBarIconArea::OnMouseEvent(wxMouseEvent& event) { wxEventType type = 0; @@ -241,10 +230,19 @@ void wxTaskBarIconArea::OnMouseEvent(wxMouseEvent& event) } void wxTaskBarIconArea::OnMenuEvent(wxCommandEvent& event) -{ +{ m_icon->ProcessEvent(event); } +// ---------------------------------------------------------------------------- +// wxTaskBarIconBase class: +// ---------------------------------------------------------------------------- + +bool wxTaskBarIconBase::IsAvailable() +{ + return wxTaskBarIconArea::IsProtocolSupported(); +} + // ---------------------------------------------------------------------------- // wxTaskBarIcon class: // ---------------------------------------------------------------------------- @@ -258,7 +256,11 @@ wxTaskBarIcon::wxTaskBarIcon() : m_iconWnd(NULL) wxTaskBarIcon::~wxTaskBarIcon() { if (m_iconWnd) + { + m_iconWnd->Disconnect(wxEVT_DESTROY, + wxWindowDestroyEventHandler(wxTaskBarIcon::OnDestroy), NULL, this); RemoveIcon(); + } } bool wxTaskBarIcon::IsOk() const @@ -271,6 +273,14 @@ bool wxTaskBarIcon::IsIconInstalled() const return m_iconWnd != NULL; } +// Destroy event from wxTaskBarIconArea +void wxTaskBarIcon::OnDestroy(wxWindowDestroyEvent&) +{ + // prevent crash if wxTaskBarIconArea is destroyed by something else, + // for example if panel/kicker is killed + m_iconWnd = NULL; +} + bool wxTaskBarIcon::SetIcon(const wxIcon& icon, const wxString& tooltip) { wxBitmap bmp; @@ -281,6 +291,9 @@ bool wxTaskBarIcon::SetIcon(const wxIcon& icon, const wxString& tooltip) m_iconWnd = new wxTaskBarIconArea(this, bmp); if (m_iconWnd->IsOk()) { + m_iconWnd->Connect(wxEVT_DESTROY, + wxWindowDestroyEventHandler(wxTaskBarIcon::OnDestroy), + NULL, this); m_iconWnd->Show(); } else @@ -293,13 +306,15 @@ bool wxTaskBarIcon::SetIcon(const wxIcon& icon, const wxString& tooltip) else { m_iconWnd->SetTrayIcon(bmp); - } - + } + #if wxUSE_TOOLTIPS if (!tooltip.empty()) m_iconWnd->SetToolTip(tooltip); else m_iconWnd->SetToolTip(NULL); +#else + wxUnusedVar(tooltip); #endif return true; } @@ -320,3 +335,5 @@ bool wxTaskBarIcon::PopupMenu(wxMenu *menu) m_iconWnd->PopupMenu(menu); return true; } + +#endif // wxUSE_TASKBARICON