2
* Copyright (c) 2010 Sharkbaitbobby <sharkbaitbobby+awn@gmail.com>
4
* This program is free software; you can redistribute it and/or modify
5
* it under the terms of the GNU General Public License as published by
6
* the Free Software Foundation; either version 2 of the License, or
7
* (at your option) any later version.
9
* This program is distributed in the hope that it will be useful,
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
* GNU General Public License for more details.
14
* You should have received a copy of the GNU General Public License
15
* along with this program; if not, write to the Free Software
16
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
25
#include <glib/gi18n-lib.h>
26
#include <libawn/libawn.h>
27
#include <libindicator/indicator-object.h>
29
typedef struct _IndicatorApplet IndicatorApplet;
30
struct _IndicatorApplet {
39
DesktopAgnosticConfigClient *config;
40
gint config_rows_cols;
41
gboolean config_ind_app;
42
gboolean config_ind_app_ses;
44
gboolean config_messaging;
45
gboolean config_network;
46
gboolean config_sound;
47
gboolean config_other_menus;
63
static gboolean icon_button_press(AwnIcon *icon, GdkEventButton *event, IndicatorApplet *iapplet);
64
static gboolean icon_right_click(AwnIcon *icon, GdkEventButton *event, IndicatorApplet *iapplet);
65
static gboolean icon_scroll(AwnIcon *icon, GdkEventScroll *event, IndicatorApplet *iapplet);
66
static void get_shown_entries(IndicatorApplet *iapplet);
67
static void resize_da(IndicatorApplet *iapplet);
68
static void update_config(IndicatorApplet *iapplet);
69
static void update_icon_mode(IndicatorApplet *iapplet);
72
show_about(GtkMenuItem *item, gpointer user_data)
74
const gchar *license = "This program is free software; you can redistribute \
75
it and/or modify it under the terms of the GNU General Public License as \
76
published by the Free Software Foundation; either version 2 of the License, \
77
or (at your option) any later version.\n\nThis program is distributed in the \
78
hope that it will be useful, but WITHOUT ANY WARRANTY; without even the \
79
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. \
80
See the GNU General Public License for more details.\n\nYou should have \
81
received a copy of the GNU General Public License along with this program; \
82
if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth \
83
Floor, Boston, MA 02110-1301 USA.";
84
const gchar *authors[] = {"Sharkbaitbobby <sharkbaitbobby+awn@gmail.com>",
87
GtkWidget *about = gtk_about_dialog_new();
89
gtk_about_dialog_set_program_name(GTK_ABOUT_DIALOG(about), "Indicator Applet");
90
gtk_about_dialog_set_version(GTK_ABOUT_DIALOG(about), VERSION);
91
gtk_about_dialog_set_comments(GTK_ABOUT_DIALOG(about),
92
_("An applet to hold all of the system indicators"));
93
gtk_about_dialog_set_copyright(GTK_ABOUT_DIALOG(about),
94
"Copyright \xc2\xa9 2010 Sharkbaitbobby");
95
gtk_about_dialog_set_logo_icon_name(GTK_ABOUT_DIALOG(about), "indicator-applet");
96
gtk_about_dialog_set_license(GTK_ABOUT_DIALOG(about), license);
97
gtk_about_dialog_set_wrap_license(GTK_ABOUT_DIALOG(about), TRUE);
98
gtk_about_dialog_set_authors(GTK_ABOUT_DIALOG(about), authors);
99
gtk_about_dialog_set_website(GTK_ABOUT_DIALOG(about),
100
"http://wiki.awn-project.org/Indicator_Applet");
101
gtk_about_dialog_set_website_label(GTK_ABOUT_DIALOG(about),
102
"wiki.awn-project.org");
104
gtk_window_set_icon_name(GTK_WINDOW(about), "indicator-applet");
106
gtk_dialog_run(GTK_DIALOG(about));
107
gtk_widget_destroy(about);
110
/* Preferences dialog ... */
112
check_toggled(GtkToggleButton *button, IndicatorApplet *iapplet)
114
desktop_agnostic_config_client_set_bool(iapplet->config,
115
DESKTOP_AGNOSTIC_CONFIG_GROUP_DEFAULT,
116
(gchar*)g_object_get_data(G_OBJECT(button), "ldakey"),
117
gtk_toggle_button_get_active(button), NULL);
118
update_config(iapplet);
119
get_shown_entries(iapplet);
121
update_icon_mode(iapplet);
127
applet_mode_check_toggled(GtkToggleButton *button, IndicatorApplet *iapplet)
129
desktop_agnostic_config_client_set_bool(iapplet->config,
130
DESKTOP_AGNOSTIC_CONFIG_GROUP_DEFAULT,
131
"applet_icon_mode", gtk_toggle_button_get_active(button),
134
update_config(iapplet);
135
update_icon_mode(iapplet);
139
make_check_button(IndicatorApplet *iapplet,
145
GtkWidget *check = gtk_check_button_new_with_label(label);
146
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check), enabled);
147
g_signal_connect(G_OBJECT(check), "toggled", G_CALLBACK(check_toggled), (gpointer)iapplet);
148
g_object_set_data(G_OBJECT(check), "ldakey", key);
149
gtk_box_pack_start(GTK_BOX(box), check, FALSE, FALSE, 0);
153
spin_changed(GtkSpinButton *spin, IndicatorApplet *iapplet)
155
desktop_agnostic_config_client_set_int(iapplet->config,
156
DESKTOP_AGNOSTIC_CONFIG_GROUP_DEFAULT,
157
"rows_cols", (gint)gtk_spin_button_get_value(spin),
159
update_config(iapplet);
161
if (!iapplet->applet_mode)
168
show_prefs(GtkMenuItem *item, IndicatorApplet *iapplet)
170
GtkDialog *win = GTK_DIALOG(gtk_dialog_new_with_buttons(_("Indicator Applet Preferences"),
171
NULL, GTK_DIALOG_NO_SEPARATOR, GTK_STOCK_CLOSE, GTK_RESPONSE_ACCEPT,
174
iapplet->dialog = win;
176
GtkWidget *label = gtk_label_new(NULL);
177
gtk_label_set_markup(GTK_LABEL(label), g_strdup_printf("<b>%s</b>", _("Enabled Entries")));
178
gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
179
gtk_box_pack_start(GTK_BOX(win->vbox), label, FALSE, FALSE, 0);
181
GtkWidget *vbox = gtk_vbox_new(FALSE, 3);
182
make_check_button(iapplet, _("Indicator Applet"),
183
"indicator_applet", iapplet->config_ind_app, vbox);
184
make_check_button(iapplet, _("Indicator Applet Session (Quit)"),
185
"indicator_applet_session", iapplet->config_ind_app_ses, vbox);
186
make_check_button(iapplet, _("Me Menu"),
187
"me_menu", iapplet->config_me, vbox);
188
make_check_button(iapplet, _("Messaging Menu"),
189
"messaging_menu", iapplet->config_messaging, vbox);
190
make_check_button(iapplet, _("Network Menu"),
191
"network_menu", iapplet->config_network, vbox);
192
make_check_button(iapplet, _("Sound Control Menu"),
193
"sound_menu", iapplet->config_sound, vbox);
194
make_check_button(iapplet, _("Other Menus"),
195
"other_menus", iapplet->config_other_menus, vbox);
197
GtkWidget *align = gtk_alignment_new(0.0, 0.5, 1.0, 0.0);
198
gtk_alignment_set_padding(GTK_ALIGNMENT(align), 0, 0, 12, 0);
199
gtk_container_add(GTK_CONTAINER(align), vbox);
201
gtk_box_pack_start(GTK_BOX(win->vbox), align, FALSE, FALSE, 0);
203
label = gtk_label_new(NULL);
204
gtk_label_set_markup(GTK_LABEL(label), g_strdup_printf("<b>%s</b>", _("Options")));
205
gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
206
gtk_box_pack_start(GTK_BOX(win->vbox), label, FALSE, FALSE, 0);
208
vbox = gtk_vbox_new(FALSE, 3);
209
GtkPositionType pos = awn_applet_get_pos_type(iapplet->applet);
210
if (pos == GTK_POS_TOP || pos == GTK_POS_BOTTOM)
212
label = gtk_label_new(_("Number of rows:"));
216
label = gtk_label_new(_("Number of columns:"));
218
GtkWidget *spin = gtk_spin_button_new_with_range(1.0, 3.0, 1.0);
219
gtk_spin_button_set_digits(GTK_SPIN_BUTTON(spin), 0);
220
gtk_spin_button_set_value(GTK_SPIN_BUTTON(spin), (gdouble)iapplet->config_rows_cols);
221
g_signal_connect(G_OBJECT(spin), "value-changed", G_CALLBACK(spin_changed), (gpointer)iapplet);
223
GtkWidget *hbox = gtk_hbox_new(FALSE, 0);
224
gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
225
gtk_box_pack_end(GTK_BOX(hbox), spin, FALSE, FALSE, 0);
226
gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
228
GtkWidget *check = gtk_check_button_new_with_label(_("Enable Applet Icon mode"));
229
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check), iapplet->applet_mode);
230
g_signal_connect(G_OBJECT(check), "toggled",
231
G_CALLBACK(applet_mode_check_toggled), (gpointer)iapplet);
232
gtk_box_pack_start(GTK_BOX(vbox), check, FALSE, FALSE, 0);
234
align = gtk_alignment_new(0.0, 0.5, 1.0, 0.0);
235
gtk_alignment_set_padding(GTK_ALIGNMENT(align), 0, 0, 12, 0);
236
gtk_container_add(GTK_CONTAINER(align), vbox);
237
gtk_box_pack_start(GTK_BOX(win->vbox), align, FALSE, FALSE, 0);
239
gtk_container_set_border_width(GTK_CONTAINER(win), 12);
240
gtk_window_set_icon_name(GTK_WINDOW(win), "indicator-applet");
241
gtk_widget_show_all(GTK_WIDGET(win));
243
gtk_widget_destroy(GTK_WIDGET(win));
247
get_bool(IndicatorApplet *iapplet, gchar *key)
249
return desktop_agnostic_config_client_get_bool(iapplet->config,
250
DESKTOP_AGNOSTIC_CONFIG_GROUP_DEFAULT,
255
update_config(IndicatorApplet *iapplet)
257
iapplet->config_rows_cols = desktop_agnostic_config_client_get_int(iapplet->config,
258
DESKTOP_AGNOSTIC_CONFIG_GROUP_DEFAULT,
260
if (iapplet->config_rows_cols < 1)
262
iapplet->config_rows_cols = 2;
264
iapplet->config_ind_app = get_bool(iapplet, "indicator_applet");
265
iapplet->config_ind_app_ses = get_bool(iapplet, "indicator_applet_session");
266
iapplet->config_me = get_bool(iapplet, "me_menu");
267
iapplet->config_messaging = get_bool(iapplet, "messaging_menu");
268
iapplet->config_network = get_bool(iapplet, "network_menu");
269
iapplet->config_sound = get_bool(iapplet, "sound_menu");
270
iapplet->config_other_menus = get_bool(iapplet, "other_menus");
271
iapplet->applet_mode = get_bool(iapplet, "applet_icon_mode");
274
/* Dealing with libindicator ... */
276
get_shown_entries(IndicatorApplet *iapplet)
278
// Causes segfaults for various reasons... (none fully known)
279
/*if (iapplet->shown_images != NULL)
281
g_list_free(iapplet->shown_images);
283
if (iapplet->shown_menus != NULL)
285
g_list_free(iapplet->shown_menus);
288
iapplet->shown_images = NULL;
289
iapplet->shown_menus = NULL;
296
for (l = iapplet->images; l; l = l->next)
300
IndicatorObject *io = INDICATOR_OBJECT(g_object_get_data(G_OBJECT(l->data), "indicator"));
301
if (INDICATOR_IS_OBJECT(io))
303
name = (gchar*)g_object_get_data(G_OBJECT(io), "filename");
305
if (!g_strcmp0(name, "libapplication.so"))
307
if (iapplet->config_ind_app)
313
else if (!g_strcmp0(name, "libme.so"))
315
if (iapplet->config_me)
321
else if (!g_strcmp0(name, "libmessaging.so"))
323
if (iapplet->config_messaging)
329
else if (!g_strcmp0(name, "libnetworkmenu.so"))
331
if (iapplet->config_network)
337
else if (!g_strcmp0(name, "libsession.so"))
339
if (iapplet->config_ind_app_ses)
345
else if (!g_strcmp0(name, "libsoundmenu.so"))
347
if (iapplet->config_sound)
355
if (iapplet->config_other_menus)
363
iapplet->shown_images = g_list_append(iapplet->shown_images, l->data);
364
iapplet->shown_menus = g_list_append(iapplet->shown_menus,
365
g_list_nth_data(iapplet->menus, i));
374
pixbuf_changed(GObject *image, GParamSpec *spec, IndicatorApplet *iapplet)
376
if (iapplet->applet_mode)
378
update_icon_mode(iapplet);
382
gtk_widget_queue_draw(iapplet->da);
389
entry_added(IndicatorObject *io, IndicatorObjectEntry *entry, IndicatorApplet *iapplet)
391
if (entry->image == NULL || entry->menu == NULL)
393
/* If either of these is NULL, there will likely be problems when
394
* the entry is removed */
398
g_object_set_data(G_OBJECT(entry->image), "indicator", io);
399
iapplet->images = g_list_append(iapplet->images, entry->image);
400
iapplet->menus = g_list_append(iapplet->menus, entry->menu);
403
gint handler = g_signal_connect(G_OBJECT(entry->image), "notify::pixbuf",
404
G_CALLBACK(pixbuf_changed), (gpointer)iapplet);
405
g_object_set_data(G_OBJECT(entry->image), "pixbufhandler", (gpointer)handler);
407
gtk_widget_hide(GTK_WIDGET(entry->menu));
409
get_shown_entries(iapplet);
411
update_icon_mode(iapplet);
417
entry_removed(IndicatorObject *io, IndicatorObjectEntry *entry, IndicatorApplet *iapplet)
419
iapplet->images = g_list_remove(iapplet->images, entry->image);
420
iapplet->menus = g_list_remove(iapplet->menus, entry->menu);
423
gint handler = (gint)g_object_get_data(G_OBJECT(entry->image), "pixbufhandler");
425
if (g_signal_handler_is_connected(G_OBJECT(entry->image), handler))
427
g_signal_handler_disconnect(G_OBJECT(entry->image), handler);
430
get_shown_entries(iapplet);
432
update_icon_mode(iapplet);
436
load_module(const gchar * name, IndicatorApplet *iapplet)
438
g_return_val_if_fail(name != NULL, FALSE);
440
if (!g_str_has_suffix(name, G_MODULE_SUFFIX))
445
gchar *fullpath = g_build_filename(INDICATOR_DIR, name, NULL);
446
IndicatorObject *io = iapplet->io = indicator_object_new_from_file(fullpath);
449
g_signal_connect(G_OBJECT(io), INDICATOR_OBJECT_SIGNAL_ENTRY_ADDED,
450
G_CALLBACK(entry_added), iapplet);
451
g_signal_connect(G_OBJECT(io), INDICATOR_OBJECT_SIGNAL_ENTRY_REMOVED,
452
G_CALLBACK(entry_removed), iapplet);
454
GList *entries = indicator_object_get_entries(io);
457
g_object_set_data(G_OBJECT(io), "filename", (gpointer)g_strdup(name));
459
for (entry = entries; entry != NULL; entry = g_list_next(entry))
461
entry_added(io, (IndicatorObjectEntry*)entry->data, iapplet);
464
g_list_free(entries);
469
/* Drawing, widgets, etc ... */
471
resize_da(IndicatorApplet *iapplet)
473
gint size = awn_applet_get_size(iapplet->applet);
474
GtkPositionType pos = awn_applet_get_pos_type(iapplet->applet);
475
gint rc = iapplet->config_rows_cols;
477
gint pb_size = size * 1.1 / rc;
479
gint num = g_list_length(iapplet->shown_images);
481
if (pos == GTK_POS_TOP || pos == GTK_POS_BOTTOM)
483
gtk_widget_set_size_request(iapplet->da,
484
((int)(num / rc) + num % rc) * pb_size, -1);
488
gtk_widget_set_size_request(iapplet->da, -1,
489
((int)(num / rc) + num % rc) * pb_size);
492
gtk_widget_queue_draw(iapplet->da);
496
determine_position(IndicatorApplet *iapplet, gint x, gint y)
498
AwnApplet *applet = iapplet->applet;
499
GtkPositionType pos = awn_applet_get_pos_type(applet);
500
gint size = awn_applet_get_size(applet);
501
gint offset = awn_applet_get_offset(applet);
502
gint width = iapplet->da->allocation.width;
503
gint height = iapplet->da->allocation.height;
504
gint rc = iapplet->config_rows_cols;
505
gint pb_size = size * 1.1 / rc;
507
gint col = -1, row = -1, num = -1, dx = -1, dy = -1;
512
row = (height - y - offset) / pb_size;
517
dy = y - height + offset + pb_size * (row + 1);
519
col = (gint)(x / pb_size);
520
dx = x - col * pb_size;
521
num = col * rc + row;
525
row = (y - offset) / pb_size;
530
dy = y - (offset + pb_size * row);
532
col = (gint)(x / pb_size);
533
dx = x - col * pb_size;
534
num = col * rc + row;
538
col = (x - offset) / pb_size;
543
dx = x - (offset + pb_size * col);
545
row = (gint)(y / pb_size);
546
dy = y - row * pb_size;
547
num = row * rc + col;
551
col = (width - x - offset) / pb_size;
556
dx = x - width + offset + pb_size * (col + 1);
558
row = (gint)(y / pb_size);
559
dy = y - row * pb_size;
560
num = row * rc + col;
564
if (row == -1 || col == -1 || num == -1 || num >= g_list_length(iapplet->shown_menus))
569
iapplet->popup_num = num;
577
da_expose_event(GtkWidget *da, GdkEventExpose *event, IndicatorApplet *iapplet)
579
AwnApplet *applet = AWN_APPLET(iapplet->applet);
581
cairo_t *cr = gdk_cairo_create(da->window);
583
cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR);
586
cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
588
GtkPositionType pos = awn_applet_get_pos_type(applet);
589
gint offset = awn_applet_get_offset(applet);
590
gint size = awn_applet_get_size(applet);
591
gint w = da->allocation.width;
592
gint h = da->allocation.height;
593
gfloat x = 0.0, y = 0.0;
594
gint rc = iapplet->config_rows_cols;
595
gint pb_size = size * 1.1 / rc;
600
GtkIconInfo *icon_info;
604
GtkIconTheme *theme = gtk_icon_theme_get_default();
607
for (i = 0; i < g_list_length(iapplet->shown_images); i++)
612
image = GTK_IMAGE(g_list_nth_data(iapplet->shown_images, i));
613
icon = g_object_get_data(G_OBJECT(image), "indicator-names-data");
615
icon_info = gtk_icon_theme_lookup_by_gicon(theme, icon, pb_size,
616
GTK_ICON_LOOKUP_FORCE_SIZE | GTK_ICON_LOOKUP_USE_BUILTIN);
617
if (icon_info == NULL)
619
icon_info = gtk_icon_theme_lookup_by_gicon(theme, icon, 22,
620
GTK_ICON_LOOKUP_FORCE_SIZE | GTK_ICON_LOOKUP_USE_BUILTIN);
623
if (icon_info == NULL)
625
if (gtk_image_get_storage_type(image) == GTK_IMAGE_PIXBUF)
627
pb = gtk_image_get_pixbuf(image);
629
if (gdk_pixbuf_get_width(pb) != pb_size || gdk_pixbuf_get_height(pb) != pb_size)
631
pb = gdk_pixbuf_scale_simple(pb, pb_size, pb_size, GDK_INTERP_BILINEAR);
638
icon_path = (gchar*)gtk_icon_info_get_filename(icon_info);
639
pb = gdk_pixbuf_new_from_file_at_size(icon_path, pb_size, pb_size, NULL);
641
gtk_icon_info_free(icon_info);
649
x = (i - i % rc) * pb_size / rc;
650
y = h - pb_size * (1 + i % rc) - offset;
654
x = (i - i % rc) * pb_size / rc;
655
y = pb_size * (i % rc) + offset;
659
x = pb_size * (i % rc) + offset;
660
y = (i - i % rc) * pb_size / rc;
664
x = w - pb_size * (1 + i % rc) - offset;
665
y = (i - i % rc) * pb_size / rc;
669
cairo_rectangle(cr, x, y, pb_size, pb_size);
671
cairo_translate(cr, x, y);
673
if (GDK_IS_PIXBUF(pb))
675
gdk_cairo_set_source_pixbuf(cr, pb, 0.0, 0.0);
682
g_object_unref(G_OBJECT(pb));
689
update_icon_mode(IndicatorApplet *iapplet)
691
if (iapplet->applet_mode)
693
gtk_widget_hide(iapplet->da);
698
gtk_widget_show(iapplet->da);
701
for (l = gtk_container_get_children(GTK_CONTAINER(iapplet->icon_box)); l; l = l->next)
703
if (GTK_WIDGET(l->data) != iapplet->da)
705
gtk_widget_hide(GTK_WIDGET(l->data));
712
if (iapplet->shown_images == NULL)
717
gint size = awn_applet_get_size(iapplet->applet);
724
GtkIconInfo *icon_info;
726
gint nshown = g_list_length(iapplet->shown_images);
728
for (i = 0; i < nshown; i++)
730
image = GTK_IMAGE(g_list_nth_data(iapplet->shown_images, i));
732
if (g_list_length(iapplet->awnicons) <= i)
734
/* Make new AwnIcon... */
735
awnicon = AWN_ICON(awn_themed_icon_new());
736
g_signal_connect(G_OBJECT(awnicon), "button-press-event",
737
G_CALLBACK(icon_button_press), (gpointer)iapplet);
738
g_signal_connect(G_OBJECT(awnicon), "context-menu-popup",
739
G_CALLBACK(icon_right_click), (gpointer)iapplet);
740
g_signal_connect(G_OBJECT(awnicon), "scroll-event",
741
G_CALLBACK(icon_scroll), (gpointer)iapplet);
742
g_object_set_data(G_OBJECT(awnicon), "num", (gpointer)i);
744
gtk_box_pack_start(GTK_BOX(iapplet->icon_box), GTK_WIDGET(awnicon), FALSE, FALSE, 0);
745
gtk_widget_show(GTK_WIDGET(awnicon));
747
iapplet->awnicons = g_list_append(iapplet->awnicons, (gpointer)awnicon);
751
awnicon = AWN_ICON(g_list_nth_data(iapplet->awnicons, i));
754
awn_icon_set_pos_type(awnicon, awn_applet_get_pos_type(iapplet->applet));
755
awn_icon_set_offset(awnicon, awn_applet_get_offset(iapplet->applet));
757
IndicatorObject *io = INDICATOR_OBJECT(g_object_get_data(G_OBJECT(image), "indicator"));
758
if (INDICATOR_IS_OBJECT(io))
760
const gchar *name = g_object_get_data(G_OBJECT(io), "filename");
762
if (!g_strcmp0(name, "libme.so"))
764
awn_icon_set_tooltip_text(awnicon, _("Me menu"));
766
else if (!g_strcmp0(name, "libmessaging.so"))
768
awn_icon_set_tooltip_text(awnicon, _("Messaging menu"));
770
else if (!g_strcmp0(name, "libnetworkmenu.so"))
772
awn_icon_set_tooltip_text(awnicon, _("Network menu"));
774
else if (!g_strcmp0(name, "libsession.so"))
776
awn_icon_set_tooltip_text(awnicon, _("Indicator Applet Session"));
778
else if (!g_strcmp0(name, "libsoundmenu.so"))
780
awn_icon_set_tooltip_text(awnicon, _("Sound Menu"));
784
awn_icon_set_tooltip_text(awnicon, _("Indicator Applet"));
789
icon = g_object_get_data(G_OBJECT(image), "indicator-names-data");
791
theme = gtk_icon_theme_get_default();
792
icon_info = gtk_icon_theme_lookup_by_gicon(theme, icon, size,
793
GTK_ICON_LOOKUP_FORCE_SIZE | GTK_ICON_LOOKUP_USE_BUILTIN);
794
if (icon_info == NULL)
796
icon_info = gtk_icon_theme_lookup_by_gicon(theme, icon, 22,
797
GTK_ICON_LOOKUP_FORCE_SIZE | GTK_ICON_LOOKUP_USE_BUILTIN);
800
if (icon_info == NULL)
802
if (gtk_image_get_storage_type(image) == GTK_IMAGE_PIXBUF)
804
pb = gtk_image_get_pixbuf(image);
806
if (gdk_pixbuf_get_width(pb) != size || gdk_pixbuf_get_height(pb) != size)
808
pb = gdk_pixbuf_scale_simple(pb, size, size, GDK_INTERP_BILINEAR);
815
const gchar *icon_path = gtk_icon_info_get_filename(icon_info);
816
pb = gdk_pixbuf_new_from_file_at_size(icon_path, size, size, NULL);
818
gtk_icon_info_free(icon_info);
821
awn_icon_set_from_pixbuf(awnicon, pb);
824
g_object_unref(G_OBJECT(pb));
827
gtk_widget_show(GTK_WIDGET(awnicon));
830
if (g_list_length(iapplet->awnicons) > i)
834
for (j = g_list_length(iapplet->awnicons); j > i; j--)
836
rm = g_list_nth_data(iapplet->awnicons, j - 1);
837
iapplet->awnicons = g_list_remove(iapplet->awnicons, rm);
838
gtk_widget_destroy(GTK_WIDGET(rm));
843
/* AwnIcon-related code ... */
845
icon_menu_position(GtkMenu *menu, gint *x, gint *y, gboolean *move, IndicatorApplet *iapplet)
847
GtkWidget *icon = GTK_WIDGET(g_list_nth_data(iapplet->awnicons, iapplet->popup_num));
848
GtkPositionType pos_type = awn_applet_get_pos_type(iapplet->applet);
849
gint size = awn_applet_get_size(iapplet->applet);
850
gint offset = awn_applet_get_offset(iapplet->applet);
852
gint mw = GTK_WIDGET(menu)->requisition.width;
853
gint mh = GTK_WIDGET(menu)->requisition.height;
854
gint aw = icon->allocation.width;
855
gint ah = icon->allocation.height;
857
GdkScreen *screen = gtk_widget_get_screen(icon);
858
gint sw = gdk_screen_get_width(screen);
859
gint sh = gdk_screen_get_height(screen);
864
*x = offset + size * 1.1;
865
gdk_window_get_origin(icon->window, NULL, y);
868
*x = sw - offset - size * 1.1 - mw;
869
gdk_window_get_origin(icon->window, NULL, y);
872
gdk_window_get_origin(icon->window, x, NULL);
873
*y = offset + size * 1.1;
876
gdk_window_get_origin(icon->window, x, NULL);
877
*y = sh - offset - size * 1.1 - mh;
885
icon_button_press(AwnIcon *icon, GdkEventButton *event, IndicatorApplet *iapplet)
887
if (iapplet->shown_menus == NULL || event->button == 3)
892
iapplet->popup_num = (gint)g_object_get_data(G_OBJECT(icon), "num");
894
gtk_menu_popup(GTK_MENU(g_list_nth_data(iapplet->shown_menus, iapplet->popup_num)), NULL, NULL,
895
(GtkMenuPositionFunc)icon_menu_position, (gpointer)iapplet, 1, event->time);
901
icon_right_click(AwnIcon *icon, GdkEventButton *event, IndicatorApplet *iapplet)
903
if (!iapplet->awn_menu)
905
iapplet->awn_menu = awn_applet_create_default_menu(iapplet->applet);
907
GtkWidget *item = gtk_image_menu_item_new_from_stock(GTK_STOCK_PREFERENCES, NULL);
908
g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(show_prefs), (gpointer)iapplet);
909
gtk_menu_shell_append(GTK_MENU_SHELL(iapplet->awn_menu), GTK_WIDGET(item));
911
item = gtk_image_menu_item_new_from_stock(GTK_STOCK_ABOUT, NULL);
912
g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(show_about), NULL);
913
gtk_menu_shell_append(GTK_MENU_SHELL(iapplet->awn_menu), GTK_WIDGET(item));
915
gtk_widget_show_all(iapplet->awn_menu);
918
gtk_menu_popup(GTK_MENU(iapplet->awn_menu), NULL, NULL, NULL, NULL,
919
event->button, event->time);
925
icon_scroll(AwnIcon *icon, GdkEventScroll *event, IndicatorApplet *iapplet)
927
gint num = (gint)g_object_get_data(G_OBJECT(icon), "num");
929
GtkWidget *image = g_list_nth_data(iapplet->shown_images, num);
930
IndicatorObject *io = g_object_get_data(G_OBJECT(image), "indicator");
931
g_signal_emit_by_name(io, "scroll", 1, event->direction);
936
/* DrawingArea-related code ... */
938
da_menu_position(GtkMenu *menu, gint *x, gint *y, gboolean *move, IndicatorApplet *iapplet)
940
AwnApplet *applet = AWN_APPLET(iapplet->applet);
941
GtkPositionType pos = awn_applet_get_pos_type(applet);
942
gint size = awn_applet_get_size(applet);
943
gint offset = awn_applet_get_offset(applet);
944
gint mwidth = GTK_WIDGET(menu)->requisition.width;
945
gint mheight = GTK_WIDGET(menu)->requisition.height;
946
gint rc = iapplet->config_rows_cols;
947
gint pb_size = size * 1.1 / rc;
953
*y -= iapplet->dy + mheight;
957
*y += pb_size - iapplet->dy;
960
*x += pb_size - iapplet->dx;
964
*x -= iapplet->dx + mwidth;
973
da_button_press(GtkWidget *widget, GdkEventButton *event, IndicatorApplet *iapplet)
975
AwnApplet *applet = AWN_APPLET(iapplet->applet);
976
if (event->button == 3)
978
if (!iapplet->awn_menu)
980
iapplet->awn_menu = awn_applet_create_default_menu(applet);
982
GtkWidget *item = gtk_image_menu_item_new_from_stock(GTK_STOCK_PREFERENCES, NULL);
983
g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(show_prefs), (gpointer)iapplet);
984
gtk_menu_shell_append(GTK_MENU_SHELL(iapplet->awn_menu), GTK_WIDGET(item));
986
item = gtk_image_menu_item_new_from_stock(GTK_STOCK_ABOUT, NULL);
987
g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(show_about), NULL);
988
gtk_menu_shell_append(GTK_MENU_SHELL(iapplet->awn_menu), GTK_WIDGET(item));
990
gtk_widget_show_all(iapplet->awn_menu);
993
gtk_menu_popup(GTK_MENU(iapplet->awn_menu), NULL, NULL, NULL, NULL,
994
event->button, event->time);
999
if (iapplet->applet_mode || !determine_position(iapplet, (gint)event->x, (gint)event->y))
1004
gtk_menu_popup(GTK_MENU(g_list_nth_data(iapplet->shown_menus, iapplet->popup_num)), NULL, NULL,
1005
(GtkMenuPositionFunc)da_menu_position, (gpointer)iapplet, event->button, event->time);
1011
da_scroll(GtkWidget *da, GdkEventScroll *event, IndicatorApplet *iapplet)
1013
if (!determine_position(iapplet, (gint)event->x, (gint)event->y))
1018
GtkWidget *image = g_list_nth_data(iapplet->shown_images, iapplet->popup_num);
1019
IndicatorObject *io = g_object_get_data(G_OBJECT(image), "indicator");
1020
g_signal_emit_by_name(io, "scroll", 1, event->direction);
1026
applet_size_changed(AwnApplet *applet, gint size, IndicatorApplet *iapplet)
1028
update_icon_mode(iapplet);
1034
applet_position_changed(AwnApplet *applet, GtkPositionType pos, IndicatorApplet *iapplet)
1036
update_icon_mode(iapplet);
1042
awn_applet_factory_initp(const gchar *name, const gchar *uid, gint panel_id)
1044
AwnApplet *applet = awn_applet_new(name, uid, panel_id);
1046
GtkWidget *da = gtk_drawing_area_new();
1047
gtk_widget_add_events(da, GDK_BUTTON_PRESS_MASK);
1048
gtk_widget_show(da);
1050
GtkWidget *icon_box = awn_icon_box_new_for_applet(applet);
1051
gtk_box_pack_start(GTK_BOX(icon_box), da, FALSE, FALSE, 0);
1052
gtk_widget_show_all(icon_box);
1053
gtk_container_add(GTK_CONTAINER(applet), icon_box);
1055
IndicatorApplet* iapplet = g_new0(IndicatorApplet, 1);
1058
iapplet->applet = applet;
1059
iapplet->icon_box = icon_box;
1060
iapplet->images = NULL;
1061
iapplet->menus = NULL;
1062
iapplet->shown_images = NULL;
1063
iapplet->shown_menus = NULL;
1064
iapplet->awnicons = NULL;
1065
iapplet->popup_num = -1;
1066
iapplet->last_num = -1;
1068
iapplet->config = awn_config_get_default_for_applet(iapplet->applet, NULL);
1069
update_config(iapplet);
1071
g_signal_connect(G_OBJECT(applet), "position-changed",
1072
G_CALLBACK(applet_position_changed), (gpointer)iapplet);
1073
g_signal_connect(G_OBJECT(applet), "size-changed",
1074
G_CALLBACK(applet_size_changed), (gpointer)iapplet);
1076
g_signal_connect(G_OBJECT(da), "button-press-event",
1077
G_CALLBACK(da_button_press), (gpointer)iapplet);
1078
g_signal_connect(G_OBJECT(da), "expose-event",
1079
G_CALLBACK(da_expose_event), (gpointer)iapplet);
1080
g_signal_connect(G_OBJECT(da), "scroll-event",
1081
G_CALLBACK(da_scroll), (gpointer)iapplet);
1083
gtk_icon_theme_append_search_path(gtk_icon_theme_get_default(), INDICATOR_ICONS_DIR);
1084
/* Code (mostly) from gnome-panel's indicator-applet-0.3.6/src/applet-main.c */
1085
if (g_file_test(INDICATOR_DIR, (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)))
1087
GDir *dir = g_dir_open(INDICATOR_DIR, 0, NULL);
1090
while ((name = g_dir_read_name(dir)) != NULL)
1092
/* Don't load the global menu used in Unity (Ubuntu Netbook Edition) */
1093
if (!g_strcmp0(name, "libappmenu.so"))
1097
load_module(name, iapplet);
1103
update_icon_mode(iapplet);