FileManager statement from old config should never be scanned again.
[lxde/lxpanel.git] / src / configurator.c
index bfacd7e..8056731 100644 (file)
@@ -1,6 +1,6 @@
 /**
  *
- * Copyright (c) 2006 LxDE Developers, see the file AUTHORS for details.
+ * Copyright (c) 2006-2014 LxDE Developers, see the file AUTHORS for details.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -21,6 +21,8 @@
 #include "config.h"
 #endif
 
+#define __LXPANEL_INTERNALS__
+
 #include "private.h"
 #include "misc.h"
 #include "bg.h"
@@ -41,17 +43,11 @@ enum{
     N_COLS
 };
 
-void panel_configure(Panel* p, int sel_page );
-void restart(void);
-void gtk_run(void);
-void logout(void);
 static void save_global_config();
 
 Command commands[] = {
     //{ "configure", N_("Preferences"), configure },
-#ifndef DISABLE_MENU
     { "run", N_("Run"), gtk_run },
-#endif
     { "restart", N_("Restart"), restart },
     { "logout", N_("Logout"), logout },
     { NULL, NULL },
@@ -60,7 +56,6 @@ Command commands[] = {
 static char* logout_cmd = NULL;
 
 extern GSList* all_panels;
-extern gchar *cprofile;
 extern int config;
 
 /* macros to update config */
@@ -79,7 +74,7 @@ extern int config;
 #define UPDATE_GLOBAL_COLOR(panel,name,val) do { \
     config_setting_t *_s = config_setting_add(config_setting_get_elem(config_setting_get_member(config_root_setting(panel->config),""),\
                                                                       0),\
-                                              name,PANEL_CONF_TYPE_INT);\
+                                              name,PANEL_CONF_TYPE_STRING);\
     if (_s) { \
         char _c[8];\
         snprintf(_c, sizeof(_c), "#%06x",val);\
@@ -89,8 +84,7 @@ extern int config;
  * 0 to 255, and (2^(2n) - 1) / (2^n - 1) = 2^n + 1 = 257, with n = 8. */
 static guint16 const alpha_scale_factor = 257;
 
-void panel_global_config_save( Panel* p, FILE *fp);
-void panel_plugin_config_save( Panel* p, FILE *fp);
+void panel_config_save(Panel *p);
 
 static void update_opt_menu(GtkWidget *w, int ind);
 static void update_toggle_button(GtkWidget *w, gboolean n);
@@ -118,18 +112,15 @@ response_event(GtkDialog *widget, gint arg1, Panel* panel )
 }
 
 static void
-update_panel_geometry( Panel* p )
+update_panel_geometry( LXPanel* p )
 {
     /* Guard against being called early in panel creation. */
-    if (p->topgwin != NULL)
-    {
-        calculate_position(p);
-        gtk_widget_set_size_request(p->topgwin, p->aw, p->ah);
-        gdk_window_move(p->topgwin->window, p->ax, p->ay);
-        panel_update_background(p);
-        panel_establish_autohide(p);
-        panel_set_wm_strut(p);
-    }
+    _calculate_position(p);
+    gtk_widget_set_size_request(GTK_WIDGET(p), p->priv->aw, p->priv->ah);
+    gdk_window_move(gtk_widget_get_window(GTK_WIDGET(p)), p->priv->ax, p->priv->ay);
+    _panel_queue_update_background(p);
+    _panel_establish_autohide(p);
+    _panel_set_wm_strut(p);
 }
 
 static gboolean edge_selector(Panel* p, int edge)
@@ -143,122 +134,139 @@ gboolean panel_edge_available(Panel* p, int edge, gint monitor)
     GSList* l;
     for (l = all_panels; l != NULL; l = l->next)
         {
-        Panel* pl = (Panel*) l->data;
-        if ((pl != p) && (pl->edge == edge) && (pl->monitor == monitor))
+        LXPanel* pl = (LXPanel*) l->data;
+        if ((pl->priv != p) && (pl->priv->edge == edge) && (pl->priv->monitor == monitor))
             return FALSE;
         }
     return TRUE;
 }
 
-static void set_edge(Panel* p, int edge)
+static void set_edge(LXPanel* panel, int edge)
 {
+    Panel *p = panel->priv;
+
     p->edge = edge;
-    update_panel_geometry(p);
-    panel_set_panel_configuration_changed(p);
+    update_panel_geometry(panel);
+    _panel_set_panel_configuration_changed(panel);
     UPDATE_GLOBAL_STRING(p, "edge", num2str(edge_pair, edge, "none"));
 }
 
-static void edge_bottom_toggle(GtkToggleButton *widget, Panel *p)
+static void edge_bottom_toggle(GtkToggleButton *widget, LXPanel *p)
 {
     if (gtk_toggle_button_get_active(widget))
         set_edge(p, EDGE_BOTTOM);
 }
 
-static void edge_top_toggle(GtkToggleButton *widget, Panel *p)
+static void edge_top_toggle(GtkToggleButton *widget, LXPanel *p)
 {
     if (gtk_toggle_button_get_active(widget))
         set_edge(p, EDGE_TOP);
 }
 
-static void edge_left_toggle(GtkToggleButton *widget, Panel *p)
+static void edge_left_toggle(GtkToggleButton *widget, LXPanel *p)
 {
     if (gtk_toggle_button_get_active(widget))
         set_edge(p, EDGE_LEFT);
 }
 
-static void edge_right_toggle(GtkToggleButton *widget, Panel *p)
+static void edge_right_toggle(GtkToggleButton *widget, LXPanel *p)
 {
     if (gtk_toggle_button_get_active(widget))
         set_edge(p, EDGE_RIGHT);
 }
 
-static void set_monitor(GtkAdjustment *widget, Panel *p)
+static void set_monitor(GtkSpinButton *widget, LXPanel *panel)
 {
-    p->monitor = gtk_adjustment_get_value(widget);
-    update_panel_geometry(p);
-    panel_set_panel_configuration_changed(p);
+    Panel *p = panel->priv;
+
+    p->monitor = gtk_spin_button_get_value_as_int(widget) - 1;
+    update_panel_geometry(panel);
+    _panel_set_panel_configuration_changed(panel);
     UPDATE_GLOBAL_INT(p, "monitor", p->monitor);
 }
 
-static void set_alignment(Panel* p, int align)
+static void set_alignment(LXPanel* panel, int align)
 {
-    if (p->margin_control) 
+    Panel *p = panel->priv;
+
+    if (p->margin_control)
         gtk_widget_set_sensitive(p->margin_control, (align != ALLIGN_CENTER));
     p->allign = align;
-    update_panel_geometry(p);
+    update_panel_geometry(panel);
     UPDATE_GLOBAL_STRING(p, "allign", num2str(allign_pair, align, "none"));
 }
 
-static void align_left_toggle(GtkToggleButton *widget, Panel *p)
+static void align_left_toggle(GtkToggleButton *widget, LXPanel *p)
 {
     if (gtk_toggle_button_get_active(widget))
         set_alignment(p, ALLIGN_LEFT);
 }
 
-static void align_center_toggle(GtkToggleButton *widget, Panel *p)
+static void align_center_toggle(GtkToggleButton *widget, LXPanel *p)
 {
     if (gtk_toggle_button_get_active(widget))
         set_alignment(p, ALLIGN_CENTER);
 }
 
-static void align_right_toggle(GtkToggleButton *widget, Panel *p)
+static void align_right_toggle(GtkToggleButton *widget, LXPanel *p)
 {
     if (gtk_toggle_button_get_active(widget))
         set_alignment(p, ALLIGN_RIGHT);
 }
 
 static void
-set_margin( GtkSpinButton* spin,  Panel* p  )
+set_margin(GtkSpinButton* spin, LXPanel* panel)
 {
+    Panel *p = panel->priv;
+
     p->margin = (int)gtk_spin_button_get_value(spin);
-    update_panel_geometry(p);
+    update_panel_geometry(panel);
     UPDATE_GLOBAL_INT(p, "margin", p->margin);
 }
 
 static void
-set_width(  GtkSpinButton* spin, Panel* p )
+set_width(GtkSpinButton* spin, LXPanel* panel)
 {
+    Panel *p = panel->priv;
+
     p->width = (int)gtk_spin_button_get_value(spin);
-    update_panel_geometry(p);
+    update_panel_geometry(panel);
     UPDATE_GLOBAL_INT(p, "width", p->width);
 }
 
 static void
-set_height( GtkSpinButton* spin, Panel* p )
+set_height(GtkSpinButton* spin, LXPanel* panel)
 {
+    Panel *p = panel->priv;
+
     p->height = (int)gtk_spin_button_get_value(spin);
-    update_panel_geometry(p);
+    update_panel_geometry(panel);
     UPDATE_GLOBAL_INT(p, "height", p->height);
 }
 
-static void set_width_type( GtkWidget *item, Panel* p )
+static void set_width_type( GtkWidget *item, LXPanel* panel )
 {
     GtkWidget* spin;
+    Panel *p = panel->priv;
     int widthtype;
     gboolean t;
+
     widthtype = gtk_combo_box_get_active(GTK_COMBO_BOX(item)) + 1;
+    if (p->widthtype == widthtype) /* not changed */
+        return;
+
     p->widthtype = widthtype;
 
     spin = (GtkWidget*)g_object_get_data(G_OBJECT(item), "width_spin" );
     t = (widthtype != WIDTH_REQUEST);
     gtk_widget_set_sensitive( spin, t );
-    if (widthtype == WIDTH_PERCENT)
+    switch (widthtype)
     {
+    case WIDTH_PERCENT:
         gtk_spin_button_set_range( GTK_SPIN_BUTTON(spin), 0, 100 );
         gtk_spin_button_set_value( GTK_SPIN_BUTTON(spin), 100 );
-    }
-    else if (widthtype == WIDTH_PIXEL)
-    {
+        break;
+    case WIDTH_PIXEL:
         if ((p->edge == EDGE_TOP) || (p->edge == EDGE_BOTTOM))
         {
             gtk_spin_button_set_range( GTK_SPIN_BUTTON(spin), 0, gdk_screen_width() );
@@ -269,25 +277,18 @@ static void set_width_type( GtkWidget *item, Panel* p )
             gtk_spin_button_set_range( GTK_SPIN_BUTTON(spin), 0, gdk_screen_height() );
             gtk_spin_button_set_value( GTK_SPIN_BUTTON(spin), gdk_screen_height() );
         }
-    } else
-        return;
+        break;
+    case WIDTH_REQUEST:
+        break;
+    default: ;
+    }
 
-    update_panel_geometry(p);
+    update_panel_geometry(panel);
     UPDATE_GLOBAL_STRING(p, "widthtype", num2str(width_pair, widthtype, "none"));
 }
 
 /* FIXME: heighttype and spacing and RoundCorners */
 
-static void set_log_level( GtkWidget *cbox, Panel* p)
-{
-    configured_log_level = gtk_combo_box_get_active(GTK_COMBO_BOX(cbox));
-    if (!log_level_set_on_commandline)
-        log_level = configured_log_level;
-    ERR("panel-pref: log level configured to %d, log_level is now %d\n",
-            configured_log_level, log_level);
-    UPDATE_GLOBAL_INT(p, "loglevel", configured_log_level);
-}
-
 static void transparency_toggle( GtkWidget *b, Panel* p)
 {
     GtkWidget* tr = (GtkWidget*)g_object_get_data(G_OBJECT(b), "tint_clr");
@@ -422,35 +423,43 @@ on_use_font_size_toggled( GtkToggleButton* btn,   Panel* p )
 
 
 static void
-set_dock_type(GtkToggleButton* toggle,  Panel* p )
+set_dock_type(GtkToggleButton* toggle, LXPanel* panel)
 {
+    Panel *p = panel->priv;
+
     p->setdocktype = gtk_toggle_button_get_active(toggle) ? 1 : 0;
     panel_set_dock_type( p );
-    update_panel_geometry(p);
+    update_panel_geometry(panel);
     UPDATE_GLOBAL_INT(p, "setdocktype", p->setdocktype);
 }
 
 static void
-set_strut(GtkToggleButton* toggle,  Panel* p )
+set_strut(GtkToggleButton* toggle, LXPanel* panel)
 {
+    Panel *p = panel->priv;
+
     p->setstrut = gtk_toggle_button_get_active(toggle) ? 1 : 0;
-    update_panel_geometry(p);
+    update_panel_geometry(panel);
     UPDATE_GLOBAL_INT(p, "setpartialstrut", p->setstrut);
 }
 
 static void
-set_autohide(GtkToggleButton* toggle,  Panel* p )
+set_autohide(GtkToggleButton* toggle, LXPanel* panel)
 {
+    Panel *p = panel->priv;
+
     p->autohide = gtk_toggle_button_get_active(toggle) ? 1 : 0;
-    update_panel_geometry(p);
+    update_panel_geometry(panel);
     UPDATE_GLOBAL_INT(p, "autohide", p->autohide);
 }
 
 static void
-set_height_when_minimized( GtkSpinButton* spin,  Panel* p  )
+set_height_when_minimized(GtkSpinButton* spin, LXPanel* panel)
 {
+    Panel *p = panel->priv;
+
     p->height_when_hidden = (int)gtk_spin_button_get_value(spin);
-    update_panel_geometry(p);
+    update_panel_geometry(panel);
     UPDATE_GLOBAL_INT(p, "heightwhenhidden", p->height_when_hidden);
 }
 
@@ -473,7 +482,7 @@ on_sel_plugin_changed( GtkTreeSelection* tree_sel, GtkWidget* label )
     {
         GtkTreeView* view = gtk_tree_selection_get_tree_view( tree_sel );
         GtkWidget *edit_btn = GTK_WIDGET(g_object_get_data( G_OBJECT(view), "edit_btn" ));
-        LXPanelPluginInit *init;
+        const LXPanelPluginInit *init;
         gtk_tree_model_get( model, &it, COL_DATA, &pl, -1 );
         init = PLUGIN_CLASS(pl);
         gtk_label_set_text( GTK_LABEL(label), _(init->description) );
@@ -494,8 +503,8 @@ on_plugin_expand_toggled(GtkCellRendererToggle* render, char* path, GtkTreeView*
         gboolean old_expand, expand, fill;
         guint padding;
         GtkPackType pack_type;
-        LXPanelPluginInit *init;
-        Panel *panel;
+        const LXPanelPluginInit *init;
+        LXPanel *panel;
 
         gtk_tree_model_get( model, &it, COL_DATA, &pl, COL_EXPAND, &expand, -1 );
         init = PLUGIN_CLASS(pl);
@@ -504,14 +513,15 @@ on_plugin_expand_toggled(GtkCellRendererToggle* render, char* path, GtkTreeView*
         if (init->expand_available)
         {
             config_setting_t *s = g_object_get_qdata(G_OBJECT(pl), lxpanel_plugin_qconf);
+            GtkBox *box = GTK_BOX(panel->priv->box);
             /* Only honor "stretch" if allowed by the plugin. */
             expand = ! expand;
             gtk_list_store_set( GTK_LIST_STORE(model), &it, COL_EXPAND, expand, -1 );
 
             /* Query the old packing of the plugin widget.
              * Apply the new packing with only "expand" modified. */
-            gtk_box_query_child_packing( GTK_BOX(panel->box), pl, &old_expand, &fill, &padding, &pack_type );
-            gtk_box_set_child_packing( GTK_BOX(panel->box), pl, expand, fill, padding, pack_type );
+            gtk_box_query_child_packing( box, pl, &old_expand, &fill, &padding, &pack_type );
+            gtk_box_set_child_packing( box, pl, expand, fill, padding, pack_type );
             if (expand)
                 config_group_set_int(s, "expand", 1);
             else
@@ -532,7 +542,7 @@ static void on_stretch_render(GtkTreeViewColumn * column, GtkCellRenderer * rend
         NULL);
 }
 
-static void init_plugin_list( Panel* p, GtkTreeView* view, GtkWidget* label )
+static void init_plugin_list( LXPanel* p, GtkTreeView* view, GtkWidget* label )
 {
     GtkListStore* list;
     GtkTreeViewColumn* col;
@@ -561,13 +571,13 @@ static void init_plugin_list( Panel* p, GtkTreeView* view, GtkWidget* label )
     gtk_tree_view_append_column( view, col );
 
     list = gtk_list_store_new( N_COLS, G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_POINTER );
-    plugins = gtk_container_get_children(GTK_CONTAINER(p->box));
+    plugins = p->priv->box ? gtk_container_get_children(GTK_CONTAINER(p->priv->box)) : NULL;
     for( l = plugins; l; l = l->next )
     {
         GtkTreeIter it;
         gboolean expand;
         GtkWidget *w = (GtkWidget*)l->data;
-        gtk_container_child_get(GTK_CONTAINER(p->box), w, "expand", &expand, NULL);
+        gtk_container_child_get(GTK_CONTAINER(p->priv->box), w, "expand", &expand, NULL);
         gtk_list_store_append( list, &it );
         gtk_list_store_set( list, &it,
                             COL_NAME, _(PLUGIN_CLASS(w)->name),
@@ -587,14 +597,14 @@ static void init_plugin_list( Panel* p, GtkTreeView* view, GtkWidget* label )
         gtk_tree_selection_select_iter( tree_sel, &it );
 }
 
-static void on_add_plugin_row_activated( GtkTreeView *tree_view, 
-                                         GtkTreePath *path, 
-                                         GtkTreeViewColumn *col, 
-                                         gpointer user_data) 
+static void on_add_plugin_row_activated( GtkTreeView *tree_view,
+                                         GtkTreePath *path,
+                                         GtkTreeViewColumn *col,
+                                         gpointer user_data)
 {
     GtkWidget *dlg;
 
-    dlg = (GtkWidget *) user_data; 
+    dlg = (GtkWidget *) user_data;
 
     (void) tree_view;
     (void) path;
@@ -608,7 +618,7 @@ static void on_add_plugin_response( GtkDialog* dlg,
                                     int response,
                                     GtkTreeView* _view )
 {
-    Panel* p = (Panel*) g_object_get_data( G_OBJECT(_view), "panel" );
+    LXPanel* p = (LXPanel*) g_object_get_data( G_OBJECT(_view), "panel" );
     if( response == GTK_RESPONSE_OK )
     {
         GtkTreeView* view;
@@ -624,7 +634,7 @@ static void on_add_plugin_response( GtkDialog* dlg,
             GtkWidget *pl;
             config_setting_t *cfg;
 
-            cfg = config_group_add_subgroup(config_root_setting(p->config),
+            cfg = config_group_add_subgroup(config_root_setting(p->priv->config),
                                             "Plugin");
             gtk_tree_model_get( model, &it, 1, &type, -1 );
             config_group_set_string(cfg, "type", type);
@@ -633,10 +643,10 @@ static void on_add_plugin_response( GtkDialog* dlg,
                 GtkTreePath* tree_path;
                 gboolean expand;
 
-                panel_config_save(p);
+                panel_config_save(p->priv);
 
                 plugin_widget_set_background(pl, p);
-                gtk_container_child_get(GTK_CONTAINER(p->box), pl, "expand", &expand, NULL);
+                gtk_container_child_get(GTK_CONTAINER(p->priv->box), pl, "expand", &expand, NULL);
                 model = gtk_tree_view_get_model( _view );
                 gtk_list_store_append( GTK_LIST_STORE(model), &it );
                 gtk_list_store_set( GTK_LIST_STORE(model), &it,
@@ -671,7 +681,7 @@ static void on_add_plugin( GtkButton* btn, GtkTreeView* _view )
     GHashTableIter iter;
     gpointer key, val;
 
-    Panel* p = (Panel*) g_object_get_data( G_OBJECT(_view), "panel" );
+    LXPanel* p = (LXPanel*) g_object_get_data( G_OBJECT(_view), "panel" );
 
     classes = lxpanel_get_all_types();
 
@@ -685,8 +695,8 @@ static void on_add_plugin( GtkButton* btn, GtkTreeView* _view )
     panel_apply_icon(GTK_WINDOW(dlg));
 
     /* fix background */
-    if (p->background)
-        gtk_widget_set_style(dlg, p->defstyle);
+    if (p->priv->background)
+        gtk_widget_set_style(dlg, p->priv->defstyle);
 
     /* gtk_widget_set_sensitive( parent_win, FALSE ); */
     scroll = gtk_scrolled_window_new( NULL, NULL );
@@ -695,8 +705,8 @@ static void on_add_plugin( GtkButton* btn, GtkTreeView* _view )
     gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll),
                                    GTK_POLICY_AUTOMATIC,
                                    GTK_POLICY_AUTOMATIC );
-    gtk_box_pack_start( GTK_BOX(GTK_DIALOG(dlg)->vbox), scroll,
-                         TRUE, TRUE, 4 );
+    gtk_box_pack_start( GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dlg))),
+                        scroll, TRUE, TRUE, 4 );
     view = GTK_TREE_VIEW(gtk_tree_view_new());
     gtk_container_add( GTK_CONTAINER(scroll), GTK_WIDGET(view) );
     tree_sel = gtk_tree_view_get_selection( view );
@@ -717,7 +727,7 @@ static void on_add_plugin( GtkButton* btn, GtkTreeView* _view )
     g_hash_table_iter_init(&iter, classes);
     while(g_hash_table_iter_next(&iter, &key, &val))
     {
-        register LXPanelPluginInit *init = val;
+        register const LXPanelPluginInit *init = val;
         if (init->superseded)
             continue;
         if (!init->one_per_system || !_class_is_present(init))
@@ -736,7 +746,7 @@ static void on_add_plugin( GtkButton* btn, GtkTreeView* _view )
     gtk_tree_view_set_model( view, GTK_TREE_MODEL(list) );
     g_object_unref( list );
 
-    /* 
+    /*
      * The user can add a plugin either by clicking the "Add" button, or by
      * double-clicking the plugin.
      */
@@ -759,7 +769,7 @@ static void on_remove_plugin( GtkButton* btn, GtkTreeView* view )
     GtkTreeSelection* tree_sel = gtk_tree_view_get_selection( view );
     GtkWidget* pl;
 
-    Panel* p = (Panel*) g_object_get_data( G_OBJECT(view), "panel" );
+    LXPanel* p = (LXPanel*) g_object_get_data( G_OBJECT(view), "panel" );
 
     if( gtk_tree_selection_get_selected( tree_sel, &model, &it ) )
     {
@@ -775,17 +785,17 @@ static void on_remove_plugin( GtkButton* btn, GtkTreeView* view )
         /* reset conf pointer because the widget still may be referenced by configurator */
         g_object_set_qdata(G_OBJECT(pl), lxpanel_plugin_qconf, NULL);
         gtk_widget_destroy(pl);
-        panel_config_save(p);
+        panel_config_save(p->priv);
     }
 }
 
-void modify_plugin( GtkTreeView* view )
+static void modify_plugin( GtkTreeView* view )
 {
     GtkTreeSelection* tree_sel = gtk_tree_view_get_selection( view );
     GtkTreeModel* model;
     GtkTreeIter it;
     GtkWidget* pl;
-    LXPanelPluginInit *init;
+    const LXPanelPluginInit *init;
 
     if( ! gtk_tree_selection_get_selected( tree_sel, &model, &it ) )
         return;
@@ -795,19 +805,36 @@ void modify_plugin( GtkTreeView* view )
     if (init->config)
     {
         GtkWidget *dlg;
-        Panel *panel = PLUGIN_PANEL(pl);
-        dlg = init->config(panel, pl, GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(view))));
+        LXPanel *panel = PLUGIN_PANEL(pl);
+        dlg = init->config(panel, pl);
         if (dlg)
             _panel_show_config_dialog(panel, pl, dlg);
     }
 }
 
-static int get_widget_index(Panel* p, GtkWidget* pl)
+typedef struct
 {
-    GList *plugins = gtk_container_get_children(GTK_CONTAINER(p->box));
-    int i = g_list_index(plugins, pl);
-    g_list_free(plugins);
-    return i;
+    GtkWidget *pl;
+    int cur;
+    int idx;
+} WidgetIndexData;
+
+static void get_widget_index_cb(GtkWidget *widget, gpointer data)
+{
+    if (((WidgetIndexData *)data)->pl == widget)
+        ((WidgetIndexData *)data)->idx = ((WidgetIndexData *)data)->cur;
+    ((WidgetIndexData *)data)->cur++;
+}
+
+static int get_widget_index(LXPanel* p, GtkWidget* pl)
+{
+    WidgetIndexData data;
+
+    data.pl = pl;
+    data.idx = -1;
+    data.cur = 0;
+    gtk_container_foreach(GTK_CONTAINER(p->priv->box), get_widget_index_cb, &data);
+    return data.idx;
 }
 
 static void on_moveup_plugin(  GtkButton* btn, GtkTreeView* view )
@@ -817,7 +844,7 @@ static void on_moveup_plugin(  GtkButton* btn, GtkTreeView* view )
     GtkTreeSelection* tree_sel = gtk_tree_view_get_selection( view );
     int i;
 
-    Panel* panel = (Panel*) g_object_get_data( G_OBJECT(view), "panel" );
+    LXPanel* panel = (LXPanel*) g_object_get_data( G_OBJECT(view), "panel" );
 
     if( ! gtk_tree_model_get_iter_first( model, &it ) )
         return;
@@ -839,8 +866,8 @@ static void on_moveup_plugin(  GtkButton* btn, GtkTreeView* view )
                 i = 1;
             config_setting_move_elem(s, config_setting_get_parent(s), i);
             /* reorder in panel */
-            gtk_box_reorder_child(GTK_BOX(panel->box), pl, i - 1);
-            panel_config_save(panel);
+            gtk_box_reorder_child(GTK_BOX(panel->priv->box), pl, i - 1);
+            panel_config_save(panel->priv);
             return;
         }
         prev = it;
@@ -856,7 +883,7 @@ static void on_movedown_plugin(  GtkButton* btn, GtkTreeView* view )
     config_setting_t *s;
     int i;
 
-    Panel* panel = (Panel*) g_object_get_data( G_OBJECT(view), "panel" );
+    LXPanel* panel = (LXPanel*) g_object_get_data( G_OBJECT(view), "panel" );
 
     if( ! gtk_tree_selection_get_selected( tree_sel, &model, &it ) )
         return;
@@ -874,8 +901,8 @@ static void on_movedown_plugin(  GtkButton* btn, GtkTreeView* view )
     /* reorder in config, 0 is Global */
     config_setting_move_elem(s, config_setting_get_parent(s), i + 1);
     /* reorder in panel */
-    gtk_box_reorder_child(GTK_BOX(panel->box), pl, i);
-    panel_config_save(panel);
+    gtk_box_reorder_child(GTK_BOX(panel->priv->box), pl, i);
+    panel_config_save(panel->priv);
 }
 
 static void
@@ -923,8 +950,9 @@ static void on_app_chooser_destroy(GtkComboBox *fm, gpointer _unused)
     }
 }
 
-void panel_configure( Panel* p, int sel_page )
+void panel_configure( LXPanel* panel, int sel_page )
 {
+    Panel *p = panel->priv;
     GtkBuilder* builder;
     GtkWidget *w, *w2, *tint_clr;
     FmMimeType *mt;
@@ -947,6 +975,7 @@ void panel_configure( Panel* p, int sel_page )
     }
 
     p->pref_dialog = (GtkWidget*)gtk_builder_get_object( builder, "panel_pref" );
+    gtk_window_set_transient_for(GTK_WINDOW(p->pref_dialog), GTK_WINDOW(panel));
     g_signal_connect(p->pref_dialog, "response", G_CALLBACK(response_event), p);
     g_object_add_weak_pointer( G_OBJECT(p->pref_dialog), (gpointer) &p->pref_dialog );
     gtk_window_set_position( GTK_WINDOW(p->pref_dialog), GTK_WIN_POS_CENTER );
@@ -955,16 +984,16 @@ void panel_configure( Panel* p, int sel_page )
     /* position */
     w = (GtkWidget*)gtk_builder_get_object( builder, "edge_bottom" );
     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w), edge_selector(p, EDGE_BOTTOM));
-    g_signal_connect(w, "toggled", G_CALLBACK(edge_bottom_toggle), p);
+    g_signal_connect(w, "toggled", G_CALLBACK(edge_bottom_toggle), panel);
     w = (GtkWidget*)gtk_builder_get_object( builder, "edge_top" );
     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w), edge_selector(p, EDGE_TOP));
-    g_signal_connect(w, "toggled", G_CALLBACK(edge_top_toggle), p);
+    g_signal_connect(w, "toggled", G_CALLBACK(edge_top_toggle), panel);
     w = (GtkWidget*)gtk_builder_get_object( builder, "edge_left" );
     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w), edge_selector(p, EDGE_LEFT));
-    g_signal_connect(w, "toggled", G_CALLBACK(edge_left_toggle), p);
+    g_signal_connect(w, "toggled", G_CALLBACK(edge_left_toggle), panel);
     w = (GtkWidget*)gtk_builder_get_object( builder, "edge_right" );
     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w), edge_selector(p, EDGE_RIGHT));
-    g_signal_connect(w, "toggled", G_CALLBACK(edge_right_toggle), p);
+    g_signal_connect(w, "toggled", G_CALLBACK(edge_right_toggle), panel);
 
     /* monitor */
     monitors = 1;
@@ -972,28 +1001,28 @@ void panel_configure( Panel* p, int sel_page )
     if(screen) monitors = gdk_screen_get_n_monitors(screen);
     g_assert(monitors >= 1);
     w = (GtkWidget*)gtk_builder_get_object( builder, "monitor" );
-    gtk_spin_button_set_value(GTK_SPIN_BUTTON(w), p->monitor + 1);
     gtk_spin_button_set_range(GTK_SPIN_BUTTON(w), 1, monitors);
+    gtk_spin_button_set_value(GTK_SPIN_BUTTON(w), p->monitor + 1);
     gtk_widget_set_sensitive(w, monitors > 1);
-    g_signal_connect(w, "value-changed", G_CALLBACK(set_monitor), p);
+    g_signal_connect(w, "value-changed", G_CALLBACK(set_monitor), panel);
 
     /* alignment */
     p->alignment_left_label = w = (GtkWidget*)gtk_builder_get_object( builder, "alignment_left" );
     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w), (p->allign == ALLIGN_LEFT));
-    g_signal_connect(w, "toggled", G_CALLBACK(align_left_toggle), p);
+    g_signal_connect(w, "toggled", G_CALLBACK(align_left_toggle), panel);
     w = (GtkWidget*)gtk_builder_get_object( builder, "alignment_center" );
     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w), (p->allign == ALLIGN_CENTER));
-    g_signal_connect(w, "toggled", G_CALLBACK(align_center_toggle), p);
+    g_signal_connect(w, "toggled", G_CALLBACK(align_center_toggle), panel);
     p->alignment_right_label = w = (GtkWidget*)gtk_builder_get_object( builder, "alignment_right" );
     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w), (p->allign == ALLIGN_RIGHT));
-    g_signal_connect(w, "toggled", G_CALLBACK(align_right_toggle), p);
+    g_signal_connect(w, "toggled", G_CALLBACK(align_right_toggle), panel);
 
     /* margin */
     p->margin_control = w = (GtkWidget*)gtk_builder_get_object( builder, "margin" );
     gtk_spin_button_set_value(GTK_SPIN_BUTTON(w), p->margin);
     gtk_widget_set_sensitive(p->margin_control, (p->allign != ALLIGN_CENTER));
     g_signal_connect( w, "value-changed",
-                      G_CALLBACK(set_margin), p);
+                      G_CALLBACK(set_margin), panel);
 
     /* size */
     p->width_label = (GtkWidget*)gtk_builder_get_object( builder, "width_label");
@@ -1006,19 +1035,19 @@ void panel_configure( Panel* p, int sel_page )
         upper = (((p->edge == EDGE_TOP) || (p->edge == EDGE_BOTTOM)) ? gdk_screen_width() : gdk_screen_height());
     gtk_spin_button_set_range( GTK_SPIN_BUTTON(w), 0, upper );
     gtk_spin_button_set_value( GTK_SPIN_BUTTON(w), p->width );
-    g_signal_connect( w, "value-changed", G_CALLBACK(set_width), p );
+    g_signal_connect( w, "value-changed", G_CALLBACK(set_width), panel );
 
     w = (GtkWidget*)gtk_builder_get_object( builder, "width_unit" );
     update_opt_menu( w, p->widthtype - 1 );
     g_object_set_data(G_OBJECT(w), "width_spin", p->width_control );
     g_signal_connect( w, "changed",
-                     G_CALLBACK(set_width_type), p);
+                     G_CALLBACK(set_width_type), panel);
 
     p->height_label = (GtkWidget*)gtk_builder_get_object( builder, "height_label");
     p->height_control = w = (GtkWidget*)gtk_builder_get_object( builder, "height" );
     gtk_spin_button_set_range( GTK_SPIN_BUTTON(w), PANEL_HEIGHT_MIN, PANEL_HEIGHT_MAX );
     gtk_spin_button_set_value( GTK_SPIN_BUTTON(w), p->height );
-    g_signal_connect( w, "value-changed", G_CALLBACK(set_height), p );
+    g_signal_connect( w, "value-changed", G_CALLBACK(set_height), panel );
 
     w = (GtkWidget*)gtk_builder_get_object( builder, "height_unit" );
     update_opt_menu( w, HEIGHT_PIXEL - 1);
@@ -1040,7 +1069,7 @@ void panel_configure( Panel* p, int sel_page )
     w = (GtkWidget*)gtk_builder_get_object( builder, "as_dock" );
     update_toggle_button( w, p->setdocktype );
     g_signal_connect( w, "toggled",
-                      G_CALLBACK(set_dock_type), p );
+                      G_CALLBACK(set_dock_type), panel );
 
     /* Explaination from Ruediger Arp <ruediger@gmx.net>:
         "Set Strut": Reserve panel's space so that it will not be
@@ -1054,17 +1083,17 @@ void panel_configure( Panel* p, int sel_page )
     w = (GtkWidget*)gtk_builder_get_object( builder, "reserve_space" );
     update_toggle_button( w, p->setstrut );
     g_signal_connect( w, "toggled",
-                      G_CALLBACK(set_strut), p );
+                      G_CALLBACK(set_strut), panel );
 
     w = (GtkWidget*)gtk_builder_get_object( builder, "autohide" );
     update_toggle_button( w, p->autohide );
     g_signal_connect( w, "toggled",
-                      G_CALLBACK(set_autohide), p );
+                      G_CALLBACK(set_autohide), panel );
 
     w = (GtkWidget*)gtk_builder_get_object( builder, "height_when_minimized" );
     gtk_spin_button_set_value(GTK_SPIN_BUTTON(w), p->height_when_hidden);
     g_signal_connect( w, "value-changed",
-                      G_CALLBACK(set_height_when_minimized), p);
+                      G_CALLBACK(set_height_when_minimized), panel);
 
     /* transparancy */
     tint_clr = w = (GtkWidget*)gtk_builder_get_object( builder, "tint_clr" );
@@ -1156,7 +1185,7 @@ void panel_configure( Panel* p, int sel_page )
         g_signal_connect( w, "clicked", G_CALLBACK(on_movedown_plugin), plugin_list );
 
         w = (GtkWidget*)gtk_builder_get_object( builder, "plugin_desc" );
-        init_plugin_list( p, GTK_TREE_VIEW(plugin_list), w );
+        init_plugin_list( panel, GTK_TREE_VIEW(plugin_list), w );
     }
     /* advanced, applications */
     mt = fm_mime_type_from_name("inode/directory");
@@ -1187,11 +1216,6 @@ void panel_configure( Panel* p, int sel_page )
                         &logout_cmd);
     }
 
-    w = (GtkWidget*)gtk_builder_get_object( builder, "log_level" );
-    update_opt_menu(w, configured_log_level);
-    g_signal_connect(w, "changed", G_CALLBACK(set_log_level), p);
-
-
     panel_adjust_geometry_terminology(p);
     gtk_widget_show(GTK_WIDGET(p->pref_dialog));
     w = (GtkWidget*)gtk_builder_get_object( builder, "notebook" );
@@ -1202,20 +1226,15 @@ void panel_configure( Panel* p, int sel_page )
 
 void panel_config_save( Panel* p )
 {
-    gchar *fname, *dir;
-
-    dir = get_config_file( cprofile, "panels", FALSE );
-    fname = g_build_filename( dir, p->name, NULL );
+    gchar *fname;
 
-    /* ensure the 'panels' dir exists */
-    if( ! g_file_test( dir, G_FILE_TEST_EXISTS ) )
-        g_mkdir_with_parents( dir, 0755 );
-    g_free( dir );
+    fname = _user_config_file_name("panels", p->name);
+    /* existance of 'panels' dir ensured in main() */
 
     if (!config_write_file(p->config, fname)) {
-        ERR("can't open for write %s:", fname);
+        g_warning("can't open for write %s:", fname);
         g_free( fname );
-        RET();
+        return;
     }
     g_free( fname );
 
@@ -1224,6 +1243,11 @@ void panel_config_save( Panel* p )
     p->config_changed = 0;
 }
 
+void lxpanel_config_save(LXPanel *p)
+{
+    panel_config_save(p->priv);
+}
+
 void restart(void)
 {
     /* This is defined in panel.c */
@@ -1311,7 +1335,7 @@ static void on_browse_btn_clicked(GtkButton* btn, GtkEntry* entry)
 {
     char* file;
     GtkFileChooserAction action = (GtkFileChooserAction) g_object_get_data(G_OBJECT(btn), "chooser-action");
-    GtkWidget* dlg = GTK_WIDGET(g_object_get_data(G_OBJECT(btn), "dlg"));    
+    GtkWidget* dlg = GTK_WIDGET(g_object_get_data(G_OBJECT(btn), "dlg"));
     GtkWidget* fc = gtk_file_chooser_dialog_new(
                                         (action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER) ? _("Select a directory") : _("Select a file"),
                                         GTK_WINDOW(dlg),
@@ -1327,7 +1351,7 @@ static void on_browse_btn_clicked(GtkButton* btn, GtkEntry* entry)
     {
         file = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(fc));
         gtk_entry_set_text(entry, file);
-        on_entry_focus_out_old(GTK_WIDGET(entry), NULL, g_object_get_data(G_OBJECT(dlg), "file-val"));
+        on_entry_focus_out_old(GTK_WIDGET(entry), NULL, g_object_get_data(G_OBJECT(btn), "file-val"));
         g_free(file);
     }
     gtk_widget_destroy(fc);
@@ -1351,19 +1375,28 @@ static void generic_config_dlg_response(GtkWidget * dlg, int response, Panel * p
     panel_config_save(panel);
 }
 
-void _panel_show_config_dialog(Panel *panel, GtkWidget *p, GtkWidget *dlg)
+void _panel_show_config_dialog(LXPanel *panel, GtkWidget *p, GtkWidget *dlg)
 {
+    gint x, y;
+
     /* If there is already a plugin configuration dialog open, close it.
      * Then record this one in case the panel or plugin is deleted. */
-    if (panel->plugin_pref_dialog != NULL)
-        gtk_dialog_response(GTK_DIALOG(panel->plugin_pref_dialog), GTK_RESPONSE_CLOSE);
-    panel->plugin_pref_dialog = dlg;
+    if (panel->priv->plugin_pref_dialog != NULL)
+        gtk_dialog_response(GTK_DIALOG(panel->priv->plugin_pref_dialog), GTK_RESPONSE_CLOSE);
+    panel->priv->plugin_pref_dialog = dlg;
 
     /* add some handlers to destroy the dialog on responce or widget destroy */
-    g_signal_connect(dlg, "response", G_CALLBACK(generic_config_dlg_response), panel);
+    g_signal_connect(dlg, "response", G_CALLBACK(generic_config_dlg_response), panel->priv);
     g_signal_connect(p, "destroy", G_CALLBACK(on_plugin_destroy), dlg);
     g_object_set_data(G_OBJECT(dlg), "generic-config-plugin", p);
 
+    /* adjust config dialog window position to be near plugin */
+    gtk_window_set_transient_for(GTK_WINDOW(dlg), GTK_WINDOW(panel));
+//    gtk_window_iconify(GTK_WINDOW(dlg));
+    gtk_widget_show(dlg);
+    lxpanel_plugin_popup_set_position_helper(panel, p, dlg, &x, &y);
+    gdk_window_move(gtk_widget_get_window(dlg), x, y);
+
     gtk_window_present(GTK_WINDOW(dlg));
 }
 
@@ -1377,13 +1410,15 @@ static GtkWidget *_lxpanel_generic_config_dlg(const char *title, Panel *p,
                                                   GTK_STOCK_CLOSE,
                                                   GTK_RESPONSE_CLOSE,
                                                   NULL );
+    GtkBox *dlg_vbox = GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dlg)));
+
     panel_apply_icon(GTK_WINDOW(dlg));
 
     if( apply_func )
         g_object_set_data( G_OBJECT(dlg), "apply_func", apply_func );
     g_object_set_data( G_OBJECT(dlg), "apply_func_data", plugin );
 
-    gtk_box_set_spacing( GTK_BOX(GTK_DIALOG(dlg)->vbox), 4 );
+    gtk_box_set_spacing( dlg_vbox, 4 );
 
     while( name )
     {
@@ -1438,18 +1473,18 @@ static GtkWidget *_lxpanel_generic_config_dlg(const char *title, Panel *p,
         if( entry )
         {
             if(( type == CONF_TYPE_BOOL ) || ( type == CONF_TYPE_TRIM ))
-                gtk_box_pack_start( GTK_BOX(GTK_DIALOG(dlg)->vbox), entry, FALSE, FALSE, 2 );
+                gtk_box_pack_start( dlg_vbox, entry, FALSE, FALSE, 2 );
             else
             {
                 GtkWidget* hbox = gtk_hbox_new( FALSE, 2 );
                 gtk_box_pack_start( GTK_BOX(hbox), label, FALSE, FALSE, 2 );
                 gtk_box_pack_start( GTK_BOX(hbox), entry, TRUE, TRUE, 2 );
-                gtk_box_pack_start( GTK_BOX(GTK_DIALOG(dlg)->vbox), hbox, FALSE, FALSE, 2 );
+                gtk_box_pack_start( dlg_vbox, hbox, FALSE, FALSE, 2 );
                 if ((type == CONF_TYPE_FILE_ENTRY) || (type == CONF_TYPE_DIRECTORY_ENTRY))
                 {
                     GtkWidget* browse = gtk_button_new_with_mnemonic(_("_Browse"));
                     gtk_box_pack_start( GTK_BOX(hbox), browse, TRUE, TRUE, 2 );
-                    g_object_set_data(G_OBJECT(dlg), "file-val", val);
+                    g_object_set_data(G_OBJECT(browse), "file-val", val);
                     g_object_set_data(G_OBJECT(browse), "dlg", dlg);
 
                     GtkFileChooserAction action = GTK_FILE_CHOOSER_ACTION_OPEN;
@@ -1468,13 +1503,13 @@ static GtkWidget *_lxpanel_generic_config_dlg(const char *title, Panel *p,
 
     gtk_container_set_border_width( GTK_CONTAINER(dlg), 8 );
 
-    gtk_widget_show_all( dlg );
+    gtk_widget_show_all(GTK_WIDGET(dlg_vbox));
 
     return dlg;
 }
 
 /* new plugins API -- apply_func() gets GtkWidget* */
-GtkWidget *lxpanel_generic_config_dlg(const char *title, Panel *panel,
+GtkWidget *lxpanel_generic_config_dlg(const char *title, LXPanel *panel,
                                       GSourceFunc apply_func, GtkWidget *plugin,
                                       const char *name, ...)
 {
@@ -1484,7 +1519,7 @@ GtkWidget *lxpanel_generic_config_dlg(const char *title, Panel *panel,
     if (plugin == NULL)
         return NULL;
     va_start(args, name);
-    dlg = _lxpanel_generic_config_dlg(title, panel, apply_func, plugin, name, args);
+    dlg = _lxpanel_generic_config_dlg(title, panel->priv, apply_func, plugin, name, args);
     va_end(args);
     return dlg;
 }
@@ -1502,55 +1537,58 @@ GtkWidget* create_generic_config_dlg( const char* title, GtkWidget* parent,
     va_start(args, name);
     dlg = _lxpanel_generic_config_dlg(title, plugin->panel, apply_func, plugin, name, args);
     va_end(args);
-    _panel_show_config_dialog(plugin->panel, plugin->pwid, dlg);
+    _panel_show_config_dialog(plugin->panel->topgwin, plugin->pwid, dlg);
     return dlg;
 }
 
-char* get_config_file( const char* profile, const char* file_name, gboolean is_global )
-{
-    char* path;
-    if( is_global )
-    {
-        path = g_build_filename( PACKAGE_DATA_DIR, "lxpanel/profile", profile, file_name, NULL );
-    }
-    else
-    {
-        char* dir = g_build_filename( g_get_user_config_dir(), "lxpanel" , profile, NULL);
-        /* make sure the private profile dir exists */
-        /* FIXME: Should we do this everytime this func gets called?
-    *        Maybe simply doing this before saving config files is enough. */
-        g_mkdir_with_parents( dir, 0700 );
-        path = g_build_filename( dir,file_name, NULL);
-        g_free( dir );
-    }
-    return path;
-}
+#define COMMAND_GROUP "Command"
 
-const char command_group[] = "Command";
 void load_global_config()
 {
     GKeyFile* kf = g_key_file_new();
-    char* file = get_config_file( cprofile, "config", FALSE );
-    gboolean loaded = g_key_file_load_from_file( kf, file, 0, NULL );
-    if( ! loaded )
+    char* file = NULL;
+    gboolean loaded = FALSE;
+    const gchar * const * dir = g_get_system_config_dirs();
+
+    /* try to load system config file first */
+    if (dir) while (dir[0] && !loaded)
+    {
+        g_free(file);
+        file = _system_config_file_name(dir[0], "config");
+        if (g_key_file_load_from_file(kf, file, 0, NULL))
+            loaded = TRUE;
+        dir++;
+    }
+    if (!loaded) /* fallback to old config place for backward compatibility */
     {
-        g_free( file );
-        file = get_config_file( cprofile, "config", TRUE ); /* get the system-wide config file */
-        loaded = g_key_file_load_from_file( kf, file, 0, NULL );
+        g_free(file);
+        file = _old_system_config_file_name("config");
+        if (g_key_file_load_from_file(kf, file, 0, NULL))
+            loaded = TRUE;
     }
+    /* now try to load user config file */
+    g_free(file);
+    file = _user_config_file_name("config", NULL);
+    if (g_key_file_load_from_file(kf, file, 0, NULL))
+        loaded = TRUE;
+    g_free(file);
 
     if( loaded )
     {
         char *fm, *tmp;
         GList *apps, *l;
 
-        logout_cmd = g_key_file_get_string( kf, command_group, "Logout", NULL );
+        logout_cmd = g_key_file_get_string( kf, COMMAND_GROUP, "Logout", NULL );
         /* check for terminal setting on upgrade */
         if (fm_config->terminal == NULL)
-            fm_config->terminal = g_key_file_get_string(kf, command_group,
+        {
+            fm_config->terminal = g_key_file_get_string(kf, COMMAND_GROUP,
                                                         "Terminal", NULL);
+            if (fm_config->terminal != NULL) /* setting changed, save it */
+                fm_config_save(fm_config, NULL);
+        }
         /* this is heavy but fortunately it will be ran only once: on upgrade */
-        fm = g_key_file_get_string(kf, command_group, "FileManager", NULL);
+        fm = g_key_file_get_string(kf, COMMAND_GROUP, "FileManager", NULL);
         if (fm)
         {
             tmp = strchr(fm, ' '); /* chop params */
@@ -1576,6 +1614,7 @@ void load_global_config()
                 g_object_unref(l->data);
             g_list_free(apps);
             g_free(tmp);
+            save_global_config();
         }
     }
     g_key_file_free( kf );
@@ -1583,15 +1622,16 @@ void load_global_config()
 
 static void save_global_config()
 {
-    char* file = get_config_file( cprofile, "config", FALSE );
+    char* file = _user_config_file_name("config", NULL);
     FILE* f = fopen( file, "w" );
     if( f )
     {
-        fprintf( f, "[%s]\n", command_group );
+        fprintf( f, "[" COMMAND_GROUP "]\n");
         if( logout_cmd )
             fprintf( f, "Logout=%s\n", logout_cmd );
         fclose( f );
     }
+    g_free(file);
 }
 
 void free_global_config()