Since berlios is down again, I'll submit this proposed patch to the forum. Maybe someone can confirm it for me.
This patch will lessen the occurance of the drag'n'drop hang that occurs with GTK and Scintilla. This is actually a GTK bug, but is aggravated by the manner in which Scintilla coded a double click.
The hang occurs because GTK and wxGTK are out of synch and cannot handle a mouse key up event while also handling a mouse moving event. So the mouse key up event is lost. But while dragging, wxGTK is depending on the key up to end the drag. Once the hang occurs, no more mouse events are ever seen by wxGTK because the underlying OS has the mouse in drag capture.
This "fix" moves the Scintilla drag initiation out of the mouse ButtonDown code and into the ButtonMove code to avoid the ButtonDown double click problem. Having the code in ButtonDown exacerbates the problem by entering the drag code over and over again. The "fix" enters the drag initiation only once, and only if the key is already down and the mouse is moving. It will not initiate another drag until a subsequent mouse ButtonUp.
The hang can still occur (until the GTK/wxGTK bug is fixed), but only if you try really really hard.
Index: src/scintilla/src/Editor.cxx
===================================================================
--- src/scintilla/src/Editor.cxx (revision 2387)
+++ src/scintilla/src/Editor.cxx (working copy)
@@ -5,6 +5,18 @@
// Copyright 1998-2004 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
+//Lines tagged //pecan 20060506 is a patch to avoid the GTK drag'n'drop hang bug.
+//GTK is not handling a mouse "moving buttonUp" event well. The keyUp event is completely missed
+// causing wxGTK to hang in the drag routine waiting for the up event.GTK has the mouse captured,
+// so no event will ever be seen by wxGTK.
+//This is aggravated by the manner in which scintilla coded the mouse doubleClick.
+// It treats it as two single ButtonDown clicks, entering DragNdrop over and over again.
+//This patch moves the initiation of the drag into the MouseMove code to avoid the double click
+// problem. It will not allow secondary drags until a subsequent mouse up event.
+//This patch does not cure the problem, it can still happen if the user quickly drags
+// and lifts the mouse key at the same time the mouse is moving. But it's much harder
+// to cause the hang. Pecan
+
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
@@ -442,6 +454,9 @@
hsEnd = -1;
llc.SetLevel(LineLayoutCache::llcCaret);
+ #ifdef __WXGTK__
+ m_mouseButtonDownCnt = 0; //pecan 20060507
+ #endif
}
Editor::~Editor() {
@@ -1212,7 +1227,7 @@
where most code reside, and the lines after the caret, eg. the body of a function.
| | | | |
-slop | strict | jumps | even | Caret can go to the margin | When reaching limitÝ(caret going out of
+slop | strict | jumps | even | Caret can go to the margin | When reaching limit (caret going out of
| | | | | visibility or going into the UZ) display is...
-----+--------+-------+------+--------------------------------------------+--------------------------------------------------------------
0 | 0 | 0 | 0 | Yes | moved to put caret on top/on right
@@ -5037,6 +5052,9 @@
void Editor::ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, bool alt) {
//Platform::DebugPrintf("Scintilla:ButtonDown %d %d = %d alt=%d\n", curTime, lastClickTime, curTime - lastClickTime, alt);
+ #ifdef __WXGTK__
+ m_mouseButtonDownCnt++; //pecan 20060507
+ #endif
ptMouseLast = pt;
int newPos = PositionFromLocation(pt);
newPos = MovePositionOutsideChar(newPos, currentPos - newPos);
@@ -5124,12 +5142,18 @@
}
if (!shift) {
inDragDrop = PointInSelection(pt) && !SelectionEmpty();
+ #ifdef __WXGTK__
+ if (m_mouseButtonDownCnt>1) //pecan 20060507
+ inDragDrop = false; //pecan 20060507
+ #endif
}
if (inDragDrop) {
+ #ifndef __WXGTK__ //for GTK, code moved to ButtonMove() //pecan 20060507
SetMouseCapture(false);
SetDragPosition(newPos);
CopySelectionRange(&drag);
StartDrag();
+ #endif
} else {
SetDragPosition(invalidPosition);
SetMouseCapture(true);
@@ -5203,6 +5227,18 @@
}
ptMouseLast = pt;
//Platform::DebugPrintf("Move %d %d\n", pt.x, pt.y);
+ #ifdef __WXGTK__ //pecan 20060507
+ // code moved here from ButtonDown to avoid GTK doubleClick/drag hang bug
+ if (inDragDrop) {
+ SetMouseCapture(false);
+ int newPos = PositionFromLocation(pt);
+ SetDragPosition(newPos);
+ CopySelectionRange(&drag);
+ m_mouseButtonDownCnt++; //don't do again until mouse ButtonUp //pecan 20060507
+ StartDrag();
+ }
+ #endif //pecan 20060507
+
if (HaveMouseCapture()) {
// Slow down autoscrolling/selection
@@ -5289,7 +5325,10 @@
}
void Editor::ButtonUp(Point pt, unsigned int curTime, bool ctrl) {
- //Platform::DebugPrintf("ButtonUp %d\n", HaveMouseCapture());
+ //Platform::DebugPrintf("ButtonUp mouseCapture%d downCnt:%d", HaveMouseCapture(), m_mouseButtonDownCnt);
+ #ifdef __WXGTK__
+ m_mouseButtonDownCnt = 0; //pecan 20060507
+ #endif
if (HaveMouseCapture()) {
if (PointInSelMargin(pt)) {
DisplayCursor(Window::cursorReverseArrow);
Index: src/scintilla/src/Editor.h
===================================================================
--- src/scintilla/src/Editor.h (revision 2387)
+++ src/scintilla/src/Editor.h (working copy)
@@ -528,6 +528,8 @@
virtual sptr_t DefWndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) = 0;
+ int m_mouseButtonDownCnt; //pecan 20060507
+
public:
// Public so the COM thunks can access it.
bool IsUnicodeMode() const;
The line with "-slop" in it has nothing to do with the patch. But svn keeps putting it back into my source. When I save the file, svn now thinks the line is changed. Darn it ! It does no harm, though.
Will submit patch to Berlios when it comes back up.
thanks
pecan