Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix: problem with cursors that are not the same on my OS as hardcoded in the MouseCursor class #182

Merged
merged 1 commit into from
Jan 2, 2014

Conversation

ivan-danilov
Copy link
Contributor

Hi.

I was investigating why White is often very slow to get items (WPF application) and found out that it was waiting inside Window.HourGlassWait() method. Adding some debug logging shown such thing:

[Debug] 'TestStack.White.UIItems.UIItem' HourGlassWait: current cursor is 65543, waiting again
[Debug] 'TestStack.White.UIItems.UIItem' HourGlassWait: current cursor is 65543, waiting again
[Debug] 'TestStack.White.UIItems.UIItem' HourGlassWait: current cursor is 65543, waiting again
[Debug] 'TestStack.White.UIItems.UIItem' HourGlassWait: current cursor is 65543, waiting again

and yet several dozens of such lines after what timeout happened.

Here HCURSOR=65543 is defined as SilverlightWait. But we don't use Silverlight at all. Trying to figure out what is happening I've written such piece:

        // this is from http://www.pinvoke.net/default.aspx/user32/LoadCursor.html
        [DllImport("user32.dll")]
        static extern IntPtr LoadCursor(IntPtr hInstance, IDC_STANDARD_CURSORS lpCursorName);

        // this is from http://pinvoke.net/default.aspx/Constants/IDC_.html
        enum IDC_STANDARD_CURSORS
        {
            IDC_ARROW = 32512,
            IDC_IBEAM = 32513,
            IDC_WAIT = 32514,
            IDC_CROSS = 32515,
            IDC_UPARROW = 32516,
            IDC_SIZE = 32640,
            IDC_ICON = 32641,
            IDC_SIZENWSE = 32642,
            IDC_SIZENESW = 32643,
            IDC_SIZEWE = 32644,
            IDC_SIZENS = 32645,
            IDC_SIZEALL = 32646,
            IDC_NO = 32648,
            IDC_HAND = 32649,
            IDC_APPSTARTING = 32650,
            IDC_HELP = 32651
        }

        var values = Enum.GetValues(typeof (IDC_STANDARD_CURSORS)).Cast<IDC_STANDARD_CURSORS>().ToArray();
        foreach (var idcStandardCursor in values)
        {
            var c = LoadCursor(IntPtr.Zero, idcStandardCursor);
            Console.WriteLine("{0} = {1}", idcStandardCursor.ToString(), c.ToInt32());
        }

And the result was:

IDC_ARROW = 65543
IDC_IBEAM = 65545
IDC_WAIT = 65547
IDC_CROSS = 65549
IDC_UPARROW = 65551
IDC_SIZE = 0
IDC_ICON = 0
IDC_SIZENWSE = 65553
IDC_SIZENESW = 65555
IDC_SIZEWE = 65557
IDC_SIZENS = 65559
IDC_SIZEALL = 65561
IDC_NO = 65563
IDC_HAND = 65571
IDC_APPSTARTING = 65565
IDC_HELP = 65567

It seems that in my OS 65543 is precisely "normal" arrow cursor. And Window.HourGlassWait() waits until something else found. Not to mention that waiting results in failure.
By the way, other cursors in the MouseCursor.cs are also not coincide with my OS values.

Now, this pull request is more a question then ready-to-merge code, because I don't know what to replace Silverlight values with, so just commented them. But overall this code make unit-tests of White pass on my machine and my real code work much-much faster (I believe that before I was waiting for a timeout on almost each WaitHourGlass() call).

@JakeGinnivan
Copy link
Member

Awesome find, the other option is to make the cursors return based on the framework which is being waited so for WPF the silverlight cursor is not part of the checked collection?

I would like to get this in, as it could explain some of the slowness some people experience. Appreciate you digging into this.

Did you want to have a go at changing WaitCursors to take the framework id. Something like:

MouseCursor.WaitCursors(AutomationElement.FrameworkId).Contains(...)

You could have a Dictionary, or ConcurrentDictionary which is the lookup for the list. Or having two hardcoded lists, one for Silverlight, one not?

@ivan-danilov
Copy link
Contributor Author

Hm... global cursor that is returned from GetCursorInfo() is more OS-specific thing. I don't have Silverlight to check, but... does it really have its own variant of Hourglass cursor? Not equals to IDC_WAIT?
Making WaitCursors framework-dependent would require much code duplication. Not sure it is worthwhile.

Could anyone with Silverlight check if it really has its own cursor or not? And if yes - where it comes from? Hardcoding HCURSOR values was not a good idea obviously :)

@JakeGinnivan
Copy link
Member

True, also the Silverlight support needs work and I have been asking for a community champion for it to step up. Nobody has yet. I think this is a good change.

Could you remove the commented code and raise an issue to describe this, then mention the issue number in the commit (for release notes).

Will merge and get a release out in the new year containing this

JakeGinnivan added a commit that referenced this pull request Jan 2, 2014
Fix: problem with cursors that are not the same on my OS as hardcoded in the MouseCursor class
@JakeGinnivan JakeGinnivan merged commit 70d0104 into TestStack:master Jan 2, 2014
@JakeGinnivan
Copy link
Member

Thanks!

@ivan-danilov ivan-danilov deleted the cursors-fix branch January 2, 2014 17:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants