[PATCH] Handle GrabNotViewable return from XGrabPointer()

Hi,

XGrabPointer() can fail with GrabNotViewable if the window being gabbed
is offscreen.

An example of this is that QEMU grabs its window if you press Ctrl-Alt.

Ctrl-Alt- is a common shortcut for changing workspace, so if you
do Ctrl-Alt- the window manager switches workspace, the window
becomes unviewable and then QEMU tries to do SDL_WM_GrabInput().

The current code blocks in this case:

/* Try to grab the mouse */
for (;:wink: {
int result =
XGrabPointer(display, data->window, True, 0, GrabModeAsync,
GrabModeAsync, data->window, None, CurrentTime);
if (result == GrabSuccess) {
break;
}
SDL_Delay(100);
}

This causes the QEMU process to block, which means that if you’re
running a background task in your QEMU guest and you switch workspaces,
the task stops and when you switch back to that workspace you find it
hasn’t made any progress.

SDL should allow grabs to fail rather than blocking the calling app. The
patch against SDL-1.2 below does that. I’m happy to re-work this for
SDL-1.3 if people agree, it will just take a little more work because
SetWindowGrab() doesn’t return a status code.

Some more background here:

https://bugzilla.redhat.com/480065

Thanks,
Mark.

diff -up ./src/video/x11/SDL_x11wm.c.grab-not-viewable ./src/video/x11/SDL_x11wm.c
— ./src/video/x11/SDL_x11wm.c.grab-not-viewable 2007-12-31 04:48:13.000000000 +0000
+++ ./src/video/x11/SDL_x11wm.c 2009-01-15 10:27:14.000000000 +0000
@@ -351,13 +351,14 @@ SDL_GrabMode X11_GrabInputNoLock(_THIS,
result = XGrabPointer(SDL_Display, SDL_Window, True, 0,
GrabModeAsync, GrabModeAsync,
SDL_Window, None, CurrentTime);

  •   	if ( result == GrabSuccess ) {
    
  •   	if ( result == GrabSuccess || result == GrabNotViewable ) {
      		break;
      	}
      	SDL_Delay(100);
      }
      if ( result != GrabSuccess ) {
      	/* Uh, oh, what do we do here? */ ;
    
  •   	return(SDL_GRAB_OFF);
      }
      /* Now grab the keyboard */
      XGrabKeyboard(SDL_Display, WMwindow, True,

hi,

please make sure you’ve submitted this to bugzilla as well…
http://bugzilla.libsdl.org/On Thu, Jan 29, 2009 at 2:19 AM, Mark McLoughlin wrote:

Hi,

XGrabPointer() can fail with GrabNotViewable if the window being gabbed
is offscreen.

An example of this is that QEMU grabs its window if you press Ctrl-Alt.

Ctrl-Alt- is a common shortcut for changing workspace, so if you
do Ctrl-Alt- the window manager switches workspace, the window
becomes unviewable and then QEMU tries to do SDL_WM_GrabInput().

The current code blocks in this case:

/* Try to grab the mouse */
for (;:wink: {
int result =
XGrabPointer(display, data->window, True, 0, GrabModeAsync,
GrabModeAsync, data->window, None, CurrentTime);
if (result == GrabSuccess) {
break;
}
SDL_Delay(100);
}

This causes the QEMU process to block, which means that if you’re
running a background task in your QEMU guest and you switch workspaces,
the task stops and when you switch back to that workspace you find it
hasn’t made any progress.

SDL should allow grabs to fail rather than blocking the calling app. The
patch against SDL-1.2 below does that. I’m happy to re-work this for
SDL-1.3 if people agree, it will just take a little more work because
SetWindowGrab() doesn’t return a status code.

Some more background here:

https://bugzilla.redhat.com/480065

Thanks,
Mark.

diff -up ./src/video/x11/SDL_x11wm.c.grab-not-viewable ./src/video/x11/SDL_x11wm.c
— ./src/video/x11/SDL_x11wm.c.grab-not-viewable 2007-12-31 04:48:13.000000000 +0000
+++ ./src/video/x11/SDL_x11wm.c 2009-01-15 10:27:14.000000000 +0000
@@ -351,13 +351,14 @@ SDL_GrabMode X11_GrabInputNoLock(_THIS,
result = XGrabPointer(SDL_Display, SDL_Window, True, 0,
GrabModeAsync, GrabModeAsync,
SDL_Window, None, CurrentTime);

  •                   if ( result == GrabSuccess ) {
    
  •                   if ( result == GrabSuccess || result == GrabNotViewable ) {
                             break;
                     }
                     SDL_Delay(100);
             }
             if ( result != GrabSuccess ) {
                     /* Uh, oh, what do we do here? */ ;
    
  •                   return(SDL_GRAB_OFF);
             }
             /* Now grab the keyboard */
             XGrabKeyboard(SDL_Display, WMwindow, True,
    

SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org