[Xfce4-commits] <thunar:nick/uca-startup-notification> Add support for startup notification to the UCA plugin.
Nick Schermer
noreply at xfce.org
Wed Nov 4 16:02:02 CET 2009
Updating branch refs/heads/nick/uca-startup-notification
to 84f07c2df64bf59bc21d7e0971148316b8df6cda (commit)
from 118999809103507688d0413c2136a2a3422ae609 (commit)
commit 84f07c2df64bf59bc21d7e0971148316b8df6cda
Author: Nick Schermer <nick at xfce.org>
Date: Wed Nov 4 16:00:40 2009 +0100
Add support for startup notification to the UCA plugin.
plugins/thunar-uca/Makefile.am | 6 ++
plugins/thunar-uca/thunar-uca-editor.c | 22 ++++++--
plugins/thunar-uca/thunar-uca-model.c | 27 ++++++++++
plugins/thunar-uca/thunar-uca-model.h | 2 +
plugins/thunar-uca/thunar-uca-provider.c | 81 ++++++++++++++---------------
5 files changed, 91 insertions(+), 47 deletions(-)
diff --git a/plugins/thunar-uca/Makefile.am b/plugins/thunar-uca/Makefile.am
index e9a05a4..2e37016 100644
--- a/plugins/thunar-uca/Makefile.am
+++ b/plugins/thunar-uca/Makefile.am
@@ -33,8 +33,14 @@ thunar_uca_la_SOURCES = \
thunar_uca_la_CFLAGS = \
$(EXO_CFLAGS) \
$(LIBXFCE4UTIL_CFLAGS) \
+ $(LIBXFCE4UI_CFLAGS) \
$(PLATFORM_CFLAGS)
+thunar_uca_la_LIBADD = \
+ $(EXO_LIBS) \
+ $(LIBXFCE4UTIL_LIBS) \
+ $(LIBXFCE4UI_LIBS)
+
thunar_uca_la_LDFLAGS = \
-avoid-version \
-export-dynamic \
diff --git a/plugins/thunar-uca/thunar-uca-editor.c b/plugins/thunar-uca/thunar-uca-editor.c
index e513fbd..eac1241 100644
--- a/plugins/thunar-uca/thunar-uca-editor.c
+++ b/plugins/thunar-uca/thunar-uca-editor.c
@@ -59,6 +59,7 @@ struct _ThunarUcaEditor
GtkWidget *description_entry;
GtkWidget *icon_button;
GtkWidget *command_entry;
+ GtkWidget *sn_button;
GtkWidget *parameter_entry;
GtkWidget *patterns_entry;
GtkWidget *directories_button;
@@ -119,7 +120,7 @@ thunar_uca_editor_init (ThunarUcaEditor *uca_editor)
Basic
*/
label = gtk_label_new (_("Basic"));
- table = gtk_table_new (6, 2, FALSE);
+ table = gtk_table_new (7, 2, FALSE);
gtk_table_set_col_spacings (GTK_TABLE (table), 12);
gtk_table_set_row_spacings (GTK_TABLE (table), 6);
gtk_container_set_border_width (GTK_CONTAINER (table), 12);
@@ -199,12 +200,19 @@ thunar_uca_editor_init (ThunarUcaEditor *uca_editor)
atk_relation_set_add (relations, relation);
g_object_unref (G_OBJECT (relation));
+ uca_editor->sn_button = gtk_check_button_new_with_label (_("Use Startup Notification"));
+ gtk_widget_set_tooltip_text (uca_editor->sn_button, _("Enable this option if you want a waiting cursor when the action "
+ "is launched. This is also highly recommended when you have focus "
+ "stealing enabled in your window manager."));
+ gtk_table_attach (GTK_TABLE (table), uca_editor->sn_button, 1, 2, 3, 4, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
+ gtk_widget_show (uca_editor->sn_button);
+
label = g_object_new (GTK_TYPE_LABEL, "label", _("_Icon:"), "use-underline", TRUE, "xalign", 0.0f, NULL);
- gtk_table_attach (GTK_TABLE (table), label, 0, 1, 3, 4, GTK_FILL, GTK_FILL, 0, 0);
+ gtk_table_attach (GTK_TABLE (table), label, 0, 1, 4, 5, GTK_FILL, GTK_FILL, 0, 0);
gtk_widget_show (label);
align = gtk_alignment_new (0.0f, 0.5f, 0.0f, 0.0f);
- gtk_table_attach (GTK_TABLE (table), align, 1, 2, 3, 4, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
+ gtk_table_attach (GTK_TABLE (table), align, 1, 2, 4, 5, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
gtk_widget_show (align);
uca_editor->icon_button = gtk_button_new_with_label (_("No icon"));
@@ -223,11 +231,11 @@ thunar_uca_editor_init (ThunarUcaEditor *uca_editor)
g_object_unref (G_OBJECT (relation));
align = g_object_new (GTK_TYPE_ALIGNMENT, "height-request", 12, NULL);
- gtk_table_attach (GTK_TABLE (table), align, 0, 2, 4, 5, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
+ gtk_table_attach (GTK_TABLE (table), align, 0, 2, 5, 6, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
gtk_widget_show (align);
hbox = gtk_hbox_new (FALSE, 6);
- gtk_table_attach (GTK_TABLE (table), hbox, 0, 2, 5, 6, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
+ gtk_table_attach (GTK_TABLE (table), hbox, 0, 2, 6, 7, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
gtk_widget_show (hbox);
image = gtk_image_new_from_stock (GTK_STOCK_DIALOG_INFO, GTK_ICON_SIZE_DND);
@@ -763,6 +771,7 @@ thunar_uca_editor_load (ThunarUcaEditor *uca_editor,
gchar *command;
gchar *icon;
gchar *name;
+ gboolean startup_notify;
g_return_if_fail (THUNAR_UCA_IS_EDITOR (uca_editor));
g_return_if_fail (THUNAR_UCA_IS_MODEL (uca_model));
@@ -776,6 +785,7 @@ thunar_uca_editor_load (ThunarUcaEditor *uca_editor,
THUNAR_UCA_MODEL_COLUMN_TYPES, &types,
THUNAR_UCA_MODEL_COLUMN_ICON, &icon,
THUNAR_UCA_MODEL_COLUMN_NAME, &name,
+ THUNAR_UCA_MODEL_COLUMN_STARTUP_NOTIFY, &startup_notify,
-1);
/* setup the new selection */
@@ -789,6 +799,7 @@ thunar_uca_editor_load (ThunarUcaEditor *uca_editor,
gtk_entry_set_text (GTK_ENTRY (uca_editor->patterns_entry), (patterns != NULL) ? patterns : "");
gtk_entry_set_text (GTK_ENTRY (uca_editor->command_entry), (command != NULL) ? command : "");
gtk_entry_set_text (GTK_ENTRY (uca_editor->name_entry), (name != NULL) ? name : "");
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (uca_editor->sn_button), startup_notify);
/* cleanup */
g_free (description);
@@ -823,6 +834,7 @@ thunar_uca_editor_save (ThunarUcaEditor *uca_editor,
gtk_entry_get_text (GTK_ENTRY (uca_editor->description_entry)),
thunar_uca_editor_get_icon_name (uca_editor),
gtk_entry_get_text (GTK_ENTRY (uca_editor->command_entry)),
+ gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (uca_editor->sn_button)),
gtk_entry_get_text (GTK_ENTRY (uca_editor->patterns_entry)),
thunar_uca_editor_get_types (uca_editor));
}
diff --git a/plugins/thunar-uca/thunar-uca-model.c b/plugins/thunar-uca/thunar-uca-model.c
index 822c8a2..c196e9e 100644
--- a/plugins/thunar-uca/thunar-uca-model.c
+++ b/plugins/thunar-uca/thunar-uca-model.c
@@ -74,6 +74,7 @@ typedef enum
PARSER_ICON,
PARSER_NAME,
PARSER_COMMAND,
+ PARSER_STARTUP_NOTIFY,
PARSER_PATTERNS,
PARSER_DESCRIPTION,
PARSER_DIRECTORIES,
@@ -161,6 +162,7 @@ struct _ThunarUcaModelItem
gchar *description;
gchar *icon;
gchar *command;
+ gboolean startup_notify : 1;
gchar **patterns;
ThunarUcaTypes types;
@@ -183,6 +185,7 @@ typedef struct
GString *command;
GString *patterns;
GString *description;
+ gboolean startup_notify;
gboolean description_use;
guint description_match;
ThunarUcaTypes types;
@@ -324,6 +327,9 @@ thunar_uca_model_get_column_type (GtkTreeModel *tree_model,
case THUNAR_UCA_MODEL_COLUMN_COMMAND:
return G_TYPE_STRING;
+ case THUNAR_UCA_MODEL_COLUMN_STARTUP_NOTIFY:
+ return G_TYPE_BOOLEAN;
+
case THUNAR_UCA_MODEL_COLUMN_PATTERNS:
return G_TYPE_STRING;
@@ -418,6 +424,10 @@ thunar_uca_model_get_value (GtkTreeModel *tree_model,
g_value_set_static_string (value, item->command);
break;
+ case THUNAR_UCA_MODEL_COLUMN_STARTUP_NOTIFY:
+ g_value_set_boolean (value, item->startup_notify);
+ break;
+
case THUNAR_UCA_MODEL_COLUMN_PATTERNS:
str = g_strjoinv (";", item->patterns);
g_value_take_string (value, str);
@@ -580,6 +590,7 @@ thunar_uca_model_load_from_file (ThunarUcaModel *uca_model,
parser.command = g_string_new (NULL);
parser.patterns = g_string_new (NULL);
parser.description = g_string_new (NULL);
+ parser.startup_notify = FALSE;
xfce_stack_push (parser.stack, PARSER_START);
/* parse the file */
@@ -654,6 +665,7 @@ start_element_handler (GMarkupParseContext *context,
parser->name_match = XFCE_LOCALE_NO_MATCH;
parser->description_match = XFCE_LOCALE_NO_MATCH;
parser->types = 0;
+ parser->startup_notify = FALSE;
g_string_truncate (parser->icon, 0);
g_string_truncate (parser->name, 0);
g_string_truncate (parser->command, 0);
@@ -739,6 +751,11 @@ start_element_handler (GMarkupParseContext *context,
xfce_stack_push (parser->stack, PARSER_DESCRIPTION);
}
+ else if (strcmp (element_name, "startup-notify") == 0)
+ {
+ parser->startup_notify = TRUE;
+ xfce_stack_push (parser->stack, PARSER_STARTUP_NOTIFY);
+ }
else if (strcmp (element_name, "directories") == 0)
{
parser->types |= THUNAR_UCA_TYPE_DIRECTORIES;
@@ -816,6 +833,7 @@ end_element_handler (GMarkupParseContext *context,
parser->description->str,
parser->icon->str,
parser->command->str,
+ parser->startup_notify,
parser->patterns->str,
parser->types);
}
@@ -848,6 +866,11 @@ end_element_handler (GMarkupParseContext *context,
goto unknown_element;
break;
+ case PARSER_STARTUP_NOTIFY:
+ if (strcmp (element_name, "startup-notify") != 0)
+ goto unknown_element;
+ break;
+
case PARSER_DIRECTORIES:
if (strcmp (element_name, "directories") != 0)
goto unknown_element;
@@ -1247,6 +1270,7 @@ thunar_uca_model_update (ThunarUcaModel *uca_model,
const gchar *description,
const gchar *icon,
const gchar *command,
+ gboolean startup_notify,
const gchar *patterns,
ThunarUcaTypes types)
{
@@ -1271,6 +1295,7 @@ thunar_uca_model_update (ThunarUcaModel *uca_model,
if (G_LIKELY (description != NULL && *description != '\0'))
item->description = g_strdup (description);
item->types = types;
+ item->startup_notify = startup_notify;
/* setup the patterns */
item->patterns = g_strsplit ((patterns != NULL && *patterns != '\0') ? patterns : "*", ";", -1);
@@ -1366,6 +1391,8 @@ thunar_uca_model_save (ThunarUcaModel *uca_model,
fprintf (fp, "%s", escaped);
g_free (patterns);
g_free (escaped);
+ if (item->startup_notify)
+ fprintf (fp, "<startup-notify/>");
if ((item->types & THUNAR_UCA_TYPE_DIRECTORIES) != 0)
fprintf (fp, "<directories/>");
if ((item->types & THUNAR_UCA_TYPE_AUDIO_FILES) != 0)
diff --git a/plugins/thunar-uca/thunar-uca-model.h b/plugins/thunar-uca/thunar-uca-model.h
index 2d8e291..58a362f 100644
--- a/plugins/thunar-uca/thunar-uca-model.h
+++ b/plugins/thunar-uca/thunar-uca-model.h
@@ -41,6 +41,7 @@ typedef enum
THUNAR_UCA_MODEL_COLUMN_DESCRIPTION,
THUNAR_UCA_MODEL_COLUMN_ICON,
THUNAR_UCA_MODEL_COLUMN_COMMAND,
+ THUNAR_UCA_MODEL_COLUMN_STARTUP_NOTIFY,
THUNAR_UCA_MODEL_COLUMN_PATTERNS,
THUNAR_UCA_MODEL_COLUMN_TYPES,
THUNAR_UCA_MODEL_COLUMN_STOCK_ID,
@@ -91,6 +92,7 @@ void thunar_uca_model_update (ThunarUcaModel *uca_mod
const gchar *description,
const gchar *icon,
const gchar *command,
+ gboolean startup_notify,
const gchar *patterns,
ThunarUcaTypes types);
diff --git a/plugins/thunar-uca/thunar-uca-provider.c b/plugins/thunar-uca/thunar-uca-provider.c
index 63bae6c..0519cd0 100644
--- a/plugins/thunar-uca/thunar-uca-provider.c
+++ b/plugins/thunar-uca/thunar-uca-provider.c
@@ -23,8 +23,8 @@
#include <config.h>
#endif
-#include <glib/gi18n.h>
#include <gio/gio.h>
+#include <libxfce4ui/libxfce4ui.h>
#include <thunar-uca/thunar-uca-chooser.h>
#include <thunar-uca/thunar-uca-context.h>
@@ -71,7 +71,7 @@ struct _ThunarUcaProvider
* child process has terminated.
*/
gchar *child_watch_path;
- gint child_watch_id;
+ XfceSpawn *child_spawn;
};
@@ -133,10 +133,6 @@ thunar_uca_provider_init (ThunarUcaProvider *uca_provider)
/* grab a reference on the default model */
uca_provider->model = thunar_uca_model_get_default ();
-
- /* initialize child watch support */
- uca_provider->child_watch_path = NULL;
- uca_provider->child_watch_id = -1;
}
@@ -145,18 +141,10 @@ static void
thunar_uca_provider_finalize (GObject *object)
{
ThunarUcaProvider *uca_provider = THUNAR_UCA_PROVIDER (object);
- GSource *source;
/* give up maintaince of any pending child watch */
- if (G_UNLIKELY (uca_provider->child_watch_id >= 0))
- {
- /* reset the callback function to g_spawn_close_pid() so the plugin can be
- * safely unloaded and the child will still not become a zombie afterwards.
- * This also resets the child_watch_id and child_watch_path properties.
- */
- source = g_main_context_find_source_by_id (NULL, uca_provider->child_watch_id);
- g_source_set_callback (source, (GSourceFunc) g_spawn_close_pid, NULL, NULL);
- }
+ if (G_UNLIKELY (uca_provider->child_spawn != NULL))
+ xfce_spawn_unref (uca_provider->child_spawn);
/* drop our reference on the model */
g_object_unref (G_OBJECT (uca_provider->model));
@@ -306,7 +294,6 @@ thunar_uca_provider_activated (ThunarUcaProvider *uca_provider,
GtkWidget *dialog;
GtkWidget *window;
gboolean succeed;
- GSource *source;
GError *error = NULL;
GList *files;
gchar **argv;
@@ -315,7 +302,9 @@ thunar_uca_provider_activated (ThunarUcaProvider *uca_provider,
gchar *label;
gchar *uri;
gint argc;
- gint pid;
+ gchar *icon_name = NULL;
+ gboolean startup_notify;
+ XfceSpawn *child_spawn;
g_return_if_fail (THUNAR_UCA_IS_PROVIDER (uca_provider));
g_return_if_fail (GTK_IS_ACTION (action));
@@ -339,6 +328,12 @@ thunar_uca_provider_activated (ThunarUcaProvider *uca_provider,
succeed = thunar_uca_model_parse_argv (uca_provider->model, &iter, files, &argc, &argv, &error);
if (G_LIKELY (succeed))
{
+ /* get the icon name and whether startup notification is active */
+ gtk_tree_model_get (GTK_TREE_MODEL (uca_provider->model), &iter,
+ THUNAR_UCA_MODEL_COLUMN_ICON, &icon_name,
+ THUNAR_UCA_MODEL_COLUMN_STARTUP_NOTIFY, &startup_notify,
+ -1);
+
/* determine the working from the first file */
if (G_LIKELY (files != NULL))
{
@@ -363,35 +358,42 @@ thunar_uca_provider_activated (ThunarUcaProvider *uca_provider,
}
/* spawn the command on the window's screen */
- succeed = gdk_spawn_on_screen (gtk_widget_get_screen (GTK_WIDGET (window)), working_directory,
- argv, NULL, G_SPAWN_DO_NOT_REAP_CHILD | G_SPAWN_SEARCH_PATH,
- NULL, NULL, &pid, &error);
+ child_spawn = xfce_spawn_on_screen_watch (gtk_widget_get_screen (GTK_WIDGET (window)),
+ working_directory, argv, NULL,
+ G_SPAWN_DO_NOT_REAP_CHILD | G_SPAWN_SEARCH_PATH,
+ startup_notify, gtk_get_current_event_time (),
+ icon_name,
+ thunar_uca_provider_child_watch, uca_provider,
+ thunar_uca_provider_child_watch_destroy,
+ &error);
/* check if we succeed */
- if (G_LIKELY (succeed))
+ if (G_LIKELY (child_spawn != NULL))
{
/* check if we already have a child watch */
- if (G_UNLIKELY (uca_provider->child_watch_id >= 0))
- {
- /* reset the callback function to g_spawn_close_pid() so the plugin can be
- * safely unloaded and the child will still not become a zombie afterwards.
- */
- source = g_main_context_find_source_by_id (NULL, uca_provider->child_watch_id);
- g_source_set_callback (source, (GSourceFunc) g_spawn_close_pid, NULL, NULL);
- }
+ if (G_UNLIKELY (uca_provider->child_spawn != NULL))
+ xfce_spawn_unref (uca_provider->child_spawn);
- /* schedule the new child watch */
- uca_provider->child_watch_id = g_child_watch_add_full (G_PRIORITY_LOW, pid, thunar_uca_provider_child_watch,
- uca_provider, thunar_uca_provider_child_watch_destroy);
+ /* set new child spawn */
+ uca_provider->child_spawn = child_spawn;
/* take over ownership of the working directory as child watch path */
uca_provider->child_watch_path = working_directory;
working_directory = NULL;
+
+ /* everything went fine */
+ succeed = TRUE;
+ }
+ else
+ {
+ /* spawning the child failed */
+ succeed = FALSE;
}
/* cleanup */
g_free (working_directory);
g_strfreev (argv);
+ g_free (icon_name);
}
/* present error message to the user */
@@ -421,7 +423,6 @@ thunar_uca_provider_child_watch (GPid pid,
{
ThunarUcaProvider *uca_provider = THUNAR_UCA_PROVIDER (user_data);
GFileMonitor *monitor;
- GError *error = NULL;
GFile *file;
GDK_THREADS_ENTER ();
@@ -433,7 +434,7 @@ thunar_uca_provider_child_watch (GPid pid,
file = g_file_new_for_path (uca_provider->child_watch_path);
/* schedule a changed notification on the path */
- monitor = g_file_monitor (file, G_FILE_MONITOR_NONE, NULL, &error);
+ monitor = g_file_monitor (file, G_FILE_MONITOR_NONE, NULL, NULL);
if (monitor != NULL)
{
@@ -445,9 +446,6 @@ thunar_uca_provider_child_watch (GPid pid,
g_object_unref (file);
}
- /* need to cleanup */
- g_spawn_close_pid (pid);
-
GDK_THREADS_LEAVE ();
}
@@ -461,8 +459,7 @@ thunar_uca_provider_child_watch_destroy (gpointer user_data)
/* reset child watch id and path */
g_free (uca_provider->child_watch_path);
uca_provider->child_watch_path = NULL;
- uca_provider->child_watch_id = -1;
-}
-
-
+ xfce_spawn_unref (uca_provider->child_spawn);
+ uca_provider->child_spawn = NULL;
+}
More information about the Xfce4-commits
mailing list