dotnet / winforms

Windows Forms is a .NET UI framework for building Windows desktop applications.
MIT License
4.35k stars 962 forks source link

Cursor flicker when hovering the pointer on the selected text in RichTextBox #3063

Open Lydia-Shi opened 4 years ago

Lydia-Shi commented 4 years ago

Minimal repro:

  1. Create a new Winforms Core application
  2. Drag and drop a RichTextBox to the form designer
  3. Build and run this application
  4. Type some words in the RichTextBox and select some text
  5. Hover the pointer on the select text and observer the cursor

Or Run the attached project CursorFlickerPrj.zip and repeat step4 & step5.

Expected behavior: The cursor is not flicker.

Actual behavior: The cursor is flicker. Flicker333

weltkante commented 4 years ago

Unfortunately the flicker is by design, see comment in WM_CURSOR handler of RichTextBox

The implementation forwards WM_CURSOR to the native control in an attempt to observe its behavior. It tries to suppress it but obviously is not successful in doing so because suppression only happens when over links - outside links you get standard native behavior.

The result is that you have two places setting the "default" cursor, the native default cursor over selection is an arrow cursor, the managed default of TextBoxBase does not differentiate between selection and always uses IBeam. You'd get even more flicker if the user provided cursor customization since then the managed and native side would disagree even more.

If you want to get rid of flicker you need to decide on who is in charge, either the native control or the managed control, having two sides providing cursors always will lead to flicker when they do not agree.

Ideally you would be able to detect if the user does cursor customization and if not you'd just let the native control take charge. If there is cursor customization you'd no longer forward WM_CURSOR to the native control and always use the users cursor decision. I don't know how easy it is to differentiate between these two cases.

If you can't differentiate then you have to drop native defaults and reimplement link handling without forwarding WM_CURSOR (or just live with the flicker as 'by design')

ghost commented 2 years ago

This issue is now marked as "up for grabs", and we’re looking for a community volunteer to work on this issue. If we receive no interest in 120 days, we will close the issue. To learn more about how we handle feature requests, please see our documentation.

Happy Coding!