diff options
| author | nyamatongwe <nyamatongwe@gmail.com> | 2013-03-13 10:21:33 +1100 | 
|---|---|---|
| committer | nyamatongwe <nyamatongwe@gmail.com> | 2013-03-13 10:21:33 +1100 | 
| commit | 3ee697fc002bd2ac942ce40b32e317f431974b46 (patch) | |
| tree | a65eb47622ac39953c58f937f291f3bb3830df1f | |
| parent | 12e6f6374e791c61e778994475d224054aa01520 (diff) | |
| download | scintilla-mirror-3ee697fc002bd2ac942ce40b32e317f431974b46.tar.gz | |
Implement high-priority idle work on Cocoa to avoid abandoning paints in some situations.
Rename IdleStyling to IdleWork.
| -rw-r--r-- | cocoa/ScintillaCocoa.h | 6 | ||||
| -rw-r--r-- | cocoa/ScintillaCocoa.mm | 59 | ||||
| -rw-r--r-- | gtk/ScintillaGTK.cxx | 2 | ||||
| -rw-r--r-- | src/Editor.cxx | 2 | ||||
| -rw-r--r-- | src/Editor.h | 2 | 
5 files changed, 68 insertions, 3 deletions
| diff --git a/cocoa/ScintillaCocoa.h b/cocoa/ScintillaCocoa.h index 1a7852bce..87702f51e 100644 --- a/cocoa/ScintillaCocoa.h +++ b/cocoa/ScintillaCocoa.h @@ -120,6 +120,7 @@ private:    int scrollTicks;    NSTimer* tickTimer;    NSTimer* idleTimer; +  CFRunLoopObserverRef observer;    FindHighlightLayer *layerFindIndicator; @@ -184,6 +185,11 @@ public:    void TimerFired(NSTimer* timer);    void IdleTimerFired(); +  static void UpdateObserver(CFRunLoopObserverRef observer, CFRunLoopActivity activity, void *sci); +  void ObserverAdd(); +  void ObserverRemove(); +  virtual void IdleWork(); +  virtual void QueueIdleWork(WorkNeeded::workItems items, int upTo);    int InsertText(NSString* input);    bool KeyboardInput(NSEvent* event); diff --git a/cocoa/ScintillaCocoa.mm b/cocoa/ScintillaCocoa.mm index fe12690a4..8a31b40d3 100644 --- a/cocoa/ScintillaCocoa.mm +++ b/cocoa/ScintillaCocoa.mm @@ -383,6 +383,7 @@ ScintillaCocoa::ScintillaCocoa(NSView* view)  {    wMain = view; // Don't retain since we're owned by view, which would cause a cycle    timerTarget = [[TimerTarget alloc] init: this]; +  observer = NULL;    layerFindIndicator = NULL;    Initialise();  } @@ -428,12 +429,70 @@ void ScintillaCocoa::Initialise()   */  void ScintillaCocoa::Finalise()  { +  ObserverRemove();    SetTicking(false);    ScintillaBase::Finalise();  }  //-------------------------------------------------------------------------------------------------- +void ScintillaCocoa::UpdateObserver(CFRunLoopObserverRef observer, CFRunLoopActivity activity, void *info) { +  ScintillaCocoa* sci = reinterpret_cast<ScintillaCocoa*>(info); +  sci->IdleWork(); +} + +//-------------------------------------------------------------------------------------------------- + +/** + * Add an observer to the run loop to perform styling as high-priority idle task. + */ + +void ScintillaCocoa::ObserverAdd() { +  if (!observer) { +    CFRunLoopObserverContext context; +    context.version = 0; +    context.info = this; +    context.retain = NULL; +    context.release = NULL; +    context.copyDescription = NULL; + +    CFRunLoopRef mainRunLoop = CFRunLoopGetMain(); +    observer = CFRunLoopObserverCreate(NULL, kCFRunLoopEntry | kCFRunLoopBeforeWaiting, +      true, 0, UpdateObserver, &context); +    CFRunLoopAddObserver(mainRunLoop, observer, kCFRunLoopCommonModes); +  } +} + +//-------------------------------------------------------------------------------------------------- + +/** + * Remove the run loop observer. + */ +void ScintillaCocoa::ObserverRemove() { +  if (observer) { +    CFRunLoopRef mainRunLoop = CFRunLoopGetMain(); +    CFRunLoopRemoveObserver(mainRunLoop, observer, kCFRunLoopCommonModes); +    CFRelease(observer); +  } +  observer = NULL; +} + +//-------------------------------------------------------------------------------------------------- + +void ScintillaCocoa::IdleWork() { +  Editor::IdleWork(); +  ObserverRemove(); +} + +//-------------------------------------------------------------------------------------------------- + +void ScintillaCocoa::QueueIdleWork(WorkNeeded::workItems items, int upTo) { +  Editor::QueueIdleWork(items, upTo); +  ObserverAdd(); +} + +//-------------------------------------------------------------------------------------------------- +  /**   * Convert a core foundation string into an array of bytes in a particular encoding   */ diff --git a/gtk/ScintillaGTK.cxx b/gtk/ScintillaGTK.cxx index 2e48d5e46..20c398b86 100644 --- a/gtk/ScintillaGTK.cxx +++ b/gtk/ScintillaGTK.cxx @@ -2761,7 +2761,7 @@ gboolean ScintillaGTK::StyleIdle(ScintillaGTK *sciThis) {  #ifndef GDK_VERSION_3_6  	gdk_threads_enter();  #endif -	sciThis->IdleStyling(); +	sciThis->IdleWork();  #ifndef GDK_VERSION_3_6  	gdk_threads_leave();  #endif diff --git a/src/Editor.cxx b/src/Editor.cxx index f2a6a1f62..740162faa 100644 --- a/src/Editor.cxx +++ b/src/Editor.cxx @@ -6714,7 +6714,7 @@ void Editor::StyleToPositionInView(Position pos) {  	}  } -void Editor::IdleStyling() { +void Editor::IdleWork() {  	// Style the line after the modification as this allows modifications that change just the  	// line of the modification to heal instead of propagating to the rest of the window.  	if (workNeeded.items & WorkNeeded::workStyle) diff --git a/src/Editor.h b/src/Editor.h index bc7babb13..bf3e26d92 100644 --- a/src/Editor.h +++ b/src/Editor.h @@ -540,7 +540,7 @@ protected:	// ScintillaBase subclass needs access to much of Editor  	int PositionAfterArea(PRectangle rcArea);  	void StyleToPositionInView(Position pos); -	void IdleStyling(); +	virtual void IdleWork();  	virtual void QueueIdleWork(WorkNeeded::workItems items, int upTo=0);  	virtual bool PaintContains(PRectangle rc); | 
