Bug 12650

Summary: windows not receiving mouse events when in multiple screen context
Product: xorg Reporter: Dodji Seketeli <dodji>
Component: Server/GeneralAssignee: Xorg Project Team <xorg-team>
Status: RESOLVED FIXED QA Contact: Xorg Project Team <xorg-team>
Severity: normal    
Priority: medium CC: palglowr, peter.hutterer
Version: git   
Hardware: Other   
OS: All   
Whiteboard:
i915 platform: i915 features:
Bug Depends on:    
Bug Blocks: 12042    
Attachments:
Description Flags
this patch hopefully fixes the problem none

Description Dodji Seketeli 2007-10-02 02:48:55 UTC
When the xserver has several pScreen datastructures - each one being connected to a monitor - windows that are on screens which pScreen->myNym > 0 don't receive mouse events. Even calling *WarpCursor() when the mouse has to go from one screen to another.

To reproduce, I used Xephyr. I applied the patch #11853 (attached to bug #12042) to Xephyr from git master. That patch adds multiscreen capabilities to Xephyr.

Then launch Xephyr: hw/kdrive/ephyr/Xephyr :4 -ac -screen 640x480 -screen 320x240 .

This launches Xephyr with two screens. One screen, (with number :4.0) has a geometry of 640x480, and another one (with number :4.1) has a geometry of 320x240.

Launch xeyes two xeyes applications, one on each Xephyr screen:

DISPLAY=:4.0 xeyes &
DISPLAY=:4.1 xeyes &

Try to move the mouse on the second screen. You will notice that the eyes don't move on the second screen.

You can try something similar using the xev application. It is even more explicit.
Comment 1 Dodji Seketeli 2007-10-02 03:04:31 UTC
Created attachment 11854 [details] [review]
this patch hopefully fixes the problem

It seems the problem was due to the mouse sprite "context" not being properly updated when switching from one screen to another. Note that the switch from one screen to another was triggered by a call to miPointerWarpCursor().

So I have added a new function to the DIX layer: UpdateSpriteFromScreen() which basically updates the sprite context. That UpdateSpriteFromScreen() is now called by miPointerWarpCursor().
Comment 2 Dodji Seketeli 2007-10-02 04:59:42 UTC
Okay, I have pushed the patch to the xserver, master branch. The commit is 81692b628f41cb64329f3cccc0503fb216a2b8e3.

So this should close the bug for now.
Comment 3 Shunichi Fuji 2007-10-18 00:39:00 UTC
hi, since this patch apply,
mouse doesn't work anymore in enemy-territory (OpenGL game).
i tracked problem at around GenerateEvent.
are CursorLimits() or ConstrainCursor() or DisplayCursor() function corrent
in UpdateSpriteForScreen when GenerateEvent is true?
pointer move re-actived when apply this "all UpdateSpriteForScreen disabled when GenerateEvent is true patch".
it work xeyes on Xephyr in normal session.

diff --git a/mi/mipointer.c b/mi/mipointer.c
index 24ff4cc..79c9313 100644
--- a/mi/mipointer.c
+++ b/mi/mipointer.c
@@ -261,8 +261,8 @@ miPointerWarpCursor (pScreen, x, y)
        miPointer.x = x;
        miPointer.y = y;
        miPointer.pScreen = pScreen;
+       UpdateSpriteForScreen (pScreen) ;
     }
-    UpdateSpriteForScreen (pScreen) ;
 }
 
 /*
Comment 4 Peter Hutterer 2008-01-15 17:10:30 UTC
(In reply to comment #3)
> hi, since this patch apply,
> mouse doesn't work anymore in enemy-territory (OpenGL game).
> i tracked problem at around GenerateEvent.
> are CursorLimits() or ConstrainCursor() or DisplayCursor() function corrent
> in UpdateSpriteForScreen when GenerateEvent is true?
> pointer move re-actived when apply this "all UpdateSpriteForScreen disabled
> when GenerateEvent is true patch".
> it work xeyes on Xephyr in normal session.
> 
> diff --git a/mi/mipointer.c b/mi/mipointer.c
> index 24ff4cc..79c9313 100644
> --- a/mi/mipointer.c
> +++ b/mi/mipointer.c
> @@ -261,8 +261,8 @@ miPointerWarpCursor (pScreen, x, y)
>         miPointer.x = x;
>         miPointer.y = y;
>         miPointer.pScreen = pScreen;
> +       UpdateSpriteForScreen (pScreen) ;
>      }
> -    UpdateSpriteForScreen (pScreen) ;
>  }
> 
>  /*
> 

I'm pretty sure we need to call USFS even if we generate events. Can you please try the following patch:

diff --git a/mi/mipointer.c b/mi/mipointer.c
index 2c3c689..138e988 100644
--- a/mi/mipointer.c
+++ b/mi/mipointer.c
@@ -232,9 +232,13 @@ miPointerWarpCursor (pScreen, x, y)
     int                x, y;
 {
     SetupScreen (pScreen);
+    BOOL changedScreen = FALSE
 
     if (miPointer.pScreen != pScreen)
+    {
        (*pScreenPriv->screenFuncs->NewEventScreen) (pScreen, TRUE);
+        changedScreen = TRUE;
+    }
 
     if (GenerateEvent)
     {
@@ -255,7 +259,9 @@ miPointerWarpCursor (pScreen, x, y)
        miPointer.y = y;
        miPointer.pScreen = pScreen;
     }
-    UpdateSpriteForScreen (pScreen) ;
+
+    if (changedScreen)
+        UpdateSpriteForScreen (pScreen) ;
 }
 
 /*
Comment 5 Shunichi Fuji 2008-02-03 19:48:26 UTC
thx.
I confirmed that it get back my mouse moving.
Comment 6 Peter Hutterer 2008-02-05 00:49:45 UTC
Pushed as 521a7f26e088029707fb9a2bb80c9ddc734a3f8b.

Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.