#include "gtkintl.h"
#include "gtkiconfactory.h"
+#include "gtkmain.h"
#include "gtkmarshalers.h"
-#include "gtktooltips.h"
#include "gtktrayicon.h"
#include "gtkprivate.h"
#include "gtkwidget.h"
+#ifdef GDK_WINDOWING_X11
+#include "gdk/x11/gdkx.h"
+#endif
+
#ifdef GDK_WINDOWING_WIN32
#include "gtkicontheme.h"
#include "gtklabel.h"
#include "gtklabel.h"
#endif
+#include "gdkkeysyms.h"
+
#include "gtkalias.h"
#define BLINK_TIMEOUT 500
#ifdef GDK_WINDOWING_X11
GtkWidget *tray_icon;
GtkWidget *image;
- GtkTooltips *tooltips;
#endif
#ifdef GDK_WINDOWING_WIN32
static void gtk_status_icon_embedded_changed (GtkStatusIcon *status_icon);
static void gtk_status_icon_orientation_changed (GtkStatusIcon *status_icon);
+static gboolean gtk_status_icon_key_press (GtkStatusIcon *status_icon,
+ GdkEventKey *event);
+static void gtk_status_icon_popup_menu (GtkStatusIcon *status_icon);
#endif
static gboolean gtk_status_icon_button_press (GtkStatusIcon *status_icon,
GdkEventButton *event);
static void gtk_status_icon_disable_blinking (GtkStatusIcon *status_icon);
static void gtk_status_icon_reset_image_data (GtkStatusIcon *status_icon);
-
+static void gtk_status_icon_update_image (GtkStatusIcon *status_icon);
G_DEFINE_TYPE (GtkStatusIcon, gtk_status_icon, G_TYPE_OBJECT)
return FALSE;
}
+static UINT taskbar_created_msg = 0;
+static GSList *status_icons = NULL;
+
static LRESULT CALLBACK
wndproc (HWND hwnd,
UINT message,
WPARAM wparam,
LPARAM lparam)
{
+ if (message == taskbar_created_msg)
+ {
+ GSList *rover;
+
+ for (rover = status_icons; rover != NULL; rover = rover->next)
+ {
+ GtkStatusIcon *status_icon = GTK_STATUS_ICON (rover->data);
+ GtkStatusIconPrivate *priv = status_icon->priv;
+
+ priv->nid.hWnd = hwnd;
+ priv->nid.uID = GPOINTER_TO_UINT (status_icon);
+ priv->nid.uCallbackMessage = WM_GTK_TRAY_NOTIFICATION;
+ priv->nid.uFlags = NIF_MESSAGE;
+
+ if (!Shell_NotifyIconW (NIM_ADD, &priv->nid))
+ {
+ g_warning ("%s:%d:Shell_NotifyIcon(NIM_ADD) failed", __FILE__, __LINE__-2);
+ priv->nid.hWnd = NULL;
+ continue;
+ }
+
+ gtk_status_icon_update_image (status_icon);
+ }
+ return 0;
+ }
+
if (message == WM_GTK_TRAY_NOTIFICATION)
{
ButtonCallbackData *bc;
if (hwnd)
return hwnd;
+ taskbar_created_msg = RegisterWindowMessage("TaskbarCreated");
+
memset (&wclass, 0, sizeof(WNDCLASS));
wclass.lpszClassName = "gtkstatusicon-observer";
wclass.lpfnWndProc = wndproc;
if (!klass)
return NULL;
- hwnd = CreateWindow (MAKEINTRESOURCE(klass),
+ hwnd = CreateWindow (MAKEINTRESOURCE (klass),
NULL, WS_POPUP,
0, 0, 1, 1, NULL, NULL,
hmodule, NULL);
gtk_widget_add_events (GTK_WIDGET (priv->tray_icon),
GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK);
+ g_signal_connect_swapped (priv->tray_icon, "key-press-event",
+ G_CALLBACK (gtk_status_icon_key_press), status_icon);
+ g_signal_connect_swapped (priv->tray_icon, "popup-menu",
+ G_CALLBACK (gtk_status_icon_popup_menu), status_icon);
g_signal_connect_swapped (priv->tray_icon, "notify::embedded",
G_CALLBACK (gtk_status_icon_embedded_changed), status_icon);
g_signal_connect_swapped (priv->tray_icon, "notify::orientation",
g_signal_connect_swapped (priv->tray_icon, "screen-changed",
G_CALLBACK (gtk_status_icon_screen_changed), status_icon);
priv->image = gtk_image_new ();
+ GTK_WIDGET_SET_FLAGS (priv->image, GTK_CAN_FOCUS);
gtk_container_add (GTK_CONTAINER (priv->tray_icon), priv->image);
gtk_widget_show (priv->image);
g_signal_connect_swapped (priv->image, "size-allocate",
G_CALLBACK (gtk_status_icon_size_allocate), status_icon);
- status_icon->priv->tooltips = gtk_tooltips_new ();
- g_object_ref_sink (priv->tooltips);
#endif
#ifdef GDK_WINDOWING_WIN32
g_warning ("%s:%d:Shell_NotifyIcon(NIM_ADD) failed", __FILE__, __LINE__-2);
priv->nid.hWnd = NULL;
}
+
+ status_icons = g_slist_append (status_icons, status_icon);
+
#endif
#ifdef GDK_WINDOWING_QUARTZ
GObjectConstructParam *construct_params)
{
GObject *object;
+#ifdef GDK_WINDOWING_X11
GtkStatusIcon *status_icon;
GtkStatusIconPrivate *priv;
-
+#endif
+
object = G_OBJECT_CLASS (gtk_status_icon_parent_class)->constructor (type,
n_construct_properties,
construct_params);
priv->blank_icon = NULL;
#ifdef GDK_WINDOWING_X11
- if (priv->tooltips)
- g_object_unref (priv->tooltips);
- priv->tooltips = NULL;
-
gtk_widget_destroy (priv->tray_icon);
#endif
DestroyIcon (priv->nid.hIcon);
gtk_widget_destroy (priv->dummy_widget);
+
+ status_icons = g_slist_remove (status_icons, status_icon);
#endif
#ifdef GDK_WINDOWING_QUARTZ
g_object_notify (G_OBJECT (status_icon), "orientation");
}
+static gboolean
+gtk_status_icon_key_press (GtkStatusIcon *status_icon,
+ GdkEventKey *event)
+{
+ guint state, keyval;
+
+ state = event->state & gtk_accelerator_get_default_mod_mask ();
+ keyval = event->keyval;
+ if (state == 0 &&
+ (keyval == GDK_Return ||
+ keyval == GDK_KP_Enter ||
+ keyval == GDK_ISO_Enter ||
+ keyval == GDK_space ||
+ keyval == GDK_KP_Space))
+ {
+ emit_activate_signal (status_icon);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static void
+gtk_status_icon_popup_menu (GtkStatusIcon *status_icon)
+{
+ emit_popup_menu_signal (status_icon, 0, gtk_get_current_event_time ());
+}
+
#endif
static gboolean
priv = status_icon->priv;
#ifdef GDK_WINDOWING_X11
- gtk_tooltips_set_tip (priv->tooltips, priv->tray_icon,
- tooltip_text, NULL);
+
+ gtk_widget_set_tooltip_text (priv->tray_icon, tooltip_text);
+
#endif
#ifdef GDK_WINDOWING_WIN32
if (tooltip_text == NULL)
#ifdef GDK_WINDOWING_X11
if (visible)
gtk_widget_show (priv->tray_icon);
- else if (GTK_WIDGET_REALIZED (priv->tray_icon)) {
- gtk_widget_hide (priv->tray_icon);
- gtk_widget_unrealize (priv->tray_icon);
- }
+ else if (GTK_WIDGET_REALIZED (priv->tray_icon))
+ {
+ gtk_widget_hide (priv->tray_icon);
+ gtk_widget_unrealize (priv->tray_icon);
+ }
#endif
#ifdef GDK_WINDOWING_WIN32
if (priv->nid.hWnd != NULL)
#endif /* GDK_WINDOWING_X11 */
}
+/**
+ * gtk_status_icon_get_x11_window_id:
+ * @status_icon: a #GtkStatusIcon
+ *
+ * This function is only useful on the X11/freedesktop.org platform.
+ * It returns a window ID for the widget in the underlying
+ * status icon implementation. This is useful for the Galago
+ * notification service, which can send a window ID in the protocol
+ * in order for the server to position notification windows
+ * pointing to a status icon reliably.
+ *
+ * This function is not intended for other use cases which are
+ * more likely to be met by one of the non-X11 specific methods, such
+ * as gtk_status_icon_position_menu().
+ *
+ * Return value: An 32 bit unsigned integer identifier for the
+ * underlying X11 Window
+ *
+ * Since: 2.14
+ */
+guint32
+gtk_status_icon_get_x11_window_id (GtkStatusIcon *status_icon)
+{
+#ifdef GDK_WINDOWING_X11
+ gtk_widget_realize (GTK_WIDGET (status_icon->priv->tray_icon));
+ return GDK_WINDOW_XID (GTK_WIDGET (status_icon->priv->tray_icon)->window);
+#else
+ return 0;
+#endif
+}
#define __GTK_STATUS_ICON_C__
#include "gtkaliasdef.c"