Fix input methods that depend on OpenKey, Unikey and similar software.

Fix flashing cursor on Windows! How this was not reported?!
Fix crash when closing ecode on Windows and tabs with same name where present.
This commit is contained in:
Martín Lucas Golini
2025-05-24 20:48:42 -03:00
parent d3667b55fd
commit dcea675e5b
10 changed files with 100 additions and 61 deletions

View File

@@ -37,6 +37,10 @@ struct DocumentContentChange {
class EE_API TextDocument {
public:
static bool isTextDocummentCommand( std::string_view cmd );
static bool isTextDocummentCommand( String::HashType cmdHash );
enum class UndoRedo { Undo, Redo };
enum class IndentType { IndentSpaces, IndentTabs };

View File

@@ -920,6 +920,7 @@ class EE_API UICodeEditor : public UIWidget, public TextDocument::Client {
std::vector<PluginRequestedSpace> mPluginTopSpaces;
Float mPluginsTopSpace{ 0 };
Uint64 mLastExecuteEventId{ 0 };
String::HashType mLastCmdHash{ 0 };
Text mLineTextCache;
size_t mJumpLinesLength{ 5 };
UIIcon* mFileLockIcon{ nullptr };

View File

@@ -189,6 +189,7 @@ class EE_API UIConsole : public UIWidget,
Float mQuakeModeHeightPercent{ 0.6f };
#endif
Uint64 mLastExecuteEventId{ 0 };
String::HashType mLastCmdHash{ 0 };
UIPopUpMenu* mCurrentMenu{ nullptr };
size_t mMenuIconSize{ 16 };

View File

@@ -145,6 +145,7 @@ class EE_API UITextInput : public UITextView, public TextDocument::Client {
size_t mMenuIconSize{ 16 };
UIPopUpMenu* mCurrentMenu{ nullptr };
Uint64 mLastExecuteEventId{ 0 };
String::HashType mLastCmdHash{ 0 };
HintDisplay mHintDisplay{ HintDisplay::Always };
void resetWaitCursor();

View File

@@ -26,6 +26,16 @@ namespace EE { namespace UI { namespace Doc {
static constexpr char DEFAULT_NON_WORD_CHARS[] = " \t\n/\\()\"':,.;<>~!@#$%^&*|+=[]{}`?-";
static UnorderedSet<String::HashType> TEXT_DOCUMENT_COMMANDS = {};
bool TextDocument::isTextDocummentCommand( std::string_view cmd ) {
return TEXT_DOCUMENT_COMMANDS.contains( String::hash( cmd ) );
}
bool TextDocument::isTextDocummentCommand( String::HashType cmdHash ) {
return TEXT_DOCUMENT_COMMANDS.contains( cmdHash );
}
bool TextDocument::isNonWord( String::StringBaseType ch ) const {
return mNonWordChars.find_first_of( ch ) != String::InvalidPos;
}
@@ -3793,6 +3803,11 @@ void TextDocument::initializeCommands() {
mCommands["unescape"] = [this] { unescape(); };
mCommands["to-base64"] = [this] { toBase64(); };
mCommands["from-base64"] = [this] { fromBase64(); };
if ( TEXT_DOCUMENT_COMMANDS.empty() ) {
for ( const auto& [cmd, _] : mCommands )
TEXT_DOCUMENT_COMMANDS.insert( String::hash( cmd ) );
}
}
TextRange TextDocument::getTopMostCursor() {

View File

@@ -1078,7 +1078,8 @@ Uint32 UICodeEditor::onTextInput( const TextInputEvent& event ) {
input->isMetaPressed() || ( input->isLeftAltPressed() && !input->isLeftControlPressed() ) )
return 0;
if ( mLastExecuteEventId == getUISceneNode()->getWindow()->getInput()->getEventsSentId() )
if ( mLastExecuteEventId == getUISceneNode()->getWindow()->getInput()->getEventsSentId() &&
!TextDocument::isTextDocummentCommand( mLastCmdHash ) )
return 0;
mDoc->textInput( event.getText() );
@@ -1291,11 +1292,16 @@ Uint32 UICodeEditor::onKeyDown( const KeyEvent& event ) {
// Allow copy selection on locked mode
if ( !mLocked || mUnlockedCmd.find( cmd ) != mUnlockedCmd.end() ) {
mDoc->execute( cmd, this );
mLastCmdHash = String::hash( cmd );
mLastExecuteEventId = getUISceneNode()->getWindow()->getInput()->getEventsSentId();
return 1;
}
}
return 0;
}
Uint32 UICodeEditor::onKeyUp( const KeyEvent& event ) {
if ( isEnabledFlashCursor() && event.getSanitizedMod() == KeyMod::getDefaultModifier() ) {
if ( mModDownCount == 0 )
mModDownClock.restart();
@@ -1312,10 +1318,6 @@ Uint32 UICodeEditor::onKeyDown( const KeyEvent& event ) {
mModDownClock.restart();
}
return 0;
}
Uint32 UICodeEditor::onKeyUp( const KeyEvent& event ) {
mLastActivity.restart();
for ( auto& plugin : mPlugins )
if ( plugin->onKeyUp( this, event ) )

View File

@@ -920,6 +920,7 @@ Uint32 UIConsole::onKeyDown( const KeyEvent& event ) {
std::string cmd = mKeyBindings.getCommandFromKeyBind( { event.getKeyCode(), event.getMod() } );
if ( !cmd.empty() ) {
mDoc.execute( cmd );
mLastCmdHash = String::hash( cmd );
mLastExecuteEventId = getUISceneNode()->getWindow()->getInput()->getEventsSentId();
return 1;
}
@@ -935,7 +936,8 @@ Uint32 UIConsole::onTextInput( const TextInputEvent& event ) {
input->isMetaPressed() || ( input->isLeftAltPressed() && !input->isLeftControlPressed() ) )
return 0;
if ( mLastExecuteEventId == getUISceneNode()->getWindow()->getInput()->getEventsSentId() )
if ( mLastExecuteEventId == getUISceneNode()->getWindow()->getInput()->getEventsSentId() &&
!TextDocument::isTextDocummentCommand( mLastCmdHash ) )
return 0;
const String& text = event.getText();

View File

@@ -770,6 +770,7 @@ Uint32 UITextInput::onKeyDown( const KeyEvent& event ) {
// Allow copy selection on locked mode
if ( mAllowEditing ) {
mDoc.execute( cmd );
mLastCmdHash = String::hash( cmd );
mLastExecuteEventId = getUISceneNode()->getWindow()->getInput()->getEventsSentId();
return 1;
}
@@ -788,7 +789,8 @@ Uint32 UITextInput::onTextInput( const TextInputEvent& event ) {
input->isMetaPressed() || ( input->isLeftAltPressed() && !input->isLeftControlPressed() ) )
return 0;
if ( mLastExecuteEventId == getUISceneNode()->getWindow()->getInput()->getEventsSentId() )
if ( mLastExecuteEventId == getUISceneNode()->getWindow()->getInput()->getEventsSentId() &&
!TextDocument::isTextDocummentCommand( mLastCmdHash ) )
return 0;
const String& text = event.getText();

View File

@@ -1786,67 +1786,73 @@ std::map<KeyBindings::Shortcut, std::string> App::getDefaultKeybindings() {
std::map<KeyBindings::Shortcut, std::string> App::getLocalKeybindings() {
return {
{ { KEY_RETURN, KEYMOD_LALT | KEYMOD_LCTRL }, "fullscreen-toggle" },
{ { KEY_F3, KEYMOD_NONE }, "repeat-find" },
{ { KEY_F3, KEYMOD_SHIFT }, "find-prev" },
{ { KEY_F12, KEYMOD_NONE }, "console-toggle" },
{ { KEY_F, KeyMod::getDefaultModifier() }, "find-replace" },
{ { KEY_Q, KeyMod::getDefaultModifier() | KEYMOD_SHIFT }, "close-app" },
{ { KEY_O, KeyMod::getDefaultModifier() }, "open-file" },
{ { KEY_W, KeyMod::getDefaultModifier() | KEYMOD_SHIFT }, "download-file-web" },
{ { KEY_O, KeyMod::getDefaultModifier() | KEYMOD_SHIFT }, "open-folder" },
{ { KEY_F11, KeyMod::getDefaultModifier() | KEYMOD_SHIFT }, "debug-widget-tree-view" },
{ { KEY_K, KeyMod::getDefaultModifier() }, "open-locatebar" },
{ { KEY_P, KeyMod::getDefaultModifier() }, "open-command-palette" },
{ { KEY_F, KeyMod::getDefaultModifier() | KEYMOD_SHIFT }, "open-global-search" },
{ { KEY_L, KeyMod::getDefaultModifier() }, "go-to-line" },
{ { KEY_F3, KEYMOD_NONE }, "repeat-find" }, { { KEY_F3, KEYMOD_SHIFT }, "find-prev" },
{ { KEY_F12, KEYMOD_NONE }, "console-toggle" },
{ { KEY_F, KeyMod::getDefaultModifier() }, "find-replace" },
{ { KEY_Q, KeyMod::getDefaultModifier() | KEYMOD_SHIFT }, "close-app" },
{ { KEY_O, KeyMod::getDefaultModifier() }, "open-file" },
{ { KEY_W, KeyMod::getDefaultModifier() | KEYMOD_SHIFT }, "download-file-web" },
{ { KEY_O, KeyMod::getDefaultModifier() | KEYMOD_SHIFT }, "open-folder" },
{ { KEY_F11, KeyMod::getDefaultModifier() | KEYMOD_SHIFT }, "debug-widget-tree-view" },
{ { KEY_K, KeyMod::getDefaultModifier() }, "open-locatebar" },
{ { KEY_P, KeyMod::getDefaultModifier() }, "open-command-palette" },
{ { KEY_F, KeyMod::getDefaultModifier() | KEYMOD_SHIFT }, "open-global-search" },
{ { KEY_L, KeyMod::getDefaultModifier() }, "go-to-line" },
#if EE_PLATFORM == EE_PLATFORM_MACOS
{ { KEY_M, KeyMod::getDefaultModifier() | KEYMOD_SHIFT }, "menu-toggle" },
{ { KEY_M, KeyMod::getDefaultModifier() | KEYMOD_SHIFT }, "menu-toggle" },
#else
{ { KEY_M, KeyMod::getDefaultModifier() }, "menu-toggle" },
{ { KEY_M, KeyMod::getDefaultModifier() }, "menu-toggle" },
#endif
{ { KEY_S, KeyMod::getDefaultModifier() | KEYMOD_SHIFT }, "save-all" },
{ { KEY_F9, KEYMOD_LALT }, "switch-side-panel" },
{ { KEY_J, KeyMod::getDefaultModifier() | KEYMOD_LALT | KEYMOD_SHIFT },
"terminal-split-left" },
{ { KEY_L, KeyMod::getDefaultModifier() | KEYMOD_LALT | KEYMOD_SHIFT },
"terminal-split-right" },
{ { KEY_I, KeyMod::getDefaultModifier() | KEYMOD_LALT | KEYMOD_SHIFT },
"terminal-split-top" },
{ { KEY_K, KeyMod::getDefaultModifier() | KEYMOD_LALT | KEYMOD_SHIFT },
"terminal-split-bottom" },
{ { KEY_S, KeyMod::getDefaultModifier() | KEYMOD_LALT | KEYMOD_SHIFT },
"terminal-split-swap" },
{ { KEY_T, KeyMod::getDefaultModifier() | KEYMOD_LALT | KEYMOD_SHIFT },
"reopen-closed-tab" },
{ { KEY_1, KEYMOD_LALT }, "toggle-status-locate-bar" },
{ { KEY_2, KEYMOD_LALT }, "toggle-status-global-search-bar" },
{ { KEY_3, KEYMOD_LALT }, "toggle-status-terminal" },
{ { KEY_4, KEYMOD_LALT }, "toggle-status-build-output" },
{ { KEY_5, KEYMOD_LALT }, "toggle-status-app-output" },
{ { KEY_B, KeyMod::getDefaultModifier() | KEYMOD_SHIFT }, "project-build-start-cancel" },
{ { KEY_C, KeyMod::getDefaultModifier() | KEYMOD_SHIFT }, "project-build-cancel" },
{ { KEY_R, KeyMod::getDefaultModifier() }, "project-build-and-run" },
{ { KEY_O, KEYMOD_LALT | KEYMOD_SHIFT }, "show-open-documents" },
{ { KEY_K, KeyMod::getDefaultModifier() | KEYMOD_SHIFT }, "open-workspace-symbol-search" },
{ { KEY_P, KeyMod::getDefaultModifier() | KEYMOD_SHIFT }, "open-document-symbol-search" },
{ { KEY_N, KEYMOD_SHIFT | KEYMOD_LALT }, "create-new-window" },
{ { KEY_S, KeyMod::getDefaultModifier() | KEYMOD_SHIFT }, "save-all" },
{ { KEY_F9, KEYMOD_LALT }, "switch-side-panel" },
{ { KEY_J, KeyMod::getDefaultModifier() | KEYMOD_LALT | KEYMOD_SHIFT },
"terminal-split-left" },
{ { KEY_L, KeyMod::getDefaultModifier() | KEYMOD_LALT | KEYMOD_SHIFT },
"terminal-split-right" },
{ { KEY_I, KeyMod::getDefaultModifier() | KEYMOD_LALT | KEYMOD_SHIFT },
"terminal-split-top" },
{ { KEY_K, KeyMod::getDefaultModifier() | KEYMOD_LALT | KEYMOD_SHIFT },
"terminal-split-bottom" },
{ { KEY_S, KeyMod::getDefaultModifier() | KEYMOD_LALT | KEYMOD_SHIFT },
"terminal-split-swap" },
{ { KEY_T, KeyMod::getDefaultModifier() | KEYMOD_LALT | KEYMOD_SHIFT },
"reopen-closed-tab" },
{ { KEY_1, KEYMOD_LALT }, "toggle-status-locate-bar" },
{ { KEY_2, KEYMOD_LALT }, "toggle-status-global-search-bar" },
{ { KEY_3, KEYMOD_LALT }, "toggle-status-terminal" },
{ { KEY_4, KEYMOD_LALT }, "toggle-status-build-output" },
{ { KEY_5, KEYMOD_LALT }, "toggle-status-app-output" },
{ { KEY_B, KeyMod::getDefaultModifier() | KEYMOD_SHIFT },
"project-build-start-cancel" },
{ { KEY_C, KeyMod::getDefaultModifier() | KEYMOD_SHIFT }, "project-build-cancel" },
{ { KEY_R, KeyMod::getDefaultModifier() }, "project-build-and-run" },
{ { KEY_O, KEYMOD_LALT | KEYMOD_SHIFT }, "show-open-documents" },
{ { KEY_K, KeyMod::getDefaultModifier() | KEYMOD_SHIFT },
"open-workspace-symbol-search" },
{ { KEY_P, KeyMod::getDefaultModifier() | KEYMOD_SHIFT },
"open-document-symbol-search" },
{ { KEY_N, KEYMOD_SHIFT | KEYMOD_LALT }, "create-new-window" },
};
}
// Old keybindings will be rebinded to the new keybindings when they are still set to the old
// keybindind
std::map<std::string, std::string> App::getMigrateKeybindings() {
return { { "fullscreen-toggle", "alt+return" }, { "switch-to-tab-1", "alt+1" },
{ "switch-to-tab-2", "alt+2" }, { "switch-to-tab-3", "alt+3" },
{ "switch-to-tab-4", "alt+4" }, { "switch-to-tab-5", "alt+5" },
{ "switch-to-tab-6", "alt+6" }, { "switch-to-tab-7", "alt+7" },
{ "switch-to-tab-8", "alt+8" }, { "switch-to-tab-9", "alt+9" },
{ "switch-to-last-tab", "alt+0" },
return {
{ "fullscreen-toggle", "alt+return" }, { "switch-to-tab-1", "alt+1" },
{ "switch-to-tab-2", "alt+2" }, { "switch-to-tab-3", "alt+3" },
{ "switch-to-tab-4", "alt+4" }, { "switch-to-tab-5", "alt+5" },
{ "switch-to-tab-6", "alt+6" }, { "switch-to-tab-7", "alt+7" },
{ "switch-to-tab-8", "alt+8" }, { "switch-to-tab-9", "alt+9" },
{ "switch-to-last-tab", "alt+0" },
#if EE_PLATFORM == EE_PLATFORM_MACOS
{ "menu-toggle", "mod+shift+m" },
{ "menu-toggle", "mod+shift+m" },
#endif
{ "lock-toggle", "mod+shift+l" }, { "debug-widget-tree-view", "f11" },
{ "project-build-and-run", "f5" }, { "project-build-start", "mod+shift+b" } };
{ "lock-toggle", "mod+shift+l" }, { "debug-widget-tree-view", "f11" },
{ "project-build-and-run", "f5" }, {
"project-build-start", "mod+shift+b"
}
};
}
std::vector<std::string> App::getUnlockedCommands() {
@@ -2482,7 +2488,8 @@ void App::onCodeEditorCreated( UICodeEditor* editor, TextDocument& doc ) {
}
editor->on( Event::OnClose, [this, editor]( auto ) {
if ( editor->hasClass( NOT_UNIQUE_FILENAME ) )
if ( SceneManager::existsSingleton() && !SceneManager::instance()->isShuttingDown() &&
editor->hasClass( NOT_UNIQUE_FILENAME ) )
updateNonUniqueTabTitles();
} );
@@ -3491,9 +3498,10 @@ void App::init( const LogLevel& logLevel, std::string file, const Float& pidelDe
mConfig.windowState.pixelDensity =
pidelDensity > 0
? pidelDensity
: ( mConfig.windowState.pixelDensity > 0 ? mConfig.windowState.pixelDensity
: currentDisplay->getPixelDensity() > 2 ? currentDisplay->getPixelDensity() / 2
: currentDisplay->getPixelDensity() );
: ( mConfig.windowState.pixelDensity > 0
? mConfig.windowState.pixelDensity
: currentDisplay->getPixelDensity() > 2 ? currentDisplay->getPixelDensity() / 2
: currentDisplay->getPixelDensity() );
#else
mConfig.windowState.pixelDensity =
pidelDensity > 0

View File

@@ -742,6 +742,9 @@ UIMenu* SettingsMenu::createDocumentMenu() {
mApp->getConfig().workspace.sessionSnapshot = item->isActive();
} else if ( "allow_flash_cursor" == id ) {
mApp->getConfig().editor.flashCursor = item->isActive();
mSplitter->forEachEditor( [this]( UICodeEditor* editor ) {
editor->setEnableFlashCursor( mApp->getConfig().editor.flashCursor );
} );
} else if ( "tab_stops" == id ) {
mApp->getConfig().doc.tabStops = item->isActive();
mSplitter->forEachEditor( [this]( UICodeEditor* editor ) {