Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / lazarus / 2010-12

Purpose of MouseCapture?

10 messages · 3 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Hans-Peter Diettrich

What's the purpose of setting the mouse capture in the LCL?

It seems okay to let the user capture the mouse, and also the dragmanager, but any other attempt to capture mouse messages looks not logical to me. In the IDE it forces the DragManager to abort dragging, and only bogus can happen in other cases, when mouse messages are not delivered to the control under the mouse.

With the (new?) csCaptureMouse control state flag the mouse is captured on every mouse event, with the beforementioned effect that the DragManager stops working properly. This flag seems to be used in detail inside the IDE.

I'd suggest to redesign the message handling in so far, that mouse and key messages are sent immediately to an active DragManager, before any other attempt to dispatch the messages to a different target. This will eliminate any chance to break a drag operation in other than the designed ways. Else the application (in detail the IDE) can enter an inconsistent state, and the new (very buggy) drag window on Win32 (Vista...) cas work without adding code for forwarding all messages to the DragManager.

DoDi

Reply by email

Paul Ishenin
to Hans-Peter Diettrich
Hans-Peter Diettrich wrote
Hans-Peter Diettrich schrieb: > What's the purpose of setting the mouse capture in the LCL? While nobody seems to know, I found that TSpltter uses mouse capture.

Sorry, I did not notice the initial mail.

So the DragManager simply should ignore CaptureChanged.

The purpose of mouse capture is to be sure that you are recieving all mouse events until you want to stop mouse capture or external event stops your mouse capture. Such external event can be for example switching task or another window require a mouse capture.

When you start a drag operator you must always request the capture. In other case you cannot track mouse events outside the dragged control. DragManager must handle the CaptureChanged event in order to understand that capture it has was requested by other control and therefore it must stop the drag operation.

Best regards,
Paul Ishenin

Reply by email

Graeme Geldenhuys
to Hans-Peter Diettrich: While nobody seems to know, I found that TSpltter uses mouse capture. So the DragManager…
Hans-Peter Diettrich wrote
> What's the purpose of setting the mouse capture in the LCL? While nobody seems to know, I found that TSpltter uses mouse capture.

MouseCapture (at least under fpGUI) is also used while the mouse button is down, eg on a TButton. For example (i think this works under LCL too). Click a TButton, and hold the mouse button down. Now move the mouse cursor outside the TButton bounds. The TButton should pop up (normal state again), and when you hove the mouse over the TButton, the mouse would be pressed again.

Mouse events normally get delivered only to the window underneath the mouse. MouseCapture, captures the mouse input and makes sure it gets delivered to a specific window even if the mouse is over another window.

Regards, ? - Graeme - _______________________________________________ fpGUI - a cross-platform Free Pascal GUI toolkit http://fpgui.sourceforge.net

Reply by email

Hans-Peter Diettrich
to Paul Ishenin: Sorry, I did not notice the initial mail. The purpose of mouse capture is to be sure that…
Show quoted text 10 lines
08.01.2011 22:16, Hans-Peter Diettrich wrote: > Hans-Peter Diettrich schrieb: >> What's the purpose of setting the mouse capture in the LCL? > > While nobody seems to know, I found that TSpltter uses mouse capture. Sorry, I did not notice the initial mail. > > So the DragManager simply should ignore CaptureChanged. The purpose of mouse capture is to be sure that you are recieving all mouse events until you want to stop mouse capture

So much about theory. My question was about reasons for using mouse capture in LCL components, in detail the csCaptureMouse control state flag. So far its only reasonable use is in a TSplitter, to allow for fake moves (user feedback) and to obtain the final position of the splitter.

or external event stops your mouse capture. Such external event can be for example switching task or another window require a mouse capture.

The mouse is a shared resource, managed by the OS. I doubt that the mouse capture can be stolen by other processes. I.e. the owner of the mouse capture must release the capture, at some time (usually when the mouse button is released).

When you start a drag operator you must always request the capture. In other case you cannot track mouse events outside the dragged control.

ACK.

DragManager must handle the CaptureChanged event in order to understand that capture it has was requested by other control and therefore it must stop the drag operation.

NACK. The LCL components implement some weird behaviour, that can result in many changes of the mouse capture at the begin of a drag operation. These nearly unpredictable changes often cause the DragManager to stop dragging, in the current implementation. Once a control is dragged, there is no reason why the mouse capture should change until the end of the operation. When a control decides that dragging should stop, it should call DragManager.DragStop, everything else is insane.

DoDi

Reply by email

Hans-Peter Diettrich
to Graeme Geldenhuys: MouseCapture (at least under fpGUI) is also used while the mouse button is down, eg on a…
Show quoted text 10 lines
On 8 January 2011 17:16, Hans-Peter Diettrich wrote: >> What's the purpose of setting the mouse capture in the LCL? > While nobody seems to know, I found that TSpltter uses mouse capture. MouseCapture (at least under fpGUI) is also used while the mouse button is down, eg on a TButton. For example (i think this works under LCL too). Click a TButton, and hold the mouse button down. Now move the mouse cursor outside the TButton bounds. The TButton should pop up (normal state again), and when you hove the mouse over the TButton, the mouse would be pressed again.

That's questionable behaviour, that must be checked for compatibility with e.g. an DragManager.

Since a DragManager has no HWND and cannot capture the mouse itself, a safe implementation would redirect all mouse and keyboard events to an dragging DragManager immediately, instead of delivering the events to the target control, in the hope that it will *in any case* forward the messages to the DragManager.

At least I observed some weird behaviour of some controls, that do not check properly for a drag operation in progress. No such checks are required, and can be forgotten or implemented in a wrong way, when the event dispatcher already checks for a dragging operation in progress.

DoDi

Reply by email

Paul Ishenin
to Hans-Peter Diettrich: So much about theory. My question was about reasons for using mouse capture in LCL…
Hans-Peter Diettrich wrote 5 lines
So much about theory. My question was about reasons for using mouse capture in LCL components, in detail the csCaptureMouse control state flag. So far its only reasonable use is in a TSplitter, to allow for fake moves (user feedback) and to obtain the final position of the splitter.

I tried to reduce usage of csCaptureMouse in LCL components. It is used much less than a year before.

Show quoted text 8 lines
> or external event stops your mouse capture. Such external event can > be for example switching task or another window require a mouse capture. The mouse is a shared resource, managed by the OS. I doubt that the mouse capture can be stolen by other processes. I.e. the owner of the mouse capture must release the capture, at some time (usually when the mouse button is released).

No, mouse capture can be stolen by any process.

Show quoted text 12 lines
> DragManager must handle the CaptureChanged event in order to > understand that capture it has was requested by other control and > therefore it must stop the drag operation. NACK. The LCL components implement some weird behaviour, that can result in many changes of the mouse capture at the begin of a drag operation. These nearly unpredictable changes often cause the DragManager to stop dragging, in the current implementation. Once a control is dragged, there is no reason why the mouse capture should change until the end of the operation. When a control decides that dragging should stop, it should call DragManager.DragStop, everything else is insane.

As result you will get a situation when application thinks that it dragges something but capture is not owned by the drag manager so mouse events are not tracked by it.

Best regards,
Paul Ishenin

Reply by email

Paul Ishenin
to Hans-Peter Diettrich: That's questionable behaviour, that must be checked for compatibility with e.g. an…
Hans-Peter Diettrich wrote 6 lines
Since a DragManager has no HWND and cannot capture the mouse itself, a safe implementation would redirect all mouse and keyboard events to an dragging DragManager immediately, instead of delivering the events to the target control, in the hope that it will *in any case* forward the messages to the DragManager.

When you drag from one window to another the space between windows is not owned by your application and therefore nobody forward messages to the drag manager.

Best regards,
Paul Ishenin

Reply by email

Hans-Peter Diettrich
to Paul Ishenin: I tried to reduce usage of csCaptureMouse in LCL components. It is used much less than a…
Show quoted text 5 lines
> The mouse is a shared resource, managed by the OS. I doubt that the > mouse capture can be stolen by other processes. I.e. the owner of the > mouse capture must release the capture, at some time (usually when the > mouse button is released). No, mouse capture can be stolen by any process.

I doubt that, but not every OS is perfect ;-)

At least the OS must notify the application that it lost mouse capture - this may be the only capture event that has to be handled by the DragManager.

Show quoted text 14 lines
>> DragManager must handle the CaptureChanged event in order to >> understand that capture it has was requested by other control and >> therefore it must stop the drag operation. > > NACK. The LCL components implement some weird behaviour, that can result > in many changes of the mouse capture at the begin of a drag operation. > These nearly unpredictable changes often cause the DragManager to stop > dragging, in the current implementation. Once a control is dragged, > there is no reason why the mouse capture should change until the end > of the operation. When a control decides that dragging should stop, it > should call DragManager.DragStop, everything else is insane. As result you will get a situation when application thinks that it dragges something but capture is not owned by the drag manager so mouse events are not tracked by it.

This cannot happen when the dragging condition is managed properly by the DragManager. Even if something goes really wrong, dragging stops at the next release of the mouse button, dispatched to the DragManager.

DoDi

Reply by email

Hans-Peter Diettrich
to Paul Ishenin: When you drag from one window to another the space between windows is not owned by your…
Show quoted text 8 lines
> Since a DragManager has no HWND and cannot capture the mouse itself, a > safe implementation would redirect all mouse and keyboard events to an > dragging DragManager immediately, instead of delivering the events to > the target control, in the hope that it will *in any case* forward the > messages to the DragManager. When you drag from one window to another the space between windows is not owned by your application and therefore nobody forward messages to the drag manager.

The mouse must be captured when dragging starts, of course. But afterwards all mouse messages must be handled *only* by the DragManager, until dragging is finished.

Please note that I never said that a mouse capture is of no it must be handled properly, what is not the case in the current LCL implementation.

DoDi

Reply by email