Bug 733605

Summary: changing workspace during SDL_WM_GrabInput leaves SDL client stuck
Product: Red Hat Enterprise Linux 6 Reporter: Petr Pisar <ppisar>
Component: SDLAssignee: Petr Pisar <ppisar>
Status: CLOSED ERRATA QA Contact: Lukáš Zachar <lzachar>
Severity: medium Docs Contact:
Priority: low    
Version: 6.2CC: mrezanin, ovasik, pbonzini, psplicha, xen-maint
Target Milestone: rcKeywords: Patch
Target Release: ---   
Hardware: Unspecified   
OS: Unspecified   
Whiteboard:
Fixed In Version: SDL-1.2.14-3.el6 Doc Type: Bug Fix
Doc Text:
Cause Grabbing mouse input on SDL window that is not visible (e.g. a the window is on different work space or out of screen borders). Consequence The SDL application get stuck until the window becomes visible. Fix SDL_WM_GrabInput() function has been adjusted to not block if X server cannot grab focus because the window is not viewable and it signals failure to the application immediately. Result Application gets failure from SDL library instead of blocking till window becomes visible.
Story Points: ---
Clone Of: 664771 Environment:
Last Closed: 2012-04-03 15:20:37 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Attachments:
Description Flags
Non-interractive test case
none
Proposed patch none

Description Petr Pisar 2011-08-26 08:24:14 UTC
+++ This bug was initially created as a clone of Bug #664771 +++

Created attachment 470009 [details]
test program

Description of problem:
Easily reproducible using Xen's SDL interface (KVM's is probably susceptible as well).  Run this loop in a shell:

    i=0; while sleep 1; do echo $i; i=$((i+1)); done

Change workspace, stay there, go back.  The counter won't advance from the moment you press Ctrl-Alt-Right to the moment you go back to the original workspace and release Ctrl-Alt.

The bug provides a standalone program that demonstrates this bug.

Version-Release number of selected component (if applicable):
SDL-1.2.10-7.el5

How reproducible:
100%

Steps to Reproduce:
1. Compile attached program:
gcc sdl.c `/usr/bin/sdl-config --cflags --libs` -o sdl
2. Run it with >1 workspaces set up.
3. Do Ctrl-Alt-Right and back (making sure Ctrl-Alt are pressed for more than one second)

Actual results:
Counter in the console remains stuck.

Expected results:
Counter in the console proceeds normally.

Additional info:
Patch at attachment 329082 [details] applies.

The bug is also present in RHEL6's libSDL, but SDL mode is not supported by KVM there so it's less severe there.  The bug seems not to be present in upstream SDL 1.3.

--- Additional comment from pbonzini on 2011-02-28 11:00:14 GMT ---

Requesting fasttrack since this blocks a Xen bug (bug 664773).  Petr mentioned offline a worry that the blocking loop may be part of API.  However, I believe that this is true only when grab will succeed.  In the GrabNotViewable case, grab cannot succeed.

SDL 1.3 does not block and does not grab in an even more general case (http://hg.libsdl.org/SDL/file/40c9d744e595/src/video/x11/SDL_x11window.c, search for X11_SetWindowGrab).  Whenever the window is not focused the grab will fail (and it obviously isn't focused if it isn't visible).

--- Additional comment from ppisar on 2011-03-01 14:39:29 GMT ---

src/video/x11/SDL_x11wm.c:X11_GrabInputNoLock() will return SDL_GRAB_OFF, if invalid arguments have been supplied, or if ungrab has been requested.

Otherwise (i.e. grab has been requested) following loop is proceeded:

        for ( ; ; ) {
            result = XGrabPointer(SDL_Display, SDL_Window, True, 0,
                        GrabModeAsync, GrabModeAsync,
                        SDL_Window, None, CurrentTime);
            if ( result == GrabSuccess ) {
                break;
            }
            SDL_Delay(100);
        }

As you can see the function will block until it can grab.

The function is wrapped by X11_GrabInput() that does just a thing: it locks event thread. And public function SDL_WM_GrabInput() (via SDL_WM_GrabInputRaw()) does not check the return value. Also other direct calls inside SDL do not check return value of X11_GrabInputNoLock().

So X11_GrabInputNoLock() return value is directly exported to application, or it's assumed the grab always succeeds.

Underlying X11 function XGrabPointer() can return whole variety of error codes (e.g. AlreadyGrabbed) and SDL does not return on them. So, in my opinion, the loop is intentional and SDL application should expect blocking.

Regarding SDL 1.3: 1.3 branch is incompatible project. You can argue with 1.3 API in 1.2 branch.

You should understand current 1.2 implementation always block and lot of applications can rely on it. Changing behavior in RHEL-5 does not sound well to me.

I will raise a bug to upstream to decide what to do if X11 cannot grab a pointer.

[...]
--- Additional comment from ppisar on 2011-07-20 09:21:49 GMT ---

As you can see from external tracker link, upstream is confident SDL-1.3 will not block, but no resolution about SDL-1.2 has been provided. I will ping upstream again with proposed patch to excite some action.

----
RHEL-6 (SDL-1.2.14-2.el6.x86_64) affected too.

Comment 1 Petr Pisar 2011-08-26 08:28:28 UTC
This is no issue for KVM GUI in RHEL-6 as SDL is not used there. Removing bug
#664773 from list of blocked.

Comment 2 Petr Pisar 2011-08-26 08:29:38 UTC
Created attachment 520031 [details]
Non-interractive test case

Comment 3 Petr Pisar 2011-08-26 08:30:13 UTC
Created attachment 520032 [details]
Proposed patch

Comment 4 Ondrej Vasik 2011-11-03 09:23:36 UTC
Easyfix, proposing for 6.3 fastrack

Comment 5 Petr Pisar 2012-01-02 09:07:58 UTC
Upstream decided not to accept this change into version 1.2 to conserve API.

Comment 9 Petr Pisar 2012-01-10 17:23:31 UTC
    Technical note added. If any revisions are required, please edit the "Technical Notes" field
    accordingly. All revisions will be proofread by the Engineering Content Services team.
    
    New Contents:
Cause
    Grabbing mouse input on SDL window that is not visible
    (e.g. a the window is on different work space or out of
    screen borders).
Consequence
    The SDL application get stuck until the window becomes
    visible. 
Fix
    SDL_WM_GrabInput() function has been adjusted to not block
    if X server cannot grab focus because the window is not
    viewable and it signals failure to the application
    immediately.
Result
    Application gets failure from SDL library instead of
    blocking till window becomes visible.

Comment 11 errata-xmlrpc 2012-04-03 15:20:37 UTC
Since the problem described in this bug report should be
resolved in a recent advisory, it has been closed with a
resolution of ERRATA.

For information on the advisory, and where to find the updated
files, follow the link below.

If the solution does not work for you, open a new bug report.

http://rhn.redhat.com/errata/RHBA-2012-0446.html