Add optional LTO and harden Windows clipboard handling

- add --with-lto support to Premake 4 and 5 release builds
  - use ThinLTO with Clang, automatic LTO with GCC, and LTCG with MSVC
  - exclude Emscripten builds from LTO configuration
  - retry SDL2 clipboard writes on Windows when the clipboard is temporarily unavailable
  - make the UIMergeView copy regression test independent of the system clipboard
This commit is contained in:
Martín Lucas Golini
2026-09-01 00:46:13 -03:00
parent 6e467dbb59
commit 47f9336c0a
4 changed files with 55 additions and 4 deletions
@@ -33,6 +33,17 @@ void ClipboardSDL::setText( const std::string& text ) {
#if EE_PLATFORM == EE_PLATFORM_EMSCRIPTEN
sContent = text;
emscripten_browser_clipboard::copy( text );
#elif EE_PLATFORM == EE_PLATFORM_WIN
// SDL2's Windows backend retries reads when another process owns the clipboard, but not
// writes. Clipboard ownership is transient, so mirror the read-side retry policy here.
static constexpr int MAX_ATTEMPTS = 3;
for ( int attempt = 0; attempt < MAX_ATTEMPTS; ++attempt ) {
if ( SDL_SetClipboardText( text.c_str() ) == 0 )
return;
if ( attempt + 1 < MAX_ATTEMPTS )
SDL_Delay( 10 );
}
Log::warning( "Failed to set clipboard text: %s", SDL_GetError() );
#else
SDL_SetClipboardText( text.c_str() );
#endif
+6 -4
View File
@@ -2,7 +2,6 @@
#include <eepp/ui/doc/syntaxdefinitionmanager.hpp>
#include <eepp/ui/tools/uimergeview.hpp>
#include <eepp/ui/uiapplication.hpp>
#include <eepp/window/clipboard.hpp>
using namespace EE;
using namespace EE::UI;
@@ -82,9 +81,12 @@ UTEST( UIMergeView, UsesSharedResultDocumentAndAcceptIsUndoable ) {
EXPECT_TRUE( view->isToolbarVisible() );
EXPECT_TRUE( view->hasCommand( "merge-accept-left" ) );
auto* leftEditor = view->getLeftEditor();
leftEditor->getDocument().setSelection( { { 0, 0 }, { 0, 4 } } );
leftEditor->getDocument().execute( "copy", leftEditor );
EXPECT_STREQ( "left", app.getWindow()->getClipboard()->getText().c_str() );
auto& leftDocument = leftEditor->getDocument();
// Keep this hermetic: the Windows system clipboard can be temporarily owned by another
// process. The regression is that replacement side documents must retain the copy command.
EXPECT_TRUE( leftDocument.hasCommand( "copy" ) );
leftDocument.setSelection( { { 0, 0 }, { 0, 4 } } );
EXPECT_TRUE( leftDocument.getAllSelectedText() == "left" );
view->setToolbarVisible( false );
EXPECT_FALSE( view->isToolbarVisible() );
view->setToolbarVisible( true );