+2008-02-11 Matthias Clasen <mclasen@redhat.com>
+
+ Support keynav in status icons. (#473786, Li Yuan)
+
+ * gtk/gtkstatusicon.c: Handle keynav, make the tray icon focusable.
+
+ * gtk/gtktrayicon-x11.c: Draw a focus rectangle when focused.
+
2008-02-11 Kristian Rietveld <kris@imendio.com>
* gtk/gtkcellview.c (gtk_cell_view_cell_layout_reorder)
static void gtk_status_icon_orientation_changed (GtkStatusIcon *status_icon);
#endif
+static gboolean gtk_status_icon_key_press (GtkStatusIcon *status_icon,
+ GdkEventKey *event);
+static void gtk_status_icon_popup_menu (GtkStatusIcon *status_icon);
static gboolean gtk_status_icon_button_press (GtkStatusIcon *status_icon,
GdkEventButton *event);
static void gtk_status_icon_disable_blinking (GtkStatusIcon *status_icon);
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);
#endif
+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 ());
+}
+
static gboolean
gtk_status_icon_button_press (GtkStatusIcon *status_icon,
GdkEventButton *event)
gtk_tray_icon_expose (GtkWidget *widget,
GdkEventExpose *event)
{
+ GtkWidget *focus_child;
+ gint border_width, x, y, width, height;
+ gboolean retval = FALSE;
+
gdk_window_clear_area (widget->window, event->area.x, event->area.y,
event->area.width, event->area.height);
- if (GTK_WIDGET_CLASS (gtk_tray_icon_parent_class)->expose_event)
- return GTK_WIDGET_CLASS (gtk_tray_icon_parent_class)->expose_event (widget, event);
+ if (GTK_WIDGET_CLASS (gtk_tray_icon_parent_class)->expose_event)
+ retval = GTK_WIDGET_CLASS (gtk_tray_icon_parent_class)->expose_event (widget, event);
+
+ focus_child = GTK_CONTAINER (widget)->focus_child;
+ if (focus_child && GTK_WIDGET_HAS_FOCUS (focus_child))
+ {
+ border_width = GTK_CONTAINER (widget)->border_width;
+
+ x = widget->allocation.x + border_width;
+ y = widget->allocation.y + border_width;
+
+ width = widget->allocation.width - 2 * border_width;
+ height = widget->allocation.height - 2 * border_width;
+
+ gtk_paint_focus (widget->style, widget->window,
+ GTK_WIDGET_STATE (widget),
+ &event->area, widget, "tray_icon",
+ x, y, width, height);
+ }
- return FALSE;
+ return retval;
}
static void