Paul Ishenin wrote 7 lines
Qt mouse grab is very heavy. On windows it can grab input so that only
ctrl+alt+del can unlock this grab. Qt installs windows hook which is imo
a very big hack. LCL uses mouse grabs often and we dont need so heavy
grabs since LCL can lock the whole system with them. At the same moment
qt guys uses grabMouseWhileInWindow for their tasks. Can we publish this
function in the bindings library then I will use it for windows-qt
application.
grabMouseWhileInWindow is not only private, but also the implementation of grabMouseWhileInWindow writes in local private variables, that are used by grab/release mouse to check for existing grabs. If we would just write a grabMouseWhileInWindow (i.e. grab w/o hook), we cannot correctly update those local private variables. Other calls to grab/release would not work correctly.
The capture is windows call SetCapture,
the hook is windows call SetWindowsHookExA
the local variables are mouseGrb,mouseGrbCur,journalRec code from Qt:
./gui/kernel/qwidget_win.cpp
... local variables in qwidget_win.cpp
static QWidget *mouseGrb = 0;
static QCursor *mouseGrbCur = 0;
static QWidget *keyboardGrb = 0;
static HHOOK journalRec = 0;
...
void QWidgetPrivate::grabMouseWhileInWindow()
{
Q_Q(QWidget);
if (!qt_nograb()) {
if (mouseGrb)
mouseGrb->releaseMouse();
Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
SetCapture(q->effectiveWinId());
mouseGrb = q;
#ifndef QT_NO_CURSOR
mouseGrbCur = new QCursor(mouseGrb->cursor());
#endif
}
}
...
#ifndef Q_OS_WINCE
void QWidget::grabMouse()
{
if (!qt_nograb()) {
if (mouseGrb)
mouseGrb->releaseMouse();
journalRec = SetWindowsHookExA(WH_JOURNALRECORD,
(HOOKPROC)qJournalRecordProc, GetModuleHandleA(0), 0);
Q_ASSERT(testAttribute(Qt::WA_WState_Created));
SetCapture(effectiveWinId());
mouseGrb = this;
mouseGrbCur = new QCursor(mouseGrb->cursor());
}
}
void QWidget::releaseMouse()
{
if (!qt_nograb() && mouseGrb == this) {
ReleaseCapture();
if (journalRec) {
UnhookWindowsHookEx(journalRec);
journalRec = 0;
}
if (mouseGrbCur) {
delete mouseGrbCur;
mouseGrbCur = 0;
}
mouseGrb = 0;
}
}
#endif
....