SDL icon indicating copy to clipboard operation
SDL copied to clipboard

Can't receive WM_MOUSEWHEEL on windows7 sp1

Open sandsc opened this issue 2 years ago • 2 comments

Creating a sdl window with avaloniaui NativeControlHost, and embed this control in avalonia parent control, found that WM_MOUSEWHEEL can't receive when mouse wheel is rotated on mouse device, however, strangely WM_MOUSEWHEEL can still received when use laptop's touch pad. But on Windows 10, everything works fine。 MSDN docs on WM_MOUSEWHEEL:

Sent to the focus window when the mouse wheel is rotated. The DefWindowProc function propagates the message to the window's parent. There should be no internal forwarding of the message, since DefWindowProc propagates it up the parent chain until it finds a window that processes it.

So I add following code to set focus when mouse click on window, then WM_MOUSEWHEEL generated either by touchpad or mouse device can be receive correctly.

 case WM_RBUTTONUP:
 case WM_MBUTTONUP:
 case WM_XBUTTONUP:
 case WM_LBUTTONDOWN:
 case WM_LBUTTONDBLCLK:
 case WM_RBUTTONDOWN:
 case WM_RBUTTONDBLCLK:
 case WM_MBUTTONDOWN:
 case WM_MBUTTONDBLCLK:
 case WM_XBUTTONDOWN:
 case WM_XBUTTONDBLCLK:

 {
     if (!IsWindows10OrGreater()) {
         SetFocus(data->hwnd);
     }
     SDL_Mouse *mouse = SDL_GetMouse();
     if (!mouse->relative_mode || mouse->relative_mode_warp) {
         if (GetMouseMessageSource() != SDL_MOUSE_EVENT_SOURCE_TOUCH &&
             lParam != data->last_pointer_update) {
             WIN_CheckWParamMouseButtons(wParam, data, 0);
         }
     }
 } break;

I'm not sure if this is a bug or if I'm using it the wrong way.

sandsc avatar Dec 20 '23 10:12 sandsc

Does this fix anything?

diff --git a/src/video/windows/SDL_windowsevents.c b/src/video/windows/SDL_windowsevents.c
index 89e05cd50..05f65ccdf 100644
--- a/src/video/windows/SDL_windowsevents.c
+++ b/src/video/windows/SDL_windowsevents.c
@@ -620,6 +620,7 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
                 SDL_SendMouseMotion(WIN_GetEventTimestamp(), data->window, 0, 0, (float)GET_X_LPARAM(lParam), (float)GET_Y_LPARAM(lParam));
             }
         }
+        returnCode = 0;
     } break;

     case WM_LBUTTONUP:
@@ -642,6 +643,7 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
                 WIN_CheckWParamMouseButtons(wParam, data, 0);
             }
         }
+        returnCode = 0;
     } break;

     case WM_INPUT:
@@ -766,6 +768,7 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
         } else {
             SDL_SendMouseWheel(WIN_GetEventTimestamp(), data->window, 0, fAmount, 0.0f, SDL_MOUSEWHEEL_NORMAL);
         }
+        returnCode = 0;
     } break;

     case WM_MOUSELEAVE:

slouken avatar Dec 24 '23 15:12 slouken

We're releasing SDL 2.30 soon and haven't heard back, so I'm going ahead and moving this to the next milestone.

slouken avatar Jan 06 '24 14:01 slouken

This bug is reappeared on latest commit, still need to add following code to gets MouseWheel event on Windows7.

 case WM_LBUTTONUP:
  case WM_RBUTTONUP:
  case WM_MBUTTONUP:
  case WM_XBUTTONUP:
  case WM_LBUTTONDOWN:
  case WM_LBUTTONDBLCLK:
  case WM_RBUTTONDOWN:
  case WM_RBUTTONDBLCLK:
  case WM_MBUTTONDOWN:
  case WM_MBUTTONDBLCLK:
  case WM_XBUTTONDOWN:
  case WM_XBUTTONDBLCLK:
  {
      if (!IsWindows10OrGreater()) {
          SetFocus(data->hwnd);
      }
      /* SDL_Mouse *mouse = SDL_GetMouse(); */
      if (!data->videodata->raw_mouse_enabled) {
          if (GetMouseMessageSource((ULONG)GetMessageExtraInfo()) != SDL_MOUSE_EVENT_SOURCE_TOUCH &&
              lParam != data->last_pointer_update) {
              WIN_CheckWParamMouseButtons(WIN_GetEventTimestamp(), wParam, data, SDL_GLOBAL_MOUSE_ID);
          }
      }
  } break;

sandsc avatar Jul 31 '24 02:07 sandsc

I'm wondering if this is an issue with the embedded control rather than SDL?

Can you reproduce this with testwm --info event?

slouken avatar Jul 31 '24 04:07 slouken

I'm wondering if this is an issue with the embedded control rather than SDL?

Can you reproduce this with testwm --info event?

Yes, you are right, I add follow code in testwm’s event loop.

   if (event.type == SDL_EVENT_MOUSE_WHEEL) {
       SDL_Window *window = SDL_GetMouseFocus();
       if (window) {
           SDL_Log("Window %u, mouse wheel move, x: %f,y: %f\n",
                   SDL_GetWindowID(window),
                   event.wheel.x,
                   event.wheel.y);
       }
   }

When I scroll mouse wheel, I can get mouse wheel events on windows 7.
image

btw, I found an new bug while I was testing with testwm app, when I toggled full screen with ctrl+enter, the app crashed for access violation. image image

sandsc avatar Aug 05 '24 08:08 sandsc

I'm wondering if this is an issue with the embedded control rather than SDL? Can you reproduce this with testwm --info event?

Yes, you are right, I add follow code in testwm’s event loop. ... When I scroll mouse wheel, I can get mouse wheel events on windows 7.

Maybe you just need to give the SDL window focus when the hosting control gains focus?

btw, I found an new bug while I was testing with testwm app, when I toggled full screen with ctrl+enter, the app crashed for access violation.

Can you update to the latest SDL code? I believe this is already fixed. Line 1145 is now SDL_UpdateFullscreenDisplayModes()

slouken avatar Aug 05 '24 12:08 slouken

Maybe you just need to give the SDL window focus when the hosting control gains focus?

I'm wondering why it doesn't work only on windows7? There may be some platform differences in the mechanism about control getting focus.

Can you update to the latest SDL code? I believe this is already fixed. Line 1145 is now SDL_UpdateFullscreenDisplayModes()

And yes, this is already fixed on latest code.

I'm now manually setting the control focus on the windows7 platform to fix this, thanks for the reply, I'll close this issue for now.

sandsc avatar Aug 06 '24 01:08 sandsc