Fix invalid memory access when Event::OnDocumentChange is processed in LSPClientPlugin.

Some refactor of Keyboards Shortcuts.
This commit is contained in:
Martín Lucas Golini
2024-09-25 20:56:05 -03:00
parent f433141837
commit 92291448c0
5 changed files with 39 additions and 12 deletions

View File

@@ -37,6 +37,11 @@ class EE_API KeyBindings {
static std::string keybindFormat( std::string str );
static Shortcut toShortcut( const Window::Input* input, const std::string& keys );
static std::string fromShortcut( const Window::Input* input, KeyBindings::Shortcut shortcut,
bool format = false );
KeyBindings( const Window::Input* input );
void addKeybindsString( const std::map<std::string, std::string>& binds );

View File

@@ -136,6 +136,18 @@ class EE_API DocEvent : public Event {
TextDocument* doc;
};
class EE_API DocChangedEvent : public DocEvent {
public:
DocChangedEvent( Node* node, TextDocument* doc, const Uint32& eventType, URI oldDocURI ) :
DocEvent( node, doc, eventType ), mOldDocURI( oldDocURI ) {}
const URI& getOldDocURI() const { return mOldDocURI; }
protected:
TextDocument* doc;
URI mOldDocURI;
};
class EE_API DocSyntaxDefEvent : public DocEvent {
public:
DocSyntaxDefEvent( Node* node, TextDocument* doc, const Uint32& eventType,
@@ -990,7 +1002,7 @@ class EE_API UICodeEditor : public UIWidget, public TextDocument::Client {
virtual void onDocumentReset( TextDocument* );
virtual void onDocumentChanged();
virtual void onDocumentChanged( URI oldDocURI );
virtual void onFoldRegionsUpdated( size_t oldCount, size_t newCount );

View File

@@ -76,7 +76,8 @@ void KeyBindings::replaceKeybind( const KeyBindings::Shortcut& keys, const std::
mKeybindingsInvert[command] = sanitizeShortcut( keys );
}
KeyBindings::Shortcut KeyBindings::getShortcutFromString( const std::string& keys ) {
KeyBindings::Shortcut KeyBindings::toShortcut( const Window::Input* input,
const std::string& keys ) {
Shortcut shortcut;
Uint32 mod = 0;
auto keysSplit = String::split( keys, '+' );
@@ -89,12 +90,16 @@ KeyBindings::Shortcut KeyBindings::getShortcutFromString( const std::string& key
if ( ( mod = KeyMod::getKeyMod( part ) ) ) {
shortcut.mod |= mod;
} else {
shortcut.key = mInput->getKeyFromName( part );
shortcut.key = input->getKeyFromName( part );
}
}
return shortcut;
}
KeyBindings::Shortcut KeyBindings::getShortcutFromString( const std::string& keys ) {
return toShortcut( mInput, keys );
}
void KeyBindings::removeKeybind( const KeyBindings::Shortcut& keys ) {
auto it = mShortcuts.find( keys.toUint64() );
if ( it != mShortcuts.end() ) {
@@ -163,9 +168,10 @@ const std::map<std::string, Uint64> KeyBindings::getKeybindings() const {
return mKeybindingsInvert;
}
std::string KeyBindings::getShortcutString( KeyBindings::Shortcut shortcut, bool format ) const {
std::string KeyBindings::fromShortcut( const Window::Input* input, KeyBindings::Shortcut shortcut,
bool format ) {
std::vector<std::string> mods;
std::string keyname( String::toLower( mInput->getKeyName( shortcut.key ) ) );
std::string keyname( String::toLower( input->getKeyName( shortcut.key ) ) );
const auto& MOD_MAP = KeyMod::getModMap();
if ( shortcut.mod & MOD_MAP.at( "mod" ) )
mods.emplace_back( "mod" );
@@ -185,4 +191,8 @@ std::string KeyBindings::getShortcutString( KeyBindings::Shortcut shortcut, bool
return format ? keybindFormat( ret ) : ret;
}
std::string KeyBindings::getShortcutString( KeyBindings::Shortcut shortcut, bool format ) const {
return fromShortcut( mInput, shortcut, format );
}
}} // namespace EE::UI

View File

@@ -654,10 +654,10 @@ void UICodeEditor::onDocumentReset( TextDocument* ) {
findRegionsDelayed();
}
void UICodeEditor::onDocumentChanged() {
void UICodeEditor::onDocumentChanged( URI oldDocURI ) {
if ( mFindReplace )
mFindReplace->setDoc( mDoc );
DocEvent event( this, mDoc.get(), Event::OnDocumentChanged );
DocChangedEvent event( this, mDoc.get(), Event::OnDocumentChanged, oldDocURI );
sendEvent( &event );
}
@@ -942,6 +942,7 @@ TextDocument& UICodeEditor::getDocument() {
void UICodeEditor::setDocument( std::shared_ptr<TextDocument> doc ) {
if ( mDoc.get() != doc.get() ) {
URI oldDocURI = mDoc->getURI();
mDoc->unregisterClient( this );
mDocView.setDocument( nullptr );
if ( mDoc.use_count() == 1 )
@@ -949,7 +950,7 @@ void UICodeEditor::setDocument( std::shared_ptr<TextDocument> doc ) {
mDoc = doc;
mDoc->registerClient( this );
mDocView.setDocument( doc );
onDocumentChanged();
onDocumentChanged( oldDocURI );
if ( mDoc->isLoading() ) {
mInvalidateOnLoaded = true;
} else {

View File

@@ -1479,20 +1479,19 @@ void LSPClientPlugin::onRegister( UICodeEditor* editor ) {
} ) );
listeners.push_back(
editor->addEventListener( Event::OnDocumentChanged, [this, editor]( const Event* ) {
editor->addEventListener( Event::OnDocumentChanged, [this, editor]( const Event* event ) {
const DocChangedEvent* docChangedEvent = static_cast<const DocChangedEvent*>( event );
TextDocument* oldDoc = mEditorDocs[editor];
TextDocument* newDoc = editor->getDocumentRef().get();
URI docURI;
{
Lock l( mDocMutex );
docURI = oldDoc->getURI();
mDocs.erase( oldDoc );
mEditorDocs[editor] = newDoc;
}
{
Lock l( mDocCurrentSymbolsMutex );
mDocCurrentSymbols.erase( docURI );
mDocCurrentSymbols.erase( docChangedEvent->getOldDocURI() );
}
updateCurrentSymbol( editor->getDocument() );