static void thunar_uca_provider_child_watch (GPid pid, gint status, gpointer user_data) { ThunarUcaProvider *uca_provider = THUNAR_UCA_PROVIDER (user_data); ThunarVfsMonitor *monitor; ThunarVfsPath *path; GDK_THREADS_ENTER (); /* verify that we still have a valid child_watch_path */ if (G_LIKELY (uca_provider->child_watch_path != NULL)) { /* determine the corresponding ThunarVfsPath */ path = thunar_vfs_path_new (uca_provider->child_watch_path, NULL); if (G_LIKELY (path != NULL)) { /* schedule a changed notification on the path */ monitor = thunar_vfs_monitor_get_default (); thunar_vfs_monitor_feed (monitor, THUNAR_VFS_MONITOR_EVENT_CHANGED, path); g_object_unref (G_OBJECT (monitor)); /* release the ThunarVfsPath */ thunar_vfs_path_unref (path); } } /* need to cleanup */ g_spawn_close_pid (pid); GDK_THREADS_LEAVE (); }
static void thunar_uca_provider_child_watch_destroy (gpointer user_data, GClosure *closure) { ThunarUcaProvider *uca_provider = THUNAR_UCA_PROVIDER (user_data); GClosure *child_watch; /* leave if the closure is not the one we're watching */ if (uca_provider->child_watch == closure || closure == NULL) { /* reset child watch and path */ if (G_UNLIKELY (uca_provider->child_watch != NULL)) { child_watch = uca_provider->child_watch; uca_provider->child_watch = NULL; g_closure_invalidate (child_watch); g_closure_unref (child_watch); } g_free (uca_provider->child_watch_path); uca_provider->child_watch_path = NULL; } }
static void thunar_uca_provider_child_watch_destroy (gpointer user_data) { ThunarUcaProvider *uca_provider = THUNAR_UCA_PROVIDER (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; }
static void thunar_uca_provider_finalize (GObject *object) { ThunarUcaProvider *uca_provider = THUNAR_UCA_PROVIDER (object); /* give up maintaince of any pending child watch */ thunar_uca_provider_child_watch_destroy (uca_provider, NULL); /* drop our reference on the model */ g_object_unref (G_OBJECT (uca_provider->model)); (*G_OBJECT_CLASS (thunar_uca_provider_parent_class)->finalize) (object); }
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); } /* drop our reference on the model */ g_object_unref (G_OBJECT (uca_provider->model)); (*G_OBJECT_CLASS (thunar_uca_provider_parent_class)->finalize) (object); }
static GList* thunar_uca_provider_get_file_actions (ThunarxMenuProvider *menu_provider, GtkWidget *window, GList *files) { GtkTreeRowReference *row; ThunarUcaProvider *uca_provider = THUNAR_UCA_PROVIDER (menu_provider); ThunarUcaContext *uca_context = NULL; GtkTreeIter iter; GtkAction *action; GList *actions = NULL; GList *paths; GList *lp; gchar *stock_id; gchar *tooltip; gchar *label; gchar *name; paths = thunar_uca_model_match (uca_provider->model, files); for (lp = g_list_last (paths); lp != NULL; lp = lp->prev) { /* try to lookup the tree iter for the specified tree path */ if (gtk_tree_model_get_iter (GTK_TREE_MODEL (uca_provider->model), &iter, lp->data)) { /* determine the label, tooltip and stock-id for the item */ gtk_tree_model_get (GTK_TREE_MODEL (uca_provider->model), &iter, THUNAR_UCA_MODEL_COLUMN_NAME, &label, THUNAR_UCA_MODEL_COLUMN_STOCK_ID, &stock_id, THUNAR_UCA_MODEL_COLUMN_DESCRIPTION, &tooltip, -1); /* generate a unique action name */ name = g_strdup_printf ("ThunarUca::action-%d", ++uca_provider->last_action_id); /* create the new action with the given parameters */ action = gtk_action_new (name, label, tooltip, stock_id); /* grab a tree row reference on the given path */ row = gtk_tree_row_reference_new (GTK_TREE_MODEL (uca_provider->model), lp->data); g_object_set_qdata_full (G_OBJECT (action), thunar_uca_row_quark, row, (GDestroyNotify) gtk_tree_row_reference_free); /* allocate a new context on-demand */ if (G_LIKELY (uca_context == NULL)) uca_context = thunar_uca_context_new (window, files); else uca_context = thunar_uca_context_ref (uca_context); g_object_set_qdata_full (G_OBJECT (action), thunar_uca_context_quark, uca_context, (GDestroyNotify) thunar_uca_context_unref); /* connect the "activate" signal */ g_signal_connect_data (G_OBJECT (action), "activate", G_CALLBACK (thunar_uca_provider_activated), g_object_ref (G_OBJECT (uca_provider)), (GClosureNotify) g_object_unref, G_CONNECT_SWAPPED); /* add the action to the return list */ actions = g_list_prepend (actions, action); /* cleanup */ g_free (stock_id); g_free (tooltip); g_free (label); g_free (name); } /* release the tree path */ gtk_tree_path_free (lp->data); } g_list_free (paths); return actions; }