new wxTaskBarIcon implementation for GTK2
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@58777 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -3007,6 +3007,7 @@ src/osx/iphone/window.mm
|
||||
</set>
|
||||
<set var="ADVANCED_GTK_HDR" hints="files">
|
||||
wx/gtk/hildon/notifmsg.h
|
||||
wx/gtk/taskbar.h
|
||||
</set>
|
||||
|
||||
<set var="ADVANCED_GTK_NATIVE_SRC" hints="files">
|
||||
|
34
include/wx/gtk/taskbar.h
Normal file
34
include/wx/gtk/taskbar.h
Normal file
@@ -0,0 +1,34 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Name: wx/gtk/taskbar.h
|
||||
// Purpose: wxTaskBarIcon class for GTK2
|
||||
// Author: Paul Cornett
|
||||
// Created: 2009-02-08
|
||||
// RCS-ID: $Id$
|
||||
// Copyright: (c) 2009 Paul Cornett
|
||||
// Licence: wxWindows licence
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _WX_GTK_TASKBARICON_H_
|
||||
#define _WX_GTK_TASKBARICON_H_
|
||||
|
||||
class WXDLLIMPEXP_ADV wxTaskBarIcon: public wxTaskBarIconBase
|
||||
{
|
||||
public:
|
||||
wxTaskBarIcon();
|
||||
~wxTaskBarIcon();
|
||||
virtual bool SetIcon(const wxIcon& icon, const wxString& tooltip = wxString());
|
||||
virtual bool RemoveIcon();
|
||||
virtual bool PopupMenu(wxMenu* menu);
|
||||
bool IsOk() const { return true; }
|
||||
bool IsIconInstalled() const;
|
||||
|
||||
class Private;
|
||||
|
||||
private:
|
||||
Private* m_priv;
|
||||
|
||||
DECLARE_DYNAMIC_CLASS(wxTaskBarIcon)
|
||||
DECLARE_NO_COPY_CLASS(wxTaskBarIcon)
|
||||
};
|
||||
|
||||
#endif // _WX_GTK_TASKBARICON_H_
|
@@ -1,33 +0,0 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// File: wx/gtk/taskbarpriv.h
|
||||
// Purpose: wxTaskBarIcon (src/unix/taskbarx11.cpp) helper for GTK2
|
||||
// Author: Vaclav Slavik
|
||||
// Modified by:
|
||||
// Created: 2004/05/29
|
||||
// RCS-ID: $Id$
|
||||
// Copyright: (c) Vaclav Slavik, 2004
|
||||
// Licence: wxWindows licence
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _WX_GTK_TASKBARPRIV_H_
|
||||
#define _WX_GTK_TASKBARPRIV_H_
|
||||
|
||||
#include "wx/toplevel.h"
|
||||
|
||||
class WXDLLIMPEXP_ADV wxTaskBarIconAreaBase : public wxTopLevelWindow
|
||||
{
|
||||
public:
|
||||
wxTaskBarIconAreaBase();
|
||||
|
||||
// Returns true if SYSTRAY protocol is supported by the desktop
|
||||
static bool IsProtocolSupported();
|
||||
|
||||
wxEvtHandler *m_invokingWindow;
|
||||
|
||||
protected:
|
||||
#if wxUSE_MENUS_NATIVE
|
||||
virtual void DoPopupMenuUpdateUI(wxMenu* menu);
|
||||
#endif // wxUSE_MENUS_NATIVE
|
||||
};
|
||||
|
||||
#endif // _WX_GTK_TASKBARPRIV_H_
|
@@ -316,7 +316,6 @@ protected:
|
||||
|
||||
#if wxUSE_MENUS_NATIVE
|
||||
virtual bool DoPopupMenu( wxMenu *menu, int x, int y );
|
||||
virtual void DoPopupMenuUpdateUI(wxMenu* menu);
|
||||
#endif // wxUSE_MENUS_NATIVE
|
||||
|
||||
virtual void DoCaptureMouse();
|
||||
|
@@ -65,6 +65,8 @@ private:
|
||||
#include "wx/palmos/taskbar.h"
|
||||
#elif defined(__WXMSW__)
|
||||
#include "wx/msw/taskbar.h"
|
||||
#elif defined(__WXGTK20__)
|
||||
#include "wx/gtk/taskbar.h"
|
||||
#elif defined(__WXGTK__) || defined(__WXX11__) || defined(__WXMOTIF__)
|
||||
#include "wx/unix/taskbarx11.h"
|
||||
#elif defined (__WXMAC__)
|
||||
|
@@ -1,8 +1,8 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// File: src/gtk/taskbar.cpp
|
||||
// Purpose: wxTaskBarIcon (src/unix/taskbarx11.cpp) helper for GTK2
|
||||
// Purpose: wxTaskBarIcon
|
||||
// Author: Vaclav Slavik
|
||||
// Modified by:
|
||||
// Modified by: Paul Cornett
|
||||
// Created: 2004/05/29
|
||||
// RCS-ID: $Id$
|
||||
// Copyright: (c) Vaclav Slavik, 2004
|
||||
@@ -14,73 +14,283 @@
|
||||
|
||||
#if wxUSE_TASKBARICON
|
||||
|
||||
#include "wx/gtk/taskbarpriv.h"
|
||||
#include "wx/taskbar.h"
|
||||
|
||||
#ifndef WX_PRECOMP
|
||||
#include "wx/log.h"
|
||||
#include "wx/frame.h"
|
||||
#include "wx/toplevel.h"
|
||||
#include "wx/menu.h"
|
||||
#include "wx/icon.h"
|
||||
#endif
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include <gdk/gdkx.h>
|
||||
|
||||
#include "eggtrayicon.h"
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
wxTaskBarIconAreaBase::wxTaskBarIconAreaBase()
|
||||
class wxTaskBarIcon::Private
|
||||
{
|
||||
if (IsProtocolSupported())
|
||||
{
|
||||
m_widget = GTK_WIDGET(egg_tray_icon_new("systray icon"));
|
||||
g_object_ref(m_widget);
|
||||
gtk_window_set_resizable(GTK_WINDOW(m_widget), false);
|
||||
public:
|
||||
Private(wxTaskBarIcon* taskBarIcon);
|
||||
~Private();
|
||||
void SetIcon();
|
||||
void size_allocate(int width, int height);
|
||||
|
||||
wxLogTrace(_T("systray"), _T("using freedesktop.org systray spec"));
|
||||
// owning wxTaskBarIcon
|
||||
wxTaskBarIcon* m_taskBarIcon;
|
||||
// used when GTK+ >= 2.10
|
||||
GtkStatusIcon* m_statusIcon;
|
||||
// used when GTK+ < 2.10
|
||||
GtkWidget* m_eggTrayIcon;
|
||||
// for PopupMenu
|
||||
wxWindow* m_win;
|
||||
// for tooltip when GTK+ < 2.10
|
||||
GtkTooltips* m_tooltips;
|
||||
wxBitmap m_bitmap;
|
||||
wxString m_tipText;
|
||||
// width and height of available space, only used when GTK+ < 2.10
|
||||
int m_size;
|
||||
};
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
extern "C" {
|
||||
static void
|
||||
icon_size_allocate(GtkWidget*, GtkAllocation* alloc, wxTaskBarIcon::Private* priv)
|
||||
{
|
||||
priv->size_allocate(alloc->width, alloc->height);
|
||||
}
|
||||
|
||||
wxTopLevelWindow::Create(
|
||||
NULL, wxID_ANY, _T("systray icon"),
|
||||
wxDefaultPosition, wxDefaultSize,
|
||||
wxDEFAULT_FRAME_STYLE | wxFRAME_NO_TASKBAR | wxSIMPLE_BORDER |
|
||||
wxFRAME_SHAPED,
|
||||
wxEmptyString /*eggtray doesn't like setting wmclass*/);
|
||||
|
||||
// WM frame extents are not useful for wxTaskBarIcon
|
||||
m_deferShow = false;
|
||||
gulong handler_id = g_signal_handler_find(
|
||||
m_widget,
|
||||
GSignalMatchType(G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_DATA),
|
||||
g_signal_lookup("property_notify_event", GTK_TYPE_WIDGET),
|
||||
0, NULL, NULL, this);
|
||||
if (handler_id != 0)
|
||||
g_signal_handler_disconnect(m_widget, handler_id);
|
||||
|
||||
m_invokingWindow = NULL;
|
||||
static void
|
||||
icon_destroy(GtkWidget*, wxTaskBarIcon::Private* priv)
|
||||
{
|
||||
// Icon window destroyed, probably because tray program has died.
|
||||
// Recreate icon so it will appear if tray program is restarted.
|
||||
priv->m_eggTrayIcon = NULL;
|
||||
priv->SetIcon();
|
||||
}
|
||||
|
||||
bool wxTaskBarIconAreaBase::IsProtocolSupported()
|
||||
static void
|
||||
icon_activate(void*, wxTaskBarIcon* taskBarIcon)
|
||||
{
|
||||
Display *display = GDK_DISPLAY();
|
||||
Screen *screen = DefaultScreenOfDisplay(display);
|
||||
// activate occurs from single click with GTK+
|
||||
wxTaskBarIconEvent event(wxEVT_TASKBAR_LEFT_DOWN, taskBarIcon);
|
||||
if (!taskBarIcon->SafelyProcessEvent(event))
|
||||
{
|
||||
// if single click not handled, send double click for compatibility
|
||||
event.SetEventType(wxEVT_TASKBAR_LEFT_DCLICK);
|
||||
taskBarIcon->SafelyProcessEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
icon_popup_menu(GtkWidget*, wxTaskBarIcon* taskBarIcon)
|
||||
{
|
||||
wxTaskBarIconEvent event(wxEVT_TASKBAR_CLICK, taskBarIcon);
|
||||
taskBarIcon->SafelyProcessEvent(event);
|
||||
return true;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
icon_button_press_event(GtkWidget*, GdkEventButton* event, wxTaskBarIcon* taskBarIcon)
|
||||
{
|
||||
if (event->type == GDK_BUTTON_PRESS)
|
||||
{
|
||||
if (event->button == 1)
|
||||
icon_activate(NULL, taskBarIcon);
|
||||
else if (event->button == 3)
|
||||
icon_popup_menu(NULL, taskBarIcon);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#if GTK_CHECK_VERSION(2,10,0)
|
||||
static void
|
||||
status_icon_popup_menu(GtkStatusIcon*, guint, guint, wxTaskBarIcon* taskBarIcon)
|
||||
{
|
||||
icon_popup_menu(NULL, taskBarIcon);
|
||||
}
|
||||
#endif
|
||||
} // extern "C"
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
bool wxTaskBarIconBase::IsAvailable()
|
||||
{
|
||||
char name[32];
|
||||
g_snprintf(name, sizeof(name), "_NET_SYSTEM_TRAY_S%d",
|
||||
XScreenNumberOfScreen(screen));
|
||||
Atom atom = XInternAtom(display, name, False);
|
||||
gdk_x11_get_default_screen());
|
||||
Atom atom = gdk_x11_get_xatom_by_name(name);
|
||||
|
||||
Window manager = XGetSelectionOwner(display, atom);
|
||||
Window manager = XGetSelectionOwner(gdk_x11_get_default_xdisplay(), atom);
|
||||
|
||||
return (manager != None);
|
||||
return manager != None;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Pop-up menu stuff
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#if wxUSE_MENUS_NATIVE
|
||||
void wxTaskBarIconAreaBase::DoPopupMenuUpdateUI(wxMenu* menu)
|
||||
wxTaskBarIcon::Private::Private(wxTaskBarIcon* taskBarIcon)
|
||||
{
|
||||
menu->UpdateUI(m_invokingWindow);
|
||||
m_taskBarIcon = taskBarIcon;
|
||||
m_statusIcon = NULL;
|
||||
m_eggTrayIcon = NULL;
|
||||
m_win = NULL;
|
||||
m_tooltips = NULL;
|
||||
m_size = 0;
|
||||
}
|
||||
#endif // wxUSE_MENUS_NATIVE
|
||||
|
||||
wxTaskBarIcon::Private::~Private()
|
||||
{
|
||||
if (m_statusIcon)
|
||||
g_object_unref(m_statusIcon);
|
||||
else if (m_eggTrayIcon)
|
||||
{
|
||||
g_signal_handlers_disconnect_by_func(m_eggTrayIcon, (void*)icon_destroy, this);
|
||||
gtk_widget_destroy(m_eggTrayIcon);
|
||||
}
|
||||
if (m_win)
|
||||
{
|
||||
m_win->PopEventHandler();
|
||||
m_win->Destroy();
|
||||
}
|
||||
if (m_tooltips)
|
||||
{
|
||||
gtk_object_destroy(GTK_OBJECT(m_tooltips));
|
||||
g_object_unref(m_tooltips);
|
||||
}
|
||||
}
|
||||
|
||||
void wxTaskBarIcon::Private::SetIcon()
|
||||
{
|
||||
#if GTK_CHECK_VERSION(2,10,0)
|
||||
if (gtk_check_version(2,10,0) == NULL)
|
||||
{
|
||||
if (m_statusIcon)
|
||||
gtk_status_icon_set_from_pixbuf(m_statusIcon, m_bitmap.GetPixbuf());
|
||||
else
|
||||
{
|
||||
m_statusIcon = gtk_status_icon_new_from_pixbuf(m_bitmap.GetPixbuf());
|
||||
g_signal_connect(m_statusIcon, "activate",
|
||||
G_CALLBACK(icon_activate), m_taskBarIcon);
|
||||
g_signal_connect(m_statusIcon, "popup_menu",
|
||||
G_CALLBACK(status_icon_popup_menu), m_taskBarIcon);
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
m_size = 0;
|
||||
if (m_eggTrayIcon)
|
||||
{
|
||||
GtkWidget* image = GTK_BIN(m_eggTrayIcon)->child;
|
||||
gtk_image_set_from_pixbuf(GTK_IMAGE(image), m_bitmap.GetPixbuf());
|
||||
}
|
||||
else
|
||||
{
|
||||
m_eggTrayIcon = GTK_WIDGET(egg_tray_icon_new("wxTaskBarIcon"));
|
||||
gtk_widget_add_events(m_eggTrayIcon, GDK_BUTTON_PRESS_MASK);
|
||||
g_signal_connect(m_eggTrayIcon, "size_allocate",
|
||||
G_CALLBACK(icon_size_allocate), this);
|
||||
g_signal_connect(m_eggTrayIcon, "destroy",
|
||||
G_CALLBACK(icon_destroy), this);
|
||||
g_signal_connect(m_eggTrayIcon, "button_press_event",
|
||||
G_CALLBACK(icon_button_press_event), m_taskBarIcon);
|
||||
g_signal_connect(m_eggTrayIcon, "popup_menu",
|
||||
G_CALLBACK(icon_popup_menu), m_taskBarIcon);
|
||||
GtkWidget* image = gtk_image_new_from_pixbuf(m_bitmap.GetPixbuf());
|
||||
gtk_container_add(GTK_CONTAINER(m_eggTrayIcon), image);
|
||||
gtk_widget_show_all(m_eggTrayIcon);
|
||||
}
|
||||
}
|
||||
#if wxUSE_TOOLTIPS
|
||||
const char* tip_text = NULL;
|
||||
if (!m_tipText.empty())
|
||||
tip_text = m_tipText;
|
||||
|
||||
#if GTK_CHECK_VERSION(2,10,0)
|
||||
if (m_statusIcon)
|
||||
gtk_status_icon_set_tooltip(m_statusIcon, tip_text);
|
||||
else
|
||||
#endif
|
||||
{
|
||||
if (tip_text && m_tooltips == NULL)
|
||||
{
|
||||
m_tooltips = gtk_tooltips_new();
|
||||
g_object_ref(m_tooltips);
|
||||
gtk_object_sink(GTK_OBJECT(m_tooltips));
|
||||
}
|
||||
if (m_tooltips)
|
||||
gtk_tooltips_set_tip(m_tooltips, m_eggTrayIcon, tip_text, "");
|
||||
}
|
||||
#endif // wxUSE_TOOLTIPS
|
||||
}
|
||||
|
||||
void wxTaskBarIcon::Private::size_allocate(int width, int height)
|
||||
{
|
||||
int size = height;
|
||||
EggTrayIcon* icon = EGG_TRAY_ICON(m_eggTrayIcon);
|
||||
if (egg_tray_icon_get_orientation(icon) == GTK_ORIENTATION_VERTICAL)
|
||||
size = width;
|
||||
if (m_size == size)
|
||||
return;
|
||||
m_size = size;
|
||||
int w = m_bitmap.GetWidth();
|
||||
int h = m_bitmap.GetHeight();
|
||||
if (w > size || h > size)
|
||||
{
|
||||
if (w > size) w = size;
|
||||
if (h > size) h = size;
|
||||
GdkPixbuf* pixbuf =
|
||||
gdk_pixbuf_scale_simple(m_bitmap.GetPixbuf(), w, h, GDK_INTERP_BILINEAR);
|
||||
GtkImage* image = GTK_IMAGE(GTK_BIN(m_eggTrayIcon)->child);
|
||||
gtk_image_set_from_pixbuf(image, pixbuf);
|
||||
g_object_unref(pixbuf);
|
||||
}
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
IMPLEMENT_DYNAMIC_CLASS(wxTaskBarIcon, wxEvtHandler)
|
||||
|
||||
wxTaskBarIcon::wxTaskBarIcon()
|
||||
{
|
||||
m_priv = new Private(this);
|
||||
}
|
||||
|
||||
wxTaskBarIcon::~wxTaskBarIcon()
|
||||
{
|
||||
delete m_priv;
|
||||
}
|
||||
|
||||
bool wxTaskBarIcon::SetIcon(const wxIcon& icon, const wxString& tooltip)
|
||||
{
|
||||
m_priv->m_bitmap = icon;
|
||||
m_priv->m_tipText = tooltip;
|
||||
m_priv->SetIcon();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool wxTaskBarIcon::RemoveIcon()
|
||||
{
|
||||
delete m_priv;
|
||||
m_priv = new Private(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool wxTaskBarIcon::IsIconInstalled() const
|
||||
{
|
||||
return m_priv->m_statusIcon || m_priv->m_eggTrayIcon;
|
||||
}
|
||||
|
||||
bool wxTaskBarIcon::PopupMenu(wxMenu* menu)
|
||||
{
|
||||
#if wxUSE_MENUS
|
||||
if (m_priv->m_win == NULL)
|
||||
{
|
||||
m_priv->m_win = new wxTopLevelWindow(
|
||||
NULL, wxID_ANY, wxString(), wxDefaultPosition, wxDefaultSize, 0);
|
||||
m_priv->m_win->PushEventHandler(this);
|
||||
}
|
||||
wxPoint point(-1, -1);
|
||||
#ifdef __WXUNIVERSAL__
|
||||
point = wxGetMousePosition();
|
||||
#endif
|
||||
m_priv->m_win->PopupMenu(menu, point);
|
||||
#endif // wxUSE_MENUS
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif // wxUSE_TASKBARICON
|
||||
|
@@ -3962,11 +3962,6 @@ void wxPopupMenuPositionCallback( GtkMenu *menu,
|
||||
}
|
||||
}
|
||||
|
||||
void wxWindowGTK::DoPopupMenuUpdateUI(wxMenu* menu)
|
||||
{
|
||||
menu->UpdateUI();
|
||||
}
|
||||
|
||||
bool wxWindowGTK::DoPopupMenu( wxMenu *menu, int x, int y )
|
||||
{
|
||||
wxCHECK_MSG( m_widget != NULL, false, wxT("invalid window") );
|
||||
@@ -3975,7 +3970,7 @@ bool wxWindowGTK::DoPopupMenu( wxMenu *menu, int x, int y )
|
||||
|
||||
SetInvokingWindow( menu, this );
|
||||
|
||||
DoPopupMenuUpdateUI(menu);
|
||||
menu->UpdateUI();
|
||||
|
||||
wxPoint pos;
|
||||
gpointer userdata;
|
||||
|
@@ -21,7 +21,7 @@
|
||||
// For compilers that support precompilation, includes "wx.h".
|
||||
#include "wx/wxprec.h"
|
||||
|
||||
#if wxUSE_TASKBARICON
|
||||
#if wxUSE_TASKBARICON && !defined(__WXGTK20__)
|
||||
|
||||
#include "wx/taskbar.h"
|
||||
|
||||
@@ -48,15 +48,6 @@
|
||||
// base class that implements toolkit-specific method:
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#ifdef __WXGTK20__
|
||||
#include <gtk/gtk.h>
|
||||
#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:
|
||||
@@ -68,17 +59,14 @@
|
||||
|
||||
static bool IsProtocolSupported() { return false; }
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// toolkit dependent methods to set properties on helper window:
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#if defined(__WXGTK__)
|
||||
#include <gdk/gdk.h>
|
||||
#include <gdk/gdkx.h>
|
||||
#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__)
|
||||
@@ -126,10 +114,6 @@ END_EVENT_TABLE()
|
||||
wxTaskBarIconArea::wxTaskBarIconArea(wxTaskBarIcon *icon, const wxBitmap &bmp)
|
||||
: wxTaskBarIconAreaBase(), m_icon(icon), m_bmp(bmp)
|
||||
{
|
||||
#if defined(__WXGTK20__) && defined(TASKBAR_ICON_AREA_BASE_INCLUDED)
|
||||
m_invokingWindow = icon;
|
||||
#endif
|
||||
|
||||
// Set initial size to bitmap size (tray manager may and often will
|
||||
// change it):
|
||||
SetClientSize(wxSize(bmp.GetWidth(), bmp.GetHeight()));
|
||||
|
Reference in New Issue
Block a user