From c5dedff99f306588a7217d40a4281db7d1baffaa Mon Sep 17 00:00:00 2001 From: Neil Date: Thu, 11 Oct 2018 09:29:05 +1100 Subject: Add SCI_SETCOMMANDEVENTS API to allow turning off command events. This can reduce the time taken to fold a document by half. --- cocoa/ScintillaCocoa.mm | 2 +- doc/ScintillaDoc.html | 14 +++++++++++++- doc/ScintillaHistory.html | 4 ++++ gtk/ScintillaGTK.cxx | 7 ++++--- include/Scintilla.h | 2 ++ include/Scintilla.iface | 6 ++++++ qt/ScintillaEditBase/ScintillaQt.cpp | 10 ++++++---- src/Editor.cxx | 16 +++++++++++++--- src/Editor.h | 1 + win32/ScintillaWin.cxx | 8 +++++--- 10 files changed, 55 insertions(+), 15 deletions(-) diff --git a/cocoa/ScintillaCocoa.mm b/cocoa/ScintillaCocoa.mm index d88e0e3ed..1338a66fa 100644 --- a/cocoa/ScintillaCocoa.mm +++ b/cocoa/ScintillaCocoa.mm @@ -1969,7 +1969,7 @@ void ScintillaCocoa::NotifyChange() { //-------------------------------------------------------------------------------------------------- void ScintillaCocoa::NotifyFocus(bool focus) { - if (notifyProc != NULL) + if (commandEvents && notifyProc) notifyProc(notifyObj, WM_COMMAND, Platform::LongFromTwoShorts(static_cast(GetCtrlID()), (focus ? SCEN_SETFOCUS : SCEN_KILLFOCUS)), (uintptr_t) this); diff --git a/doc/ScintillaDoc.html b/doc/ScintillaDoc.html index bfda8622a..891b4ce7d 100644 --- a/doc/ScintillaDoc.html +++ b/doc/ScintillaDoc.html @@ -7263,6 +7263,8 @@ struct SCNotification {

The following SCI_* messages are associated with these notifications:

SCI_SETMODEVENTMASK(int eventMask)
SCI_GETMODEVENTMASK → int
+ SCI_SETCOMMANDEVENTS(bool commandEvents)
+ SCI_GETCOMMANDEVENTS → bool
SCI_SETMOUSEDWELLTIME(int periodMilliseconds)
SCI_GETMOUSEDWELLTIME → int
SCI_SETIDENTIFIER(int identifier)
@@ -7749,7 +7751,9 @@ href="#SCI_POSITIONFROMLINE">SCI_POSITIONFROMLINE(lineNumber); EN_CHANGE). No other information is sent. If you need more detailed information use SCN_MODIFIED. You can filter the types of changes you are notified about with SCI_SETMODEVENTMASK.

+ href="#SCI_SETMODEVENTMASK">SCI_SETMODEVENTMASK and + SCI_SETCOMMANDEVENTS.

SCI_SETMODEVENTMASK(int eventMask)
SCI_GETMODEVENTMASK → int
@@ -7769,6 +7773,14 @@ href="#SCI_POSITIONFROMLINE">SCI_POSITIONFROMLINE(lineNumber); SC_MOD_BEFOREINSERT, SC_MOD_BEFOREDELETE, SC_MULTILINEUNDOREDO, and SC_MODEVENTMASKALL.

+

SCI_SETCOMMANDEVENTS(bool commandEvents)
+ SCI_GETCOMMANDEVENTS → bool
+ These messages set and get whether SCEN_* command events are + sent to the container. For SCEN_CHANGE this acts as an additional filter over + SCI_SETMODEVENTMASK. + Most applications should set this off to avoid overhead and only use + SCN_MODIFIED.

+

SCEN_SETFOCUS
SCEN_KILLFOCUS
SCEN_SETFOCUS (512) is fired when Scintilla receives focus and diff --git a/doc/ScintillaHistory.html b/doc/ScintillaHistory.html index 4b6b8926d..7e2fc7e2e 100644 --- a/doc/ScintillaHistory.html +++ b/doc/ScintillaHistory.html @@ -551,6 +551,10 @@ Release 4.1.3

    +
  • + Add SCI_SETCOMMANDEVENTS API to allow turning off command events as they + can be a significant performance cost. +
  • Fixed a crash on Cocoa in bidirectional mode where some patterns of invalid UTF-8 caused failures to create Unicode strings. diff --git a/gtk/ScintillaGTK.cxx b/gtk/ScintillaGTK.cxx index 6bcb1ae29..1df3ed4b9 100644 --- a/gtk/ScintillaGTK.cxx +++ b/gtk/ScintillaGTK.cxx @@ -1076,9 +1076,10 @@ void ScintillaGTK::NotifyChange() { } void ScintillaGTK::NotifyFocus(bool focus) { - g_signal_emit(G_OBJECT(sci), scintilla_signals[COMMAND_SIGNAL], 0, - Platform::LongFromTwoShorts - (GetCtrlID(), focus ? SCEN_SETFOCUS : SCEN_KILLFOCUS), PWidget(wMain)); + if (commandEvents) + g_signal_emit(G_OBJECT(sci), scintilla_signals[COMMAND_SIGNAL], 0, + Platform::LongFromTwoShorts + (GetCtrlID(), focus ? SCEN_SETFOCUS : SCEN_KILLFOCUS), PWidget(wMain)); Editor::NotifyFocus(focus); } diff --git a/include/Scintilla.h b/include/Scintilla.h index ccbeef99e..ea8654ce8 100644 --- a/include/Scintilla.h +++ b/include/Scintilla.h @@ -697,6 +697,8 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam, #define SCI_RELEASEDOCUMENT 2377 #define SCI_GETDOCUMENTOPTIONS 2379 #define SCI_GETMODEVENTMASK 2378 +#define SCI_SETCOMMANDEVENTS 2717 +#define SCI_GETCOMMANDEVENTS 2718 #define SCI_SETFOCUS 2380 #define SCI_GETFOCUS 2381 #define SC_STATUS_OK 0 diff --git a/include/Scintilla.iface b/include/Scintilla.iface index 00a4c4ac1..57a2c3b11 100644 --- a/include/Scintilla.iface +++ b/include/Scintilla.iface @@ -1799,6 +1799,12 @@ get int GetDocumentOptions=2379(,) # Get which document modification events are sent to the container. get int GetModEventMask=2378(,) +# Set whether command events are sent to the container. +set void SetCommandEvents=2717(bool commandEvents,) + +# Get whether command events are sent to the container. +get bool GetCommandEvents=2718(,) + # Change internal focus flag. set void SetFocus=2380(bool focus,) # Get internal focus flag. diff --git a/qt/ScintillaEditBase/ScintillaQt.cpp b/qt/ScintillaEditBase/ScintillaQt.cpp index cf4709a0e..8aebb9521 100644 --- a/qt/ScintillaEditBase/ScintillaQt.cpp +++ b/qt/ScintillaEditBase/ScintillaQt.cpp @@ -380,10 +380,12 @@ void ScintillaQt::NotifyChange() void ScintillaQt::NotifyFocus(bool focus) { - emit command( - Platform::LongFromTwoShorts - (GetCtrlID(), focus ? SCEN_SETFOCUS : SCEN_KILLFOCUS), - reinterpret_cast(wMain.GetID())); + if (commandEvents) { + emit command( + Platform::LongFromTwoShorts + (GetCtrlID(), focus ? SCEN_SETFOCUS : SCEN_KILLFOCUS), + reinterpret_cast(wMain.GetID())); + } Editor::NotifyFocus(focus); } diff --git a/src/Editor.cxx b/src/Editor.cxx index ad26a62d8..83cb6fec6 100644 --- a/src/Editor.cxx +++ b/src/Editor.cxx @@ -181,6 +181,7 @@ Editor::Editor() { needIdleStyling = false; modEventMask = SC_MODEVENTMASKALL; + commandEvents = true; pdoc->AddWatcher(this, 0); @@ -2677,9 +2678,11 @@ void Editor::NotifyModified(Document *, DocModification mh, void *) { // If client wants to see this modification if (mh.modificationType & modEventMask) { - if ((mh.modificationType & (SC_MOD_CHANGESTYLE | SC_MOD_CHANGEINDICATOR)) == 0) { - // Real modification made to text of document. - NotifyChange(); // Send EN_CHANGE + if (commandEvents) { + if ((mh.modificationType & (SC_MOD_CHANGESTYLE | SC_MOD_CHANGEINDICATOR)) == 0) { + // Real modification made to text of document. + NotifyChange(); // Send EN_CHANGE + } } SCNotification scn = {}; @@ -7651,6 +7654,13 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { case SCI_GETMODEVENTMASK: return modEventMask; + case SCI_SETCOMMANDEVENTS: + commandEvents = static_cast(wParam); + return 0; + + case SCI_GETCOMMANDEVENTS: + return commandEvents; + case SCI_CONVERTEOLS: pdoc->ConvertLineEnds(static_cast(wParam)); SetSelection(sel.MainCaret(), sel.MainAnchor()); // Ensure selection inside document diff --git a/src/Editor.h b/src/Editor.h index fb892bdcb..a75461afe 100644 --- a/src/Editor.h +++ b/src/Editor.h @@ -229,6 +229,7 @@ protected: // ScintillaBase subclass needs access to much of Editor bool needIdleStyling; int modEventMask; + bool commandEvents; SelectionText drag; diff --git a/win32/ScintillaWin.cxx b/win32/ScintillaWin.cxx index f7f1f7e2c..71b6d9e5e 100644 --- a/win32/ScintillaWin.cxx +++ b/win32/ScintillaWin.cxx @@ -2001,9 +2001,11 @@ void ScintillaWin::NotifyChange() { } void ScintillaWin::NotifyFocus(bool focus) { - ::SendMessage(::GetParent(MainHWND()), WM_COMMAND, - MAKELONG(GetCtrlID(), focus ? SCEN_SETFOCUS : SCEN_KILLFOCUS), - reinterpret_cast(MainHWND())); + if (commandEvents) { + ::SendMessage(::GetParent(MainHWND()), WM_COMMAND, + MAKELONG(GetCtrlID(), focus ? SCEN_SETFOCUS : SCEN_KILLFOCUS), + reinterpret_cast(MainHWND())); + } Editor::NotifyFocus(focus); } -- cgit v1.2.3