fix(wasm): KiCad 10 kiplatform/libgit2 stubs, e2e fixtures, asyncify -g hook

- wasm/kiplatform: add EnableDarkMode, IO::TimestampDir, UI::AllowNetworkFileSystems,
  UI::CancelPendingScroll, SECRETS::DeleteSecret (new KiCad 10 functions).
- wasm/stubs/libgit2_stub.c: ~156 no-op stubs for KiCad 10's restructured git
  backend + git-backed local history + text_eval VCS.
- tests/kicad: bump the demo project dir 9.99 -> 10.0 (KiCad 10 stores projects
  under /home/kicad/documents/kicad/10.0/) — fixes load-pcb + 3d-viewer e2e.
- scripts/common/apply-asyncify.sh: ASYNCIFY_EXTRA_OPTS hook (e.g. -g for
  symbolizable wasm traces).
- kicad submodule -> ef00c2d3 (KiCad 10 link + runtime adaptations).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Istvan Matejcsok 2026-06-23 21:23:20 +02:00
commit cdaa96250d
10 changed files with 264 additions and 8 deletions

View file

@ -83,5 +83,12 @@ void AddDynamicLibrarySearchPath( const wxString& aPath )
// No dynamic library loading in WASM
}
void EnableDarkMode( bool aForce )
{
// Native platforms use this to theme window chrome (title bars, etc.).
// In the browser the page/host controls theming via CSS, so this is a no-op.
(void) aForce;
}
} // namespace APP
} // namespace KIPLATFORM

View file

@ -6,7 +6,9 @@
#include <kiplatform/io.h>
#include <wx/string.h>
#include <wx/filename.h>
#include <wx/dir.h>
#include <stdio.h>
#include <sys/stat.h>
namespace KIPLATFORM
{
@ -45,5 +47,38 @@ void LongPathAdjustment( wxFileName& aFilename )
// No-op on non-Windows platforms
}
long long TimestampDir( const wxString& aDirPath, const wxString& aFilespec )
{
// Mirror the native implementations: accumulate (mtime, size) over files
// matching the spec so callers can detect library-directory changes. The
// Emscripten virtual filesystem supports stat(), so this works for MEMFS-
// backed local libraries (git/network libraries are handled JS-side).
long long timestamp = 0;
wxDir dir( aDirPath );
if( !dir.IsOpened() )
return timestamp;
wxString filename;
bool cont = dir.GetFirst( &filename, aFilespec, wxDIR_FILES );
while( cont )
{
wxString fullPath = aDirPath + wxFILE_SEP_PATH + filename;
struct stat entryStat;
if( stat( fullPath.fn_str(), &entryStat ) == 0 )
{
timestamp += static_cast<long long>( entryStat.st_mtime ) * 1000;
timestamp += entryStat.st_size;
}
cont = dir.GetNext( &filename );
}
return timestamp;
}
} // namespace IO
} // namespace KIPLATFORM

View file

@ -72,5 +72,26 @@ bool GetSecret( const wxString& aService, const wxString& aKey, wxString& aSecre
#endif
}
bool DeleteSecret( const wxString& aService, const wxString& aKey )
{
#ifdef __EMSCRIPTEN__
int result = EM_ASM_INT({
try {
var service = UTF8ToString($0);
var key = UTF8ToString($1);
var storageKey = 'kicad_secret_' + service + '_' + key;
localStorage.removeItem(storageKey);
return 1;
} catch(e) {
console.warn('Failed to delete secret:', e);
return 0;
}
}, aService.utf8_str().data(), aKey.utf8_str().data());
return result == 1;
#else
return false;
#endif
}
} // namespace SECRETS
} // namespace KIPLATFORM

View file

@ -191,5 +191,21 @@ void SetFloatLevel( wxWindow* aWindow )
// No floating window levels in browser
}
void AllowNetworkFileSystems( wxDialog* aDialog )
{
// Native platforms use this to let file dialogs browse network mounts.
// The browser's file dialogs are virtual (MEMFS / JS bridge), so this is
// a no-op.
(void) aDialog;
}
void CancelPendingScroll( wxDataViewCtrl* aCtrl )
{
// Native (GTK/macOS) platforms cancel an in-flight kinetic/async scroll on
// the data view. The browser wx port has no such pending-scroll state, so
// this is a no-op.
(void) aCtrl;
}
} // namespace UI
} // namespace KIPLATFORM