Send mouse leave updates for Windows and X11.
authorJørgen P. Tjernø
Mon, 22 Apr 2013 18:14:55 -0700
changeset 7089257fc4e541e1
parent 7088 664d8532219b
child 7090 c4ac8be0065b
Send mouse leave updates for Windows and X11.

We now generate a final SDL_MOUSEMOTION before the cursor leaves the
window, followed by a SDL_WINDOWEVENT_LEAVE.
src/events/SDL_mouse.c
src/events/SDL_windowevents.c
src/video/SDL_sysvideo.h
src/video/SDL_video.c
src/video/windows/SDL_windowsevents.c
src/video/windows/SDL_windowsvideo.c
src/video/windows/SDL_windowswindow.c
src/video/windows/SDL_windowswindow.h
src/video/x11/SDL_x11events.c
     1.1 --- a/src/events/SDL_mouse.c	Mon Apr 22 18:14:32 2013 -0700
     1.2 +++ b/src/events/SDL_mouse.c	Mon Apr 22 18:14:55 2013 -0700
     1.3 @@ -33,6 +33,8 @@
     1.4  /* The mouse state */
     1.5  static SDL_Mouse SDL_mouse;
     1.6  
     1.7 +static int
     1.8 +SDL_PrivateSendMouseMotion(SDL_Window * window, SDL_MouseID mouseID, int relative, int x, int y);
     1.9  
    1.10  /* Public functions */
    1.11  int
    1.12 @@ -154,8 +156,9 @@
    1.13  #endif
    1.14          if (window == mouse->focus) {
    1.15  #ifdef DEBUG_MOUSE
    1.16 -            printf("Mouse left window, synthesizing focus lost event\n");
    1.17 +            printf("Mouse left window, synthesizing move & focus lost event\n");
    1.18  #endif
    1.19 +            SDL_PrivateSendMouseMotion(window, mouse->mouseID, 0, x, y);
    1.20              SDL_SetMouseFocus(NULL);
    1.21          }
    1.22          return SDL_FALSE;
    1.23 @@ -176,18 +179,25 @@
    1.24  int
    1.25  SDL_SendMouseMotion(SDL_Window * window, SDL_MouseID mouseID, int relative, int x, int y)
    1.26  {
    1.27 +    if (window && !relative) {
    1.28 +        SDL_Mouse *mouse = SDL_GetMouse();
    1.29 +        if (!SDL_UpdateMouseFocus(window, x, y, mouse->buttonstate)) {
    1.30 +            return 0;
    1.31 +        }
    1.32 +    }
    1.33 +
    1.34 +    return SDL_PrivateSendMouseMotion(window, mouseID, relative, x, y);
    1.35 +}
    1.36 +
    1.37 +static int
    1.38 +SDL_PrivateSendMouseMotion(SDL_Window * window, SDL_MouseID mouseID, int relative, int x, int y)
    1.39 +{
    1.40      SDL_Mouse *mouse = SDL_GetMouse();
    1.41      int posted;
    1.42      int xrel;
    1.43      int yrel;
    1.44      int x_max = 0, y_max = 0;
    1.45  
    1.46 -    if (window && !relative) {
    1.47 -        if (!SDL_UpdateMouseFocus(window, x, y, mouse->buttonstate)) {
    1.48 -            return 0;
    1.49 -        }
    1.50 -    }
    1.51 -
    1.52      /* relative motion is calculated regarding the system cursor last position */
    1.53      if (relative) {
    1.54          xrel = x;
    1.55 @@ -676,4 +686,4 @@
    1.56      return shown;
    1.57  }
    1.58  
    1.59 -/* vi: set ts=4 sw=4 expandtab: */
    1.60 +/* vi: set ts=4 sw=4 expandtab: */
    1.61 \ No newline at end of file
     2.1 --- a/src/events/SDL_windowevents.c	Mon Apr 22 18:14:32 2013 -0700
     2.2 +++ b/src/events/SDL_windowevents.c	Mon Apr 22 18:14:55 2013 -0700
     2.3 @@ -148,12 +148,14 @@
     2.4              return 0;
     2.5          }
     2.6          window->flags |= SDL_WINDOW_MOUSE_FOCUS;
     2.7 +        SDL_OnWindowEnter(window);
     2.8          break;
     2.9      case SDL_WINDOWEVENT_LEAVE:
    2.10          if (!(window->flags & SDL_WINDOW_MOUSE_FOCUS)) {
    2.11              return 0;
    2.12          }
    2.13          window->flags &= ~SDL_WINDOW_MOUSE_FOCUS;
    2.14 +		SDL_OnWindowLeave(window);
    2.15          break;
    2.16      case SDL_WINDOWEVENT_FOCUS_GAINED:
    2.17          if (window->flags & SDL_WINDOW_INPUT_FOCUS) {
     3.1 --- a/src/video/SDL_sysvideo.h	Mon Apr 22 18:14:32 2013 -0700
     3.2 +++ b/src/video/SDL_sysvideo.h	Mon Apr 22 18:14:55 2013 -0700
     3.3 @@ -201,6 +201,7 @@
     3.4      int (*CreateWindowFramebuffer) (_THIS, SDL_Window * window, Uint32 * format, void ** pixels, int *pitch);
     3.5      int (*UpdateWindowFramebuffer) (_THIS, SDL_Window * window, const SDL_Rect * rects, int numrects);
     3.6      void (*DestroyWindowFramebuffer) (_THIS, SDL_Window * window);
     3.7 +    void (*OnWindowEnter) (_THIS, SDL_Window * window);
     3.8  
     3.9      /* * * */
    3.10      /*
    3.11 @@ -367,6 +368,8 @@
    3.12  extern void SDL_OnWindowResized(SDL_Window * window);
    3.13  extern void SDL_OnWindowMinimized(SDL_Window * window);
    3.14  extern void SDL_OnWindowRestored(SDL_Window * window);
    3.15 +extern void SDL_OnWindowEnter(SDL_Window * window);
    3.16 +extern void SDL_OnWindowLeave(SDL_Window * window);
    3.17  extern void SDL_OnWindowFocusGained(SDL_Window * window);
    3.18  extern void SDL_OnWindowFocusLost(SDL_Window * window);
    3.19  extern void SDL_UpdateWindowGrab(SDL_Window * window);
     4.1 --- a/src/video/SDL_video.c	Mon Apr 22 18:14:32 2013 -0700
     4.2 +++ b/src/video/SDL_video.c	Mon Apr 22 18:14:55 2013 -0700
     4.3 @@ -2029,6 +2029,19 @@
     4.4  }
     4.5  
     4.6  void
     4.7 +SDL_OnWindowEnter(SDL_Window * window)
     4.8 +{
     4.9 +    if (_this->OnWindowEnter) {
    4.10 +        _this->OnWindowEnter(_this, window);
    4.11 +    }
    4.12 +}
    4.13 +
    4.14 +void
    4.15 +SDL_OnWindowLeave(SDL_Window * window)
    4.16 +{
    4.17 +}
    4.18 +
    4.19 +void
    4.20  SDL_OnWindowFocusGained(SDL_Window * window)
    4.21  {
    4.22      if (window->gamma && _this->SetWindowGammaRamp) {
     5.1 --- a/src/video/windows/SDL_windowsevents.c	Mon Apr 22 18:14:32 2013 -0700
     5.2 +++ b/src/video/windows/SDL_windowsevents.c	Mon Apr 22 18:14:55 2013 -0700
     5.3 @@ -445,10 +445,16 @@
     5.4          }
     5.5  
     5.6  #ifdef WM_MOUSELEAVE
     5.7 -    /* FIXME: Do we need the SDL 1.2 hack to generate WM_MOUSELEAVE now? */
     5.8      case WM_MOUSELEAVE:
     5.9          if (SDL_GetMouseFocus() == data->window) {
    5.10 -            SDL_SetMouseFocus(NULL);
    5.11 +			if (!SDL_GetMouse()->relative_mode) {
    5.12 +				POINT cursorPos;
    5.13 +				GetCursorPos(&cursorPos);
    5.14 +				ScreenToClient(hwnd, &cursorPos);
    5.15 +				SDL_SendMouseMotion(data->window, 0, 0, cursorPos.x, cursorPos.y);
    5.16 +			}
    5.17 +
    5.18 +			SDL_SetMouseFocus(NULL);
    5.19          }
    5.20          returnCode = 0;
    5.21          break;
     6.1 --- a/src/video/windows/SDL_windowsvideo.c	Mon Apr 22 18:14:32 2013 -0700
     6.2 +++ b/src/video/windows/SDL_windowsvideo.c	Mon Apr 22 18:14:55 2013 -0700
     6.3 @@ -121,6 +121,7 @@
     6.4      device->CreateWindowFramebuffer = WIN_CreateWindowFramebuffer;
     6.5      device->UpdateWindowFramebuffer = WIN_UpdateWindowFramebuffer;
     6.6      device->DestroyWindowFramebuffer = WIN_DestroyWindowFramebuffer;
     6.7 +    device->OnWindowEnter = WIN_OnWindowEnter;
     6.8      
     6.9      device->shape_driver.CreateShaper = Win32_CreateShaper;
    6.10      device->shape_driver.SetWindowShape = Win32_SetWindowShape;
     7.1 --- a/src/video/windows/SDL_windowswindow.c	Mon Apr 22 18:14:32 2013 -0700
     7.2 +++ b/src/video/windows/SDL_windowswindow.c	Mon Apr 22 18:14:55 2013 -0700
     7.3 @@ -678,6 +678,25 @@
     7.4      }
     7.5  }
     7.6  
     7.7 +void WIN_OnWindowEnter(_THIS, SDL_Window * window)
     7.8 +{
     7.9 +#ifdef WM_MOUSELEAVE
    7.10 +    SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
    7.11 +    TRACKMOUSEEVENT trackMouseEvent;
    7.12 +
    7.13 +    if (!data || !data->hwnd) {
    7.14 +        /* The window wasn't fully initialized */
    7.15 +        return;
    7.16 +    }
    7.17 +
    7.18 +    trackMouseEvent.cbSize = sizeof(TRACKMOUSEEVENT);
    7.19 +    trackMouseEvent.dwFlags = TME_LEAVE;
    7.20 +    trackMouseEvent.hwndTrack = data->hwnd;
    7.21 +
    7.22 +    TrackMouseEvent(&trackMouseEvent);
    7.23 +#endif /* WM_MOUSELEAVE */
    7.24 +}
    7.25 +
    7.26  #endif /* SDL_VIDEO_DRIVER_WINDOWS */
    7.27  
    7.28  /* vi: set ts=4 sw=4 expandtab: */
     8.1 --- a/src/video/windows/SDL_windowswindow.h	Mon Apr 22 18:14:32 2013 -0700
     8.2 +++ b/src/video/windows/SDL_windowswindow.h	Mon Apr 22 18:14:55 2013 -0700
     8.3 @@ -56,6 +56,7 @@
     8.4  extern void WIN_DestroyWindow(_THIS, SDL_Window * window);
     8.5  extern SDL_bool WIN_GetWindowWMInfo(_THIS, SDL_Window * window,
     8.6                                      struct SDL_SysWMinfo *info);
     8.7 +extern void WIN_OnWindowEnter(_THIS, SDL_Window * window);
     8.8  
     8.9  #endif /* _SDL_windowswindow_h */
    8.10  
     9.1 --- a/src/video/x11/SDL_x11events.c	Mon Apr 22 18:14:32 2013 -0700
     9.2 +++ b/src/video/x11/SDL_x11events.c	Mon Apr 22 18:14:55 2013 -0700
     9.3 @@ -324,6 +324,10 @@
     9.4              if (xevent.xcrossing.mode == NotifyUngrab)
     9.5                  printf("Mode: NotifyUngrab\n");
     9.6  #endif
     9.7 +            if (!SDL_GetMouse()->relative_mode) {
     9.8 +                SDL_SendMouseMotion(data->window, 0, 0, xevent.xcrossing.x, xevent.xcrossing.y);
     9.9 +            }
    9.10 +
    9.11              if (xevent.xcrossing.mode != NotifyGrab &&
    9.12                  xevent.xcrossing.mode != NotifyUngrab &&
    9.13                  xevent.xcrossing.detail != NotifyInferior) {