diff --git a/bin/assets/colorschemes/colorschemes.conf b/bin/assets/colorschemes/colorschemes.conf index 3a43a445b..70b3f4406 100644 --- a/bin/assets/colorschemes/colorschemes.conf +++ b/bin/assets/colorschemes/colorschemes.conf @@ -160,6 +160,28 @@ string = #b8bb26 operator = #ebdbb2 function = #8ec07c +[gruvbox material dark] +background = #1d2021 +text = #d4be98 +caret = #fbf1c7 +accent = #ebdbb2 +selection = #3c3836 +line_number = #928374 +line_number2 = #ebdbb2 +line_highlight = #32302f + +normal = #d4be98 +symbol = #d4be98 +comment = #a9b665 +keyword = #e86861 +keyword2 = #e78a4e +number = #d3869b +literal = #d3869b +string = #d8a657 +operator = #dd854c +function = #89b482 +minimap_background = #1d2021AA + [liqube] background = #13171e text = #abb2bf diff --git a/include/eepp/ui/uiscenenode.hpp b/include/eepp/ui/uiscenenode.hpp index 2a8d1adbc..d99d1ad55 100644 --- a/include/eepp/ui/uiscenenode.hpp +++ b/include/eepp/ui/uiscenenode.hpp @@ -177,6 +177,8 @@ class EE_API UISceneNode : public SceneNode { bool mIsLoading; bool mVerbose; bool mUpdatingLayouts; + bool mFirstUpdate{ true }; + Clock mClock; UIThemeManager* mUIThemeManager{ nullptr }; UIIconThemeManager* mUIIconThemeManager{ nullptr }; std::vector mFontFaces; diff --git a/src/eepp/system/process.cpp b/src/eepp/system/process.cpp index e8da3c216..d80978085 100644 --- a/src/eepp/system/process.cpp +++ b/src/eepp/system/process.cpp @@ -22,7 +22,7 @@ namespace EE { namespace System { -#define PROCESS_PTR ( (struct subprocess_s*)mProcess ) +#define PROCESS_PTR ( static_cast( mProcess ) ) Process::Process() {} @@ -35,8 +35,10 @@ Process::Process( const std::string& command, const Uint32& options, Process::~Process() { mShuttingDown = true; - if ( mProcess && isAlive() ) + if ( mProcess && isAlive() ) { + subprocess_init_shutdown( PROCESS_PTR ); kill(); + } if ( mStdOutThread.joinable() ) mStdOutThread.join(); if ( mStdErrThread.joinable() ) diff --git a/src/eepp/ui/uicodeeditor.cpp b/src/eepp/ui/uicodeeditor.cpp index 8534b2c27..dd4d26d46 100644 --- a/src/eepp/ui/uicodeeditor.cpp +++ b/src/eepp/ui/uicodeeditor.cpp @@ -440,7 +440,6 @@ bool UICodeEditor::loadAsyncFromFile( } runOnMainThread( [&, onLoaded, wasLocked, success] { invalidateEditor(); - updateLongestLineWidth(); invalidateDraw(); if ( !wasLocked ) setLocked( false ); diff --git a/src/eepp/ui/uiscenenode.cpp b/src/eepp/ui/uiscenenode.cpp index 6d8208827..3fd38d4a6 100644 --- a/src/eepp/ui/uiscenenode.cpp +++ b/src/eepp/ui/uiscenenode.cpp @@ -567,14 +567,28 @@ UISceneNode* UISceneNode::setPixelsSize( const Float& x, const Float& y ) { void UISceneNode::update( const Time& elapsed ) { UISceneNode* uiSceneNode = SceneManager::instance()->getUISceneNode(); + if ( mFirstUpdate && mVerbose ) { + mClock.restart(); + } + SceneManager::instance()->setCurrentUISceneNode( this ); updateDirtyStyles(); updateDirtyStyleStates(); updateDirtyLayouts(); + if ( mFirstUpdate && mVerbose ) { + Log::debug( "UISceneNode::update first update dirty took: %.2f ms", + mClock.getElapsedTime().asMilliseconds() ); + } + SceneNode::update( elapsed ); + if ( mFirstUpdate && mVerbose ) { + Log::debug( "UISceneNode::update first SceneNode::update update took: %.2f ms", + mClock.getElapsedTime().asMilliseconds() ); + } + // We process again all the dirty states since the update could have created new dirty states // that we want to process BEFORE drawing the scene, since we can avoid some resizes/animations // glitches. Also after the SceneNode::update (having run updated the actions, responded to @@ -597,6 +611,12 @@ void UISceneNode::update( const Time& elapsed ) { } SceneManager::instance()->setCurrentUISceneNode( uiSceneNode ); + + if ( mFirstUpdate && mVerbose ) { + mFirstUpdate = false; + Log::debug( "UISceneNode::update first update took: %.2f ms", + mClock.getElapsedTime().asMilliseconds() ); + } } void UISceneNode::onWidgetDelete( Node* node ) { @@ -749,6 +769,7 @@ void UISceneNode::setIsLoading( bool isLoading ) { void UISceneNode::updateDirtyLayouts() { if ( !mDirtyLayouts.empty() ) { + Clock clock; mUpdatingLayouts = true; for ( UILayout* layout : mDirtyLayouts ) { @@ -757,6 +778,9 @@ void UISceneNode::updateDirtyLayouts() { mDirtyLayouts.clear(); mUpdatingLayouts = false; + + if ( mVerbose ) + Log::info( "Layout tree updated in %.2f ms", clock.getElapsedTime().asMilliseconds() ); } } diff --git a/src/eepp/ui/uisplitter.cpp b/src/eepp/ui/uisplitter.cpp index 6a24dbfe8..b74ce54d7 100644 --- a/src/eepp/ui/uisplitter.cpp +++ b/src/eepp/ui/uisplitter.cpp @@ -303,7 +303,7 @@ void UISplitter::updateLayout() { if ( !getParent()->isLayout() && ( !getParent()->asType()->ownsChildPosition() || isGravityOwner() ) ) { bool sizeChanged = false; - Sizef size( getSize() ); + Sizef size( UIWidget::getSize() ); if ( getLayoutWidthPolicy() == SizePolicy::MatchParent && 0 == getLayoutWeight() ) { Float w = getParent()->getSize().getWidth() - mLayoutMargin.Left - mLayoutMargin.Right; @@ -313,7 +313,7 @@ void UISplitter::updateLayout() { w = w - pLay->getPadding().Left - pLay->getPadding().Right; } - if ( (int)w != (int)getSize().getWidth() ) { + if ( (int)w != (int)UIWidget::getSize().getWidth() ) { sizeChanged = true; size.setWidth( w ); } @@ -327,7 +327,7 @@ void UISplitter::updateLayout() { h = h - pLay->getPadding().Top - pLay->getPadding().Bottom; } - if ( (int)h != (int)getSize().getHeight() ) { + if ( (int)h != (int)UIWidget::getSize().getHeight() ) { sizeChanged = true; size.setHeight( h ); } diff --git a/src/thirdparty/subprocess/subprocess.h b/src/thirdparty/subprocess/subprocess.h index 0fb8ff580..90138ddcc 100644 --- a/src/thirdparty/subprocess/subprocess.h +++ b/src/thirdparty/subprocess/subprocess.h @@ -210,6 +210,8 @@ subprocess_write_stdin(struct subprocess_s *const process, char *const buffer, /// @return If the process is still alive non-zero is returned. subprocess_weak int subprocess_alive(struct subprocess_s *const process); +subprocess_weak void subprocess_init_shutdown(struct subprocess_s *const process); + #if defined(__cplusplus) #define SUBPROCESS_CAST(type, x) static_cast(x) #define SUBPROCESS_PTR_CAST(type, x) reinterpret_cast(x) @@ -403,6 +405,7 @@ struct subprocess_s { subprocess_size_t alive; int options; + int shutting_down; }; #ifdef __clang__ #pragma clang diagnostic pop @@ -1347,8 +1350,9 @@ subprocess_write_stdin(struct subprocess_s *const process, char *const buffer, fsync(fd); } else if (ret <= 0) { if (ret == -1) { - if ((errno == EAGAIN ) || (errno == EINPROGRESS)) + if (((errno == EAGAIN ) || (errno == EINPROGRESS)) && !process->shutting_down) { continue; + } return -1; } if (ret == 0) @@ -1359,6 +1363,10 @@ subprocess_write_stdin(struct subprocess_s *const process, char *const buffer, #endif } +subprocess_weak void subprocess_init_shutdown(struct subprocess_s *const process) { + process->shutting_down = 1; +} + #if defined(__cplusplus) } // extern "C" #endif diff --git a/src/tools/ecode/appconfig.cpp b/src/tools/ecode/appconfig.cpp index 23857ecc6..cc206c1da 100644 --- a/src/tools/ecode/appconfig.cpp +++ b/src/tools/ecode/appconfig.cpp @@ -517,8 +517,9 @@ void AppConfig::loadProject( std::string projectFolder, UICodeEditorSplitter* ed return; editorsToLoad = countTotalEditors( j ); - loadDocuments( editorSplitter, pool, j, - editorSplitter->tabWidgetFromWidget( editorSplitter->getCurWidget() ), app ); + UITabWidget* curTabWidget = + editorSplitter->tabWidgetFromWidget( editorSplitter->getCurWidget() ); + loadDocuments( editorSplitter, pool, j, curTabWidget, app ); } } diff --git a/src/tools/ecode/ecode.cpp b/src/tools/ecode/ecode.cpp index afa2fd636..0c9a82525 100644 --- a/src/tools/ecode/ecode.cpp +++ b/src/tools/ecode/ecode.cpp @@ -2776,6 +2776,7 @@ void App::cleanUpRecentFolders() { } void App::loadFolder( const std::string& path ) { + Clock dirTreeClock; if ( !mCurrentProject.empty() ) { closeEditors(); } else { @@ -2792,7 +2793,9 @@ void App::loadFolder( const std::string& path ) { loadDirTree( rpath ); + Clock projClock; mConfig.loadProject( rpath, mSplitter, mConfigPath, mProjectDocConfig, mThreadPool, this ); + Log::info( "Load project took: %.2f ms", projClock.getElapsedTime().asMilliseconds() ); loadFileSystemMatcher( rpath ); diff --git a/src/tools/ecode/plugins/lsp/lspclientserver.cpp b/src/tools/ecode/plugins/lsp/lspclientserver.cpp index fc1f8eb07..8fec94601 100644 --- a/src/tools/ecode/plugins/lsp/lspclientserver.cpp +++ b/src/tools/ecode/plugins/lsp/lspclientserver.cpp @@ -1434,7 +1434,7 @@ LSPClientServer::documentSymbols( const URI& document, LSPClientServer::LSPRequestHandle LSPClientServer::documentSymbolsBroadcast( const URI& document ) { return documentSymbols( document, [this, document]( const PluginIDType& id, - LSPSymbolInformationList&& res ) { + LSPSymbolInformationList&& res ) { getManager()->getPlugin()->setDocumentSymbolsFromResponse( id, document, std::move( res ) ); } ); } @@ -1786,6 +1786,10 @@ static std::vector switchHeaderSourceName( const URI& uri ) { return { basePath + ".cpp" }; } else if ( FileSystem::fileExtension( uri.getPath() ) == "c" ) { return { basePath + ".h" }; + } else if ( FileSystem::fileExtension( uri.getPath() ) == "cc" ) { + return { basePath + ".hh" }; + } else if ( FileSystem::fileExtension( uri.getPath() ) == "hh" ) { + return { basePath + ".cc" }; } else if ( FileSystem::fileExtension( uri.getPath() ) == "h" ) { return { basePath + ".c" }; } @@ -1797,16 +1801,20 @@ void LSPClientServer::switchSourceHeader( const URI& document ) { newRequest( "textDocument/switchSourceHeader", textDocumentURI( document ) ), [this, document]( const IdType&, json res ) { std::vector uris( switchHeaderSourceName( document ) ); - for ( const auto& uri : uris ) { - if ( res.is_string() && - ( uri.empty() || FileSystem::fileNameFromPath( res.get() ) == - FileSystem::fileNameFromPath( uri.getFSPath() ) ) ) { - mManager->goToLocation( { res.get(), TextRange() } ); - break; - } else if ( !uri.empty() ) { - mManager->findAndOpenClosestURI( uris ); - break; + if ( !uris.empty() ) { + for ( const auto& uri : uris ) { + if ( res.is_string() && + ( uri.empty() || FileSystem::fileNameFromPath( res.get() ) == + FileSystem::fileNameFromPath( uri.getFSPath() ) ) ) { + mManager->goToLocation( { res.get(), TextRange() } ); + break; + } else if ( !uri.empty() ) { + mManager->findAndOpenClosestURI( uris ); + break; + } } + } else if ( res.is_string() ) { + mManager->goToLocation( { res.get(), TextRange() } ); } } ); }