Convert to radio buttons in panel configuration dialog
authormartyj19 <martyj19@comcast.net>
Mon, 15 Jun 2009 17:42:24 +0000 (17:42 +0000)
committermartyj19 <martyj19@comcast.net>
Mon, 15 Jun 2009 17:42:24 +0000 (17:42 +0000)
- Allows edges to be grayed out so panels can't draw on top of one another
Update height/width terminology in panel configuration dialog on orientation change
Add configuration dialog to directory menu plugin (FR2221932)
Straighten out label draw in directory menu plugin
Add mechanism to ensure that only one system tray per system can be configured
- Alleviates complaint that system tray does not appear (Bug2048295)
Code cleanup in static plugin registration
Change create new panel to go directly to its configuration dialog
Refactoring in panel creation to separate configuration loading from GUI handling
- Needed for panel creation going directly to configuration dialog
Introduce standard right-click handling function for plugins
Major cleanup of deskno plugin; properly handle font color
Major cleanup of CPU plugin, incorporating Patch2802496

19 files changed:
data/ui/panel-pref.glade
src/configurator.c
src/misc.h
src/panel.c
src/panel.h
src/plugin.c
src/plugin.h
src/plugins/cpu/cpu.c
src/plugins/dclock.c
src/plugins/deskno/deskno.c
src/plugins/dirmenu.c
src/plugins/kbled/kbled.c
src/plugins/netstatus/netstatus.c
src/plugins/separator.c
src/plugins/space.c
src/plugins/thermal/thermal.c
src/plugins/volumealsa/volumealsa.c
src/plugins/wincmd.c
src/systray/tray.c

index 16f6645..785dc77 100644 (file)
@@ -1,88 +1,33 @@
 <?xml version="1.0"?>
 <interface>
-  <requires lib="gtk+" version="2.16"/>
+  <!-- interface-requires gtk+ 2.12 -->
   <!-- interface-naming-policy toplevel-contextual -->
-  <object class="GtkAdjustment" id="adjustment1">
-    <property name="upper">32767</property>
-    <property name="step_increment">1</property>
-  </object>
-  <object class="GtkAdjustment" id="adjustment2">
-    <property name="upper">100</property>
-    <property name="step_increment">1</property>
-  </object>
-  <object class="GtkAdjustment" id="adjustment3">
-    <property name="upper">100</property>
-    <property name="step_increment">1</property>
-  </object>
-  <object class="GtkAdjustment" id="adjustment4">
-    <property name="value">2</property>
-    <property name="lower">2</property>
-    <property name="upper">10</property>
-    <property name="step_increment">1</property>
-  </object>
-  <object class="GtkListStore" id="model1">
-    <columns>
-      <!-- column-name gchararray -->
-      <column type="gchararray"/>
-    </columns>
-    <data>
-      <row>
-        <col id="0" translatable="yes">Left</col>
-      </row>
-      <row>
-        <col id="0" translatable="yes">Center</col>
-      </row>
-      <row>
-        <col id="0" translatable="yes">Right</col>
-      </row>
-    </data>
-  </object>
-  <object class="GtkListStore" id="model2">
+  <object class="GtkListStore" id="liststore1">
     <columns>
-      <!-- column-name gchararray -->
+      <!-- column-name item text -->
       <column type="gchararray"/>
     </columns>
     <data>
       <row>
-        <col id="0" translatable="yes">Left</col>
-      </row>
-      <row>
-        <col id="0" translatable="yes">Right</col>
+        <col id="0" translatable="yes">Dynamic</col>
       </row>
       <row>
-        <col id="0" translatable="yes">Top</col>
+        <col id="0" translatable="yes">Pixels</col>
       </row>
       <row>
-        <col id="0" translatable="yes">Bottom</col>
-      </row>
-    </data>
-  </object>
-  <object class="GtkListStore" id="model3">
-    <columns>
-      <!-- column-name gchararray -->
-      <column type="gchararray"/>
-    </columns>
-    <data>
-      <row>
-        <col id="0" translatable="yes">Pixels</col>
+        <col id="0" translatable="yes">% Percent</col>
       </row>
     </data>
   </object>
-  <object class="GtkListStore" id="model4">
+  <object class="GtkListStore" id="liststore2">
     <columns>
-      <!-- column-name gchararray -->
+      <!-- column-name item text -->
       <column type="gchararray"/>
     </columns>
     <data>
       <row>
-        <col id="0" translatable="yes">Dynamic</col>
-      </row>
-      <row>
         <col id="0" translatable="yes">Pixels</col>
       </row>
-      <row>
-        <col id="0" translatable="yes">% Percent</col>
-      </row>
     </data>
   </object>
   <object class="GtkDialog" id="panel_pref">
                                   </packing>
                                 </child>
                                 <child>
-                                  <object class="GtkComboBox" id="align">
+                                  <object class="GtkSpinButton" id="margin">
                                     <property name="visible">True</property>
-                                    <property name="model">model1</property>
-                                    <child>
-                                      <object class="GtkCellRendererText" id="renderer1"/>
-                                      <attributes>
-                                        <attribute name="text">0</attribute>
-                                      </attributes>
-                                    </child>
+                                    <property name="can_focus">True</property>
+                                    <property name="adjustment">adjustment4</property>
+                                    <property name="climb_rate">1</property>
                                   </object>
                                   <packing>
                                     <property name="left_attach">1</property>
                                     <property name="right_attach">2</property>
-                                    <property name="top_attach">1</property>
-                                    <property name="bottom_attach">2</property>
+                                    <property name="top_attach">2</property>
+                                    <property name="bottom_attach">3</property>
                                     <property name="x_options"></property>
                                     <property name="y_options"></property>
                                   </packing>
                                 </child>
                                 <child>
-                                  <object class="GtkComboBox" id="edge">
+                                  <object class="GtkVBox" id="vbox7">
                                     <property name="visible">True</property>
-                                    <property name="model">model2</property>
+                                    <property name="orientation">vertical</property>
                                     <child>
-                                      <object class="GtkCellRendererText" id="renderer2"/>
-                                      <attributes>
-                                        <attribute name="text">0</attribute>
-                                      </attributes>
+                                      <object class="GtkRadioButton" id="edge_bottom">
+                                        <property name="label" translatable="yes">Bottom</property>
+                                        <property name="visible">True</property>
+                                        <property name="can_focus">True</property>
+                                        <property name="receives_default">False</property>
+                                        <property name="active">True</property>
+                                        <property name="draw_indicator">True</property>
+                                      </object>
+                                      <packing>
+                                        <property name="position">0</property>
+                                      </packing>
+                                    </child>
+                                    <child>
+                                      <object class="GtkRadioButton" id="edge_top">
+                                        <property name="label" translatable="yes">Top  </property>
+                                        <property name="visible">True</property>
+                                        <property name="can_focus">True</property>
+                                        <property name="receives_default">False</property>
+                                        <property name="active">True</property>
+                                        <property name="draw_indicator">True</property>
+                                        <property name="group">edge_bottom</property>
+                                      </object>
+                                      <packing>
+                                        <property name="position">1</property>
+                                      </packing>
+                                    </child>
+                                    <child>
+                                      <object class="GtkRadioButton" id="edge_left">
+                                        <property name="label" translatable="yes">Left</property>
+                                        <property name="visible">True</property>
+                                        <property name="can_focus">True</property>
+                                        <property name="receives_default">False</property>
+                                        <property name="active">True</property>
+                                        <property name="draw_indicator">True</property>
+                                        <property name="group">edge_bottom</property>
+                                      </object>
+                                      <packing>
+                                        <property name="position">2</property>
+                                      </packing>
+                                    </child>
+                                    <child>
+                                      <object class="GtkRadioButton" id="edge_right">
+                                        <property name="label" translatable="yes">Right</property>
+                                        <property name="visible">True</property>
+                                        <property name="can_focus">True</property>
+                                        <property name="receives_default">False</property>
+                                        <property name="active">True</property>
+                                        <property name="draw_indicator">True</property>
+                                        <property name="group">edge_bottom</property>
+                                      </object>
+                                      <packing>
+                                        <property name="position">3</property>
+                                      </packing>
                                     </child>
                                   </object>
                                   <packing>
                                     <property name="left_attach">1</property>
                                     <property name="right_attach">2</property>
-                                    <property name="x_options"></property>
-                                    <property name="y_options"></property>
                                   </packing>
                                 </child>
                                 <child>
-                                  <object class="GtkSpinButton" id="margin">
+                                  <object class="GtkVBox" id="vbox9">
                                     <property name="visible">True</property>
-                                    <property name="can_focus">True</property>
-                                    <property name="adjustment">adjustment1</property>
-                                    <property name="climb_rate">1</property>
+                                    <property name="orientation">vertical</property>
+                                    <child>
+                                      <object class="GtkRadioButton" id="alignment_left">
+                                        <property name="label" translatable="yes">Left </property>
+                                        <property name="visible">True</property>
+                                        <property name="can_focus">True</property>
+                                        <property name="receives_default">False</property>
+                                        <property name="active">True</property>
+                                        <property name="draw_indicator">True</property>
+                                      </object>
+                                      <packing>
+                                        <property name="position">0</property>
+                                      </packing>
+                                    </child>
+                                    <child>
+                                      <object class="GtkRadioButton" id="alignment_center">
+                                        <property name="label" translatable="yes">Center</property>
+                                        <property name="visible">True</property>
+                                        <property name="can_focus">True</property>
+                                        <property name="receives_default">False</property>
+                                        <property name="active">True</property>
+                                        <property name="draw_indicator">True</property>
+                                        <property name="group">alignment_left</property>
+                                      </object>
+                                      <packing>
+                                        <property name="position">1</property>
+                                      </packing>
+                                    </child>
+                                    <child>
+                                      <object class="GtkRadioButton" id="alignment_right">
+                                        <property name="label" translatable="yes">Right</property>
+                                        <property name="visible">True</property>
+                                        <property name="can_focus">True</property>
+                                        <property name="receives_default">False</property>
+                                        <property name="active">True</property>
+                                        <property name="draw_indicator">True</property>
+                                        <property name="group">alignment_left</property>
+                                      </object>
+                                      <packing>
+                                        <property name="position">2</property>
+                                      </packing>
+                                    </child>
                                   </object>
                                   <packing>
                                     <property name="left_attach">1</property>
                                     <property name="right_attach">2</property>
-                                    <property name="top_attach">2</property>
-                                    <property name="bottom_attach">3</property>
-                                    <property name="x_options"></property>
-                                    <property name="y_options"></property>
+                                    <property name="top_attach">1</property>
+                                    <property name="bottom_attach">2</property>
                                   </packing>
                                 </child>
                               </object>
                                 <property name="n_columns">3</property>
                                 <property name="row_spacing">2</property>
                                 <child>
-                                  <object class="GtkLabel" id="label10">
+                                  <object class="GtkLabel" id="width_label">
                                     <property name="visible">True</property>
                                     <property name="xalign">0</property>
                                     <property name="label" translatable="yes">Width:</property>
                                   </packing>
                                 </child>
                                 <child>
-                                  <object class="GtkLabel" id="label11">
+                                  <object class="GtkLabel" id="height_label">
                                     <property name="visible">True</property>
                                     <property name="xalign">0</property>
                                     <property name="label" translatable="yes">Height:</property>
                                 <child>
                                   <object class="GtkComboBox" id="height_unit">
                                     <property name="visible">True</property>
-                                    <property name="model">model3</property>
+                                    <property name="model">liststore2</property>
                                     <child>
-                                      <object class="GtkCellRendererText" id="renderer3"/>
+                                      <object class="GtkCellRendererText" id="cellrenderertext2"/>
                                       <attributes>
                                         <attribute name="text">0</attribute>
                                       </attributes>
                                   <object class="GtkSpinButton" id="width">
                                     <property name="visible">True</property>
                                     <property name="can_focus">True</property>
-                                    <property name="adjustment">adjustment2</property>
+                                    <property name="adjustment">adjustment3</property>
                                     <property name="climb_rate">1</property>
                                   </object>
                                   <packing>
                                   <object class="GtkSpinButton" id="height">
                                     <property name="visible">True</property>
                                     <property name="can_focus">True</property>
-                                    <property name="adjustment">adjustment3</property>
+                                    <property name="adjustment">adjustment2</property>
                                     <property name="climb_rate">1</property>
                                   </object>
                                   <packing>
                                 <child>
                                   <object class="GtkComboBox" id="width_unit">
                                     <property name="visible">True</property>
-                                    <property name="model">model4</property>
+                                    <property name="model">liststore1</property>
                                     <child>
-                                      <object class="GtkCellRendererText" id="renderer4"/>
+                                      <object class="GtkCellRendererText" id="cellrenderertext1"/>
                                       <attributes>
                                         <attribute name="text">0</attribute>
                                       </attributes>
                                         <property name="can_focus">True</property>
                                         <property name="max_length">2</property>
                                         <property name="invisible_char">&#x2022;</property>
-                                        <property name="adjustment">adjustment4</property>
+                                        <property name="adjustment">adjustment1</property>
                                       </object>
                                       <packing>
                                         <property name="position">1</property>
       <action-widget response="-7">close_btn</action-widget>
     </action-widgets>
   </object>
+  <object class="GtkAdjustment" id="adjustment1">
+    <property name="value">2</property>
+    <property name="lower">2</property>
+    <property name="upper">10</property>
+    <property name="step_increment">1</property>
+  </object>
+  <object class="GtkAdjustment" id="adjustment2">
+    <property name="upper">100</property>
+    <property name="step_increment">1</property>
+  </object>
+  <object class="GtkAdjustment" id="adjustment3">
+    <property name="upper">100</property>
+    <property name="step_increment">1</property>
+  </object>
+  <object class="GtkAdjustment" id="adjustment4">
+    <property name="upper">32767</property>
+    <property name="step_increment">1</property>
+  </object>
 </interface>
index 836343c..dd9d5e8 100644 (file)
@@ -149,33 +149,80 @@ update_panel_geometry( Panel* p )
     panel_set_wm_strut( p );
 }
 
-static void
-set_edge( GtkComboBox *widget,  Panel* p )
+static gboolean edge_selector(Panel* p, int edge)
 {
-    int edge;
+    return (p->edge == edge);
+}
 
-    ENTER;
-    edge = gtk_combo_box_get_active(widget) + 1;
+/* If there is a panel on this edge and it is not the panel being configured, set the edge unavailable. */
+gboolean panel_edge_available(Panel* p, int edge)
+{
+    GSList* l;
+    for (l = all_panels; l != NULL; l = l->next)
+        {
+        Panel* pl = (Panel*) l->data;
+        if ((pl != p) && (pl->edge == edge))
+            return FALSE;
+        }
+    return TRUE;
+}
+
+static void set_edge(Panel* p, int edge)
+{
     p->edge = edge;
-    panel_set_orientation( p );
+    panel_set_orientation(p);
     update_panel_geometry(p);
-    panel_update_background( p );
-    RET();
+    panel_update_background(p);
 }
 
-static void
-set_allign( GtkComboBox *widget,  Panel* p )
+static void edge_bottom_toggle(GtkToggleButton *widget, Panel *p)
 {
-    int allign;
-    gboolean t;
+    if (gtk_toggle_button_get_active(widget))
+        set_edge(p, EDGE_BOTTOM);
+}
 
-    ENTER;
-    allign = gtk_combo_box_get_active(widget) + 1;
+static void edge_top_toggle(GtkToggleButton *widget, Panel *p)
+{
+    if (gtk_toggle_button_get_active(widget))
+        set_edge(p, EDGE_TOP);
+}
+
+static void edge_left_toggle(GtkToggleButton *widget, Panel *p)
+{
+    if (gtk_toggle_button_get_active(widget))
+        set_edge(p, EDGE_LEFT);
+}
+
+static void edge_right_toggle(GtkToggleButton *widget, Panel *p)
+{
+    if (gtk_toggle_button_get_active(widget))
+        set_edge(p, EDGE_RIGHT);
+}
+
+static void set_alignment(Panel* p, int align)
+{
     if (p->margin_control) 
-        gtk_widget_set_sensitive(p->margin_control, (allign != ALLIGN_CENTER));
-    p->allign = allign;
+        gtk_widget_set_sensitive(p->margin_control, (align != ALLIGN_CENTER));
+    p->allign = align;
     update_panel_geometry(p);
-    RET();
+}
+
+static void align_left_toggle(GtkToggleButton *widget, Panel *p)
+{
+    if (gtk_toggle_button_get_active(widget))
+        set_alignment(p, ALLIGN_LEFT);
+}
+
+static void align_center_toggle(GtkToggleButton *widget, Panel *p)
+{
+    if (gtk_toggle_button_get_active(widget))
+        set_alignment(p, ALLIGN_CENTER);
+}
+
+static void align_right_toggle(GtkToggleButton *widget, Panel *p)
+{
+    if (gtk_toggle_button_get_active(widget))
+        set_alignment(p, ALLIGN_RIGHT);
 }
 
 static void
@@ -565,10 +612,12 @@ static void on_add_plugin( GtkButton* btn, GtkTreeView* _view )
                                G_TYPE_STRING,
                                G_TYPE_STRING );
 
+    /* Populate list of available plugins.
+     * Omit plugins that can only exist once per system if it is already configured. */
     for( tmp = classes; tmp; tmp = tmp->next ) {
         PluginClass* pc = (PluginClass*)tmp->data;
-        if( ! pc->invisible ) {
-            /* FIXME: should we display invisible plugins? */
+        if (( ! pc->one_per_system ) || ( ! pc->one_per_system_instantiated))
+        {
             GtkTreeIter it;
             gtk_list_store_append( list, &it );
             gtk_list_store_set( list, &it,
@@ -764,6 +813,7 @@ void panel_configure( Panel* p, int sel_page )
 
     if( p->pref_dialog )
     {
+        panel_adjust_geometry_terminology(p);
         gtk_window_present(GTK_WINDOW(p->pref_dialog));
         return;
     }
@@ -782,14 +832,35 @@ void panel_configure( Panel* p, int sel_page )
     panel_apply_icon(GTK_WINDOW(p->pref_dialog));
 
     /* position */
-    w = (GtkWidget*)gtk_builder_get_object( builder, "edge" );
-    update_opt_menu( w, p->edge - 1 );
-    g_signal_connect( w, "changed", G_CALLBACK(set_edge), p);
-
-    w = (GtkWidget*)gtk_builder_get_object( builder, "align" );
-    update_opt_menu( w, p->allign - 1 );
-    g_signal_connect( w, "changed", G_CALLBACK(set_allign), p);
-
+    w = (GtkWidget*)gtk_builder_get_object( builder, "edge_bottom" );
+    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w), edge_selector(p, EDGE_BOTTOM));
+    gtk_widget_set_sensitive(w, panel_edge_available(p, EDGE_BOTTOM));
+    g_signal_connect(w, "toggled", G_CALLBACK(edge_bottom_toggle), p);
+    w = (GtkWidget*)gtk_builder_get_object( builder, "edge_top" );
+    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w), edge_selector(p, EDGE_TOP));
+    gtk_widget_set_sensitive(w, panel_edge_available(p, EDGE_TOP));
+    g_signal_connect(w, "toggled", G_CALLBACK(edge_top_toggle), p);
+    w = (GtkWidget*)gtk_builder_get_object( builder, "edge_left" );
+    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w), edge_selector(p, EDGE_LEFT));
+    gtk_widget_set_sensitive(w, panel_edge_available(p, EDGE_LEFT));
+    g_signal_connect(w, "toggled", G_CALLBACK(edge_left_toggle), p);
+    w = (GtkWidget*)gtk_builder_get_object( builder, "edge_right" );
+    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w), edge_selector(p, EDGE_RIGHT));
+    gtk_widget_set_sensitive(w, panel_edge_available(p, EDGE_RIGHT));
+    g_signal_connect(w, "toggled", G_CALLBACK(edge_right_toggle), p);
+
+    /* alignment */
+    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);
+    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);
+    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_left_toggle), p);
+
+    /* margin */
     p->margin_control = w = (GtkWidget*)gtk_builder_get_object( builder, "margin" );
     gtk_spin_button_set_value( (GtkSpinButton*)w, p->margin );
     gtk_widget_set_sensitive(p->margin_control, (p->allign != ALLIGN_CENTER));
@@ -797,6 +868,7 @@ void panel_configure( Panel* p, int sel_page )
                       G_CALLBACK(set_margin), p);
 
     /* size */
+    p->width_label = (GtkWidget*)gtk_builder_get_object( builder, "width_label");
     width = w = (GtkWidget*)gtk_builder_get_object( builder, "width" );
     gtk_widget_set_sensitive( w, p->widthtype != WIDTH_REQUEST );
     gint upper = 0;
@@ -815,7 +887,8 @@ void panel_configure( Panel* p, int sel_page )
     g_signal_connect( w, "changed",
                      G_CALLBACK(set_width_type), p);
 
-    w = (GtkWidget*)gtk_builder_get_object( builder, "height" );
+    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( (GtkSpinButton*)w, PANEL_HEIGHT_MIN, PANEL_HEIGHT_MAX );
     gtk_spin_button_set_value( (GtkSpinButton*)w, p->height );
     g_signal_connect( w, "value-changed", G_CALLBACK(set_height), p );
@@ -967,6 +1040,7 @@ void panel_configure( Panel* p, int sel_page )
                         &logout_cmd);
     }
 
+    panel_adjust_geometry_terminology(p);
     gtk_widget_show(GTK_WIDGET(p->pref_dialog));
     w = (GtkWidget*)gtk_builder_get_object( builder, "notebook" );
     gtk_notebook_set_current_page( (GtkNotebook*)w, sel_page );
@@ -1136,10 +1210,12 @@ static void on_file_chooser_btn_file_set(GtkFileChooser* btn, char** val)
 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* fc = gtk_file_chooser_dialog_new(_("Select a file"),
+    GtkWidget* fc = gtk_file_chooser_dialog_new(
+                                        (action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER) ? _("Select a directory") : _("Select a file"),
                                         GTK_WINDOW(dlg),
-                                        GTK_FILE_CHOOSER_ACTION_OPEN,
+                                        action,
                                         GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
                                         GTK_STOCK_OK, GTK_RESPONSE_OK,
                                         NULL);
@@ -1197,6 +1273,7 @@ GtkWidget* create_generic_config_dlg( const char* title, GtkWidget* parent,
         {
             case CONF_TYPE_STR:
             case CONF_TYPE_FILE_ENTRY: /* entry with a button to browse for files. */
+            case CONF_TYPE_DIRECTORY_ENTRY: /* entry with a button to browse for directories. */
                 entry = gtk_entry_new();
                 if( *(char**)val )
                     gtk_entry_set_text( GTK_ENTRY(entry), *(char**)val );
@@ -1246,12 +1323,14 @@ GtkWidget* create_generic_config_dlg( const char* title, GtkWidget* parent,
                 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 );
-                if( type == CONF_TYPE_FILE_ENTRY )
+                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), "dlg", dlg);
+                    g_object_set_data(G_OBJECT(browse), "chooser-action",
+                        (gpointer) ((type == CONF_TYPE_DIRECTORY_ENTRY) ? GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER : GTK_FILE_CHOOSER_ACTION_OPEN));
                     g_signal_connect( browse, "clicked", G_CALLBACK(on_browse_btn_clicked), entry );
                 }
             }
@@ -1343,6 +1422,6 @@ lxpanel_get_file_manager()
 extern const char*
 lxpanel_get_terminal()
 {
-    return terminal_cmd ? terminal_cmd : "xterm -e %s";
+    return terminal_cmd ? terminal_cmd : "lxterminal -e %s";
 }
 
index 22fd977..f6a9814 100644 (file)
@@ -34,6 +34,7 @@ enum {
     CONF_TYPE_BOOL,
     CONF_TYPE_FILE,
     CONF_TYPE_FILE_ENTRY,
+    CONF_TYPE_DIRECTORY_ENTRY,
     CONF_TYPE_TRIM
 };
 
index 69a438e..032b0ff 100644 (file)
@@ -54,10 +54,55 @@ GSList* all_panels = NULL;  /* a single-linked list storing all panels */
 gboolean is_restarting = FALSE;
 
 static int panel_start( Panel *p, char **fp );
+static void panel_start_gui(Panel *p);
 void panel_config_save(Panel* panel);   /* defined in configurator.c */
 
 gboolean is_in_lxde = FALSE;
 
+/* Allocate and initialize new Panel structure. */
+static Panel* panel_allocate(void)
+{
+    Panel* p = g_slice_new0(Panel);
+    p->allign = ALLIGN_CENTER;
+    p->edge = EDGE_NONE;
+    p->widthtype = WIDTH_PERCENT;
+    p->width = 100;
+    p->heighttype = HEIGHT_PIXEL;
+    p->height = PANEL_HEIGHT_DEFAULT;
+    p->setdocktype = 1;
+    p->setstrut = 1;
+    p->round_corners = 0;
+    p->autohide = 0;
+    p->visible = TRUE;
+    p->height_when_hidden = 2;
+    p->transparent = 0;
+    p->alpha = 127;
+    p->tintcolor = 0xFFFFFFFF;
+    p->usefontcolor = 0;
+    p->fontcolor = 0x00000000;
+    p->spacing = 0;
+    return p;
+}
+
+/* Normalize panel configuration after load from file or reconfiguration. */
+static void panel_normalize_configuration(Panel* p)
+{
+    panel_set_orientation( p );
+    if (p->width < 0)
+        p->width = 100;
+    if (p->widthtype == WIDTH_PERCENT && p->width > 100)
+        p->width = 100;
+    p->heighttype = HEIGHT_PIXEL;
+    if (p->heighttype == HEIGHT_PIXEL) {
+        if (p->height < PANEL_HEIGHT_MIN)
+            p->height = PANEL_HEIGHT_MIN;
+        else if (p->height > PANEL_HEIGHT_MAX)
+            p->height = PANEL_HEIGHT_MAX;
+    }
+    if (p->background)
+        p->transparent = 0;
+}
+
 /****************************************************
  *         panel's handlers for WM events           *
  ****************************************************/
@@ -151,6 +196,7 @@ gboolean show_system_menu( gpointer system_menu );
 
 /* defined in configurator.c */
 void panel_configure(Panel* p, int sel_page );
+gboolean panel_edge_available(Panel* p, int edge);
 
 /* built-in commands, defined in configurator.c */
 void restart(void);
@@ -441,22 +487,15 @@ panel_popupmenu_configure(GtkWidget *widget, gpointer user_data)
     return TRUE;
 }
 
-static gint
-panel_press_button_event(GtkWidget *widget, GdkEvent *event, gpointer user_data)
+/* Handler for "button_press_event" signal with Panel as parameter. */
+static gboolean panel_button_press_event_with_panel(GtkWidget *widget, GdkEventButton *event, Panel *panel)
 {
-    GdkEventButton *event_button;
-
-    g_return_val_if_fail (event != NULL, FALSE);
-    event_button = (GdkEventButton *)event;
-    if (event_button->button == 3) {
-            GtkMenu *menu;
-            Panel* panel = (Panel*)user_data;
-            /* create menu */
-            menu = lxpanel_get_panel_menu( panel, NULL, FALSE );
-            gtk_menu_popup(menu, NULL, NULL, NULL, NULL, event_button->button, event_button->time);
-            return TRUE;
-    }
-
+    if (event->button == 3)     /* right button */
+    {
+        GtkMenu* popup = (GtkMenu*) lxpanel_get_panel_menu(panel, NULL, FALSE);
+        gtk_menu_popup(popup, NULL, NULL, NULL, NULL, event->button, event->time);
+        return TRUE;
+    }    
     return FALSE;
 }
 
@@ -468,115 +507,6 @@ static void panel_popupmenu_config_plugin( GtkMenuItem* item, Plugin* plugin )
     plugin->panel->config_changed = TRUE;
 }
 
-#if 0
-static void on_add_plugin_response( GtkDialog* dlg,
-                                    int response,
-                                    Panel* p )
-{
-    if( response == GTK_RESPONSE_OK )
-    {
-        GtkTreeView* view;
-        GtkTreeSelection* tree_sel;
-        GtkTreeIter it;
-        GtkTreeModel* model;
-
-        view = (GtkTreeView*)g_object_get_data( G_OBJECT(dlg), "avail-plugins" );
-        tree_sel = gtk_tree_view_get_selection( view );
-        if( gtk_tree_selection_get_selected( tree_sel, &model, &it ) )
-        {
-            char* type = NULL;
-            Plugin* pl;
-            gtk_tree_model_get( model, &it, 1, &type, -1 );
-            if( pl = plugin_load( type ) )
-            {
-                GtkTreePath* tree_path;
-
-                pl->panel = p;
-                plugin_start( pl, NULL );
-                p->plugins = g_list_append(p->plugins, pl);
-                /* FIXME: will show all cause problems? */
-                gtk_widget_show_all( pl->pwid );
-
-                /* update background of the newly added plugin */
-                plugin_widget_set_background( pl->pwid, pl->panel );
-            }
-            g_free( type );
-        }
-    }
-    gtk_widget_destroy( (GtkWidget*)dlg );
-}
-
-void panel_add_plugin( Panel* panel, GtkWindow* parent_win )
-{
-    GtkWidget* dlg, *scroll;
-    GList* classes;
-    GList* tmp;
-    GtkTreeViewColumn* col;
-    GtkCellRenderer* render;
-    GtkTreeView* view;
-    GtkListStore* list;
-    GtkTreeSelection* tree_sel;
-
-    classes = plugin_get_available_classes();
-
-    dlg = gtk_dialog_new_with_buttons( _("Add plugin to panel"),
-                                       GTK_WINDOW(parent_win), 0,
-                                       GTK_STOCK_CANCEL,
-                                       GTK_RESPONSE_CANCEL,
-                                       GTK_STOCK_ADD,
-                                       GTK_RESPONSE_OK, NULL );
-    panel_apply_icon(GTK_WINDOW(dlg));
-
-    /* gtk_widget_set_sensitive( parent_win, FALSE ); */
-    scroll = gtk_scrolled_window_new( NULL, NULL );
-    gtk_scrolled_window_set_shadow_type( (GtkScrolledWindow*)scroll,
-                                          GTK_SHADOW_IN );
-    gtk_scrolled_window_set_policy((GtkScrolledWindow*)scroll,
-                                   GTK_POLICY_AUTOMATIC,
-                                   GTK_POLICY_AUTOMATIC );
-    gtk_box_pack_start( (GtkBox*)GTK_DIALOG(dlg)->vbox, scroll,
-                         TRUE, TRUE, 4 );
-    view = (GtkTreeView*)gtk_tree_view_new();
-    gtk_container_add( (GtkContainer*)scroll, view );
-    tree_sel = gtk_tree_view_get_selection( view );
-    gtk_tree_selection_set_mode( tree_sel, GTK_SELECTION_BROWSE );
-
-    render = gtk_cell_renderer_text_new();
-    col = gtk_tree_view_column_new_with_attributes(
-                                            _("Available plugins"),
-                                            render, "text", 0, NULL );
-    gtk_tree_view_append_column( view, col );
-
-    list = gtk_list_store_new( 2,
-                               G_TYPE_STRING,
-                               G_TYPE_STRING );
-
-    for( tmp = classes; tmp; tmp = tmp->next ) {
-        PluginClass* pc = (PluginClass*)tmp->data;
-        if( ! pc->invisible ) {
-            /* FIXME: should we display invisible plugins? */
-            GtkTreeIter it;
-            gtk_list_store_append( list, &it );
-            gtk_list_store_set( list, &it,
-                                0, _(pc->name),
-                                1, pc->type, -1 );
-            /* g_debug( "%s (%s)", pc->type, _(pc->name) ); */
-        }
-    }
-
-    gtk_tree_view_set_model( view, GTK_TREE_MODEL(list) );
-    g_object_unref( list );
-
-    g_signal_connect( dlg, "response",
-                      on_add_plugin_response, panel );
-    g_object_set_data( dlg, "avail-plugins", view );
-    g_object_weak_ref( dlg, plugin_class_list_free, classes );
-
-    gtk_window_set_default_size( (GtkWindow*)dlg, 320, 400 );
-    gtk_widget_show_all( dlg );
-}
-#endif
-
 static void panel_popupmenu_add_item( GtkMenuItem* item, Panel* panel )
 {
     /* panel_add_plugin( panel, panel->topgwin ); */
@@ -621,70 +551,32 @@ static char* gen_panel_name( int edge )
     return name;
 }
 
+static void try_allocate_edge(Panel* p, int edge)
+{
+    if ((p->edge == EDGE_NONE) && (panel_edge_available(p, edge)))
+        p->edge = edge;
+}
+
 /* FIXME: Potentially we can support multiple panels at the same edge,
  * but currently this cannot be done due to some positioning problems. */
 static void panel_popupmenu_create_panel( GtkMenuItem* item, Panel* panel )
 {
-    int i;
-    GSList* group = NULL;
-    GtkWidget* btns[ 4 ], *box, *frame;
-    const char* edges[]={N_("Left"), N_("Right"), N_("Top"), N_("Bottom")};
-    GtkWidget* dlg = gtk_dialog_new_with_buttons(
-                                        _("Create New Panel"),
-                                        GTK_WINDOW(panel->topgwin),
-                                        GTK_DIALOG_MODAL,
-                                        GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
-                                        GTK_STOCK_OK, GTK_RESPONSE_OK, NULL );
-    panel_apply_icon(GTK_WINDOW(dlg));
-    gtk_container_set_border_width( (GtkContainer*)dlg, 8 );
-    frame = gtk_frame_new( _("Where to put the panel?"));
-    gtk_box_pack_start( (GtkBox*)((GtkDialog*)dlg)->vbox, frame, TRUE, TRUE, 0 );
-    box = gtk_vbox_new( FALSE, 2 );
-    gtk_container_add( (GtkContainer*)frame, box );
-    for( i = 0; i < 4; ++i )
-    {
-        GSList* l;
-        btns[ i ] = gtk_radio_button_new_with_label( group, _(edges[i]) );
-        group = gtk_radio_button_get_group( (GtkRadioButton*)btns[ i ] );
-        gtk_box_pack_start( GTK_BOX(box), btns[ i ], FALSE, TRUE, 2 );
-        for( l = all_panels; l; l = l->next )
-        {
-            Panel* p = (Panel*)l->data;
-            /* If there is already a panel on this edge */
-            if( p->edge == (i + 1) )
-                gtk_widget_set_sensitive( btns[i], FALSE );
-            /* FIXME: multiple panel at the same edge should be supported in the future. */
-        }
-    }
-    gtk_widget_show_all( dlg );
-
-    if( gtk_dialog_run( GTK_DIALOG(dlg) ) == GTK_RESPONSE_OK )
-    {
-        char* pfp;
-        char default_conf[128];
-        for( i = 0; i < 4; ++i )
-        {
-            if( gtk_toggle_button_get_active( (GtkToggleButton*)btns[i] ) )
-                break;
-        }
-        ++i;    /* 0 is EDGE_NONE, all edge values start from 1 */
-        g_snprintf( default_conf, 128,
-                "global{\n"
-                "edge=%s\n"
-                "}\n",
-                num2str( edge_pair, i, "bottom" ) );
-        panel = g_slice_new0( Panel );
-        panel->name = gen_panel_name(i);
-        pfp = default_conf;
-        if ( panel_start( panel, &pfp )) {
-            panel_config_save( panel );
-            all_panels = g_slist_prepend( all_panels, panel );
-        }
-        else {
-            panel_destroy( panel );
-        }
-    }
-    gtk_widget_destroy( dlg );
+    Panel* new_panel = panel_allocate();
+
+    /* Allocate the edge. */
+    try_allocate_edge(new_panel, EDGE_BOTTOM);
+    try_allocate_edge(new_panel, EDGE_TOP);
+    try_allocate_edge(new_panel, EDGE_LEFT);
+    try_allocate_edge(new_panel, EDGE_RIGHT);
+    new_panel->name = gen_panel_name(new_panel->edge);
+
+    panel_configure(new_panel, 0);
+    panel_normalize_configuration(new_panel);
+    panel_start_gui(new_panel);
+    gtk_widget_show_all(new_panel->topgwin);
+
+    panel_config_save(new_panel);
+    all_panels = g_slist_prepend(all_panels, new_panel);
 }
 
 static void panel_popupmenu_delete_panel( GtkMenuItem* item, Panel* panel )
@@ -750,7 +642,7 @@ void panel_apply_icon( GtkWindow *w )
     gtk_window_set_icon_from_file(w, PACKAGE_DATA_DIR "/lxpanel/images/my-computer.png", NULL);
 }
 
-extern GtkMenu* lxpanel_get_panel_menu( Panel* panel, Plugin* plugin, gboolean use_sub_menu )
+GtkMenu* lxpanel_get_panel_menu( Panel* panel, Plugin* plugin, gboolean use_sub_menu )
 {
     GtkWidget  *menu_item, *img;
     GtkMenu *ret,*menu;
@@ -942,6 +834,10 @@ panel_start_gui(Panel *p)
 
     ENTER;
 
+    p->curdesk = get_net_current_desktop();
+    p->desknum = get_net_number_of_desktops();
+    p->workarea = get_xaproperty (GDK_ROOT_WINDOW(), a_NET_WORKAREA, XA_CARDINAL, &p->wa_len);
+
     // main toplevel window
     p->topgwin =  gtk_window_new(GTK_WINDOW_TOPLEVEL);
     p->display = gdk_display_get_default();
@@ -967,7 +863,7 @@ panel_start_gui(Panel *p)
 
     gtk_widget_add_events( p->topgwin, GDK_BUTTON_PRESS_MASK );
     g_signal_connect(G_OBJECT (p->topgwin), "button_press_event",
-          (GCallback) panel_press_button_event, p);
+          (GCallback) panel_button_press_event_with_panel, p);
 
     g_signal_connect (G_OBJECT (p->topgwin), "realize",
           (GCallback) panel_realize, p);
@@ -1027,11 +923,39 @@ panel_start_gui(Panel *p)
     RET();
 }
 
+void panel_adjust_geometry_terminology(Panel *p)
+{
+    if ((p->height_label != NULL) && (p->width_label != NULL))
+    {
+        if ((p->edge == EDGE_TOP) || (p->edge == EDGE_BOTTOM))
+        {
+            gtk_label_set_text(GTK_LABEL(p->height_label), _("Height:"));
+            gtk_label_set_text(GTK_LABEL(p->width_label), _("Width:"));
+        }
+        else
+        {
+            gtk_label_set_text(GTK_LABEL(p->height_label), _("Width:"));
+            gtk_label_set_text(GTK_LABEL(p->width_label), _("Height:"));
+        }
+    }
+}
+
 void panel_set_orientation(Panel *p)
 {
     GList* l;
+
+    int previous_orientation = p->orientation;
     p->orientation = (p->edge == EDGE_TOP || p->edge == EDGE_BOTTOM)
         ? ORIENT_HORIZ : ORIENT_VERT;
+
+    if (previous_orientation != p->orientation)
+    {
+        panel_adjust_geometry_terminology(p);
+        p->height = ((p->orientation == ORIENT_HORIZ) ? PANEL_HEIGHT_DEFAULT : PANEL_WIDTH_DEFAULT);
+        if (p->height_control != NULL)
+            gtk_spin_button_set_value(GTK_SPIN_BUTTON(p->height_control), p->height);
+    }
+
     if (p->orientation == ORIENT_HORIZ) {
         p->my_box_new = gtk_hbox_new;
         p->my_separator_new = gtk_vseparator_new;
@@ -1048,6 +972,7 @@ void panel_set_orientation(Panel *p)
             gtk_container_add( GTK_CONTAINER(p->topgwin), GTK_WIDGET(newbox) );
         }
     }
+
     /* NOTE: This loop won't be executed when panel started since
        plugins are not loaded at that time.
        This is used when the orientation of the panel is changed
@@ -1131,30 +1056,10 @@ panel_parse_global(Panel *p, char **fp)
             }
         }
     }
-    panel_set_orientation( p );
 
-    if (p->width < 0)
-        p->width = 100;
-    if (p->widthtype == WIDTH_PERCENT && p->width > 100)
-        p->width = 100;
-    p->heighttype = HEIGHT_PIXEL;
-    if (p->heighttype == HEIGHT_PIXEL) {
-        if (p->height < PANEL_HEIGHT_MIN)
-            p->height = PANEL_HEIGHT_MIN;
-        else if (p->height > PANEL_HEIGHT_MAX)
-            p->height = PANEL_HEIGHT_MAX;
-    }
-
-    if (p->background)
-        p->transparent = 0;
-
-    p->curdesk = get_net_current_desktop();
-    p->desknum = get_net_number_of_desktops();
-    p->workarea = get_xaproperty (GDK_ROOT_WINDOW(), a_NET_WORKAREA, XA_CARDINAL, &p->wa_len);
-    /* print_wmdata(p); */
+    panel_normalize_configuration(p);
 
-    panel_start_gui(p);
-    RET(1);
+    return 1;
 }
 
 static int
@@ -1248,25 +1153,6 @@ int panel_start( Panel *p, char **fp )
     ENTER;
     s.len = 256;
 
-    p->allign = ALLIGN_CENTER;
-    p->edge = EDGE_BOTTOM;
-    p->widthtype = WIDTH_PERCENT;
-    p->width = 100;
-    p->heighttype = HEIGHT_PIXEL;
-    p->height = PANEL_HEIGHT_DEFAULT;
-    p->setdocktype = 1;
-    p->setstrut = 1;
-    p->round_corners = 0;
-    p->autohide = 0;
-    p->visible = TRUE;
-    p->height_when_hidden = 2;
-    p->transparent = 0;
-    p->alpha = 127;
-    p->tintcolor = 0xFFFFFFFF;
-    p->usefontcolor = 0;
-    p->fontcolor = 0x00000000;
-    p->spacing = 0;
-
     if ((lxpanel_get_line(fp, &s) != LINE_BLOCK_START) || g_ascii_strcasecmp(s.t[0], "Global")) {
         ERR( "lxpanel: config file must start from Global section\n");
         RET(0);
@@ -1274,6 +1160,8 @@ int panel_start( Panel *p, char **fp )
     if (!panel_parse_global(p, fp))
         RET(0);
 
+    panel_start_gui(p);
+
     while (lxpanel_get_line(fp, &s) != LINE_NONE) {
         if ((s.type  != LINE_BLOCK_START) || g_ascii_strcasecmp(s.t[0], "Plugin")) {
             ERR( "lxpanel: expecting Plugin section\n");
@@ -1281,13 +1169,10 @@ int panel_start( Panel *p, char **fp )
         }
         panel_parse_plugin(p, fp);
     }
-    gtk_widget_show_all(p->topgwin);
 
     /* update backgrond of panel and all plugins */
     panel_update_background( p );
-
-    /* print_wmdata(p); */
-    RET(1);
+    return 1;
 }
 
 static void
@@ -1341,7 +1226,7 @@ Panel* panel_new( const char* config_file, const char* config_name )
         g_file_get_contents( config_file, &fp, NULL, NULL );
         if( fp )
         {
-            panel = g_slice_new0( Panel );
+            panel = panel_allocate();
             panel->name = g_strdup( config_name );
             pfp = fp;
 
index 18f3243..07dc920 100644 (file)
@@ -39,9 +39,11 @@ enum {
 };
 enum { POS_NONE, POS_START, POS_END };
 
-#define PANEL_HEIGHT_DEFAULT  26
-#define PANEL_HEIGHT_MAX      200
-#define PANEL_HEIGHT_MIN      16
+#define PANEL_ICON_SIZE               24       /* Default size of panel icons */
+#define PANEL_HEIGHT_DEFAULT          26       /* Default height of horizontal panel */
+#define PANEL_WIDTH_DEFAULT           26       /* Default "height" of vertical panel: not yet finished, will be wide */
+#define PANEL_HEIGHT_MAX              200      /* Maximum height of panel */
+#define PANEL_HEIGHT_MIN              16       /* Minimum height of panel */
 
 /* to check if we are in LXDE */
 extern gboolean is_in_lxde;
@@ -106,6 +108,9 @@ struct _Panel{
 
     GtkWidget* pref_dialog; /* preference dialog */
     GtkWidget* margin_control;         /* Margin control in preference dialog */
+    GtkWidget* height_label;           /* Label of height control */
+    GtkWidget* width_label;            /* Label of width control */
+    GtkWidget* height_control;         /* Height control in preference dialog */
 };
 
 
@@ -200,6 +205,7 @@ extern FbEv *fbev;
 
 void panel_apply_icon(GtkWindow *w);
 void panel_destroy(Panel *p);
+void panel_adjust_geometry_terminology(Panel *p);
 void panel_establish_autohide(Panel *p);
 void panel_set_wm_strut(Panel *p);
 void panel_set_dock_type(Panel *p);
index ea8878c..48b9fcc 100644 (file)
@@ -69,13 +69,12 @@ GTypePlugin* lx_type_plugin_get(const char* plugin_name)
 }
 #endif
 
-/* counter for static (built-in) plugins must be greater then zero
+/* Dynamic parameter for static (built-in) plugins must be FALSE
  * so lxpanel will not try to unload them */
-
-#define REGISTER_PLUGIN_CLASS(pc, dynamic) \
+#define REGISTER_STATIC_PLUGIN_CLASS(pc) \
 do {\
     extern PluginClass pc;\
-    register_plugin_class(&pc, dynamic);\
+    register_plugin_class(&pc, FALSE);\
 } while (0)
 
 
@@ -84,67 +83,52 @@ register_plugin_class(PluginClass *pc, int dynamic)
 {
     pcl = g_list_append(pcl, pc);
     pc->dynamic = dynamic;
-    if (!pc->dynamic)
-        pc->count++;
-    /* reloading netstatus results in segfault due to registering static type in dll.
-     * so keep it always onboard until bug fix */
-    if (!strcmp(pc->type, "netstatus"))
-        pc->count++;
 }
 
 static void
 init_plugin_class_list()
 {
 #ifdef STATIC_SEPARATOR
-    REGISTER_PLUGIN_CLASS(separator_plugin_class, 0);
+    REGISTER_STATIC_PLUGIN_CLASS(separator_plugin_class);
 #endif
 
-/* Remove image plugin since it seems to be useless. */
-/*
-#ifdef STATIC_IMAGE
-    REGISTER_PLUGIN_CLASS(image_plugin_class, 0);
-#endif
-*/
-
 #ifdef STATIC_LAUNCHBAR
-    REGISTER_PLUGIN_CLASS(launchbar_plugin_class, 0);
+    REGISTER_STATIC_PLUGIN_CLASS(launchbar_plugin_class);
 #endif
 
 #ifdef STATIC_DCLOCK
-    REGISTER_PLUGIN_CLASS(dclock_plugin_class, 0);
+    REGISTER_STATIC_PLUGIN_CLASS(dclock_plugin_class);
 #endif
 
 #ifdef STATIC_WINCMD
-    REGISTER_PLUGIN_CLASS(wincmd_plugin_class, 0);
+    REGISTER_STATIC_PLUGIN_CLASS(wincmd_plugin_class);
 #endif
 
 #ifdef STATIC_DIRMENU
-    REGISTER_PLUGIN_CLASS(dirmenu_plugin_class, 0);
+    REGISTER_STATIC_PLUGIN_CLASS(dirmenu_plugin_class);
 #endif
 
 #ifdef STATIC_TASKBAR
-    REGISTER_PLUGIN_CLASS(taskbar_plugin_class, 0);
+    REGISTER_STATIC_PLUGIN_CLASS(taskbar_plugin_class);
 #endif
 
 #ifdef STATIC_PAGER
-    REGISTER_PLUGIN_CLASS(pager_plugin_class, 0);
+    REGISTER_STATIC_PLUGIN_CLASS(pager_plugin_class);
 #endif
 
 #ifdef STATIC_TRAY
-    REGISTER_PLUGIN_CLASS(tray_plugin_class, 0);
+    REGISTER_STATIC_PLUGIN_CLASS(tray_plugin_class);
 #endif
 
 #ifndef DISABLE_MENU
 #ifdef STATIC_MENU
-    REGISTER_PLUGIN_CLASS(menu_plugin_class, 0);
+    REGISTER_STATIC_PLUGIN_CLASS(menu_plugin_class);
 #endif
 #endif
 
 #ifdef STATIC_SPACE
-    REGISTER_PLUGIN_CLASS(space_plugin_class, 0);
+    REGISTER_STATIC_PLUGIN_CLASS(space_plugin_class);
 #endif
-
-    RET();
 }
 
 GList* plugin_find_class( const char* type )
@@ -171,7 +155,7 @@ plugin_load_dynamic( const char* type, const gchar* path )
     m = g_module_open(path, G_MODULE_BIND_LAZY);
     if (!m) {
         /* ERR("error is %s\n", g_module_error()); */
-        RET(NULL);
+        return NULL;
     }
     g_snprintf( class_name, 128, "%s_plugin_class", type );
 
@@ -183,7 +167,7 @@ plugin_load_dynamic( const char* type, const gchar* path )
         RET(NULL);
     }
     pc->gmodule = m;
-    register_plugin_class(pc, 1);
+    register_plugin_class(pc, TRUE);
     return pc;
 }
 
@@ -194,7 +178,6 @@ plugin_load(char *type)
     PluginClass *pc = NULL;
     Plugin *plug = NULL;
 
-    ENTER;
     if (!pcl)
         init_plugin_class_list();
 
@@ -207,10 +190,6 @@ plugin_load(char *type)
     else if ( g_module_supported() ) {
         gchar path[ PATH_MAX ];
         
-#if 0   /* put plugins in config dir is too dirty... */
-        g_snprintf(path, PATH_MAX, "%s/.lxpanel/plugins/%s.so", getenv("HOME"), type);
-        pc = plugin_load_dynamic( type, path );
-#endif
         if( !pc ) {
             g_snprintf(path, PATH_MAX, PACKAGE_LIB_DIR "/lxpanel/plugins/%s.so", type);
             pc = plugin_load_dynamic( type, path );
@@ -220,41 +199,38 @@ plugin_load(char *type)
 
     /* nothing was found */
     if (!pc)
-        RET(NULL);
+        return NULL;
 
     plug = g_new0(Plugin, 1);
     g_return_val_if_fail (plug != NULL, NULL);
     plug->class = pc;
     pc->count++;
-    RET(plug);
+    return plug;
 }
 
 
 void plugin_put(Plugin *this)
 {
     PluginClass *pc = this->class;
-    ENTER;
     plugin_class_unref( pc );
     g_free(this);
-    RET();
 }
 
 int
 plugin_start(Plugin *this, char** fp)
 {
-    ENTER;
 
     DBG("%s\n", this->class->type);
 
     if (!this->class->constructor(this, fp)) {
-//        if (!this->class->invisible)
-//            gtk_widget_destroy(this->pwid);
-        RET(0);
+        return 0;
     }
 
-    if (!this->class->invisible && this->pwid ) {
+    if (this->class->one_per_system)
+        this->class->one_per_system_instantiated = TRUE;
+
+    if (this->pwid ) {
         /* this->pwid is created by the plugin */
-        //this->pwid = gtk_bgbox_new();
         gtk_widget_set_name(this->pwid, this->class->type);
         gtk_box_pack_start(GTK_BOX(this->panel->box), this->pwid, this->expand, TRUE,
               this->padding);
@@ -262,29 +238,27 @@ plugin_start(Plugin *this, char** fp)
 
         gtk_widget_show(this->pwid);
     }
-    RET(1);
+    return 1;
 }
 
 
 void plugin_stop(Plugin *this)
 {
-    ENTER;
-    /* g_debug("%s\n", this->class->type); */
+    if (/*!this->class->invisible &&*/ this->pwid )
+    {
+        gtk_widget_destroy(this->pwid);
+        this->pwid = NULL;
+    }
     this->class->destructor(this);
     this->panel->plug_num--;
-    if (!this->class->invisible && this->pwid )
-        gtk_widget_destroy(this->pwid);
-    /* this->pwid is destroyed in the dtor of plugins */
-    RET();
+    this->class->one_per_system_instantiated = FALSE;
 }
 
 void plugin_class_unref( PluginClass* pc )
 {
     --pc->count;
-    if (pc->count == 0 && pc->dynamic) {
+    if (pc->count == 0 && pc->dynamic && ( ! pc->not_unloadable)) {
         pcl = g_list_remove(pcl, pc);
-        /* pc points now somewhere inside loaded lib, so if g_module_close
-         * will touch it after dlclose (and 2.6 does) it will result in segfault */
         g_module_close(pc->gmodule);
     }
 }
@@ -314,30 +288,6 @@ GList* plugin_get_available_classes()
     }
 
 #ifndef DISABLE_PLUGINS_LOADING
-#if 0   /* Put plugins in config dir is too dirty... */
-    dir_path = g_build_filename( g_get_home_dir(), ".lxpanel/plugins", NULL );
-    if( dir = g_dir_open( dir_path, 0, NULL ) ) {
-        while( file = g_dir_read_name( dir ) ) {
-            GModule *m;
-            char* type;
-            if( ! g_str_has_suffix( file, ".so" ) )
-                  continue;
-            type = g_strndup( file, strlen(file) - 3 );
-            l = plugin_find_class( type );
-            if( l == NULL ) { /* If it has not been loaded */
-                path = g_build_filename( dir_path, file, NULL );
-                if( pc = plugin_load_dynamic( type, path ) ) {
-                    ++pc->count;
-                    classes = g_list_prepend( classes, pc );
-                }
-                g_free( path );
-            }
-            g_free( type );
-        }
-        g_dir_close( dir );
-    }
-    g_free( dir_path );
-#endif
     if( dir = g_dir_open( PACKAGE_LIB_DIR "/lxpanel/plugins", 0, NULL ) ) {
         while( file = g_dir_read_name( dir ) ) {
             GModule *m;
@@ -437,7 +387,19 @@ plugin_widget_set_background( GtkWidget* w, Panel* p )
 
 void plugin_set_background( Plugin* pl, Panel* p )
 {
-    if( G_UNLIKELY( pl->class->invisible || ! pl->pwid ) )
-        return;
-    plugin_widget_set_background( pl->pwid, p );
+    if (pl->pwid != NULL)
+        plugin_widget_set_background( pl->pwid, p );
+}
+
+/* Handler for "button_press_event" signal with Plugin as parameter.
+ * External so can be used from a plugin. */
+gboolean plugin_button_press_event(GtkWidget *widget, GdkEventButton *event, Plugin *plugin)
+{
+    if (event->button == 3)     /* right button */
+    {
+        GtkMenu* popup = (GtkMenu*) lxpanel_get_panel_menu(plugin->panel, plugin, FALSE);
+        gtk_menu_popup(popup, NULL, NULL, NULL, NULL, event->button, event->time);
+        return TRUE;
+    }    
+    return FALSE;
 }
index 26ca8ea..5ca99fd 100644 (file)
@@ -36,6 +36,10 @@ typedef struct {
 
     int dynamic : 1;
     int invisible : 1;
+    int not_unloadable : 1;                    /* Not unloadable due to GModule restriction */
+    int one_per_system : 1;                    /* Special: only one possible per system, such as system tray */
+    int one_per_system_instantiated : 1;       /* True if one instance exists */
+
     /* these fields are pointers to the data within loaded dll */
     char *type;
     char *name;
@@ -77,10 +81,10 @@ void plugin_class_list_free( GList* classes );
 
 void plugin_set_background( Plugin* pl, Panel* p );
 void plugin_widget_set_background( GtkWidget* w, Panel* p );
+gboolean plugin_button_press_event(GtkWidget *widget, GdkEventButton *event, Plugin *plugin);
 
 /* FIXME: optional definitions */
 #define STATIC_SEPARATOR
-/* #define STATIC_IMAGE */
 #define STATIC_LAUNCHBAR
 #define STATIC_DCLOCK
 #define STATIC_WINCMD
index d5c9091..a7ceec9 100644 (file)
@@ -1,4 +1,4 @@
-/*
+/**
  * CPU usage plugin to lxpanel
  *
  * Copyright (c) 2008 LxDE Developers, see the file AUTHORS for details.
@@ -21,7 +21,6 @@
  */
 /*A little bug fixed by Mykola <mykola@2ka.mipt.ru>:) */
 
-
 #include <string.h>
 #include <sys/time.h>
 #include <time.h>
 #include "panel.h"
 #include "misc.h"
 
-#define KILOBYTE 1024
-#define MAX_WGSIZE 100
-
 #define BORDER_SIZE 2
 
 #include "dbg.h"
-typedef unsigned long tick;
+
+typedef unsigned long CPUTick;                 /* Value from /proc/stat */
+typedef float CPUSample;                       /* Saved CPU utilization value as 0.0..1.0 */
 
 struct cpu_stat {
-    tick u, n, s, i;
+    CPUTick u, n, s, i;                                /* User, nice, system, idle */
 };
 
-
+/* Private context for CPU plugin. */
 typedef struct {
-    GdkGC *gc_cpu;
-    GdkColor *ccpu;
-    GtkWidget *da;
-    GtkWidget *evbox;
-    GdkPixmap *pixmap;
-    /* GtkTooltips *tip; */
-
-    int timer;
-    tick *stats_cpu;
-    unsigned int ini_stats;
-    int Wwg;
-    int Hwg;
-    struct cpu_stat cpu_anterior;
-} cpu_t;
-
-
-static int
-cpu_update(cpu_t *c)
+    GdkGC * graphics_context;                  /* Graphics context for drawing area */
+    GdkColor foreground_color;                 /* Foreground color for drawing area */
+    GtkWidget * da;                            /* Drawing area */
+    GdkPixmap * pixmap;                                /* Pixmap to be drawn on drawing area */
+
+    int timer;                                 /* Timer for periodic update */
+    CPUSample * stats_cpu;                     /* Ring buffer of CPU utilization values */
+    unsigned int ring_cursor;                  /* Cursor for ring buffer */
+    int pixmap_width;                          /* Width of drawing area pixmap; also size of ring buffer; does not include border size */
+    int pixmap_height;                         /* Height of drawing area pixmap; does not include border size */
+    struct cpu_stat previous_cpu_stat;         /* Previous value of cpu_stat */
+} CPUPlugin;
+
+static void redraw_pixmap(CPUPlugin * c);
+static gboolean cpu_update(CPUPlugin * c);
+static gboolean configure_event(GtkWidget * widget, GdkEventConfigure * event, CPUPlugin * c);
+static gboolean expose_event(GtkWidget * widget, GdkEventExpose * event, CPUPlugin * c);
+static int cpu_constructor(Plugin * p, char ** fp);
+static void cpu_destructor(Plugin * p);
+
+/* Redraw after timer callback or resize. */
+static void redraw_pixmap(CPUPlugin * c)
 {
-    int cpu_u=0, cpu_s=0, cpu_n=0, cpu_i=100;
+    /* Erase pixmap. */
+    gdk_draw_rectangle(c->pixmap, c->da->style->black_gc, TRUE, 0, 0, c->pixmap_width, c->pixmap_height);
+
+    /* Recompute pixmap. */
     unsigned int i;
-    struct cpu_stat cpu, cpu_r;
-    FILE *stat;
-    float total;
-
-    ENTER;
-    if(!c->pixmap)
-        RET(TRUE);
-
-    /* possible because of autohide */
-    if ( (c->Wwg - BORDER_SIZE) < 0 ) 
-       RET(TRUE);
-       
-    stat = fopen("/proc/stat", "r");
-    if(!stat)
-        RET(TRUE);
-    fscanf(stat, "cpu %lu %lu %lu %lu", &cpu.u, &cpu.n, &cpu.s, &cpu.i);
-    fclose(stat);
-
-    cpu_r.u = cpu.u - c->cpu_anterior.u;
-    cpu_r.n = cpu.n - c->cpu_anterior.n;
-    cpu_r.s = cpu.s - c->cpu_anterior.s;
-    cpu_r.i = cpu.i - c->cpu_anterior.i;
-
-    total = cpu_r.u + cpu_r.n + cpu_r.s + cpu_r.i;
-    cpu_u = cpu_r.u * (c->Hwg-BORDER_SIZE * 2) / total;
-    cpu_s = cpu_r.n * (c->Hwg-BORDER_SIZE * 2) / total;
-    cpu_n = cpu_r.s * (c->Hwg-BORDER_SIZE * 2) / total;
-    cpu_i = cpu_r.i * (c->Hwg-BORDER_SIZE * 2) / total;
-
-    c->cpu_anterior = cpu;
-
-    c->stats_cpu[c->ini_stats++] = cpu_u + cpu_s + cpu_n;
-    c->ini_stats %= c->Wwg;
-
-    gdk_draw_rectangle(c->pixmap, c->da->style->black_gc, TRUE, 0, 0, c->Wwg - BORDER_SIZE * 2, c->Hwg - BORDER_SIZE * 2);
-    
-    for (i = 0; i < (c->Wwg - BORDER_SIZE); i++)
+    unsigned int drawing_cursor = c->ring_cursor;
+    for (i = 0; i < c->pixmap_width; i++)
     {
-        int val = c->stats_cpu[(i + c->ini_stats) % (c->Wwg - BORDER_SIZE * 2) ];
-        if (val)
-            gdk_draw_line(c->pixmap, c->gc_cpu, i, (c->Hwg - BORDER_SIZE * 2), i, (c->Hwg - BORDER_SIZE * 2) - val);
+        /* Draw one bar of the CPU usage graph. */
+        if (c->stats_cpu[drawing_cursor] != 0.0)
+            gdk_draw_line(c->pixmap, c->graphics_context,
+                i, c->pixmap_height,
+                i, c->pixmap_height - c->stats_cpu[drawing_cursor] * c->pixmap_height);
+
+        /* Increment and wrap drawing cursor. */
+        drawing_cursor += 1;
+       if (drawing_cursor >= c->pixmap_width)
+            drawing_cursor = 0;
     }
+
+    /* Redraw pixmap. */
     gtk_widget_queue_draw(c->da);
-    RET(TRUE);
 }
 
-static gint
-configure_event(GtkWidget *widget, GdkEventConfigure *event, cpu_t *c)
+/* Periodic timer callback. */
+static gboolean cpu_update(CPUPlugin * c)
 {
-    ENTER;
-    if (c->pixmap)
-        g_object_unref(c->pixmap);
-
-    tick *t0 = g_new0(typeof(*c->stats_cpu), widget->allocation.width);
-    unsigned int imax = ((c->Wwg > widget->allocation.width) ? widget->allocation.width : c->Wwg);
-
-    c->Wwg = widget->allocation.width;
-    c->Hwg = widget->allocation.height;
-    if (c->stats_cpu)
+    if ((c->stats_cpu != NULL) && (c->pixmap != NULL))
     {
-        memcpy(t0, c->stats_cpu, imax * sizeof(tick));
-        g_free(c->stats_cpu);
+        /* Open statistics file and scan out CPU usage. */
+        struct cpu_stat cpu;
+        FILE * stat = fopen("/proc/stat", "r");
+        if (stat == NULL)
+            return TRUE;
+        int fscanf_result = fscanf(stat, "cpu %lu %lu %lu %lu", &cpu.u, &cpu.n, &cpu.s, &cpu.i);
+        fclose(stat);
+
+        /* Ensure that fscanf succeeded. */
+        if (fscanf_result == 4)
+        {
+            /* Compute delta from previous statistics. */
+            struct cpu_stat cpu_delta;
+            cpu_delta.u = cpu.u - c->previous_cpu_stat.u;
+            cpu_delta.n = cpu.n - c->previous_cpu_stat.n;
+            cpu_delta.s = cpu.s - c->previous_cpu_stat.s;
+            cpu_delta.i = cpu.i - c->previous_cpu_stat.i;
+
+            /* Copy current to previous. */
+            memcpy(&c->previous_cpu_stat, &cpu, sizeof(struct cpu_stat));
+
+            /* Compute user+nice+system as a fraction of total.
+             * Introduce this sample to ring buffer, increment and wrap ring buffer cursor. */
+            float cpu_uns = cpu_delta.u + cpu_delta.n + cpu_delta.s;
+            c->stats_cpu[c->ring_cursor] = cpu_uns / (cpu_uns + cpu_delta.i);
+            c->ring_cursor += 1;
+            if (c->ring_cursor >= c->pixmap_width)
+                c->ring_cursor = 0;
+
+            /* Redraw with the new sample. */
+            redraw_pixmap(c);
+        }
     }
-    c->stats_cpu = t0;
-
-    /* set pixmap size */
-    c->pixmap = gdk_pixmap_new (widget->window,
-          widget->allocation.width-BORDER_SIZE * 2,
-          widget->allocation.height-BORDER_SIZE * 2,
-          -1);
-    gdk_draw_rectangle (c->pixmap,
-          widget->style->black_gc,
-          TRUE,
-          0, 0,
-          widget->allocation.width-BORDER_SIZE * 2,
-          widget->allocation.height-BORDER_SIZE * 2); 
-
-   RET(TRUE);
+    return TRUE;
 }
 
-
-static gint
-expose_event(GtkWidget *widget, GdkEventExpose *event, cpu_t *c)
+/* Handler for configure_event on drawing area. */
+static gboolean configure_event(GtkWidget * widget, GdkEventConfigure * event, CPUPlugin * c)
 {
-    ENTER;
-    gdk_draw_drawable (widget->window,
-          c->da->style->black_gc,
-          c->pixmap,
-          event->area.x, event->area.y,
-          event->area.x+BORDER_SIZE, event->area.y+BORDER_SIZE,
-          event->area.width, event->area.height);
-
-    RET(FALSE);
+    /* Allocate pixmap and statistics buffer without border pixels. */
+    int new_pixmap_width = widget->allocation.width - BORDER_SIZE * 2;
+    int new_pixmap_height = widget->allocation.height - BORDER_SIZE * 2;
+    if ((new_pixmap_width > 0) && (new_pixmap_height > 0))
+    {
+        /* If statistics buffer does not exist or it changed size, reallocate and preserve existing data. */
+        if ((c->stats_cpu == NULL) || (new_pixmap_width != c->pixmap_width))
+        {
+            CPUSample * new_stats_cpu = g_new0(typeof(*c->stats_cpu), new_pixmap_width);
+            if (c->stats_cpu != NULL)
+            {
+                if (new_pixmap_width > c->pixmap_width)
+                {
+                    /* New allocation is larger.
+                     * Introduce new "oldest" samples of zero following the cursor. */
+                    memcpy(&new_stats_cpu[0],
+                        &c->stats_cpu[0], c->ring_cursor * sizeof(CPUSample));
+                    memcpy(&new_stats_cpu[new_pixmap_width - c->pixmap_width + c->ring_cursor],
+                        &c->stats_cpu[c->ring_cursor], (c->pixmap_width - c->ring_cursor) * sizeof(CPUSample));
+                }
+                else if (c->ring_cursor <= new_pixmap_width)
+                {
+                    /* New allocation is smaller, but still larger than the ring buffer cursor.
+                     * Discard the oldest samples following the cursor. */
+                    memcpy(&new_stats_cpu[0],
+                        &c->stats_cpu[0], c->ring_cursor * sizeof(CPUSample));
+                    memcpy(&new_stats_cpu[c->ring_cursor],
+                        &c->stats_cpu[c->pixmap_width - new_pixmap_width + c->ring_cursor], (new_pixmap_width - c->ring_cursor) * sizeof(CPUSample));
+                }
+                else
+                {
+                    /* New allocation is smaller, and also smaller than the ring buffer cursor.
+                     * Discard all oldest samples following the ring buffer cursor and additional samples at the beginning of the buffer. */
+                    memcpy(&new_stats_cpu[0],
+                        &c->stats_cpu[c->ring_cursor - new_pixmap_width], new_pixmap_width * sizeof(CPUSample));
+                    c->ring_cursor = 0;
+                }
+                g_free(c->stats_cpu);
+            }
+            c->stats_cpu = new_stats_cpu;
+        }
+
+        /* Allocate or reallocate pixmap. */
+        c->pixmap_width = new_pixmap_width;
+        c->pixmap_height = new_pixmap_height;
+        if (c->pixmap)
+            g_object_unref(c->pixmap);
+        c->pixmap = gdk_pixmap_new(widget->window, c->pixmap_width, c->pixmap_height, -1);
+
+        /* Redraw pixmap at the new size. */
+        redraw_pixmap(c);
+    }
+    return TRUE;
 }
 
-static gboolean  on_button_press(GtkWidget* w, GdkEventButton* evt, Plugin* plugin)
+/* Handler for expose_event on drawing area. */
+static gboolean expose_event(GtkWidget * widget, GdkEventExpose * event, CPUPlugin * c)
 {
-    if( evt->button == 3 )  /* right button */
+    /* Draw the requested part of the pixmap onto the drawing area.
+     * Translate it in both x and y by the border size. */
+    if (c->pixmap != NULL)
     {
-        GtkMenu* popup = lxpanel_get_panel_menu( plugin->panel, plugin, FALSE );
-        gtk_menu_popup( popup, NULL, NULL, NULL, NULL, evt->button, evt->time );
-        return TRUE;
+        gdk_draw_drawable (widget->window,
+              c->da->style->black_gc,
+              c->pixmap,
+              event->area.x, event->area.y,
+              event->area.x + BORDER_SIZE, event->area.y + BORDER_SIZE,
+              event->area.width, event->area.height);
     }
     return FALSE;
 }
 
-static int
-cpu_constructor(Plugin *p, char **fp)
+/* Plugin constructor. */
+static int cpu_constructor(Plugin * p, char ** fp)
 {
-    cpu_t *c;
-
-    ENTER;
-    c = g_new0(cpu_t, 1);
+    /* Allocate plugin context and set into Plugin private data pointer. */
+    CPUPlugin * c = g_new0(CPUPlugin, 1);
     p->priv = c;
 
+    /* Allocate top level widget and set into Plugin widget pointer. */
     p->pwid = gtk_event_box_new();
-    GTK_WIDGET_SET_FLAGS( p->pwid, GTK_NO_WINDOW );
+    gtk_container_set_border_width(GTK_CONTAINER(p->pwid), 1);
+    GTK_WIDGET_SET_FLAGS(p->pwid, GTK_NO_WINDOW);
 
+    /* Allocate drawing area as a child of top level widget.  Enable button press events. */
     c->da = gtk_drawing_area_new();
-    gtk_widget_set_size_request(c->da, 40, 20);
-    gtk_widget_add_events( c->da, GDK_BUTTON_PRESS_MASK );
-
-    gtk_widget_show(c->da);
-
-    c->gc_cpu = gdk_gc_new(p->panel->topgwin->window);
-
-    c->ccpu = (GdkColor *)malloc(sizeof(GdkColor));
-    gdk_color_parse("green",  c->ccpu);
-    gdk_colormap_alloc_color(gdk_drawable_get_colormap(p->panel->topgwin->window),  c->ccpu, FALSE, TRUE);
-    gdk_gc_set_foreground(c->gc_cpu,  c->ccpu);
-
+    gtk_widget_set_size_request(c->da, 40, PANEL_HEIGHT_DEFAULT);
+    gtk_widget_add_events(c->da, GDK_BUTTON_PRESS_MASK);
     gtk_container_add(GTK_CONTAINER(p->pwid), c->da);
-    gtk_container_set_border_width (GTK_CONTAINER (p->pwid), 1);
 
-    g_signal_connect (G_OBJECT (c->da),"configure_event",
-          G_CALLBACK (configure_event), (gpointer) c);
-    g_signal_connect (G_OBJECT (c->da), "expose_event",
-          G_CALLBACK (expose_event), (gpointer) c);
-    g_signal_connect( c->da, "button-press-event",
-          G_CALLBACK(on_button_press), p );
+    /* Clone a graphics context and set "green" as its foreground color.
+     * We will use this to draw the graph. */
+    c->graphics_context = gdk_gc_new(p->panel->topgwin->window);
+    gdk_color_parse("green",  &c->foreground_color);
+    gdk_colormap_alloc_color(gdk_drawable_get_colormap(p->panel->topgwin->window), &c->foreground_color, FALSE, TRUE);
+    gdk_gc_set_foreground(c->graphics_context, &c->foreground_color);
+
+    /* Connect signals. */
+    g_signal_connect(G_OBJECT(c->da), "configure_event", G_CALLBACK(configure_event), (gpointer) c);
+    g_signal_connect(G_OBJECT(c->da), "expose_event", G_CALLBACK(expose_event), (gpointer) c);
+    g_signal_connect(c->da, "button-press-event", G_CALLBACK(plugin_button_press_event), p);
 
+    /* Show the widget.  Connect a timer to refresh the statistics. */
+    gtk_widget_show(c->da);
     c->timer = g_timeout_add(1500, (GSourceFunc) cpu_update, (gpointer) c);
-    RET(1);
+    return 1;
 }
 
-static void
-cpu_destructor(Plugin *p)
+/* Plugin destructor. */
+static void cpu_destructor(Plugin * p)
 {
-    cpu_t *c = (cpu_t *) p->priv;
+    CPUPlugin * c = (CPUPlugin *) p->priv;
+
+    /* Disconnect the timer. */
+    g_source_remove(c->timer);
 
-    ENTER;
+    /* Deallocate memory. */
+    g_object_unref(c->graphics_context);
     g_object_unref(c->pixmap);
-    g_object_unref(c->gc_cpu);
     g_free(c->stats_cpu);
-    g_free(c->ccpu);
-    g_source_remove(c->timer);
-    /* g_object_unref( c->tip ); */
-    g_free(p->priv);
-    RET();
+    g_free(c);
 }
 
-
+/* Plugin descriptor. */
 PluginClass cpu_plugin_class = {
-    fname: NULL,
-    count: 0,
 
     type : "cpu",
     name : N_("CPU Usage Monitor"),
index eec165a..594afc1 100644 (file)
@@ -85,27 +85,23 @@ static GtkWidget *create_calendar()
 
     gtk_widget_show_all(win);
 
-    RET(win);
+    return win;
 }
 
 static void *
 actionProcess( void *arg )
 {
-    ENTER;
-    RET((void *)system((char *) arg));
+    return ((void *)system((char *) arg));
 }
 
 static  gboolean
 clicked( GtkWidget *widget, GdkEventButton* evt, Plugin* plugin)
 {
     dclock *dc = (dclock*)plugin->priv;
-    ENTER2;
-    if( evt->button == 3 )  /* right button */
-    {
-        GtkMenu* popup = lxpanel_get_panel_menu( plugin->panel, plugin, FALSE );
-        gtk_menu_popup( popup, NULL, NULL, NULL, NULL, evt->button, evt->time );
+
+    /* Standard right-click handling. */
+    if (plugin_button_press_event(widget, evt, plugin))
         return TRUE;
-    }
 
     if( dc->action ) {
         pthread_t actionThread;
@@ -120,7 +116,7 @@ clicked( GtkWidget *widget, GdkEventButton* evt, Plugin* plugin)
             dc->calwin = NULL;
         }
     }
-    RET2(FALSE);
+    return FALSE;
 }
 
 static gint
@@ -132,7 +128,6 @@ clock_update(gpointer data )
     dclock *dc;
     gchar *utf8;
 
-    ENTER;
     g_assert(data != NULL);
     dc = (dclock *)data;
 
@@ -169,7 +164,7 @@ clock_update(gpointer data )
             }
     }
 
-    RET(TRUE);
+    return TRUE;
 }
 
 
@@ -179,7 +174,6 @@ dclock_constructor(Plugin *p, char** fp)
     line s;
     dclock *dc;
 
-    ENTER;
     dc = g_slice_new0(dclock);
     g_return_val_if_fail(dc != NULL, 0);
     p->priv = dc;
@@ -217,11 +211,12 @@ dclock_constructor(Plugin *p, char** fp)
             }
         }
     }
-    dc->main = gtk_event_box_new();
+
+    p->pwid = dc->main = gtk_event_box_new();
 
     g_signal_connect (G_OBJECT (dc->main), "button_press_event",
           G_CALLBACK (clicked), (gpointer) p);
-    dc->clockw = gtk_label_new("");
+    dc->clockw = gtk_label_new(NULL);
     gtk_misc_set_alignment(GTK_MISC(dc->clockw), 0.5, 0.5);
     gtk_misc_set_padding(GTK_MISC(dc->clockw), 4, 0);
     update_label_orient( p );
@@ -232,10 +227,7 @@ dclock_constructor(Plugin *p, char** fp)
 
     clock_update( dc );
 
-    /* store the created Plugin widget in Plugin->pwid */
-    p->pwid = dc->main;
-
-    RET(1);
+    return 1;
 
  error:
     g_free(dc->cfmt);
@@ -243,7 +235,7 @@ dclock_constructor(Plugin *p, char** fp)
     g_free(dc->action);
     g_free(dc->prev_str);
     g_slice_free(dclock, dc);
-    RET(0);
+    return 0;
 }
 
 
@@ -252,20 +244,15 @@ dclock_destructor(Plugin *p)
 {
     dclock *dc = (dclock *)p->priv;
 
-    ENTER;
     if (dc->timer)
         g_source_remove(dc->timer);
 
-    /* g_object_unref( dc->tip ); */
     gtk_widget_destroy(dc->clockw);
 
-    /* p->pwid = dc->main;
-    gtk_widget_destroy(dc->main); */
     g_free(dc->cfmt);
     g_free(dc->tfmt);
     g_free(dc->action);
     g_slice_free(dclock, dc);
-    RET();
 }
 
 static void apply_config( Plugin* p )
@@ -320,8 +307,6 @@ update_label_orient( Plugin* p )
 }
 
 PluginClass dclock_plugin_class = {
-    fname: NULL,
-    count: 0,
 
     type : "dclock",
     name : N_("Digital Clock"),
index a8d105d..7df1aa1 100644 (file)
@@ -1,3 +1,24 @@
+/**
+ * Desktop number plugin to lxpanel
+ *
+ * Copyright (c) 2008 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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
 // reused dclock.c and variables from pager.c
 // 11/23/04 by cmeury
 
 
 #include "dbg.h"
 
+/* Private context for desktop number plugin. */
 typedef struct {
-    GtkWidget *main;
-    GtkWidget *namew;
-    GtkTooltips *tip;
-} deskno;
+    Panel *panel;                      /* Back pointer to Panel */
+    GtkWidget *label;                  /* Label */
+} DesknoPlugin;
+
+static gboolean name_update(GtkWidget * widget, DesknoPlugin * dc);
+static gboolean clicked(GtkWidget * widget, GdkEventButton * event, Plugin * p);
+static int deskno_constructor(Plugin * p, char ** fp);
+static void deskno_destructor(Plugin * p);
 
-static  void
-clicked( GtkWidget *widget, gpointer data)
+/* Handler for current_desktop event from window manager. */
+static gboolean name_update(GtkWidget * widget, DesknoPlugin * dc)
 {
-    int desknum = get_net_current_desktop();
-    int desks = get_net_number_of_desktops();
-    int newdesk;
-
-    ENTER;
-    if(desknum == (desks - 1))
-    newdesk = 0;
-    else
-    newdesk = desknum + 1;
-    g_assert(data != NULL);
-    Xclimsg(GDK_ROOT_WINDOW(), a_NET_CURRENT_DESKTOP, newdesk, 0, 0, 0, 0);
-    RET();
+    /* Compute and redraw the desktop number. */
+    char buffer[128];
+    g_snprintf(buffer, sizeof(buffer), "<span color=\"#%06x\"><b>%d</b></span>",
+        ((dc->panel->usefontcolor) ? gcolor2rgb24(&dc->panel->gfontcolor) : 0), get_net_current_desktop() + 1);
+    gtk_label_set_markup(GTK_LABEL(dc->label), buffer);
+    return TRUE;
 }
 
+/* Handler for button-press-event on top level widget. */
+static gboolean clicked(GtkWidget * widget, GdkEventButton * event, Plugin * p)
+{
+    /* Standard left-click handling. */
+    if (plugin_button_press_event(widget, event, p))
+        return TRUE;
 
+    /* Right-click goes to next desktop, wrapping around to first. */
+    int desknum = get_net_current_desktop();
+    int desks = get_net_number_of_desktops();
+    int newdesk = desknum + 1;
+    if (newdesk >= desks)
+        newdesk = 0;
 
-static gint
-name_update(GtkWidget *widget, deskno *dc)
-{
-    char buffer [15];
-    int n;
-    int desknum = get_net_current_desktop() + 1;
-
-    ENTER;
-    n = sprintf(buffer, "<b>%d</b>", desknum);
-    gtk_label_set_markup (GTK_LABEL(dc->namew), buffer) ;
-    RET(TRUE);
+    /* Ask the window manager to make the new desktop current. */
+    Xclimsg(GDK_ROOT_WINDOW(), a_NET_CURRENT_DESKTOP, newdesk, 0, 0, 0, 0);
+    return TRUE;
 }
 
-
-static int
-deskno_constructor(Plugin *p, char** fp)
+/* Plugin constructor. */
+static int deskno_constructor(Plugin * p, char ** fp)
 {
-    deskno *dc;
-    GtkWidget *button;
-
-    ENTER;
-    dc = g_new0(deskno, 1);
+    /* Allocate plugin context and set into Plugin private data pointer. */
+    DesknoPlugin * dc = g_new0(DesknoPlugin, 1);
     g_return_val_if_fail(dc != NULL, 0);
     p->priv = dc;
+    dc->panel = p->panel;
 
-    dc->main = gtk_event_box_new();
-    dc->tip  = gtk_tooltips_new();
-    button = gtk_button_new();
-    gtk_button_set_relief(GTK_BUTTON(button),GTK_RELIEF_NONE);
-    g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (clicked), (gpointer) dc);
-    dc->namew = gtk_label_new("ww");
-    gtk_container_add(GTK_CONTAINER(button), dc->namew);
-    name_update(button, dc);
-    g_signal_connect (G_OBJECT (fbev), "current_desktop", G_CALLBACK (name_update), (gpointer) dc);
-
-    p->pwid = button;
-    gtk_widget_show_all(p->pwid);
+    /* Allocate top level widget and set into Plugin widget pointer. */
+    p->pwid = gtk_event_box_new();
+    gtk_container_set_border_width(GTK_CONTAINER (p->pwid), 1);
 
-    RET(1);
-}
+    /* Allocate label widget and add to top level. */
+    dc->label = gtk_label_new(NULL);
+    gtk_container_add(GTK_CONTAINER(p->pwid), dc->label);
+
+    /* Connect signals.  Note use of window manager event object. */
+    g_signal_connect(p->pwid, "button_press_event", G_CALLBACK(clicked), p);
+    g_signal_connect(G_OBJECT(fbev), "current_desktop", G_CALLBACK(name_update), (gpointer) dc);
 
+    /* Initialize value and show the widget. */
+    name_update(NULL, dc);
+    gtk_widget_show_all(p->pwid);
+    return 1;
+}
 
-static void
-deskno_destructor(Plugin *p)
+/* Plugin destructor. */
+static void deskno_destructor(Plugin * p)
 {
-  deskno *dc = (deskno *)p->priv;
+    DesknoPlugin * dc = (DesknoPlugin *) p->priv;
 
-  ENTER;
-  dc = (deskno *) p->priv;
-  g_signal_handlers_disconnect_by_func(G_OBJECT (fbev), name_update, dc);
-  g_free(dc);
-  RET();
+    /* Disconnect signal from window manager event object. */
+    g_signal_handlers_disconnect_by_func(G_OBJECT(fbev), name_update, dc);
+    g_free(dc);
 }
 
+/* Plugin descriptor. */
 PluginClass deskno_plugin_class = {
-    fname: NULL,
-    count: 0,
 
     type : "deskno",
     name : N_("Desktop No / Workspace Name"),
index ea5d266..afba97f 100644 (file)
@@ -45,6 +45,7 @@ static GdkPixbuf* folder_icon = NULL;
 static GtkWidget* create_menu( Plugin* p,
                                const char* path,
                                gboolean open_at_top );
+static void dirmenu_apply_config_to_children(GtkWidget *w, dirmenu* dm);
 
 static void open_dir( Plugin* p, const char* path )
 {
@@ -138,14 +139,11 @@ static void on_select( GtkMenuItem* item, Plugin* p )
     }
 }
 
-#if GTK_CHECK_VERSION(2, 10, 0)
-/* NOTE: It seems that this doesn't work in older versions of gtk+?? */
 static void on_deselect( GtkMenuItem* item, Plugin* p )
 {
     /* delete old menu on deselect to save resource */
     gtk_menu_item_set_submenu( item, gtk_menu_new() );
 }
-#endif
 
 void on_sel_done( GtkWidget *menu, Plugin* p )
 {
@@ -200,12 +198,8 @@ static GtkWidget* create_menu( Plugin* p,
                 gtk_menu_shell_append( GTK_MENU_SHELL(menu), item );
                 g_signal_connect( item, "select",
                                   G_CALLBACK(on_select), p );
-#if GTK_CHECK_VERSION(2, 10, 0)
-                /* NOTE: It seems that this doesn't work in older
-                         versions of gtk+?? */
                 g_signal_connect( item, "deselect",
                                   G_CALLBACK(on_deselect), p);
-#endif
             }
             g_free( full );
         }
@@ -255,9 +249,9 @@ clicked (GtkWidget *widget, GdkEventButton *event, Plugin *p)
 {
     dirmenu *dm = (dirmenu *)p->priv;
 
-    ENTER;
-    if (event->type != GDK_BUTTON_PRESS)
-        RET(FALSE);
+    /* Standard left-click handling. */
+    if (plugin_button_press_event(widget, event, p))
+        return TRUE;
 
     if (event->button == 1) {
         show_menu( widget, p, event->button, event->time );
@@ -271,19 +265,17 @@ clicked (GtkWidget *widget, GdkEventButton *event, Plugin *p)
         g_free( path );
     }
 
-    RET(TRUE);
+    return TRUE;
 }
 
 static void
 dirmenu_destructor(Plugin *p)
 {
     dirmenu *dm = (dirmenu *)p->priv;
-    ENTER;
     g_free( dm->image );
     g_free( dm->path );
     g_free( dm->name );
     g_free(dm);
-    RET();
 }
 
 static int
@@ -294,7 +286,6 @@ dirmenu_constructor(Plugin *p, char **fp)
     dirmenu *dm;
     int w, h;
 
-    ENTER;
     s.len = 256;
     dm = g_new0(dirmenu, 1);
     g_return_val_if_fail(dm != NULL, 0);
@@ -341,11 +332,17 @@ dirmenu_constructor(Plugin *p, char **fp)
     if (! fname)
         fname = strdup("file-manager");
 
-    dm->button = fb_button_new_from_file_with_label(fname, w, h, 0x202020, TRUE, (p->panel->orientation == ORIENT_HORIZ ? dm->name : NULL));
-
+    /* Create button.
+     * It is not known why, but the button text will not draw if it is edited from empty to non-empty
+     * unless this strategy of initializing it with a non-empty value first is followed. */
+    p->pwid = dm->button = fb_button_new_from_file_with_colorlabel(fname, w, h,
+        0x202020, ((p->panel->usefontcolor) ? gcolor2rgb24(&p->panel->gfontcolor) : 0), TRUE,
+        "Temp");
+    dirmenu_apply_config_to_children(dm->button, dm);
     gtk_container_set_border_width( GTK_CONTAINER(dm->button), 0 );
     g_signal_connect( dm->button, "button_press_event",
                       G_CALLBACK(clicked), p );
+    gtk_widget_set_size_request( dm->button, -1, PANEL_ICON_SIZE );
 
     gtk_widget_show( dm->button );
     g_free(fname);
@@ -354,17 +351,13 @@ dirmenu_constructor(Plugin *p, char **fp)
     gtk_widget_set_tooltip_text( dm->button,
                                  fname ? fname : g_get_home_dir());
     g_free( fname );
-
-    /* store the created plugin widget in plugin->pwid */
-    p->pwid = dm->button;
-
-    RET(1);
+    return 1;
 
  error:
     g_free(fname);
     dirmenu_destructor(p);
     ERR( "%s - exit\n", __FUNCTION__);
-    RET(0);
+    return 0;
 }
 
 static void save_config( Plugin* p, FILE* fp )
@@ -375,9 +368,46 @@ static void save_config( Plugin* p, FILE* fp )
     lxpanel_put_str( fp, "image", dm->image );
 }
 
+static void dirmenu_apply_config_to_children(GtkWidget *w, dirmenu* dm)
+{
+    if (GTK_IS_CONTAINER(w))
+       gtk_container_foreach(GTK_CONTAINER(w), (GtkCallback) dirmenu_apply_config_to_children, (gpointer) dm);
+    else if (GTK_IS_LABEL(w))
+    {
+        if (dm->name == NULL)
+           gtk_label_set_text(GTK_LABEL(w), NULL);
+        else
+        {
+            gchar str[512];
+            g_snprintf(str, sizeof(str), "<span color=\"#%06x\">%s</span>",
+                ((dm->panel->usefontcolor) ? gcolor2rgb24(&dm->panel->gfontcolor) : 0), dm->name);
+            gtk_label_set_markup(GTK_LABEL(w), str);
+        }
+    }
+}
+
+static void dirmenu_apply_config(Plugin* p)
+{
+    dirmenu* dm = (dirmenu*)p->priv;
+    gtk_widget_set_tooltip_text(dm->button, ((dm->path != NULL) ? expand_tilda(dm->path) : g_get_home_dir()));
+    gtk_container_foreach(GTK_CONTAINER(dm->button), (GtkCallback) dirmenu_apply_config_to_children, (gpointer) dm);
+}
+
+static void dirmenu_configure( Plugin *p, GtkWindow* parent )
+{
+    GtkWidget* dlg;
+    dirmenu* dm = (dirmenu*)p->priv;
+    dlg = create_generic_config_dlg( _(p->class->name),
+                                     GTK_WIDGET(parent),
+                                    (GSourceFunc) dirmenu_apply_config, (gpointer) p,
+                                     _("Directory"), &dm->path, CONF_TYPE_DIRECTORY_ENTRY,
+                                     _("Label"), &dm->name, CONF_TYPE_STR,
+//                                     _("Icon"), &dm->image, CONF_TYPE_FILE_ENTRY,
+                                     NULL );
+    gtk_window_present( GTK_WINDOW(dlg) );
+}
+
 PluginClass dirmenu_plugin_class = {
-    fname: NULL,
-    count: 0,
 
     type : "dirmenu",
     name : N_("Directory Menu"),
@@ -386,6 +416,6 @@ PluginClass dirmenu_plugin_class = {
 
     constructor : dirmenu_constructor,
     destructor  : dirmenu_destructor,
-    config : NULL,
+    config : dirmenu_configure,
     save : save_config
 };
index 538d885..10c036f 100644 (file)
@@ -109,17 +109,6 @@ event_filter(GdkXEvent *gdkxevent, GdkEvent *event, Plugin* p)
     return GDK_FILTER_CONTINUE;
 }
 
-static gboolean on_button_press (GtkWidget* widget, GdkEventButton* evt, Plugin* p)
-{
-    KbLed *kl = (KbLed*)p->priv;
-    if( evt->button == 3 ) { /* Right click*/
-        GtkMenu* popup = (GtkMenu*)lxpanel_get_panel_menu( p->panel, p, FALSE );
-        gtk_menu_popup( popup, NULL, NULL, NULL, NULL, evt->button, evt->time );
-        return TRUE;
-    }
-    return FALSE;
-}
-
 static void kbled_orientation( Plugin* p )
 {
     KbLed* kl = (KbLed*)p->priv;
@@ -212,7 +201,7 @@ static int kbled_constructor(Plugin *p, char **fp)
     p->pwid = gtk_event_box_new();
     gtk_widget_add_events( p->pwid, GDK_BUTTON_PRESS_MASK );
     g_signal_connect( p->pwid, "button-press-event",
-            G_CALLBACK(on_button_press), p );
+            G_CALLBACK(plugin_button_press_event), p );
 
     /* create a box */
     kl->mainw = p->panel->my_box_new( FALSE, 0 );
@@ -278,6 +267,7 @@ static void kbled_config( Plugin *p, GtkWindow* parent )
                                      _("Show NumLock"), &kl->visible[1], CONF_TYPE_BOOL,
                                      _("Show ScrollLock"), &kl->visible[2], CONF_TYPE_BOOL,
                                      NULL );
+    gtk_widget_set_size_request(GTK_WIDGET(dlg), 200, -1);
     gtk_window_present( GTK_WINDOW(dlg) );
 }
 
@@ -286,7 +276,7 @@ PluginClass kbled_plugin_class = {
     count: 0,
 
     type : "kbled",
-    name : N_("Keyboard Led"),
+    name : N_("Keyboard LED"),
     version: "1.0",
     description : N_("Indicators for CapsLock, NumLock, and ScrollLock keys"),
 
index 2c6f0c9..b35be38 100644 (file)
@@ -194,6 +194,9 @@ PluginClass netstatus_plugin_class = {
     version: "1.0",
     description : N_("Monitor network status"),
 
+    /* Reloading netstatus results in segfault due to registering static type. */
+    not_unloadable : TRUE,
+
     constructor : netstatus_constructor,
     destructor  : netstatus_destructor,
     config : netstatus_config,
index c3d7433..2a9309c 100644 (file)
 
 #include "dbg.h"
 
-static gboolean on_btn_press( GtkWidget* w, GdkEventButton* evt, Plugin* plugin )
-{
-    if( evt->button == 3 )
-    {
-        GtkMenu* popup = lxpanel_get_panel_menu
-                ( plugin->panel, plugin, FALSE );
-        gtk_menu_popup( popup, NULL, NULL, NULL, NULL, evt->button, evt->time );
-    }
-    return TRUE;
-}
-
 static int
 separator_constructor(Plugin *p, char **fp)
 {
     GtkWidget *sep, *eb;
     line s;
 
-    ENTER;
     s.len = 256;
     if( fp )
     {
@@ -50,10 +38,11 @@ separator_constructor(Plugin *p, char **fp)
             RET(0);
         }
     }
+
     p->pwid = eb = gtk_event_box_new();
     GTK_WIDGET_SET_FLAGS( eb, GTK_NO_WINDOW );
     gtk_widget_add_events( p->pwid, GDK_BUTTON_PRESS_MASK );
-    g_signal_connect( p->pwid, "button-press-event", G_CALLBACK( on_btn_press ), p );
+    g_signal_connect( p->pwid, "button-press-event", G_CALLBACK(plugin_button_press_event), p );
 
     gtk_container_set_border_width(GTK_CONTAINER(eb), 1);
     gtk_widget_show(eb);
@@ -61,25 +50,18 @@ separator_constructor(Plugin *p, char **fp)
     sep = p->panel->my_separator_new();
     gtk_widget_show(sep);
     gtk_container_add (GTK_CONTAINER (eb), sep);
-    p->priv = eb; /* just to alloc smth */
 
-    RET(1);
+    return 1;
 }
 
 static void
 separator_destructor(Plugin *p)
 {
-    ENTER;
-/* The widget is destroyed in plugin_stop().
-    GtkWidget* eb = GTK_WIDGET((GtkEventBox*)p->priv);
-    gtk_widget_destroy( eb );
-*/
-    RET();
 }
 
 static void orientation_changed( Plugin* p )
 {
-    GtkWidget* eb = GTK_WIDGET((GtkEventBox*)p->priv);
+    GtkWidget* eb = GTK_WIDGET((GtkEventBox*)p->pwid);
     GtkWidget* sep = gtk_bin_get_child( GTK_BIN(eb) );
     if( GTK_IS_VSEPARATOR(sep) ) {
         if( p->panel->orientation == GTK_ORIENTATION_HORIZONTAL )
@@ -96,8 +78,6 @@ static void orientation_changed( Plugin* p )
 }
 
 PluginClass separator_plugin_class = {
-    fname: NULL,
-    count: 0,
 
     type : "separator",
     name : N_("Separator"),
index 57e6b90..d7eaafb 100644 (file)
@@ -36,12 +36,7 @@ space_destructor(Plugin *p)
 {
     space *sp = (space *)p->priv;
 
-    ENTER;
-    /* The widget is destroyed in plugin_stop().
-    gtk_widget_destroy(sp->mainw);
-    */
     g_free(sp);
-    RET();
 }
 
 static gboolean on_btn_press( GtkWidget* w, GdkEventButton* evt, Plugin* plugin )
index ac885d5..7804542 100644 (file)
@@ -36,22 +36,6 @@ typedef struct {
              cl_warning2;
 } thermal;
 
-static  gboolean
-clicked( GtkWidget *widget, GdkEventButton* evt, Plugin* plugin)
-{
-
-    ENTER2;
-    if( evt->button == 3 )  /* right button */
-    {
-        GtkMenu* popup = (GtkMenu*)lxpanel_get_panel_menu
-                ( plugin->panel, plugin, FALSE );
-        gtk_menu_popup( popup, NULL, NULL, NULL, NULL, evt->button, evt->time );
-        return TRUE;
-    }
-
-    RET2(TRUE);
-}
-
 static gint
 get_critical(thermal *th){
     FILE *state;
@@ -193,7 +177,7 @@ thermal_constructor(Plugin *p, char** fp)
     th->tip  = gtk_tooltips_new();
 
     g_signal_connect (G_OBJECT (p->pwid), "button_press_event",
-          G_CALLBACK (clicked), (gpointer) p);
+          G_CALLBACK (plugin_button_press_event), (gpointer) p);
 
     line s;
     s.len = 256;
index 5af3791..80e800f 100644 (file)
@@ -214,12 +214,9 @@ static gboolean focus_out_event(GtkWidget *widget, GdkEvent *event, volume_t *vo
 
 static gboolean tray_icon_press(GtkWidget *widget, GdkEventButton *event, volume_t *vol)
 {
-    if( event->button == 3 )  /* right button */
-    {
-        GtkMenu* popup = lxpanel_get_panel_menu( vol->plugin->panel, vol->plugin, FALSE );
-        gtk_menu_popup( popup, NULL, NULL, NULL, NULL, event->button, event->time );
+    /* Standard right-click handling. */
+    if (plugin_button_press_event(widget, event, vol->plugin))
         return TRUE;
-    }
 
     if (vol->show==0) {
         gtk_window_set_position(GTK_WINDOW(vol->dlg), GTK_WIN_POS_MOUSE);
@@ -383,7 +380,7 @@ volumealsa_constructor(Plugin *p, char **fp)
     vol->mainw = gtk_event_box_new();
 
     gtk_widget_add_events(vol->mainw, GDK_BUTTON_PRESS_MASK);
-    gtk_widget_set_size_request( vol->mainw, 24, 24 );
+    gtk_widget_set_size_request( vol->mainw, PANEL_ICON_SIZE, PANEL_ICON_SIZE );
 
     g_signal_connect(G_OBJECT(vol->mainw), "button-press-event",
                          G_CALLBACK(tray_icon_press), vol);
index b7491e4..112d0b5 100644 (file)
@@ -137,11 +137,9 @@ clicked (GtkWidget *widget, GdkEventButton *event, Plugin* plugin)
 {
     wincmd *wc = (wincmd *)plugin->priv;
 
-    ENTER;
-    if (event->type != GDK_BUTTON_PRESS)
-        RET(FALSE);
-
-    ENTER2;
+    /* Standard right-click handling. */
+    if (plugin_button_press_event(widget, event, plugin))
+        return TRUE;
 
     if (event->button == 1) {
         wc->action1 = 1 - wc->action1;
@@ -151,13 +149,8 @@ clicked (GtkWidget *widget, GdkEventButton *event, Plugin* plugin)
         wc->action2 = 1 - wc->action2;
         toggle_shaded(wc, wc->action2);
         DBG("wincmd: shade all\n");
-    } else if( event->button == 3 ) { /* right button */
-        GtkMenu* popup = (GtkMenu*)lxpanel_get_panel_menu
-                ( plugin->panel, plugin, FALSE );
-        gtk_menu_popup( popup, NULL, NULL, NULL, NULL, event->button, event->time );
-        return TRUE;
     }
-    RET(FALSE);
+    return FALSE;
 }
 
 static void
@@ -165,11 +158,8 @@ wincmd_destructor(Plugin *p)
 {
     wincmd *wc = (wincmd *)p->priv;
 
-    ENTER;
     g_free( wc->image );
-    /* g_object_unref( wc->tips ); */
     g_free(wc);
-    RET();
 }
 
 
@@ -180,11 +170,9 @@ wincmd_constructor(Plugin *p, char **fp)
     line s;
     gchar *fname;
     wincmd *wc;
-    //GdkPixbuf *gp, *gps;
     GtkWidget *button;
     int w, h;
 
-    ENTER;
     s.len = 256;
     wc = g_new0(wincmd, 1);
     g_return_val_if_fail(wc != NULL, 0);
@@ -247,13 +235,13 @@ wincmd_constructor(Plugin *p, char **fp)
     /* store the created plugin widget in plugin->pwid */
     p->pwid = button;
 
-    RET(1);
+    return 1;
 
  error:
     g_free(fname);
     wincmd_destructor(p);
     ERR( "%s - exit\n", __FUNCTION__);
-    RET(0);
+    return 0;
 }
 
 static void save_config( Plugin* p, FILE* fp )
@@ -273,7 +261,7 @@ PluginClass wincmd_plugin_class = {
     type : "wincmd",
     name : N_("Minimize All Windows"),
     version: "1.0",
-    description : N_("Sends commands to all desktop windows.\nSupported commnds are 1)toggle iconify and 2) toggle shade"),
+    description : N_("Sends commands to all desktop windows.\nSupported commands are 1)toggle iconify and 2) toggle shade"),
 
     constructor : wincmd_constructor,
     destructor  : wincmd_destructor,
index aa1454a..01ff7f1 100644 (file)
@@ -212,6 +212,9 @@ PluginClass tray_plugin_class = {
     version: "1.0",
     description : N_("Old KDE/GNOME Tray"),
 
+    /* Set a flag to identify the system tray.  It is special in that only one per system can exist. */
+    one_per_system : TRUE,
+
     constructor : tray_constructor,
     destructor  : tray_destructor,
     config : NULL,