From 25a40ab903e04458796be87f12774555d075aee8 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Tue, 23 Jun 2026 10:41:40 +0200 Subject: [PATCH 1/2] fix(developer): resync model and keyboard after device switch in Server When a new OSK is attached, we need to set its active keyboard and lexical model. These are undocumented API contracts between Keyman Engine for Web and Keyman Developer Server, so this appears to have changed in v.19 for keyboards (although the sync is also necessary for v.18). Fixes: #15217 Test-bot: skip --- developer/src/server/src/site/test.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/developer/src/server/src/site/test.js b/developer/src/server/src/site/test.js index eeefd21fced..000a2006323 100644 --- a/developer/src/server/src/site/test.js +++ b/developer/src/server/src/site/test.js @@ -262,6 +262,11 @@ function setupKeyman() { newOSK.setSize(targetDevice.dimensions[0]+'px', targetDevice.dimensions[1]+'px'); } document.getElementById('osk-host').appendChild(newOSK.element); + + // After attaching a new OSK, we also need to set the OSK's active keyboard + // and model + newOSK.activeKeyboard = keyman.contextManager.activeKeyboard; // Note: undocumented KeymanWeb API refs on both sides + selectModel(keyman.core.activeModel?.id); } setOSK(); From db881049e1d75203b9a0df83b03a94dd94281df0 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Thu, 2 Jul 2026 14:55:46 +0200 Subject: [PATCH 2/2] fix(developer): move osk banner resync from Server frontend to Web set osk After review, it is better to do the sync of the model banner in KeymanWeb `set osk()` than in the client of the API. The client should be able to assign a new OSK and have it "just work" without needing to attach things to it. Fixes: #15217 --- developer/src/server/src/site/test.js | 5 ----- web/src/engine/src/main/keymanEngineBase.ts | 2 ++ 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/developer/src/server/src/site/test.js b/developer/src/server/src/site/test.js index 000a2006323..eeefd21fced 100644 --- a/developer/src/server/src/site/test.js +++ b/developer/src/server/src/site/test.js @@ -262,11 +262,6 @@ function setupKeyman() { newOSK.setSize(targetDevice.dimensions[0]+'px', targetDevice.dimensions[1]+'px'); } document.getElementById('osk-host').appendChild(newOSK.element); - - // After attaching a new OSK, we also need to set the OSK's active keyboard - // and model - newOSK.activeKeyboard = keyman.contextManager.activeKeyboard; // Note: undocumented KeymanWeb API refs on both sides - selectModel(keyman.core.activeModel?.id); } setOSK(); diff --git a/web/src/engine/src/main/keymanEngineBase.ts b/web/src/engine/src/main/keymanEngineBase.ts index 268752ad48c..e1095956c91 100644 --- a/web/src/engine/src/main/keymanEngineBase.ts +++ b/web/src/engine/src/main/keymanEngineBase.ts @@ -389,6 +389,8 @@ export class KeymanEngineBase< if (this.contextManager.activeKeyboard) { value.activeKeyboard = this.contextManager.activeKeyboard; } + value.bannerController.selectBanner(this.core.languageProcessor.state); + value.refreshLayout(); value.on('keyevent', this.keyEventListener); this.core.keyboardProcessor.layerStore.handler = value.layerChangeHandler; }