Add support for button press/release and scroll events. Patch by Ed Catmur
* gtk/gtkstatusicon.[hc]: Add support for button press/release and scroll events. Patch by Ed Catmur svn path=/trunk/; revision=21746
This commit is contained in:
@ -1,3 +1,11 @@
|
|||||||
|
2008-11-01 Matthias Clasen <mclasen@redhat.com>
|
||||||
|
|
||||||
|
Bug 409435 – GtkStatusIcon enhancements: DnD, scroll events,
|
||||||
|
middle click, rich tooltips
|
||||||
|
|
||||||
|
* gtk/gtkstatusicon.[hc]: Add support for button press/release and
|
||||||
|
scroll events. Patch by Ed Catmur
|
||||||
|
|
||||||
2008-11-01 Matthias Clasen <mclasen@redhat.com>
|
2008-11-01 Matthias Clasen <mclasen@redhat.com>
|
||||||
|
|
||||||
Bug 322934 – Replace menu's proxy icons with empty space hiding icons
|
Bug 322934 – Replace menu's proxy icons with empty space hiding icons
|
||||||
|
@ -40,6 +40,7 @@
|
|||||||
|
|
||||||
#include "gtkprivate.h"
|
#include "gtkprivate.h"
|
||||||
#include "gtkwidget.h"
|
#include "gtkwidget.h"
|
||||||
|
#include "gtktooltip.h"
|
||||||
|
|
||||||
#ifdef GDK_WINDOWING_X11
|
#ifdef GDK_WINDOWING_X11
|
||||||
#include "gdk/x11/gdkx.h"
|
#include "gdk/x11/gdkx.h"
|
||||||
@ -86,6 +87,9 @@ enum
|
|||||||
ACTIVATE_SIGNAL,
|
ACTIVATE_SIGNAL,
|
||||||
POPUP_MENU_SIGNAL,
|
POPUP_MENU_SIGNAL,
|
||||||
SIZE_CHANGED_SIGNAL,
|
SIZE_CHANGED_SIGNAL,
|
||||||
|
BUTTON_PRESS_EVENT_SIGNAL,
|
||||||
|
BUTTON_RELEASE_EVENT_SIGNAL,
|
||||||
|
SCROLL_EVENT_SIGNAL,
|
||||||
LAST_SIGNAL
|
LAST_SIGNAL
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -157,6 +161,8 @@ static void gtk_status_icon_screen_changed (GtkStatusIcon *status_icon,
|
|||||||
GdkScreen *old_screen);
|
GdkScreen *old_screen);
|
||||||
static void gtk_status_icon_embedded_changed (GtkStatusIcon *status_icon);
|
static void gtk_status_icon_embedded_changed (GtkStatusIcon *status_icon);
|
||||||
static void gtk_status_icon_orientation_changed (GtkStatusIcon *status_icon);
|
static void gtk_status_icon_orientation_changed (GtkStatusIcon *status_icon);
|
||||||
|
static gboolean gtk_status_icon_scroll (GtkStatusIcon *status_icon,
|
||||||
|
GdkEventScroll *event);
|
||||||
|
|
||||||
static gboolean gtk_status_icon_key_press (GtkStatusIcon *status_icon,
|
static gboolean gtk_status_icon_key_press (GtkStatusIcon *status_icon,
|
||||||
GdkEventKey *event);
|
GdkEventKey *event);
|
||||||
@ -164,6 +170,8 @@ static void gtk_status_icon_popup_menu (GtkStatusIcon *status_icon);
|
|||||||
#endif
|
#endif
|
||||||
static gboolean gtk_status_icon_button_press (GtkStatusIcon *status_icon,
|
static gboolean gtk_status_icon_button_press (GtkStatusIcon *status_icon,
|
||||||
GdkEventButton *event);
|
GdkEventButton *event);
|
||||||
|
static gboolean gtk_status_icon_button_release (GtkStatusIcon *status_icon,
|
||||||
|
GdkEventButton *event);
|
||||||
static void gtk_status_icon_disable_blinking (GtkStatusIcon *status_icon);
|
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_reset_image_data (GtkStatusIcon *status_icon);
|
||||||
static void gtk_status_icon_update_image (GtkStatusIcon *status_icon);
|
static void gtk_status_icon_update_image (GtkStatusIcon *status_icon);
|
||||||
@ -180,6 +188,10 @@ gtk_status_icon_class_init (GtkStatusIconClass *class)
|
|||||||
gobject_class->set_property = gtk_status_icon_set_property;
|
gobject_class->set_property = gtk_status_icon_set_property;
|
||||||
gobject_class->get_property = gtk_status_icon_get_property;
|
gobject_class->get_property = gtk_status_icon_get_property;
|
||||||
|
|
||||||
|
class->button_press_event = NULL;
|
||||||
|
class->button_release_event = NULL;
|
||||||
|
class->scroll_event = NULL;
|
||||||
|
|
||||||
g_object_class_install_property (gobject_class,
|
g_object_class_install_property (gobject_class,
|
||||||
PROP_PIXBUF,
|
PROP_PIXBUF,
|
||||||
g_param_spec_object ("pixbuf",
|
g_param_spec_object ("pixbuf",
|
||||||
@ -304,7 +316,6 @@ gtk_status_icon_class_init (GtkStatusIconClass *class)
|
|||||||
GTK_ORIENTATION_HORIZONTAL,
|
GTK_ORIENTATION_HORIZONTAL,
|
||||||
GTK_PARAM_READABLE));
|
GTK_PARAM_READABLE));
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GtkStatusIcon::activate:
|
* GtkStatusIcon::activate:
|
||||||
* @status_icon: the object which received the signal
|
* @status_icon: the object which received the signal
|
||||||
@ -386,6 +397,86 @@ gtk_status_icon_class_init (GtkStatusIconClass *class)
|
|||||||
1,
|
1,
|
||||||
G_TYPE_INT);
|
G_TYPE_INT);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GtkStatusIcon::button-press-event:
|
||||||
|
* @status_icon: the object which received the signal
|
||||||
|
* @event: the #GdkEventButton which triggered this signal
|
||||||
|
*
|
||||||
|
* The ::button-press-event signal will be emitted when a button
|
||||||
|
* (typically from a mouse) is pressed.
|
||||||
|
*
|
||||||
|
* Whether this event is emitted is platform-dependent. Use the
|
||||||
|
* #GtkStatusIcon::activate and #GtkStatusIcon::popup-menu signals
|
||||||
|
* in preference.
|
||||||
|
*
|
||||||
|
* Return value: %TRUE to stop other handlers from being invoked
|
||||||
|
* for the event. %FALSE to propagate the event further.
|
||||||
|
*
|
||||||
|
* Since: 2.16
|
||||||
|
*/
|
||||||
|
status_icon_signals [BUTTON_PRESS_EVENT_SIGNAL] =
|
||||||
|
g_signal_new (I_("button_press_event"),
|
||||||
|
G_TYPE_FROM_CLASS (gobject_class),
|
||||||
|
G_SIGNAL_RUN_LAST,
|
||||||
|
G_STRUCT_OFFSET (GtkStatusIconClass, button_press_event),
|
||||||
|
g_signal_accumulator_true_handled, NULL,
|
||||||
|
_gtk_marshal_BOOLEAN__BOXED,
|
||||||
|
G_TYPE_BOOLEAN, 1,
|
||||||
|
GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GtkStatusIcon::button-release-event:
|
||||||
|
* @status_icon: the object which received the signal
|
||||||
|
* @event: the #GdkEventButton which triggered this signal
|
||||||
|
*
|
||||||
|
* The ::button-release-event signal will be emitted when a button
|
||||||
|
* (typically from a mouse) is released.
|
||||||
|
*
|
||||||
|
* Whether this event is emitted is platform-dependent. Use the
|
||||||
|
* #GtkStatusIcon::activate and #GtkStatusIcon::popup-menu signals
|
||||||
|
* in preference.
|
||||||
|
*
|
||||||
|
* Return value: %TRUE to stop other handlers from being invoked
|
||||||
|
* for the event. %FALSE to propagate the event further.
|
||||||
|
*
|
||||||
|
* Since: 2.16
|
||||||
|
*/
|
||||||
|
status_icon_signals [BUTTON_RELEASE_EVENT_SIGNAL] =
|
||||||
|
g_signal_new (I_("button_release_event"),
|
||||||
|
G_TYPE_FROM_CLASS (gobject_class),
|
||||||
|
G_SIGNAL_RUN_LAST,
|
||||||
|
G_STRUCT_OFFSET (GtkStatusIconClass, button_release_event),
|
||||||
|
g_signal_accumulator_true_handled, NULL,
|
||||||
|
_gtk_marshal_BOOLEAN__BOXED,
|
||||||
|
G_TYPE_BOOLEAN, 1,
|
||||||
|
GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GtkStatusIcon::scroll-event:
|
||||||
|
* @status_icon: the object which received the signal.
|
||||||
|
* @event: the #GdkEventScroll which triggered this signal
|
||||||
|
*
|
||||||
|
* The ::scroll-event signal is emitted when a button in the 4 to 7
|
||||||
|
* range is pressed. Wheel mice are usually configured to generate
|
||||||
|
* button press events for buttons 4 and 5 when the wheel is turned.
|
||||||
|
*
|
||||||
|
* Whether this event is emitted is platform-dependent.
|
||||||
|
*
|
||||||
|
* Returns: %TRUE to stop other handlers from being invoked for the event.
|
||||||
|
* %FALSE to propagate the event further.
|
||||||
|
*
|
||||||
|
* Since: 2.16
|
||||||
|
*/
|
||||||
|
status_icon_signals[SCROLL_EVENT_SIGNAL] =
|
||||||
|
g_signal_new (I_("scroll_event"),
|
||||||
|
G_TYPE_FROM_CLASS (gobject_class),
|
||||||
|
G_SIGNAL_RUN_LAST,
|
||||||
|
G_STRUCT_OFFSET (GtkStatusIconClass, scroll_event),
|
||||||
|
g_signal_accumulator_true_handled, NULL,
|
||||||
|
_gtk_marshal_BOOLEAN__BOXED,
|
||||||
|
G_TYPE_BOOLEAN, 1,
|
||||||
|
GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
|
||||||
|
|
||||||
g_type_class_add_private (class, sizeof (GtkStatusIconPrivate));
|
g_type_class_add_private (class, sizeof (GtkStatusIconPrivate));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -426,7 +517,10 @@ button_callback (gpointer data)
|
|||||||
{
|
{
|
||||||
ButtonCallbackData *bc = (ButtonCallbackData *) data;
|
ButtonCallbackData *bc = (ButtonCallbackData *) data;
|
||||||
|
|
||||||
|
if (event->type == GDK_BUTTON_PRESS)
|
||||||
gtk_status_icon_button_press (bc->status_icon, bc->event);
|
gtk_status_icon_button_press (bc->status_icon, bc->event);
|
||||||
|
else
|
||||||
|
gtk_status_icon_button_release (bc->status_icon, bc->event);
|
||||||
|
|
||||||
gdk_event_free ((GdkEvent *) bc->event);
|
gdk_event_free ((GdkEvent *) bc->event);
|
||||||
g_free (data);
|
g_free (data);
|
||||||
@ -472,17 +566,62 @@ wndproc (HWND hwnd,
|
|||||||
if (message == WM_GTK_TRAY_NOTIFICATION)
|
if (message == WM_GTK_TRAY_NOTIFICATION)
|
||||||
{
|
{
|
||||||
ButtonCallbackData *bc;
|
ButtonCallbackData *bc;
|
||||||
|
guint button;
|
||||||
|
|
||||||
switch (lparam)
|
switch (lparam)
|
||||||
{
|
{
|
||||||
case WM_LBUTTONDOWN:
|
case WM_LBUTTONDOWN:
|
||||||
|
button = 1;
|
||||||
|
goto buttondown0;
|
||||||
|
|
||||||
|
case WM_MBUTTONDOWN:
|
||||||
|
button = 2;
|
||||||
|
goto buttondown0;
|
||||||
|
|
||||||
case WM_RBUTTONDOWN:
|
case WM_RBUTTONDOWN:
|
||||||
|
button = 3;
|
||||||
|
goto buttondown0;
|
||||||
|
|
||||||
|
case WM_XBUTTONDOWN:
|
||||||
|
if (HIWORD (wparam) == XBUTTON1)
|
||||||
|
button = 4;
|
||||||
|
else
|
||||||
|
button = 5;
|
||||||
|
|
||||||
|
buttondown0:
|
||||||
bc = g_new (ButtonCallbackData, 1);
|
bc = g_new (ButtonCallbackData, 1);
|
||||||
bc->event = (GdkEventButton *) gdk_event_new (GDK_BUTTON_PRESS);
|
bc->event = (GdkEventButton *) gdk_event_new (GDK_BUTTON_PRESS);
|
||||||
bc->status_icon = GTK_STATUS_ICON (wparam);
|
bc->status_icon = GTK_STATUS_ICON (wparam);
|
||||||
build_button_event (bc->status_icon->priv, bc->event, (lparam == WM_LBUTTONDOWN) ? 1 : 3);
|
build_button_event (bc->status_icon->priv, bc->event, button);
|
||||||
g_idle_add (button_callback, bc);
|
g_idle_add (button_callback, bc);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case WM_LBUTTONUP:
|
||||||
|
button = 1;
|
||||||
|
goto buttonup0;
|
||||||
|
|
||||||
|
case WM_MBUTTONUP:
|
||||||
|
button = 2;
|
||||||
|
goto buttonup0;
|
||||||
|
|
||||||
|
case WM_RBUTTONUP:
|
||||||
|
button = 3;
|
||||||
|
goto buttonup0;
|
||||||
|
|
||||||
|
case WM_XBUTTONUP:
|
||||||
|
if (HIWORD (wparam) == XBUTTON1)
|
||||||
|
button = 4;
|
||||||
|
else
|
||||||
|
button = 5;
|
||||||
|
|
||||||
|
buttonup0:
|
||||||
|
bc = g_new (ButtonCallbackData, 1);
|
||||||
|
bc->event = (GdkEventButton *) gdk_event_new (GDK_BUTTON_RELEASE);
|
||||||
|
bc->status_icon = GTK_STATUS_ICON (wparam);
|
||||||
|
build_button_event (bc->status_icon->priv, bc->event, button);
|
||||||
|
g_idle_add (button_callback, bc);
|
||||||
|
break;
|
||||||
|
|
||||||
default :
|
default :
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -551,7 +690,8 @@ gtk_status_icon_init (GtkStatusIcon *status_icon)
|
|||||||
priv->tray_icon = GTK_WIDGET (_gtk_tray_icon_new (NULL));
|
priv->tray_icon = GTK_WIDGET (_gtk_tray_icon_new (NULL));
|
||||||
|
|
||||||
gtk_widget_add_events (GTK_WIDGET (priv->tray_icon),
|
gtk_widget_add_events (GTK_WIDGET (priv->tray_icon),
|
||||||
GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK);
|
GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
|
||||||
|
GDK_SCROLL_MASK);
|
||||||
|
|
||||||
g_signal_connect_swapped (priv->tray_icon, "key-press-event",
|
g_signal_connect_swapped (priv->tray_icon, "key-press-event",
|
||||||
G_CALLBACK (gtk_status_icon_key_press), status_icon);
|
G_CALLBACK (gtk_status_icon_key_press), status_icon);
|
||||||
@ -563,6 +703,10 @@ gtk_status_icon_init (GtkStatusIcon *status_icon)
|
|||||||
G_CALLBACK (gtk_status_icon_orientation_changed), status_icon);
|
G_CALLBACK (gtk_status_icon_orientation_changed), status_icon);
|
||||||
g_signal_connect_swapped (priv->tray_icon, "button-press-event",
|
g_signal_connect_swapped (priv->tray_icon, "button-press-event",
|
||||||
G_CALLBACK (gtk_status_icon_button_press), status_icon);
|
G_CALLBACK (gtk_status_icon_button_press), status_icon);
|
||||||
|
g_signal_connect_swapped (priv->tray_icon, "button-release-event",
|
||||||
|
G_CALLBACK (gtk_status_icon_button_release), status_icon);
|
||||||
|
g_signal_connect_swapped (priv->tray_icon, "scroll-event",
|
||||||
|
G_CALLBACK (gtk_status_icon_scroll), status_icon);
|
||||||
g_signal_connect_swapped (priv->tray_icon, "screen-changed",
|
g_signal_connect_swapped (priv->tray_icon, "screen-changed",
|
||||||
G_CALLBACK (gtk_status_icon_screen_changed), status_icon);
|
G_CALLBACK (gtk_status_icon_screen_changed), status_icon);
|
||||||
priv->image = gtk_image_new ();
|
priv->image = gtk_image_new ();
|
||||||
@ -1384,6 +1528,14 @@ static gboolean
|
|||||||
gtk_status_icon_button_press (GtkStatusIcon *status_icon,
|
gtk_status_icon_button_press (GtkStatusIcon *status_icon,
|
||||||
GdkEventButton *event)
|
GdkEventButton *event)
|
||||||
{
|
{
|
||||||
|
gboolean handled = FALSE;
|
||||||
|
|
||||||
|
g_signal_emit (status_icon,
|
||||||
|
status_icon_signals [BUTTON_PRESS_EVENT_SIGNAL], 0,
|
||||||
|
event, &handled);
|
||||||
|
if (handled)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
if (event->button == 1 && event->type == GDK_BUTTON_PRESS)
|
if (event->button == 1 && event->type == GDK_BUTTON_PRESS)
|
||||||
{
|
{
|
||||||
emit_activate_signal (status_icon);
|
emit_activate_signal (status_icon);
|
||||||
@ -1398,6 +1550,30 @@ gtk_status_icon_button_press (GtkStatusIcon *status_icon,
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gtk_status_icon_button_release (GtkStatusIcon *status_icon,
|
||||||
|
GdkEventButton *event)
|
||||||
|
{
|
||||||
|
gboolean handled = FALSE;
|
||||||
|
g_signal_emit (status_icon,
|
||||||
|
status_icon_signals [BUTTON_RELEASE_EVENT_SIGNAL], 0,
|
||||||
|
event, &handled);
|
||||||
|
return handled;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef GDK_WINDOWING_X11
|
||||||
|
static gboolean
|
||||||
|
gtk_status_icon_scroll (GtkStatusIcon *status_icon,
|
||||||
|
GdkEventScroll *event)
|
||||||
|
{
|
||||||
|
gboolean handled = FALSE;
|
||||||
|
g_signal_emit (status_icon,
|
||||||
|
status_icon_signals [SCROLL_EVENT_SIGNAL], 0,
|
||||||
|
event, &handled);
|
||||||
|
return handled;
|
||||||
|
}
|
||||||
|
#endif /* GDK_WINDOWING_X11 */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gtk_status_icon_reset_image_data (GtkStatusIcon *status_icon)
|
gtk_status_icon_reset_image_data (GtkStatusIcon *status_icon)
|
||||||
{
|
{
|
||||||
|
@ -61,13 +61,16 @@ struct _GtkStatusIconClass
|
|||||||
guint32 activate_time);
|
guint32 activate_time);
|
||||||
gboolean (* size_changed) (GtkStatusIcon *status_icon,
|
gboolean (* size_changed) (GtkStatusIcon *status_icon,
|
||||||
gint size);
|
gint size);
|
||||||
|
gboolean (* button_press_event) (GtkStatusIcon *status_icon,
|
||||||
|
GdkEventButton *event);
|
||||||
|
gboolean (* button_release_event) (GtkStatusIcon *status_icon,
|
||||||
|
GdkEventButton *event);
|
||||||
|
gboolean (* scroll_event) (GtkStatusIcon *status_icon,
|
||||||
|
GdkEventScroll *event);
|
||||||
|
|
||||||
void (*__gtk_reserved1);
|
void (*__gtk_reserved1);
|
||||||
void (*__gtk_reserved2);
|
void (*__gtk_reserved2);
|
||||||
void (*__gtk_reserved3);
|
void (*__gtk_reserved3);
|
||||||
void (*__gtk_reserved4);
|
|
||||||
void (*__gtk_reserved5);
|
|
||||||
void (*__gtk_reserved6);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
GType gtk_status_icon_get_type (void) G_GNUC_CONST;
|
GType gtk_status_icon_get_type (void) G_GNUC_CONST;
|
||||||
@ -105,7 +108,6 @@ GdkScreen *gtk_status_icon_get_screen (GtkStatusIcon *st
|
|||||||
|
|
||||||
void gtk_status_icon_set_tooltip (GtkStatusIcon *status_icon,
|
void gtk_status_icon_set_tooltip (GtkStatusIcon *status_icon,
|
||||||
const gchar *tooltip_text);
|
const gchar *tooltip_text);
|
||||||
|
|
||||||
void gtk_status_icon_set_visible (GtkStatusIcon *status_icon,
|
void gtk_status_icon_set_visible (GtkStatusIcon *status_icon,
|
||||||
gboolean visible);
|
gboolean visible);
|
||||||
gboolean gtk_status_icon_get_visible (GtkStatusIcon *status_icon);
|
gboolean gtk_status_icon_get_visible (GtkStatusIcon *status_icon);
|
||||||
@ -125,6 +127,9 @@ gboolean gtk_status_icon_get_geometry (GtkStatusIcon *st
|
|||||||
GdkScreen **screen,
|
GdkScreen **screen,
|
||||||
GdkRectangle *area,
|
GdkRectangle *area,
|
||||||
GtkOrientation *orientation);
|
GtkOrientation *orientation);
|
||||||
|
gboolean gtk_status_icon_get_has_tooltip (GtkStatusIcon *status_icon);
|
||||||
|
gchar *gtk_status_icon_get_tooltip_text (GtkStatusIcon *status_icon);
|
||||||
|
gchar *gtk_status_icon_get_tooltip_markup (GtkStatusIcon *status_icon);
|
||||||
|
|
||||||
guint32 gtk_status_icon_get_x11_window_id (GtkStatusIcon *status_icon);
|
guint32 gtk_status_icon_get_x11_window_id (GtkStatusIcon *status_icon);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user