システムトレイをいじってみる 3/3

システムトレイからメニューを表示出来るようにしてみます。
完成図
(クリックした状態でのスクリーンショットの方法が分からなかったのでデジカメで撮りました ^^;)


tray.cにこのコードを追加します。


void
on_item1_activate (GtkMenuItem *menuitem,
gpointer status_icon)
{
gtk_status_icon_set_blinking(status_icon, isBlinking);
isBlinking = !isBlinking;
}

void
on_item2_activate (GtkMenuItem *menuitem,
gpointer user_data)
{
gtk_main_quit();
}

GtkWidget*
create_menu (GObject *status_icon)
{
GtkWidget *menu;
GtkWidget *item1;
GtkWidget *item2;

menu = gtk_menu_new ();
gtk_widget_show (menu);

item1 = gtk_menu_item_new_with_mnemonic ("アイコン点滅");
gtk_widget_show (item1);
gtk_container_add (GTK_CONTAINER (menu), item1);

item2 = gtk_menu_item_new_with_mnemonic ("Quit(_Q)");
gtk_widget_show (item2);
gtk_container_add (GTK_CONTAINER (menu), item2);

g_signal_connect ((gpointer) item1, "activate",
G_CALLBACK (on_item1_activate),
status_icon);

g_signal_connect ((gpointer) item2, "activate",
G_CALLBACK (on_item2_activate),
NULL);
return menu;
}

メニューを構成する関数群です。
create_menu関数では、GtkStatusIconのポインタを引数としてとっていますが、
GtkStatusIconはGtkWidgetではないので注意が必要です。

    • -


アイコンを右クリックした時に呼ばれるコールバック関数はこのようにします。
(このようにするのがベストなのか自信はないですが)



void on_statusIcon_popup_menu (GtkStatusIcon *status_icon, gpointer user_data) {
GtkWidget *menu;
menu = create_menu(G_OBJECT(status_icon));
GdkEvent *event;

event = gdk_event_new(GDK_3BUTTON_PRESS);
guint32 event_time = gdk_event_get_time(event);

gtk_menu_popup (menu, NULL, NULL, gtk_status_icon_position_menu, status_icon, 2, event_time);

gdk_event_free(event);
}

gtk_menu_popup関数にGdkEventを引数として渡す必要があるのですが、
StatusIconをクリックしただけではイベントが発生しません。
 (EventBoxをStatusIconにAddすることも無理っぽいです)
そのため、自分でイベントを作る必要があります。


gtk_menu_popup関数について
引数4:gtk_status_icon_position_menu は
GtkMenuとStatusIconを関連付けるための関数です。(関数に関数を渡しています。参考資料の1)
引数5:status_iconはon_statusIcon_popup_menuに渡されたStatusIconへのポインタです。
引数6:マジックナンバー2が登場していますが(汗)、右クリックのことです。何を入れても動作に影響は無いようです。

参考資料

  1. GtkStatusIcon gtk-status-icon-position-menu
  2. GtkMenu gtk-popup-menu
  3. GdkEvents

GtkMenuについては
GTK/GNOMEによるGUIプログラミングで配布されているサンプルコードの
gtk-sources-20070419/gtk/gtkpopupmenu/gtkpopupmenu-sample.c
を参考にしました。