[Xfce4-commits] <xfce4-panel:master> Add support for X-XFCE-Unique=SCREEN.
Nick Schermer
noreply at xfce.org
Thu Jun 3 20:52:01 CEST 2010
Updating branch refs/heads/master
to 1a74095b4985b02d79b449a8b5034395a5687dea (commit)
from 7fb06f700bc8f332166adf581ae8ffcacaf068a9 (commit)
commit 1a74095b4985b02d79b449a8b5034395a5687dea
Author: Nick Schermer <nick at xfce.org>
Date: Thu Jun 3 20:46:37 2010 +0200
Add support for X-XFCE-Unique=SCREEN.
This allows to make a plugin unique for a screen. Also
improve (and fix) the handling of unique plugins in the
module code and items dialog.
panel/panel-item-dialog.c | 57 +++++++++++++++++++++++++++----
panel/panel-module-factory.c | 4 ++
panel/panel-module.c | 76 +++++++++++++++++++++++++++++++++++-------
panel/panel-module.h | 6 ++-
4 files changed, 121 insertions(+), 22 deletions(-)
diff --git a/panel/panel-item-dialog.c b/panel/panel-item-dialog.c
index e20cd40..fa48e13 100644
--- a/panel/panel-item-dialog.c
+++ b/panel/panel-item-dialog.c
@@ -59,6 +59,8 @@ static gboolean panel_item_dialog_unique_changed_foreach (GtkTreeModel
static gboolean panel_item_dialog_separator_func (GtkTreeModel *model,
GtkTreeIter *iter,
gpointer user_data);
+static void panel_item_dialog_selection_changed (GtkTreeSelection *selection,
+ PanelItemDialog *dialog);
static PanelModule *panel_item_dialog_get_selected_module (GtkTreeView *treeview);
static void panel_item_dialog_drag_begin (GtkWidget *treeview,
GdkDragContext *context,
@@ -101,6 +103,7 @@ struct _PanelItemDialog
/* pointers to list */
GtkListStore *store;
GtkTreeView *treeview;
+ GtkWidget *add_button;
};
enum
@@ -153,6 +156,7 @@ panel_item_dialog_init (PanelItemDialog *dialog)
GtkTreeModel *filter;
GtkTreeViewColumn *column;
GtkCellRenderer *renderer;
+ GtkTreeSelection *selection;
dialog->application = panel_application_get ();
@@ -175,11 +179,12 @@ panel_item_dialog_init (PanelItemDialog *dialog)
gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE);
gtk_window_set_default_size (GTK_WINDOW (dialog), 350, 450);
- gtk_dialog_add_buttons (GTK_DIALOG (dialog),
- GTK_STOCK_HELP, GTK_RESPONSE_HELP,
- GTK_STOCK_ADD, GTK_RESPONSE_OK,
- GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
- NULL);
+ dialog->add_button = gtk_button_new_from_stock (GTK_STOCK_ADD);
+ gtk_widget_show (dialog->add_button);
+
+ gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_HELP, GTK_RESPONSE_HELP);
+ gtk_dialog_add_action_widget (GTK_DIALOG (dialog), dialog->add_button, GTK_RESPONSE_OK);
+ gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE);
gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_CLOSE);
main_vbox = gtk_vbox_new (FALSE, BORDER * 2);
@@ -234,6 +239,9 @@ panel_item_dialog_init (PanelItemDialog *dialog)
gtk_container_add (GTK_CONTAINER (scroll), treeview);
gtk_widget_show (treeview);
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
+ g_signal_connect (G_OBJECT (selection), "changed", G_CALLBACK (panel_item_dialog_selection_changed), dialog);
+
g_object_unref (G_OBJECT (filter));
/* signals for treeview dnd */
@@ -329,8 +337,13 @@ panel_item_dialog_unique_changed (PanelModuleFactory *factory,
panel_return_if_fail (GTK_IS_LIST_STORE (dialog->store));
/* search the module and update its sensitivity */
+ g_object_set_data (G_OBJECT (dialog->store), "dialog", dialog);
gtk_tree_model_foreach (GTK_TREE_MODEL (dialog->store),
panel_item_dialog_unique_changed_foreach, module);
+ g_object_set_data (G_OBJECT (dialog->store), "dialog", NULL);
+
+ /* update button sensitivity */
+ panel_item_dialog_selection_changed (gtk_tree_view_get_selection (dialog->treeview), dialog);
}
@@ -343,6 +356,7 @@ panel_item_dialog_unique_changed_foreach (GtkTreeModel *model,
{
PanelModule *module;
gboolean result;
+ GtkWidget *dialog;
panel_return_val_if_fail (PANEL_IS_MODULE (user_data), FALSE);
@@ -358,9 +372,13 @@ panel_item_dialog_unique_changed_foreach (GtkTreeModel *model,
if (result)
{
+ dialog = g_object_get_data (G_OBJECT (model), "dialog");
+ panel_return_val_if_fail (PANEL_IS_ITEM_DIALOG (dialog), FALSE);
+
/* update the module unique status */
gtk_list_store_set (GTK_LIST_STORE (model), iter,
- COLUMN_SENSITIVE, panel_module_is_usable (module), -1);
+ COLUMN_SENSITIVE, panel_module_is_usable (module,
+ gtk_widget_get_screen (dialog)), -1);
}
g_object_unref (G_OBJECT (module));
@@ -389,6 +407,28 @@ panel_item_dialog_separator_func (GtkTreeModel *model,
+static void
+panel_item_dialog_selection_changed (GtkTreeSelection *selection,
+ PanelItemDialog *dialog)
+{
+ PanelModule *module;
+ gboolean sensitive = FALSE;
+
+ panel_return_if_fail (PANEL_IS_ITEM_DIALOG (dialog));
+ panel_return_if_fail (GTK_IS_TREE_SELECTION (selection));
+
+ module = panel_item_dialog_get_selected_module (dialog->treeview);
+ if (module != NULL)
+ {
+ sensitive = panel_module_is_usable (module, gtk_widget_get_screen (GTK_WIDGET (dialog)));
+ g_object_unref (G_OBJECT (module));
+ }
+
+ gtk_widget_set_sensitive (dialog->add_button, sensitive);
+}
+
+
+
static PanelModule *
panel_item_dialog_get_selected_module (GtkTreeView *treeview)
{
@@ -440,7 +480,7 @@ panel_item_dialog_drag_begin (GtkWidget *treeview,
module = panel_item_dialog_get_selected_module (GTK_TREE_VIEW (treeview));
if (G_LIKELY (module != NULL))
{
- if (panel_module_is_usable (module))
+ if (panel_module_is_usable (module, gtk_widget_get_screen (GTK_WIDGET (dialog))))
{
/* set the drag icon */
icon_name = panel_module_get_icon_name (module);
@@ -512,7 +552,8 @@ panel_item_dialog_populate_store (PanelItemDialog *dialog)
gtk_list_store_insert_with_values (dialog->store, &iter, n,
COLUMN_MODULE, module,
COLUMN_ICON_NAME, panel_module_get_icon_name (module),
- COLUMN_SENSITIVE, panel_module_is_usable (module), -1);
+ COLUMN_SENSITIVE, panel_module_is_usable (module,
+ gtk_widget_get_screen (GTK_WIDGET (dialog))), -1);
}
g_list_free (modules);
diff --git a/panel/panel-module-factory.c b/panel/panel-module-factory.c
index 9419e11..9a6e3ca 100644
--- a/panel/panel-module-factory.c
+++ b/panel/panel-module-factory.c
@@ -434,5 +434,9 @@ panel_module_factory_new_plugin (PanelModuleFactory *factory,
g_object_weak_ref (G_OBJECT (provider), panel_module_factory_remove_plugin, factory);
}
+ /* emit unique-changed if the plugin is unique */
+ if (panel_module_is_unique (module))
+ panel_module_factory_emit_unique_changed (module);
+
return provider;
}
diff --git a/panel/panel-module.c b/panel/panel-module.c
index 778044a..4df39b5 100644
--- a/panel/panel-module.c
+++ b/panel/panel-module.c
@@ -38,6 +38,11 @@
+typedef enum _PanelModuleRunMode PanelModuleRunMode;
+typedef enum _PanelModuleUnique PanelModuleUnique;
+
+
+
static void panel_module_dispose (GObject *object);
static void panel_module_finalize (GObject *object);
static gboolean panel_module_load (GTypeModule *type_module);
@@ -60,6 +65,13 @@ enum _PanelModuleRunMode
EXTERNAL_46 /* external executable with comunication through PanelPluginExternal46 */
};
+enum _PanelModuleUnique
+{
+ UNIQUE_FALSE,
+ UNIQUE_TRUE,
+ UNIQUE_SCREEN
+};
+
struct _PanelModule
{
GTypeModule __parent__;
@@ -78,7 +90,7 @@ struct _PanelModule
/* unique handling */
guint use_count;
- guint is_unique : 1;
+ PanelModuleUnique unique_mode;
/* module location (null for 4.6 plugins) */
GModule *library;
@@ -128,7 +140,7 @@ panel_module_init (PanelModule *module)
module->comment = NULL;
module->icon_name = NULL;
module->use_count = 0;
- module->is_unique = FALSE;
+ module->unique_mode = UNIQUE_FALSE;
module->library = NULL;
module->construct_func = NULL;
module->plugin_type = G_TYPE_NONE;
@@ -272,7 +284,7 @@ panel_module_plugin_destroyed (gpointer user_data,
g_type_module_unuse (G_TYPE_MODULE (module));
/* emit signal unique signal in the factory */
- if (module->is_unique)
+ if (module->unique_mode != UNIQUE_FALSE)
panel_module_factory_emit_unique_changed (module);
}
@@ -288,6 +300,7 @@ panel_module_new_from_desktop_file (const gchar *filename,
const gchar *module_name;
gchar *path;
const gchar *module_exec;
+ const gchar *module_unique;
panel_return_val_if_fail (!exo_str_is_empty (filename), NULL);
panel_return_val_if_fail (!exo_str_is_empty (name), NULL);
@@ -374,7 +387,16 @@ panel_module_new_from_desktop_file (const gchar *filename,
module->display_name = g_strdup (xfce_rc_read_entry (rc, "Name", name));
module->comment = g_strdup (xfce_rc_read_entry (rc, "Comment", NULL));
module->icon_name = g_strdup (xfce_rc_read_entry_untranslated (rc, "Icon", NULL));
- module->is_unique = xfce_rc_read_bool_entry (rc, "X-XFCE-Unique", FALSE);
+
+ module_unique = xfce_rc_read_entry (rc, "X-XFCE-Unique", NULL);
+ if (G_LIKELY (module_unique == NULL))
+ module->unique_mode = UNIQUE_FALSE;
+ else if (strcasecmp (module_unique, "screen") == 0)
+ module->unique_mode = UNIQUE_SCREEN;
+ else if (strcasecmp (module_unique, "true") == 0)
+ module->unique_mode = UNIQUE_TRUE;
+ else
+ module->unique_mode = UNIQUE_FALSE;
}
xfce_rc_close (rc);
@@ -399,7 +421,7 @@ panel_module_new_plugin (PanelModule *module,
panel_return_val_if_fail (module->mode != UNKNOWN, NULL);
/* return null if the module is not usable (unique and already used) */
- if (G_UNLIKELY (!panel_module_is_usable (module)))
+ if (G_UNLIKELY (!panel_module_is_usable (module, screen)))
return NULL;
switch (module->mode)
@@ -460,10 +482,6 @@ panel_module_new_plugin (PanelModule *module,
g_object_weak_ref (G_OBJECT (plugin),
panel_module_plugin_destroyed, module);
- /* emit unique-changed if the plugin is unique */
- if (module->is_unique)
- panel_module_factory_emit_unique_changed (module);
-
/* add link to the module */
g_object_set_qdata (G_OBJECT (plugin), module_quark, module);
}
@@ -554,10 +572,44 @@ panel_module_is_valid (PanelModule *module)
gboolean
-panel_module_is_usable (PanelModule *module)
+panel_module_is_unique (PanelModule *module)
+{
+ panel_return_val_if_fail (PANEL_IS_MODULE (module), FALSE);
+
+ return module->unique_mode != UNIQUE_FALSE;
+}
+
+
+
+gboolean
+panel_module_is_usable (PanelModule *module,
+ GdkScreen *screen)
{
+ PanelModuleFactory *factory;
+ GSList *plugins, *li;
+ gboolean usable = TRUE;
+
panel_return_val_if_fail (PANEL_IS_MODULE (module), FALSE);
+ panel_return_val_if_fail (GDK_IS_SCREEN (screen), FALSE);
+
+ if (module->use_count > 0
+ && module->unique_mode == UNIQUE_TRUE)
+ return FALSE;
+
+ if (module->use_count > 0
+ && module->unique_mode == UNIQUE_SCREEN)
+ {
+ factory = panel_module_factory_get ();
+ plugins = panel_module_factory_get_plugins (factory, panel_module_get_name (module));
+
+ /* search existing plugins if one of them runs on this screen */
+ for (li = plugins; usable && li != NULL; li = li->next)
+ if (screen == gtk_widget_get_screen (GTK_WIDGET (li->data)))
+ usable = FALSE;
+
+ g_slist_free (plugins);
+ g_object_unref (G_OBJECT (factory));
+ }
- /* whether the module is usable */
- return module->is_unique ? module->use_count == 0 : TRUE;
+ return usable;
}
diff --git a/panel/panel-module.h b/panel/panel-module.h
index ee1459a..33ba56f 100644
--- a/panel/panel-module.h
+++ b/panel/panel-module.h
@@ -27,7 +27,6 @@ G_BEGIN_DECLS
typedef struct _PanelModuleClass PanelModuleClass;
typedef struct _PanelModule PanelModule;
-typedef enum _PanelModuleRunMode PanelModuleRunMode;
#define PANEL_TYPE_MODULE (panel_module_get_type ())
#define PANEL_MODULE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), PANEL_TYPE_MODULE, PanelModule))
@@ -63,7 +62,10 @@ PanelModule *panel_module_get_from_plugin_provider (XfcePanelPluginProvider *pro
gboolean panel_module_is_valid (PanelModule *module);
-gboolean panel_module_is_usable (PanelModule *module) G_GNUC_PURE;
+gboolean panel_module_is_unique (PanelModule *module) G_GNUC_PURE;
+
+gboolean panel_module_is_usable (PanelModule *module,
+ GdkScreen *screen);
G_END_DECLS
More information about the Xfce4-commits
mailing list