diff options
| -rw-r--r-- | src/Editor.cxx | 30 | ||||
| -rw-r--r-- | src/Editor.h | 1 | ||||
| -rw-r--r-- | win32/ScintillaWin.cxx | 37 | 
3 files changed, 50 insertions, 18 deletions
diff --git a/src/Editor.cxx b/src/Editor.cxx index 422237f97..9cf3c31b3 100644 --- a/src/Editor.cxx +++ b/src/Editor.cxx @@ -380,6 +380,7 @@ Editor::Editor() {  	wrapWidth = LineLayout::wrapWidthInfinite;  	docLineLastWrapped = -1;  	docLastLineToWrap = -1; +	backgroundWrapEnabled = true;  	hsStart = -1;  	hsEnd = -1; @@ -1426,11 +1427,12 @@ void Editor::NeedWrapping(int docLineStartWrapping, int docLineEndWrapping) {  // condition is called only from idler).  // Return true if wrapping occurred.  bool Editor::WrapLines(bool fullWrap, int priorityWrapLineStart) { -	// If there are any pending wraps do them during idle. +	// If there are any pending wraps, do them during idle if possible.  	if (wrapState != eWrapNone) {  		if (docLineLastWrapped < docLastLineToWrap) { -			if (!SetIdle(true)) { -				// If platform does not have Idle events, perform full wrap +			if (!(backgroundWrapEnabled && SetIdle(true))) { +				// Background wrapping is disabled, or idle processing +				// not supported.  A full wrap is required.  				fullWrap = true;  			}  		} @@ -1441,9 +1443,6 @@ bool Editor::WrapLines(bool fullWrap, int priorityWrapLineStart) {  			// No priority wrap pending  			return false;  		} -	} else { -		// If there is no wrap, disable the idle call. -		SetIdle(false);  	}  	int goodTopLine = topLine;  	bool wrapOccurred = false; @@ -5050,18 +5049,25 @@ void Editor::Tick() {  bool Editor::Idle() { -	bool idleDone = false; -	// Wrap lines during idle. -	WrapLines(false, -1); -	// No more wrapping -	if (docLineLastWrapped == docLastLineToWrap) -		idleDone = true; +	bool idleDone; + +	bool wrappingDone = (wrapState == eWrapNone) || (!backgroundWrapEnabled); + +	if (!wrappingDone) { +		// Wrap lines during idle. +		WrapLines(false, -1); +		// No more wrapping +		if (docLineLastWrapped == docLastLineToWrap) +			wrappingDone = true; +	}  	// Add more idle things to do here, but make sure idleDone is  	// set correctly before the function returns. returning  	// false will stop calling this idle funtion until SetIdle() is  	// called again. +	idleDone = wrappingDone; // && thatDone && theOtherThingDone... +  	return !idleDone;  } diff --git a/src/Editor.h b/src/Editor.h index b8c32ab64..6eccb50bd 100644 --- a/src/Editor.h +++ b/src/Editor.h @@ -287,6 +287,7 @@ protected:	// ScintillaBase subclass needs access to much of Editor  	// Wrapping support  	enum { eWrapNone, eWrapWord } wrapState; +	bool backgroundWrapEnabled;  	int wrapWidth;  	int docLineLastWrapped;  	int docLastLineToWrap; diff --git a/win32/ScintillaWin.cxx b/win32/ScintillaWin.cxx index 4c9f7341a..9c2d78e1c 100644 --- a/win32/ScintillaWin.cxx +++ b/win32/ScintillaWin.cxx @@ -171,10 +171,13 @@ class ScintillaWin :  	static sptr_t PASCAL CTWndProc(  		    HWND hWnd, UINT iMessage, WPARAM wParam, sptr_t lParam); +	enum { invalidTimerID, standardTimerID, idleTimerID }; +  	virtual void StartDrag();  	sptr_t WndPaint(uptr_t wParam);  	sptr_t HandleComposition(uptr_t wParam, sptr_t lParam);  	virtual sptr_t DefWndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam); +	virtual bool SetIdle(bool on);  	virtual void SetTicking(bool on);  	virtual void SetMouseCapture(bool on);  	virtual bool HaveMouseCapture(); @@ -282,6 +285,7 @@ void ScintillaWin::Initialise() {  void ScintillaWin::Finalise() {  	ScintillaBase::Finalise();  	SetTicking(false); +	SetIdle(false);  	::RevokeDragDrop(MainHWND());  	::OleUninitialize();  } @@ -577,7 +581,14 @@ sptr_t ScintillaWin::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam  		return 0;  	case WM_TIMER: -		Tick(); +		if (wParam == standardTimerID && timer.ticking) { +			Tick(); +		} else if (wParam == idleTimerID && idler.state) { +			if (!Idle()) +				SetIdle(false); +		} else { +			return 1; +		}  		break;  	case WM_GETMINMAXINFO: @@ -887,11 +898,8 @@ void ScintillaWin::SetTicking(bool on) {  	if (timer.ticking != on) {  		timer.ticking = on;  		if (timer.ticking) { -			timer.tickerID = reinterpret_cast<TickerID>(1); -			if (::SetTimer(MainHWND(), reinterpret_cast<uptr_t>(timer.tickerID), timer.tickSize, NULL) == 0) { -				timer.ticking = false; -				timer.tickerID = 0;  -			} +			timer.tickerID = ::SetTimer(MainHWND(), standardTimerID, timer.tickSize, NULL) +				? reinterpret_cast<TickerID>(standardTimerID) : 0;  		} else {  			::KillTimer(MainHWND(), reinterpret_cast<uptr_t>(timer.tickerID));  			timer.tickerID = 0; @@ -900,6 +908,23 @@ void ScintillaWin::SetTicking(bool on) {  	timer.ticksToWait = caret.period;  } +bool ScintillaWin::SetIdle(bool on) { +	// On Win32 the Idler is implemented as a Timer on the Scintilla window.  This +	// takes advantage of the fact that WM_TIMER messages are very low priority, +	// and are only posted when the message queue is empty, i.e. during idle time. +	if (idler.state != on) { +		if (on) { +			idler.idlerID = ::SetTimer(MainHWND(), idleTimerID, 20, NULL) +				? reinterpret_cast<IdlerID>(idleTimerID) : 0; +		} else { +			::KillTimer(MainHWND(), reinterpret_cast<uptr_t>(idler.idlerID)); +			idler.idlerID = 0; +		} +		idler.state = idler.idlerID != 0; +	} +	return idler.state; +} +  void ScintillaWin::SetMouseCapture(bool on) {  	if (mouseDownCaptures) {  		if (on) {  | 
