[Xfce4-commits] <xfce4-settings:stephan/dialogs> Enable buttons in the UI

Stephan Arts noreply at xfce.org
Tue Mar 20 19:14:01 CET 2012


Updating branch refs/heads/stephan/dialogs
         to 4220c6d9f63b27401c25f259f003231d138819e8 (commit)
       from 16fdfe2b76dc0f99761a332934314cac20a70ce5 (commit)

commit 4220c6d9f63b27401c25f259f003231d138819e8
Author: Stephan Arts <stephan at xfce.org>
Date:   Tue Mar 20 19:11:39 2012 +0100

    Enable buttons in the UI

 .../appearance-settings/appearance-dialog.glade    |    2 +-
 dialogs/appearance-settings/main.c                 |  888 +++++++++++++++++---
 2 files changed, 773 insertions(+), 117 deletions(-)

diff --git a/dialogs/appearance-settings/appearance-dialog.glade b/dialogs/appearance-settings/appearance-dialog.glade
index 72128af..20582fa 100644
--- a/dialogs/appearance-settings/appearance-dialog.glade
+++ b/dialogs/appearance-settings/appearance-dialog.glade
@@ -127,7 +127,7 @@
                             <property name="vscrollbar_policy">automatic</property>
                             <property name="shadow_type">in</property>
                             <child>
-                              <object class="GtkTreeView" id="theme_name_treeview">
+                              <object class="GtkTreeView" id="xfwm4_theme_treeview">
                                 <property name="visible">True</property>
                                 <property name="can_focus">True</property>
                                 <property name="headers_visible">False</property>
diff --git a/dialogs/appearance-settings/main.c b/dialogs/appearance-settings/main.c
index f1486a1..bff1fa9 100644
--- a/dialogs/appearance-settings/main.c
+++ b/dialogs/appearance-settings/main.c
@@ -41,6 +41,8 @@
 #include "appearance-dialog_ui.h"
 #include "images.h"
 
+#define XFWM4_DEFAULT_THEME             "Default"
+
 #define INCH_MM      25.4
 
 /* Use a fallback DPI of 96 which should be ok-ish on most systems
@@ -50,6 +52,27 @@
 /* Increase this number if new gtk settings have been added */
 #define INITIALIZE_UINT (1)
 
+typedef struct _MenuTemplate     MenuTemplate;
+struct _MenuTemplate
+{
+  const gchar *name;
+  const gchar *value;
+};
+
+static const MenuTemplate title_align_values[] = {
+  { N_("Left"), "left" },
+  { N_("Center"), "center" },
+  { N_("Right"), "right" },
+  { NULL, NULL },
+};
+
+enum
+{
+  XFWM4_THEME_COLUMN_NAME,
+  XFWM4_THEME_COLUMN_RC,
+  N_XFWM4_THEME_COLUMNS
+};
+
 enum
 {
     COLUMN_THEME_NAME,
@@ -96,8 +119,40 @@ static GOptionEntry option_entries[] =
     { NULL }
 };
 
-/* Global xfconf channel */
+static void
+xfwm_settings_active_frame_drag_data (GtkWidget        *widget,
+                                      GdkDragContext   *drag_context,
+                                      gint              x,
+                                      gint              y,
+                                      GtkSelectionData *data,
+                                      guint             info,
+                                      guint             timestamp,
+                                      gpointer         *user_data);
+
+static GdkPixbuf *
+xfwm_settings_create_icon_from_widget (GtkWidget *widget);
+
+static void
+cb_xfwm_title_button_alignment_changed (GtkComboBox *combo,
+                                        GtkWidget   *button);
+static void
+cb_xfwm_title_button_drag_data (GtkWidget        *widget,
+                                GdkDragContext   *drag_context,
+                                GtkSelectionData *data,
+                                guint             info,
+                                guint             timestamp);
+static void
+cb_xfwm_title_button_drag_begin (GtkWidget      *widget,
+                                 GdkDragContext *drag_context);
+static void
+cb_xfwm_title_button_drag_end (GtkWidget      *widget,
+                               GdkDragContext *drag_context);
+static gboolean
+cb_appearance_settings_signal_blocker (GtkWidget *widget);
+
+/* Global xfconf channels */
 static XfconfChannel *xsettings_channel;
+static XfconfChannel *xfwm4_channel;
 
 static int
 compute_xsettings_dpi (GtkWidget *widget)
@@ -124,6 +179,54 @@ compute_xsettings_dpi (GtkWidget *widget)
 }
 
 static void
+cb_xfwm_theme_tree_selection_changed (GtkTreeSelection *selection,
+                                      GtkBuilder       *builder)
+{
+    GtkTreeModel *model;
+    gboolean      has_selection;
+    XfceRc       *rc;
+    GtkWidget    *widget;
+    gchar        *name;
+    gchar        *filename;
+    GtkTreeIter   iter;
+    gboolean      button_layout = FALSE;
+    gboolean      title_alignment = FALSE;
+
+    /* Get the selected list iter */
+    has_selection = gtk_tree_selection_get_selected (selection, &model, &iter);
+    if (G_LIKELY (has_selection))
+    {
+        /* Get the theme name */
+        gtk_tree_model_get (model, &iter,
+                            XFWM4_THEME_COLUMN_NAME, &name,
+                            XFWM4_THEME_COLUMN_RC, &filename, -1);
+
+        /* Store the new theme */
+        xfconf_channel_set_string (xfwm4_channel, "/general/theme", name);
+
+        /* check in the rc if the theme supports a custom button layout and/or
+         * title alignement */
+        rc = xfce_rc_simple_open (filename, TRUE);
+        g_free (filename);
+        if (G_LIKELY (rc != NULL))
+        {
+            button_layout = !xfce_rc_has_entry (rc, "button_layout");
+            title_alignment = !xfce_rc_has_entry (rc, "title_alignment");
+            xfce_rc_close (rc);
+        }
+
+        /* Cleanup */
+        g_free (name);
+    }
+
+    widget = GTK_WIDGET (gtk_builder_get_object (builder, "button_layout_box"));
+    gtk_widget_set_sensitive (widget, button_layout);
+
+    widget = GTK_WIDGET (gtk_builder_get_object (builder, "title_align_box"));
+    gtk_widget_set_sensitive (widget, title_alignment);
+}
+
+static void
 cb_theme_tree_selection_changed (GtkTreeSelection *selection,
                                  const gchar      *property)
 {
@@ -262,6 +365,56 @@ cb_custom_dpi_spin_button_changed (GtkSpinButton   *custom_dpi_spin,
     xfconf_channel_set_int (xsettings_channel, "/Xft/DPI", dpi);
 }
 
+static void
+cb_xfwm_title_alignment_changed (GtkComboBox  *combo)
+{
+  GtkTreeModel *model;
+  GtkTreeIter   iter;
+  gchar        *alignment;
+
+  model = gtk_combo_box_get_model (combo);
+
+  gtk_combo_box_get_active_iter (combo, &iter);
+  gtk_tree_model_get (model, &iter, 1, &alignment, -1);
+
+  xfconf_channel_set_string (xfwm4_channel, "/general/title_alignment", alignment);
+
+  g_free (alignment);
+}
+
+static void
+xfwm_settings_save_button_layout (GtkBuilder *builder)
+{
+  GList        *children;
+  GList        *iter;
+  const gchar **key_chars;
+  gchar        *value;
+  const gchar  *name;
+  gint          i;
+  GtkContainer *container;
+
+  container = (GtkContainer *)gtk_builder_get_object (builder, "active-frame");
+  children = gtk_container_get_children (container);
+
+  key_chars = g_new0 (const char *, g_list_length (children) + 1);
+
+  for (i = 0, iter = children; iter != NULL; ++i, iter = g_list_next (iter))
+  {
+    name = gtk_buildable_get_name (GTK_BUILDABLE (iter->data));
+    key_chars[i] = &name[strlen(name)-1]; //((const gchar *) g_object_get_data (G_OBJECT (iter->data), "key_char"));
+  }
+
+  value = g_strjoinv ("", (gchar **) key_chars);
+  g_debug("%s", value);
+
+  //xfconf_channel_set_string (xfwm4_channel, "/general/button_layout", value);
+
+  g_list_free (children);
+  g_free (key_chars);
+  g_free (value);
+}
+
+
 #ifdef ENABLE_SOUND_SETTINGS
 static void
 cb_enable_event_sounds_check_button_toggled (GtkToggleButton *toggle, GtkWidget *button)
@@ -275,6 +428,75 @@ cb_enable_event_sounds_check_button_toggled (GtkToggleButton *toggle, GtkWidget
 #endif
 
 static void
+appearance_settings_load_xfwm4_themes (GtkListStore *list_store,
+                                       GtkTreeView  *tree_view)
+{
+    GtkTreeIter   iter;
+    GDir         *dir;
+    const gchar  *file;
+    gint          i;
+    gchar        *filename;
+    GHashTable   *themes;
+    gchar       **theme_dirs;
+    gchar        *active_theme_name;
+
+    themes = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
+
+    active_theme_name = xfconf_channel_get_string (xfwm4_channel,
+                                                   "/general/theme",
+                                                   XFWM4_DEFAULT_THEME);
+    xfce_resource_push_path (XFCE_RESOURCE_THEMES, DATADIR G_DIR_SEPARATOR_S "themes");
+    theme_dirs = xfce_resource_dirs (XFCE_RESOURCE_THEMES);
+    xfce_resource_pop_path (XFCE_RESOURCE_THEMES);
+
+    for (i = 0; theme_dirs[i] != NULL; ++i)
+    {
+        dir = g_dir_open (theme_dirs[i], 0, NULL);
+
+        if (G_UNLIKELY (dir == NULL))
+            continue;
+
+        while ((file = g_dir_read_name (dir)) != NULL)
+        {
+            filename = g_build_filename (theme_dirs[i], file, "xfwm4", "themerc", NULL);
+
+            /* check if the theme rc exists and there is not already a theme with the
+             * same name in the database */
+            if (g_file_test (filename, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR) &&
+                g_hash_table_lookup (themes, file) == NULL)
+            {
+              g_hash_table_insert (themes, g_strdup (file), GINT_TO_POINTER (1));
+
+              /* insert in the list store */
+              gtk_list_store_append (list_store, &iter);
+              gtk_list_store_set (list_store, &iter,
+                                  XFWM4_THEME_COLUMN_NAME, file,
+                                  XFWM4_THEME_COLUMN_RC, filename, -1);
+
+              if (G_UNLIKELY (g_str_equal (active_theme_name, file)))
+                {
+                  GtkTreePath *path = gtk_tree_model_get_path (GTK_TREE_MODEL(list_store), &iter);
+
+                  gtk_tree_selection_select_iter (gtk_tree_view_get_selection (tree_view),
+                                                  &iter);
+                  gtk_tree_view_scroll_to_cell (tree_view, path, NULL, TRUE, 0.5, 0.5);
+
+                  gtk_tree_path_free (path);
+                }
+            }
+
+          g_free (filename);
+        }
+
+      g_dir_close (dir);
+    }
+
+  g_free (active_theme_name);
+  g_strfreev (theme_dirs);
+  g_hash_table_destroy (themes);
+}
+
+static void
 appearance_settings_load_icon_themes (GtkListStore *list_store,
                                       GtkTreeView  *tree_view)
 {
@@ -519,161 +741,296 @@ appearance_settings_dialog_channel_property_changed (XfconfChannel *channel,
 
     g_return_if_fail (property_name != NULL);
     g_return_if_fail (GTK_IS_BUILDER (builder));
-
-    if (strcmp (property_name, "/Xft/RGBA") == 0)
+    if (channel == xsettings_channel)
     {
-        str = xfconf_channel_get_string (xsettings_channel, property_name, xft_rgba_array[0]);
-        for (i = 0; i < G_N_ELEMENTS (xft_rgba_array); i++)
+        if (strcmp (property_name, "/Xft/RGBA") == 0)
         {
-            if (strcmp (str, xft_rgba_array[i]) == 0)
+            str = xfconf_channel_get_string (xsettings_channel, property_name, xft_rgba_array[0]);
+            for (i = 0; i < G_N_ELEMENTS (xft_rgba_array); i++)
             {
-                object = gtk_builder_get_object (builder, "xft_rgba_combo_box");
-                gtk_combo_box_set_active (GTK_COMBO_BOX (object), i);
-                break;
+                if (strcmp (str, xft_rgba_array[i]) == 0)
+                {
+                    object = gtk_builder_get_object (builder, "xft_rgba_combo_box");
+                    gtk_combo_box_set_active (GTK_COMBO_BOX (object), i);
+                    break;
+                }
             }
+            g_free (str);
         }
-        g_free (str);
-    }
-    else if (strcmp (property_name, "/Gtk/ToolbarStyle") == 0)
-    {
-        str = xfconf_channel_get_string (xsettings_channel, property_name, toolbar_styles_array[2]);
-        for (i = 0; i < G_N_ELEMENTS (toolbar_styles_array); i++)
+        else if (strcmp (property_name, "/Gtk/ToolbarStyle") == 0)
         {
-            if (strcmp (str, toolbar_styles_array[i]) == 0)
+            str = xfconf_channel_get_string (xsettings_channel, property_name, toolbar_styles_array[2]);
+            for (i = 0; i < G_N_ELEMENTS (toolbar_styles_array); i++)
             {
-                object = gtk_builder_get_object (builder, "gtk_toolbar_style_combo_box");
-                gtk_combo_box_set_active (GTK_COMBO_BOX (object), i);
-                break;
+                if (strcmp (str, toolbar_styles_array[i]) == 0)
+                {
+                    object = gtk_builder_get_object (builder, "gtk_toolbar_style_combo_box");
+                    gtk_combo_box_set_active (GTK_COMBO_BOX (object), i);
+                    break;
+                }
             }
+            g_free (str);
         }
-        g_free (str);
-    }
-    else if (strcmp (property_name, "/Xft/HintStyle") == 0)
-    {
-        str = xfconf_channel_get_string (xsettings_channel, property_name, xft_hint_styles_array[0]);
-        for (i = 0; i < G_N_ELEMENTS (xft_hint_styles_array); i++)
+        else if (strcmp (property_name, "/Xft/HintStyle") == 0)
         {
-            if (strcmp (str, xft_hint_styles_array[i]) == 0)
+            str = xfconf_channel_get_string (xsettings_channel, property_name, xft_hint_styles_array[0]);
+            for (i = 0; i < G_N_ELEMENTS (xft_hint_styles_array); i++)
             {
-                object = gtk_builder_get_object (builder, "xft_hinting_style_combo_box");
-                gtk_combo_box_set_active (GTK_COMBO_BOX (object), i);
-                break;
+                if (strcmp (str, xft_hint_styles_array[i]) == 0)
+                {
+                    object = gtk_builder_get_object (builder, "xft_hinting_style_combo_box");
+                    gtk_combo_box_set_active (GTK_COMBO_BOX (object), i);
+                    break;
+                }
             }
+            g_free (str);
         }
-        g_free (str);
-    }
-    else if (strcmp (property_name, "/Xft/Antialias") == 0)
-    {
-        object = gtk_builder_get_object (builder, "xft_antialias_check_button");
-        antialias = xfconf_channel_get_int (xsettings_channel, property_name, -1);
-        switch (antialias)
+        else if (strcmp (property_name, "/Xft/Antialias") == 0)
         {
-            case 1:
-                gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (object), TRUE);
-                break;
+            object = gtk_builder_get_object (builder, "xft_antialias_check_button");
+            antialias = xfconf_channel_get_int (xsettings_channel, property_name, -1);
+            switch (antialias)
+            {
+                case 1:
+                    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (object), TRUE);
+                    break;
 
-            case 0:
-                gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (object), FALSE);
-                break;
+                case 0:
+                    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (object), FALSE);
+                    break;
 
-            default: /* -1 */
-                gtk_toggle_button_set_inconsistent (GTK_TOGGLE_BUTTON (object), TRUE);
-                break;
+                default: /* -1 */
+                    gtk_toggle_button_set_inconsistent (GTK_TOGGLE_BUTTON (object), TRUE);
+                    break;
+            }
         }
-    }
-    else if (strcmp (property_name, "/Xft/DPI") == 0)
-    {
-        /* The DPI has changed, so get its value and the last known custom value */
-        dpi = xfconf_channel_get_int (xsettings_channel, property_name, FALLBACK_DPI);
-        custom_dpi = xfconf_channel_get_int (xsettings_channel, "/Xfce/LastCustomDPI", -1);
+        else if (strcmp (property_name, "/Xft/DPI") == 0)
+        {
+            /* The DPI has changed, so get its value and the last known custom value */
+            dpi = xfconf_channel_get_int (xsettings_channel, property_name, FALLBACK_DPI);
+            custom_dpi = xfconf_channel_get_int (xsettings_channel, "/Xfce/LastCustomDPI", -1);
 
-        /* Activate the check button if we're using a custom DPI */
-        object = gtk_builder_get_object (builder, "xft_custom_dpi_check_button");
-        gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (object), dpi >= 0);
+            /* Activate the check button if we're using a custom DPI */
+            object = gtk_builder_get_object (builder, "xft_custom_dpi_check_button");
+            gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (object), dpi >= 0);
 
-        /* If we're not using a custom DPI, compute the future custom DPI automatically */
-        if (custom_dpi == -1)
-            custom_dpi = compute_xsettings_dpi (GTK_WIDGET (object));
+            /* If we're not using a custom DPI, compute the future custom DPI automatically */
+            if (custom_dpi == -1)
+                custom_dpi = compute_xsettings_dpi (GTK_WIDGET (object));
 
-        object = gtk_builder_get_object (builder, "xft_custom_dpi_spin_button");
+            object = gtk_builder_get_object (builder, "xft_custom_dpi_spin_button");
 
-        if (dpi > 0)
-        {
-            /* We're using a custom DPI, so use the current DPI setting for the spin value */
-            gtk_spin_button_set_value (GTK_SPIN_BUTTON (object), dpi);
+            if (dpi > 0)
+            {
+                /* We're using a custom DPI, so use the current DPI setting for the spin value */
+                gtk_spin_button_set_value (GTK_SPIN_BUTTON (object), dpi);
+            }
+            else
+            {
+                /* Set the spin button value to the last custom DPI */
+                gtk_spin_button_set_value (GTK_SPIN_BUTTON (object), custom_dpi);
+            }
         }
-        else
+        else if (strcmp (property_name, "/Net/ThemeName") == 0)
         {
-            /* Set the spin button value to the last custom DPI */
-            gtk_spin_button_set_value (GTK_SPIN_BUTTON (object), custom_dpi);
-        }
-    }
-    else if (strcmp (property_name, "/Net/ThemeName") == 0)
-    {
-        GtkTreeIter iter;
-        gboolean    reload;
+            GtkTreeIter iter;
+            gboolean    reload;
 
-        object = gtk_builder_get_object (builder, "gtk_theme_treeview");
-        model = gtk_tree_view_get_model (GTK_TREE_VIEW (object));
-        reload = TRUE;
+            object = gtk_builder_get_object (builder, "gtk_theme_treeview");
+            model = gtk_tree_view_get_model (GTK_TREE_VIEW (object));
+            reload = TRUE;
 
-        if (gtk_tree_selection_get_selected (gtk_tree_view_get_selection (GTK_TREE_VIEW (object)),
-                                             &model,
-                                             &iter))
-        {
-            gchar *selected_name;
-            gchar *new_name;
+            if (gtk_tree_selection_get_selected (gtk_tree_view_get_selection (GTK_TREE_VIEW (object)),
+                                                 &model,
+                                                 &iter))
+            {
+                gchar *selected_name;
+                gchar *new_name;
 
-            gtk_tree_model_get (model, &iter, COLUMN_THEME_NAME, &selected_name, -1);
+                gtk_tree_model_get (model, &iter, COLUMN_THEME_NAME, &selected_name, -1);
 
-            new_name = xfconf_channel_get_string (channel, property_name, NULL);
+                new_name = xfconf_channel_get_string (channel, property_name, NULL);
 
-            reload = (strcmp (new_name, selected_name) != 0);
+                reload = (strcmp (new_name, selected_name) != 0);
 
-            g_free (selected_name);
-            g_free (new_name);
-        }
+                g_free (selected_name);
+                g_free (new_name);
+            }
 
-        if (reload)
+            if (reload)
+            {
+                gtk_list_store_clear (GTK_LIST_STORE (model));
+                appearance_settings_load_ui_themes (GTK_LIST_STORE (model), GTK_TREE_VIEW (object));
+            }
+        }
+        else if (strcmp (property_name, "/Net/IconThemeName") == 0)
         {
-            gtk_list_store_clear (GTK_LIST_STORE (model));
-            appearance_settings_load_ui_themes (GTK_LIST_STORE (model), GTK_TREE_VIEW (object));
+            GtkTreeIter iter;
+            gboolean    reload;
+
+            reload = TRUE;
+
+            object = gtk_builder_get_object (builder, "icon_theme_treeview");
+            model = gtk_tree_view_get_model (GTK_TREE_VIEW (object));
+
+            if (gtk_tree_selection_get_selected (gtk_tree_view_get_selection (GTK_TREE_VIEW (object)),
+                                                 &model,
+                                                 &iter))
+            {
+                gchar *selected_name;
+                gchar *new_name;
+
+                gtk_tree_model_get (model, &iter, COLUMN_THEME_NAME, &selected_name, -1);
+
+                new_name = xfconf_channel_get_string (channel, property_name, NULL);
+
+                reload = (strcmp (new_name, selected_name) != 0);
+
+                g_free (selected_name);
+                g_free (new_name);
+            }
+
+
+            if (reload)
+            {
+                gtk_list_store_clear (GTK_LIST_STORE (model));
+                appearance_settings_load_icon_themes (GTK_LIST_STORE (model), GTK_TREE_VIEW (object));
+            }
         }
     }
-    else if (strcmp (property_name, "/Net/IconThemeName") == 0)
+
+    if (channel == xfwm4_channel)
     {
-        GtkTreeIter iter;
-        gboolean    reload;
+        if (strcmp (property_name, "/general/theme") == 0)
+        {
+            GtkTreeIter iter;
+            gboolean    reload;
 
-        reload = TRUE;
+            reload = TRUE;
 
-        object = gtk_builder_get_object (builder, "icon_theme_treeview");
-        model = gtk_tree_view_get_model (GTK_TREE_VIEW (object));
+            object = gtk_builder_get_object (builder, "xfwm4_theme_treeview");
+            model = gtk_tree_view_get_model (GTK_TREE_VIEW (object));
 
-        if (gtk_tree_selection_get_selected (gtk_tree_view_get_selection (GTK_TREE_VIEW (object)),
-                                             &model,
-                                             &iter))
-        {
-            gchar *selected_name;
-            gchar *new_name;
+            if (gtk_tree_selection_get_selected (gtk_tree_view_get_selection (GTK_TREE_VIEW (object)),
+                                                 &model,
+                                                 &iter))
+            {
+                gchar *selected_name;
+                gchar *new_name;
+
+                gtk_tree_model_get (model, &iter, XFWM4_THEME_COLUMN_NAME, &selected_name, -1);
 
-            gtk_tree_model_get (model, &iter, COLUMN_THEME_NAME, &selected_name, -1);
+                new_name = xfconf_channel_get_string (channel, property_name, NULL);
 
-            new_name = xfconf_channel_get_string (channel, property_name, NULL);
+                reload = (strcmp (new_name, selected_name) != 0);
 
-            reload = (strcmp (new_name, selected_name) != 0);
+                g_free (selected_name);
+                g_free (new_name);
+            }
 
-            g_free (selected_name);
-            g_free (new_name);
+
+            if (reload)
+            {
+                gtk_list_store_clear (GTK_LIST_STORE (model));
+                appearance_settings_load_xfwm4_themes (GTK_LIST_STORE (model), GTK_TREE_VIEW (object));
+            }
         }
+        else if (strcmp (property_name, "/general/title_alignment") == 0)
+        {
+            GtkWidget    *combo;
+            gchar        *alignment;
+            GtkTreeIter   iter;
+            const gchar  *new_value;
+
+            combo = GTK_WIDGET (gtk_builder_get_object (builder, "title_align_combo"));
+            model = gtk_combo_box_get_model (GTK_COMBO_BOX (combo));
 
+            if (gtk_tree_model_get_iter_first (model, &iter))
+            {
+                do
+                {
+                    gtk_tree_model_get (model, &iter, 1, &alignment, -1);
 
-        if (reload)
+                    if (G_UNLIKELY (G_VALUE_TYPE (value) == G_TYPE_INVALID))
+                        new_value = "center";
+                    else
+                        new_value = g_value_get_string (value);
+
+                    if (G_UNLIKELY (g_str_equal (alignment, new_value)))
+                    {
+                        g_free (alignment);
+                        gtk_combo_box_set_active_iter (GTK_COMBO_BOX (combo), &iter);
+                        break;
+                    }
+
+                    g_free (alignment);
+                }
+                while (gtk_tree_model_iter_next (model, &iter));
+            }
+        }
+        else if (strcmp (property_name, "/general/button_layout") == 0)
         {
-            gtk_list_store_clear (GTK_LIST_STORE (model));
-            appearance_settings_load_icon_themes (GTK_LIST_STORE (model), GTK_TREE_VIEW (object));
+            GtkWidget   *active_box;
+            GtkWidget   *hidden_box;
+            GtkWidget   *button;
+            GList       *children;
+            GList       *iter;
+            const gchar *str_value;
+            const gchar *key_char;
+
+            hidden_box = GTK_WIDGET (gtk_builder_get_object (builder, "hidden-box"));
+            active_box = GTK_WIDGET (gtk_builder_get_object (builder, "active-box"));
+
+            gtk_widget_set_app_paintable (active_box, FALSE);
+            gtk_widget_set_app_paintable (hidden_box, FALSE);
+
+            children = gtk_container_get_children (GTK_CONTAINER (active_box));
+
+            /* Move all buttons to the hidden list, except for the title */
+            for (iter = children; iter != NULL; iter = g_list_next (iter))
+            {
+                button = GTK_WIDGET (iter->data);
+                key_char = (const gchar *) g_object_get_data (G_OBJECT (button), "key_char");
+
+                if (G_LIKELY (key_char[0] != '|'))
+                {
+                    g_object_ref (button);
+                    gtk_container_remove (GTK_CONTAINER (active_box), button);
+                    gtk_box_pack_start (GTK_BOX (hidden_box), button, FALSE, FALSE, 0);
+                    g_object_unref (button);
+                }
+            }
+
+            g_list_free (children);
+
+            children = g_list_concat (gtk_container_get_children (GTK_CONTAINER (active_box)),
+                                      gtk_container_get_children (GTK_CONTAINER (hidden_box)));
+
+            /* Move buttons to the active list */
+            for (str_value = g_value_get_string (value); *str_value != '\0'; ++str_value)
+            {
+                for (iter = children; iter != NULL; iter = g_list_next (iter))
+                {
+                    button = GTK_WIDGET (iter->data);
+                    key_char = (const gchar *) g_object_get_data (G_OBJECT (button), "key_char");
+
+                    if (g_str_has_prefix (str_value, key_char))
+                    {
+                        g_object_ref (button);
+                        gtk_container_remove (GTK_CONTAINER (gtk_widget_get_parent (button)), button);
+                        gtk_box_pack_start (GTK_BOX (active_box), button,
+                                            key_char[0] == '|', key_char[0] == '|', 0);
+                        g_object_unref (button);
+                    }
+                }
+            }
+
+            g_list_free (children);
+
+            gtk_widget_set_app_paintable (active_box, TRUE);
+            gtk_widget_set_app_paintable (hidden_box, TRUE);
         }
-    }
+    } 
 }
 
 static void
@@ -791,11 +1148,166 @@ cb_theme_uri_dropped (GtkWidget        *widget,
 static void
 appearance_settings_dialog_configure_widgets (GtkBuilder *builder)
 {
-    GObject          *object, *object2;
-    GtkListStore     *list_store;
-    GtkCellRenderer  *renderer;
-    GdkPixbuf        *pixbuf;
-    GtkTreeSelection *selection;
+    GObject            *object, *object2;
+    GtkTreeIter         iter;
+    const MenuTemplate *template;
+    GtkListStore       *list_store;
+    GtkCellRenderer    *renderer;
+    GdkPixbuf          *pixbuf;
+    GtkTreeSelection   *selection;
+    GtkWidget          *hidden_frame;
+    GtkWidget          *hidden_box;
+    GtkWidget          *active_frame;
+    GtkWidget          *active_box;
+    GtkWidget          *title_font_button;
+    GtkWidget          *title_align_combo;
+    GList              *children;
+    GList              *list_iter;
+    GValue              value = { 0, };
+    GtkTargetEntry      target_entry[2];
+    const gchar        *name;
+
+    /* xfwm4 themes */
+    object = gtk_builder_get_object (builder, "xfwm4_theme_treeview");
+
+    list_store = gtk_list_store_new (N_XFWM4_THEME_COLUMNS, G_TYPE_STRING, G_TYPE_STRING);
+    gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (list_store), XFWM4_THEME_COLUMN_NAME, GTK_SORT_ASCENDING);
+    gtk_tree_view_set_model (GTK_TREE_VIEW (object), GTK_TREE_MODEL (list_store));
+    renderer = gtk_cell_renderer_text_new ();
+    gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (object), 0, "", renderer, "text", XFWM4_THEME_COLUMN_NAME, NULL);
+
+    appearance_settings_load_xfwm4_themes (list_store, GTK_TREE_VIEW (object));
+
+    g_object_unref (G_OBJECT (list_store));
+
+    selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (object));
+    gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE);
+    g_signal_connect (G_OBJECT (selection), "changed", G_CALLBACK (cb_xfwm_theme_tree_selection_changed), builder);
+
+    title_font_button = GTK_WIDGET (gtk_builder_get_object (builder, "title_font_button"));
+    xfconf_g_property_bind (xfwm4_channel,
+                            "/general/title_font", G_TYPE_STRING,
+                            title_font_button, "font-name");
+
+    title_align_combo = GTK_WIDGET (gtk_builder_get_object (builder, "title_align_combo"));
+    gtk_cell_layout_clear (GTK_CELL_LAYOUT (title_align_combo));
+
+    renderer = gtk_cell_renderer_text_new ();
+    gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (title_align_combo), renderer, TRUE);
+    gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (title_align_combo), renderer, "text", 0);
+
+    list_store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_STRING);
+    gtk_combo_box_set_model (GTK_COMBO_BOX (title_align_combo), GTK_TREE_MODEL (list_store));
+
+    for (template = title_align_values; template->name != NULL; ++template)
+    {
+        gtk_list_store_append (list_store, &iter);
+        gtk_list_store_set (list_store, &iter, 0, _(template->name), 1, template->value, -1);
+    }
+    g_object_unref (G_OBJECT (list_store));
+
+    xfconf_channel_get_property (xfwm4_channel, "/general/title_alignment", &value);
+    appearance_settings_dialog_channel_property_changed (xfwm4_channel, "/general/title_alignment", &value, builder);
+    g_value_unset (&value);
+
+    g_signal_connect (title_align_combo, "changed",
+                      G_CALLBACK (cb_xfwm_title_alignment_changed), NULL);
+
+    /* Style tab: button layout */
+    {
+
+        active_frame = GTK_WIDGET (gtk_builder_get_object (builder, "active-frame"));
+        hidden_frame = GTK_WIDGET (gtk_builder_get_object (builder, "hidden-frame"));
+        active_box = GTK_WIDGET (gtk_builder_get_object (builder, "active-box"));
+        hidden_box = GTK_WIDGET (gtk_builder_get_object (builder, "hidden-box"));
+
+        target_entry[0].target = "_xfwm4_button_layout";
+        target_entry[0].flags = 0;
+        target_entry[0].info = 2;
+
+        target_entry[1].target = "_xfwm4_active_layout";
+        target_entry[1].flags = 0;
+        target_entry[1].info = 3;
+
+        gtk_drag_dest_set (active_frame, GTK_DEST_DEFAULT_ALL, target_entry, 2, GDK_ACTION_MOVE);
+
+        g_signal_connect (active_frame, "drag-data-received",
+                          G_CALLBACK (xfwm_settings_active_frame_drag_data), builder);
+#if 0
+        g_signal_connect (active_frame, "drag-motion",
+                          G_CALLBACK (xfwm_settings_active_frame_drag_motion), builder);
+        g_signal_connect (active_frame, "drag-leave",
+                          G_CALLBACK (xfwm_settings_active_frame_drag_leave), builder);
+#endif
+
+        gtk_drag_dest_set (hidden_frame, GTK_DEST_DEFAULT_ALL, target_entry, 1, GDK_ACTION_MOVE);
+
+#if 0
+        g_signal_connect (hidden_frame, "drag-data-received",
+                          G_CALLBACK (xfwm_settings_hidden_frame_drag_data), settings);
+#endif
+
+        children = gtk_container_get_children (GTK_CONTAINER (active_box));
+        for (list_iter = children; list_iter != NULL; list_iter = g_list_next (list_iter))
+        {
+            object = list_iter->data;
+            name = gtk_buildable_get_name (GTK_BUILDABLE (object));
+
+            if (name[strlen (name) - 1] == '|')
+            {
+                g_signal_connect (title_align_combo, "changed",
+                                  G_CALLBACK (cb_xfwm_title_button_alignment_changed), object);
+                cb_xfwm_title_button_alignment_changed (GTK_COMBO_BOX (title_align_combo),
+                                                              GTK_WIDGET (object));
+            }
+
+            g_object_set_data (object, "key_char", (gpointer) &name[strlen (name) - 1]);
+            g_debug("%s", (char *)g_object_get_data (object, "key_char"));
+            gtk_drag_source_set (GTK_WIDGET(object), GDK_BUTTON1_MASK, &target_entry[1], 1, GDK_ACTION_MOVE);
+
+            g_signal_connect (object, "drag_data_get",
+                              G_CALLBACK (cb_xfwm_title_button_drag_data), NULL);
+            g_signal_connect (object, "drag_begin", G_CALLBACK (cb_xfwm_title_button_drag_begin),
+                              NULL);
+            g_signal_connect (object, "drag_end", G_CALLBACK (cb_xfwm_title_button_drag_end),
+                              NULL);
+            g_signal_connect (object, "button_press_event",
+                              G_CALLBACK (cb_appearance_settings_signal_blocker), NULL);
+            g_signal_connect (object, "enter_notify_event",
+                              G_CALLBACK (cb_appearance_settings_signal_blocker), NULL);
+            g_signal_connect (object, "focus",  G_CALLBACK (cb_appearance_settings_signal_blocker), NULL);
+        }
+        g_list_free (children);
+
+        children = gtk_container_get_children (GTK_CONTAINER (hidden_box));
+        for (list_iter = children; list_iter != NULL; list_iter = g_list_next (list_iter))
+        {
+            object = list_iter->data;
+            name = gtk_buildable_get_name (GTK_BUILDABLE (object));
+
+            g_object_set_data (object, "key_char", (gpointer) &name[strlen (name) - 1]);
+            g_debug("%s", &name[strlen(name)-1]);
+            gtk_drag_source_set (GTK_WIDGET (object), GDK_BUTTON1_MASK, &target_entry[0], 1, GDK_ACTION_MOVE);
+
+              g_signal_connect (object, "drag_data_get",
+                                G_CALLBACK (cb_xfwm_title_button_drag_data), NULL);
+              g_signal_connect (object, "drag_begin", G_CALLBACK (cb_xfwm_title_button_drag_begin),
+                                NULL);
+              g_signal_connect (object, "drag_end", G_CALLBACK (cb_xfwm_title_button_drag_end),
+                                NULL);
+              g_signal_connect (object, "button_press_event",
+                                G_CALLBACK (cb_appearance_settings_signal_blocker), NULL);
+              g_signal_connect (object, "enter_notify_event",
+                                G_CALLBACK (cb_appearance_settings_signal_blocker), NULL);
+              g_signal_connect (object, "focus",  G_CALLBACK (cb_appearance_settings_signal_blocker), NULL);
+        }
+        g_list_free (children);
+
+        xfconf_channel_get_property (xfwm4_channel, "/general/button_layout", &value);
+        appearance_settings_dialog_channel_property_changed(xfwm4_channel,
+                                                            "/general/button_layout", &value, builder);
+        g_value_unset (&value);
+    }
 
     /* Icon themes list */
     object = gtk_builder_get_object (builder, "icon_theme_treeview");
@@ -1001,6 +1513,7 @@ main (gint argc, gchar **argv)
 
     /* open the xsettings channel */
     xsettings_channel = xfconf_channel_new ("xsettings");
+    xfwm4_channel = xfconf_channel_new ("xfwm4");
     if (G_LIKELY (xsettings_channel))
     {
         /* hook to make sure the libxfce4ui library is linked */
@@ -1015,6 +1528,8 @@ main (gint argc, gchar **argv)
             /* connect signal to monitor the channel */
             g_signal_connect (G_OBJECT (xsettings_channel), "property-changed",
                 G_CALLBACK (appearance_settings_dialog_channel_property_changed), builder);
+            g_signal_connect (G_OBJECT (xfwm4_channel), "property-changed",
+                G_CALLBACK (appearance_settings_dialog_channel_property_changed), builder);
 
             appearance_settings_dialog_configure_widgets (builder);
 
@@ -1063,8 +1578,9 @@ main (gint argc, gchar **argv)
         /* Release Builder */
         g_object_unref (G_OBJECT (builder));
 
-        /* release the channel */
+        /* release the channels */
         g_object_unref (G_OBJECT (xsettings_channel));
+        g_object_unref (G_OBJECT (xfwm4_channel));
     }
 
     /* shutdown xfconf */
@@ -1072,3 +1588,143 @@ main (gint argc, gchar **argv)
 
     return EXIT_SUCCESS;
 }
+
+static void
+xfwm_settings_active_frame_drag_data (GtkWidget        *widget,
+                                      GdkDragContext   *drag_context,
+                                      gint              x,
+                                      gint              y,
+                                      GtkSelectionData *data,
+                                      guint             info,
+                                      guint             timestamp,
+                                      gpointer         *user_data)
+{
+    GtkWidget *source;
+    GtkWidget *parent;
+    GtkWidget *active_box;
+    GList     *children;
+    GList     *iter;
+    gint       xoffset;
+    gint       i;
+    GtkBuilder*builder = GTK_BUILDER (user_data);
+
+    source = GTK_WIDGET (gtk_builder_get_object (builder,
+                                (const gchar *)gtk_selection_data_get_data (data)));
+    parent = gtk_widget_get_parent (source);
+
+    active_box = GTK_WIDGET (gtk_builder_get_object (builder, "active-box"));
+
+    g_object_ref (source);
+    gtk_container_remove (GTK_CONTAINER (parent), source);
+    gtk_box_pack_start (GTK_BOX (active_box), source, info == 3, info == 3, 0);
+    g_object_unref (source);
+
+    xoffset = widget->allocation.x;
+
+    children = gtk_container_get_children (GTK_CONTAINER (active_box));
+
+    for (i = 0, iter = children; iter != NULL; ++i, iter = g_list_next (iter))
+    {
+        if (GTK_WIDGET_VISIBLE (iter->data))
+        {
+            if (x < (GTK_WIDGET (iter->data)->allocation.width / 2 +
+               GTK_WIDGET (iter->data)->allocation.x - xoffset))
+            {
+                break;
+            }
+        }
+    }
+
+    g_list_free (children);
+
+    gtk_box_reorder_child (GTK_BOX (active_box), source, i);
+
+    xfwm_settings_save_button_layout (builder);
+}
+
+static void
+cb_xfwm_title_button_alignment_changed (GtkComboBox *combo,
+                                        GtkWidget   *button)
+{
+    GtkTreeModel *model;
+    GtkTreeIter   iter;
+    gchar        *value;
+    float         align = 0.5f;
+
+    model = gtk_combo_box_get_model (combo);
+    gtk_combo_box_get_active_iter (combo, &iter);
+    gtk_tree_model_get (model, &iter, 1, &value, -1);
+
+    if (g_str_equal (value, "left"))
+    {
+        align = 0.0f;
+    }
+    else if (g_str_equal (value, "right"))
+    {
+        align = 1.0f;
+    }
+
+    gtk_button_set_alignment (GTK_BUTTON (button), align, 0.5f);
+
+    g_free (value);
+}
+
+static void
+cb_xfwm_title_button_drag_data (GtkWidget        *widget,
+                                GdkDragContext   *drag_context,
+                                GtkSelectionData *data,
+                                guint             info,
+                                guint             timestamp)
+{
+    const gchar *name;
+
+    name = gtk_buildable_get_name (GTK_BUILDABLE (widget));
+
+    gtk_widget_hide (widget);
+    gtk_selection_data_set (data, gdk_atom_intern ("_xfwm4_button_layout", FALSE), 8,
+                            (const guchar *)name, strlen (name));
+}
+
+
+
+static void
+cb_xfwm_title_button_drag_begin (GtkWidget      *widget,
+                                 GdkDragContext *drag_context)
+{
+    GdkPixbuf *pixbuf;
+
+    g_return_if_fail (GTK_IS_WIDGET (widget));
+
+    pixbuf = xfwm_settings_create_icon_from_widget (widget);
+    gtk_drag_source_set_icon_pixbuf (widget, pixbuf);
+    g_object_unref (pixbuf);
+
+    gtk_widget_hide (widget);
+}
+
+static void
+cb_xfwm_title_button_drag_end (GtkWidget      *widget,
+                               GdkDragContext *drag_context)
+{
+    gtk_widget_show (widget);
+}
+
+static gboolean
+cb_appearance_settings_signal_blocker (GtkWidget *widget)
+{
+    return TRUE;
+}
+
+static GdkPixbuf *
+xfwm_settings_create_icon_from_widget (GtkWidget *widget)
+{
+  GdkWindow *drawable;
+
+  g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
+
+  drawable = GDK_DRAWABLE (gtk_widget_get_parent_window (widget));
+  return gdk_pixbuf_get_from_drawable (NULL, drawable, NULL,
+                                       widget->allocation.x, widget->allocation.y, 0, 0,
+                                       widget->allocation.width, widget->allocation.height);
+}
+


More information about the Xfce4-commits mailing list