~ubuntu-core-dev/update-notifier/ubuntu

« back to all changes in this revision

Viewing changes to src/trayappletui.c

  • Committer: Iain Lane
  • Date: 2019-08-01 12:34:01 UTC
  • Revision ID: iain.lane@canonical.com-20190801123401-dd5pfj314b3t55hk
Make livepatch_get_num_fixes (private API) return 'ssize_t' instead of
'gssize', which will allow us to use the '%zd' format string to print its
value. That in turn allows the string to be extracted into the .pot file
for translation.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include <glib.h>
 
2
 
 
3
#include "update-notifier.h"
 
4
#include "trayappletui.h"
 
5
 
 
6
void tray_applet_ui_ensure(TrayApplet *ta)
 
7
{
 
8
   g_debug("tray_applet_ui_ensure: %s", ta->name);
 
9
#ifdef HAVE_APP_INDICATOR
 
10
   if (ta->indicator)
 
11
      return;
 
12
   ta->indicator = app_indicator_new (ta->name, ta->name,
 
13
                                      APP_INDICATOR_CATEGORY_SYSTEM_SERVICES);
 
14
#else
 
15
   if (ta->tray_icon)
 
16
      return;
 
17
   ta->tray_icon = gtk_status_icon_new_from_icon_name (ta->name);
 
18
   gtk_status_icon_set_visible (ta->tray_icon, FALSE);
 
19
#endif
 
20
}
 
21
 
 
22
void tray_applet_ui_set_icon(TrayApplet *ta, const char *icon_name)
 
23
{
 
24
#ifdef HAVE_APP_INDICATOR
 
25
   return app_indicator_set_icon(ta->indicator, icon_name);
 
26
#else
 
27
   return gtk_status_icon_set_from_icon_name(ta->tray_icon, icon_name);
 
28
#endif
 
29
}
 
30
 
 
31
// visible
 
32
gboolean tray_applet_ui_get_visible(TrayApplet *ta)
 
33
{
 
34
#ifdef HAVE_APP_INDICATOR
 
35
   if (!ta->indicator)
 
36
      return FALSE;
 
37
   return app_indicator_get_status(ta->indicator) != APP_INDICATOR_STATUS_PASSIVE;
 
38
#else
 
39
   if (!ta->tray_icon)
 
40
      return FALSE;
 
41
   return gtk_status_icon_get_visible(ta->tray_icon);
 
42
#endif
 
43
}
 
44
 
 
45
void tray_applet_ui_set_visible(TrayApplet *ta, gboolean visible)
 
46
{
 
47
#ifdef HAVE_APP_INDICATOR
 
48
   if (visible)
 
49
      app_indicator_set_status(ta->indicator, APP_INDICATOR_STATUS_ACTIVE);
 
50
   else
 
51
      app_indicator_set_status(ta->indicator, APP_INDICATOR_STATUS_PASSIVE);  
 
52
#else
 
53
   gtk_status_icon_set_visible(ta->tray_icon, visible);
 
54
#endif
 
55
}
 
56
 
 
57
// tooltips are only support for GtkStatusIcon, so with the indicator
 
58
// we need to simulate this with a menu
 
59
void tray_applet_ui_set_tooltip_text(TrayApplet *ta, const char *text)
 
60
{
 
61
#ifdef HAVE_APP_INDICATOR
 
62
   // there are no tooltips so we show them in the menu as inactive entries
 
63
   if (!ta->menu) {
 
64
      ta->menu = gtk_menu_new();
 
65
   }
 
66
   // clear out any previous fake tooltip
 
67
   GList *l = gtk_container_get_children(GTK_CONTAINER(ta->menu));
 
68
   if (l && l->data && g_object_get_data(G_OBJECT(l->data), "fake-tooltip")) {
 
69
      // the tooltip itself
 
70
      gtk_container_remove(GTK_CONTAINER(ta->menu), l->data);
 
71
      // and the seperator
 
72
      if (g_list_next(l))
 
73
         gtk_container_remove(GTK_CONTAINER(ta->menu), g_list_next(l)->data);
 
74
   }
 
75
   g_list_free(l);
 
76
 
 
77
   // when we simluate the tooltip we may get really long lines, those
 
78
   // need to be split up. in order to do that in a unicode friendly
 
79
   // way we ask pango to do the line wrap for us
 
80
   GtkWidget *label = gtk_label_new(text);
 
81
   g_object_ref_sink(label);
 
82
   gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
 
83
   PangoLayout *layout = gtk_label_get_layout(GTK_LABEL(label));
 
84
   // use 300px max for a line by default
 
85
   static const gint MAX_LINE_SIZE_IN_PIXEL = 300;
 
86
   pango_layout_set_width(layout, 
 
87
                          pango_units_from_double(MAX_LINE_SIZE_IN_PIXEL));
 
88
 
 
89
   // now go over the lines that pango identified and manually add \n
 
90
   GSList *lines = pango_layout_get_lines_readonly(layout);
 
91
   GString *new_text = g_string_new("");
 
92
   while (lines != NULL) {
 
93
      new_text = g_string_append_len(new_text, 
 
94
                                     text+((PangoLayoutLine*)lines->data)->start_index,
 
95
                                     ((PangoLayoutLine*)lines->data)->length);
 
96
      lines = g_slist_next(lines);
 
97
      // avoid final newline
 
98
      if (lines != NULL)
 
99
         new_text = g_string_append(new_text, "\n");
 
100
   }
 
101
 
 
102
   // add a new one
 
103
   GtkWidget *menu_item = gtk_menu_item_new_with_label(new_text->str);
 
104
   gtk_menu_shell_insert(GTK_MENU_SHELL(ta->menu), menu_item, 0);
 
105
   g_object_set_data(G_OBJECT(menu_item), "fake-tooltip", "1");
 
106
   gtk_widget_set_sensitive(menu_item, FALSE);
 
107
   gtk_widget_show(menu_item);
 
108
   menu_item = gtk_separator_menu_item_new();
 
109
   gtk_menu_shell_insert(GTK_MENU_SHELL(ta->menu), menu_item, 1);
 
110
   gtk_widget_show(menu_item);
 
111
 
 
112
   // and free
 
113
   g_slist_free(lines);
 
114
   g_string_free(new_text, TRUE);
 
115
   g_object_unref(label);
 
116
#else
 
117
   gtk_status_icon_set_tooltip_text (ta->tray_icon,  text);
 
118
#endif
 
119
}
 
120
 
 
121
#ifndef HAVE_APP_INDICATOR
 
122
// internal helper for the tray_applet_ui_set_menu call
 
123
static gboolean
 
124
popup_menu_for_gtk_status_icon_cb (GtkStatusIcon *status_icon,
 
125
                                   guint          button,
 
126
                                   guint          activate_time,
 
127
                                   TrayApplet     *ta)
 
128
{
 
129
   gtk_menu_set_screen (GTK_MENU (ta->menu),
 
130
                        gtk_status_icon_get_screen(ta->tray_icon));
 
131
   gtk_menu_popup (GTK_MENU (ta->menu), NULL, NULL, 
 
132
                   gtk_status_icon_position_menu, ta->tray_icon,
 
133
                   button, activate_time);
 
134
   return TRUE;
 
135
}
 
136
#endif
 
137
 
 
138
// add a menu to the applet, on the indicators this is left-click,
 
139
// on the GtkStatusBar its right click
 
140
void tray_applet_ui_set_menu(TrayApplet *ta, GtkWidget *menu)
 
141
{
 
142
   ta->menu = menu;
 
143
#ifdef HAVE_APP_INDICATOR
 
144
   app_indicator_set_menu(ta->indicator, GTK_MENU(ta->menu));
 
145
#else
 
146
   g_signal_connect (G_OBJECT(ta->tray_icon),
 
147
                     "popup-menu",
 
148
                     G_CALLBACK (popup_menu_for_gtk_status_icon_cb),
 
149
                     ta);
 
150
#endif
 
151
   
 
152
 
 
153
}
 
154
 
 
155
 
 
156
void tray_applet_ui_set_single_action(TrayApplet *ta, 
 
157
                                      const char *label,
 
158
                                      GCallback callback,
 
159
                                      void *data)
 
160
{
 
161
#ifdef HAVE_APP_INDICATOR
 
162
   GtkWidget *menu = gtk_menu_new();
 
163
   GtkWidget *menu_item = gtk_menu_item_new_with_label(label);
 
164
      g_signal_connect (G_OBJECT(menu_item),
 
165
                        "activate",
 
166
                        G_CALLBACK(callback),
 
167
                        data);
 
168
   gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
 
169
   gtk_widget_show_all(menu);
 
170
   app_indicator_set_menu(ta->indicator, GTK_MENU(menu));
 
171
#else
 
172
   tray_applet_ui_set_tooltip_text (ta, label);
 
173
   g_signal_connect (G_OBJECT(ta->tray_icon),
 
174
                     "activate",
 
175
                     callback,
 
176
                     data);
 
177
#endif
 
178
}
 
179
 
 
180
void tray_applet_ui_set_data(TrayApplet *ta, const char *key, void *data)
 
181
{
 
182
#ifdef HAVE_APP_INDICATOR
 
183
   g_object_set_data(G_OBJECT(ta->indicator), key, data);
 
184
#else
 
185
   g_object_set_data(G_OBJECT(ta->tray_icon), key, data);
 
186
#endif
 
187
}
 
188
 
 
189
void* tray_applet_ui_get_data(TrayApplet *ta, const char *key)
 
190
{
 
191
#ifdef HAVE_APP_INDICATOR
 
192
   return g_object_get_data(G_OBJECT(ta->indicator), key);
 
193
#else
 
194
   return g_object_get_data(G_OBJECT(ta->tray_icon), key);
 
195
#endif
 
196
}
 
197
 
 
198
void tray_applet_ui_destroy(TrayApplet *ta)
 
199
{
 
200
   g_debug("tray_applet_ui_destroy: %s", ta->name);
 
201
#ifdef HAVE_APP_INDICATOR
 
202
   g_clear_object(&ta->indicator);
 
203
#else
 
204
   g_clear_object(&ta->tray_icon);
 
205
#endif
 
206
}