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