Hi, Martin and I started a discussion in the bugtracker and decided to move it here so more people can participate.
The bug report (http://bugs.freepascal.org/view.php?id=14336) is related to cursor handling on Windows. To sum up, the bug is resolved, but we are still looking for more reliable means to set cursors in general and default cursor in particular. Martin Friebe wrote: > There are 2 issues: > 1) For SetCursor it is already documented on msdn that > it does nothing, if the value is already set. > Who is to say that future Window versions will check > the position first, and ignore if it hasn't changed? > It should work using "CallWindowProc " CallWindowProc would require us to pass WParam an LParam values for WM_SETCURSOR message, and documentation about them seems a bit vague to me. I would not rely on default WindowProc behaviour unless I know what exactly must be passed in WParam and LParam. If I don't know it I would rather use SetCursorPos because at least it does not have documented restrictions like SetCursor has. SetCursorPos behavior can change later but for now it is predictable and clearly documented in contrast to WM_SETCURSOR. That's my thoughts on "CallWindowProc vs SetCursorPos". The problem is, as you stated, both CallWindowProc and SetCursorPos will cause WindowProc execution, that is more expensive than SetCursor preceded by some calculations. So, let me summarize your proposed changes for the future as I understand them and add my comments. 1) Remove cursor handling from MouseMove (at least in the cross widget part of the LCL) I agree with this suggestion. AFAIU the first place to look at is TControl.WMMouseMove. 2) Add new LCL message talking controls to update their cursor (like WM_SETCURSOR on Windows) and ensure all WidgetSets use this message. I'm not sure I understand you right here, but missing LM_SETMOUSE message led me to conclusion that you suggest what I stated above. If I get it right, it is hard to comment for me because I'm almost completely clueless about GTK and QT APIs so I cannot say if it worth the effort to make such change for all widgetsets. 3) Decide (or find out) if Control.SetCursor should trigger this message to update a cursor. This is a controversial question, because triggering this message would involve costly message processing, but allow to handle cursors from one place. So it seems to evaluate to "execution speed vs code clarity" and the problem is to estimate differences. I have not done any measurements but both "CalculateBounds[+GetClassCursor]+SetCursor" (acting independently) and "GetCursorPos+SetCursorPos" (causing costly message processing) seems to work fast enough for me not to notice the difference. So maybe it is a matter of taste. It would be interesting to know what other think. 4) Optimize the current handling in WindowProc See (3). 5) Decide if passing on handling to parent WinControl is wanted if "control.Cursor := crDefault" is done To conitue "Intended behaviour of crDefault cursor..." thread, here is what I think. a. We usually want to set a specific cursor for single control like Button, not for container like Panel b. It means containers usually have Cursor = crDefault, so it makes no difference whether cursor handling is passed to Parent or not. c. If we set custom cursor for container like Panel what do we most likely mean by it? Users coming from Delphi would expect Delphi behaviour that is setting it for Panel only. If there is a Button on the Panel and Button.Cursor = crDefault then it is system default cursor for buttons. <IMHO> So it seems crDefault in Delphi means "System default cursor for this kind of control". Screen.Cursor is an exception and crDefault here means "Do not override cursor settings" </IMHO> d. Sometimes it is useful to make child controls inherit cursor settings from parent. This helps to set e.g. crHourGlass for disabled panel with all child controls and then restore original cursor. In order to keep Delphi compatibility we can introduce crParent cursor and pass cursor handling to parent control if this cursor is set for child control. In this case crParent could still fallback to crDefault if the control has no parent. -- _______________________________________________ Lazarus mailing list [email protected] http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
