dolphin-emulator/Externals/wxWidgets3/src/unix/taskbarx11.cpp
Soren Jorvang d14efe561b Import r67258 of the wxWidgets trunk, which I expect will before
long become wxWidgets 2.9.2, which in turn is expected to be the
last 2.9 release before the 3.0 stable release.

Since the full wxWidgets distribution is rather large, I have
imported only the parts that we use, on a subdirectory basis:

art
include/wx/*.*
include/wx/aui
include/wx/cocoa
include/wx/generic
include/wx/gtk
include/wx/meta
include/wx/msw
include/wx/osx
include/wx/persist
include/wx/private
include/wx/protocol
include/wx/unix
src/aui
src/common
src/generic
src/gtk
src/msw
src/osx
src/unix


git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@7380 8ced0084-cf51-0410-be5f-012b33b47a6e
2011-03-20 18:05:19 +00:00

339 lines
9.3 KiB
C++

/////////////////////////////////////////////////////////////////////////
// File: src/unix/taskbarx11.cpp
// Purpose: wxTaskBarIcon class for common Unix desktops
// Author: Vaclav Slavik
// Modified by:
// Created: 04/04/2003
// RCS-ID: $Id: taskbarx11.cpp 61508 2009-07-23 20:30:22Z VZ $
// Copyright: (c) Vaclav Slavik, 2003
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////
// 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
// src/gtk/taskbar.cpp and used from here under wxGTK.
//
// Thanks to Ian Campbell, author of XMMS Status Docklet, for publishing
// KDE and GNOME 1.2 methods.
// For compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h"
#if wxUSE_TASKBARICON && !defined(__WXGTK20__)
#include "wx/taskbar.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
#endif
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#ifdef __VMS
#pragma message enable nosimpint
#endif
// ----------------------------------------------------------------------------
// base class that implements toolkit-specific method:
// ----------------------------------------------------------------------------
class WXDLLIMPEXP_ADV wxTaskBarIconAreaBase : public wxFrame
{
public:
wxTaskBarIconAreaBase()
: wxFrame(NULL, wxID_ANY, wxT("systray icon"),
wxDefaultPosition, wxDefaultSize,
wxDEFAULT_FRAME_STYLE | wxFRAME_NO_TASKBAR |
wxSIMPLE_BORDER | wxFRAME_SHAPED) {}
static bool IsProtocolSupported() { return false; }
};
// ----------------------------------------------------------------------------
// toolkit dependent methods to set properties on helper window:
// ----------------------------------------------------------------------------
#if defined(__WXGTK__)
#include <gtk/gtk.h>
#include <gdk/gdkx.h>
#define GetDisplay() GDK_DISPLAY()
#define GetXWindow(wxwin) GDK_WINDOW_XWINDOW((wxwin)->m_widget->window)
#elif defined(__WXX11__) || defined(__WXMOTIF__)
#include "wx/x11/privx.h"
#define GetDisplay() ((Display*)wxGlobalDisplay())
#define GetXWindow(wxwin) ((Window)(wxwin)->GetHandle())
#else
#error "You must define X11 accessors for this port!"
#endif
// ----------------------------------------------------------------------------
// wxTaskBarIconArea is the real window that shows the icon:
// ----------------------------------------------------------------------------
class WXDLLIMPEXP_ADV wxTaskBarIconArea : public wxTaskBarIconAreaBase
{
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);
void OnMenuEvent(wxCommandEvent& event);
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(wxID_ANY, wxTaskBarIconArea::OnMenuEvent)
EVT_PAINT(wxTaskBarIconArea::OnPaint)
END_EVENT_TABLE()
wxTaskBarIconArea::wxTaskBarIconArea(wxTaskBarIcon *icon, const wxBitmap &bmp)
: 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(wxT("systray"),
wxT("using legacy KDE1,2 and GNOME 1.2 methods"));
SetLegacyWMProperties();
}
}
void wxTaskBarIconArea::SetTrayIcon(const wxBitmap& bmp)
{
m_bmp = bmp;
// determine suitable bitmap size:
wxSize winsize(GetClientSize());
wxSize bmpsize(m_bmp.GetWidth(), m_bmp.GetHeight());
wxSize iconsize(wxMin(winsize.x, bmpsize.x), wxMin(winsize.y, bmpsize.y));
// rescale the bitmap to fit into the tray icon window:
if (bmpsize != iconsize)
{
wxImage img = m_bmp.ConvertToImage();
img.Rescale(iconsize.x, iconsize.y);
m_bmp = wxBitmap(img);
}
wxRegion region;
region.Union(m_bmp);
// if the bitmap is smaller than the window, offset it:
if (winsize != iconsize)
{
m_pos.x = (winsize.x - iconsize.x) / 2;
m_pos.y = (winsize.y - iconsize.y) / 2;
region.Offset(m_pos.x, m_pos.y);
}
// set frame's shape to correct value and redraw:
SetShape(region);
Refresh();
}
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);
data[0] = 0;
XChangeProperty(GetDisplay(), GetXWindow(this),
_KDE_NET_WM_SYSTEM_TRAY_WINDOW_FOR,
XA_WINDOW, 32,
PropModeReplace, (unsigned char*)data, 1);
// GNOME 1.2 & KDE 1:
Atom KWM_DOCKWINDOW =
XInternAtom(GetDisplay(), "KWM_DOCKWINDOW", False);
data[0] = 1;
XChangeProperty(GetDisplay(), GetXWindow(this),
KWM_DOCKWINDOW,
KWM_DOCKWINDOW, 32,
PropModeReplace, (unsigned char*)data, 1);
}
void wxTaskBarIconArea::OnSizeChange(wxSizeEvent& WXUNUSED(event))
{
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);
SetTrayIcon(bmp);
}
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;
wxEventType mtype = event.GetEventType();
if (mtype == wxEVT_LEFT_DOWN)
type = wxEVT_TASKBAR_LEFT_DOWN;
else if (mtype == wxEVT_LEFT_UP)
type = wxEVT_TASKBAR_LEFT_UP;
else if (mtype == wxEVT_LEFT_DCLICK)
type = wxEVT_TASKBAR_LEFT_DCLICK;
else if (mtype == wxEVT_RIGHT_DOWN)
type = wxEVT_TASKBAR_RIGHT_DOWN;
else if (mtype == wxEVT_RIGHT_UP)
type = wxEVT_TASKBAR_RIGHT_UP;
else if (mtype == wxEVT_RIGHT_DCLICK)
type = wxEVT_TASKBAR_RIGHT_DCLICK;
else if (mtype == wxEVT_MOTION)
type = wxEVT_TASKBAR_MOVE;
else
return;
wxTaskBarIconEvent e(type, m_icon);
m_icon->ProcessEvent(e);
}
void wxTaskBarIconArea::OnMenuEvent(wxCommandEvent& event)
{
m_icon->ProcessEvent(event);
}
// ----------------------------------------------------------------------------
// wxTaskBarIconBase class:
// ----------------------------------------------------------------------------
bool wxTaskBarIconBase::IsAvailable()
{
return wxTaskBarIconArea::IsProtocolSupported();
}
// ----------------------------------------------------------------------------
// wxTaskBarIcon class:
// ----------------------------------------------------------------------------
IMPLEMENT_DYNAMIC_CLASS(wxTaskBarIcon, wxEvtHandler)
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
{
return true;
}
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;
bmp.CopyFromIcon(icon);
if (!m_iconWnd)
{
m_iconWnd = new wxTaskBarIconArea(this, bmp);
if (m_iconWnd->IsOk())
{
m_iconWnd->Connect(wxEVT_DESTROY,
wxWindowDestroyEventHandler(wxTaskBarIcon::OnDestroy),
NULL, this);
m_iconWnd->Show();
}
else
{
m_iconWnd->Destroy();
m_iconWnd = NULL;
return false;
}
}
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;
}
bool wxTaskBarIcon::RemoveIcon()
{
if (!m_iconWnd)
return false;
m_iconWnd->Destroy();
m_iconWnd = NULL;
return true;
}
bool wxTaskBarIcon::PopupMenu(wxMenu *menu)
{
if (!m_iconWnd)
return false;
m_iconWnd->PopupMenu(menu);
return true;
}
#endif // wxUSE_TASKBARICON