248
by Michael Vogt
* src/crash.{c,h}: |
1 |
#ifdef HAVE_CONFIG_H
|
2 |
#include "config.h" |
|
3 |
#endif
|
|
4 |
||
5 |
#include <sys/types.h> |
|
6 |
#include <sys/stat.h> |
|
7 |
#include <unistd.h> |
|
8 |
||
9 |
#include <libnotify/notify.h> |
|
10 |
||
11 |
#include "update-notifier.h" |
|
12 |
#include "update.h" |
|
13 |
||
279
by Michael Vogt
* src/update-notifier.{c,h}: |
14 |
|
15 |
||
16 |
||
276.1.1
by martin at piware
* src/crash.c: If the user is an admin, also check for crashes of system |
17 |
static gboolean |
18 |
check_system_crashes() { |
|
19 |
int exitcode; |
|
280
by Michael Vogt
* src/crash.c: |
20 |
|
279
by Michael Vogt
* src/update-notifier.{c,h}: |
21 |
if(!in_admin_group()) |
22 |
return FALSE; |
|
276.1.1
by martin at piware
* src/crash.c: If the user is an admin, also check for crashes of system |
23 |
|
24 |
// check for system crashes
|
|
608
by Michael Vogt
* src/crash.c: |
25 |
gchar *argv[] = { CRASHREPORT_HELPER, "--system", NULL }; |
26 |
if(!g_spawn_sync(NULL, |
|
27 |
argv, |
|
28 |
NULL, |
|
29 |
G_SPAWN_STDOUT_TO_DEV_NULL|G_SPAWN_STDERR_TO_DEV_NULL, |
|
30 |
NULL, |
|
31 |
NULL, |
|
32 |
NULL, |
|
33 |
NULL, |
|
34 |
&exitcode, |
|
35 |
NULL)) { |
|
276.1.1
by martin at piware
* src/crash.c: If the user is an admin, also check for crashes of system |
36 |
g_warning("Can not run %s\n", CRASHREPORT_HELPER); |
37 |
return FALSE; |
|
38 |
}
|
|
39 |
||
40 |
return exitcode == 0; |
|
41 |
}
|
|
42 |
||
610
by Michael Vogt
* src/crash.c: |
43 |
static gboolean |
44 |
ask_invoke_apport_with_gksu() |
|
45 |
{
|
|
46 |
GtkDialog *dialog; |
|
47 |
gchar *msg = _("System program problem detected"); |
|
48 |
gchar *descr = _("Do you want to reporting the problem " |
|
49 |
"now?"); |
|
50 |
dialog = gtk_message_dialog_new (NULL, |
|
51 |
GTK_DIALOG_DESTROY_WITH_PARENT, |
|
52 |
GTK_MESSAGE_QUESTION, |
|
53 |
GTK_BUTTONS_NONE, |
|
54 |
msg); |
|
55 |
gtk_message_dialog_format_secondary_text(dialog, descr); |
|
56 |
gtk_dialog_add_button(dialog, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL); |
|
57 |
gtk_dialog_add_button(dialog, _("Report problem…"), GTK_RESPONSE_ACCEPT); |
|
58 |
int res = gtk_dialog_run(dialog); |
|
59 |
gtk_widget_destroy(dialog); |
|
60 |
if (res == GTK_RESPONSE_ACCEPT) |
|
61 |
return TRUE; |
|
62 |
return FALSE; |
|
63 |
}
|
|
64 |
||
253
by Michael Vogt
* improved the crash report handling: |
65 |
static gboolean |
262
by Michael Vogt
* src/crash.c: |
66 |
run_apport(TrayApplet *ta) |
253
by Michael Vogt
* improved the crash report handling: |
67 |
{
|
607
by Michael Vogt
merged from seb128, modified slightly to make the unity special case more obvious |
68 |
g_debug("fire up the crashreport tool\n"); |
69 |
if (check_system_crashes()) { |
|
610
by Michael Vogt
* src/crash.c: |
70 |
// be nice and always ask first before firing up gksu with its fullscreen
|
71 |
// window
|
|
72 |
if (ask_invoke_apport_with_gksu()) { |
|
73 |
invoke_with_gksu(CRASHREPORT_REPORT_APP, |
|
74 |
_("<span weight=\"bold\" size=\"larger\">Please enter your password to access problem reports of system programs</span>"), |
|
75 |
TRUE); |
|
76 |
}
|
|
77 |
return TRUE; |
|
276.1.1
by martin at piware
* src/crash.c: If the user is an admin, also check for crashes of system |
78 |
} else |
610
by Michael Vogt
* src/crash.c: |
79 |
return g_spawn_command_line_async(CRASHREPORT_REPORT_APP, NULL); |
253
by Michael Vogt
* improved the crash report handling: |
80 |
}
|
248
by Michael Vogt
* src/crash.{c,h}: |
81 |
|
334
by Michael Vogt
* fix crash in leftover from pre-GtkStatusIcon code (LP: #127965) |
82 |
static gboolean |
248
by Michael Vogt
* src/crash.{c,h}: |
83 |
show_notification (TrayApplet *ta) |
84 |
{
|
|
329
by Michael Vogt
* use GtkStatusIcon instead of EggTrayIcon, that makes |
85 |
NotifyNotification *n; |
86 |
||
365
by Michael Vogt
* src/update.c, src/crash.c, src/hooks.c: |
87 |
// check if the update-icon is still visible (in the delay time a
|
88 |
// update may already have been performed)
|
|
89 |
if(!gtk_status_icon_get_visible(ta->tray_icon)) |
|
90 |
return FALSE; |
|
91 |
||
329
by Michael Vogt
* use GtkStatusIcon instead of EggTrayIcon, that makes |
92 |
GdkRectangle area; |
93 |
gtk_status_icon_get_geometry(ta->tray_icon, NULL, &area, NULL); |
|
94 |
||
95 |
// no usefull coordiante yet, do another timeout
|
|
96 |
if(area.x <= 0 || area.y <= 0 || area.width <= 0 || area.height <= 0) |
|
97 |
return TRUE; |
|
98 |
||
99 |
// now show a notification handle
|
|
100 |
n = notify_notification_new_with_status_icon( |
|
101 |
_("Crash report detected"), |
|
301
by Jonathan Riddell
Fix grammer, A application -> An Application |
102 |
_("An application has crashed on your " |
248
by Michael Vogt
* src/crash.{c,h}: |
103 |
"system (now or in the past). "
|
104 |
"Click on the notification icon to "
|
|
105 |
"display details. "
|
|
106 |
),
|
|
107 |
GTK_STOCK_DIALOG_INFO, |
|
329
by Michael Vogt
* use GtkStatusIcon instead of EggTrayIcon, that makes |
108 |
ta->tray_icon); |
248
by Michael Vogt
* src/crash.{c,h}: |
109 |
notify_notification_set_timeout (n, 60000); |
110 |
notify_notification_show (n, NULL); |
|
111 |
g_object_set_data (G_OBJECT(ta->tray_icon), "notification", n); |
|
112 |
||
113 |
return FALSE; |
|
114 |
}
|
|
115 |
||
262
by Michael Vogt
* src/crash.c: |
116 |
static void |
117 |
hide_crash_applet(TrayApplet *ta) |
|
118 |
{
|
|
119 |
NotifyNotification *n; |
|
120 |
||
329
by Michael Vogt
* use GtkStatusIcon instead of EggTrayIcon, that makes |
121 |
gtk_status_icon_set_visible(ta->tray_icon, FALSE); |
262
by Michael Vogt
* src/crash.c: |
122 |
|
123 |
/* Hide any notification popup */
|
|
124 |
n = g_object_get_data (G_OBJECT(ta->tray_icon), "notification"); |
|
125 |
if (n) |
|
126 |
notify_notification_close (n, NULL); |
|
127 |
g_object_set_data (G_OBJECT(ta->tray_icon), "notification", NULL); |
|
128 |
}
|
|
129 |
||
248
by Michael Vogt
* src/crash.{c,h}: |
130 |
gboolean
|
131 |
crashreport_check (TrayApplet *ta) |
|
132 |
{
|
|
133 |
int crashreports_found = 0; |
|
253
by Michael Vogt
* improved the crash report handling: |
134 |
static gboolean first_run = TRUE; |
282
by Martin Pitt
* src/crash.c: Only show a notification for system crash reports, do not |
135 |
gboolean system_crashes; |
608
by Michael Vogt
* src/crash.c: |
136 |
g_debug("crashreport_check\n"); |
137 |
||
257
by Michael Vogt
* debian/control: |
138 |
// don't do anything if no apport-gtk is installed
|
139 |
if(!g_file_test(CRASHREPORT_REPORT_APP, G_FILE_TEST_IS_EXECUTABLE)) |
|
254
by Michael Vogt
* src/crash.c, src/hooks.c: |
140 |
return FALSE; |
248
by Michael Vogt
* src/crash.{c,h}: |
141 |
|
311
by Martin Pitt
* src/crash.c: Do not show apport crash reports if above gconf key is false. |
142 |
// Check whether the user doesn't want notifications
|
143 |
if (!gconf_client_get_bool ((GConfClient*) ta->user_data, |
|
144 |
GCONF_KEY_APPORT_NOTIFICATIONS, NULL)) { |
|
607
by Michael Vogt
merged from seb128, modified slightly to make the unity special case more obvious |
145 |
g_debug("apport notifications disabled in gconf, not displaying crashes"); |
146 |
return FALSE; |
|
311
by Martin Pitt
* src/crash.c: Do not show apport crash reports if above gconf key is false. |
147 |
}
|
148 |
||
257
by Michael Vogt
* debian/control: |
149 |
// check for (new) reports by calling CRASHREPORT_HELPER
|
150 |
// and checking the return code
|
|
151 |
int exitcode; |
|
608
by Michael Vogt
* src/crash.c: |
152 |
gchar *argv[] = { CRASHREPORT_HELPER, NULL }; |
153 |
if(!g_spawn_sync(NULL, |
|
154 |
argv, |
|
155 |
NULL, |
|
156 |
G_SPAWN_STDOUT_TO_DEV_NULL|G_SPAWN_STDERR_TO_DEV_NULL, |
|
157 |
NULL, |
|
158 |
NULL, |
|
159 |
NULL, |
|
160 |
NULL, |
|
161 |
&exitcode, |
|
162 |
NULL)) { |
|
257
by Michael Vogt
* debian/control: |
163 |
g_warning("Can not run %s\n", CRASHREPORT_HELPER); |
164 |
return FALSE; |
|
248
by Michael Vogt
* src/crash.{c,h}: |
165 |
}
|
257
by Michael Vogt
* debian/control: |
166 |
// exitcode == 0: repots found, else no reports
|
282
by Martin Pitt
* src/crash.c: Only show a notification for system crash reports, do not |
167 |
system_crashes = check_system_crashes(); |
168 |
crashreports_found = !exitcode || system_crashes; |
|
248
by Michael Vogt
* src/crash.{c,h}: |
169 |
|
607
by Michael Vogt
merged from seb128, modified slightly to make the unity special case more obvious |
170 |
gboolean visible = gtk_status_icon_get_visible(ta->tray_icon); |
171 |
||
172 |
// normal operation
|
|
173 |
||
253
by Michael Vogt
* improved the crash report handling: |
174 |
// crashreport found and first run: show notification bubble and
|
175 |
// return
|
|
282
by Martin Pitt
* src/crash.c: Only show a notification for system crash reports, do not |
176 |
if((crashreports_found > 0) && (system_crashes || first_run)) { |
329
by Michael Vogt
* use GtkStatusIcon instead of EggTrayIcon, that makes |
177 |
gtk_status_icon_set_tooltip(ta->tray_icon, |
178 |
_("Crash report detected")); |
|
179 |
gtk_status_icon_set_visible(ta->tray_icon, TRUE); |
|
311
by Martin Pitt
* src/crash.c: Do not show apport crash reports if above gconf key is false. |
180 |
/* Show the notification, after a delay so it doesn't look ugly
|
181 |
* if we've just logged in */
|
|
182 |
g_timeout_add(5000, (GSourceFunc)(show_notification), ta); |
|
253
by Michael Vogt
* improved the crash report handling: |
183 |
}
|
184 |
// crashreport found and already visible
|
|
282
by Martin Pitt
* src/crash.c: Only show a notification for system crash reports, do not |
185 |
else if((crashreports_found > 0) && !(system_crashes || first_run)) { |
262
by Michael Vogt
* src/crash.c: |
186 |
run_apport(ta); |
260
by Michael Vogt
* src/crash.c: |
187 |
// if apport was run, we don't care anymore and hide the icon
|
188 |
crashreports_found=0; |
|
253
by Michael Vogt
* improved the crash report handling: |
189 |
}
|
260
by Michael Vogt
* src/crash.c: |
190 |
|
253
by Michael Vogt
* improved the crash report handling: |
191 |
// no crashreports, but visible
|
260
by Michael Vogt
* src/crash.c: |
192 |
if((crashreports_found == 0) && visible) { |
262
by Michael Vogt
* src/crash.c: |
193 |
hide_crash_applet(ta); |
248
by Michael Vogt
* src/crash.{c,h}: |
194 |
}
|
195 |
||
610
by Michael Vogt
* src/crash.c: |
196 |
// special case for unity (and generally stuff that lacks a
|
197 |
// notification area, if the icon can not be embedded we just
|
|
198 |
// fire up apport regardless in-your-face
|
|
199 |
// WARNING: this needs to be *after* the normal operation
|
|
200 |
// and the event loop needs to be flushed, otherwise
|
|
201 |
// gtk_status_icon_is_embedded() will return FALSE
|
|
202 |
while (gtk_events_pending()) |
|
203 |
gtk_main_iteration(); |
|
204 |
if (!gtk_status_icon_is_embedded (ta->tray_icon) && |
|
205 |
crashreports_found > 0) { |
|
206 |
g_debug("unity handler"); |
|
207 |
crashreports_found=0; |
|
208 |
run_apport(ta); |
|
209 |
return TRUE; |
|
210 |
}
|
|
211 |
||
212 |
||
253
by Michael Vogt
* improved the crash report handling: |
213 |
first_run = FALSE; |
248
by Michael Vogt
* src/crash.{c,h}: |
214 |
return TRUE; |
215 |
}
|
|
216 |
||
217 |
static gboolean |
|
218 |
button_release_cb (GtkWidget *widget, |
|
219 |
TrayApplet *ta) |
|
220 |
{
|
|
607
by Michael Vogt
merged from seb128, modified slightly to make the unity special case more obvious |
221 |
run_apport(ta); |
222 |
hide_crash_applet(ta); |
|
223 |
return TRUE; |
|
248
by Michael Vogt
* src/crash.{c,h}: |
224 |
}
|
225 |
||
610
by Michael Vogt
* src/crash.c: |
226 |
static gboolean |
227 |
crashreport_check_initially(TrayApplet *ta) |
|
228 |
{
|
|
229 |
crashreport_check(ta); |
|
230 |
// stop timeout handler
|
|
231 |
return FALSE; |
|
232 |
}
|
|
248
by Michael Vogt
* src/crash.{c,h}: |
233 |
|
234 |
void
|
|
235 |
crashreport_tray_icon_init (TrayApplet *ta) |
|
236 |
{
|
|
237 |
||
238 |
ta->user_data = gconf_client_get_default(); |
|
239 |
g_signal_connect (G_OBJECT(ta->tray_icon), |
|
329
by Michael Vogt
* use GtkStatusIcon instead of EggTrayIcon, that makes |
240 |
"activate", |
248
by Michael Vogt
* src/crash.{c,h}: |
241 |
G_CALLBACK (button_release_cb), |
242 |
ta); |
|
243 |
||
244 |
/* Check for crashes for the first time */
|
|
610
by Michael Vogt
* src/crash.c: |
245 |
g_timeout_add_seconds(1, crashreport_check_initially, ta); |
248
by Michael Vogt
* src/crash.{c,h}: |
246 |
}
|