diff --git a/web/src/engine/osk/src/keyboard-layout/oskLayer.ts b/web/src/engine/osk/src/keyboard-layout/oskLayer.ts index 9f9486e28e1..3f73620949b 100644 --- a/web/src/engine/osk/src/keyboard-layout/oskLayer.ts +++ b/web/src/engine/osk/src/keyboard-layout/oskLayer.ts @@ -4,6 +4,11 @@ import OSKRow from './oskRow.js'; import OSKBaseKey from './oskBaseKey.js'; import VisualKeyboard from '../visualKeyboard.js'; +export interface LayerLayoutParams { + keyboardHeight: number; + spacebarText: string; +} + export default class OSKLayer { public readonly element: HTMLDivElement; public readonly rows: OSKRow[]; @@ -76,6 +81,21 @@ export default class OSKLayer { this.capsKey = this.findKey('K_CAPS'); this.numKey = this.findKey('K_NUMLOCK'); this.scrollKey = this.findKey('K_SCROLL'); + + if(this.spaceBarKey) { + const spacebarLabel = this.spaceBarKey.label; + let tButton = this.spaceBarKey.btn; + + if (typeof (tButton.className) == 'undefined' || tButton.className == '') { + tButton.className = 'kmw-spacebar'; + } else if (tButton.className.indexOf('kmw-spacebar') == -1) { + tButton.className += ' kmw-spacebar'; + } + + if (spacebarLabel.className != 'kmw-spacebar-caption') { + spacebarLabel.className = 'kmw-spacebar-caption'; + } + } } /** @@ -96,7 +116,35 @@ export default class OSKLayer { return null; } - public refreshLayout(vkbd: VisualKeyboard, layerHeight: number) { + /** + * Indicate the current language and keyboard on the space bar + **/ + showLanguage(displayName: string) { + if(!this.spaceBarKey) { + return () => {}; + } + + try { + const spacebarLabel = this.spaceBarKey.label; + + // The key can read the text from here during the display update without us + // needing to trigger a reflow by running the closure below early. + this.spaceBarKey.spec.text = displayName; + + // It sounds redundant, but this dramatically cuts down on browser DOM processing; + // but sometimes innerText is reported empty when it actually isn't, so set it + // anyway in that case (Safari, iOS 14.4) + if (spacebarLabel.innerText != displayName || displayName == '') { + spacebarLabel.innerText = displayName; + } + } + catch (ex) { } + } + + public refreshLayout(vkbd: VisualKeyboard, layoutParams: LayerLayoutParams) { + const layerHeight = layoutParams.keyboardHeight; + this.showLanguage(layoutParams.spacebarText); + // Check the heights of each row, in case different layers have different row counts. const nRows = this.rows.length; const rowHeight = this._rowHeight = Math.floor(layerHeight/(nRows == 0 ? 1 : nRows)); diff --git a/web/src/engine/osk/src/views/oskView.ts b/web/src/engine/osk/src/views/oskView.ts index 760a664e123..e7c6ecdd0d6 100644 --- a/web/src/engine/osk/src/views/oskView.ts +++ b/web/src/engine/osk/src/views/oskView.ts @@ -658,6 +658,7 @@ export default abstract class OSKView if(this.bannerView.height > 0) { availableHeight -= this.bannerView.height + 5; } + // Triggers the VisualKeyboard.refreshLayout() method, which includes a showLanguage() call. this.vkbd.setSize(this.computedWidth, availableHeight, pending); const bs = this._Box.style; @@ -665,9 +666,6 @@ export default abstract class OSKView // visualizations, not to help text or empty views. bs.width = bs.maxWidth = this.computedWidth + 'px'; bs.height = bs.maxHeight = this.computedHeight + 'px'; - - // Ensure that the layer's spacebar is properly captioned. - this.vkbd.showLanguage(); } else { const bs = this._Box.style; bs.width = 'auto'; @@ -855,9 +853,8 @@ export default abstract class OSKView // Also, only change the layer ID itself if there is an actual corresponding layer // in the OSK. if(this.vkbd?.layerGroup.layers[newValue] && !this.vkbd?.layerLocked) { + // triggers state-update + layer refresh automatically. this.vkbd.layerId = newValue; - // Ensure that the layer's spacebar is properly captioned. - this.vkbd.showLanguage(); } // Ensure the keyboard view is modeling the correct state. (Correct layer, etc.) @@ -892,10 +889,6 @@ export default abstract class OSKView // First thing after it's made visible. this.refreshLayoutIfNeeded(); - if(this.keyboardView instanceof VisualKeyboard) { - this.keyboardView.showLanguage(); - } - this._Visible=true; /* In case it's still '0' from a hide() operation. diff --git a/web/src/engine/osk/src/visualKeyboard.ts b/web/src/engine/osk/src/visualKeyboard.ts index bb90538f299..89253ea8f5d 100644 --- a/web/src/engine/osk/src/visualKeyboard.ts +++ b/web/src/engine/osk/src/visualKeyboard.ts @@ -1115,38 +1115,6 @@ export default class VisualKeyboard extends EventEmitter implements Ke //#endregion - /** - * Indicate the current language and keyboard on the space bar - **/ - showLanguage() { - let activeStub = this.layoutKeyboardProperties; - let displayName: string = activeStub?.displayName ?? '(System keyboard)'; - - try { - var t = this.spaceBar.key.label; - let tParent = t.parentNode; - if (typeof (tParent.className) == 'undefined' || tParent.className == '') { - tParent.className = 'kmw-spacebar'; - } else if (tParent.className.indexOf('kmw-spacebar') == -1) { - tParent.className += ' kmw-spacebar'; - } - - if (t.className != 'kmw-spacebar-caption') { - t.className = 'kmw-spacebar-caption'; - } - - // It sounds redundant, but this dramatically cuts down on browser DOM processing; - // but sometimes innerText is reported empty when it actually isn't, so set it - // anyway in that case (Safari, iOS 14.4) - if (t.innerText != displayName || displayName == '') { - t.innerText = displayName; - } - - this.spaceBar.key.refreshLayout(this); - } - catch (ex) { } - } - /** * Add or remove a class from a keyboard key (when touched or clicked) * or add a key preview for phone devices @@ -1269,7 +1237,6 @@ export default class VisualKeyboard extends EventEmitter implements Ke const isInDOM = computedStyle.height != '' && computedStyle.height != 'auto'; // Step 2: determine basic layout geometry, refresh things that might update. - this.showLanguage(); // In case the spacebar-text mode setting has changed. if (fixedSize) { this._computedWidth = this.width; @@ -1307,7 +1274,10 @@ export default class VisualKeyboard extends EventEmitter implements Ke // Step 4: perform layout operations. // Needs the refreshed layout info to work correctly. if(this.currentLayer) { - this.currentLayer.refreshLayout(this, this._computedHeight - this.getVerticalLayerGroupPadding()); + this.currentLayer.refreshLayout(this, { + keyboardHeight: this._computedHeight - this.getVerticalLayerGroupPadding(), + spacebarText: this.layoutKeyboardProperties?.displayName ?? '(System keyboard)' + }); } }