From ffe2ddace3959bf7afd988aab690ba01f411ee98 Mon Sep 17 00:00:00 2001 From: Eduard Braun Date: Fri, 24 Feb 2017 23:47:19 +0100 Subject: [PATCH] Fix flickering issue if Doc is deleted from outside Improve behavior when notifying the user about a buffer change (opened file changed or deleted) - Restore the Notepad++ window and switch to the document in question *before* showing the dialog (this was only done afterwards before) - Fix flickering issue described in #1018 and #2010 which was exposed by f2cd7790669ec3867977293f5c83bdec235b81b5 Closes #2956 --- PowerEditor/src/Notepad_plus.cpp | 70 ++++++++++++-------------------- PowerEditor/src/Notepad_plus.h | 1 + 2 files changed, 28 insertions(+), 43 deletions(-) diff --git a/PowerEditor/src/Notepad_plus.cpp b/PowerEditor/src/Notepad_plus.cpp index ac40b341..e575b45f 100644 --- a/PowerEditor/src/Notepad_plus.cpp +++ b/PowerEditor/src/Notepad_plus.cpp @@ -4963,6 +4963,27 @@ void Notepad_plus::drawTabbarColoursFromStylerArray() TabBarPlus::setColour(stInact->_bgColor, TabBarPlus::inactiveBg); } +void Notepad_plus::prepareBufferChangedDialog(Buffer * buffer) +{ + // immediately show window if it was minimized before + if (::IsIconic(_pPublicInterface->getHSelf())) + ::ShowWindow(_pPublicInterface->getHSelf(), SW_RESTORE); + + // switch to the file that changed + int index = _pDocTab->getIndexByBuffer(buffer->getID()); + int iView = currentView(); + if (index == -1) + iView = otherView(); + activateBuffer(buffer->getID(), iView); //activate the buffer in the first view possible + + // prevent flickering issue by "manually" clicking and activating the _pEditView + // (mouse events seem to get lost / improperly handled when showing the dialog) + auto curPos = _pEditView->execute(SCI_GETCURRENTPOS); + ::PostMessage(_pEditView->getHSelf(), WM_LBUTTONDOWN, 0, 0); + ::PostMessage(_pEditView->getHSelf(), WM_LBUTTONUP, 0, 0); + ::PostMessage(_pEditView->getHSelf(), SCI_SETSEL, curPos, curPos); +} + void Notepad_plus::notifyBufferChanged(Buffer * buffer, int mask) { // To avoid to crash while MS-DOS style is set as default language, @@ -4983,8 +5004,6 @@ void Notepad_plus::notifyBufferChanged(Buffer * buffer, int mask) //Only event that applies to non-active Buffers if (mask & BufferChangeStatus) { //reload etc - bool didDialog = false; - bool doCloseDoc = false; switch(buffer->getStatus()) { case DOC_UNNAMED: //nothing todo @@ -4997,28 +5016,9 @@ void Notepad_plus::notifyBufferChanged(Buffer * buffer, int mask) bool autoUpdate = (nppGUI._fileAutoDetection == cdAutoUpdate) || (nppGUI._fileAutoDetection == cdAutoUpdateGo2end); if (!autoUpdate || buffer->isDirty()) { - // if file updating is not silently, we switch to the file to update. - int index = _pDocTab->getIndexByBuffer(buffer->getID()); - int iView = currentView(); - if (index == -1) - iView = otherView(); - activateBuffer(buffer->getID(), iView); //activate the buffer in the first view possible - - // Then we ask user to update - didDialog = true; - - // This section deal with the flicking issue which was caused by f2cd779 (discussed in detail @ #1018) - // Idea is : - // 1. First get the current caret position. - // 2. Send WM_LBUTTONDOWN and WM_LBUTTONUP message (which acts as double click at 0,0) - // 3. Now set caret back to original position. - // - auto curPos = _pEditView->execute(SCI_GETCURRENTPOS); - ::PostMessage(_pEditView->getHSelf(), WM_LBUTTONDOWN, 0, 0); - ::PostMessage(_pEditView->getHSelf(), WM_LBUTTONUP, 0, 0); - ::PostMessage(_pEditView->getHSelf(), SCI_SETSEL, curPos, curPos); - // Now the flickering issue is not seen. + prepareBufferChangedDialog(buffer); + // Then we ask user to update if (doReloadOrNot(buffer->getFullPathName(), buffer->isDirty()) != IDYES) break; //abort } @@ -5050,42 +5050,26 @@ void Notepad_plus::notifyBufferChanged(Buffer * buffer, int mask) } case DOC_DELETED: //ask for keep { + prepareBufferChangedDialog(buffer); + SCNotification scnN; scnN.nmhdr.code = NPPN_FILEDELETED; scnN.nmhdr.hwndFrom = _pPublicInterface->getHSelf(); scnN.nmhdr.idFrom = (uptr_t)buffer->getID(); _pluginsManager.notify(&scnN); - int index = _pDocTab->getIndexByBuffer(buffer->getID()); - int iView = currentView(); - if (index == -1) - iView = otherView(); - - activateBuffer(buffer->getID(), iView); //activate the buffer in the first view possible - didDialog = true; - doCloseDoc = doCloseOrNot(buffer->getFullPathName()) == IDNO; + int doCloseDoc = doCloseOrNot(buffer->getFullPathName()) == IDNO; if (doCloseDoc) { //close in both views, doing current view last since that has to remain opened bool isSnapshotMode = nppGUI.isSnapshotMode(); doClose(buffer->getID(), otherView(), isSnapshotMode); doClose(buffer->getID(), currentView(), isSnapshotMode); + return; } break; } } - - if (didDialog) - { - auto curPos = _pEditView->execute(SCI_GETCURRENTPOS); - ::PostMessage(_pEditView->getHSelf(), WM_LBUTTONUP, 0, 0); - ::PostMessage(_pEditView->getHSelf(), SCI_SETSEL, curPos, curPos); - if (::IsIconic(_pPublicInterface->getHSelf())) - ::ShowWindow(_pPublicInterface->getHSelf(), SW_RESTORE); - - if (doCloseDoc) // buffer has been deleted, cannot (and no need to) go on - return; - } } if (mask & (BufferChangeReadonly)) diff --git a/PowerEditor/src/Notepad_plus.h b/PowerEditor/src/Notepad_plus.h index 42b23a3e..1251c9bd 100644 --- a/PowerEditor/src/Notepad_plus.h +++ b/PowerEditor/src/Notepad_plus.h @@ -207,6 +207,7 @@ public: void loadLastSession(); bool loadSession(Session & session, bool isSnapshotMode = false); + void prepareBufferChangedDialog(Buffer * buffer); void notifyBufferChanged(Buffer * buffer, int mask); bool findInFinderFiles(FindersInfo *findInFolderInfo); bool findInFiles();