fix(theme): stop the boot theme re-send from resurrecting hidden chrome
Since comments-ux 0002, WasmTool re-sends the shell theme through kicadSetColorTheme on every boot; setColorTheme ran CommonSettingsChanged unconditionally, which recreates the menubar/toolbars — and they come back SHOWN, undoing the kicadSetChrome(false) the read-only viewer and mobile canvas-only mode applied moments earlier (CI: read-only-editor + mobile-editor "9 visible menu titles"). Two-part fix in pcbjam_theme: - early-out when the requested theme AND the wx dark-chrome flag are already applied — the every-boot re-send (still needed for warm relaunches with stale MEMFS settings) becomes a true no-op; - after a REAL apply, re-assert the hidden chrome via a hook the merged image installs (kicadSetChrome(false) when the snapshot says hidden), queued with CallAfter from inside the fiber body so FIFO lands it behind the CallAfter-deferred ReCreateMenuBar. Covers viewers/mobile users toggling dark mode mid-session. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Y32etYBCKV6t1qDoLoGmgF
This commit is contained in:
parent
3ff53f0a78
commit
b0e84ff849
2 changed files with 52 additions and 6 deletions
|
|
@ -83,6 +83,14 @@ bool pcbCollabTestClearSelection();
|
|||
void pcbSetColorTheme( std::string aTheme );
|
||||
void pcbSetDarkChrome( bool aDark );
|
||||
|
||||
// Post-theme-apply hook shared with pcbjam_theme.h — identical inline-variable
|
||||
// definition instead of including that header (this TU stays header-light);
|
||||
// keep the two declarations in sync.
|
||||
namespace pcbjam_theme
|
||||
{
|
||||
inline void ( *g_afterThemeApplied )() = nullptr;
|
||||
}
|
||||
|
||||
bool schEditorActive();
|
||||
int schLibsSymbolUsage( std::string aLibNickname, std::string aSymbolName );
|
||||
void schCollabApply( std::string aJson );
|
||||
|
|
@ -398,6 +406,15 @@ static void collabSetStyle( std::string aJson )
|
|||
// Each side no-ops on a null frame.
|
||||
static void setColorTheme( std::string aTheme )
|
||||
{
|
||||
// A real theme apply rebuilds the menubar/toolbars, which come back
|
||||
// SHOWN — re-hide them when the chrome is supposed to be hidden
|
||||
// (read-only viewer / mobile canvas-only). Installed here, not in
|
||||
// pcbjam_theme.h, because the chrome snapshot is merged-image state.
|
||||
pcbjam_theme::g_afterThemeApplied = []() {
|
||||
if( s_chromeSnap.valid )
|
||||
kicadSetChrome( false );
|
||||
};
|
||||
|
||||
pcbSetColorTheme( aTheme );
|
||||
schSetColorTheme( aTheme );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,6 +31,17 @@ extern "C" bool wxWasmGetDarkAppearance();
|
|||
|
||||
namespace pcbjam_theme {
|
||||
|
||||
/** Merged-image hook (installed by kicad_editor_embind.cpp): re-assert the
|
||||
* canvas-only chrome state after a theme apply. CommonSettingsChanged
|
||||
* recreates the menubar (CallAfter-deferred, eda_base_frame.cpp) and the
|
||||
* toolbars, and they come back SHOWN — without this, a theme apply
|
||||
* resurrects the chrome kicadSetChrome(false) hid (read-only viewer /
|
||||
* mobile canvas-only). Inline variable: the dispatcher TU re-declares the
|
||||
* identical definition instead of including this (deliberately
|
||||
* header-light) — keep the two in sync. Null in the standalone bundles,
|
||||
* which have no chrome API. */
|
||||
inline void ( *g_afterThemeApplied )() = nullptr;
|
||||
|
||||
/** Set the chrome appearance FLAG only — no widget traffic, no fiber. Safe
|
||||
* from the browser main thread at any point (it writes one bool in shared
|
||||
* wasm memory); the embedder calls it at onRuntimeInitialized, BEFORE main()
|
||||
|
|
@ -77,22 +88,40 @@ inline void setColorTheme( EDA_DRAW_FRAME* aFrame, const std::string& aTheme )
|
|||
return;
|
||||
|
||||
pcbjam_collab::runOnFiber( aFrame, [aFrame, aTheme]() {
|
||||
if( APP_SETTINGS_BASE* cfg = aFrame->config() )
|
||||
// The shell only ever sends our dark theme name or the builtin
|
||||
// default, so the chrome appearance rides on that distinction.
|
||||
const bool dark = aTheme != "_builtin_default";
|
||||
const wxString theme = wxString::FromUTF8( aTheme.c_str() );
|
||||
APP_SETTINGS_BASE* cfg = aFrame->config();
|
||||
|
||||
// The shell re-sends its theme on EVERY boot (a warm relaunch can
|
||||
// have stale MEMFS settings from a HomePage theme switch) — skip the
|
||||
// apply when nothing changes: CommonSettingsChanged below is not
|
||||
// free, it rebuilds the menubar and toolbars.
|
||||
if( cfg && cfg->m_ColorTheme == theme && dark == wxWasmGetDarkAppearance() )
|
||||
return;
|
||||
|
||||
if( cfg )
|
||||
{
|
||||
cfg->m_ColorTheme = wxString::FromUTF8( aTheme.c_str() );
|
||||
cfg->m_ColorTheme = theme;
|
||||
// Persist now — wasm sessions never exit cleanly, so the normal
|
||||
// save-on-close path would lose the choice.
|
||||
Pgm().GetSettingsManager().Save( cfg );
|
||||
}
|
||||
|
||||
// wx chrome first (panels/toolbars), then the GAL canvas colors. The
|
||||
// shell only ever sends our dark theme name or the builtin default,
|
||||
// so the chrome appearance rides on that distinction.
|
||||
syncChromeAppearance( aTheme != "_builtin_default" );
|
||||
// wx chrome first (panels/toolbars), then the GAL canvas colors.
|
||||
syncChromeAppearance( dark );
|
||||
|
||||
// 0 flags: no env/text vars changed; the frame's override chain still
|
||||
// unconditionally reloads colors and recaches the view.
|
||||
aFrame->CommonSettingsChanged( 0 );
|
||||
|
||||
// Queued from INSIDE the fiber body, AFTER CommonSettingsChanged: the
|
||||
// menubar rebuild it triggers is itself a CallAfter on this same
|
||||
// handler, so FIFO puts the re-assert behind the rebuilt (shown)
|
||||
// menubar.
|
||||
if( void ( *hook )() = g_afterThemeApplied )
|
||||
aFrame->CallAfter( hook );
|
||||
} );
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue