Step to reproduce: use SciTE open a long document, put caret at beginning lines. scroll down to ensure caret is invisible. then press Insert key. the INS/OVR in statusbar mode not updated.
Original reported at https://github.com/zufuliu/notepad2/issues/95#issuecomment-466048621
Changelist 6373 (79f86be9e988):
+ ContainerNeedsUpdate(SC_UPDATE_SELECTION);
ShowCaretAtCurrentPosition();
- ContainerNeedsUpdate(SC_UPDATE_CONTENT);
- NotifyUpdateUI();
6337 (79f86be9e988).
That patch appears to be the wrong way around as it is less likely to send a notification if the NotifyUpdateUI is deleted. Red lines are removed and green lines added.
Why does it change the notification from SC_UPDATE_SELECTION to SC_UPDATE_CONTENT? This is different to the behaviour of SCI_SETOVERTYPE.
An explicit NotifyUpdateUI is immediate rather than lazy. It may be better to defer this using QueueIdleWork.
Adding
QueueIdleWork(WorkNeeded::workUpdateUI);not works.The full changeset is at
https://sourceforge.net/p/scintilla/code/ci/79f86be9e988efc5b1462ae549c271c4f3a1b82c/
https://sourceforge.net/p/scintilla/code/ci/4a93de8f37c02962108ef9ed7057108ff27d47e5/
NotifyUpdateUI();is not required when caret is visible.Not related to this bug. SourceForge seems has different commit hash (40 hex instead of 12) for Mercurial compared to local TortoiseHg Web Browser, OpenJDK and Octave.
http://hg.openjdk.java.net/jdk/jdk12/rev/0276cba45aac
https://hg.savannah.gnu.org/hgweb/octave/rev/c4d05690b2f9
QueueIdleWork works on Cocoa but not Win32. ContainerNeedsUpdate requires a later Paint() or IdleWork() to post the notification. Most caret changes make a visual change causing a paint but a change to overstrike mode when there is no visible caret is optimized away.
There could be a NotifyUpdateUI in Idle and a SetIdle(true) for SCI_EDITTOGGLEOVERTYPE and SCI_SETOVERTYPE but that adds unnecessary idling when there will be a paint.
For Win32 the attached patch will detect whether a windows invalidation was performed which will cause a paint and only SetIdle when there won't be a paint (caret is off-screen).
However, this doesn't work on Cocoa where Scintilla doesn't optimize window invalidation (as some off-screen areas are still drawn on Cocoa) but the platform does. The platforms could be queried whether there will be a paint due to invalid areas but that would require work on each platform and the platform APIs may have different behaviour - the most obvious on GTK, gdk_window_get_update_area deletes the update area.
Currently, always calling SetIdle for SCI_EDITTOGGLEOVERTYPE and SCI_SETOVERTYPE and adding NotifyUpdateUI in Idle seems the most likely solution. SCI_EDITTOGGLEOVERTYPE and SCI_SETOVERTYPE aren't called often but it will still be a performance decrease which may be more noticeable if this spreads to other scenarios.
The patch works.
Maybe the line
invalidated = InvalidateRangein the loop isinvalidated |= InvalidateRangeUsing a bitwise operator on bool is likely to trigger a warning from a linter.
Fix committed as [9fcf43]. This is the simpler version thta always calls SetIdle(true) for EDITTOGGLEOVERTYPE and SCI_SETOVERTYPE. Its a little inneficient but that isn't worth making a more complex fix.
Related
Commit: [9fcf43]