[Xfce4-commits] <xfce4-panel:master> Panel: Work with a unique id for each panel.
Nick Schermer
noreply at xfce.org
Thu Dec 29 17:36:02 CET 2011
Updating branch refs/heads/master
to 1473206aa9771e110d5b5e80fd8f1b370f986638 (commit)
from e835c3b533d7c15e4329d83a767660b6079f147d (commit)
commit 1473206aa9771e110d5b5e80fd8f1b370f986638
Author: Nick Schermer <nick at xfce.org>
Date: Thu Dec 29 16:16:15 2011 +0100
Panel: Work with a unique id for each panel.
Give each panel a unique id that does not change over
its lifetime. This should prevent most of the problems
where panel configuration is lost or strange resets when
a panel is removed from the preferences dialog.
panel/main.c | 2 +-
panel/panel-application.c | 331 +++++++++++++++++++---------------
panel/panel-application.h | 10 +-
panel/panel-dbus-service.c | 12 +-
panel/panel-dialogs.c | 76 ++++++--
panel/panel-item-dialog.c | 14 ++
panel/panel-item-dialog.h | 8 +-
panel/panel-preferences-dialog.c | 156 +++++++++++------
panel/panel-preferences-dialog.glade | 4 +-
panel/panel-preferences-dialog.h | 8 +-
panel/panel-window.c | 34 ++++-
panel/panel-window.h | 5 +-
12 files changed, 421 insertions(+), 239 deletions(-)
diff --git a/panel/main.c b/panel/main.c
index 15600c8..a70a04f 100644
--- a/panel/main.c
+++ b/panel/main.c
@@ -355,7 +355,7 @@ main (gint argc, gchar **argv)
/* open dialog if we started from launch_panel */
if (opt_preferences >= 0)
- panel_preferences_dialog_show (panel_application_get_nth_window (application, opt_preferences));
+ panel_preferences_dialog_show_from_id (opt_preferences);
gtk_main ();
diff --git a/panel/panel-application.c b/panel/panel-application.c
index 3b304a0..143f489 100644
--- a/panel/panel-application.c
+++ b/panel/panel-application.c
@@ -302,11 +302,9 @@ panel_application_xfconf_window_bindings (PanelApplication *application,
};
panel_return_if_fail (XFCONF_IS_CHANNEL (application->xfconf));
- panel_return_if_fail (g_slist_index (application->windows, window) > -1);
/* create the property base */
- property_base = g_strdup_printf ("/panels/panel-%d",
- g_slist_index (application->windows, window));
+ property_base = g_strdup_printf ("/panels/panel-%d", panel_window_get_id (window));
/* bind all the properties */
panel_properties_bind (application->xfconf, G_OBJECT (window),
@@ -335,74 +333,109 @@ panel_application_load_real (PanelApplication *application)
gchar *output_name;
gint screen_num;
GdkDisplay *display;
+ GValue val = { 0, };
+ GPtrArray *panels;
+ gint panel_id;
panel_return_if_fail (PANEL_IS_APPLICATION (application));
panel_return_if_fail (XFCONF_IS_CHANNEL (application->xfconf));
display = gdk_display_get_default ();
- /* walk all the panel in the configuration */
- n_panels = xfconf_channel_get_uint (application->xfconf, "/panels", 0);
- for (i = 0; i < n_panels; i++)
+ if (xfconf_channel_get_property (application->xfconf, "/panels", &val)
+ && (G_VALUE_HOLDS_UINT (&val)
+ || G_VALUE_HOLDS (&val, PANEL_PROPERTIES_TYPE_VALUE_ARRAY)))
{
- screen = NULL;
-
- /* start the panel directly on the correct screen */
- g_snprintf (buf, sizeof (buf), "/panels/panel-%u/output-name", i);
- output_name = xfconf_channel_get_string (application->xfconf, buf, NULL);
- if (output_name != NULL
- && strncmp (output_name, "screen-", 7) == 0
- && sscanf (output_name, "screen-%d", &screen_num) == 1)
+ if (G_VALUE_HOLDS_UINT (&val))
{
- if (screen_num < gdk_display_get_n_screens (display))
- screen = gdk_display_get_screen (display, screen_num);
+ n_panels = g_value_get_uint (&val);
+ panels = NULL;
+ }
+ else
+ {
+ panels = g_value_get_boxed (&val);
+ n_panels = panels->len;
}
- g_free (output_name);
- /* create a new window */
- window = panel_application_new_window (application, screen, FALSE);
+ /* walk all the panel in the configuration */
+ for (i = 0; i < n_panels; i++)
+ {
+ screen = NULL;
- /* walk all the plugins on the panel */
- g_snprintf (buf, sizeof (buf), "/panels/panel-%u/plugin-ids", i);
- array = xfconf_channel_get_arrayv (application->xfconf, buf);
- if (array == NULL)
- continue;
+ /* get the panel id */
+ if (panels != NULL)
+ {
+ /* get the id from the array */
+ value = g_ptr_array_index (panels, i);
+ panel_assert (value != NULL);
+ panel_id = g_value_get_int (value);
+ }
+ else
+ {
+ /* use the list position if /panels is an uint */
+ panel_id = i;
+ }
- for (j = 0; j < array->len; j++)
- {
- /* get the plugin id */
- value = g_ptr_array_index (array, j);
- panel_assert (value != NULL);
- unique_id = g_value_get_int (value);
-
- /* get the plugin name */
- g_snprintf (buf, sizeof (buf), "/plugins/plugin-%d", unique_id);
- name = xfconf_channel_get_string (application->xfconf, buf, NULL);
-
- /* append the plugin to the panel */
- if (unique_id < 1 || name == NULL
- || !panel_application_plugin_insert (application, window,
- name, unique_id, NULL, -1))
+ /* start the panel directly on the correct screen */
+ g_snprintf (buf, sizeof (buf), "/panels/panel-%d/output-name", panel_id);
+ output_name = xfconf_channel_get_string (application->xfconf, buf, NULL);
+ if (output_name != NULL
+ && strncmp (output_name, "screen-", 7) == 0
+ && sscanf (output_name, "screen-%d", &screen_num) == 1)
{
- /* plugin could not be loaded, remove it from the channel */
- g_snprintf (buf, sizeof (buf), "/panels/plugin-%d", unique_id);
- if (xfconf_channel_has_property (application->xfconf, buf))
- xfconf_channel_reset_property (application->xfconf, buf, TRUE);
-
- /* show warnings */
- g_message ("Plugin \"%s-%d\" was not found and has been "
- "removed from the configuration", name, unique_id);
+ if (screen_num < gdk_display_get_n_screens (display))
+ screen = gdk_display_get_screen (display, screen_num);
}
+ g_free (output_name);
- g_free (name);
+ /* create a new window */
+ window = panel_application_new_window (application, screen, panel_id, FALSE);
+
+ /* walk all the plugins on the panel */
+ g_snprintf (buf, sizeof (buf), "/panels/panel-%d/plugin-ids", panel_id);
+ array = xfconf_channel_get_arrayv (application->xfconf, buf);
+ if (array == NULL)
+ continue;
+
+ for (j = 0; j < array->len; j++)
+ {
+ /* get the plugin id */
+ value = g_ptr_array_index (array, j);
+ panel_assert (value != NULL);
+ unique_id = g_value_get_int (value);
+
+ /* get the plugin name */
+ g_snprintf (buf, sizeof (buf), "/plugins/plugin-%d", unique_id);
+ name = xfconf_channel_get_string (application->xfconf, buf, NULL);
+
+ /* append the plugin to the panel */
+ if (unique_id < 1 || name == NULL
+ || !panel_application_plugin_insert (application, window,
+ name, unique_id, NULL, -1))
+ {
+ /* plugin could not be loaded, remove it from the channel */
+ g_snprintf (buf, sizeof (buf), "/panels/plugin-%d", unique_id);
+ if (xfconf_channel_has_property (application->xfconf, buf))
+ xfconf_channel_reset_property (application->xfconf, buf, TRUE);
+
+ /* show warnings */
+ g_message ("Plugin \"%s-%d\" was not found and has been "
+ "removed from the configuration", name, unique_id);
+ }
+
+ g_free (name);
+ }
+
+ xfconf_array_free (array);
}
- xfconf_array_free (array);
+ /* free xfconf array or uint */
+ g_value_unset (&val);
}
/* create empty window if everything else failed */
if (G_UNLIKELY (application->windows == NULL))
- panel_application_new_window (application, NULL, TRUE);
+ panel_application_new_window (application, NULL, -1, TRUE);
}
@@ -791,58 +824,37 @@ static void
panel_application_window_destroyed (GtkWidget *window,
PanelApplication *application)
{
- guint n;
gchar *property;
- GSList *li, *lnext;
- gboolean passed_destroyed_window = FALSE;
GtkWidget *itembar;
+ gint panel_id;
panel_return_if_fail (PANEL_IS_WINDOW (window));
panel_return_if_fail (PANEL_IS_APPLICATION (application));
panel_return_if_fail (g_slist_find (application->windows, window) != NULL);
- /* leave if the application is locked */
- if (panel_application_get_locked (application))
+ /* leave if the application or window is locked */
+ if (panel_application_get_locked (application)
+ || panel_window_get_locked (PANEL_WINDOW (window)))
return;
- /* we need to update the bindings of all the panels... */
- for (li = application->windows, n = 0; li != NULL; li = lnext, n++)
- {
- lnext = li->next;
+ panel_id = panel_window_get_id (PANEL_WINDOW (window));
+ panel_debug (PANEL_DEBUG_APPLICATION,
+ "removing configuration and plugins of panel %d",
+ panel_id);
- /* TODO, this might go wrong when only 1 window is locked */
- if (panel_window_get_locked (li->data))
- continue;
+ /* remove from the internal list */
+ application->windows = g_slist_remove (application->windows, window);
- if (passed_destroyed_window)
- {
- /* save this panel again at it's new position */
- panel_properties_unbind (G_OBJECT (li->data));
- panel_application_xfconf_window_bindings (application,
- PANEL_WINDOW (li->data),
- TRUE);
- }
- else if (li->data == window)
- {
- /* disconnect bindings from this panel */
- panel_properties_unbind (G_OBJECT (window));
-
- /* remove all the plugins from the itembar */
- itembar = gtk_bin_get_child (GTK_BIN (window));
- gtk_container_foreach (GTK_CONTAINER (itembar),
- panel_application_plugin_remove, NULL);
-
- /* remove from the internal list */
- application->windows = g_slist_delete_link (application->windows, li);
+ /* disconnect bindings from this panel */
+ panel_properties_unbind (G_OBJECT (window));
- /* keep updating the bindings for the remaining windows */
- passed_destroyed_window = TRUE;
- }
- }
+ /* remove all the plugins from the itembar */
+ itembar = gtk_bin_get_child (GTK_BIN (window));
+ gtk_container_foreach (GTK_CONTAINER (itembar),
+ panel_application_plugin_remove, NULL);
- /* remove the last property from the channel */
- property = g_strdup_printf ("/panels/panel-%u", n - 1);
- panel_assert (n - 1 == g_slist_length (application->windows));
+ /* remove the panel settings */
+ property = g_strdup_printf ("/panels/panel-%d", panel_id);
xfconf_channel_reset_property (application->xfconf, property, TRUE);
g_free (property);
@@ -1169,6 +1181,21 @@ panel_application_drag_leave (GtkWidget *window,
+static gboolean
+panel_application_window_id_exists (PanelApplication *application,
+ gint id)
+{
+ GSList *li;
+
+ for (li = application->windows; li != NULL; li = li->next)
+ if (panel_window_get_id (li->data) == id)
+ return TRUE;
+
+ return FALSE;
+}
+
+
+
PanelApplication *
panel_application_get (void)
{
@@ -1251,19 +1278,30 @@ panel_application_save (PanelApplication *application,
XfconfChannel *channel = application->xfconf;
GPtrArray *array;
GValue *value;
+ GPtrArray *panels;
+ gint panel_id;
panel_return_if_fail (PANEL_IS_APPLICATION (application));
panel_return_if_fail (XFCONF_IS_CHANNEL (channel));
+ panels = g_ptr_array_new ();
+
for (li = application->windows, i = 0; li != NULL; li = li->next, i++)
{
+ /* store the panel id */
+ value = g_new0 (GValue, 1);
+ panel_id = panel_window_get_id (li->data);
+ g_value_init (value, G_TYPE_INT);
+ g_value_set_int (value, panel_id);
+ g_ptr_array_add (panels, value);
+
/* skip this window if it is locked */
if (panel_window_get_locked (li->data))
continue;
panel_debug (PANEL_DEBUG_APPLICATION,
- "saving /panels/panel-%u, save-plugins=%s",
- i, PANEL_DEBUG_BOOL (save_plugin_providers));
+ "saving /panels/panel-%d, save-plugins=%s",
+ panel_id, PANEL_DEBUG_BOOL (save_plugin_providers));
/* get the itembar children */
itembar = gtk_bin_get_child (GTK_BIN (li->data));
@@ -1272,7 +1310,7 @@ panel_application_save (PanelApplication *application,
/* only cleanup and continue if there are no children */
if (G_UNLIKELY (children == NULL))
{
- g_snprintf (buf, sizeof (buf), "/panels/panel-%u/plugin-ids", i);
+ g_snprintf (buf, sizeof (buf), "/panels/panel-%d/plugin-ids", panel_id);
if (xfconf_channel_has_property (channel, buf))
xfconf_channel_reset_property (channel, buf, FALSE);
continue;
@@ -1303,16 +1341,21 @@ panel_application_save (PanelApplication *application,
}
/* store the plugins for this panel */
- g_snprintf (buf, sizeof (buf), "/panels/panel-%u/plugin-ids", i);
+ g_snprintf (buf, sizeof (buf), "/panels/panel-%d/plugin-ids", panel_id);
xfconf_channel_set_arrayv (channel, buf, array);
g_list_free (children);
xfconf_array_free (array);
}
- /* store the number of panels */
+ /* store the panel ids */
if (!xfconf_channel_is_property_locked (channel, "/panels"))
- xfconf_channel_set_uint (channel, "/panels", i);
+ {
+ if (!xfconf_channel_set_arrayv (channel, "/panels", panels))
+ g_warning ("Failed to store the number of panels");
+ }
+
+ xfconf_array_free (panels);
}
@@ -1360,14 +1403,12 @@ panel_application_add_new_item (PanelApplication *application,
const gchar *plugin_name,
gchar **arguments)
{
- gint nth = 0;
- GSList *li;
- gboolean active;
- PanelWindow *window;
+ PanelWindow *window = NULL;
+ gint panel_id;
panel_return_if_fail (PANEL_IS_APPLICATION (application));
panel_return_if_fail (plugin_name != NULL);
- panel_return_if_fail (g_slist_length (application->windows) > 0);
+ panel_return_if_fail (application->windows != NULL);
/* leave if the config is locked */
if (panel_application_get_locked (application))
@@ -1375,30 +1416,34 @@ panel_application_add_new_item (PanelApplication *application,
if (panel_module_factory_has_module (application->factory, plugin_name))
{
- /* find a suitable window if there are 2 or more windows */
+ /* find a suitable panel if there are 2 or more panel */
if (LIST_HAS_TWO_OR_MORE_ENTRIES (application->windows))
{
- /* try to find an avtive panel */
- for (li = application->windows, nth = 0; li != NULL; li = li->next, nth++)
+ /* ask the user to select a panel */
+ panel_id = panel_dialogs_choose_panel (application);
+ if (panel_id == -1)
{
- g_object_get (G_OBJECT (li->data), "active", &active, NULL);
- if (active)
- break;
+ /* cancel was clicked */
+ return;
+ }
+ else
+ {
+ /* get panel from the id */
+ window = panel_application_get_window (application, panel_id);
}
-
- /* no active panel found, ask user to select a panel, leave when
- * the cancel button is pressed */
- if (li == NULL
- && (nth = panel_dialogs_choose_panel (application)) == -1)
- return;
+ }
+ else
+ {
+ /* get the first (and only) window */
+ window = g_slist_nth_data (application->windows, 0);
}
- /* add the plugin to the end of the choosen window */
- window = g_slist_nth_data (application->windows, nth);
- if (!panel_window_get_locked (window))
+ if (window != NULL && !panel_window_get_locked (window))
{
+ /* insert plugin at the end of the panel */
panel_application_plugin_insert (application, window,
- plugin_name, -1, arguments, -1);
+ plugin_name, -1,
+ arguments, -1);
}
}
else
@@ -1413,6 +1458,7 @@ panel_application_add_new_item (PanelApplication *application,
PanelWindow *
panel_application_new_window (PanelApplication *application,
GdkScreen *screen,
+ gint panel_id,
gboolean new_window)
{
GtkWidget *window;
@@ -1422,13 +1468,23 @@ panel_application_new_window (PanelApplication *application,
static const gchar *props[] = { "mode", "size", "nrows" };
guint i;
gchar *position;
+ static gint unqiue_id_counter = 1;
panel_return_val_if_fail (PANEL_IS_APPLICATION (application), NULL);
panel_return_val_if_fail (screen == NULL || GDK_IS_SCREEN (screen), NULL);
panel_return_val_if_fail (XFCONF_IS_CHANNEL (application->xfconf), NULL);
+ panel_return_val_if_fail (new_window || !panel_application_window_id_exists (application, panel_id), NULL);
+
+ if (new_window)
+ {
+ /* get a new unique id */
+ panel_id = unqiue_id_counter;
+ while (panel_application_window_id_exists (application, panel_id))
+ panel_id = ++unqiue_id_counter;
+ }
/* create panel window */
- window = panel_window_new (screen);
+ window = panel_window_new (screen, panel_id);
/* monitor window destruction */
g_signal_connect (G_OBJECT (window), "destroy",
@@ -1437,12 +1493,10 @@ panel_application_new_window (PanelApplication *application,
/* add the window to internal list */
application->windows = g_slist_append (application->windows, window);
- /* flush the window properties */
if (new_window)
{
- /* remove the xfconf properties */
- idx = g_slist_index (application->windows, window);
- property = g_strdup_printf ("/panels/panel-%d", idx);
+ /* remove the old xfconf properties to be sure */
+ property = g_strdup_printf ("/panels/panel-%d", panel_id);
xfconf_channel_reset_property (application->xfconf, property, TRUE);
g_free (property);
}
@@ -1480,7 +1534,7 @@ panel_application_new_window (PanelApplication *application,
/* create a position so not all panels overlap */
idx = g_slist_index (application->windows, window);
- position = g_strdup_printf ("p=0;x=100;y=%d", 100 + (idx * 48 * 2));
+ position = g_strdup_printf ("p=0;x=100;y=%d", 100 + (idx * 48) + 10);
g_object_set (G_OBJECT (window), "position", position, NULL);
g_free (position);
}
@@ -1490,35 +1544,28 @@ panel_application_new_window (PanelApplication *application,
-guint
-panel_application_get_n_windows (PanelApplication *application)
+GSList *
+panel_application_get_windows (PanelApplication *application)
{
- panel_return_val_if_fail (PANEL_IS_APPLICATION (application), 0);
-
- return g_slist_length (application->windows);
+ panel_return_val_if_fail (PANEL_IS_APPLICATION (application), NULL);
+ return application->windows;
}
-gint
-panel_application_get_window_index (PanelApplication *application,
- PanelWindow *window)
+PanelWindow *
+panel_application_get_window (PanelApplication *application,
+ gint panel_id)
{
- panel_return_val_if_fail (PANEL_IS_APPLICATION (application), 0);
- panel_return_val_if_fail (PANEL_IS_WINDOW (window), 0);
-
- return g_slist_index (application->windows, window);
-}
-
+ GSList *li;
+ panel_return_val_if_fail (PANEL_IS_APPLICATION (application), NULL);
-PanelWindow *
-panel_application_get_nth_window (PanelApplication *application,
- guint idx)
-{
- panel_return_val_if_fail (PANEL_IS_APPLICATION (application), 0);
+ for (li = application->windows; li != NULL; li = li->next)
+ if (panel_window_get_id (li->data) == panel_id)
+ return li->data;
- return g_slist_nth_data (application->windows, idx);
+ return NULL;
}
diff --git a/panel/panel-application.h b/panel/panel-application.h
index 5073821..ee1d719 100644
--- a/panel/panel-application.h
+++ b/panel/panel-application.h
@@ -55,15 +55,13 @@ void panel_application_add_new_item (PanelApplication *applic
PanelWindow *panel_application_new_window (PanelApplication *application,
GdkScreen *screen,
+ gint id,
gboolean new_window);
-guint panel_application_get_n_windows (PanelApplication *application);
+GSList *panel_application_get_windows (PanelApplication *application);
-gint panel_application_get_window_index (PanelApplication *application,
- PanelWindow *window);
-
-PanelWindow *panel_application_get_nth_window (PanelApplication *application,
- guint idx);
+PanelWindow *panel_application_get_window (PanelApplication *application,
+ gint panel_id);
void panel_application_window_select (PanelApplication *application,
PanelWindow *window);
diff --git a/panel/panel-dbus-service.c b/panel/panel-dbus-service.c
index 42382b6..955e466 100644
--- a/panel/panel-dbus-service.c
+++ b/panel/panel-dbus-service.c
@@ -192,15 +192,11 @@ panel_dbus_service_display_preferences_dialog (PanelDBusService *service,
guint active,
GError **error)
{
- PanelApplication *application;
-
panel_return_val_if_fail (PANEL_IS_DBUS_SERVICE (service), FALSE);
panel_return_val_if_fail (error == NULL || *error == NULL, FALSE);
/* show the preferences dialog */
- application = panel_application_get ();
- panel_preferences_dialog_show (panel_application_get_nth_window (application, active));
- g_object_unref (G_OBJECT (application));
+ panel_preferences_dialog_show_from_id (active);
return TRUE;
}
@@ -212,15 +208,11 @@ panel_dbus_service_display_items_dialog (PanelDBusService *service,
guint active,
GError **error)
{
- PanelApplication *application;
-
panel_return_val_if_fail (PANEL_IS_DBUS_SERVICE (service), FALSE);
panel_return_val_if_fail (error == NULL || *error == NULL, FALSE);
/* show the items dialog */
- application = panel_application_get ();
- panel_item_dialog_show (panel_application_get_nth_window (application, active));
- g_object_unref (G_OBJECT (application));
+ panel_preferences_dialog_show_from_id (active);
return TRUE;
}
diff --git a/panel/panel-dialogs.c b/panel/panel-dialogs.c
index d7fd918..f268ba6 100644
--- a/panel/panel-dialogs.c
+++ b/panel/panel-dialogs.c
@@ -89,19 +89,45 @@ panel_dialogs_show_about (void)
+enum
+{
+ CHOOSER_COLUMN_ID,
+ CHOOSER_COLUMN_TEXT,
+ N_CHOOSER_COLUMNS
+};
+
+
+
+static gint
+panel_dialogs_choose_panel_combo_get_id (GtkComboBox *combo)
+{
+ gint panel_id = -1;
+ GtkTreeIter iter;
+ GtkTreeModel *model;
+
+ if (gtk_combo_box_get_active_iter (combo, &iter))
+ {
+ model = gtk_combo_box_get_model (combo);
+ gtk_tree_model_get (model, &iter, CHOOSER_COLUMN_ID, &panel_id, -1);
+ }
+
+ return panel_id;
+}
+
+
+
static void
panel_dialogs_choose_panel_combo_changed (GtkComboBox *combo,
PanelApplication *application)
{
- gint idx;
+ gint panel_id;
panel_return_if_fail (PANEL_IS_APPLICATION (application));
panel_return_if_fail (GTK_IS_COMBO_BOX (combo));
- /* select active panel */
- idx = gtk_combo_box_get_active (combo);
+ panel_id = panel_dialogs_choose_panel_combo_get_id (combo);
panel_application_window_select (application,
- panel_application_get_nth_window (application, idx));
+ panel_application_get_window (application, panel_id));
}
@@ -109,13 +135,16 @@ panel_dialogs_choose_panel_combo_changed (GtkComboBox *combo,
gint
panel_dialogs_choose_panel (PanelApplication *application)
{
- GtkWidget *dialog;
- GtkWidget *vbox;
- GtkWidget *label;
- GtkWidget *combo;
- guint i;
- gint response = -1;
- gchar *name;
+ GtkWidget *dialog;
+ GtkWidget *vbox;
+ GtkWidget *label;
+ GtkWidget *combo;
+ gchar *name;
+ GtkListStore *store;
+ GtkCellRenderer *renderer;
+ GSList *windows, *li;
+ gint i;
+ gint panel_id;
panel_return_val_if_fail (PANEL_IS_APPLICATION (application), -1);
@@ -138,15 +167,26 @@ panel_dialogs_choose_panel (PanelApplication *application)
gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
gtk_widget_show (label);
- combo = gtk_combo_box_new_text ();
+ store = gtk_list_store_new (N_CHOOSER_COLUMNS, G_TYPE_INT, G_TYPE_STRING);
+ combo = gtk_combo_box_new_with_model (GTK_TREE_MODEL (store));
gtk_box_pack_start (GTK_BOX (vbox), combo, FALSE, FALSE, 0);
gtk_widget_show (combo);
+ g_object_unref (G_OBJECT (store));
+
+ renderer = gtk_cell_renderer_text_new ();
+ gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), renderer, TRUE);
+ gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo), renderer,
+ "text", CHOOSER_COLUMN_TEXT, NULL);
/* insert the panels */
- for (i = 0; i < panel_application_get_n_windows (application); i++)
+ windows = panel_application_get_windows (application);
+ for (li = windows, i = 0; li != NULL; li = li->next, i++)
{
- name = g_strdup_printf (_("Panel %d"), i + 1);
- gtk_combo_box_append_text (GTK_COMBO_BOX (combo), name);
+ panel_id = panel_window_get_id (li->data);
+ name = g_strdup_printf (_("Panel %d"), panel_id);
+ gtk_list_store_insert_with_values (store, NULL, i,
+ CHOOSER_COLUMN_ID, panel_id,
+ CHOOSER_COLUMN_TEXT, name, -1);
g_free (name);
}
@@ -157,13 +197,15 @@ panel_dialogs_choose_panel (PanelApplication *application)
/* run the dialog */
if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK)
- response = gtk_combo_box_get_active (GTK_COMBO_BOX (combo));
+ panel_id = panel_dialogs_choose_panel_combo_get_id (GTK_COMBO_BOX (combo));
+ else
+ panel_id = -1;
gtk_widget_destroy (dialog);
/* unset panel selections */
panel_application_window_select (application, NULL);
- return response;
+ return panel_id;
}
diff --git a/panel/panel-item-dialog.c b/panel/panel-item-dialog.c
index 06a5d2e..e9a6fc7 100644
--- a/panel/panel-item-dialog.c
+++ b/panel/panel-item-dialog.c
@@ -814,6 +814,20 @@ panel_item_dialog_show (PanelWindow *window)
+void
+panel_item_dialog_show_from_id (gint panel_id)
+{
+ PanelApplication *application;
+ PanelWindow *window;
+
+ application = panel_application_get ();
+ window = panel_application_get_window (application, panel_id);
+ panel_item_dialog_show (window);
+ g_object_unref (G_OBJECT (application));
+}
+
+
+
gboolean
panel_item_dialog_visible (void)
{
diff --git a/panel/panel-item-dialog.h b/panel/panel-item-dialog.h
index d0a276a..aee1e2a 100644
--- a/panel/panel-item-dialog.h
+++ b/panel/panel-item-dialog.h
@@ -33,11 +33,13 @@ typedef struct _PanelItemDialog PanelItemDialog;
#define PANEL_IS_ITEM_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), PANEL_TYPE_ITEM_DIALOG))
#define PANEL_ITEM_DIALOG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PANEL_TYPE_ITEM_DIALOG, PanelItemDialogClass))
-GType panel_item_dialog_get_type (void) G_GNUC_CONST;
+GType panel_item_dialog_get_type (void) G_GNUC_CONST;
-void panel_item_dialog_show (PanelWindow *window);
+void panel_item_dialog_show (PanelWindow *active);
-gboolean panel_item_dialog_visible (void);
+void panel_item_dialog_show_from_id (gint panel_id);
+
+gboolean panel_item_dialog_visible (void);
G_END_DECLS
diff --git a/panel/panel-preferences-dialog.c b/panel/panel-preferences-dialog.c
index 6e89eca..f05c603 100644
--- a/panel/panel-preferences-dialog.c
+++ b/panel/panel-preferences-dialog.c
@@ -61,7 +61,8 @@ static void panel_preferences_dialog_bg_image_file_set
static void panel_preferences_dialog_bg_image_notified (PanelPreferencesDialog *dialog);
static void panel_preferences_dialog_panel_combobox_changed (GtkComboBox *combobox,
PanelPreferencesDialog *dialog);
-static void panel_preferences_dialog_panel_combobox_rebuild (PanelPreferencesDialog *dialog);
+static gboolean panel_preferences_dialog_panel_combobox_rebuild (PanelPreferencesDialog *dialog,
+ gint panel_id);
static void panel_preferences_dialog_panel_add (GtkWidget *widget,
PanelPreferencesDialog *dialog);
static void panel_preferences_dialog_panel_remove (GtkWidget *widget,
@@ -270,9 +271,6 @@ panel_preferences_dialog_init (PanelPreferencesDialog *dialog)
G_CALLBACK (panel_preferences_dialog_output_changed),
dialog);
- /* rebuild the panel combobox */
- panel_preferences_dialog_panel_combobox_rebuild (dialog);
-
/* show the dialog */
gtk_widget_show (GTK_WIDGET (window));
}
@@ -673,9 +671,9 @@ static void
panel_preferences_dialog_panel_sensitive (PanelPreferencesDialog *dialog)
{
- GObject *object;
- gboolean locked = TRUE;
- gint n_windows;
+ GObject *object;
+ gboolean locked = TRUE;
+ GSList *windows;
panel_return_if_fail (PANEL_IS_PREFERENCES_DIALOG (dialog));
@@ -684,8 +682,9 @@ panel_preferences_dialog_panel_sensitive (PanelPreferencesDialog *dialog)
object = gtk_builder_get_object (GTK_BUILDER (dialog), "panel-remove");
panel_return_if_fail (GTK_IS_WIDGET (object));
- n_windows = panel_application_get_n_windows (dialog->application);
- gtk_widget_set_sensitive (GTK_WIDGET (object), !locked && n_windows > 1);
+ windows = panel_application_get_windows (dialog->application);
+ gtk_widget_set_sensitive (GTK_WIDGET (object),
+ !locked && g_slist_length (windows) > 1);
object = gtk_builder_get_object (GTK_BUILDER (dialog), "panel-add");
panel_return_if_fail (GTK_IS_WIDGET (object));
@@ -707,8 +706,10 @@ static void
panel_preferences_dialog_panel_combobox_changed (GtkComboBox *combobox,
PanelPreferencesDialog *dialog)
{
- gint nth;
- GtkWidget *itembar;
+ gint panel_id;
+ GtkWidget *itembar;
+ GtkTreeModel *model;
+ GtkTreeIter iter;
panel_return_if_fail (GTK_IS_COMBO_BOX (combobox));
panel_return_if_fail (PANEL_IS_PREFERENCES_DIALOG (dialog));
@@ -724,8 +725,18 @@ panel_preferences_dialog_panel_combobox_changed (GtkComboBox *combobo
panel_preferences_dialog_bindings_unbind (dialog);
/* set the selected window */
- nth = gtk_combo_box_get_active (combobox);
- dialog->active = panel_application_get_nth_window (dialog->application, nth);
+ if (gtk_combo_box_get_active_iter (combobox, &iter))
+ {
+ model = gtk_combo_box_get_model (combobox);
+ gtk_tree_model_get (model, &iter, 0, &panel_id, -1);
+
+ dialog->active = panel_application_get_window (dialog->application, panel_id);
+ }
+ else
+ {
+ dialog->active = NULL;
+ }
+
panel_application_window_select (dialog->application, dialog->active);
if (G_LIKELY (dialog->active != NULL))
@@ -748,18 +759,23 @@ panel_preferences_dialog_panel_combobox_changed (GtkComboBox *combobo
-static void
-panel_preferences_dialog_panel_combobox_rebuild (PanelPreferencesDialog *dialog)
+static gboolean
+panel_preferences_dialog_panel_combobox_rebuild (PanelPreferencesDialog *dialog,
+ gint panel_id)
{
- GObject *store, *combo;
- gint n, n_items;
- gchar *name;
+ GObject *store, *combo;
+ gint i;
+ GSList *windows, *li;
+ gchar *name;
+ gint id;
+ GtkTreeIter iter;
+ gboolean selected = FALSE;
/* get the combo box and model */
store = gtk_builder_get_object (GTK_BUILDER (dialog), "panel-store");
- panel_return_if_fail (GTK_IS_LIST_STORE (store));
+ panel_return_val_if_fail (GTK_IS_LIST_STORE (store), FALSE);
combo = gtk_builder_get_object (GTK_BUILDER (dialog), "panel-combobox");
- panel_return_if_fail (GTK_IS_COMBO_BOX (combo));
+ panel_return_val_if_fail (GTK_IS_COMBO_BOX (combo), FALSE);
/* block signal */
g_signal_handlers_block_by_func (combo,
@@ -769,20 +785,34 @@ panel_preferences_dialog_panel_combobox_rebuild (PanelPreferencesDialog *dialog)
gtk_list_store_clear (GTK_LIST_STORE (store));
/* add new names */
- n_items = panel_application_get_n_windows (dialog->application);
- for (n = 0; n < n_items; n++)
+ windows = panel_application_get_windows (dialog->application);
+ for (li = windows, i = 0; li != NULL; li = li->next, i++)
{
/* I18N: panel combo box in the preferences dialog */
- name = g_strdup_printf (_("Panel %d"), n + 1);
- gtk_list_store_insert_with_values (GTK_LIST_STORE (store), NULL, n, 0, name, -1);
+ id = panel_window_get_id (li->data);
+ name = g_strdup_printf (_("Panel %d"), id);
+ gtk_list_store_insert_with_values (GTK_LIST_STORE (store), &iter, i,
+ 0, id, 1, name, -1);
g_free (name);
+
+ if (id == panel_id)
+ {
+ /* select panel id */
+ gtk_combo_box_set_active_iter (GTK_COMBO_BOX (combo), &iter);
+ selected = TRUE;
+ }
}
/* unblock signal */
g_signal_handlers_unblock_by_func (combo,
panel_preferences_dialog_panel_combobox_changed, dialog);
+ if (selected)
+ panel_preferences_dialog_panel_combobox_changed (GTK_COMBO_BOX (combo), dialog);
+
panel_preferences_dialog_panel_sensitive (dialog);
+
+ return selected;
}
@@ -791,28 +821,22 @@ static void
panel_preferences_dialog_panel_add (GtkWidget *widget,
PanelPreferencesDialog *dialog)
{
- gint active;
PanelWindow *window;
- GObject *object;
+ gint panel_id;
/* create new window */
window = panel_application_new_window (dialog->application,
- gtk_widget_get_screen (widget), TRUE);
+ gtk_widget_get_screen (widget), -1, TRUE);
/* block autohide */
panel_window_freeze_autohide (window);
- /* rebuild the selector */
- panel_preferences_dialog_panel_combobox_rebuild (dialog);
-
/* show window */
gtk_widget_show (GTK_WIDGET (window));
- /* select new panel (new window is appended) */
- object = gtk_builder_get_object (GTK_BUILDER (dialog), "panel-combobox");
- panel_return_if_fail (GTK_IS_WIDGET (object));
- active = panel_application_get_n_windows (dialog->application) - 1;
- gtk_combo_box_set_active (GTK_COMBO_BOX (object), active);
+ /* rebuild the selector */
+ panel_id = panel_window_get_id (window);
+ panel_preferences_dialog_panel_combobox_rebuild (dialog, panel_id);
}
@@ -821,36 +845,41 @@ static void
panel_preferences_dialog_panel_remove (GtkWidget *widget,
PanelPreferencesDialog *dialog)
{
- gint nth;
+ gint idx;
GObject *combo;
GtkWidget *toplevel;
+ GSList *windows;
+ gint n_windows;
/* leave if the window is locked */
if (panel_window_get_locked (dialog->active))
return;
- /* get active panel */
- nth = panel_application_get_window_index (dialog->application, dialog->active);
-
toplevel = gtk_widget_get_toplevel (widget);
if (xfce_dialog_confirm (GTK_WINDOW (toplevel), GTK_STOCK_REMOVE, NULL,
_("The panel and plugin configurations will be permanently removed"),
- _("Are you sure you want to remove panel %d?"), nth + 1))
+ _("Are you sure you want to remove panel %d?"),
+ panel_window_get_id (dialog->active)))
{
/* release the bindings */
panel_preferences_dialog_bindings_unbind (dialog);
+ /* get position of the panel */
+ windows = panel_application_get_windows (dialog->application);
+ idx = g_slist_index (windows, dialog->active);
+ n_windows = g_slist_length (windows) - 2;
+
/* destroy the panel */
gtk_widget_destroy (GTK_WIDGET (dialog->active));
dialog->active = NULL;
/* rebuild the selector */
- panel_preferences_dialog_panel_combobox_rebuild (dialog);
+ panel_preferences_dialog_panel_combobox_rebuild (dialog, -1);
- /* select new active window */
+ /* select window after this window */
combo = gtk_builder_get_object (GTK_BUILDER (dialog), "panel-combobox");
panel_return_if_fail (GTK_IS_WIDGET (combo));
- gtk_combo_box_set_active (GTK_COMBO_BOX (combo), MAX (0, nth - 1));
+ gtk_combo_box_set_active (GTK_COMBO_BOX (combo), CLAMP (idx, 0, n_windows));
}
}
@@ -1248,9 +1277,10 @@ panel_preferences_dialog_item_selection_changed (GtkTreeSelection *selecti
void
panel_preferences_dialog_show (PanelWindow *active)
{
- gint idx = 0;
- GObject *window, *combo;
- GdkScreen *screen;
+ gint panel_id = 0;
+ GObject *window, *combo;
+ GdkScreen *screen;
+ GSList *windows;
panel_return_if_fail (active == NULL || PANEL_IS_WINDOW (active));
@@ -1258,21 +1288,23 @@ panel_preferences_dialog_show (PanelWindow *active)
if (panel_dialogs_kiosk_warning ())
return;
- if (G_LIKELY (dialog_singleton == NULL))
+ if (dialog_singleton == NULL)
{
/* create new dialog singleton */
dialog_singleton = g_object_new (PANEL_TYPE_PREFERENCES_DIALOG, NULL);
g_object_add_weak_pointer (G_OBJECT (dialog_singleton), (gpointer) &dialog_singleton);
}
- /* get the active window index */
- if (G_LIKELY (active))
- idx = panel_application_get_window_index (dialog_singleton->application, active);
- else
- active = panel_application_get_nth_window (dialog_singleton->application, idx);
+ if (active == NULL)
+ {
+ /* select first window */
+ windows = panel_application_get_windows (dialog_singleton->application);
+ if (windows != NULL)
+ active = g_slist_nth_data (windows, 0);
+ }
/* get the active screen */
- if (active != NULL)
+ if (G_LIKELY (active != NULL))
screen = gtk_widget_get_screen (GTK_WIDGET (active));
else
screen = gdk_screen_get_default ();
@@ -1286,7 +1318,23 @@ panel_preferences_dialog_show (PanelWindow *active)
/* select the active window in the dialog */
combo = gtk_builder_get_object (GTK_BUILDER (dialog_singleton), "panel-combobox");
panel_return_if_fail (GTK_IS_WIDGET (combo));
- gtk_combo_box_set_active (GTK_COMBO_BOX (combo), idx);
+ panel_id = panel_window_get_id (active);
+ if (!panel_preferences_dialog_panel_combobox_rebuild (dialog_singleton, panel_id))
+ gtk_combo_box_set_active (GTK_COMBO_BOX (combo), 0);
+}
+
+
+
+void
+panel_preferences_dialog_show_from_id (gint panel_id)
+{
+ PanelApplication *application;
+ PanelWindow *window;
+
+ application = panel_application_get ();
+ window = panel_application_get_window (application, panel_id);
+ panel_preferences_dialog_show (window);
+ g_object_unref (G_OBJECT (application));
}
diff --git a/panel/panel-preferences-dialog.glade b/panel/panel-preferences-dialog.glade
index 92d7dc8..062cbed 100644
--- a/panel/panel-preferences-dialog.glade
+++ b/panel/panel-preferences-dialog.glade
@@ -22,6 +22,8 @@
</object>
<object class="GtkListStore" id="panel-store">
<columns>
+ <!-- column-name id -->
+ <column type="gint"/>
<!-- column-name title -->
<column type="gchararray"/>
</columns>
@@ -132,7 +134,7 @@
<child>
<object class="GtkCellRendererText" id="cellrenderertext2"/>
<attributes>
- <attribute name="text">0</attribute>
+ <attribute name="text">1</attribute>
</attributes>
</child>
</object>
diff --git a/panel/panel-preferences-dialog.h b/panel/panel-preferences-dialog.h
index c60ac5f..89d73f3 100644
--- a/panel/panel-preferences-dialog.h
+++ b/panel/panel-preferences-dialog.h
@@ -35,11 +35,13 @@ typedef struct _PanelPreferencesDialog PanelPreferencesDialog;
#define PANEL_IS_PREFERENCES_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), PANEL_TYPE_PREFERENCES_DIALOG))
#define PANEL_PREFERENCES_DIALOG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PANEL_TYPE_PREFERENCES_DIALOG, PanelPreferencesDialogClass))
-GType panel_preferences_dialog_get_type (void) G_GNUC_CONST;
+GType panel_preferences_dialog_get_type (void) G_GNUC_CONST;
-void panel_preferences_dialog_show (PanelWindow *active);
+void panel_preferences_dialog_show (PanelWindow *active);
-gboolean panel_preferences_dialog_visible (void);
+void panel_preferences_dialog_show_from_id (gint panel_id);
+
+gboolean panel_preferences_dialog_visible (void);
G_END_DECLS
diff --git a/panel/panel-window.c b/panel/panel-window.c
index f2e3ac0..d84189a 100644
--- a/panel/panel-window.c
+++ b/panel/panel-window.c
@@ -146,6 +146,7 @@ static void panel_window_plugin_set_screen_position (GtkWidget *w
enum
{
PROP_0,
+ PROP_ID,
PROP_MODE,
PROP_SIZE,
PROP_NROWS,
@@ -245,6 +246,9 @@ struct _PanelWindow
{
PanelBaseWindow __parent__;
+ /* unique id of this panel */
+ gint id;
+
/* whether the user is allowed to make
* changes to this window */
guint locked : 1;
@@ -342,6 +346,13 @@ panel_window_class_init (PanelWindowClass *klass)
gtkwidget_class->realize = panel_window_realize;
g_object_class_install_property (gobject_class,
+ PROP_ID,
+ g_param_spec_int ("id", NULL, NULL,
+ 0, G_MAXINT, 0,
+ EXO_PARAM_READWRITE
+ | G_PARAM_CONSTRUCT_ONLY));
+
+ g_object_class_install_property (gobject_class,
PROP_MODE,
g_param_spec_enum ("mode", NULL, NULL,
XFCE_TYPE_PANEL_PLUGIN_MODE,
@@ -445,6 +456,7 @@ panel_window_class_init (PanelWindowClass *klass)
static void
panel_window_init (PanelWindow *window)
{
+ window->id = -1;
window->locked = TRUE;
window->screen = NULL;
window->struts_edge = STRUTS_EDGE_NONE;
@@ -496,6 +508,10 @@ panel_window_get_property (GObject *object,
switch (prop_id)
{
+ case PROP_ID:
+ g_value_set_int (value, window->id);
+ break;
+
case PROP_MODE:
g_value_set_enum (value, window->mode);
break;
@@ -569,6 +585,10 @@ panel_window_set_property (GObject *object,
switch (prop_id)
{
+ case PROP_ID:
+ window->id = g_value_get_int (value);
+ break;
+
case PROP_MODE:
val_mode = g_value_get_enum (value);
if (window->mode != val_mode)
@@ -2531,12 +2551,14 @@ panel_window_plugin_set_screen_position (GtkWidget *widget,
GtkWidget *
-panel_window_new (GdkScreen *screen)
+panel_window_new (GdkScreen *screen,
+ gint id)
{
if (screen == NULL)
screen = gdk_screen_get_default ();
return g_object_new (PANEL_TYPE_WINDOW,
+ "id", id,
"type", GTK_WINDOW_TOPLEVEL,
"decorated", FALSE,
"resizable", FALSE,
@@ -2550,6 +2572,16 @@ panel_window_new (GdkScreen *screen)
+gint
+panel_window_get_id (PanelWindow *window)
+{
+ panel_return_val_if_fail (PANEL_IS_WINDOW (window), -1);
+ panel_return_val_if_fail (window->id > -1, -1);
+ return window->id;
+}
+
+
+
gboolean
panel_window_has_position (PanelWindow *window)
{
diff --git a/panel/panel-window.h b/panel/panel-window.h
index b745c48..e31d2b6 100644
--- a/panel/panel-window.h
+++ b/panel/panel-window.h
@@ -35,7 +35,10 @@ typedef struct _PanelWindow PanelWindow;
GType panel_window_get_type (void) G_GNUC_CONST;
-GtkWidget *panel_window_new (GdkScreen *screen) G_GNUC_MALLOC;
+GtkWidget *panel_window_new (GdkScreen *screen,
+ gint id) G_GNUC_MALLOC;
+
+gint panel_window_get_id (PanelWindow *window);
gboolean panel_window_has_position (PanelWindow *window);
More information about the Xfce4-commits
mailing list