Problems with querying the pointer



Just discovered a problem with our functions to query the pointer. 
(When working on fixing http://bugzilla.gnome.org/show_bug.cgi?id=85672)

We have:

===
GdkWindow*    gdk_window_at_pointer      (gint          *win_x,
                                          gint          *win_y);
GdkWindow *  gdk_screen_get_window_at_pointer (GdkScreen   *screen,
					       gint        *win_x,
					       gint        *win_y);
GdkWindow*    gdk_window_get_pointer	 (GdkWindow	  *window,
					  gint		  *x,
					  gint		  *y,
					  GdkModifierType *mask);
===

These can be hooked (for event recording purposes) with:

===
struct _GdkPointerHooks 
{
  GdkWindow* (*get_pointer)       (GdkWindow	   *window,
			           gint	           *x,
			           gint   	   *y,
			           GdkModifierType *mask);
  GdkWindow* (*window_at_pointer) (GdkScreen       *screen,
                                   gint            *win_x,
                                   gint            *win_y);
};


GdkPointerHooks *gdk_set_pointer_hooks (const GdkPointerHooks *new_hooks);   
===

All of the API above except for gdk_screen_get_window_at_pointer() is
in GTK+-2.0, so can't be changed. (The GdkScreen parameter in 
GdkPointerHooks was a dummy typedef.)

Now the problem here is that the pointer is per-display, not per-screen.

for ->window_at_pointer(), there is a pretty simple workaround - we can
interpret the GdkScreen parameter as just one representative screen
on the display. (*)

->get_pointer() is more of a mess. The corresponding X interface
is:

       Bool XQueryPointer(display, w, root_return, child_return,
       root_x_return, root_y_return,
                            win_x_return, win_y_return, mask_return)
             Display *display;
             Window w;
             Window *root_return, *child_return;
             int *root_x_return, *root_y_return;
             int *win_x_return, *win_y_return;
             unsigned int *mask_return;

So includes a root_return parameter, but with the (*get_pointer)
API, there is no indication that the pointer was on a different
screen.

I frankly don't see any remotely reasonable way to fix this, so
I think what we need to do is just say that 
gdk_window_set_pointer_hooks() is a non-multihead safe API, and
augment it with a new multihead-aware API. My proposal for this
is:
 
struct _GdkDisplayPointerHooks 
{
  void (*get_pointer)              (GdkDisplay	    *display,
                                    GdkWindow      **root_window,
			            gint	    *x,
			            gint   	    *y,
			            GdkModifierType *mask);
  GdkWindow* (*window_get_pointer) (GdkDisplay      *display,
                                    GdkWindow	    *window,
			            gint	    *x,
			            gint   	    *y,
			            GdkModifierType *mask);
  GdkWindow* (*window_at_pointer)  (GdkDisplay      *display,
                                    gint            *win_x,
                                    gint            *win_y);
};

GdkPointerHooks *gdk_display_set_pointer_hooks (GdkDisplay            *display,
                                                const GdkPointerHooks *new_hooks);
void             gdk_display_get_pointer     (GdkDisplay      *display,
                                              GdkWindow      **root_window,
        			              gint	      *x,
        			              gint 	      *y,
			                      GdkModifierType *mask);
GdkWindow *      gdk_display_get_window_at_pointer (GdkDisplay      *display,
        			                    gint	    *win_x,
        			                    gint 	    *win_y);

And remove gdk_screen_get_window_at_pointer().

gdk_set_pointer_hooks() would set the GdkDisplayPointerHooks for the default 
display to a thunk set of pointer hooks that would work for the single-screen,
single-display case.

Regards,
                                        Owen

(*) The question would remain whether we should:

  a) Change gdk_screen_get_window_at_Pointer() to 
     gdk_display_get_window_at_pointer(), and leave a mismatch
     between this and GdkPointerHooks.

  b) Keep the match and expose the oddity
     (gdk_screen_get_window_at_pointer() can return a window
     on a different screen) in a more common API.
  
    It would still be messy.



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