Skip to content

Commit

Permalink
#5337: Add loopback guard to PrefabSelector::handleSelectionChange. I…
Browse files Browse the repository at this point in the history
…t doesn't occur anymore after the changes to MapFileProgressHandler, but it still provides additional protection.
  • Loading branch information
codereader committed Sep 20, 2020
1 parent 661ad35 commit 8a444bd
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 8 deletions.
10 changes: 7 additions & 3 deletions radiant/ui/MapFileProgressHandler.cpp
Expand Up @@ -53,6 +53,11 @@ void MapFileProgressHandler::dispatchWithLockAndCatch(const std::function<void()

void MapFileProgressHandler::handleFileOperation(map::FileOperation& msg)
{
if (registry::getValue<bool>(RKEY_MAP_SUPPRESS_LOAD_STATUS_DIALOG))
{
return; // no progress dialog enabled
}

auto lock = std::make_unique< std::lock_guard<std::mutex> >(_lock);

// A previous _blocker update might indicate a cancel operation, propagate this info
Expand All @@ -75,8 +80,7 @@ void MapFileProgressHandler::handleFileOperation(map::FileOperation& msg)
dispatchWithLockAndCatch([title, this]()
{
// Level might have been decreased in the meantime, check it
if (_level > 0 && GlobalMainFrame().isActiveApp() &&
!registry::getValue<bool>(RKEY_MAP_SUPPRESS_LOAD_STATUS_DIALOG))
if (_level > 0 && GlobalMainFrame().isActiveApp())
{
_blocker.reset(new ScreenUpdateBlocker(title, _("Processing..."), true));
}
Expand Down Expand Up @@ -129,7 +133,7 @@ void MapFileProgressHandler::handleFileOperation(map::FileOperation& msg)
// Release the lock, and give the UI a chance to process
lock.reset();

wxTheApp->Yield();
wxTheApp->ProcessPendingEvents();
}

}
6 changes: 3 additions & 3 deletions radiant/ui/mainframe/ScreenUpdateBlocker.cpp
Expand Up @@ -22,9 +22,6 @@ ScreenUpdateBlocker::ScreenUpdateBlocker(const std::string& title, const std::st
showModalProgressDialog();
}

// Process pending events to fully show the dialog
wxTheApp->Yield(true);

// Register for the "is-active" changed event, to display this dialog
// as soon as Radiant is getting the focus again
GlobalMainFrame().getWxTopLevelWindow()->Bind(wxEVT_SET_FOCUS, &ScreenUpdateBlocker::onMainWindowFocus, this);
Expand All @@ -41,6 +38,9 @@ void ScreenUpdateBlocker::showModalProgressDialog()

// Eat all window events
_disabler.reset(new wxWindowDisabler(_dialog));

// Process pending events to fully show the dialog
wxTheApp->Yield(true);
}

ScreenUpdateBlocker::~ScreenUpdateBlocker()
Expand Down
13 changes: 11 additions & 2 deletions radiant/ui/prefabselector/PrefabSelector.cpp
Expand Up @@ -29,6 +29,7 @@

#include "string/trim.h"
#include "string/case_conv.h"
#include "util/ScopedBoolLock.h"
#include <functional>

namespace ui
Expand Down Expand Up @@ -63,7 +64,8 @@ PrefabSelector::PrefabSelector() :
_useRecentPath(nullptr),
_recentPathSelector(nullptr),
_customPath(nullptr),
_insertAsGroupBox(nullptr)
_insertAsGroupBox(nullptr),
_handlingSelectionChange(false)
{
SetSizer(new wxBoxSizer(wxVERTICAL));

Expand Down Expand Up @@ -466,7 +468,14 @@ void PrefabSelector::clearPreview()

void PrefabSelector::handleSelectionChange()
{
wxDataViewItem item = _treeView->GetSelection();
if (_handlingSelectionChange)
{
return;
}

util::ScopedBoolLock lock(_handlingSelectionChange);

wxDataViewItem item = _treeView->GetSelection();

if (!item.IsOk())
{
Expand Down
2 changes: 2 additions & 0 deletions radiant/ui/prefabselector/PrefabSelector.h
Expand Up @@ -91,6 +91,8 @@ class PrefabSelector :

std::list<std::string> _recentPaths;

bool _handlingSelectionChange;

private:
// Private constructor, creates widgets
PrefabSelector();
Expand Down

0 comments on commit 8a444bd

Please sign in to comment.