1 /*
2 * Copyright (c) 2010 Mike Massonnet, <mmassonnet@xfce.org>
3 *
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 (at
7 * your option) any later version.
8 */
9
10 #ifdef HAVE_CONFIG_H
11 #include <config.h>
12 #endif
13
14 #ifdef HAVE_UNISTD_H
15 #include <unistd.h>
16 #endif
17
18 #include <X11/Xlib.h>
19 #include <X11/Xutil.h>
20 #include <X11/Xatom.h>
21 #include <X11/Xos.h>
22 #include <X11/Xmu/WinUtil.h>
23 #include <X11/cursorfont.h>
24 #include <X11/Xproto.h>
25
26 #include <glib-object.h>
27 #include <glib/gi18n.h>
28 #include <gtk/gtk.h>
29 #include <gdk/gdkkeysyms.h>
30
31 #include "settings.h"
32 #include "task-manager.h"
33 #include "process-window.h"
34 #include "process-window_ui.h"
35 #include "process-monitor.h"
36 #include "process-tree-view.h"
37 #include "process-statusbar.h"
38 #include "exec-tool-button.h"
39 #include "settings-tool-button.h"
40
41
42
43 typedef struct _XtmProcessWindowClass XtmProcessWindowClass;
44 struct _XtmProcessWindowClass
45 {
46 GtkWidgetClass parent_class;
47 };
48
49 struct _XtmProcessWindow
50 {
51 GtkWidget parent;
52 /*<private>*/
53 GtkBuilder * builder;
54 GtkWidget * window;
55 GtkWidget * toolbar;
56 GtkWidget * filter_entry;
57 GtkWidget * cpu_monitor;
58 GtkWidget * mem_monitor;
59 GtkWidget * vpaned;
60 GtkWidget * treeview;
61 GtkWidget * statusbar;
62 GtkWidget * exec_button;
63 GtkWidget * settings_button;
64 XtmSettings * settings;
65 };
66 G_DEFINE_TYPE (XtmProcessWindow, xtm_process_window, GTK_TYPE_WIDGET)
67
68 static void xtm_process_window_finalize (GObject *object);
69 static void xtm_process_window_hide (GtkWidget *widget);
70
71 static void emit_destroy_signal (XtmProcessWindow *window);
72 static gboolean xtm_process_window_configure_event (XtmProcessWindow *window, GdkEvent *event);
73 static gboolean xtm_process_vpaned_move_event (XtmProcessWindow *window, GdkEventButton *event);
74 static gboolean xtm_process_window_key_pressed (XtmProcessWindow *window, GdkEventKey *event);
75 static void toolbar_update_style (XtmProcessWindow *window);
76 static void monitor_update_step_size (XtmProcessWindow *window);
77 static void show_about_dialog (XtmProcessWindow *window);
78
79
80 static void
filter_entry_icon_pressed_cb(GtkEntry * entry,gint position,GdkEventButton * event __unused,gpointer data __unused)81 filter_entry_icon_pressed_cb (GtkEntry *entry,
82 gint position,
83 GdkEventButton *event __unused,
84 gpointer data __unused)
85 {
86 if (position == GTK_ENTRY_ICON_SECONDARY) {
87 gtk_entry_set_text (entry, "");
88 gtk_widget_grab_focus (GTK_WIDGET(entry));
89 }
90 }
91
92 static Window
Select_Window(Display * dpy,int screen)93 Select_Window (Display *dpy, int screen)
94 {
95 int status;
96 Cursor cursor;
97 XEvent event;
98 Window target_win = None, root = RootWindow(dpy,screen);
99 int buttons = 0;
100
101 /* Make the target cursor */
102 cursor = XCreateFontCursor(dpy, XC_crosshair);
103
104 /* Grab the pointer using target cursor, letting it roam all over */
105 status = XGrabPointer(dpy, root, False,
106 ButtonPressMask|ButtonReleaseMask, GrabModeSync,
107 GrabModeAsync, root, cursor, CurrentTime);
108 if (status != GrabSuccess) {
109 fprintf (stderr, "Can't grab the mouse.\n");
110 return None;
111 }
112
113 /* Let the user select a window... */
114 while ((target_win == None) || (buttons != 0)) {
115 /* allow one more event */
116 XAllowEvents(dpy, SyncPointer, CurrentTime);
117 XWindowEvent(dpy, root, ButtonPressMask|ButtonReleaseMask, &event);
118 switch (event.type) {
119 case ButtonPress:
120 if (target_win == None) {
121 target_win = event.xbutton.subwindow; /* window selected */
122 if (target_win == None) target_win = root;
123 }
124 buttons++;
125 break;
126 case ButtonRelease:
127 if (buttons > 0) /* there may have been some down before we started */
128 buttons--;
129 break;
130 }
131 }
132
133 XUngrabPointer(dpy, CurrentTime); /* Done with pointer */
134
135 return target_win;
136 }
137
138 static void
xwininfo_clicked_cb(GtkButton * button __unused,gpointer user_data)139 xwininfo_clicked_cb (GtkButton *button __unused, gpointer user_data) {
140 XtmProcessWindow *window = (XtmProcessWindow *) user_data;
141 Window selected_window;
142 Display *dpy;
143 Atom atom_NET_WM_PID;
144 unsigned long _nitems;
145 Atom actual_type;
146 int actual_format;
147 unsigned char *prop;
148 int status;
149 unsigned long bytes_after;
150 GPid pid = 0;
151
152 dpy = XOpenDisplay (NULL);
153 selected_window = Select_Window (dpy, 0);
154 if (selected_window) {
155 selected_window = XmuClientWindow (dpy, selected_window);
156 }
157
158 atom_NET_WM_PID = XInternAtom(dpy, "_NET_WM_PID", False);
159
160 status = XGetWindowProperty(dpy, selected_window, atom_NET_WM_PID, 0, (~0L),
161 False, AnyPropertyType, &actual_type,
162 &actual_format, &_nitems, &bytes_after,
163 &prop);
164 if (status == BadWindow) {
165 XTM_SHOW_MESSAGE(GTK_MESSAGE_INFO,
166 _("Bad Window"), _("Window id 0x%lx does not exist!"), selected_window);
167 } if (status != Success) {
168 XTM_SHOW_MESSAGE(GTK_MESSAGE_ERROR,
169 _("XGetWindowProperty failed"), _("XGetWindowProperty failed!"));
170 } else {
171 if (_nitems > 0) {
172 memcpy(&pid, prop, sizeof(pid));
173 xtm_process_tree_view_highlight_pid(XTM_PROCESS_TREE_VIEW (window->treeview), pid);
174 } else {
175 XTM_SHOW_MESSAGE(GTK_MESSAGE_INFO,
176 _("No PID found"), _("No PID found for window 0x%lx."), selected_window);
177 }
178 g_free(prop);
179 }
180
181 }
182
183 static void
filter_entry_keyrelease_handler(GtkEntry * entry,XtmProcessTreeView * treeview)184 filter_entry_keyrelease_handler(GtkEntry *entry,
185 XtmProcessTreeView *treeview)
186 {
187 const gchar *text;
188 gboolean has_text;
189
190 text = gtk_editable_get_chars (GTK_EDITABLE(entry), 0, -1);
191 xtm_process_tree_view_set_filter(treeview, text);
192
193 has_text = gtk_entry_get_text_length (GTK_ENTRY(entry)) > 0;
194 gtk_entry_set_icon_sensitive (GTK_ENTRY(entry),
195 GTK_ENTRY_ICON_SECONDARY,
196 has_text);
197 }
198
199 static void
xtm_process_window_class_init(XtmProcessWindowClass * klass)200 xtm_process_window_class_init (XtmProcessWindowClass *klass)
201 {
202 GObjectClass *class;
203 GtkWidgetClass *widget_class;
204
205 xtm_process_window_parent_class = g_type_class_peek_parent (klass);
206 class = G_OBJECT_CLASS (klass);
207 class->finalize = xtm_process_window_finalize;
208 widget_class = GTK_WIDGET_CLASS (klass);
209 widget_class->show = xtm_process_window_show;
210 widget_class->hide = xtm_process_window_hide;
211 }
212
213 static void
xtm_show_legend(XtmProcessWindow * window)214 xtm_show_legend (XtmProcessWindow *window)
215 {
216 gboolean show_legend;
217
218 g_object_get (window->settings,
219 "show-legend", &show_legend,
220 NULL);
221 gtk_widget_set_visible (GTK_WIDGET (gtk_builder_get_object (window->builder, "legend")), show_legend);
222 }
223
224 static void
xtm_process_window_init(XtmProcessWindow * window)225 xtm_process_window_init (XtmProcessWindow *window)
226 {
227 GtkWidget *button;
228 GtkWidget *icon;
229 GtkToolItem *xwininfo;
230 gint width, height;
231 gboolean show_legend;
232
233 window->settings = xtm_settings_get_default ();
234
235 window->builder = gtk_builder_new ();
236 gtk_builder_add_from_string (window->builder, process_window_ui, process_window_ui_length, NULL);
237
238 window->window = GTK_WIDGET (gtk_builder_get_object (window->builder, "process-window"));
239 g_object_get (window->settings, "window-width", &width, "window-height", &height, NULL);
240 if (width >= 1 && height >= 1)
241 gtk_window_resize (GTK_WINDOW (window->window), width, height);
242 g_signal_connect_swapped (window->window, "destroy", G_CALLBACK (emit_destroy_signal), window);
243 g_signal_connect_swapped (window->window, "key-press-event", G_CALLBACK(xtm_process_window_key_pressed), window);
244 g_signal_connect_swapped(window->window, "configure-event",
245 G_CALLBACK(xtm_process_window_configure_event), window);
246
247 window->toolbar = GTK_WIDGET (gtk_builder_get_object (window->builder, "process-toolbar"));
248 g_signal_connect_swapped (window->settings, "notify::toolbar-style", G_CALLBACK (toolbar_update_style), window);
249 g_object_notify (G_OBJECT (window->settings), "toolbar-style");
250
251 window->exec_button = xtm_exec_tool_button_new ();
252 gtk_toolbar_insert (GTK_TOOLBAR (window->toolbar), GTK_TOOL_ITEM (window->exec_button), 0);
253
254 window->settings_button = xtm_settings_tool_button_new ();
255 gtk_toolbar_insert (GTK_TOOLBAR (window->toolbar), GTK_TOOL_ITEM (window->settings_button), 1);
256 g_signal_connect_swapped (window->settings, "notify::show-legend", G_CALLBACK (xtm_show_legend), window);
257 g_object_notify (G_OBJECT (window->settings), "show-legend");
258
259 icon = gtk_image_new_from_icon_name ("xc_crosshair", GTK_ICON_SIZE_LARGE_TOOLBAR);
260 xwininfo = gtk_tool_button_new (icon, _("Identify Window"));
261 gtk_widget_set_tooltip_text (GTK_WIDGET (xwininfo), _("Identify an open window by clicking on it."));
262 gtk_toolbar_insert (GTK_TOOLBAR (window->toolbar), GTK_TOOL_ITEM (xwininfo), 2);
263 g_signal_connect (G_OBJECT (xwininfo), "clicked",
264 G_CALLBACK (xwininfo_clicked_cb), window);
265 gtk_widget_show_all (GTK_WIDGET (xwininfo));
266
267 button = GTK_WIDGET (gtk_builder_get_object (window->builder, "toolbutton-about"));
268 g_signal_connect_swapped (button, "clicked", G_CALLBACK (show_about_dialog), window);
269
270 {
271 GtkWidget *toolitem;
272 guint refresh_rate;
273 gint handle_position;
274
275 g_object_get (window->settings,
276 "refresh-rate", &refresh_rate,
277 "handle-position", &handle_position,
278 NULL);
279
280 window->vpaned = GTK_WIDGET (gtk_builder_get_object (window->builder, "mainview-vpaned"));
281 if (handle_position > -1)
282 gtk_paned_set_position (GTK_PANED (window->vpaned), handle_position);
283 g_signal_connect_swapped(window->vpaned, "button-release-event",
284 G_CALLBACK(xtm_process_vpaned_move_event), window);
285
286 toolitem = GTK_WIDGET (gtk_builder_get_object (window->builder, "graph-cpu"));
287 window->cpu_monitor = xtm_process_monitor_new ();
288 xtm_process_monitor_set_step_size (XTM_PROCESS_MONITOR (window->cpu_monitor), refresh_rate / 1000.0f);
289 xtm_process_monitor_set_type (XTM_PROCESS_MONITOR (window->cpu_monitor), 0);
290 gtk_widget_show (window->cpu_monitor);
291 gtk_container_add (GTK_CONTAINER (toolitem), window->cpu_monitor);
292
293 toolitem = GTK_WIDGET (gtk_builder_get_object (window->builder, "graph-mem"));
294 window->mem_monitor = xtm_process_monitor_new ();
295 xtm_process_monitor_set_step_size (XTM_PROCESS_MONITOR (window->mem_monitor), refresh_rate / 1000.0f);
296 xtm_process_monitor_set_type (XTM_PROCESS_MONITOR (window->mem_monitor), 1);
297 gtk_widget_show (window->mem_monitor);
298 gtk_container_add (GTK_CONTAINER (toolitem), window->mem_monitor);
299
300 g_signal_connect_swapped (window->settings, "notify::refresh-rate", G_CALLBACK (monitor_update_step_size), window);
301 }
302
303 window->statusbar = xtm_process_statusbar_new ();
304 gtk_widget_show (window->statusbar);
305 gtk_box_pack_start (GTK_BOX (gtk_builder_get_object (window->builder, "graph-vbox")), window->statusbar, FALSE, FALSE, 0);
306
307 if (geteuid () == 0)
308 {
309 GtkCssProvider *css_provider;
310 css_provider = gtk_css_provider_new ();
311 gtk_css_provider_load_from_data (css_provider,
312 "#root-warning { background-color: #e53935; color: #ffffff; }",
313 -1, NULL);
314 gtk_style_context_add_provider_for_screen (gdk_screen_get_default (), GTK_STYLE_PROVIDER (css_provider),
315 GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
316 g_object_unref (css_provider);
317 gtk_widget_set_name (GTK_WIDGET (gtk_builder_get_object (window->builder, "root-warning-ebox")), "root-warning");
318 gtk_widget_show_all (GTK_WIDGET (gtk_builder_get_object (window->builder, "root-warning-box")));
319 }
320
321 window->treeview = xtm_process_tree_view_new ();
322 gtk_widget_show (window->treeview);
323 gtk_container_add (GTK_CONTAINER (gtk_builder_get_object (window->builder, "scrolledwindow")), window->treeview);
324
325 g_object_get (window->settings,
326 "show-legend", &show_legend,
327 NULL);
328 gtk_widget_set_visible (GTK_WIDGET (gtk_builder_get_object (window->builder, "legend")), show_legend);
329
330 window->filter_entry = GTK_WIDGET(gtk_builder_get_object (window->builder, "filter-entry"));
331 g_signal_connect (G_OBJECT(window->filter_entry), "icon-press", G_CALLBACK(filter_entry_icon_pressed_cb), NULL);
332 g_signal_connect (G_OBJECT(window->filter_entry), "changed", G_CALLBACK(filter_entry_keyrelease_handler), window->treeview);
333 gtk_widget_set_tooltip_text (window->filter_entry, _("Filter on process name"));
334
335 gtk_widget_grab_focus (GTK_WIDGET (window->filter_entry));
336 }
337
338 static void
xtm_process_window_finalize(GObject * object)339 xtm_process_window_finalize (GObject *object)
340 {
341 XtmProcessWindow *window = XTM_PROCESS_WINDOW (object);
342
343 if (GTK_IS_TREE_VIEW (window->treeview))
344 gtk_widget_destroy (window->treeview);
345
346 if (GTK_IS_BOX (window->statusbar))
347 gtk_widget_destroy (window->statusbar);
348
349 if (GTK_IS_TOOL_ITEM (window->exec_button))
350 gtk_widget_destroy (window->exec_button);
351
352 if (GTK_IS_TOOL_ITEM (window->settings_button))
353 gtk_widget_destroy (window->settings_button);
354
355 if (XTM_IS_SETTINGS (window->settings))
356 g_object_unref (window->settings);
357
358 g_object_unref (window->builder);
359 window->builder = NULL;
360 }
361
362 /**
363 * Helper functions
364 */
365
366 static void
emit_destroy_signal(XtmProcessWindow * window)367 emit_destroy_signal (XtmProcessWindow *window)
368 {
369 g_signal_emit_by_name (window, "destroy", G_TYPE_NONE);
370 }
371
372 static gboolean
xtm_process_window_configure_event(XtmProcessWindow * window,GdkEvent * event)373 xtm_process_window_configure_event(XtmProcessWindow *window,
374 GdkEvent *event) {
375
376 if (NULL != window &&
377 NULL != event && GDK_CONFIGURE == event->configure.type) {
378 g_object_set (window->settings,
379 "window-width", event->configure.width,
380 "window-height", event->configure.height,
381 NULL);
382 }
383
384 return (FALSE);
385 }
386
387 static gboolean
xtm_process_vpaned_move_event(XtmProcessWindow * window,GdkEventButton * event __unused)388 xtm_process_vpaned_move_event(XtmProcessWindow *window,
389 GdkEventButton *event __unused) {
390 gint handle_position;
391
392 if (NULL != window) {
393 handle_position = gtk_paned_get_position(GTK_PANED(window->vpaned));
394 g_object_set (window->settings,
395 "handle-position", handle_position,
396 NULL);
397 }
398
399 return (FALSE);
400 }
401
402 static gboolean
xtm_process_window_key_pressed(XtmProcessWindow * window,GdkEventKey * event)403 xtm_process_window_key_pressed (XtmProcessWindow *window, GdkEventKey *event)
404 {
405 gboolean ret = FALSE;
406
407 if (event->keyval == GDK_KEY_Escape ||
408 (event->keyval == GDK_KEY_q && (event->state & GDK_CONTROL_MASK))) {
409 xtm_settings_save_settings (window->settings);
410 g_signal_emit_by_name (window, "delete-event", event, &ret, G_TYPE_BOOLEAN);
411 ret = TRUE;
412 }
413 else if (event->keyval == GDK_KEY_f && (event->state & GDK_CONTROL_MASK)) {
414 gtk_widget_grab_focus (GTK_WIDGET(window->filter_entry));
415 ret = TRUE;
416 }
417
418 return ret;
419 }
420
421 static void
toolbar_update_style(XtmProcessWindow * window)422 toolbar_update_style (XtmProcessWindow *window)
423 {
424 XtmToolbarStyle toolbar_style;
425 g_object_get (window->settings, "toolbar-style", &toolbar_style, NULL);
426 switch (toolbar_style)
427 {
428 default:
429 case XTM_TOOLBAR_STYLE_DEFAULT:
430 gtk_toolbar_set_icon_size (GTK_TOOLBAR (window->toolbar), GTK_ICON_SIZE_MENU);
431 gtk_toolbar_unset_style (GTK_TOOLBAR (window->toolbar));
432 break;
433
434 case XTM_TOOLBAR_STYLE_SMALL:
435 gtk_toolbar_set_icon_size (GTK_TOOLBAR (window->toolbar), GTK_ICON_SIZE_SMALL_TOOLBAR);
436 gtk_toolbar_set_style (GTK_TOOLBAR (window->toolbar), GTK_TOOLBAR_ICONS);
437 break;
438
439 case XTM_TOOLBAR_STYLE_LARGE:
440 gtk_toolbar_set_icon_size (GTK_TOOLBAR (window->toolbar), GTK_ICON_SIZE_LARGE_TOOLBAR);
441 gtk_toolbar_set_style (GTK_TOOLBAR (window->toolbar), GTK_TOOLBAR_ICONS);
442 break;
443
444 case XTM_TOOLBAR_STYLE_TEXT:
445 gtk_toolbar_set_icon_size (GTK_TOOLBAR (window->toolbar), GTK_ICON_SIZE_MENU);
446 gtk_toolbar_set_style (GTK_TOOLBAR (window->toolbar), GTK_TOOLBAR_BOTH);
447 break;
448 }
449 }
450
451 static void
monitor_update_step_size(XtmProcessWindow * window)452 monitor_update_step_size (XtmProcessWindow *window)
453 {
454 guint refresh_rate;
455 g_object_get (window->settings, "refresh-rate", &refresh_rate, NULL);
456 g_object_set (window->cpu_monitor, "step-size", refresh_rate / 1000.0, NULL);
457 g_object_set (window->mem_monitor, "step-size", refresh_rate / 1000.0, NULL);
458 }
459
460 static void
show_about_dialog(XtmProcessWindow * window)461 show_about_dialog (XtmProcessWindow *window)
462 {
463 const gchar *authors[] = {
464 "(c) 2018-2019 Rozhuk Ivan",
465 "(c) 2014 Landry Breuil",
466 "(c) 2014 Harald Judt",
467 "(c) 2014 Peter de Ridder",
468 "(c) 2014 Simon Steinbess",
469 "(c) 2008-2010 Mike Massonnet",
470 "(c) 2005-2008 Johannes Zellner",
471 "",
472 "FreeBSD",
473 " \342\200\242 Rozhuk Ivan",
474 " \342\200\242 Mike Massonnet",
475 " \342\200\242 Oliver Lehmann",
476 "",
477 "OpenBSD",
478 " \342\200\242 Landry Breuil",
479 "",
480 "Linux",
481 " \342\200\242 Johannes Zellner",
482 " \342\200\242 Mike Massonnet",
483 "",
484 "OpenSolaris",
485 " \342\200\242 Mike Massonnet",
486 " \342\200\242 Peter Tribble",
487 NULL };
488 const gchar *license =
489 "This program is free software; you can redistribute it and/or modify\n"
490 "it under the terms of the GNU General Public License as published by\n"
491 "the Free Software Foundation; either version 2 of the License, or\n"
492 "(at your option) any later version.\n";
493
494 gtk_show_about_dialog (GTK_WINDOW (window->window),
495 "program-name", _("Task Manager"),
496 "version", PACKAGE_VERSION,
497 "copyright", "Copyright \302\251 2005-2019 The Xfce development team",
498 "logo-icon-name", "org.xfce.taskmanager",
499 "comments", _("Easy to use task manager"),
500 "license", license,
501 "authors", authors,
502 "translator-credits", _("translator-credits"),
503 "website", "http://goodies.xfce.org/projects/applications/xfce4-taskmanager",
504 "website-label", "goodies.xfce.org",
505 NULL);
506 }
507
508 /**
509 * Class functions
510 */
511
512 GtkWidget *
xtm_process_window_new(void)513 xtm_process_window_new (void)
514 {
515 return g_object_new (XTM_TYPE_PROCESS_WINDOW, NULL);
516 }
517
518 void
xtm_process_window_show(GtkWidget * widget)519 xtm_process_window_show (GtkWidget *widget)
520 {
521 g_return_if_fail (GTK_IS_WIDGET (widget));
522 g_return_if_fail (GTK_IS_WIDGET (XTM_PROCESS_WINDOW (widget)->window));
523 gtk_widget_show (XTM_PROCESS_WINDOW (widget)->window);
524 gtk_window_present (GTK_WINDOW (XTM_PROCESS_WINDOW (widget)->window));
525 GTK_WIDGET_CLASS (xtm_process_window_parent_class)->show(widget);
526 }
527
528 static void
xtm_process_window_hide(GtkWidget * widget)529 xtm_process_window_hide (GtkWidget *widget)
530 {
531 gint winx, winy;
532 g_return_if_fail (GTK_IS_WIDGET (widget));
533 if (!GTK_IS_WIDGET (XTM_PROCESS_WINDOW (widget)->window))
534 return;
535 gtk_window_get_position (GTK_WINDOW (XTM_PROCESS_WINDOW (widget)->window), &winx, &winy);
536 gtk_widget_hide (XTM_PROCESS_WINDOW (widget)->window);
537 gtk_window_move (GTK_WINDOW (XTM_PROCESS_WINDOW (widget)->window), winx, winy);
538 GTK_WIDGET_CLASS (xtm_process_window_parent_class)->hide(widget);
539 }
540
541 GtkTreeModel *
xtm_process_window_get_model(XtmProcessWindow * window)542 xtm_process_window_get_model (XtmProcessWindow *window)
543 {
544 g_return_val_if_fail (XTM_IS_PROCESS_WINDOW (window), NULL);
545 g_return_val_if_fail (XTM_IS_PROCESS_TREE_VIEW (window->treeview), NULL);
546 return xtm_process_tree_view_get_model (XTM_PROCESS_TREE_VIEW (window->treeview));
547 }
548
549 void
xtm_process_window_set_system_info(XtmProcessWindow * window,guint num_processes,gfloat cpu,gfloat memory,gchar * memory_str,gfloat swap __unused,gchar * swap_str)550 xtm_process_window_set_system_info (XtmProcessWindow *window, guint num_processes, gfloat cpu, gfloat memory, gchar* memory_str, gfloat swap __unused, gchar* swap_str)
551 {
552 gchar text[100];
553 gchar value[4];
554
555 g_return_if_fail (XTM_IS_PROCESS_WINDOW (window));
556 g_return_if_fail (GTK_IS_BOX (window->statusbar));
557
558 g_object_set (window->statusbar, "num-processes", num_processes, "cpu", cpu, "memory", memory_str, "swap", swap_str, NULL);
559
560 xtm_process_monitor_add_peak (XTM_PROCESS_MONITOR (window->cpu_monitor), cpu / 100.0f);
561 g_snprintf (value, sizeof(value), "%.0f", cpu);
562 g_snprintf (text, sizeof(text), _("CPU: %s%%"), value);
563 gtk_widget_set_tooltip_text (window->cpu_monitor, text);
564
565 xtm_process_monitor_add_peak (XTM_PROCESS_MONITOR (window->mem_monitor), memory / 100.0f);
566 g_snprintf (text, sizeof(text), _("Memory: %s"), memory_str);
567 gtk_widget_set_tooltip_text (window->mem_monitor, text);
568 }
569
570 void
xtm_process_window_show_swap_usage(XtmProcessWindow * window,gboolean show_swap_usage)571 xtm_process_window_show_swap_usage (XtmProcessWindow *window, gboolean show_swap_usage)
572 {
573 g_return_if_fail (XTM_IS_PROCESS_WINDOW (window));
574 g_return_if_fail (GTK_IS_BOX (window->statusbar));
575 g_object_set (window->statusbar, "show-swap", show_swap_usage, NULL);
576 }
577