Fix hanging problem while switching back a fully-folded document by using shortcut (Ctrl-TAB)

Use the _isFolding flag to avoid expensive redundant operations that cause an apparent hang when opening or switching tabs to a large fully-folded file.

The released version of Notepad++ uses the _isFolding flag to avoid expensive redundant operations when switching to a fully-folded tab using the mouse pointer.

However, opening a fully-folded file or switching to a fully-folded tab with the keyboard can produce a delay so long that Notepad++ appears to hang forever.

The hang is 100% reproducible and can be demonstrated in less than 60 seconds:

Download a deeply-nested file such as https://raw.githubusercontent.com/notepad-plus-plus/notepad-plus-plus/master/PowerEditor/src/Parameters.cpp or https://github.com/notepad-plus-plus/notepad-plus-plus/files/1555939/nppTest.zip
Open the file in Notepad++ and fold it using Alt-0
Create a new empty tab
Switch back and forth between tabs using the mouse, which is fast
Switch back and forth between tabs using the keyboard (Ctrl-Tab, Ctrl-Page(Up|Down), Ctrl-NumPad[0-9]), which will hang
This pull request applies the existing _isFolding flag to the forgotten keyboard and file open operations and prevents the hang caused by opening or switching tabs to a fully-folded file.

Fix #3996, fix #1128, fix #1806, fix #4871
Close #4867
pull/4771/merge
Chris Cammack 2018-09-22 09:32:00 -07:00 committed by Don HO
parent 84938b7b0f
commit fe458a7072
2 changed files with 14 additions and 0 deletions

View File

@ -773,6 +773,7 @@ void Notepad_plus::command(int id)
{
const int index = id - IDM_VIEW_TAB1;
BufferID buf = _pDocTab->getBufferByIndex(index);
_isFolding = true;
if(buf == BUFFER_INVALID)
{
// No buffer at chosen index, select the very last buffer instead.
@ -781,7 +782,10 @@ void Notepad_plus::command(int id)
switchToFile(_pDocTab->getBufferByIndex(last_index));
}
else
{
switchToFile(buf);
}
_isFolding = false;
}
break;
@ -789,16 +793,21 @@ void Notepad_plus::command(int id)
{
const int current_index = _pDocTab->getCurrentTabIndex();
const int last_index = _pDocTab->getItemCount() - 1;
_isFolding = true;
if(current_index < last_index)
switchToFile(_pDocTab->getBufferByIndex(current_index + 1));
else
{
switchToFile(_pDocTab->getBufferByIndex(0)); // Loop around.
}
_isFolding = false;
}
break;
case IDM_VIEW_TAB_PREV:
{
const int current_index = _pDocTab->getCurrentTabIndex();
_isFolding = true;
if(current_index > 0)
switchToFile(_pDocTab->getBufferByIndex(current_index - 1));
else
@ -806,6 +815,7 @@ void Notepad_plus::command(int id)
const int last_index = _pDocTab->getItemCount() - 1;
switchToFile(_pDocTab->getBufferByIndex(last_index)); // Loop around.
}
_isFolding = false;
}
break;
@ -2899,6 +2909,7 @@ void Notepad_plus::command(int id)
nbDoc += viewVisible(SUB_VIEW)?_subDocTab.nbItem():0;
bool doTaskList = ((NppParameters::getInstance())->getNppGUI())._doTaskList;
_isFolding = true;
if (nbDoc > 1)
{
bool direction = (id == IDC_NEXT_DOC)?dirDown:dirUp;
@ -2917,6 +2928,7 @@ void Notepad_plus::command(int id)
}
}
}
_isFolding = false;
_linkTriggered = true;
}
break;

View File

@ -1556,7 +1556,9 @@ void Notepad_plus::loadLastSession()
const NppGUI & nppGui = nppParams->getNppGUI();
Session lastSession = nppParams->getSession();
bool isSnapshotMode = nppGui.isSnapshotMode();
_isFolding = true;
loadSession(lastSession, isSnapshotMode);
_isFolding = false;
}
bool Notepad_plus::loadSession(Session & session, bool isSnapshotMode)