[gnome-shell] St: drop StClickable, add some functionality to StButton



commit c86a977564e5d2db83b0be503cb10a4c4129eeec
Author: Dan Winship <danw gnome org>
Date:   Tue Jan 25 16:22:00 2011 -0500

    St: drop StClickable, add some functionality to StButton
    
    For historical reasons, we had both StClickable and StButton, which
    were nearly identical. StButton was more widely-used, so keep that and
    port all StClickable users to that.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=640583

 data/theme/gnome-shell.css |    7 +-
 js/ui/altTab.js            |    4 +-
 js/ui/appDisplay.js        |   14 +-
 js/ui/dnd.js               |   10 +-
 js/ui/endSessionDialog.js  |   12 +-
 js/ui/panel.js             |   14 +-
 js/ui/searchDisplay.js     |   26 ++--
 src/Makefile-st.am         |    2 -
 src/st/st-button.c         |  219 ++++++++++++++++++++------
 src/st/st-button.h         |   44 ++++--
 src/st/st-clickable.c      |  363 --------------------------------------------
 src/st/st-clickable.h      |   54 -------
 src/st/st-marshal.list     |    1 +
 13 files changed, 244 insertions(+), 526 deletions(-)
---
diff --git a/data/theme/gnome-shell.css b/data/theme/gnome-shell.css
index 3e7cc81..a79b01c 100644
--- a/data/theme/gnome-shell.css
+++ b/data/theme/gnome-shell.css
@@ -217,7 +217,7 @@ StTooltip StLabel {
     transition-duration: 100;
 }
 
-.panel-button:active, .panel-button:checked, .panel-button:pressed, .panel-button:focus {
+.panel-button:active, .panel-button:checked, .panel-button:focus {
     background-gradient-direction: vertical;
     background-gradient-start: #3c3c3c;
     background-gradient-end: #131313;
@@ -541,11 +541,6 @@ StTooltip StLabel {
     transition-duration: 100;
 }
 
-.app-well-app:active > .overview-icon {
-    background-color: #1e1e1e;
-    border: 1px solid #5f5f5f;
-}
-
 .app-well-menu {
     font-size: 12px
 }
diff --git a/js/ui/altTab.js b/js/ui/altTab.js
index 03b8fdc..46c2a09 100644
--- a/js/ui/altTab.js
+++ b/js/ui/altTab.js
@@ -593,8 +593,8 @@ SwitcherList.prototype = {
     },
 
     addItem : function(item) {
-        let bbox = new St.Clickable({ style_class: 'item-box',
-                                      reactive: true });
+        let bbox = new St.Button({ style_class: 'item-box',
+                                   reactive: true });
 
         bbox.set_child(item);
         this._list.add_actor(bbox);
diff --git a/js/ui/appDisplay.js b/js/ui/appDisplay.js
index c5fe8c6..4628a5a 100644
--- a/js/ui/appDisplay.js
+++ b/js/ui/appDisplay.js
@@ -319,10 +319,11 @@ function AppWellIcon(app, iconParams) {
 AppWellIcon.prototype = {
     _init : function(app, iconParams) {
         this.app = app;
-        this.actor = new St.Clickable({ style_class: 'app-well-app',
-                                         reactive: true,
-                                         x_fill: true,
-                                         y_fill: true });
+        this.actor = new St.Button({ style_class: 'app-well-app',
+                                     reactive: true,
+                                     button_mask: St.ButtonMask.ONE | St.ButtonMask.TWO,
+                                     x_fill: true,
+                                     y_fill: true });
         this.actor._delegate = this;
 
         this.icon = new AppIcon(app, iconParams);
@@ -390,12 +391,11 @@ AppWellIcon.prototype = {
         return false;
     },
 
-    _onClicked: function(actor, event) {
+    _onClicked: function(actor, button) {
         this._removeMenuTimeout();
 
-        let button = event.get_button();
         if (button == 1) {
-            this._onActivate(event);
+            this._onActivate(Clutter.get_current_event());
         } else if (button == 2) {
             let newWorkspace = Main.overview.workspaces.addWorkspace();
             if (newWorkspace != null) {
diff --git a/js/ui/dnd.js b/js/ui/dnd.js
index 71d8c04..7c88dc2 100644
--- a/js/ui/dnd.js
+++ b/js/ui/dnd.js
@@ -112,11 +112,11 @@ _Draggable.prototype = {
             return false;
 
         this._buttonDown = true;
-        // special case St.Clickable: grabbing the pointer would mess up the
+        // special case St.Button: grabbing the pointer would mess up the
         // internal state, so we start the drag manually on hover change
-        if (this.actor instanceof St.Clickable)
+        if (this.actor instanceof St.Button)
             this.actor.connect('notify::hover',
-                               Lang.bind(this, this._onClickableHoverChanged));
+                               Lang.bind(this, this._onButtonHoverChanged));
         else
             this._grabActor();
 
@@ -127,8 +127,8 @@ _Draggable.prototype = {
         return false;
     },
 
-    _onClickableHoverChanged: function(button) {
-        if (button.hover || !button.held)
+    _onButtonHoverChanged: function(button) {
+        if (button.hover || !button.pressed)
             return;
 
         button.fake_release();
diff --git a/js/ui/endSessionDialog.js b/js/ui/endSessionDialog.js
index c25633a..6b85bd8 100644
--- a/js/ui/endSessionDialog.js
+++ b/js/ui/endSessionDialog.js
@@ -137,12 +137,12 @@ ListItem.prototype = {
 
         let layout = new St.BoxLayout({ vertical: false});
 
-        this.actor = new St.Clickable({ style_class: 'end-session-dialog-app-list-item',
-                                        can_focus:   true,
-                                        child:       layout,
-                                        reactive:    true,
-                                        x_align:     St.Align.START,
-                                        x_fill:      true });
+        this.actor = new St.Button({ style_class: 'end-session-dialog-app-list-item',
+                                     can_focus:   true,
+                                     child:       layout,
+                                     reactive:    true,
+                                     x_align:     St.Align.START,
+                                     x_fill:      true });
 
         this._icon = this._app.create_icon_texture(_ITEM_ICON_SIZE);
 
diff --git a/js/ui/panel.js b/js/ui/panel.js
index 9b7c3b3..4d0e001 100644
--- a/js/ui/panel.js
+++ b/js/ui/panel.js
@@ -612,10 +612,10 @@ Panel.prototype = {
         /* Button on the left side of the panel. */
         /* Translators: If there is no suitable word for "Activities" in your language, you can use the word for "Overview". */
         let label = new St.Label({ text: _("Activities") });
-        this.button = new St.Clickable({ name: 'panelActivities',
-                                         style_class: 'panel-button',
-                                         reactive: true,
-                                         can_focus: true });
+        this.button = new St.Button({ name: 'panelActivities',
+                                      style_class: 'panel-button',
+                                      reactive: true,
+                                      can_focus: true });
         this.button.set_child(label);
         this.button._delegate = this.button;
         this.button._xdndTimeOut = 0;
@@ -712,7 +712,7 @@ Panel.prototype = {
         // We get into the Overview mode on button-press-event as opposed to button-release-event because eventually we'll probably
         // have the Overview act like a menu that allows the user to release the mouse on the activity the user wants
         // to switch to.
-        this.button.connect('clicked', Lang.bind(this, function(b, event) {
+        this.button.connect('clicked', Lang.bind(this, function(b) {
             if (!Main.overview.animationInProgress) {
                 this._maybeToggleOverviewOnClick();
                 return true;
@@ -724,10 +724,10 @@ Panel.prototype = {
         // pressing the System key, Alt+F1 or Esc. We want the button to be pressed in when the Overview is entered
         // and to be released when it is exited regardless of how it was triggered.
         Main.overview.connect('showing', Lang.bind(this, function() {
-            this.button.active = true;
+            this.button.checked = true;
         }));
         Main.overview.connect('hiding', Lang.bind(this, function() {
-            this.button.active = false;
+            this.button.checked = false;
         }));
 
         Main.chrome.addActor(this.actor, { visibleInOverview: true });
diff --git a/js/ui/searchDisplay.js b/js/ui/searchDisplay.js
index 3ed60ad..44794f6 100644
--- a/js/ui/searchDisplay.js
+++ b/js/ui/searchDisplay.js
@@ -24,10 +24,10 @@ SearchResult.prototype = {
     _init: function(provider, metaInfo, terms) {
         this.provider = provider;
         this.metaInfo = metaInfo;
-        this.actor = new St.Clickable({ style_class: 'search-result',
-                                        reactive: true,
-                                        x_align: St.Align.START,
-                                        y_fill: true });
+        this.actor = new St.Button({ style_class: 'search-result',
+                                     reactive: true,
+                                     x_align: St.Align.START,
+                                     y_fill: true });
         this.actor._delegate = this;
 
         let content = provider.createResultActor(metaInfo, terms);
@@ -69,7 +69,7 @@ SearchResult.prototype = {
         Main.overview.toggle();
     },
 
-    _onResultClicked: function(actor, event) {
+    _onResultClicked: function(actor) {
         this.activate();
     },
 
@@ -221,23 +221,23 @@ SearchResults.prototype = {
     },
 
     _createOpenSearchProviderButton: function(provider) {
-        let clickable = new St.Clickable({ style_class: 'dash-search-button',
-                                           reactive: true,
-                                           x_fill: true,
-                                           y_align: St.Align.MIDDLE });
+        let button = new St.Button({ style_class: 'dash-search-button',
+                                     reactive: true,
+                                     x_fill: true,
+                                     y_align: St.Align.MIDDLE });
         let bin = new St.Bin({ x_fill: false,
                                x_align:St.Align.MIDDLE });
-        clickable.connect('clicked', Lang.bind(this, function() {
+        button.connect('clicked', Lang.bind(this, function() {
             this._openSearchSystem.activateResult(provider.id);
         }));
         let title = new St.Label({ text: provider.name,
                                    style_class: 'dash-search-button-label' });
 
         bin.set_child(title);
-        clickable.set_child(bin);
-        provider.actor = clickable;
+        button.set_child(bin);
+        provider.actor = button;
 
-        this._searchProvidersBox.add(clickable);
+        this._searchProvidersBox.add(button);
     },
 
     createProviderMeta: function(provider) {
diff --git a/src/Makefile-st.am b/src/Makefile-st.am
index cb54ef4..ffeeb21 100644
--- a/src/Makefile-st.am
+++ b/src/Makefile-st.am
@@ -72,7 +72,6 @@ st_source_h =					\
 	st/st-box-layout.h			\
 	st/st-box-layout-child.h		\
 	st/st-button.h				\
-	st/st-clickable.h			\
 	st/st-clipboard.h			\
 	st/st-container.h			\
 	st/st-drawing-area.h			\
@@ -130,7 +129,6 @@ st_source_c =					\
 	st/st-box-layout.c			\
 	st/st-box-layout-child.c		\
 	st/st-button.c				\
-	st/st-clickable.c			\
 	st/st-clipboard.c			\
 	st/st-container.c			\
 	st/st-drawing-area.c			\
diff --git a/src/st/st-button.c b/src/st/st-button.c
index dfee026..c3eca61 100644
--- a/src/st/st-button.c
+++ b/src/st/st-button.c
@@ -40,6 +40,7 @@
 
 #include "st-button.h"
 
+#include "st-enum-types.h"
 #include "st-marshal.h"
 #include "st-texture-cache.h"
 #include "st-private.h"
@@ -49,8 +50,10 @@ enum
   PROP_0,
 
   PROP_LABEL,
+  PROP_BUTTON_MASK,
   PROP_TOGGLE_MODE,
-  PROP_CHECKED
+  PROP_CHECKED,
+  PROP_PRESSED
 };
 
 enum
@@ -65,14 +68,16 @@ enum
 
 struct _StButtonPrivate
 {
-  gchar            *text;
+  gchar *text;
 
-  guint             is_pressed : 1;
-  guint             is_checked : 1;
-  guint             is_toggle : 1;
-  guint             has_grab : 1;
+  guint  button_mask : 3;
+  guint  is_toggle   : 1;
 
-  gint              spacing;
+  guint  pressed     : 3;
+  guint  grabbed     : 3;
+  guint  is_checked  : 1;
+
+  gint   spacing;
 };
 
 static guint button_signals[LAST_SIGNAL] = { 0, };
@@ -119,31 +124,32 @@ st_button_style_changed (StWidget *widget)
 }
 
 static void
-st_button_press (StButton *button)
+st_button_press (StButton     *button,
+                 StButtonMask  mask)
 {
-  if (button->priv->is_pressed)
-    return;
+  if (button->priv->pressed == 0)
+    st_widget_add_style_pseudo_class (ST_WIDGET (button), "active");
 
-  button->priv->is_pressed = TRUE;
-  st_widget_add_style_pseudo_class (ST_WIDGET (button), "active");
+  button->priv->pressed |= mask;
 }
 
 static void
-st_button_release (StButton *button,
-                   gboolean  clicked)
+st_button_release (StButton     *button,
+                   StButtonMask  mask,
+                   int           clicked_button)
 {
-  if (!button->priv->is_pressed)
+  button->priv->pressed &= ~mask;
+  if (button->priv->pressed != 0)
     return;
 
-  button->priv->is_pressed = FALSE;
   st_widget_remove_style_pseudo_class (ST_WIDGET (button), "active");
 
-  if (clicked)
+  if (clicked_button)
     {
       if (button->priv->is_toggle)
         st_button_set_checked (button, !button->priv->is_checked);
 
-      g_signal_emit (button, button_signals[CLICKED], 0);
+      g_signal_emit (button, button_signals[CLICKED], 0, clicked_button);
     }
 }
 
@@ -151,15 +157,18 @@ static gboolean
 st_button_button_press (ClutterActor       *actor,
                         ClutterButtonEvent *event)
 {
+  StButton *button = ST_BUTTON (actor);
+  StButtonMask mask = ST_BUTTON_MASK_FROM_BUTTON (event->button);
+
   st_widget_hide_tooltip (ST_WIDGET (actor));
 
-  if (event->button == 1)
+  if (button->priv->button_mask & mask)
     {
-      StButton *button = ST_BUTTON (actor);
+      if (button->priv->grabbed == 0)
+        clutter_grab_pointer (actor);
 
-      clutter_grab_pointer (actor);
-      button->priv->has_grab = TRUE;
-      st_button_press (button);
+      button->priv->grabbed |= mask;
+      st_button_press (button, mask);
 
       return TRUE;
     }
@@ -171,19 +180,19 @@ static gboolean
 st_button_button_release (ClutterActor       *actor,
                           ClutterButtonEvent *event)
 {
-  if (event->button == 1)
+  StButton *button = ST_BUTTON (actor);
+  StButtonMask mask = ST_BUTTON_MASK_FROM_BUTTON (event->button);
+
+  if (button->priv->button_mask & mask)
     {
-      StButton *button = ST_BUTTON (actor);
       gboolean is_click;
 
-      is_click = button->priv->has_grab && st_widget_get_hover (ST_WIDGET (button));
-      st_button_release (button, is_click);
+      is_click = button->priv->grabbed && st_widget_get_hover (ST_WIDGET (button));
+      st_button_release (button, mask, is_click ? event->button : 0);
 
-      if (button->priv->has_grab)
-        {
-          button->priv->has_grab = FALSE;
-          clutter_ungrab_pointer ();
-        }
+      button->priv->grabbed &= ~mask;
+      if (button->priv->grabbed == 0)
+        clutter_ungrab_pointer ();
 
       return TRUE;
     }
@@ -195,13 +204,18 @@ static gboolean
 st_button_key_press (ClutterActor    *actor,
                      ClutterKeyEvent *event)
 {
+  StButton *button = ST_BUTTON (actor);
+
   st_widget_hide_tooltip (ST_WIDGET (actor));
 
-  if (event->keyval == CLUTTER_KEY_space ||
-      event->keyval == CLUTTER_KEY_Return)
+  if (button->priv->button_mask & ST_BUTTON_ONE)
     {
-      st_button_press (ST_BUTTON (actor));
-      return TRUE;
+      if (event->keyval == CLUTTER_KEY_space ||
+          event->keyval == CLUTTER_KEY_Return)
+        {
+          st_button_press (button, ST_BUTTON_ONE);
+          return TRUE;
+        }
     }
 
   return FALSE;
@@ -211,16 +225,34 @@ static gboolean
 st_button_key_release (ClutterActor    *actor,
                        ClutterKeyEvent *event)
 {
-  if (event->keyval == CLUTTER_KEY_space ||
-      event->keyval == CLUTTER_KEY_Return)
+  StButton *button = ST_BUTTON (actor);
+
+  if (button->priv->button_mask & ST_BUTTON_ONE)
     {
-      st_button_release (ST_BUTTON (actor), TRUE);
-      return TRUE;
+      if (event->keyval == CLUTTER_KEY_space ||
+          event->keyval == CLUTTER_KEY_Return)
+        {
+          st_button_release (button, ST_BUTTON_ONE, 1);
+          return TRUE;
+        }
     }
 
   return FALSE;
 }
 
+static void
+st_button_key_focus_out (ClutterActor *actor)
+{
+  StButton *button = ST_BUTTON (actor);
+
+  /* If we lose focus between a key press and release, undo the press */
+  if ((button->priv->pressed & ST_BUTTON_ONE) &&
+      !(button->priv->grabbed & ST_BUTTON_ONE))
+    st_button_release (button, ST_BUTTON_ONE, 0);
+
+  CLUTTER_ACTOR_CLASS (st_button_parent_class)->key_focus_out (actor);
+}
+
 static gboolean
 st_button_enter (ClutterActor         *actor,
                  ClutterCrossingEvent *event)
@@ -230,12 +262,12 @@ st_button_enter (ClutterActor         *actor,
 
   ret = CLUTTER_ACTOR_CLASS (st_button_parent_class)->enter_event (actor, event);
 
-  if (button->priv->has_grab)
+  if (button->priv->grabbed)
     {
       if (st_widget_get_hover (ST_WIDGET (button)))
-        st_button_press (button);
+        st_button_press (button, button->priv->grabbed);
       else
-        st_button_release (button, FALSE);
+        st_button_release (button, button->priv->grabbed, 0);
     }
 
   return ret;
@@ -250,12 +282,12 @@ st_button_leave (ClutterActor         *actor,
 
   ret = CLUTTER_ACTOR_CLASS (st_button_parent_class)->leave_event (actor, event);
 
-  if (button->priv->has_grab)
+  if (button->priv->grabbed)
     {
       if (st_widget_get_hover (ST_WIDGET (button)))
-        st_button_press (button);
+        st_button_press (button, button->priv->grabbed);
       else
-        st_button_release (button, FALSE);
+        st_button_release (button, button->priv->grabbed, 0);
     }
 
   return ret;
@@ -274,6 +306,9 @@ st_button_set_property (GObject      *gobject,
     case PROP_LABEL:
       st_button_set_label (button, g_value_get_string (value));
       break;
+    case PROP_BUTTON_MASK:
+      st_button_set_button_mask (button, g_value_get_flags (value));
+      break;
     case PROP_TOGGLE_MODE:
       st_button_set_toggle_mode (button, g_value_get_boolean (value));
       break;
@@ -301,12 +336,18 @@ st_button_get_property (GObject    *gobject,
     case PROP_LABEL:
       g_value_set_string (value, priv->text);
       break;
+    case PROP_BUTTON_MASK:
+      g_value_set_flags (value, priv->button_mask);
+      break;
     case PROP_TOGGLE_MODE:
       g_value_set_boolean (value, priv->is_toggle);
       break;
     case PROP_CHECKED:
       g_value_set_boolean (value, priv->is_checked);
       break;
+    case PROP_PRESSED:
+      g_value_set_boolean (value, priv->pressed != 0);
+      break;
 
 
     default:
@@ -343,6 +384,7 @@ st_button_class_init (StButtonClass *klass)
   actor_class->button_release_event = st_button_button_release;
   actor_class->key_press_event = st_button_key_press;
   actor_class->key_release_event = st_button_key_release;
+  actor_class->key_focus_out = st_button_key_focus_out;
   actor_class->enter_event = st_button_enter;
   actor_class->leave_event = st_button_leave;
 
@@ -354,6 +396,13 @@ st_button_class_init (StButtonClass *klass)
                                NULL, G_PARAM_READWRITE);
   g_object_class_install_property (gobject_class, PROP_LABEL, pspec);
 
+  pspec = g_param_spec_flags ("button-mask",
+                              "Button mask",
+                              "Which buttons trigger the 'clicked' signal",
+                              ST_TYPE_BUTTON_MASK, ST_BUTTON_ONE,
+                              G_PARAM_READWRITE);
+  g_object_class_install_property (gobject_class, PROP_BUTTON_MASK, pspec);
+
   pspec = g_param_spec_boolean ("toggle-mode",
                                 "Toggle Mode",
                                 "Enable or disable toggling",
@@ -367,23 +416,30 @@ st_button_class_init (StButtonClass *klass)
                                 FALSE, G_PARAM_READWRITE);
   g_object_class_install_property (gobject_class, PROP_CHECKED, pspec);
 
+  pspec = g_param_spec_boolean ("pressed",
+                                "Pressed",
+                                "Indicates if the button is pressed in",
+                                FALSE, G_PARAM_READABLE);
+  g_object_class_install_property (gobject_class, PROP_PRESSED, pspec);
+
 
   /**
    * StButton::clicked:
    * @button: the object that received the signal
+   * @clicked_button: the mouse button that was used
    *
    * Emitted when the user activates the button, either with a mouse press and
    * release or with the keyboard.
    */
-
   button_signals[CLICKED] =
     g_signal_new ("clicked",
                   G_TYPE_FROM_CLASS (klass),
                   G_SIGNAL_RUN_LAST,
                   G_STRUCT_OFFSET (StButtonClass, clicked),
                   NULL, NULL,
-                  _st_marshal_VOID__VOID,
-                  G_TYPE_NONE, 0);
+                  _st_marshal_VOID__INT,
+                  G_TYPE_NONE, 1,
+                  G_TYPE_INT);
 }
 
 static void
@@ -391,6 +447,7 @@ st_button_init (StButton *button)
 {
   button->priv = ST_BUTTON_GET_PRIVATE (button);
   button->priv->spacing = 6;
+  button->priv->button_mask = ST_BUTTON_ONE;
 
   clutter_actor_set_reactive (CLUTTER_ACTOR (button), TRUE);
   st_widget_set_track_hover (ST_WIDGET (button), TRUE);
@@ -431,7 +488,7 @@ st_button_new_with_label (const gchar *text)
  *
  * Returns: the text for the button. This must not be freed by the application
  */
-G_CONST_RETURN gchar *
+const gchar *
 st_button_get_label (StButton *button)
 {
   g_return_val_if_fail (ST_IS_BUTTON (button), NULL);
@@ -488,6 +545,42 @@ st_button_set_label (StButton    *button,
 }
 
 /**
+ * st_button_get_button_mask:
+ * @button: a #StButton
+ *
+ * Gets the mask of mouse buttons that @button emits the
+ * #StButton::clicked signal for.
+ *
+ * Returns: the mask of mouse buttons that @button emits the
+ * #StButton::clicked signal for.
+ */
+StButtonMask
+st_button_get_button_mask (StButton *button)
+{
+  g_return_val_if_fail (ST_IS_BUTTON (button), 0);
+
+  return button->priv->button_mask;
+}
+
+/**
+ * st_button_set_button_mask:
+ * @button: a #Stbutton
+ * @mask: the mask of mouse buttons that @button responds to
+ *
+ * Sets which mouse buttons @button emits #StButton::clicked for.
+ */
+void
+st_button_set_button_mask (StButton     *button,
+                           StButtonMask  mask)
+{
+  g_return_if_fail (ST_IS_BUTTON (button));
+
+  button->priv->button_mask = mask;
+
+  g_object_notify (G_OBJECT (button), "button-mask");
+}
+
+/**
  * st_button_get_toggle_mode:
  * @button: a #StButton
  *
@@ -564,3 +657,29 @@ st_button_set_checked (StButton *button,
 
   g_object_notify (G_OBJECT (button), "checked");
 }
+
+/**
+ * st_button_fake_release:
+ * @button: an #StButton
+ *
+ * If this widget is holding a pointer grab, this function will
+ * will ungrab it, and reset the pressed state.  The effect is
+ * similar to if the user had released the mouse button, but without
+ * emitting the clicked signal.
+ *
+ * This function is useful if for example you want to do something
+ * after the user is holding the mouse button for a given period of
+ * time, breaking the grab.
+ */
+void
+st_button_fake_release (StButton *button)
+{
+  if (button->priv->pressed)
+    st_button_release (button, button->priv->pressed, 0);
+
+  if (button->priv->grabbed)
+    {
+      button->priv->grabbed = 0;
+      clutter_ungrab_pointer ();
+    }
+}
diff --git a/src/st/st-button.h b/src/st/st-button.h
index 15a6983..23ae81b 100644
--- a/src/st/st-button.h
+++ b/src/st/st-button.h
@@ -68,17 +68,39 @@ struct _StButtonClass
 
 GType st_button_get_type (void) G_GNUC_CONST;
 
-StWidget *            st_button_new             (void);
-StWidget *            st_button_new_with_label  (const gchar *text);
-G_CONST_RETURN gchar *st_button_get_label       (StButton    *button);
-void                  st_button_set_label       (StButton    *button,
-                                                 const gchar *text);
-void                  st_button_set_toggle_mode (StButton    *button,
-                                                 gboolean     toggle);
-gboolean              st_button_get_toggle_mode (StButton    *button);
-void                  st_button_set_checked     (StButton    *button,
-                                                 gboolean     checked);
-gboolean              st_button_get_checked     (StButton    *button);
+StWidget    *st_button_new             (void);
+StWidget    *st_button_new_with_label  (const gchar  *text);
+const gchar *st_button_get_label       (StButton     *button);
+void         st_button_set_label       (StButton     *button,
+                                        const gchar  *text);
+void         st_button_set_toggle_mode (StButton     *button,
+                                        gboolean      toggle);
+gboolean     st_button_get_toggle_mode (StButton     *button);
+void         st_button_set_checked     (StButton     *button,
+                                        gboolean      checked);
+gboolean     st_button_get_checked     (StButton     *button);
+
+void         st_button_fake_release    (StButton     *button);
+
+/**
+ * StButtonMask:
+ * @ST_BUTTON_ONE: button 1 (left)
+ * @ST_BUTTON_TWO: button 2 (middle)
+ * @ST_BUTTON_THREE: button 3 (right)
+ *
+ * A mask representing which mouse buttons an StButton responds to.
+ */
+typedef enum {
+  ST_BUTTON_ONE   = (1 << 0),
+  ST_BUTTON_TWO   = (1 << 1),
+  ST_BUTTON_THREE = (1 << 2),
+} StButtonMask;
+
+#define ST_BUTTON_MASK_FROM_BUTTON(button) (1 << ((button) - 1))
+
+void         st_button_set_button_mask (StButton     *button,
+                                        StButtonMask  mask);
+StButtonMask st_button_get_button_mask (StButton     *button);
 
 G_END_DECLS
 
diff --git a/src/st/st-marshal.list b/src/st/st-marshal.list
index 9b3bed6..69b75cc 100644
--- a/src/st/st-marshal.list
+++ b/src/st/st-marshal.list
@@ -2,6 +2,7 @@ VOID:OBJECT
 VOID:VOID
 VOID:PARAM
 VOID:POINTER
+VOID:INT
 VOID:UINT
 VOID:UINT,UINT
 VOID:OBJECT,OBJECT



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]