r2539 - in trunk/src/target/OM-2008/libraries/libmokoui: . libmokoui

chris at sita.openmoko.org chris at sita.openmoko.org
Fri Jul 27 18:41:14 CEST 2007


Author: chris
Date: 2007-07-27 18:41:13 +0200 (Fri, 27 Jul 2007)
New Revision: 2539

Modified:
   trunk/src/target/OM-2008/libraries/libmokoui/ChangeLog
   trunk/src/target/OM-2008/libraries/libmokoui/libmokoui/moko-finger-scroll.c
Log:
Synthesise more events so that buttons and other like widgets work.
Also fix a possible infinite loop.


Modified: trunk/src/target/OM-2008/libraries/libmokoui/ChangeLog
===================================================================
--- trunk/src/target/OM-2008/libraries/libmokoui/ChangeLog	2007-07-27 15:29:18 UTC (rev 2538)
+++ trunk/src/target/OM-2008/libraries/libmokoui/ChangeLog	2007-07-27 16:41:13 UTC (rev 2539)
@@ -1,3 +1,16 @@
+2007-07-27  Chris Lord  <chris at openedhand.com>
+
+	* libmokoui/moko-finger-scroll.c:
+	(moko_finger_scroll_button_press_cb),
+	(moko_finger_scroll_motion_notify_cb),
+	(moko_finger_scroll_get_topmost),
+	(moko_finger_scroll_button_release_cb), (moko_finger_scroll_add),
+	(moko_finger_scroll_get_property),
+	(moko_finger_scroll_set_property), (moko_finger_scroll_class_init),
+	(moko_finger_scroll_init):
+	Synthesise more events so that buttons and other like widgets work.
+	Also fix a possible infinite loop.
+
 2007-07-13  Chris Lord  <chris at openedhand.com>
 
 	* libmokoui/moko-finger-scroll.c:

Modified: trunk/src/target/OM-2008/libraries/libmokoui/libmokoui/moko-finger-scroll.c
===================================================================
--- trunk/src/target/OM-2008/libraries/libmokoui/libmokoui/moko-finger-scroll.c	2007-07-27 15:29:18 UTC (rev 2538)
+++ trunk/src/target/OM-2008/libraries/libmokoui/libmokoui/moko-finger-scroll.c	2007-07-27 16:41:13 UTC (rev 2539)
@@ -34,6 +34,7 @@
 	gdouble ey;
 	gboolean enabled;
 	gboolean clicked;
+	guint32 last_time;
 	gboolean moved;
 	GTimeVal click_start;
 	gdouble vmin;
@@ -66,10 +67,11 @@
 {
 	MokoFingerScrollPrivate *priv = FINGER_SCROLL_PRIVATE (scroll);
 
-	if ((!priv->enabled) || (priv->clicked) || (event->button != 1))
-		return FALSE;
+	if ((!priv->enabled) || (priv->clicked) || (event->button != 1) ||
+	    (event->time == priv->last_time)) return FALSE;
 
 	g_get_current_time (&priv->click_start);
+	priv->last_time = event->time;
 	priv->x = event->x;
 	priv->y = event->y;
 	/* Don't allow a click if we're still moving fast, where fast is
@@ -298,35 +300,50 @@
 
 static GdkWindow *
 moko_finger_scroll_get_topmost (GdkWindow *window, gint x, gint y,
-				gint *x2, gint *y2)
+				gint *tx, gint *ty)
 {
 	/* Find the GdkWindow at the given point, by recursing from a given
 	 * parent GdkWindow. Optionally return the co-ordinates transformed
 	 * relative to the child window.
 	 */
+	gint width, height;
+	
+	gdk_drawable_get_size (GDK_DRAWABLE (window), &width, &height);
+	if ((x < 0) || (x >= width) || (y < 0) || (y >= height)) return NULL;
+	
+	/*g_debug ("Finding window at (%d, %d) in %p", x, y, window);*/
+	
 	while (window) {
+		gint child_x, child_y;
 		GList *c, *children = gdk_window_peek_children (window);
 		GdkWindow *old_window = window;
 		for (c = children; c; c = c->next) {
 			GdkWindow *child = (GdkWindow *)c->data;
-			gint width, height, wx, wy;
+			gint wx, wy;
 			
-			gdk_drawable_get_size (child, &width, &height);
-			gdk_window_get_position (child, &wx, &wy);
+			gdk_window_get_geometry (child, &wx, &wy,
+				&width, &height, NULL);
+			/*g_debug ("Child: %p, (%dx%d+%d,%d)", child,
+				width, height, wx, wy);*/
 			
 			if ((x >= wx) && (x < (wx + width)) &&
 			    (y >= wy) && (y < (wy + height))) {
-				x -= wx; y -= wy;
+				child_x = x - wx; child_y = y - wy;
 				window = child;
-				break;
 			}
 		}
+		/*g_debug ("\\|/");*/
 		if (window == old_window) break;
+		
+		x = child_x;
+		y = child_y;
 	}
 	
-	if (x2) *x2 = x;
-	if (y2) *y2 = y;
+	if (tx) *tx = x;
+	if (ty) *ty = y;
 
+	/*g_debug ("Returning: %p", window);*/
+
 	return window;
 }
 
@@ -337,27 +354,29 @@
 {
 	MokoFingerScrollPrivate *priv = FINGER_SCROLL_PRIVATE (scroll);
 	GTimeVal current;
-		
-	if ((!priv->clicked) || (!priv->enabled) || (event->button != 1))
+	
+	if ((!priv->clicked) || (!priv->enabled) || (event->button != 1) ||
+	    (event->time == priv->last_time))
 		return FALSE;
 
+	priv->last_time = event->time;
 	g_get_current_time (&current);
 
 	priv->clicked = FALSE;
 	if ((!priv->moved) &&
-	    ((current.tv_sec > priv->click_start.tv_sec) ||
-	    (current.tv_usec - priv->click_start.tv_usec > 500))) {
-		GtkAdjustment *hadjust, *vadjust;
+	    (!(current.tv_sec > priv->click_start.tv_sec))/* &&
+	    (!(current.tv_usec - priv->click_start.tv_usec > 500000))*/) {
 		gint x, y;
+		GdkEventCrossing *crossing_event;
 		GdkWindow *child;
 		
-		g_object_get (G_OBJECT (GTK_BIN (priv->align)->child),
-			"hadjustment", &hadjust, "vadjustment", &vadjust, NULL);
-
 		child = moko_finger_scroll_get_topmost (
 			GTK_BIN (priv->align)->child->window,
 			event->x, event->y, &x, &y);
 
+		if ((!child) || (child == GTK_BIN (priv->align)->child->window))
+			return TRUE;
+
 		event->x = x;
 		event->y = y;
 		
@@ -367,15 +386,42 @@
 		priv->vel_x = 0;
 		priv->vel_y = 0;
 
-		/* Send synthetic click event */
-		((GdkEvent *)event)->any.window = g_object_ref (child);
-		((GdkEvent *)event)->type = GDK_BUTTON_PRESS;
+		/* Send synthetic enter event */
+		crossing_event = (GdkEventCrossing *)
+			gdk_event_new (GDK_ENTER_NOTIFY);
+		((GdkEventAny *)crossing_event)->type = GDK_ENTER_NOTIFY;
+		((GdkEventAny *)crossing_event)->window = g_object_ref (child);
+		((GdkEventAny *)crossing_event)->send_event = FALSE;
+		crossing_event->subwindow = g_object_ref (child);
+		crossing_event->time = event->time;
+		crossing_event->x = event->x;
+		crossing_event->y = event->y;
+		crossing_event->x_root = event->x_root;
+		crossing_event->y_root = event->y_root;
+		crossing_event->mode = GDK_CROSSING_NORMAL;
+		crossing_event->detail = GDK_NOTIFY_UNKNOWN;
+		crossing_event->focus = FALSE;
+		crossing_event->state = 0;
+		gdk_event_put ((GdkEvent *)crossing_event);
+		
+		/* Send synthetic click (button press/release) event */
+		((GdkEventAny *)event)->window = g_object_ref (child);
+		((GdkEventAny *)event)->type = GDK_BUTTON_PRESS;
 		gdk_event_put ((GdkEvent *)event);
-		((GdkEvent *)event)->any.window = g_object_ref (child);
-		((GdkEvent *)event)->type = GDK_BUTTON_RELEASE;
+		((GdkEventAny *)event)->window = g_object_ref (child);
+		((GdkEventAny *)event)->type = GDK_BUTTON_RELEASE;
 		gdk_event_put ((GdkEvent *)event);
+		
+		/* Send synthetic leave event */
+		((GdkEventAny *)crossing_event)->type = GDK_LEAVE_NOTIFY;
+		((GdkEventAny *)crossing_event)->window = g_object_ref (child);
+		crossing_event->subwindow = g_object_ref (child);
+		crossing_event->window = g_object_ref (child);
+		crossing_event->detail = GDK_NOTIFY_UNKNOWN;
+		gdk_event_put ((GdkEvent *)crossing_event);
+		gdk_event_free ((GdkEvent *)crossing_event);
 	}
-
+	
 	return TRUE;
 }
 
@@ -536,6 +582,8 @@
 	switch (property_id) {
 	    case PROP_ENABLED :
 		priv->enabled = g_value_get_boolean (value);
+		gtk_event_box_set_above_child (
+			GTK_EVENT_BOX (object), priv->enabled);
 		break;
 	    case PROP_MODE :
 		priv->mode = g_value_get_int (value);
@@ -672,6 +720,7 @@
 	
 	priv->moved = FALSE;
 	priv->clicked = FALSE;
+	priv->last_time = 0;
 	priv->vscroll = TRUE;
 	priv->hscroll = TRUE;
 





More information about the commitlog mailing list