I have said this before, by editing a message, but repeat it here to have more chances of somebody viewing it.
I am using this approach (
https://wiki.freepascal.org/Extending_the_IDE#Disabling_the_designer_mouse_handler) to capture mouse clicks at design time, but there is a problem. When I click a tab, it gets selected as expected. However, as soon as I move the mouse outside the tab, the IDE starts drawing a selection rectangle, as if the mouse button were still being held down.
Then, I look into the code of Lazarus designer (designer/designer.pp), and found that this behavior was an actual bug in Lazarus:
When CM_DESIGNHITTEST returns 1 on MouseUp, the designer calls MouseUp and Exit, without ever setting MouseDownComponent := nil. That only happens at the bottom of the normal path. So after a clean click on a tab:
- MouseDownComponent = our control (never cleared)
- Selection.RubberbandActive := False (was never set, since there was no move before up)
Then as soon as the mouse moves anywhere, even just off the component, MouseMoveOnControl fires, finds MouseDownComponent still set to our control, calls CM_DESIGNHITTEST with out-of-bounds coords, gets 0, falls through, and because MouseDownComponent != nil and there's no grabber, it goes straight to the rubber-band path.
A simple change on designer/designer.pp can fix the problem. I have replaced:
TControlAccess(MouseDownComponent).MouseUp(Button, Shift, p.X, p.Y);
Exit;
with
TControlAccess(MouseDownComponent).MouseUp(Button, Shift, p.X, p.Y);
MouseDownComponent:=nil;
Exit;
and that's it, selecting tabs at design time works like charm.
Please, can anybody report the bug? I would do it myself, but have no idea of how to do it (and will be out for a couple of days).