[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