← Back to team overview

unity-design team mailing list archive

Re: New notification placement

 

Am Freitag, den 28.08.2009, 11:14 +0200 schrieb David Barth:
> Mark Shuttleworth wrote: 
> > Mirco Müller wrote:
> >   
> > > Am Freitag, den 28.08.2009, 09:30 +0100 schrieb Mark Shuttleworth:
> > > 
> > >   
> > >     
> > > > ...
> > > > Mirco, is there any way to know, when the notification appears, how
> > > > long the mouse has been stationary?
> > > >     
> > > >       
> > > 	Yes, that should be doable. I'll give that a try today and let you
> > > folks know about the outcome.
> > >   
> > >     
> > OK, just let us know if it's *possible*.

Well, it is possible :)

> >  I'm thinking that we might
> > leave the fade if the mouse has moved in the past 5 seconds on the basis
> > that your eye is likely to be tracking the mouse. But if the mouse has
> > been still, we wouldn't fade because you just left the mouse there from
> > previous work.
> > 
> > This would be pretty fragile to small accidental nudges of the mouse,

	It would not need to be "fragile" in this regard. We could introduce a
movement-threshold or delta, which, if stayed within, won't make a
movement count as "real" mouse movement.

	What that delta/threshold should be is another question of course and
probably not that easy to answer, as people have different
mouse-acceleration settings, movement- or "jerking"-habits.

> >  so
> > I don't think we should implement it yet, but I'd like to know how much
> > we can cheaply determine about the mouse's behaviour in the past few
> > seconds. I do *not* want notify-osd to be eating CPU cycles watching the
> > mouse all the time, though :-)

	Like David wrote, we have a mouse-pointer monitor in notify-osd
already, because we need that in order to be able to do the
proximity-fade. To that we can easily add a "last 5 second
activity"-watcher.

> Currently, we're adding a cursor monitoring callback once a
> notification is on display, but that's polling. It's acceptable to
> finely track what the user is doing for fading, blurring, etc. But not
> as general mechanism.
> 
> However, using the XScreenSaver extension, the X server is maintaining
> this information for us, so that we can track the idle time, without
> doing any polling, in particular when no notification is on display.

	Using this does not gain (or save) us anything (in terms of
CPU-cycles... not that our current monitor is very costly), since we
have to do the mouse-pointer monitoring anyway already for
proximity-fade. To our current mouse-motion monitor we can easily add a
"last 5 second activity"-watcher.

	It's so easy that I already have a working patch for this. Not super
nice yet, but proof enough that it's a possibility for us, should we
decide to pursue that path (see attachment).

Best regards ...

Mirco
=== modified file 'src/bubble.c'
--- src/bubble.c	2009-08-26 11:17:55 +0000
+++ src/bubble.c	2009-08-28 09:37:23 +0000
@@ -95,6 +95,11 @@
 	guint            timeout;
 	guint            urgency;
 	//notification_t* notification;
+
+	gint		 last_abs_x;
+	gint		 last_abs_y;
+	GTimeVal         last_abs_timestamp;
+	gboolean         changed;
 };
 
 enum
@@ -1857,6 +1862,8 @@
 	gint           height;
 	GtkWidget*     window;
 	BubblePrivate* priv;
+	GTimeVal       timestamp;
+	gboolean       changed;
 
 	if (!bubble)
 		return FALSE;
@@ -1879,6 +1886,36 @@
 		gtk_window_get_position (GTK_WINDOW (window), &win_x, &win_y);
 		pointer_abs_x = win_x + pointer_rel_x;
 		pointer_abs_y = win_y + pointer_rel_y;
+
+		g_get_current_time (&timestamp);
+		if (timestamp.tv_sec - priv->last_abs_timestamp.tv_sec >= 5)
+		{
+			priv->last_abs_timestamp.tv_sec = timestamp.tv_sec;
+			priv->last_abs_timestamp.tv_usec = timestamp.tv_usec;
+			if (priv->changed)
+				g_print ("--- mouse moved in the last 5 sec. ---\n");
+			else
+				g_print ("--- mouse stood still in the last 5 sec. ---\n");
+
+			priv->changed = FALSE;
+		}
+
+		changed = FALSE;
+		if (priv->last_abs_x != pointer_abs_x)
+		{
+			priv->last_abs_x = pointer_abs_x;
+			changed = TRUE;
+		}
+
+		if (priv->last_abs_y != pointer_abs_y)
+		{
+			priv->last_abs_y = pointer_abs_y;
+			changed = TRUE;
+		}
+
+		if (changed)
+			priv->changed = TRUE;
+
 		gtk_window_get_size (GTK_WINDOW (window), &width, &height);
 		if (pointer_abs_x >= win_x &&
 		    pointer_abs_x <= win_x + width &&
@@ -2163,6 +2200,10 @@
 	Bubble*        this   = NULL;
 	GtkWidget*     window = NULL;
 	BubblePrivate* priv;
+	gint           pointer_rel_x;
+	gint           pointer_rel_y;
+	gint           win_x;
+	gint           win_y;
 
 	this = g_object_new (BUBBLE_TYPE, NULL);
 	if (!this)
@@ -2253,6 +2294,13 @@
 	this->priv->prevent_fade         = FALSE;
 	this->priv->placement		 = PLACEMENT_NEW;
 
+	gtk_widget_get_pointer (window, &pointer_rel_x, &pointer_rel_y);
+	gtk_window_get_position (GTK_WINDOW (window), &win_x, &win_y);
+	this->priv->last_abs_x           = win_x + pointer_rel_x;
+	this->priv->last_abs_y           = win_y + pointer_rel_y;
+	g_get_current_time (&this->priv->last_abs_timestamp);
+	this->priv->changed              = FALSE;
+
 	update_input_shape (window, 1, 1);
 
 	return this;


Follow ups

References