From b4d453b526f937a367ca2cdc8c313e21e12c5139 Mon Sep 17 00:00:00 2001 From: Mike Massonnet Date: Tue, 3 Aug 2010 22:29:42 +0200 Subject: [PATCH] Put "Execute" items within a sub-classed GtkMenuToolButton New class XtmExecToolButton that replaces the old GtkToolButton for the execution menu. The toolbar style is set to the default behavior (no forced labels). --- src/Makefile.am | 1 + src/exec-tool-button.c | 215 +++++++++++++++++++++++++++++++++++++++++ src/exec-tool-button.h | 32 ++++++ src/process-window.c | 98 +------------------ src/process-window.ui | 15 +-- 5 files changed, 255 insertions(+), 106 deletions(-) create mode 100644 src/exec-tool-button.c create mode 100644 src/exec-tool-button.h diff --git a/src/Makefile.am b/src/Makefile.am index b9a3b5a..87df5eb 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -29,6 +29,7 @@ xfce4_taskmanager_SOURCES = \ process-monitor.c process-monitor.h \ process-tree-view.c process-tree-view.h \ process-statusbar.c process-statusbar.h \ + exec-tool-button.c exec-tool-button.h \ task-manager.c task-manager.h \ settings.c settings.h \ $(NULL) diff --git a/src/exec-tool-button.c b/src/exec-tool-button.c new file mode 100644 index 0000000..960e525 --- /dev/null +++ b/src/exec-tool-button.c @@ -0,0 +1,215 @@ +/* + * Copyright (c) 2010 Mike Massonnet, + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include + +#include "exec-tool-button.h" + + + +typedef struct _XtmExecToolButtonClass XtmExecToolButtonClass; +struct _XtmExecToolButtonClass +{ + GtkMenuToolButtonClass parent_class; +}; +struct _XtmExecToolButton +{ + GtkMenuToolButton parent; + /**/ +}; +G_DEFINE_TYPE (XtmExecToolButton, xtm_exec_tool_button, GTK_TYPE_MENU_TOOL_BUTTON) + +static void xtm_exec_tool_button_finalize (GObject *object); + +static GtkWidget * construct_menu (); +static void execute_default_command (); + + + +static void +xtm_exec_tool_button_class_init (XtmExecToolButtonClass *klass) +{ + GObjectClass *class = G_OBJECT_CLASS (klass); + xtm_exec_tool_button_parent_class = g_type_class_peek_parent (klass); + class->finalize = xtm_exec_tool_button_finalize; +} + +static void +xtm_exec_tool_button_init (XtmExecToolButton *button) +{ + GtkWidget *menu; + + gtk_tool_button_set_stock_id (GTK_TOOL_BUTTON (button), "gtk-execute"); + gtk_tool_button_set_use_underline (GTK_TOOL_BUTTON (button), TRUE); + + menu = construct_menu (); + gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (button), menu); + g_signal_connect (button, "clicked", G_CALLBACK (execute_default_command), NULL); + + gtk_widget_show_all (GTK_WIDGET (button)); +} + +static void +xtm_exec_tool_button_finalize (GObject *object) +{ + G_OBJECT_CLASS (xtm_exec_tool_button_parent_class)->finalize (object); +} + + + +#ifdef HAVE_GKSU +static void +run_as_root (GtkWidget *mi) +{ + // TODO hide status icon + GtkWidget *window = gtk_widget_get_toplevel (mi); + gtk_widget_hide (window); + gksu_run (g_get_prgname (), NULL); + gtk_widget_show (window); +} +#endif + +static void +execute_command (const gchar *command) +{ + GError *error = NULL; + + gdk_spawn_command_line_on_screen (gdk_screen_get_default (), command, &error); + if (error != NULL) + { + GtkWidget *dialog = gtk_message_dialog_new (NULL, 0, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, + _("Execution error")); + gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), "%s", error->message); + gtk_window_set_title (GTK_WINDOW (dialog), _("Task Manager")); + gtk_dialog_run (GTK_DIALOG (dialog)); + gtk_widget_destroy (dialog); + g_error_free (error); + } +} + +static gboolean +program_exists (gchar *program) +{ + gchar *program_path = g_find_program_in_path (program); + if (program_path == NULL) + return FALSE; + g_free (program_path); + return TRUE; +} + +static void +execute_default_command () +{ + static gchar *command = NULL; + + if (command == NULL) + { + /* Find a runner program */ + if (program_exists ("xfrun4")) + command = g_strdup ("xfrun4"); + else if (program_exists ("gmrun")) + command = g_strdup ("gmrun"); + else if (program_exists ("gexec")) + command = g_strdup ("gexec"); + /* Find an applications-listing program */ + else if (program_exists ("xfce4-appfinder")) + command = g_strdup ("xfce4-appfinder"); + /* Find a terminal emulator */ + else if (program_exists ("exo-open")) + command = g_strdup ("exo-open --launch TerminalEmulator"); + else if (program_exists ("xterm")) + command = g_strdup ("xterm -fg grey -bg black"); + else + { + GtkWidget *dialog = gtk_message_dialog_new (NULL, 0, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, + _("Execution error")); + gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), + _("Couldn't find any default command to run.")); + gtk_window_set_title (GTK_WINDOW (dialog), _("Task Manager")); + gtk_dialog_run (GTK_DIALOG (dialog)); + gtk_widget_destroy (dialog); + return; + } + } + + execute_command (command); +} + +static void +menu_append_item (GtkMenu *menu, gchar *title, gchar *command, gchar *icon_name) +{ + GtkWidget *image = gtk_image_new_from_icon_name (icon_name, GTK_ICON_SIZE_MENU); + GtkWidget *mi = gtk_image_menu_item_new_with_label (title); + gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (mi), image); + gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi); + g_signal_connect_swapped (mi, "activate", G_CALLBACK (execute_command), command); +} + +static inline GtkWidget * +construct_menu () +{ + GtkWidget *menu = gtk_menu_new (); + +#ifdef HAVE_GKSU + /* Run task manager as root */ + if (geteuid () != 0) + { + GtkWidget *image = gtk_image_new_from_icon_name ("utilities-system-monitor", GTK_ICON_SIZE_MENU); + GtkWidget *mi = gtk_image_menu_item_new_with_label (_("Run Task Manager as root")); + gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (mi), image); + gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi); + g_signal_connect (mi, "activate", G_CALLBACK (run_as_root), NULL); + mi = gtk_separator_menu_item_new (); + gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi); + } +#endif + + /* Find a runner program */ + if (program_exists ("xfrun4")) + menu_append_item (GTK_MENU (menu), _("Run Program..."), "xfrun4", "system-run"); + else if (program_exists ("gmrun")) + menu_append_item (GTK_MENU (menu), _("Run Program..."), "gmrun", "system-run"); + else if (program_exists ("gexec")) + menu_append_item (GTK_MENU (menu), _("Run Program..."), "gexec", "system-run"); + /* Find an applications-listing program */ + if (program_exists ("xfce4-appfinder")) + menu_append_item (GTK_MENU (menu), _("Application Finder"), "xfce4-appfinder", "xfce4-appfinder"); + /* Find a terminal emulator */ + if (program_exists ("exo-open")) + menu_append_item (GTK_MENU (menu), _("Terminal emulator"), "exo-open --launch TerminalEmulator", "terminal"); + else if (program_exists ("xterm")) + menu_append_item (GTK_MENU (menu), _("XTerm"), "xterm -fg grey -bg black", "terminal"); + gtk_widget_show_all (menu); + + return menu; +} + +static void +position_menu (GtkMenu *menu, gint *x, gint *y, gboolean *push_in, GtkWidget *widget) +{ + gdk_window_get_origin (widget->window, x, y); + *x += widget->allocation.x; + *y += widget->allocation.height; + *push_in = TRUE; +} + + + +GtkWidget * +xtm_exec_tool_button_new (void) +{ + return g_object_new (XTM_TYPE_EXEC_TOOL_BUTTON, NULL); +} + diff --git a/src/exec-tool-button.h b/src/exec-tool-button.h new file mode 100644 index 0000000..a08aecc --- /dev/null +++ b/src/exec-tool-button.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2010 Mike Massonnet, + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#ifndef EXEC_TOOL_BUTTON_H +#define EXEC_TOOL_BUTTON_H + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include + +#define XTM_TYPE_EXEC_TOOL_BUTTON (xtm_exec_tool_button_get_type ()) +#define XTM_EXEC_TOOL_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), XTM_TYPE_EXEC_TOOL_BUTTON, XtmExecToolButton)) +#define XTM_EXEC_TOOL_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), XTM_TYPE_EXEC_TOOL_BUTTON, XtmExecToolButtonClass)) +#define XTM_IS_EXEC_TOOL_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), XTM_TYPE_EXEC_TOOL_BUTTON)) +#define XTM_IS_EXEC_TOOL_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), XTM_TYPE_EXEC_TOOL_BUTTON)) +#define XTM_EXEC_TOOL_BUTTON_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), XTM_TYPE_EXEC_TOOL_BUTTON, XtmExecToolButtonClass)) + +typedef struct _XtmExecToolButton XtmExecToolButton; + +GType xtm_exec_tool_button_get_type (void); +GtkWidget * xtm_exec_tool_button_new (); + +#endif /* !EXEC_TOOL_BUTTON_H */ diff --git a/src/process-window.c b/src/process-window.c index ec40ab8..3aa20f2 100644 --- a/src/process-window.c +++ b/src/process-window.c @@ -29,6 +29,7 @@ #include "process-monitor.h" #include "process-tree-view.h" #include "process-statusbar.h" +#include "exec-tool-button.h" @@ -143,8 +144,8 @@ xtm_process_window_init (XtmProcessWindow *window) gtk_widget_show (window->priv->statusbar); gtk_box_pack_start (GTK_BOX (gtk_builder_get_object (window->priv->builder, "process-vbox")), window->priv->statusbar, FALSE, FALSE, 0); - button = GTK_WIDGET (gtk_builder_get_object (window->priv->builder, "toolbutton-execute")); - g_signal_connect_swapped (button, "clicked", G_CALLBACK (show_menu_execute_task), window); + button = xtm_exec_tool_button_new (); + gtk_container_add (GTK_CONTAINER (gtk_builder_get_object (window->priv->builder, "toolbutton-execute")), button); button = GTK_WIDGET (gtk_builder_get_object (window->priv->builder, "toolbutton-preferences")); g_signal_connect_swapped (button, "clicked", G_CALLBACK (show_menu_preferences), window); @@ -223,99 +224,6 @@ menu_position_func (GtkMenu *menu, gint *x, gint *y, gboolean *push_in, GtkWidge *push_in = TRUE; } -#ifdef HAVE_GKSU -static void -run_as_root (XtmProcessWindow *window) -{ - gtk_widget_hide (window->priv->window); - gksu_run (g_get_prgname (), NULL); - gtk_widget_show (window->priv->window); -} -#endif - -static void -execute_command (const gchar *command) -{ - GError *error = NULL; - - gdk_spawn_command_line_on_screen (gdk_screen_get_default (), command, &error); - if (error != NULL) - { - GtkWidget *dialog = gtk_message_dialog_new (NULL, 0, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, - _("Execution error")); - gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), "%s", error->message); - gtk_window_set_title (GTK_WINDOW (dialog), _("Task Manager")); - gtk_dialog_run (GTK_DIALOG (dialog)); - gtk_widget_destroy (dialog); - g_error_free (error); - } -} - -static void -menu_execute_append_item (GtkMenu *menu, gchar *title, gchar *command, gchar *icon_name) -{ - GtkWidget *image = gtk_image_new_from_icon_name (icon_name, GTK_ICON_SIZE_MENU); - GtkWidget *mi = gtk_image_menu_item_new_with_label (title); - gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (mi), image); - gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi); - g_signal_connect_swapped (mi, "activate", G_CALLBACK (execute_command), command); -} - -static gboolean -program_exists (gchar *program) -{ - gchar *program_path = g_find_program_in_path (program); - if (program_path == NULL) - return FALSE; - g_free (program_path); - return TRUE; -} - -static void -show_menu_execute_task (XtmProcessWindow *window, GtkButton *button) -{ - static GtkWidget *menu = NULL; - - if (menu == NULL) - { - menu = gtk_menu_new (); - -#ifdef HAVE_GKSU - /* Run task manager as root */ - if (geteuid () != 0) - { - GtkWidget *image = gtk_image_new_from_icon_name ("utilities-system-monitor", GTK_ICON_SIZE_MENU); - GtkWidget *mi = gtk_image_menu_item_new_with_label (_("Run Task Manager as root")); - gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (mi), image); - gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi); - g_signal_connect_swapped (mi, "activate", G_CALLBACK (run_as_root), window); - - mi = gtk_separator_menu_item_new (); - gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi); - } -#endif - - /* Find a runner program */ - if (program_exists ("xfrun4")) - menu_execute_append_item (GTK_MENU (menu), _("Run Program..."), "xfrun4", "system-run"); - else if (program_exists ("gmrun")) - menu_execute_append_item (GTK_MENU (menu), _("Run Program..."), "gmrun", "system-run"); - else if (program_exists ("gexec")) - menu_execute_append_item (GTK_MENU (menu), _("Run Program..."), "gexec", "system-run"); - /* Find an applications list program */ - if (program_exists ("xfce4-appfinder")) - menu_execute_append_item (GTK_MENU (menu), _("Application Finder"), "xfce4-appfinder", "xfce4-appfinder"); - /* Find a terminal emulator */ - if (program_exists ("exo-open")) - menu_execute_append_item (GTK_MENU (menu), _("Terminal emulator"), "exo-open --launch TerminalEmulator", "terminal"); - else if (program_exists ("xterm")) - menu_execute_append_item (GTK_MENU (menu), _("XTerm"), "xterm -fg grey -bg black", "terminal"); - gtk_widget_show_all (menu); - } - - gtk_menu_popup (GTK_MENU (menu), NULL, NULL, (GtkMenuPositionFunc)menu_position_func, button, 0, gtk_get_current_event_time ()); -} - static void refresh_rate_toggled (GtkCheckMenuItem *mi, XtmSettings *settings) { diff --git a/src/process-window.ui b/src/process-window.ui index ea592be..ff61708 100644 --- a/src/process-window.ui +++ b/src/process-window.ui @@ -14,31 +14,28 @@ True - both False 1 - + True True - True - gtk-execute + + + False - True True - True True gtk-preferences False - True @@ -75,19 +72,16 @@ False - True True - True True gtk-quit False - True @@ -144,7 +138,6 @@ True automatic automatic - none