Flutter-desktop-embedding: Windows HSCURSOR not staying updated

Created on 10 Jan 2020  Â·  11Comments  Â·  Source: google/flutter-desktop-embedding

I created the window_utils plugin and there is an issue when updating the windows cursor. I can change the cursor but it is instantly reset by the application but you can see the correct cursor flash for a second. MacOS works fine. Other calls on the plugin work great on windows too.

https://github.com/rive-app/window-utils/issues/8

I am calling the correct code in C++ but I was curious if I was missing something about the runner in win32_window.cc and if there is an explicit cursor that always override the default one.

WNDCLASS Win32Window::RegisterWindowClass()
{
  WNDCLASS window_class{};
  window_class.hCursor = LoadCursor(nullptr, IDC_ARROW);

When the window is first created it does set a cursor.

At runtime you should be able to change it though.

Anywhere I should be looking?

os-windows

Most helpful comment

(Unrelated to this issue: it's great to see people experimenting with plugins on other platforms, and please do keep filing feedback. I am curious though why your plugin is duplicating functionality from window_size; if there were problems with that plugin that made it unusable for you, please let me know.)

All 11 comments

Here is the method call in C++

else if (method.compare("setCursor") == 0)
  {
    const flutter::EncodableValue *args = method_call.arguments();
    const flutter::EncodableMap &map = args->MapValue();
    bool update = map.at(flutter::EncodableValue("update")).BoolValue();
    std::string type = map.at(flutter::EncodableValue("type")).StringValue();
    HCURSOR cursor;
    if (type.compare("appStart") == 0)
    {
      cursor = LoadCursor(0, IDC_APPSTARTING);
    }
    else if (type.compare("arrow") == 0)
    {
      cursor = LoadCursor(0, IDC_ARROW);
    }
    else if (type.compare("cross") == 0)
    {
      cursor = LoadCursor(0, IDC_CROSS);
    }
    else if (type.compare("hand") == 0)
    {
      cursor = LoadCursor(0, IDC_HAND);
    }
    else if (type.compare("help") == 0)
    {
      cursor = LoadCursor(0, IDC_HELP);
    }
    else if (type.compare("iBeam") == 0)
    {
      cursor = LoadCursor(0, IDC_IBEAM);
    }
    else if (type.compare("no") == 0)
    {
      cursor = LoadCursor(0, IDC_NO);
    }
    else if (type.compare("resizeAll") == 0)
    {
      cursor = LoadCursor(0, IDC_SIZEALL);
    }
    else if (type.compare("resizeNESW") == 0)
    {
      cursor = LoadCursor(0, IDC_SIZENESW);
    }
    else if (type.compare("resizeNS") == 0)
    {
      cursor = LoadCursor(0, IDC_SIZENS);
    }
    else if (type.compare("resizeNWSE") == 0)
    {
      cursor = LoadCursor(0, IDC_SIZENWSE);
    }
    else if (type.compare("resizeWE") == 0)
    {
      cursor = LoadCursor(0, IDC_SIZEWE);
    }
    else if (type.compare("upArrow") == 0)
    {
      cursor = LoadCursor(0, IDC_UPARROW);
    }
    else if (type.compare("wait") == 0)
    {
      cursor = LoadCursor(0, IDC_WAIT);
    }
    else
    {
      cursor = LoadCursor(0, IDC_ARROW);
    }
    SetCursor(cursor);
    flutter::EncodableValue response(true);
    result->Success(&response);
  }

Got it to work:

Win32Window::MessageHandler(HWND hwnd, UINT const message, WPARAM const wparam,
                            LPARAM const lparam) noexcept
{
  auto window =
      reinterpret_cast<Win32Window *>(GetWindowLongPtr(hwnd, GWLP_USERDATA));

  if (window == nullptr)
  {
    return 0;
  }

  switch (message)
  {
  case WM_SETCURSOR:
    return TRUE;

Thank you! I am making a PR now for the cursor plugin

I left a comment on the PR. It's not clear to me that this can be done correctly outside of the embedding, so building it in (the issue Kris referenced above) seems like a much better option. That said, if there's a reasonable way to support the plugin now that doesn't have unwanted side effects we can consider it.

(Unrelated to this issue: it's great to see people experimenting with plugins on other platforms, and please do keep filing feedback. I am curious though why your plugin is duplicating functionality from window_size; if there were problems with that plugin that made it unusable for you, please let me know.)

Actually I had made the window_utils plugin that included cursor change and window size and offsets 2 days ago. I didn't realize you were making a PR for one

But yours works good too! I actually have the code for the windows side that can set the window position, side and style. Including removing title bar, custom drag events and custom drag resize.

https://github.com/rive-app/window-utils/blob/master/windows/window_utils.cpp

I didn't realize you were making a PR for one

It's been a plugin here for 8 months; only the Windows implementation is new.

Sorry I must have missed it, I just recently upstreamed my fork. But good to know! Thank you

I filed https://github.com/flutter/flutter/issues/53168 for adding the API that would be necessary to correctly implement this behavior in a plugin; closing in favor of that.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Syleron picture Syleron  Â·  5Comments

handicraftsman picture handicraftsman  Â·  10Comments

YazeedAlKhalaf picture YazeedAlKhalaf  Â·  5Comments

icode picture icode  Â·  3Comments

amrboxit4me picture amrboxit4me  Â·  6Comments