commit 6449ab331848465c0521bf3499a6a53720afe24e
Author: Richard Hughes <richard@hughsie.com>
Date:   Sat Oct 25 17:28:21 2008 +0000

    Make the duplicate key detection more robust to handle when we get the HAL
    
    2008-10-25  Richard Hughes  <richard@hughsie.com>
    
    * src/gpm-brightness-xrandr.c:
    (gpm_brightness_xrandr_filter_xevents):
    * src/gpm-button.c: (gpm_button_emit_type),
    (gpm_button_filter_x_events), (emit_button_pressed),
    (gpm_button_init), (gpm_button_finalize):
    Make the duplicate key detection more robust to handle when we get
    the HAL event before the X event.
    
    svn path=/trunk/; revision=3044

Index: gnome-power-manager-2.24.1/src/gpm-brightness-xrandr.c
===================================================================
--- gnome-power-manager-2.24.1.orig/src/gpm-brightness-xrandr.c
+++ gnome-power-manager-2.24.1/src/gpm-brightness-xrandr.c
@@ -563,7 +563,9 @@ static GdkFilterReturn
 gpm_brightness_xrandr_filter_xevents (GdkXEvent *xevent, GdkEvent *event, gpointer data)
 {
 	GpmBrightnessXRandR *brightness = GPM_BRIGHTNESS_XRANDR (data);
-	egg_warning ("Event0 %p", brightness);
+	if (event->type == GDK_NOTHING)
+		return GDK_FILTER_CONTINUE;
+	egg_warning ("Type %i", event->type);
 	if (FALSE) {
 		gpm_brightness_xrandr_may_have_changed (brightness);
 	}
Index: gnome-power-manager-2.24.1/src/gpm-button.c
===================================================================
--- gnome-power-manager-2.24.1.orig/src/gpm-button.c
+++ gnome-power-manager-2.24.1/src/gpm-button.c
@@ -53,6 +53,9 @@ struct GpmButtonPrivate
 	gboolean		 lid_is_closed;
 	HalGManager		*hal_manager; /* remove when input events is in the kernel */
 	HalGDevicestore		*hal_devicestore;
+	gchar			*last_button;
+	GTimer			*timer;
+
 };
 
 enum {
@@ -65,6 +68,35 @@ static gpointer gpm_button_object = NULL
 
 G_DEFINE_TYPE (GpmButton, gpm_button, G_TYPE_OBJECT)
 
+#define GPM_BUTTON_DUPLICATE_TIMEOUT	0.25f
+
+/**
+ * gpm_button_emit_type:
+ **/
+gboolean
+gpm_button_emit_type (GpmButton *button, const gchar *type)
+{
+	g_return_val_if_fail (button != NULL, FALSE);
+	g_return_val_if_fail (GPM_IS_BUTTON (button), FALSE);
+
+	/* did we just have this button before the timeout? */
+	if (g_strcmp0 (type, button->priv->last_button) == 0 &&
+	    g_timer_elapsed (button->priv->timer, NULL) < GPM_BUTTON_DUPLICATE_TIMEOUT) {
+		egg_debug ("ignoring duplicate button %s", type);
+		return FALSE;
+	}
+
+	egg_debug ("emitting button-pressed : %s", type);
+	g_signal_emit (button, signals [BUTTON_PRESSED], 0, type);
+
+	/* save type and last size */
+	g_free (button->priv->last_button);
+	button->priv->last_button = g_strdup (type);
+	g_timer_reset (button->priv->timer);
+
+	return TRUE;
+}
+
 static GdkFilterReturn
 gpm_button_filter_x_events (GdkXEvent *xevent,
 			    GdkEvent  *event,
@@ -73,7 +105,7 @@ gpm_button_filter_x_events (GdkXEvent *x
 	GpmButton *button = (GpmButton *) data;
 	XEvent *xev = (XEvent *) xevent;
 	guint keycode;
-	gchar *key;
+	const gchar *key;
 	gchar *keycode_str;
 
 	if (xev->type != KeyPress) {
@@ -95,12 +127,26 @@ gpm_button_filter_x_events (GdkXEvent *x
 	}
 
 	egg_debug ("Key %i mapped to HAL key %s", keycode, key);
-	g_signal_emit (button, signals [BUTTON_PRESSED], 0, key);
+	gpm_button_emit_type (button, key);
 
 	return GDK_FILTER_REMOVE;
 }
 
 /**
+ * gpm_button_reset_time:
+ *
+ * We have to refresh the event time on resume to handle duplicate buttons
+ * properly when the time is significant when we suspend.
+ **/
+gboolean
+gpm_button_reset_time (GpmButton *button)
+{
+	g_return_val_if_fail (GPM_IS_BUTTON (button), FALSE);
+	g_timer_reset (button->priv->timer);
+	return TRUE;
+}
+
+/**
  * gpm_button_grab_keystring:
  * @button: This button class instance
  * @keystr: The key string, e.g. "<Control><Alt>F11"
@@ -260,7 +306,7 @@ emit_button_pressed (GpmButton   *button
 {
 	gchar *type = NULL;
 	gboolean state;
-	const char *atype;
+	const gchar *atype;
 
 	g_return_if_fail (device != NULL);
 	g_return_if_fail (details != NULL);
@@ -318,7 +364,7 @@ emit_button_pressed (GpmButton   *button
 
 	/* we now emit all buttons, even the ones we don't know */
 	egg_debug ("emitting button-pressed : %s", atype);
-	g_signal_emit (button, signals [BUTTON_PRESSED], 0, atype);
+	gpm_button_emit_type (button, atype);
 
 	g_free (type);
 }
@@ -480,6 +526,8 @@ gpm_button_init (GpmButton *button)
 	button->priv->window = gdk_screen_get_root_window (button->priv->screen);
 
 	button->priv->hash_to_hal = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
+	button->priv->last_button = NULL;
+	button->priv->timer = g_timer_new ();
 
 	button->priv->lid_is_closed = FALSE;
 
@@ -489,7 +537,6 @@ gpm_button_init (GpmButton *button)
 
 	if (have_xevents) {
 		/* register the brightness keys */
-//		gpm_button_xevent_key (button, XF86XK_Execute, GPM_BUTTON_POWER);
 		gpm_button_xevent_key (button, XF86XK_PowerOff, GPM_BUTTON_POWER);
 //		gpm_button_xevent_key (button, XF86XK_Suspend, GPM_BUTTON_SUSPEND);
 		gpm_button_xevent_key (button, XF86XK_Sleep, GPM_BUTTON_SUSPEND); /* should be configurable */
@@ -538,6 +585,9 @@ gpm_button_finalize (GObject *object)
 
 	g_hash_table_unref (button->priv->hash_to_hal);
 
+	g_free (button->priv->last_button);
+	g_timer_destroy (button->priv->timer);
+
 	G_OBJECT_CLASS (gpm_button_parent_class)->finalize (object);
 }
 
Index: gnome-power-manager-2.24.1/src/gpm-manager.c
===================================================================
--- gnome-power-manager-2.24.1.orig/src/gpm-manager.c
+++ gnome-power-manager-2.24.1/src/gpm-manager.c
@@ -362,6 +362,7 @@ gpm_manager_action_suspend (GpmManager *
 				_("Suspending computer."), reason);
 	gpm_manager_unblank_screen (manager, NULL);
 	gpm_control_suspend (manager->priv->control, &error);
+	gpm_button_reset_time (manager->priv->button);
 	if (error != NULL) {
 		g_error_free (error);
 	}
@@ -412,6 +413,7 @@ gpm_manager_action_hibernate (GpmManager
 				_("Hibernating computer."), reason);
 	gpm_manager_unblank_screen (manager, NULL);
 	gpm_control_hibernate (manager->priv->control, &error);
+	gpm_button_reset_time (manager->priv->button);
 	if (error != NULL) {
 		g_error_free (error);
 	}
Index: gnome-power-manager-2.24.1/src/gpm-button.h
===================================================================
--- gnome-power-manager-2.24.1.orig/src/gpm-button.h
+++ gnome-power-manager-2.24.1/src/gpm-button.h
@@ -68,6 +68,7 @@ typedef struct
 GType		 gpm_button_get_type		(void);
 GpmButton	*gpm_button_new			(void);
 gboolean	 gpm_button_is_lid_closed	(GpmButton *button);
+gboolean	 gpm_button_reset_time		(GpmButton *button);
 
 G_END_DECLS
 
