diff --git a/HISTORY.md b/HISTORY.md index 164a5a93ba..c660322647 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,37 @@ # Keyman Version History +## 14.0.181 alpha 2020-11-13 + +* fix(common/core/web): fixes no-output logic check, arrow keys (#3848) +* fix(common/core/web): adds missing null-check (#3859) + +## 14.0.180 alpha 2020-11-12 + +* fix(windows): makefile format error (#3854) + +## 14.0.179 alpha 2020-11-12 + +* fix(windows): Import OSK wrong for European layouts (#3830) +* fix(windows): SizeOfImage header was wrong for dbg (#3833) +* chore(windows): symbol server support (#3834) +* fix(windows): sporadic 8087 control word corruption (#3842) + +## 14.0.178 alpha 2020-11-10 + +* fix(developer): Remove IE dependency from Developer Setup (#3839) + +## 14.0.177 alpha 2020-11-07 + +* fix(developer): support for notany() and context() (#3816) +* fix(web): support for notany() and context() (#3817) +* fix(developer): debug window inherits editor font (#3829) + +## 14.0.176 alpha 2020-11-05 + +* fix(developer): remove obsolete NRSIAllTags (#3819) +* fix(developer): Incorrect script:language map (#3818) +* fix(android/app): Remove network check on "Get Started" menu (#3823) + ## 14.0.175 alpha 2020-11-04 * feat(android/engine): Add check for associated model on ModelPickerActivity (#3808) diff --git a/VERSION.md b/VERSION.md index 64bddfe3d6..d82cce3e52 100644 --- a/VERSION.md +++ b/VERSION.md @@ -1 +1 @@ -14.0.176 \ No newline at end of file +14.0.182 \ No newline at end of file diff --git a/common/core/web/input-processor/package-lock.json b/common/core/web/input-processor/package-lock.json index 4ce637c80e..38960e20a5 100644 --- a/common/core/web/input-processor/package-lock.json +++ b/common/core/web/input-processor/package-lock.json @@ -1,6 +1,6 @@ { "name": "@keymanapp/input-processor", - "version": "14.0.176", + "version": "14.0.182", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/common/core/web/input-processor/package.json b/common/core/web/input-processor/package.json index 4304320487..a36a826e45 100644 --- a/common/core/web/input-processor/package.json +++ b/common/core/web/input-processor/package.json @@ -1,6 +1,6 @@ { "name": "@keymanapp/input-processor", - "version": "14.0.176", + "version": "14.0.182", "description": "The core text and prediction processing engine for KeymanWeb", "repository": { "type": "git", @@ -18,7 +18,7 @@ }, "homepage": "https://github.com/keymanapp/keyman#readme", "devDependencies": { - "@keymanapp/resources-gosh": "^14.0.176", + "@keymanapp/resources-gosh": "^14.0.182", "chai": "^4.2.0", "mocha": "^5.2.0", "typescript": "^3.8.3" @@ -29,11 +29,11 @@ "test": "gosh ./unit_tests/test.sh" }, "dependencies": { - "@keymanapp/keyboard-processor": "^14.0.176", - "@keymanapp/lexical-model-layer": "^14.0.176", - "@keymanapp/models-types": "^14.0.176", - "@keymanapp/web-environment": "^14.0.176", - "@keymanapp/web-utils": "^14.0.176", + "@keymanapp/keyboard-processor": "^14.0.182", + "@keymanapp/lexical-model-layer": "^14.0.182", + "@keymanapp/models-types": "^14.0.182", + "@keymanapp/web-environment": "^14.0.182", + "@keymanapp/web-utils": "^14.0.182", "@types/node": "^11.9.4", "eventemitter3": "^4.0.0", "ts-node": "^8.0.2" diff --git a/common/core/web/keyboard-processor/package-lock.json b/common/core/web/keyboard-processor/package-lock.json index ec3c7d218d..05ed2ba2d2 100644 --- a/common/core/web/keyboard-processor/package-lock.json +++ b/common/core/web/keyboard-processor/package-lock.json @@ -1,6 +1,6 @@ { "name": "@keymanapp/keyboard-processor", - "version": "14.0.176", + "version": "14.0.182", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/common/core/web/keyboard-processor/package.json b/common/core/web/keyboard-processor/package.json index e13012dbca..70b475f84a 100644 --- a/common/core/web/keyboard-processor/package.json +++ b/common/core/web/keyboard-processor/package.json @@ -1,6 +1,6 @@ { "name": "@keymanapp/keyboard-processor", - "version": "14.0.176", + "version": "14.0.182", "description": "Core module for Keyman keyboard support in KeymanWeb.", "repository": { "type": "git", @@ -18,7 +18,7 @@ }, "homepage": "https://github.com/keymanapp/keyman#readme", "devDependencies": { - "@keymanapp/resources-gosh": "^14.0.176", + "@keymanapp/resources-gosh": "^14.0.182", "chai": "^4.2.0", "mocha": "^5.2.0", "mocha-teamcity-reporter": "^3.0.0", @@ -31,9 +31,9 @@ "mocha": "mocha" }, "dependencies": { - "@keymanapp/models-types": "^14.0.176", - "@keymanapp/web-environment": "^14.0.176", - "@keymanapp/web-utils": "^14.0.176", + "@keymanapp/models-types": "^14.0.182", + "@keymanapp/web-environment": "^14.0.182", + "@keymanapp/web-utils": "^14.0.182", "@types/node": "^11.9.4", "ts-node": "^8.0.2" } diff --git a/common/core/web/keyboard-processor/src/text/defaultOutput.ts b/common/core/web/keyboard-processor/src/text/defaultOutput.ts index f0f917fa7d..0bea0dfd45 100644 --- a/common/core/web/keyboard-processor/src/text/defaultOutput.ts +++ b/common/core/web/keyboard-processor/src/text/defaultOutput.ts @@ -48,7 +48,7 @@ namespace com.keyman.text { // case Codes.keyCodes['K_TABFWD']: // return '\t'; default: - return ''; + return null; } } } diff --git a/common/core/web/keyboard-processor/src/text/kbdInterface.ts b/common/core/web/keyboard-processor/src/text/kbdInterface.ts index 20bce0e22e..fd134d34d0 100644 --- a/common/core/web/keyboard-processor/src/text/kbdInterface.ts +++ b/common/core/web/keyboard-processor/src/text/kbdInterface.ts @@ -26,7 +26,7 @@ namespace com.keyman.text { type PlainKeyboardStore = string; export type KeyboardStoreElement = (string|StoreNonCharEntry); - export type ComplexKeyboardStore = KeyboardStoreElement[]; + export type ComplexKeyboardStore = KeyboardStoreElement[]; type KeyboardStore = PlainKeyboardStore | ComplexKeyboardStore; @@ -65,12 +65,12 @@ namespace com.keyman.text { /** Discriminant field - 'i' for `index()`. */ ['t']: 'i'; - + /** * Value: the Store from which to output */ ['i']: KeyboardStore; - + /** * Offset: the offset in context for the corresponding `any()`. */ @@ -81,7 +81,7 @@ namespace com.keyman.text { /** Discriminant field - 'c' for `context()`. */ ['t']: 'c'; - + /** * Value: The offset into the current rule's context to be matched. */ @@ -108,16 +108,16 @@ namespace com.keyman.text { /** * Cache of context storing and retrieving return values from KC * Must be reset prior to each keystroke and after any text changes - * MCD 3/1/14 - **/ + * MCD 3/1/14 + **/ class CachedContext { _cache: string[][]; - - reset(): void { - this._cache = []; + + reset(): void { + this._cache = []; } - get(n: number, ln: number): string { + get(n: number, ln: number): string { // return null; // uncomment this line to disable context caching if(typeof this._cache[n] == 'undefined') { return null; @@ -127,22 +127,22 @@ namespace com.keyman.text { return this._cache[n][ln]; } - set(n: number, ln: number, val: string): void { - if(typeof this._cache[n] == 'undefined') { - this._cache[n] = []; - } - this._cache[n][ln] = val; + set(n: number, ln: number, val: string): void { + if(typeof this._cache[n] == 'undefined') { + this._cache[n] = []; + } + this._cache[n][ln] = val; } }; type CachedExEntry = {valContext: (string|number)[], deadContext: text.Deadkey[]}; - /** - * An extended version of cached context storing designed to work with + /** + * An extended version of cached context storing designed to work with * `fullContextMatch` and its helper functions. */ class CachedContextEx { _cache: CachedExEntry[][]; - + reset(): void { this._cache = []; } @@ -157,11 +157,17 @@ namespace com.keyman.text { return this._cache[n][ln]; } - set(n: number, ln: number, val: CachedExEntry): void { - if(typeof this._cache[n] == 'undefined') { - this._cache[n] = []; - } - this._cache[n][ln] = val; + set(n: number, ln: number, val: CachedExEntry): void { + if(typeof this._cache[n] == 'undefined') { + this._cache[n] = []; + } + this._cache[n][ln] = val; + } + + clone(): CachedContextEx { + let r = new CachedContextEx(); + r._cache = this._cache; + return r; } }; @@ -172,6 +178,7 @@ namespace com.keyman.text { cachedContext: CachedContext = new CachedContext(); cachedContextEx: CachedContextEx = new CachedContextEx(); + ruleContextEx: CachedContextEx; activeTargetOutput: OutputTarget; ruleBehavior: RuleBehavior; @@ -191,7 +198,7 @@ namespace com.keyman.text { constructor(variableStoreSerializer: VariableStoreSerializer = null) { this.systemStores = {}; - + this.systemStores[KeyboardInterface.TSS_PLATFORM] = new PlatformSystemStore(this); this.systemStores[KeyboardInterface.TSS_LAYER] = new MutableSystemStore(KeyboardInterface.TSS_LAYER, 'default'); @@ -201,61 +208,61 @@ namespace com.keyman.text { /** * Function KSF * Scope Public - * + * * Saves the document's current focus settings on behalf of the keyboard. Often paired with insertText. - */ + */ saveFocus(): void { } /** * A text-insertion method used by custom OSKs for helpHTML interaction, like with sil_euro_latin. - * + * * This function currently bypasses web-core's standard text handling control path and all predictive text processing. * It also has DOM-dependencies that help ensure KMW's active OutputTarget retains focus during use. */ insertText?: (Ptext: string, PdeadKey: number) => boolean; - + /** - * Function registerKeyboard KR + * Function registerKeyboard KR * Scope Public * @param {Object} Pk Keyboard object * Description Registers a keyboard with KeymanWeb once its script has fully loaded. - * + * * In web-core, this also activates the keyboard; in other modules, this method * may be replaced with other implementations. - */ + */ registerKeyboard(Pk): void { - // NOTE: This implementation is web-core specific and is intentionally replaced, whole-sale, + // NOTE: This implementation is web-core specific and is intentionally replaced, whole-sale, // by DOM-aware code. let keyboard = new keyboards.Keyboard(Pk); this.activeKeyboard = keyboard; } /** - * Used by DOM-aware KeymanWeb to add keyboard stubs, used by the `KeyboardManager` type + * Used by DOM-aware KeymanWeb to add keyboard stubs, used by the `KeyboardManager` type * to optimize resource use. - */ + */ registerStub?: (Pstub) => number; /** * Get *cached or uncached* keyboard context for a specified range, relative to caret - * + * * @param {number} n Number of characters to move back from caret * @param {number} ln Number of characters to return * @param {Object} Pelem Element to work with (must be currently focused element) - * @return {string} Context string - * + * @return {string} Context string + * * Example [abcdef|ghi] as INPUT, with the caret position marked by |: * KC(2,1,Pelem) == "e" * KC(3,3,Pelem) == "def" * KC(10,10,Pelem) == "abcdef" i.e. return as much as possible of the requested string - */ - + */ + context(n: number, ln: number, outputTarget: OutputTarget): string { var v = this.cachedContext.get(n, ln); if(v !== null) { return v; } - + var r = this.KC_(n, ln, outputTarget); this.cachedContext.set(n, ln, r); return r; @@ -263,17 +270,17 @@ namespace com.keyman.text { /** * Get (uncached) keyboard context for a specified range, relative to caret - * + * * @param {number} n Number of characters to move back from caret * @param {number} ln Number of characters to return * @param {Object} Pelem Element to work with (must be currently focused element) - * @return {string} Context string - * + * @return {string} Context string + * * Example [abcdef|ghi] as INPUT, with the caret position marked by |: * KC(2,1,Pelem) == "e" * KC(3,3,Pelem) == "def" * KC(10,10,Pelem) == "XXXXabcdef" i.e. return as much as possible of the requested string, where X = \uFFFE - */ + */ private KC_(n: number, ln: number, outputTarget: OutputTarget): string { var tempContext = ''; @@ -285,29 +292,29 @@ namespace com.keyman.text { return tempContext._kmwSubstr(-n)._kmwSubstr(0,ln); } - + /** - * Function nul KN + * Function nul KN * Scope Public * @param {number} n Length of context to check * @param {Object} Ptarg Element to work with (must be currently focused element) * @return {boolean} True if length of context is less than or equal to n * Description Test length of context, return true if the length of the context is less than or equal to n - * + * * Example [abc|def] as INPUT, with the caret position marked by |: * KN(3,Pelem) == TRUE * KN(2,Pelem) == FALSE * KN(4,Pelem) == TRUE - */ + */ nul(n: number, outputTarget: OutputTarget): boolean { var cx=this.context(n+1, 1, outputTarget); - + // With #31, the result will be a replacement character if context is empty. return cx === "\uFFFE"; } /** - * Function contextMatch KCM + * Function contextMatch KCM * Scope Public * @param {number} n Number of characters to move back from caret * @param {Object} Ptarg Focused element @@ -315,7 +322,7 @@ namespace com.keyman.text { * @param {number} ln Number of characters to return * @return {boolean} True if selected context matches val * Description Test keyboard context for match - */ + */ contextMatch(n: number, outputTarget: OutputTarget, val: string, ln: number): boolean { var cx=this.context(n, ln, outputTarget); if(cx === val) { @@ -327,14 +334,14 @@ namespace com.keyman.text { /** * Builds the *cached or uncached* keyboard context for a specified range, relative to caret - * + * * @param {number} n Number of characters to move back from caret * @param {number} ln Number of characters to return * @param {Object} Pelem Element to work with (must be currently focused element) - * @return {Array} Context array (of strings and numbers) + * @return {Array} Context array (of strings and numbers) */ private _BuildExtendedContext(n: number, ln: number, outputTarget: OutputTarget): CachedExEntry { - var cache: CachedExEntry = this.cachedContextEx.get(n, ln); + var cache: CachedExEntry = this.cachedContextEx.get(n, ln); if(cache !== null) { return cache; } else { @@ -398,13 +405,14 @@ namespace com.keyman.text { * @param {Object} Ptarg Focused element * @param {Array} rule An array of ContextEntries to match. * @return {boolean} True if the fully-specified rule context matches the current KMW state. - * + * * A KMW 10+ function designed to bring KMW closer to Keyman Desktop functionality, * near-directly modeling (externally) the compiled form of Desktop rules' context section. */ fullContextMatch(n: number, outputTarget: OutputTarget, rule: ContextEntry[]): boolean { // Stage one: build the context index map. var fullContext = this._BuildExtendedContext(n, rule.length, outputTarget); + this.ruleContextEx = this.cachedContextEx.clone(); var context = fullContext.valContext; var deadContext = fullContext.deadContext; @@ -431,7 +439,7 @@ namespace com.keyman.text { var r = rule[i] as ContextNonCharEntry; switch(r.t) { case 'd': - // We still need to set a flag here; + // We still need to set a flag here; if(r['d'] !== context[i]) { mismatch = true; } else { @@ -457,7 +465,7 @@ namespace com.keyman.text { deadContext[i].set(); } // 'n' for 'notany'. If we actually match or if we have nul context (\uFFFE), notany fails. - } else if(r.n && (result || context[i] !== NUL_CONTEXT)) { + } else if(r.n && (result || context[i] === NUL_CONTEXT)) { mismatch = true; } break; @@ -471,7 +479,7 @@ namespace com.keyman.text { deadContext[i].set(); } break; - case 'c': + case 'c': if(context[r.c - 1] !== context[i]) { mismatch = true; } else if(deadContext[i] !== undefined) { @@ -500,12 +508,12 @@ namespace com.keyman.text { } /** - * Function KIK + * Function KIK * Scope Public * @param {Object} e keystroke event * @return {boolean} true if keypress event * Description Test if event as a keypress event - */ + */ isKeypress(e: KeyEvent): boolean { if(this.activeKeyboard.isMnemonic) { // I1380 - support KIK for positional layouts return !e.LisVirtualKey; // will now return true for U_xxxx keys, but not for T_xxxx keys @@ -513,16 +521,16 @@ namespace com.keyman.text { return KeyMapping._USKeyCodeToCharCode(e) ? true : false; // I1380 - support KIK for positional layouts } } - + /** - * Function keyMatch KKM + * Function keyMatch KKM * Scope Public * @param {Object} e keystroke event * @param {number} Lruleshift * @param {number} Lrulekey * @return {boolean} True if key matches rule * Description Test keystroke with modifiers against rule - */ + */ keyMatch(e: KeyEvent, Lruleshift:number, Lrulekey:number): boolean { var retVal = false; // I3318 var keyCode = (e.Lcode == 173 ? 189 : e.Lcode); //I3555 (Firefox hyphen issue) @@ -535,7 +543,7 @@ namespace com.keyman.text { if(e.vkCode > 255) { keyCode = e.vkCode; // added to support extended (touch-hold) keys for mnemonic layouts } - + if(e.LisVirtualKey || keyCode > 255) { if((Lruleshift & 0x4000) == 0x4000 || (keyCode > 255)) { // added keyCode test to support extended keys retVal = ((Lrulekey == keyCode) && ((Lruleshift & modifierBitmask) == e.Lmodifiers)); //I3318, I3555 @@ -554,7 +562,7 @@ namespace com.keyman.text { * Function stateMatch KSM * Scope Public * @param {Object} e keystroke event - * @param {number} Lstate + * @param {number} Lstate * Description Test keystroke against state key rules */ stateMatch(e: KeyEvent, Lstate: number) { @@ -567,7 +575,7 @@ namespace com.keyman.text { * @param {Object} e * @return {Object} Object with event's virtual key flag, key code, and modifiers * Description Get object with extended key event information - */ + */ keyInformation(e: KeyEvent): KeyInformation { var ei = new KeyInformation(); ei['vk'] = e.LisVirtualKey; @@ -577,24 +585,24 @@ namespace com.keyman.text { }; /** - * Function deadkeyMatch KDM + * Function deadkeyMatch KDM * Scope Public * @param {number} n offset from current cursor position * @param {Object} Ptarg target element * @param {number} d deadkey * @return {boolean} True if deadkey found selected context matches val * Description Match deadkey at current cursor position - */ + */ deadkeyMatch(n: number, outputTarget: OutputTarget, d: number): boolean { return outputTarget.hasDeadkeyMatch(n, d); } - + /** - * Function beep KB + * Function beep KB * Scope Public * @param {Object} Pelem element to flash * Description Flash body as substitute for audible beep; notify embedded device to vibrate - */ + */ beep(outputTarget: OutputTarget): void { this.resetContextCache(); @@ -624,21 +632,21 @@ namespace com.keyman.text { return store; } } - + /** - * Function any KA + * Function any KA * Scope Public - * @param {number} n character position (index) + * @param {number} n character position (index) * @param {string} ch character to find in string - * @param {string} s 'any' string + * @param {string} s 'any' string * @return {boolean} True if character found in 'any' string, sets index accordingly * Description Test for character matching - */ + */ any(n: number, ch: KeyboardStoreElement, s: KeyboardStore): boolean { if(ch == '') { return false; } - + s = this._ExplodeStore(s); var Lix = -1; for(var i=0; i < s.length; i++) { @@ -658,18 +666,18 @@ namespace com.keyman.text { /** * Function _Index - * Scope Public + * Scope Public * @param {string} Ps string * @param {number} Pn index * Description Returns the character from a store string according to the offset in the index array */ - _Index(Ps: KeyboardStore, Pn: number): KeyboardStoreElement { + _Index(Ps: KeyboardStore, Pn: number): KeyboardStoreElement { Ps = this._ExplodeStore(Ps); if(this._AnyIndices[Pn-1] < Ps.length) { //I3319 return Ps[this._AnyIndices[Pn-1]]; } else { - /* Should not be possible for a compiled keyboard, but may arise + /* Should not be possible for a compiled keyboard, but may arise * during the development of handwritten keyboards. */ console.warn("Unmatched contextual index() statement detected in rule with index " + Pn + "!"); @@ -714,16 +722,16 @@ namespace com.keyman.text { } else { // For keyboards developed during 10.0's alpha phase - t:'d' was assumed. this.deadkeyOutput(Pdn, outputTarget, indexChar['d']); } - } + } } - - + + /** - * Function deleteContext KDC + * Function deleteContext KDC * Scope Public * @param {number} dn number of context entries to overwrite - * @param {Object} Pelem element to output to - * @param {string} s string to output + * @param {Object} Pelem element to output to + * @param {string} s string to output * Description Keyboard output */ deleteContext(dn: number, outputTarget: OutputTarget): void { @@ -765,11 +773,11 @@ namespace com.keyman.text { } /** - * Function output KO + * Function output KO * Scope Public * @param {number} dn number of characters to overwrite - * @param {Object} Pelem element to output to - * @param {string} s string to output + * @param {Object} Pelem element to output to + * @param {string} s string to output * Description Keyboard output */ output(dn: number, outputTarget: OutputTarget, s:string): void { @@ -786,16 +794,45 @@ namespace com.keyman.text { outputTarget.insertTextBeforeCaret(s); outputTarget.restoreProperties(); } - - + /** - * Function deadkeyOutput KDO + * `contextExOutput` function emits the character or object at `contextOffset` from the + * current matched rule's context. Introduced in Keyman 14.0, in order to resolve a + * gap between desktop and web core functionality for context(n) matching on notany(). + * See #917 for additional detail. + * @alias KCXO + * @public + * @param {number} Pdn number of characters to delete left of cursor + * @param {OutputTarget} outputTarget target to output to + * @param {number} contextLength length of current rule context to retrieve + * @param {number} contextOffset offset from start of current rule context, 1-based + */ + contextExOutput(Pdn: number, outputTarget: OutputTarget, contextLength: number, contextOffset: number): void { + this.resetContextCache(); + + if(Pdn >= 0) { + this.output(Pdn, outputTarget, ""); + } + + const context = this.ruleContextEx.get(contextLength, contextLength); + const dk = context.deadContext[contextOffset-1], vc = context.valContext[contextOffset-1]; + if(dk) { + outputTarget.insertDeadkeyBeforeCaret(dk.d); + } else if(typeof vc == 'string') { + this.output(-1, outputTarget, vc); + } else { + throw new Error("contextExOutput: should never be a numeric valContext with no corresponding deadContext"); + } + } + + /** + * Function deadkeyOutput KDO * Scope Public - * @param {number} Pdn no of character to overwrite (delete) - * @param {Object} Pelem element to output to + * @param {number} Pdn no of character to overwrite (delete) + * @param {Object} Pelem element to output to * @param {number} Pd deadkey id * Description Record a deadkey at current cursor position, deleting Pdn characters first - */ + */ deadkeyOutput(Pdn: number, outputTarget: OutputTarget, Pd: number): void { this.resetContextCache(); @@ -806,36 +843,36 @@ namespace com.keyman.text { outputTarget.insertDeadkeyBeforeCaret(Pd); // _DebugDeadKeys(Pelem, 'KDeadKeyOutput: dn='+Pdn+'; deadKey='+Pd); } - + /** - * KIFS compares the content of a system store with a string value - * + * KIFS compares the content of a system store with a string value + * * @param {number} systemId ID of the system store to test (only TSS_LAYER currently supported) * @param {string} strValue String value to compare to - * @param {Object} Pelem Currently active element (may be needed by future tests) - * @return {boolean} True if the test succeeds - */ + * @param {Object} Pelem Currently active element (may be needed by future tests) + * @return {boolean} True if the test succeeds + */ ifStore(systemId: number, strValue: string, outputTarget: OutputTarget): boolean { var result=true; let store = this.systemStores[systemId]; if(store) { result = store.matches(strValue); } - return result; //Moved from previous line, now supports layer selection, Build 350 + return result; //Moved from previous line, now supports layer selection, Build 350 } /** - * KSETS sets the value of a system store to a string - * + * KSETS sets the value of a system store to a string + * * @param {number} systemId ID of the system store to set (only TSS_LAYER currently supported) - * @param {string} strValue String to set as the system store content - * @param {Object} Pelem Currently active element (may be needed in future tests) + * @param {string} strValue String to set as the system store content + * @param {Object} Pelem Currently active element (may be needed in future tests) * @return {boolean} True if command succeeds * (i.e. for TSS_LAYER, if the layer is successfully selected) - * + * * Note that option/variable stores are instead set within keyboard script code, as they only * affect keyboard behavior. - */ + */ setStore(systemId: number, strValue: string, outputTarget: OutputTarget): boolean { this.resetContextCache(); if(systemId == KeyboardInterface.TSS_LAYER) { @@ -848,15 +885,15 @@ namespace com.keyman.text { /** * Load an option store value from a cookie or default value - * + * * @param {string} kbdName keyboard internal name * @param {string} storeName store (option) name, embedded in cookie name * @param {string} dfltValue default value - * @return {string} current or default option value - * + * @return {string} current or default option value + * * This will only ever be called when the keyboard is loaded, as it is used by keyboards * to initialize a store value on the keyboard's script object. - */ + */ loadStore(kbdName: string, storeName:string, dfltValue:string): string { this.resetContextCache(); if(this.variableStoreSerializer) { @@ -868,16 +905,16 @@ namespace com.keyman.text { } /** - * Save an option store value to a cookie - * + * Save an option store value to a cookie + * * @param {string} storeName store (option) name, embedded in cookie name * @param {string} optValue option value to save * @return {boolean} true if save successful - * + * * Note that a keyboard will freely manipulate the value of its variable stores on the * script object within its own code. This function's use is merely to _persist_ that * value across sessions, providing a custom user default for later uses of the keyboard. - */ + */ saveStore(storeName:string, optValue:string): boolean { this.resetContextCache(); var kbd=this.activeKeyboard; @@ -927,12 +964,12 @@ namespace com.keyman.text { outputTarget.invalidateSelection(); - outputTarget.deadkeys().resetMatched(); // I3318 + outputTarget.deadkeys().resetMatched(); // I3318 this.resetContextCache(); // Capture the initial state of the OutputTarget before any rules are matched. let preInput = Mock.from(outputTarget); - + // Establishes the results object, allowing corresponding commands to set values here as appropriate. this.ruleBehavior = new RuleBehavior(); @@ -963,7 +1000,7 @@ namespace com.keyman.text { * Publishes the KeyboardInterface's shorthand API names. As this assigns the current functions * held by the longform versions, note that this should be called after replacing any of them via * JS method extension. - * + * * DOM-aware KeymanWeb should call this after its domKbdInterface.ts code is loaded, as it replaces * a few. (This is currently done within its kmwapi.ts.) */ @@ -994,6 +1031,7 @@ namespace com.keyman.text { exportKBCallback('KDC', 'deleteContext'); exportKBCallback('KO', 'output'); exportKBCallback('KDO', 'deadkeyOutput'); + exportKBCallback('KCXO', 'contextExOutput'); exportKBCallback('KIO', 'indexOutput'); exportKBCallback('KIFS', 'ifStore'); exportKBCallback('KSETS', 'setStore'); diff --git a/common/core/web/keyboard-processor/src/text/keyboardProcessor.ts b/common/core/web/keyboard-processor/src/text/keyboardProcessor.ts index 1226c889c1..8f30d25101 100644 --- a/common/core/web/keyboard-processor/src/text/keyboardProcessor.ts +++ b/common/core/web/keyboard-processor/src/text/keyboardProcessor.ts @@ -186,7 +186,7 @@ namespace com.keyman.text { Lkc.Lstates |= this.stateKeys['K_SCROLL'] ? Codes.modifierCodes['SCROLL_LOCK'] : Codes.modifierCodes['NO_SCROLL_LOCK']; // Set LisVirtualKey to false to ensure that nomatch rule does fire for U_xxxx keys - if(Lkc.kName.substr(0,2) == 'U_') { + if(Lkc.kName && Lkc.kName.substr(0,2) == 'U_') { Lkc.LisVirtualKey=false; } diff --git a/common/core/web/keyboard-processor/tests/cases/engine/notany_context.js b/common/core/web/keyboard-processor/tests/cases/engine/notany_context.js new file mode 100644 index 0000000000..1b502fa99b --- /dev/null +++ b/common/core/web/keyboard-processor/tests/cases/engine/notany_context.js @@ -0,0 +1,112 @@ +const assert = require('chai').assert; +const fs = require('fs'); +const vm = require('vm'); + +const KeyboardProcessor = require('../../../dist'); +const KMWRecorder = require('../../../../tools/recorder/dist/nodeProctor'); + +// Required initialization setup. +global.com = KeyboardProcessor.com; // exports all keyboard-processor namespacing. +global.keyman = {}; // So that keyboard-based checks against the global `keyman` succeed. + // 10.0+ dependent keyboards, like khmer_angkor, will otherwise fail to load. + +// Initialize supplementary plane string extensions +String.kmwEnableSupplementaryPlane(false); + +const device = { + formFactor: 'desktop', + OS: 'windows', + browser: 'native' +} + +let keyboard; + +function runEngineRuleSet(ruleSet) { + for(let ruleDef of ruleSet) { + // Prepare the context! + const ruleSeq = new KMWRecorder.RecordedKeystrokeSequence(ruleDef); + const proctor = new KMWRecorder.NodeProctor(keyboard, device, assert.equal); + const target = new com.keyman.text.Mock(); + ruleSeq.test(proctor, target); + } +} + +/** + * Wrapper to simplify running tests -- supports either virtual key codes as string (e.g. 'A' is VK_A) + * or an array of integers. Does not currently support modifiers (not needed here). + * @param {String|Array} input Virtual key codes of each character (as string or array) + * @param {String} output Expected output + */ + +function runStringRuleSet(input, output) { + const rule = { + "inputs": + typeof input == 'string' + ? input.split("").map(ch => + { return { "type": "key", "keyCode": ch.charCodeAt(0), "states": 10752, "modifiers": 0, "modifierChanged": false, "isVirtualKey": true } }) + : input.map(ch => + { return { "type": "key", "keyCode": ch, "states": 10752, "modifiers": 0, "modifierChanged": false, "isVirtualKey": true } }), + "output": output + }; + return runEngineRuleSet([rule]); +} + +// ----------- + +describe('Engine - notany() and context()', function() { + before(function() { + const kp = new KeyboardProcessor(); + + // These two lines will load a keyboard from its file; headless-mode `registerKeyboard` will + // automatically set the keyboard as active. + const script = new vm.Script(fs.readFileSync('../tests/resources/keyboards/test_917.js')); + script.runInThisContext(); + + keyboard = kp.activeKeyboard; + }); + + /* + * Isolated rule tests for validity of `context()` and `notany()` statements. + */ + + describe('First set -- notany() in first context position', function() { + it("baseline: rule with nomatch is not executed", function() { + runStringRuleSet('ABC', 'abc'); + }); + + it("rule with nomatch is executed with a plain char matched", function() { + runStringRuleSet('XBC', 'xBC'); + }); + + it("rule with nomatch is executed with a deadkey matched", function() { + runStringRuleSet('DBC1', 'pass!'); + }); + }); + + describe('Second set -- notany() in second context position', function() { + it("rule with nomatch is executed with a plain char matched", function() { + runStringRuleSet('AXCD1', 'axXX1'); + }); + + it("rule with nomatch is executed with a deadkey matched", function() { + runStringRuleSet('ADCD1', 'pass!'); + }); + }); + + describe('Third set -- notany() in third context position with initial if() testing AdjustIndex', function() { + it("rule with nomatch is executed with a plain char matched", function() { + runStringRuleSet('FGHI1', 'fgXX1'); + }); + + it("rule with nomatch is executed with a deadkey matched", function() { + runStringRuleSet('FDHI1', 'pass!'); + }); + }); + + // This is actually a separate issue that was corrected in the same PR + // so we placed the test here for conciseness. + + it('verify notany comparison flip correction from #3817', function() { + runStringRuleSet('YZ', 'pass!'); + }); +}); \ No newline at end of file diff --git a/common/core/web/tests/resources/keyboards/.gitignore b/common/core/web/tests/resources/keyboards/.gitignore new file mode 100644 index 0000000000..2bf1ef8c0e --- /dev/null +++ b/common/core/web/tests/resources/keyboards/.gitignore @@ -0,0 +1 @@ +debug.log \ No newline at end of file diff --git a/common/core/web/tests/resources/keyboards/test_917.js b/common/core/web/tests/resources/keyboards/test_917.js new file mode 100644 index 0000000000..6bf1e2f108 --- /dev/null +++ b/common/core/web/tests/resources/keyboards/test_917.js @@ -0,0 +1 @@ +if(typeof keyman === 'undefined') {console.log('Keyboard requires KeymanWeb 10.0 or later');if(typeof tavultesoft !== 'undefined') tavultesoft.keymanweb.util.alert("This keyboard requires KeymanWeb 10.0 or later");} else {KeymanWeb.KR(new Keyboard_test_917());}function Keyboard_test_917(){this.KI="Keyboard_test_917";this.KN="Test #917 - notany() and context()";this.KMINVER="14.0";this.KV=null;this.KDU=0;this.KH='';this.KM=0;this.KBVER="1.0";this.KMBM=0x0000;this.s8="aeiou";this.s10="web";this.s11="native";this.KVER="13.0.9999.0";this.gs=function(t,e) {return this.g0(t,e);};this.g0=function(t,e) {var k=KeymanWeb,r=0,m=0;if(k.KKM(e,16384,49)) {if(k.KFCM(4,t,['a',{t:'d',d:0},'X','X'])){r=m=1;k.KDC(4,t);k.KO(-1,t,"pass!");}else if(k.KFCM(4,t,['f',{t:'d',d:0},'X','X'])){r=m=1;k.KDC(4,t);k.KO(-1,t,"pass!");}else if(k.KFCM(3,t,[{t:'d',d:0},'B','C'])){r=m=1;k.KDC(3,t);k.KO(-1,t,"pass!");}}else if(k.KKM(e,16384,67)) {if(k.KFCM(2,t,[{t:'a',a:this.s8,n:1},'b'])){r=m=1;k.KDC(2,t);k.KCXO(-1,t,2,1);k.KO(-1,t,"BC");}}else if(k.KKM(e,16384,68)) {if(k.KFCM(3,t,['a',{t:'a',a:this.s8,n:1},'c'])){r=m=1;k.KDC(3,t);k.KO(-1,t,"a");k.KCXO(-1,t,3,2);k.KO(-1,t,"XX");}else if(1){r=m=1;k.KDC(0,t);k.KDO(-1,t,0);}}else if(k.KKM(e,16384,73)) {if(k.KFCM(3,t,['f',{t:'a',a:this.s8,n:1},'h'])&&k.KIFS(31,this.s10,t)){r=m=1;k.KDC(3,t);k.KO(-1,t,"f");k.KCXO(-1,t,3,2);k.KO(-1,t,"XX");}else if(k.KFCM(3,t,['f',{t:'a',a:this.s8,n:1},'h'])&&k.KIFS(31,this.s11,t)){r=m=1;k.KDC(3,t);k.KO(-1,t,"f");k.KCXO(-1,t,3,2);k.KO(-1,t,"XX");}}else if(k.KKM(e,16384,90)) {if(k.KFCM(1,t,[{t:'a',a:this.s8,n:1}])){r=m=1;k.KDC(1,t);k.KO(-1,t,"pass!");}}return r;};} \ No newline at end of file diff --git a/common/core/web/tests/resources/keyboards/test_917.kmn b/common/core/web/tests/resources/keyboards/test_917.kmn new file mode 100644 index 0000000000..f261c9064a --- /dev/null +++ b/common/core/web/tests/resources/keyboards/test_917.kmn @@ -0,0 +1,46 @@ +c test_917 generated from template at 2020-11-04 06:59:27 +c with name "test_917" +c store(&VERSION) '14.0' +store(&NAME) 'Test #917 - notany() and context()' +store(©RIGHT) '©' +store(&KEYBOARDVERSION) '1.0' +store(&TARGETS) 'web' +c store(&VISUALKEYBOARD) 'test_917.kvks' +c store(&LAYOUTFILE) 'test_917.keyman-touch-layout' + +begin Unicode > use(main) + +group(main) using keys + +c type: 'abc' > 'abc' +c type: 'xbc' > 'xBC' +c type: 'dbc' > DK(1) 'BC' +c type: 'dbc1' > 'pass!' +c +store(vow) 'aeiou' +notany(vow) 'b' + 'c' > context(1) 'BC' ++ 'd' > dk(1) +dk(1) 'BC' + '1' > 'pass!' + +c type: 'adcd' > 'a' DK(1) 'XX' +c type: 'adcd1' > 'pass!' +c type: 'axcd' > 'axXX' +c type: 'axcd1' > 'axXX1' +'a' notany(vow) 'c' + 'd' > context(1) context(2) 'XX' +'a' dk(1) 'XX' + '1' > 'pass!' + +c Test for AdjustIndex correctness +c type: 'fghi' > 'fgXX' +c type: 'fghi1' > 'fgXX1' +c type: 'fdhi' > 'f' DK(1) 'XX' +c type: 'fdhi1' > 'pass!' +if(&platform = 'web') 'f' notany(vow) 'h' + 'i' > context(2) context(3) 'XX' + +c this platform matches for node-based tests ('web' doesn't!) +if(&platform = 'native') 'f' notany(vow) 'h' + 'i' > context(2) context(3) 'XX' +'f' dk(1) 'XX' + '1' > 'pass!' + + +c Test notany issue also resolved by #3817 +c type: 'yz' > 'pass!' +notany(vow) + 'z' > 'pass!' diff --git a/common/core/web/tests/resources/keyboards/unit_test_keyboards.kpj b/common/core/web/tests/resources/keyboards/unit_test_keyboards.kpj index 73278cb469..202767259c 100644 --- a/common/core/web/tests/resources/keyboards/unit_test_keyboards.kpj +++ b/common/core/web/tests/resources/keyboards/unit_test_keyboards.kpj @@ -4,6 +4,8 @@ False True + False + keyboard @@ -39,5 +41,16 @@ © 2018 SIL International + + id_1bccf5634ecd6605fe682279eed62c73 + test_917.kmn + test_917.kmn + 1.0 + .kmn +
+ Test #917 - notany() and context() + © +
+
diff --git a/common/core/web/tools/recorder/package-lock.json b/common/core/web/tools/recorder/package-lock.json index 5b1167548a..06cdeede6b 100644 --- a/common/core/web/tools/recorder/package-lock.json +++ b/common/core/web/tools/recorder/package-lock.json @@ -1,6 +1,6 @@ { "name": "@keymanapp/recorder-core", - "version": "14.0.176", + "version": "14.0.182", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/common/core/web/tools/recorder/package.json b/common/core/web/tools/recorder/package.json index fa43b2a50f..bdeead0290 100644 --- a/common/core/web/tools/recorder/package.json +++ b/common/core/web/tools/recorder/package.json @@ -1,6 +1,6 @@ { "name": "@keymanapp/recorder-core", - "version": "14.0.176", + "version": "14.0.182", "description": "Core classes used to develop KeymanWeb test cases based on keystrokes", "main": "index.js", "scripts": { @@ -17,10 +17,10 @@ }, "homepage": "https://github.com/keymanapp/keyman#readme", "dependencies": { - "@keymanapp/keyboard-processor": "^14.0.176", - "@keymanapp/models-types": "^14.0.176", - "@keymanapp/web-environment": "^14.0.176", - "@keymanapp/web-utils": "^14.0.176" + "@keymanapp/keyboard-processor": "^14.0.182", + "@keymanapp/models-types": "^14.0.182", + "@keymanapp/web-environment": "^14.0.182", + "@keymanapp/web-utils": "^14.0.182" }, "devDependencies": { "typescript": "^3.8.3" diff --git a/common/core/web/tools/sentry-manager/package-lock.json b/common/core/web/tools/sentry-manager/package-lock.json index 8efe388333..3910fe01a1 100644 --- a/common/core/web/tools/sentry-manager/package-lock.json +++ b/common/core/web/tools/sentry-manager/package-lock.json @@ -1,6 +1,6 @@ { "name": "@keymanapp/web-sentry-manager", - "version": "14.0.176", + "version": "14.0.182", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/common/core/web/tools/sentry-manager/package.json b/common/core/web/tools/sentry-manager/package.json index 3f8c582f54..4d45469809 100644 --- a/common/core/web/tools/sentry-manager/package.json +++ b/common/core/web/tools/sentry-manager/package.json @@ -1,6 +1,6 @@ { "name": "@keymanapp/web-sentry-manager", - "version": "14.0.176", + "version": "14.0.182", "description": "Common setup for KeymanWeb's Sentry-based error reporting", "main": "dist/index.js", "scripts": { @@ -20,7 +20,7 @@ "typescript": "^3.8.3" }, "dependencies": { - "@keymanapp/web-environment": "^14.0.176", + "@keymanapp/web-environment": "^14.0.182", "@sentry/browser": "^5.15.5" } } diff --git a/common/core/web/utils/package-lock.json b/common/core/web/utils/package-lock.json index 5412724cda..fc72d97cc2 100644 --- a/common/core/web/utils/package-lock.json +++ b/common/core/web/utils/package-lock.json @@ -1,6 +1,6 @@ { "name": "@keymanapp/web-utils", - "version": "14.0.176", + "version": "14.0.182", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/common/core/web/utils/package.json b/common/core/web/utils/package.json index 4a329eb053..ffb54d542c 100644 --- a/common/core/web/utils/package.json +++ b/common/core/web/utils/package.json @@ -1,6 +1,6 @@ { "name": "@keymanapp/web-utils", - "version": "14.0.176", + "version": "14.0.182", "description": "Common utility functions used throughout other Keyman packages", "main": "./dist/index.js", "types": "./dist/index.d.ts", @@ -20,8 +20,8 @@ }, "homepage": "https://github.com/keymanapp/keyman#readme", "devDependencies": { - "@keymanapp/resources-gosh": "^14.0.176", - "@keymanapp/web-environment": "^14.0.176", + "@keymanapp/resources-gosh": "^14.0.182", + "@keymanapp/web-environment": "^14.0.182", "@types/node": "^14.0.5", "typescript": "^3.8.3" } diff --git a/common/models/templates/package-lock.json b/common/models/templates/package-lock.json index 1f5b01f3da..76c5f83a80 100644 --- a/common/models/templates/package-lock.json +++ b/common/models/templates/package-lock.json @@ -1,6 +1,6 @@ { "name": "@keymanapp/models-templates", - "version": "14.0.176", + "version": "14.0.182", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/common/models/templates/package.json b/common/models/templates/package.json index 2feae9d088..3c649ca4cf 100644 --- a/common/models/templates/package.json +++ b/common/models/templates/package.json @@ -1,6 +1,6 @@ { "name": "@keymanapp/models-templates", - "version": "14.0.176", + "version": "14.0.182", "description": "Backing model implementations (templates) for Keyman's modelling layer", "keywords": [ "lm", @@ -42,8 +42,8 @@ "url": "https://github.com/keymanapp/keyman/issues" }, "devDependencies": { - "@keymanapp/models-types": "^14.0.176", - "@keymanapp/web-utils": "^14.0.176", + "@keymanapp/models-types": "^14.0.182", + "@keymanapp/web-utils": "^14.0.182", "@types/chai": "^4.2.11", "@types/mocha": "^7.0.2", "@types/node": "^14.0.4", @@ -52,6 +52,6 @@ "typescript": "^3.8.3" }, "dependencies": { - "@keymanapp/models-wordbreakers": "^14.0.176" + "@keymanapp/models-wordbreakers": "^14.0.182" } } diff --git a/common/models/types/package-lock.json b/common/models/types/package-lock.json index 122e58b66f..92453a967d 100644 --- a/common/models/types/package-lock.json +++ b/common/models/types/package-lock.json @@ -1,6 +1,6 @@ { "name": "@keymanapp/models-types", - "version": "14.0.176", + "version": "14.0.182", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/common/models/types/package.json b/common/models/types/package.json index 1349c5342f..22d2d3bec7 100644 --- a/common/models/types/package.json +++ b/common/models/types/package.json @@ -1,6 +1,6 @@ { "name": "@keymanapp/models-types", - "version": "14.0.176", + "version": "14.0.182", "description": "Type definitions in used in the modeling (lexical model/predictive text) component of Keyman.", "types": "./index.d.ts", "scripts": { diff --git a/common/models/wordbreakers/package-lock.json b/common/models/wordbreakers/package-lock.json index cc65905565..04558ca02e 100644 --- a/common/models/wordbreakers/package-lock.json +++ b/common/models/wordbreakers/package-lock.json @@ -1,6 +1,6 @@ { "name": "@keymanapp/models-wordbreakers", - "version": "14.0.176", + "version": "14.0.182", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/common/models/wordbreakers/package.json b/common/models/wordbreakers/package.json index f9cf69a098..966ddd9ae6 100644 --- a/common/models/wordbreakers/package.json +++ b/common/models/wordbreakers/package.json @@ -1,6 +1,6 @@ { "name": "@keymanapp/models-wordbreakers", - "version": "14.0.176", + "version": "14.0.182", "description": "Word breakers bundled in the modeling layer", "keywords": [ "lexical model", @@ -40,7 +40,7 @@ "url": "https://github.com/keymanapp/keyman/issues" }, "devDependencies": { - "@keymanapp/models-types": "^14.0.176", + "@keymanapp/models-types": "^14.0.182", "@types/chai": "^4.2.11", "@types/mocha": "^7.0.2", "chai": "^4.2.0", diff --git a/common/predictive-text/package-lock.json b/common/predictive-text/package-lock.json index 01eaa752f5..e166fda6b2 100644 --- a/common/predictive-text/package-lock.json +++ b/common/predictive-text/package-lock.json @@ -1,6 +1,6 @@ { "name": "@keymanapp/lexical-model-layer", - "version": "14.0.176", + "version": "14.0.182", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/common/predictive-text/package.json b/common/predictive-text/package.json index 9daa50eed6..a4fc5b4112 100644 --- a/common/predictive-text/package.json +++ b/common/predictive-text/package.json @@ -1,6 +1,6 @@ { "name": "@keymanapp/lexical-model-layer", - "version": "14.0.176", + "version": "14.0.182", "description": "Keyman/Predictive Text integration layer", "main": "build/index.js", "scripts": { @@ -21,8 +21,8 @@ }, "homepage": "https://github.com/keymanapp/keyman#readme", "devDependencies": { - "@keymanapp/models-types": "^14.0.176", - "@keymanapp/resources-gosh": "^14.0.176", + "@keymanapp/models-types": "^14.0.182", + "@keymanapp/resources-gosh": "^14.0.182", "@types/node": "^10.17.21", "chai": "^4.2.0", "karma": "^4.2.0", @@ -46,10 +46,10 @@ "typescript": "^3.8.3" }, "dependencies": { - "@keymanapp/models-templates": "^14.0.176", - "@keymanapp/models-wordbreakers": "^14.0.176", - "@keymanapp/web-environment": "^14.0.176", - "@keymanapp/web-utils": "^14.0.176", + "@keymanapp/models-templates": "^14.0.182", + "@keymanapp/models-wordbreakers": "^14.0.182", + "@keymanapp/web-environment": "^14.0.182", + "@keymanapp/web-utils": "^14.0.182", "es6-shim": "^0.35.5", "string.prototype.codepointat": "^0.2.1", "string.prototype.startswith": "^0.2.0" diff --git a/developer/js/package-lock.json b/developer/js/package-lock.json index 083a77fe63..4c58a70370 100644 --- a/developer/js/package-lock.json +++ b/developer/js/package-lock.json @@ -1,6 +1,6 @@ { "name": "@keymanapp/lexical-model-compiler", - "version": "14.0.176", + "version": "14.0.182", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/developer/js/package.json b/developer/js/package.json index d87de5bd6b..9395665db0 100644 --- a/developer/js/package.json +++ b/developer/js/package.json @@ -1,6 +1,6 @@ { "name": "@keymanapp/lexical-model-compiler", - "version": "14.0.176", + "version": "14.0.182", "description": "Keyman Developer lexical model compiler", "keywords": [ "keyboard", @@ -37,14 +37,14 @@ "node": ">=12.0.0" }, "dependencies": { - "@keymanapp/models-types": "^14.0.176", + "@keymanapp/models-types": "^14.0.182", "commander": "^3.0.0", "typescript": "^3.8.3", "xml2js": "^0.4.19" }, "devDependencies": { - "@keymanapp/models-templates": "^14.0.176", - "@keymanapp/models-wordbreakers": "^14.0.176", + "@keymanapp/models-templates": "^14.0.182", + "@keymanapp/models-wordbreakers": "^14.0.182", "@types/chai": "^4.1.7", "@types/mocha": "^5.2.7", "@types/node": "^10.14.6", diff --git a/lerna.json b/lerna.json index 54db9be65c..0a2e98949c 100644 --- a/lerna.json +++ b/lerna.json @@ -16,5 +16,5 @@ "lerna", "typescript" ], - "version": "14.0.176" + "version": "14.0.182" } diff --git a/resources/gosh/package-lock.json b/resources/gosh/package-lock.json index 3a0d2a320d..5461400719 100644 --- a/resources/gosh/package-lock.json +++ b/resources/gosh/package-lock.json @@ -1,5 +1,5 @@ { "name": "@keymanapp/resources-gosh", - "version": "14.0.176", + "version": "14.0.182", "lockfileVersion": 1 } diff --git a/resources/gosh/package.json b/resources/gosh/package.json index ec4f7adeba..023413547b 100644 --- a/resources/gosh/package.json +++ b/resources/gosh/package.json @@ -1,6 +1,6 @@ { "name": "@keymanapp/resources-gosh", - "version": "14.0.176", + "version": "14.0.182", "description": "Good Ol' Shell", "author": "Marc Durdin (https://github.com/mcdurdin)", "contributors": [ diff --git a/resources/web-environment/package-lock.json b/resources/web-environment/package-lock.json index f25b71e89d..f06053eb4e 100644 --- a/resources/web-environment/package-lock.json +++ b/resources/web-environment/package-lock.json @@ -1,5 +1,5 @@ { "name": "@keymanapp/web-environment", - "version": "14.0.176", + "version": "14.0.182", "lockfileVersion": 1 } diff --git a/resources/web-environment/package.json b/resources/web-environment/package.json index 4ee8e40030..4130442837 100644 --- a/resources/web-environment/package.json +++ b/resources/web-environment/package.json @@ -1,6 +1,6 @@ { "name": "@keymanapp/web-environment", - "version": "14.0.176", + "version": "14.0.182", "description": "A compilation utility for passing select environment variables into our TS builds", "author": "Joshua Horton (https://github.com/jahorton)", "homepage": "https://github.com/keymanapp/keyman", @@ -17,6 +17,6 @@ "url": "https://github.com/keymanapp/keyman/issues" }, "devDependencies": { - "@keymanapp/resources-gosh": "^14.0.176" + "@keymanapp/resources-gosh": "^14.0.182" } } diff --git a/web/package-lock.json b/web/package-lock.json index db7c17dc0a..169ad43706 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -1,6 +1,6 @@ { "name": "keyman", - "version": "14.0.176", + "version": "14.0.182", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/web/package.json b/web/package.json index c67a91b716..ff653df3ba 100644 --- a/web/package.json +++ b/web/package.json @@ -1,6 +1,6 @@ { "name": "keyman", - "version": "14.0.176", + "version": "14.0.182", "description": "Facilitates text input in any language.", "repository": { "type": "git", @@ -18,8 +18,8 @@ }, "homepage": "https://github.com/keymanapp/keyman#readme", "devDependencies": { - "@keymanapp/resources-gosh": "^14.0.176", - "@keymanapp/web-sentry-manager": "^14.0.176", + "@keymanapp/resources-gosh": "^14.0.182", + "@keymanapp/web-sentry-manager": "^14.0.182", "@sentry/cli": "^1.52.3", "chai": "^4.2.0", "google-closure-compiler-java": "^20200224.0.0", @@ -52,13 +52,13 @@ "sentry-cli": "sentry-cli" }, "dependencies": { - "@keymanapp/input-processor": "^14.0.176", - "@keymanapp/keyboard-processor": "^14.0.176", - "@keymanapp/lexical-model-layer": "^14.0.176", - "@keymanapp/models-types": "^14.0.176", - "@keymanapp/recorder-core": "^14.0.176", - "@keymanapp/web-environment": "^14.0.176", - "@keymanapp/web-utils": "^14.0.176", + "@keymanapp/input-processor": "^14.0.182", + "@keymanapp/keyboard-processor": "^14.0.182", + "@keymanapp/lexical-model-layer": "^14.0.182", + "@keymanapp/models-types": "^14.0.182", + "@keymanapp/recorder-core": "^14.0.182", + "@keymanapp/web-environment": "^14.0.182", + "@keymanapp/web-utils": "^14.0.182", "@types/node": "^11.9.4", "es6-shim": "^0.35.5", "eventemitter3": "^4.0.0", diff --git a/web/source/osk/visualKeyboard.ts b/web/source/osk/visualKeyboard.ts index 282f19f7b3..e3beefa17f 100644 --- a/web/source/osk/visualKeyboard.ts +++ b/web/source/osk/visualKeyboard.ts @@ -1664,11 +1664,20 @@ namespace com.keyman.osk { var classes=key.className, cs = ' kmw-key-touched'; // For phones, use key preview rather than highlighting the key, - // except for space, bksp, enter, shift and popup keys - var usePreview = ((this.keytip != null) - && (classes.indexOf('kmw-key-shift') < 0) - && (classes.indexOf('kmw-spacebar') < 0) - && (key.id.indexOf('popup') < 0 )); + var usePreview = ((this.keytip != null) && (key.id.indexOf('popup') < 0 )); + + if(usePreview) { + // Previews are not permitted for keys using any of the following CSS styles. + var excludedClasses = ['kmw-key-shift', // special keys + 'kmw-key-shift-on', // active special keys (shift, when in shift layer + 'kmw-spacebar', // space + 'kmw-key-blank', // Keys that are only used for layout control + 'kmw-key-hidden']; + + for(let c=0; c < excludedClasses.length; c++) { + usePreview = usePreview && (classes.indexOf(excludedClasses[c]) < 0); + } + } if(usePreview) { this.showKeyTip(key,on); diff --git a/web/testing/index.html b/web/testing/index.html index 8dade79279..37b21675a9 100644 --- a/web/testing/index.html +++ b/web/testing/index.html @@ -51,6 +51,7 @@

Test page for evaluating issues with mobile device rotation events.

Test page for automatic key-cap scaling.

Test page for fat-finger interaction with beep feedback

+

Test page for context() and notany() interaction

Return to main index. diff --git a/web/testing/issue917-context-and-notany/index.html b/web/testing/issue917-context-and-notany/index.html new file mode 100644 index 0000000000..b3417047b3 --- /dev/null +++ b/web/testing/issue917-context-and-notany/index.html @@ -0,0 +1,107 @@ + + + + + + + + + + + + + + + KeymanWeb Testing Page - context() and notany() interaction (#917) + + + + + + + + + + + + + + + + +

KeymanWeb Sample Page -context() and notany() interaction (#917)

+

KeymanWeb did not support notany() and context() together. This keyboard tests various scenarios in the implementation (14.0 min):

+ + + + + + + + + + + + + + + + + +
InputResultNotes
abc'abc'Should not match rule on line 19
xbc'xBC'Basic character match at start of context (notany vowel) on line 19
dbcDK(1) 'BC'Deadkey match at start of context on line 19
adcd'a' DK(1) 'XX'Second position in context, match deadkey rule on line 27
adcd?'pass!'Verifies that deadkey is conserved through rule match on line 27
axcd'axXX'Verifies that match occurs for character on line 27
axcd?'axXX?'Sanity check for line 27
fghi'fgXX'Testing adjusted index for `if` statement on line 35
fghi?'fgXX?'Sanity check for line 35
fdhi'f' DK(1) XX'Testing deadkey match for adjusted index for `if` statement on line 35
fdhi?'pass!'Verifies that deadkey is conserved thrghou rule match on line 35
+
+ +
+ +

Type in your language in this text area:

+ + +

or in this input field:

+ + +

Return to testing home page

+ + +
+ + + + + diff --git a/web/testing/issue917-context-and-notany/test_917/HISTORY.md b/web/testing/issue917-context-and-notany/test_917/HISTORY.md new file mode 100644 index 0000000000..a84bf53118 --- /dev/null +++ b/web/testing/issue917-context-and-notany/test_917/HISTORY.md @@ -0,0 +1,6 @@ +test_917 Change History +==================== + +1.0 (2020-11-04) +---------------- +* Created by diff --git a/web/testing/issue917-context-and-notany/test_917/LICENSE.md b/web/testing/issue917-context-and-notany/test_917/LICENSE.md new file mode 100644 index 0000000000..714cb32594 --- /dev/null +++ b/web/testing/issue917-context-and-notany/test_917/LICENSE.md @@ -0,0 +1,21 @@ +The MIT License (MIT) + +© + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/web/testing/issue917-context-and-notany/test_917/README.md b/web/testing/issue917-context-and-notany/test_917/README.md new file mode 100644 index 0000000000..b9fd095499 --- /dev/null +++ b/web/testing/issue917-context-and-notany/test_917/README.md @@ -0,0 +1,29 @@ +test_917 keyboard +============== + +© + +Version 1.0 + +Description +----------- + +test_917 generated from template + +Links +----- + +Supported Platforms +------------------- + * Windows + * macOS + * Linux + * Web + * iPhone + * iPad + * Android phone + * Android tablet + * Mobile devices + * Desktop devices + * Tablet devices + diff --git a/web/testing/issue917-context-and-notany/test_917/source/readme.htm b/web/testing/issue917-context-and-notany/test_917/source/readme.htm new file mode 100644 index 0000000000..9aec175da0 --- /dev/null +++ b/web/testing/issue917-context-and-notany/test_917/source/readme.htm @@ -0,0 +1,24 @@ + + + + + + test_917 + + + + +

test_917

+ +

+ test_917 1.0 generated from template. +

+ +

©

+ + + diff --git a/web/testing/issue917-context-and-notany/test_917/source/test_917.keyman-touch-layout b/web/testing/issue917-context-and-notany/test_917/source/test_917.keyman-touch-layout new file mode 100644 index 0000000000..149069b062 --- /dev/null +++ b/web/testing/issue917-context-and-notany/test_917/source/test_917.keyman-touch-layout @@ -0,0 +1,1316 @@ +{ + "tablet": { + "font": "Tahoma", + "layer": [ + { + "id": "default", + "row": [ + { + "id": 1, + "key": [ + { + "id": "K_Q", + "text": "q" + }, + { + "id": "K_W", + "text": "w" + }, + { + "id": "K_E", + "text": "e" + }, + { + "id": "K_R", + "text": "r" + }, + { + "id": "K_T", + "text": "t" + }, + { + "id": "K_Y", + "text": "y" + }, + { + "id": "K_U", + "text": "u" + }, + { + "id": "K_I", + "text": "i" + }, + { + "id": "K_O", + "text": "o" + }, + { + "id": "K_P", + "text": "p" + } + ] + }, + { + "id": 2, + "key": [ + { + "id": "K_A", + "text": "a", + "pad": 70 + }, + { + "id": "K_S", + "text": "s" + }, + { + "id": "K_D", + "text": "d" + }, + { + "id": "K_F", + "text": "f" + }, + { + "id": "K_G", + "text": "g" + }, + { + "id": "K_H", + "text": "h" + }, + { + "id": "K_J", + "text": "j" + }, + { + "id": "K_K", + "text": "k" + }, + { + "id": "K_L", + "text": "l" + }, + { + "sp": "10", + "width": "10" + } + ] + }, + { + "id": 3, + "key": [ + { + "id": "K_SHIFT", + "text": "*Shift*", + "width": "110", + "sp": "1", + "nextlayer": "shift" + }, + { + "id": "K_Z", + "text": "z" + }, + { + "id": "K_X", + "text": "x" + }, + { + "id": "K_C", + "text": "c" + }, + { + "id": "K_V", + "text": "v" + }, + { + "id": "K_B", + "text": "b" + }, + { + "id": "K_N", + "text": "n" + }, + { + "id": "K_M", + "text": "m" + }, + { + "id": "K_PERIOD", + "text": ".", + "sk": [ + { + "text": ",", + "id": "K_COMMA" + }, + { + "text": "!", + "id": "K_1", + "layer": "shift" + }, + { + "text": "?", + "id": "K_SLASH", + "layer": "shift" + }, + { + "text": "'", + "id": "K_QUOTE" + }, + { + "text": "\"", + "id": "K_QUOTE", + "layer": "shift" + }, + { + "text": "\\", + "id": "K_BKSLASH" + }, + { + "text": ":", + "id": "K_COLON", + "layer": "shift" + }, + { + "text": ";", + "id": "K_COLON" + } + ] + }, + { + "id": "K_BKSP", + "text": "*BkSp*", + "width": "90", + "sp": "1" + } + ] + }, + { + "id": 4, + "key": [ + { + "id": "K_NUMLOCK", + "text": "*123*", + "width": "140", + "sp": "1", + "nextlayer": "numeric" + }, + { + "id": "K_LOPT", + "text": "*Menu*", + "width": "120", + "sp": "1" + }, + { + "id": "K_SPACE", + "text": "", + "width": "630", + "sp": "0" + }, + { + "id": "K_ENTER", + "text": "*Enter*", + "width": "140", + "sp": "1" + } + ] + } + ] + }, + { + "id": "shift", + "row": [ + { + "id": 1, + "key": [ + { + "id": "K_Q", + "text": "Q" + }, + { + "id": "K_W", + "text": "W" + }, + { + "id": "K_E", + "text": "E" + }, + { + "id": "K_R", + "text": "R" + }, + { + "id": "K_T", + "text": "T" + }, + { + "id": "K_Y", + "text": "Y" + }, + { + "id": "K_U", + "text": "U" + }, + { + "id": "K_I", + "text": "I" + }, + { + "id": "K_O", + "text": "O" + }, + { + "id": "K_P", + "text": "P" + } + ] + }, + { + "id": 2, + "key": [ + { + "id": "K_A", + "text": "A", + "pad": 70 + }, + { + "id": "K_S", + "text": "S" + }, + { + "id": "K_D", + "text": "D" + }, + { + "id": "K_F", + "text": "F" + }, + { + "id": "K_G", + "text": "G" + }, + { + "id": "K_H", + "text": "H" + }, + { + "id": "K_J", + "text": "J" + }, + { + "id": "K_K", + "text": "K" + }, + { + "id": "K_L", + "text": "L" + }, + { + "sp": "10", + "width": "10" + } + ] + }, + { + "id": 3, + "key": [ + { + "id": "K_SHIFT", + "text": "*Shift*", + "width": "110", + "sp": "2", + "nextlayer": "default" + }, + { + "id": "K_Z", + "text": "Z" + }, + { + "id": "K_X", + "text": "X" + }, + { + "id": "K_C", + "text": "C" + }, + { + "id": "K_V", + "text": "V" + }, + { + "id": "K_B", + "text": "B" + }, + { + "id": "K_N", + "text": "N" + }, + { + "id": "K_M", + "text": "M" + }, + { + "id": "K_PERIOD", + "text": ".", + "layer": "default", + "sk": [ + { + "text": ",", + "id": "K_COMMA", + "layer": "default" + }, + { + "text": "!", + "id": "K_1", + "layer": "shift" + }, + { + "text": "?", + "id": "K_SLASH", + "layer": "shift" + }, + { + "text": "'", + "id": "K_QUOTE", + "layer": "default" + }, + { + "text": "\"", + "id": "K_QUOTE", + "layer": "shift" + }, + { + "text": "\\", + "id": "K_BKSLASH", + "layer": "default" + }, + { + "text": ":", + "id": "K_COLON", + "layer": "shift" + }, + { + "text": ";", + "id": "K_COLON", + "layer": "default" + } + ] + }, + { + "id": "K_BKSP", + "text": "*BkSp*", + "width": "90", + "sp": "1" + } + ] + }, + { + "id": 4, + "key": [ + { + "id": "K_NUMLOCK", + "text": "*123*", + "width": "140", + "sp": "1", + "nextlayer": "numeric" + }, + { + "id": "K_LOPT", + "text": "*Menu*", + "width": "120", + "sp": "1" + }, + { + "id": "K_SPACE", + "text": "", + "width": "630", + "sp": "0" + }, + { + "id": "K_ENTER", + "text": "*Enter*", + "width": "140", + "sp": "1" + } + ] + } + ] + }, + { + "id": "numeric", + "row": [ + { + "id": 1, + "key": [ + { + "id": "K_1", + "text": "1" + }, + { + "id": "K_2", + "text": "2" + }, + { + "id": "K_3", + "text": "3" + }, + { + "id": "K_4", + "text": "4" + }, + { + "id": "K_5", + "text": "5" + }, + { + "id": "K_6", + "text": "6" + }, + { + "id": "K_7", + "text": "7" + }, + { + "id": "K_8", + "text": "8" + }, + { + "id": "K_9", + "text": "9" + }, + { + "id": "K_0", + "text": "0" + } + ] + }, + { + "id": 2, + "key": [ + { + "id": "K_4", + "text": "$", + "layer": "shift", + "pad": 70 + }, + { + "id": "K_2", + "text": "@", + "layer": "shift" + }, + { + "id": "K_3", + "text": "#", + "layer": "shift" + }, + { + "id": "K_5", + "text": "%", + "layer": "shift" + }, + { + "id": "K_7", + "text": "&", + "layer": "shift" + }, + { + "id": "K_HYPHEN", + "text": "_", + "layer": "shift" + }, + { + "id": "K_EQUAL", + "text": "=", + "layer": "default" + }, + { + "id": "K_BKSLASH", + "text": "|", + "layer": "shift" + }, + { + "id": "K_BKSLASH", + "text": "\\", + "layer": "default" + }, + { + "text": "", + "width": "10", + "sp": "10" + } + ] + }, + { + "id": 3, + "key": [ + { + "id": "K_SHIFT", + "text": "*Shift*", + "width": "110", + "sp": "1" + }, + { + "id": "K_LBRKT", + "text": "[", + "sk": [ + { + "id": "U_00AB", + "text": "\u00AB" + }, + { + "id": "K_COMMA", + "text": "<", + "layer": "shift" + }, + { + "id": "K_LBRKT", + "text": "{", + "layer": "shift" + } + ] + }, + { + "id": "K_9", + "text": "(", + "layer": "shift" + }, + { + "id": "K_0", + "text": ")", + "layer": "shift" + }, + { + "id": "K_RBRKT", + "text": "]", + "sk": [ + { + "id": "U_00BB", + "text": "\u00BB" + }, + { + "id": "K_PERIOD", + "text": ">", + "layer": "shift" + }, + { + "id": "K_RBRKT", + "text": "}", + "layer": "shift" + } + ] + }, + { + "id": "K_EQUAL", + "text": "+", + "layer": "shift" + }, + { + "id": "K_HYPHEN", + "text": "-", + "layer": "default" + }, + { + "id": "K_8", + "text": "*", + "layer": "shift" + }, + { + "id": "K_SLASH", + "text": "/", + "layer": "default" + }, + { + "id": "K_BKSP", + "text": "*BkSp*", + "width": "90", + "sp": "1" + } + ] + }, + { + "id": 4, + "key": [ + { + "id": "K_LOWER", + "text": "*abc*", + "width": "140", + "sp": "1", + "nextlayer": "default" + }, + { + "id": "K_LOPT", + "text": "*Menu*", + "width": "120", + "sp": "1" + }, + { + "id": "K_SPACE", + "text": "", + "width": "630", + "sp": "0" + }, + { + "id": "K_ENTER", + "text": "*Enter*", + "width": "140", + "sp": "1" + } + ] + } + ] + } + ] + }, + "phone": { + "font": "Tahoma", + "layer": [ + { + "id": "default", + "row": [ + { + "id": 1, + "key": [ + { + "id": "K_Q", + "text": "q" + }, + { + "id": "K_W", + "text": "w" + }, + { + "id": "K_E", + "text": "e" + }, + { + "id": "K_R", + "text": "r" + }, + { + "id": "K_T", + "text": "t" + }, + { + "id": "K_Y", + "text": "y" + }, + { + "id": "K_U", + "text": "u" + }, + { + "id": "K_I", + "text": "i" + }, + { + "id": "K_O", + "text": "o" + }, + { + "id": "K_P", + "text": "p" + } + ] + }, + { + "id": 2, + "key": [ + { + "id": "K_A", + "text": "a", + "pad": "50" + }, + { + "id": "K_S", + "text": "s" + }, + { + "id": "K_D", + "text": "d" + }, + { + "id": "K_F", + "text": "f" + }, + { + "id": "K_G", + "text": "g" + }, + { + "id": "K_H", + "text": "h" + }, + { + "id": "K_J", + "text": "j" + }, + { + "id": "K_K", + "text": "k" + }, + { + "id": "K_L", + "text": "l" + }, + { + "text": "", + "width": "10", + "sp": "10" + } + ] + }, + { + "id": 3, + "key": [ + { + "id": "K_SHIFT", + "text": "*Shift*", + "sp": "1", + "nextlayer": "shift" + }, + { + "id": "K_Z", + "text": "z" + }, + { + "id": "K_X", + "text": "x" + }, + { + "id": "K_C", + "text": "c" + }, + { + "id": "K_V", + "text": "v" + }, + { + "id": "K_B", + "text": "b" + }, + { + "id": "K_N", + "text": "n" + }, + { + "id": "K_M", + "text": "m" + }, + { + "id": "K_PERIOD", + "text": ".", + "sk": [ + { + "text": ",", + "id": "K_COMMA" + }, + { + "text": "!", + "id": "K_1", + "layer": "shift" + }, + { + "text": "?", + "id": "K_SLASH", + "layer": "shift" + }, + { + "text": "'", + "id": "K_QUOTE" + }, + { + "text": "\"", + "id": "K_QUOTE", + "layer": "shift" + }, + { + "text": "\\", + "id": "K_BKSLASH" + }, + { + "text": ":", + "id": "K_COLON", + "layer": "shift" + }, + { + "text": ";", + "id": "K_COLON" + } + ] + }, + { + "id": "K_BKSP", + "text": "*BkSp*", + "width": "100", + "sp": "1" + } + ] + }, + { + "id": 4, + "key": [ + { + "id": "K_NUMLOCK", + "text": "*123*", + "width": "150", + "sp": "1", + "nextlayer": "numeric" + }, + { + "id": "K_LOPT", + "text": "*Menu*", + "width": "120", + "sp": "1" + }, + { + "id": "K_SPACE", + "text": "", + "width": "610", + "sp": "0" + }, + { + "id": "K_ENTER", + "text": "*Enter*", + "width": "150", + "sp": "1" + } + ] + } + ] + }, + { + "id": "shift", + "row": [ + { + "id": 1, + "key": [ + { + "id": "K_Q", + "text": "Q" + }, + { + "id": "K_W", + "text": "W" + }, + { + "id": "K_E", + "text": "E" + }, + { + "id": "K_R", + "text": "R" + }, + { + "id": "K_T", + "text": "T" + }, + { + "id": "K_Y", + "text": "Y" + }, + { + "id": "K_U", + "text": "U" + }, + { + "id": "K_I", + "text": "I" + }, + { + "id": "K_O", + "text": "O" + }, + { + "id": "K_P", + "text": "P" + } + ] + }, + { + "id": 2, + "key": [ + { + "id": "K_A", + "text": "A", + "pad": "50" + }, + { + "id": "K_S", + "text": "S" + }, + { + "id": "K_D", + "text": "D" + }, + { + "id": "K_F", + "text": "F" + }, + { + "id": "K_G", + "text": "G" + }, + { + "id": "K_H", + "text": "H" + }, + { + "id": "K_J", + "text": "J" + }, + { + "id": "K_K", + "text": "K" + }, + { + "id": "K_L", + "text": "L" + }, + { + "text": "", + "width": "10", + "sp": "10" + } + ] + }, + { + "id": 3, + "key": [ + { + "id": "K_SHIFT", + "text": "*Shift*", + "sp": "2", + "nextlayer": "default" + }, + { + "id": "K_Z", + "text": "Z" + }, + { + "id": "K_X", + "text": "X" + }, + { + "id": "K_C", + "text": "C" + }, + { + "id": "K_V", + "text": "V" + }, + { + "id": "K_B", + "text": "B" + }, + { + "id": "K_N", + "text": "N" + }, + { + "id": "K_M", + "text": "M" + }, + { + "id": "K_PERIOD", + "text": ".", + "layer": "default", + "sk": [ + { + "text": ",", + "id": "K_COMMA", + "layer": "default" + }, + { + "text": "!", + "id": "K_1", + "layer": "shift" + }, + { + "text": "?", + "id": "K_SLASH", + "layer": "shift" + }, + { + "text": "'", + "id": "K_QUOTE", + "layer": "default" + }, + { + "text": "\"", + "id": "K_QUOTE", + "layer": "shift" + }, + { + "text": "\\", + "id": "K_BKSLASH", + "layer": "default" + }, + { + "text": ":", + "id": "K_COLON", + "layer": "shift" + }, + { + "text": ";", + "id": "K_COLON", + "layer": "default" + } + ] + }, + { + "id": "K_BKSP", + "text": "*BkSp*", + "sp": "1" + } + ] + }, + { + "id": 4, + "key": [ + { + "id": "K_NUMLOCK", + "text": "*123*", + "width": "150", + "sp": "1", + "nextlayer": "numeric" + }, + { + "id": "K_LOPT", + "text": "*Menu*", + "width": "120", + "sp": "1" + }, + { + "id": "K_SPACE", + "text": "", + "width": "610", + "sp": "0" + }, + { + "id": "K_ENTER", + "text": "*Enter*", + "width": "150", + "sp": "1" + } + ] + } + ] + }, + { + "id": "numeric", + "row": [ + { + "id": 1, + "key": [ + { + "id": "K_1", + "text": "1" + }, + { + "id": "K_2", + "text": "2" + }, + { + "id": "K_3", + "text": "3" + }, + { + "id": "K_4", + "text": "4" + }, + { + "id": "K_5", + "text": "5" + }, + { + "id": "K_6", + "text": "6" + }, + { + "id": "K_7", + "text": "7" + }, + { + "id": "K_8", + "text": "8" + }, + { + "id": "K_9", + "text": "9" + }, + { + "id": "K_0", + "text": "0" + } + ] + }, + { + "id": 2, + "key": [ + { + "id": "K_4", + "layer": "shift", + "text": "$", + "pad": "50" + }, + { + "id": "K_2", + "layer": "shift", + "text": "@" + }, + { + "id": "K_3", + "layer": "shift", + "text": "#" + }, + { + "id": "K_5", + "layer": "shift", + "text": "%" + }, + { + "id": "K_6", + "layer": "shift", + "text": "&" + }, + { + "id": "K_HYPHEN", + "layer": "shift", + "text": "_" + }, + { + "id": "K_EQUAL", + "text": "=", + "layer": "default" + }, + { + "id": "K_BKSLASH", + "layer": "shift", + "text": "|" + }, + { + "id": "K_BKSLASH", + "text": "\\", + "layer": "default" + }, + { + "text": "", + "width": "10", + "sp": "10" + } + ] + }, + { + "id": 3, + "key": [ + { + "id": "K_LBRKT", + "text": "[", + "pad": "110", + "sk": [ + { + "id": "U_00AB", + "text": "\u00AB" + }, + { + "id": "K_COMMA", + "text": "<", + "layer": "shift" + }, + { + "id": "K_LBRKT", + "text": "{", + "layer": "shift" + } + ] + }, + { + "id": "K_9", + "layer": "shift", + "text": "(" + }, + { + "id": "K_0", + "layer": "shift", + "text": ")" + }, + { + "id": "K_RBRKT", + "text": "]", + "sk": [ + { + "id": "U_00BB", + "text": "\u00BB" + }, + { + "id": "K_PERIOD", + "text": ">", + "layer": "shift" + }, + { + "id": "K_RBRKT", + "text": "}", + "layer": "shift" + } + ] + }, + { + "id": "K_EQUAL", + "layer": "shift", + "text": "+" + }, + { + "id": "K_HYPHEN", + "text": "-" + }, + { + "id": "K_8", + "layer": "shift", + "text": "*" + }, + { + "id": "K_SLASH", + "text": "/" + }, + { + "id": "K_BKSP", + "text": "*BkSp*", + "width": "100", + "sp": "1" + } + ] + }, + { + "id": 4, + "key": [ + { + "id": "K_LOWER", + "text": "*abc*", + "width": "150", + "sp": "1", + "nextlayer": "default" + }, + { + "id": "K_LOPT", + "text": "*Menu*", + "width": "120", + "sp": "1" + }, + { + "id": "K_SPACE", + "text": "", + "width": "610", + "sp": "0" + }, + { + "id": "K_ENTER", + "text": "*Enter*", + "width": "150", + "sp": "1" + } + ] + } + ] + } + ] + } +} diff --git a/web/testing/issue917-context-and-notany/test_917/source/test_917.kmn b/web/testing/issue917-context-and-notany/test_917/source/test_917.kmn new file mode 100644 index 0000000000..d672058145 --- /dev/null +++ b/web/testing/issue917-context-and-notany/test_917/source/test_917.kmn @@ -0,0 +1,36 @@ +c test_917 generated from template at 2020-11-04 06:59:27 +c with name "test_917" +c store(&VERSION) '14.0' +store(&NAME) 'test_917' +store(©RIGHT) '©' +store(&KEYBOARDVERSION) '1.0' +store(&TARGETS) 'any' +store(&VISUALKEYBOARD) 'test_917.kvks' +store(&LAYOUTFILE) 'test_917.keyman-touch-layout' + +begin Unicode > use(main) + +group(main) using keys + +c type: 'abc' > 'abc' +c type: 'xbc' > 'xBC' +c type: 'dbc' > DK(1) 'BC' +store(vow) 'aeiou' +notany(vow) 'b' + 'c' > context(1) 'BC' ++ 'd' > dk(1) +dk(1) 'BC' + '?' > 'pass!' + +c type: 'adcd' > 'a' DK(1) 'XX' +c type: 'adcd?' > 'pass!' +c type: 'axcd' > 'axXX' +c type: 'axcd?' > 'axXX?' +'a' notany(vow) 'c' + 'd' > context(1) context(2) 'XX' +'a' dk(1) 'XX' + '?' > 'pass!' + +c Test for AdjustIndex correctness +c type: 'fghi' > 'fgXX' +c type: 'fghi?' > 'fgXX?' +c type: 'fdhi' > 'f' DK(1) 'XX' +c type: 'fdhi?' > 'pass!' +if(&platform = 'web') 'f' notany(vow) 'h' + 'i' > context(2) context(3) 'XX' +'f' dk(1) 'XX' + '?' > 'pass!' diff --git a/web/testing/issue917-context-and-notany/test_917/source/test_917.kps b/web/testing/issue917-context-and-notany/test_917/source/test_917.kps new file mode 100644 index 0000000000..e10bba7598 --- /dev/null +++ b/web/testing/issue917-context-and-notany/test_917/source/test_917.kps @@ -0,0 +1,65 @@ + + + + 13.0.9999.0 + 7.0 + + + + readme.htm + + + + + + + + + + test_917 + © + + + + + + ..\build\test_917.kmx + + 0 + .kmx + + + ..\build\test_917.js + + 0 + .js + + + ..\build\test_917.kvk + + 0 + .kvk + + + welcome.htm + + 0 + .htm + + + readme.htm + + 0 + .htm + + + + + test_917 + test_917 + 1.0 + + + + + diff --git a/web/testing/issue917-context-and-notany/test_917/source/test_917.kvks b/web/testing/issue917-context-and-notany/test_917/source/test_917.kvks new file mode 100644 index 0000000000..30a0b2605b --- /dev/null +++ b/web/testing/issue917-context-and-notany/test_917/source/test_917.kvks @@ -0,0 +1,8 @@ + + +
+ 10.0 + test_917 + +
+
diff --git a/web/testing/issue917-context-and-notany/test_917/source/welcome.htm b/web/testing/issue917-context-and-notany/test_917/source/welcome.htm new file mode 100644 index 0000000000..2ef5d177c8 --- /dev/null +++ b/web/testing/issue917-context-and-notany/test_917/source/welcome.htm @@ -0,0 +1,28 @@ + + + + + + Start Using test_917 + + + + +

Start Using test_917

+ +

+ test_917 1.0 generated from template. +

+ +

Keyboard Layout

+ + + +

©

+ + + \ No newline at end of file diff --git a/web/testing/issue917-context-and-notany/test_917/test_917.keyboard_info b/web/testing/issue917-context-and-notany/test_917/test_917.keyboard_info new file mode 100644 index 0000000000..ac39732308 --- /dev/null +++ b/web/testing/issue917-context-and-notany/test_917/test_917.keyboard_info @@ -0,0 +1,7 @@ +{ + "license": "mit", + "languages": [ + + ], + "description": "test_917 generated from template" +} diff --git a/web/testing/issue917-context-and-notany/test_917/test_917.kpj b/web/testing/issue917-context-and-notany/test_917/test_917.kpj new file mode 100644 index 0000000000..9c3cf4ad2f --- /dev/null +++ b/web/testing/issue917-context-and-notany/test_917/test_917.kpj @@ -0,0 +1,102 @@ + + + + $PROJECTPATH\build + True + True + True + keyboard + + + + id_8da317fcfaf031055ee9c2eb9e37cd18 + test_917.kmn + source\test_917.kmn + 1.0 + .kmn +
+ test_917 + © +
+
+ + id_7ef252dbb1aa15741f7e0694c9d8ede2 + test_917.kps + source\test_917.kps + + .kps +
+ test_917 + © +
+
+ + id_ede98e4633e239f933cbfd1f4e1b766c + HISTORY.md + HISTORY.md + + .md + + + id_53e892b8b41cc4caece1cfd5ef21d6e7 + LICENSE.md + LICENSE.md + + .md + + + id_0730bb7c2e8f9ea2438b52e419dd86c9 + README.md + README.md + + .md + + + id_e7fcb5e5546db6914d2f9d00de067f23 + test_917.keyboard_info + test_917.keyboard_info + + .keyboard_info + + + id_00188325e13e88dc8f51b78b3fcd756e + test_917.kmx + source\..\build\test_917.kmx + + .kmx + id_7ef252dbb1aa15741f7e0694c9d8ede2 + + + id_48e2443376bf0ead24ae53bb23ec7608 + test_917.js + source\..\build\test_917.js + + .js + id_7ef252dbb1aa15741f7e0694c9d8ede2 + + + id_6ca4926c8522c0080861ceeeb2abb05a + test_917.kvk + source\..\build\test_917.kvk + + .kvk + id_7ef252dbb1aa15741f7e0694c9d8ede2 + + + id_356e5d149c1e539356d72698c1e401a6 + welcome.htm + source\welcome.htm + + .htm + id_7ef252dbb1aa15741f7e0694c9d8ede2 + + + id_8da344c4cea6f467013357fe099006f5 + readme.htm + source\readme.htm + + .htm + id_7ef252dbb1aa15741f7e0694c9d8ede2 + +
+
diff --git a/windows/src/Defines.mak b/windows/src/Defines.mak index 0c1aaceb8d..4ed08e3b4d 100644 --- a/windows/src/Defines.mak +++ b/windows/src/Defines.mak @@ -273,3 +273,40 @@ MKVER_V=$(MKVER_APP) $(MKVER_COMMON_PARAMS) -v $(MKVER_VERSION_TXT) version.in v MKVER_M=$(MKVER_APP) $(MKVER_COMMON_PARAMS) -m manifest.in manifest.xml # Token replacement for all other file types; pattern: $(MKVER_U) MKVER_U=$(MKVER_APP) $(MKVER_COMMON_PARAMS) -u + +# +# Symstore +# + +# KEYMAN_SYMSTOREPATH defaults to sibling folder "symbols". If it is not present, +# then we won't attempt to write symbols to the store. +!IFNDEF KEYMAN_SYMSTOREPATH +KEYMAN_SYMSTOREPATH=$(KEYMAN_ROOT)\..\symbols +!ENDIF + +# Nearly matches algorithm from resources/build/build-utils.sh +# For now, we'll use it only for SYMSTORE, where it is for reference +# only. Thus using the variable name __VERSION_WITH_TAG. Issues: +# 1. always appends tier, even for stable +# 2. test builds will append a branch name for master/beta/stable-x.y +# 3. this is only available for `make symbols` (VERSION_WIN, VERSION_TIER +# are defined in Targets.mak only here) +# Fixing this properly would be possible but take a fair bit more +# work than I want to do just now. The intent is to make it possible to find +# symbols in the symstore index which we can purge later on. +__VERSION_WITH_TAG=$(VERSION_WIN)-$(VERSION_TIER) +!IFNDEF TEAMCITY_VERSION + __VERSION_WITH_TAG=$(__VERSION_WITH_TAG)-local +!ELSE +!IFDEF TEAMCITY_PR_NUMBER + __VERSION_WITH_TAG=$(__VERSION_WITH_TAG)-test-$(TEAMCITY_PR_NUMBER) +!ENDIF +!ENDIF + +# This command depends on VERSION_WIN and VERSION_TIER being defined, through +# `make symbols` (i.e. don't call `make wrap-symbols`) +SYMSTORE="C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\symstore.exe" add \ + /s "$(KEYMAN_SYMSTOREPATH)" \ + /v "$(VERSION_WIN)" \ + /c "Version: $(__VERSION_WITH_TAG)" \ + /compress /f diff --git a/windows/src/Header.mak b/windows/src/Header.mak index 1511f70af2..c6a0b15eac 100644 --- a/windows/src/Header.mak +++ b/windows/src/Header.mak @@ -2,6 +2,8 @@ # Header.mak - used for makefiles which are in parent folders # +HEADER_MAK=1 + !IFNDEF TARGETS !ERROR You must define the targets before including the Header.mak file! !ENDIF @@ -17,7 +19,8 @@ ROOT=c:\keyman\windows !include $(ROOT)\src\Defines.mak # -# These three targets are the standard targets for all +# The targets build, signcode, symbols, backup are standard +# targets for all projects # build: $(BUILDPREREQ) @@ -27,12 +30,18 @@ build: $(BUILDPREREQ) signcode: $(MAKE) -DTARGET=signcode $(TARGETS) +symbols: + $(MAKE) -DTARGET=symbols $(TARGETS) + backup: $(MAKE) -DTARGET=backup $(TARGETS) !ELSE signcode: rem no signcode required +symbols: + rem no symbols required + backup: rem no backup required !ENDIF diff --git a/windows/src/Target.mak b/windows/src/Target.mak index 6a4594eab0..f8a1e6c9ac 100644 --- a/windows/src/Target.mak +++ b/windows/src/Target.mak @@ -66,3 +66,16 @@ dirs: vcvars32: vcvars32.bat + +# This command injects the current version and tier into the VERSION_WIN and VERSION_TIER defines and then +# calls "make wrap-symbols", but it only runs if the symbols folder exists + +!IFNDEF HEADER_MAK +# we don't want this target for Makefiles with Header.mak, as they just call into sub-projects +symbols: + if exist $(KEYMAN_SYMSTOREPATH) \ + cmd /C \ + for /f %v in ($(KEYMAN_ROOT)\VERSION.md) do \ + for /f %t in ($(KEYMAN_ROOT)\TIER.md) do \ + $(MAKE) -DVERSION_TIER=%t -DVERSION_WIN=%v wrap-symbols +!ENDIF \ No newline at end of file diff --git a/windows/src/buildtools/build_standards_data/build_standards_data.dproj b/windows/src/buildtools/build_standards_data/build_standards_data.dproj index 44a5e23ce4..ac9ec94bef 100644 --- a/windows/src/buildtools/build_standards_data/build_standards_data.dproj +++ b/windows/src/buildtools/build_standards_data/build_standards_data.dproj @@ -50,6 +50,7 @@ RESTComponents;FireDAC;FireDACSqliteDriver;soaprtl;FireDACIBDriver;soapmidas;FireDACCommon;RESTBackendComponents;soapserver;CloudService;FireDACCommonDriver;inet;$(DCC_UsePackage) System;Xml;Data;Datasnap;Web;Soap;$(DCC_Namespace) build_standards_data + true DBXSqliteDriver;bindcompdbx;IndyIPCommon;DBXInterBaseDriver;vcl;IndyIPServer;vclactnband;vclFireDAC;IndySystem;tethering;svnui;mbColorLibD10;dsnapcon;FireDACADSDriver;scFontCombo;DCPdelphi2009;FireDACMSAccDriver;fmxFireDAC;vclimg;Jcl;vcltouch;JvCore;vcldb;bindcompfmx;svn;FireDACPgDriver;inetdb;DbxCommonDriver;fmx;fmxdae;xmlrtl;fmxobj;vclwinx;rtl;DbxClientDriver;CustomIPTransport;vcldsnap;dbexpress;IndyCore;vclx;bindcomp;appanalytics;dsnap;IndyIPClient;bindcompvcl;EmbeddedWebBrowser_XE;VCLRESTComponents;dbxcds;VclSmp;JvDocking;adortl;JclVcl;vclie;bindengine;DBXMySQLDriver;dsnapxml;FireDACMySQLDriver;dbrtl;inetdbxpress;IndyProtocols;keyman_components;FireDACCommonODBC;fmxase;$(DCC_UsePackage) diff --git a/windows/src/buildtools/buildpkg/Makefile b/windows/src/buildtools/buildpkg/Makefile index 2b432e9061..f3c59c40e3 100644 --- a/windows/src/buildtools/buildpkg/Makefile +++ b/windows/src/buildtools/buildpkg/Makefile @@ -6,8 +6,8 @@ build: version.res dirs $(DCC32) Buildpkg.dpr - $(TDS2DBG) buildpkg.exe $(SENTRYTOOL_DELPHIPREP) buildpkg.exe -dpr buildpkg.dpr + $(TDS2DBG) buildpkg.exe $(COPY) Buildpkg.exe $(PROGRAM)\online $(COPY) Buildpkg.exe $(PROGRAM)\buildtools if exist buildpkg.dbg $(COPY) buildpkg.dbg $(DEBUGPATH)\buildtools diff --git a/windows/src/buildtools/buildpkg/buildpkg.dproj b/windows/src/buildtools/buildpkg/buildpkg.dproj index 356dd7a92e..c2d3863286 100644 --- a/windows/src/buildtools/buildpkg/buildpkg.dproj +++ b/windows/src/buildtools/buildpkg/buildpkg.dproj @@ -62,6 +62,7 @@ false true None + true Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) @@ -212,8 +213,8 @@ - Microsoft Office 2000 Sample Automation Server Wrapper Components - Microsoft Office XP Sample Automation Server Wrapper Components + Microsoft Office 2000 Sample Automation Server Wrapper Components + Microsoft Office XP Sample Automation Server Wrapper Components diff --git a/windows/src/buildtools/importkeyboard/Makefile b/windows/src/buildtools/importkeyboard/Makefile index c0fd710689..52695c8476 100644 --- a/windows/src/buildtools/importkeyboard/Makefile +++ b/windows/src/buildtools/importkeyboard/Makefile @@ -15,6 +15,10 @@ clean: def-clean signcode: $(SIGNCODE) /d "Keyman Developer Tools" $(PROGRAM)\buildtools\importkeyboard.exe +wrap-symbols: + $(SYMSTORE) $(PROGRAM)\buildtools\importkeyboard.exe /t keyman-developer + $(SYMSTORE) $(DEBUGPATH)\buildtools\importkeyboard.pdb /t keyman-developer + backup: $(WZZIP) $(BUILD)\buildtools\importkeyboard.zip $(BACKUPDEFAULTS) importkeyboard.exe diff --git a/windows/src/buildtools/sentrytool/sentrytool.dproj b/windows/src/buildtools/sentrytool/sentrytool.dproj index bdba926643..76fb6400f7 100644 --- a/windows/src/buildtools/sentrytool/sentrytool.dproj +++ b/windows/src/buildtools/sentrytool/sentrytool.dproj @@ -49,6 +49,7 @@ false System;Xml;Data;Datasnap;Web;Soap;$(DCC_Namespace) sentrytool + true DBXSqliteDriver;IndyIPCommon;RESTComponents;bindcompdbx;DBXInterBaseDriver;vcl;IndyIPServer;vclactnband;vclFireDAC;IndySystem;tethering;svnui;mbColorLibD10;dsnapcon;FireDACADSDriver;scFontCombo;DCPdelphi2009;FireDACMSAccDriver;fmxFireDAC;vclimg;Jcl;FireDAC;vcltouch;JvCore;vcldb;bindcompfmx;svn;FireDACSqliteDriver;FireDACPgDriver;inetdb;CEF4Delphi;soaprtl;DbxCommonDriver;fmx;FireDACIBDriver;fmxdae;xmlrtl;soapmidas;fmxobj;vclwinx;rtl;DbxClientDriver;CustomIPTransport;vcldsnap;dbexpress;IndyCore;vclx;bindcomp;appanalytics;dsnap;FireDACCommon;IndyIPClient;bindcompvcl;RESTBackendComponents;EmbeddedWebBrowser_XE;VCLRESTComponents;soapserver;dbxcds;VclSmp;JvDocking;adortl;JclVcl;vclie;bindengine;DBXMySQLDriver;CloudService;dsnapxml;FireDACMySQLDriver;dbrtl;IndyProtocols;inetdbxpress;keyman_components;FireDACCommonODBC;FireDACCommonDriver;inet;fmxase;$(DCC_UsePackage) @@ -76,7 +77,6 @@ false - true 1033 (None) C:\Projects\keyman\app\windows\src\engine\tsysinfox64 diff --git a/windows/src/desktop/insthelp/Makefile b/windows/src/desktop/insthelp/Makefile index 5aad1d679b..2fd7f158f2 100644 --- a/windows/src/desktop/insthelp/Makefile +++ b/windows/src/desktop/insthelp/Makefile @@ -6,8 +6,8 @@ build: version.res dirs $(DCC32) insthelp.dpr - $(TDS2DBG) insthelp.exe $(SENTRYTOOL_DELPHIPREP) insthelp.exe -dpr insthelp.dpr + $(TDS2DBG) insthelp.exe $(COPY) insthelp.exe $(ROOT)\bin\desktop\insthelp.exe test-manifest: @@ -20,6 +20,10 @@ clean: def-clean signcode: $(SIGNCODE) /d "Keyman Desktop Install Helper" $(ROOT)\bin\desktop\insthelp.exe +wrap-symbols: + $(SYMSTORE) $(PROGRAM)\desktop\insthelp.exe /t keyman-windows + $(SYMSTORE) $(DEBUGPATH)\desktop\insthelp.dbg /t keyman-windows + backup: $(WZZIP) $(BUILD)\desktop\insthelp.zip $(BACKUPDEFAULTS) insthelp.exe diff --git a/windows/src/desktop/kmbrowserhost/Makefile b/windows/src/desktop/kmbrowserhost/Makefile index 704cca2666..8dea82e831 100644 --- a/windows/src/desktop/kmbrowserhost/Makefile +++ b/windows/src/desktop/kmbrowserhost/Makefile @@ -7,8 +7,8 @@ build: version.res manifest.res dirs $(DELPHI_MSBUILD) kmbrowserhost.dproj /p:Platform=Win32 - $(TDS2DBG) $(WIN32_TARGET_PATH)\kmbrowserhost.exe $(SENTRYTOOL_DELPHIPREP) $(WIN32_TARGET_PATH)\kmbrowserhost.exe -dpr kmbrowserhost.dpr + $(TDS2DBG) $(WIN32_TARGET_PATH)\kmbrowserhost.exe $(COPY) $(WIN32_TARGET_PATH)\kmbrowserhost.exe $(PROGRAM)\desktop if exist $(WIN32_TARGET_PATH)\kmbrowserhost.dbg $(COPY) $(WIN32_TARGET_PATH)\kmbrowserhost.dbg $(DEBUGPATH)\desktop @@ -23,6 +23,10 @@ signcode: install: $(COPY) $(PROGRAM)\desktop\kmbrowserhost.exe "$(INSTALLPATH_KEYMANDESKTOP)" +wrap-symbols: + $(SYMSTORE) $(PROGRAM)\desktop\kmbrowserhost.exe /t keyman-windows + $(SYMSTORE) $(DEBUGPATH)\desktop\kmbrowserhost.dbg /t keyman-windows + backup: $(WZZIP) $(BUILD)\desktop\kmbrowserhost.zip $(BACKUPDEFAULTS) $(WIN32_TARGET_PATH)\kmbrowserhost.exe $(WIN32_TARGET_PATH)\kmbrowserhost.dbg diff --git a/windows/src/desktop/kmbrowserhost/kmbrowserhost.dproj b/windows/src/desktop/kmbrowserhost/kmbrowserhost.dproj index 80c59f308e..023fb02cac 100644 --- a/windows/src/desktop/kmbrowserhost/kmbrowserhost.dproj +++ b/windows/src/desktop/kmbrowserhost/kmbrowserhost.dproj @@ -62,6 +62,7 @@ SENTRY_NOVCL;$(DCC_Define) 3081 CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments= + true DBXSqliteDriver;bindcompdbx;IndyIPCommon;DBXInterBaseDriver;vcl;IndyIPServer;vclactnband;vclFireDAC;IndySystem;tethering;svnui;mbColorLibD10;dsnapcon;FireDACADSDriver;scFontCombo;DCPdelphi2009;FireDACMSAccDriver;fmxFireDAC;vclimg;Jcl;vcltouch;JvCore;vcldb;bindcompfmx;svn;FireDACPgDriver;inetdb;CEF4Delphi;DbxCommonDriver;fmx;fmxdae;xmlrtl;fmxobj;vclwinx;rtl;DbxClientDriver;CustomIPTransport;vcldsnap;dbexpress;IndyCore;vclx;bindcomp;appanalytics;dsnap;IndyIPClient;bindcompvcl;EmbeddedWebBrowser_XE;VCLRESTComponents;dbxcds;VclSmp;JvDocking;adortl;JclVcl;vclie;bindengine;DBXMySQLDriver;dsnapxml;FireDACMySQLDriver;dbrtl;inetdbxpress;IndyProtocols;keyman_components;FireDACCommonODBC;fmxase;$(DCC_UsePackage) @@ -70,7 +71,6 @@ CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments= 1033 (None) - true DBXSqliteDriver;bindcompdbx;IndyIPCommon;DBXInterBaseDriver;vcl;IndyIPServer;vclactnband;vclFireDAC;IndySystem;tethering;dsnapcon;FireDACADSDriver;FireDACMSAccDriver;fmxFireDAC;vclimg;Jcl;vcltouch;vcldb;bindcompfmx;FireDACPgDriver;inetdb;DbxCommonDriver;fmx;fmxdae;xmlrtl;fmxobj;vclwinx;rtl;DbxClientDriver;CustomIPTransport;vcldsnap;dbexpress;IndyCore;vclx;bindcomp;appanalytics;dsnap;IndyIPClient;bindcompvcl;VCLRESTComponents;dbxcds;VclSmp;adortl;JclVcl;vclie;bindengine;DBXMySQLDriver;dsnapxml;FireDACMySQLDriver;dbrtl;inetdbxpress;IndyProtocols;FireDACCommonODBC;fmxase;$(DCC_UsePackage) diff --git a/windows/src/desktop/kmconfig/Makefile b/windows/src/desktop/kmconfig/Makefile index 80eaf2a02c..447de763bc 100644 --- a/windows/src/desktop/kmconfig/Makefile +++ b/windows/src/desktop/kmconfig/Makefile @@ -6,10 +6,10 @@ build: version.res manifest.res #icons $(DELPHI_MSBUILD) kmconfig.dproj /p:Platform=Win32 - $(TDS2DBG) $(WIN32_TARGET_PATH)\kmconfig.exe $(SENTRYTOOL_DELPHIPREP) $(WIN32_TARGET_PATH)\kmconfig.exe -dpr kmconfig.exe + $(TDS2DBG) $(WIN32_TARGET_PATH)\kmconfig.exe $(COPY) $(WIN32_TARGET_PATH)\kmconfig.exe $(PROGRAM)\desktop - if exist $(WIN32_TARGET_PATH)\kmconfig.exe $(COPY) $(WIN32_TARGET_PATH)\kmconfig.exe $(DEBUGPATH)\desktop + if exist $(WIN32_TARGET_PATH)\kmconfig.dbg $(COPY) $(WIN32_TARGET_PATH)\kmconfig.dbg $(DEBUGPATH)\desktop #icons: #rc icons.rc @@ -19,6 +19,10 @@ clean: def-clean signcode: $(SIGNCODE) /d "Keyman for Windows" $(PROGRAM)\desktop\kmconfig.exe +wrap-symbols: + $(SYMSTORE) $(PROGRAM)\desktop\kmconfig.exe /t keyman-windows + $(SYMSTORE) $(DEBUGPATH)\desktop\kmconfig.dbg /t keyman-windows + backup: $(WZZIP) $(BUILD)\desktop\kmconfig.zip $(BACKUPDEFAULTS) kmconfig.exe diff --git a/windows/src/desktop/kmconfig/kmconfig.dproj b/windows/src/desktop/kmconfig/kmconfig.dproj index f2b1664a93..e64a21454e 100644 --- a/windows/src/desktop/kmconfig/kmconfig.dproj +++ b/windows/src/desktop/kmconfig/kmconfig.dproj @@ -58,6 +58,7 @@ $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png kmconfig + true DBXSqliteDriver;IndyIPCommon;RESTComponents;bindcompdbx;DBXInterBaseDriver;vcl;IndyIPServer;vclactnband;vclFireDAC;IndySystem;tethering;svnui;mbColorLibD10;dsnapcon;FireDACADSDriver;scFontCombo;DCPdelphi2009;FireDACMSAccDriver;fmxFireDAC;vclimg;Jcl;FireDAC;vcltouch;JvCore;vcldb;bindcompfmx;svn;FireDACSqliteDriver;FireDACPgDriver;inetdb;CEF4Delphi;soaprtl;DbxCommonDriver;fmx;FireDACIBDriver;fmxdae;xmlrtl;soapmidas;fmxobj;vclwinx;rtl;DbxClientDriver;CustomIPTransport;vcldsnap;dbexpress;IndyCore;vclx;bindcomp;appanalytics;dsnap;FireDACCommon;IndyIPClient;bindcompvcl;RESTBackendComponents;EmbeddedWebBrowser_XE;VCLRESTComponents;soapserver;dbxcds;VclSmp;JvDocking;adortl;JclVcl;vclie;bindengine;DBXMySQLDriver;CloudService;dsnapxml;FireDACMySQLDriver;dbrtl;IndyProtocols;inetdbxpress;keyman_components;FireDACCommonODBC;FireDACCommonDriver;inet;fmxase;$(DCC_UsePackage) @@ -87,7 +88,6 @@ true 3 reset engine.compatibility.text_services_framework.notepad.exe 0 - true Keyman Config @@ -107,7 +107,6 @@ Keyman Config true true - true diff --git a/windows/src/desktop/kmshell/Makefile b/windows/src/desktop/kmshell/Makefile index 68f1a0dcd9..b54031d5bc 100644 --- a/windows/src/desktop/kmshell/Makefile +++ b/windows/src/desktop/kmshell/Makefile @@ -6,8 +6,8 @@ build: version.res manifest.res icons xml $(DCC32) kmshell.dpr - $(TDS2DBG) kmshell.exe $(SENTRYTOOL_DELPHIPREP) kmshell.exe -dpr kmshell.dpr + $(TDS2DBG) kmshell.exe $(COPY) kmshell.exe $(PROGRAM)\desktop if exist kmshell.dbg $(COPY) kmshell.dbg $(DEBUGPATH)\desktop @@ -34,6 +34,10 @@ clean: def-clean signcode: $(SIGNCODE) /d "Keyman Desktop" $(PROGRAM)\desktop\kmshell.exe +wrap-symbols: + $(SYMSTORE) $(PROGRAM)\desktop\kmshell.exe /t keyman-windows + $(SYMSTORE) $(DEBUGPATH)\desktop\kmshell.dbg /t keyman-windows + backup: $(WZZIP) $(BUILD)\desktop\kmshell.zip $(BACKUPDEFAULTS) kmshell.exe diff --git a/windows/src/desktop/setup/Makefile b/windows/src/desktop/setup/Makefile index f806aafa6e..c13be474c5 100644 --- a/windows/src/desktop/setup/Makefile +++ b/windows/src/desktop/setup/Makefile @@ -6,8 +6,8 @@ build: version.res manifest.res icons locale $(DCC32) setup.dpr - $(TDS2DBG) setup.exe $(SENTRYTOOL_DELPHIPREP) setup.exe -dpr setup.dpr + $(TDS2DBG) setup.exe $(COPY) setup.exe $(PROGRAM)\desktop locale: @@ -25,6 +25,10 @@ clean: def-clean signcode: rem SIGNCODE /d "Keyman Desktop Setup" $(PROGRAM)\desktop\setup.exe +wrap-symbols: + $(SYMSTORE) $(PROGRAM)\desktop\setup.exe /t keyman-windows + $(SYMSTORE) $(DEBUGPATH)\desktop\setup.dbg /t keyman-windows + backup: $(WZZIP) $(BUILD)\desktop\setup.zip $(BACKUPDEFAULTS) setup.exe diff --git a/windows/src/desktop/setup/setup.dproj b/windows/src/desktop/setup/setup.dproj index 5642c13af6..65996b9024 100644 --- a/windows/src/desktop/setup/setup.dproj +++ b/windows/src/desktop/setup/setup.dproj @@ -65,6 +65,7 @@ true true true + true setup_Icon.ico @@ -90,7 +91,6 @@ CompanyName=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName);FileDescription=$(MSBuildProjectName);ProductName=$(MSBuildProjectName) 1033 false - true diff --git a/windows/src/developer/TIKE/Makefile b/windows/src/developer/TIKE/Makefile index 2445702e51..d81baf7e22 100644 --- a/windows/src/developer/TIKE/Makefile +++ b/windows/src/developer/TIKE/Makefile @@ -7,8 +7,8 @@ build: version.res manifest.res icons dirs xml cd $(ROOT)\src\developer\tike $(DCC32) tike.dpr - $(TDS2DBG) tike.exe $(SENTRYTOOL_DELPHIPREP) tike.exe -dpr tike.dpr + $(TDS2DBG) tike.exe $(COPY) tike.exe $(PROGRAM)\developer $(COPY) kmlmc.cmd $(PROGRAM)\developer if exist tike.dbg $(COPY) tike.dbg $(DEBUGPATH)\developer @@ -72,6 +72,10 @@ clean: def-clean signcode: $(SIGNCODE) /d "Keyman Developer" $(PROGRAM)\developer\tike.exe +wrap-symbols: + $(SYMSTORE) $(PROGRAM)\developer\tike.exe /t keyman-developer + $(SYMSTORE) $(DEBUGPATH)\developer\tike.dbg /t keyman-developer + backup: $(WZZIP) $(BUILD)\developer\tike.zip $(BACKUPDEFAULTS) tike.exe diff --git a/windows/src/developer/TIKE/child/UfrmDebug.pas b/windows/src/developer/TIKE/child/UfrmDebug.pas index 22f22192f0..a93ef381b0 100644 --- a/windows/src/developer/TIKE/child/UfrmDebug.pas +++ b/windows/src/developer/TIKE/child/UfrmDebug.pas @@ -1171,8 +1171,7 @@ begin if FFont = nil then begin FDefaultFont := True; - //TODO:FFont := EditorMemo.AltFont; - FFont := Font; //TODO scrap this + FFont := EditorMemo.CharFont; end else FDefaultFont := False; diff --git a/windows/src/developer/TIKE/child/UfrmKeymanWizard.pas b/windows/src/developer/TIKE/child/UfrmKeymanWizard.pas index 57ce633e92..b0e6faac5c 100644 --- a/windows/src/developer/TIKE/child/UfrmKeymanWizard.pas +++ b/windows/src/developer/TIKE/child/UfrmKeymanWizard.pas @@ -2884,9 +2884,7 @@ begin FDebugForm.OnClearBreakpoint := DebugClearBreakpoint; FDebugForm.OnUpdateExecutionPoint := DebugUpdateExecutionPoint; FDebugForm.Visible := True; - - -// TODO: FDebugForm.EditorMemo := frameSource.memo; + FDebugForm.EditorMemo := frameSource; FDebugStatusForm := TfrmDebugStatus.Create(Self); FDebugStatusForm.BorderStyle := bsNone; diff --git a/windows/src/developer/TIKE/compile/CompileKeymanWeb.pas b/windows/src/developer/TIKE/compile/CompileKeymanWeb.pas index b66ecdf2a6..2b491e4ad0 100644 --- a/windows/src/developer/TIKE/compile/CompileKeymanWeb.pas +++ b/windows/src/developer/TIKE/compile/CompileKeymanWeb.pas @@ -1,18 +1,18 @@ (* Name: CompileKeymanWeb Copyright: Copyright (C) SIL International. - Documentation: - Description: + Documentation: + Description: Create Date: 26 Apr 2006 Modified Date: 24 Aug 2015 Authors: mcdurdin - Related Files: - Dependencies: + Related Files: + Dependencies: - Bugs: - Todo: - Notes: + Bugs: + Todo: + Notes: History: 26 Apr 2006 - mcdurdin - Add support for ContextEx and Context, and lots of polish 21 Jun 2006 - mcdurdin - Add embedded javascript output (for IMX support) 21 Jun 2006 - mcdurdin - Add semicolons as necessary to javascript @@ -89,10 +89,10 @@ 27 May 2015 - mcdurdin - I4724 - Compiler generates warnings for JSON files if output path is source path 24 Aug 2015 - mcdurdin - I4872 - OSK font and Touch Layout font should be the same in Developer 24 Aug 2015 - mcdurdin - I4866 - Add warn on deprecated features to project and compile - + 24 Aug 2015 - mcdurdin - I4865 - Add treat hints and warnings as errors into project 28 Feb 2018 - jahorton - GH 281 - Changed the compilation targets for KMW 10 to better support deadkeys. - + *) unit CompileKeymanWeb; // I3306 // I3310 @@ -218,6 +218,7 @@ type function JavaScript_String(ch: DWord): string; // I2242 function IsKeyboardVersion10OrLater: Boolean; + function IsKeyboardVersion14OrLater: Boolean; procedure ReportError(line: Integer; msgcode: LongWord; const text: string); // I1971 function ExpandSentinel(pwsz: PWideChar): TSentinelRecord; @@ -936,9 +937,17 @@ var end; CODE_DEADKEY: Result := Result + nlt + Format('k.KDO(%d,t,%d);', [len, recContext.Deadkey.Deadkey]); // I4611 + CODE_NOTANY: + begin + // #917: Minimum version required is 14.0: the KCXO function was only added for 14.0 + // Note that this is checked in compiler.cpp as well, so this error can probably never occur + if not IsKeyboardVersion14OrLater then + ReportError(fkp.Line, CERR_NotSupportedInKeymanWebContext, Format('Statement notany in context() match requires version 14.0+ of KeymanWeb', [GetCodeName(recContext.Code)])); // I1971 // I4061 + Result := Result + nlt + Format('k.KCXO(%d,t,%d,%d);', [len, AdjustIndex(fkp.dpContext, xstrlen(fkp.dpContext)), AdjustIndex(fkp.dpContext, ContextIndex)]); + end; else begin - ReportError(fkp.Line, CERR_NotSupportedInKeymanWebContext, Format('Statement %s is not currently supported in CODE_CONTEXT match', [GetCodeName(recContext.Code)])); // I1971 // I4061 + ReportError(fkp.Line, CERR_NotSupportedInKeymanWebContext, Format('Statement %s is not currently supported in context() match', [GetCodeName(recContext.Code)])); // I1971 // I4061 //CODE_NUL: ; // todo: check if context is longer than that... Result := Result + nlt + '/*.*/ '; // I4611 end; @@ -2174,6 +2183,11 @@ begin Result := fk.version >= VERSION_100; end; +function TCompileKeymanWeb.IsKeyboardVersion14OrLater: Boolean; +begin + Result := fk.version >= VERSION_140; +end; + procedure TCompileKeymanWeb.CheckStoreForInvalidFunctions(key: PFILE_KEY; store: PFILE_STORE); // I1520 var n: Integer; diff --git a/windows/src/developer/inst/Makefile b/windows/src/developer/inst/Makefile index 4b4a84dcca..3357750dd9 100644 --- a/windows/src/developer/inst/Makefile +++ b/windows/src/developer/inst/Makefile @@ -47,6 +47,9 @@ signcode: backup: @rem +wrap-symbols: + @rem + clean: cd $(ROOT)\src\developer\inst -del /Q download.mak diff --git a/windows/src/developer/kmanalyze/Makefile b/windows/src/developer/kmanalyze/Makefile index 1e8f6e2870..3cc017abd7 100644 --- a/windows/src/developer/kmanalyze/Makefile +++ b/windows/src/developer/kmanalyze/Makefile @@ -7,6 +7,7 @@ build: version.res dirs $(MSBUILD) kmanalyze.sln $(MSBUILD_BUILD) $(COPY) $(TARGET_PATH)\kmanalyze.exe $(PROGRAM)\developer + $(COPY) $(TARGET_PATH)\kmanalyze.pdb $(DEBUGPATH)\developer clean: def-clean $(MSBUILD) kmanalyze.sln $(MSBUILD_CLEAN) @@ -14,13 +15,17 @@ clean: def-clean signcode: $(SIGNCODE) /d "Keyman Developer Keyboard Analyzer" $(PROGRAM)\developer\kmanalyze.exe +wrap-symbols: + $(SYMSTORE) $(PROGRAM)\developer\kmanalyze.exe /t keyman-developer + $(SYMSTORE) $(DEBUGPATH)\developer\kmanalyze.pdb /t keyman-developer + backup: $(WZZIP) $(BUILD)\developer\kmanalyze.exe $(BACKUPDEFAULTS) kmanalyze.exe test-manifest: - @rem + @rem #install: # $(COPY) $(PROGRAM)\developer\kmanalyze.exe "$(INSTALLPATH_KEYMANDEVELOPER)\kmanalyze.exe" - + !include ..\..\Target.mak diff --git a/windows/src/developer/kmcmpdll/Compiler.cpp b/windows/src/developer/kmcmpdll/Compiler.cpp index 4eb236deaf..de4a0368b3 100644 --- a/windows/src/developer/kmcmpdll/Compiler.cpp +++ b/windows/src/developer/kmcmpdll/Compiler.cpp @@ -1287,6 +1287,7 @@ DWORD ProcessSystemStore(PFILE_KEYBOARD fk, DWORD SystemID, PFILE_STORE sp) else if (wcsncmp(p, L"8.0", 3) == 0) fk->version = VERSION_80; else if (wcsncmp(p, L"9.0", 3) == 0) fk->version = VERSION_90; else if (wcsncmp(p, L"10.0", 4) == 0) fk->version = VERSION_100; + else if (wcsncmp(p, L"14.0", 4) == 0) fk->version = VERSION_140; // Adds support for #917 -- context() with notany() for KeymanWeb else return CERR_InvalidVersion; if (fk->version < VERSION_60) FOldCharPosMatching = TRUE; @@ -1488,6 +1489,15 @@ DWORD CheckStatementOffsets(PFILE_KEYBOARD fk, PFILE_GROUP gp, PWSTR context, PW int contextOffset = *(p + 2); if (contextOffset > xstrlen(context)) return CERR_ContextExHasInvalidOffset; + + // Due to a limitation in earlier versions of KeymanWeb, the minimum version + // for context() referring to notany() is 14.0. See #917 for details. + if (CompileTarget == CKF_KEYMANWEB) { + for (q = context, i = 1; *q && i < contextOffset; q = incxstr(q), i++); + if (*q == UC_SENTINEL && *(q + 1) == CODE_NOTANY) { + VERIFY_KEYBOARD_VERSION(fk, VERSION_140, CERR_140FeatureOnlyContextAndNotAnyWeb); + } + } } } } diff --git a/windows/src/developer/kmcmpdll/Compiler.rc b/windows/src/developer/kmcmpdll/Compiler.rc index 888c924bac..a7c1fa2275 100644 --- a/windows/src/developer/kmcmpdll/Compiler.rc +++ b/windows/src/developer/kmcmpdll/Compiler.rc @@ -203,6 +203,7 @@ BEGIN CERR_90FeatureOnlyEmbedCSS "Embedding CSS requires store(&version) '9.0'" CERR_90FeatureOnlyTargets "&TARGETS system store requires store(&version) '9.0'" CERR_ContextAndIndexInvalidInMatchNomatch "context and index statements cannot be used in a match or nomatch statement" + CERR_140FeatureOnlyContextAndNotAnyWeb "For web and touch platforms, context() statement referring to notany() requires store(&version) '14.0'" CWARN_PlatformNotInTargets "The specified platform is not a target platform" END diff --git a/windows/src/developer/kmcmpdll/Makefile b/windows/src/developer/kmcmpdll/Makefile index e6ccbf316b..7723fa74d1 100644 --- a/windows/src/developer/kmcmpdll/Makefile +++ b/windows/src/developer/kmcmpdll/Makefile @@ -16,14 +16,14 @@ build: version.res dirs $(COPY) $(WIN32_TARGET_PATH)\kmcmpdll.dll ..\tike\kmcmpdll.dll -mkdir ..\kmcomp\$(WIN32_TARGET_PATH) $(COPY) $(WIN32_TARGET_PATH)\kmcmpdll.dll ..\kmcomp\$(WIN32_TARGET_PATH)\kmcmpdll.dll - + $(MSBUILD) kmcmpdll.sln $(MSBUILD_BUILD) /p:Platform=x64 $(COPY) $(X64_TARGET_PATH)\kmcmpdll.x64.dll $(PROGRAM)\developer\kmcmpdll.x64.dll $(COPY) $(X64_TARGET_PATH)\kmcmpdll.x64.lib $(OUTLIB)\kmcmpdll.x64.lib $(COPY) $(X64_TARGET_PATH)\kmcmpdll.x64.pdb $(DEBUGPATH)\developer\kmcmpdll.x64.pdb -mkdir ..\kmcomp\$(WIN64_TARGET_PATH) $(COPY) $(X64_TARGET_PATH)\kmcmpdll.x64.dll ..\kmcomp\$(WIN64_TARGET_PATH)\kmcmpdll.x64.dll - + clean: def-clean $(MSBUILD) kmcmpdll.sln $(MSBUILD_CLEAN) @@ -32,14 +32,20 @@ signcode: $(SIGNCODE) /d "Keyman Developer Compiler" $(PROGRAM)\developer\kmcmpdll.dll $(SIGNCODE) /d "Keyman Developer Compiler" $(PROGRAM)\developer\kmcmpdll.x64.dll +wrap-symbols: + $(SYMSTORE) $(PROGRAM)\developer\kmcmpdll.dll /t keyman-developer + $(SYMSTORE) $(PROGRAM)\developer\kmcmpdll.x64.dll /t keyman-developer + $(SYMSTORE) $(DEBUGPATH)\developer\kmcmpdll.pdb /t keyman-developer + $(SYMSTORE) $(DEBUGPATH)\developer\kmcmpdll.x64.pdb /t keyman-developer + backup: $(WZZIP) $(BUILD)\developer\kmcmpdll.zip $(BACKUPDEFAULTS) $(PROGRAM)\developer\kmcmpdll.dll $(PROGRAM)\developer\kmcmpdll.x64.dll - + test-manifest: @rem This target needed as dependency for TIKE and KMCMPDLL install: $(COPY) $(PROGRAM)\developer\kmcmpdll.dll "$(INSTALLPATH_KEYMANDEVELOPER)\kmcmpdll.dll" $(COPY) $(PROGRAM)\developer\kmcmpdll.x64.dll "$(INSTALLPATH_KEYMANDEVELOPER)\kmcmpdll.x64.dll" - + !include ..\..\Target.mak diff --git a/windows/src/developer/kmcomp/Makefile b/windows/src/developer/kmcomp/Makefile index 4e89f10397..059810af2c 100644 --- a/windows/src/developer/kmcomp/Makefile +++ b/windows/src/developer/kmcomp/Makefile @@ -11,8 +11,8 @@ TARGET_GROUP=developer build: version.res manifest.res dirs icons $(DELPHI_MSBUILD) kmcomp.dproj /p:Platform=Win32 - $(TDS2DBG) $(WIN32_TARGET_PATH)\kmcomp.exe $(SENTRYTOOL_DELPHIPREP) $(WIN32_TARGET_PATH)\kmcomp.exe -dpr kmcomp.dpr + $(TDS2DBG) $(WIN32_TARGET_PATH)\kmcomp.exe $(COPY) $(WIN32_TARGET_PATH)\kmcomp.exe $(PROGRAM)\developer if exist $(WIN32_TARGET_PATH)\kmcomp.dbg $(COPY) $(WIN32_TARGET_PATH)\kmcomp.dbg $(DEBUGPATH)\developer @@ -25,7 +25,7 @@ build: version.res manifest.res dirs icons if exist $(WIN64_TARGET_PATH)\kmcomp.x64.map del $(WIN64_TARGET_PATH)\kmcomp.x64.map ren $(WIN64_TARGET_PATH)\kmcomp.map kmcomp.x64.map - $(SENTRYTOOL_DELPHIPREP) $(WIN64_TARGET_PATH)\kmcomp.x64.exe -dpr kmcomp.dpr + # $(SENTRYTOOL_DELPHIPREP) $(WIN64_TARGET_PATH)\kmcomp.x64.exe -dpr kmcomp.dpr $(COPY) $(WIN64_TARGET_PATH)\kmcomp.x64.exe $(PROGRAM)\developer\kmcomp.x64.exe if exist $(WIN64_TARGET_PATH)\kmcomp.dbg $(COPY) $(WIN64_TARGET_PATH)\kmcomp.dbg $(DEBUGPATH)\developer\kmcomp.x64.dbg @@ -39,6 +39,12 @@ signcode: $(SIGNCODE) /d "Keyman Developer Command-Line Compiler" $(PROGRAM)\developer\kmcomp.exe $(SIGNCODE) /d "Keyman Developer Command-Line Compiler" $(PROGRAM)\developer\kmcomp.x64.exe +wrap-symbols: + $(SYMSTORE) $(PROGRAM)\developer\kmcomp.exe /t keyman-developer + $(SYMSTORE) $(PROGRAM)\developer\kmcomp.x64.exe /t keyman-developer + $(SYMSTORE) $(DEBUGPATH)\developer\kmcomp.dbg /t keyman-developer + #TODO: $(SYMSTORE) $(DEBUGPATH)\developer\kmcomp.x64.dbg /t keyman-developer + backup: $(WZZIP) $(BUILD)\developer\kmcomp.zip $(BACKUPDEFAULTS) $(PROGRAM)\developer\kmcomp.exe $(PROGRAM)\developer\kmcomp.x64.exe diff --git a/windows/src/developer/kmconvert/Keyman.Developer.System.ImportKeyboardDLL.pas b/windows/src/developer/kmconvert/Keyman.Developer.System.ImportKeyboardDLL.pas index bdcf888e4a..8947265f18 100644 --- a/windows/src/developer/kmconvert/Keyman.Developer.System.ImportKeyboardDLL.pas +++ b/windows/src/developer/kmconvert/Keyman.Developer.System.ImportKeyboardDLL.pas @@ -137,6 +137,7 @@ type FKeyStateNull: TKeyboardState; FXxxxVk: UINT; + FHas102ndKey: Boolean; function GetMaxShiftState: TKBDShiftState; function ProcessDeadKey( iKeyDead: UINT; // The index into the VirtualKey of the dead key @@ -148,6 +149,7 @@ type procedure ScanKeyboard(hkl: HKL); function WriteOutputKMNFile: string; function WriteOutputKVKSFile: string; + procedure Detect102ndKey(hkl: HKL); public constructor Create(inputHKL, layoutFile, layoutText: string); destructor Destroy; override; @@ -463,8 +465,13 @@ begin else if FRGFDeadKey[ss, False] then begin // It's a dead key + // This does not match the "Fill from layout" result because deadkeys are + // left blank in "Fill from layout". However, this is better because it + // matches the actual Windows layout. "Fill from layout" cannot deduce the + // character to put onto a deadkey currently (unlike Windows deadkeys, + // there is no isolated "default" for a Keyman deadkey). vkk := TVisualKeyboardKey.Create; - vkk.VKey := FVK; + vkk.VKey := MapScanCodeToUSVK(FSC); vkk.Text := st[1]; vkk.Flags := [kvkkUnicode]; vkk.Shift := KBDShiftStateToVisualKeyboardShiftState[ss]; @@ -486,7 +493,7 @@ begin begin // It's some characters; put 'em in there. vkk := TVisualKeyboardKey.Create; - vkk.VKey := FVK; + vkk.VKey := MapScanCodeToUSVK(FSC); vkk.Text := st; vkk.Flags := [kvkkUnicode]; vkk.Shift := KBDShiftStateToVisualKeyboardShiftState[ss]; @@ -788,6 +795,22 @@ begin end; end; end; + + Detect102ndKey(hkl); +end; + +// duplicate of TOnScreenKeyboard.UpdateEuroLayout +procedure TLoader.Detect102ndKey(hkl: HKL); +var + k102, kbackslash: UINT; +begin + k102 := MapVirtualKeyExW($56, 1, hkl); + kbackslash := MapVirtualKeyExW($2b, 1, hkl); + + if k102 <> 0 then k102 := MapVirtualKeyExW(k102, 2, hkl); + if kbackslash <> 0 then kbackslash := MapVirtualKeyExW(kbackslash, 2, hkl); + + FHas102ndKey := (kbackslash <> k102) and (k102 <> 0); end; procedure TLoader.Main(var KMN, KVKS: string); @@ -915,6 +938,9 @@ begin end; end; + if FHas102ndKey then + vk.Header.Flags := vk.Header.Flags + [kvkh102]; + vk.SaveToStream(ss, kvksfXML); Result := ss.DataString; diff --git a/windows/src/developer/kmconvert/Makefile b/windows/src/developer/kmconvert/Makefile index 81df38b61a..7b85027076 100644 --- a/windows/src/developer/kmconvert/Makefile +++ b/windows/src/developer/kmconvert/Makefile @@ -7,8 +7,8 @@ build: version.res manifest.res dirs icons $(DELPHI_MSBUILD) kmconvert.dproj /p:Platform=Win32 - $(TDS2DBG) $(WIN32_TARGET_PATH)\kmconvert.exe $(SENTRYTOOL_DELPHIPREP) $(WIN32_TARGET_PATH)\kmconvert.exe -dpr kmconvert.dpr + $(TDS2DBG) $(WIN32_TARGET_PATH)\kmconvert.exe $(COPY) $(WIN32_TARGET_PATH)\kmconvert.exe $(PROGRAM)\developer if exist $(WIN32_TARGET_PATH)\kmconvert.dbg $(COPY) $(WIN32_TARGET_PATH)\kmconvert.dbg $(DEBUGPATH)\developer @@ -21,6 +21,10 @@ clean: def-clean signcode: $(SIGNCODE) /d "Keyman Developer Conversion Utility" $(PROGRAM)\developer\kmconvert.exe +wrap-symbols: + $(SYMSTORE) $(PROGRAM)\developer\kmconvert.exe /t keyman-developer + $(SYMSTORE) $(DEBUGPATH)\developer\kmconvert.dbg /t keyman-developer + backup: $(WZZIP) $(BUILD)\developer\kmconvert.zip $(BACKUPDEFAULTS) kmconvert.exe diff --git a/windows/src/developer/kmconvert/kmconvert.dproj b/windows/src/developer/kmconvert/kmconvert.dproj index d8d6e78413..24eaddcf75 100644 --- a/windows/src/developer/kmconvert/kmconvert.dproj +++ b/windows/src/developer/kmconvert/kmconvert.dproj @@ -56,6 +56,7 @@ RESTComponents;FireDAC;FireDACSqliteDriver;soaprtl;FireDACIBDriver;soapmidas;FireDACCommon;RESTBackendComponents;soapserver;CloudService;FireDACCommonDriver;inet;$(DCC_UsePackage) System;Xml;Data;Datasnap;Web;Soap;Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;$(DCC_Namespace) kmconvert + true DBXSqliteDriver;bindcompdbx;IndyIPCommon;DBXInterBaseDriver;vcl;IndyIPServer;vclactnband;vclFireDAC;IndySystem;tethering;svnui;mbColorLibD10;dsnapcon;FireDACADSDriver;scFontCombo;DCPdelphi2009;FireDACMSAccDriver;fmxFireDAC;vclimg;Jcl;vcltouch;JvCore;vcldb;bindcompfmx;svn;FireDACPgDriver;inetdb;CEF4Delphi;DbxCommonDriver;fmx;fmxdae;xmlrtl;fmxobj;vclwinx;rtl;DbxClientDriver;CustomIPTransport;vcldsnap;dbexpress;IndyCore;vclx;bindcomp;appanalytics;dsnap;IndyIPClient;bindcompvcl;EmbeddedWebBrowser_XE;VCLRESTComponents;dbxcds;VclSmp;JvDocking;adortl;JclVcl;vclie;bindengine;DBXMySQLDriver;dsnapxml;FireDACMySQLDriver;dbrtl;inetdbxpress;IndyProtocols;keyman_components;FireDACCommonODBC;fmxase;$(DCC_UsePackage) @@ -66,7 +67,6 @@ true $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png - true (None) diff --git a/windows/src/developer/kmdecomp/Makefile b/windows/src/developer/kmdecomp/Makefile index 4fa5b3ef8e..7bf26de79c 100644 --- a/windows/src/developer/kmdecomp/Makefile +++ b/windows/src/developer/kmdecomp/Makefile @@ -16,13 +16,17 @@ clean: def-clean signcode: $(SIGNCODE) /d "Keyman Developer Decompiler" $(PROGRAM)\developer\kmdecomp.exe +wrap-symbols: + $(SYMSTORE) $(PROGRAM)\developer\kmdecomp.exe /t keyman-developer + $(SYMSTORE) $(DEBUGPATH)\developer\kmdecomp.pdb /t keyman-developer + backup: - $(WZZIP) $(BUILD)\developer\kmdecomp.zip $(BACKUPDEFAULTS) $(PROGRAM)\developer\kmdecomp.exe - + $(WZZIP) $(BUILD)\developer\kmdecomp.zip $(BACKUPDEFAULTS) $(PROGRAM)\developer\kmdecomp.exe + test-manifest: @rem This target needed as dependency for KMDECOMP install: $(COPY) $(PROGRAM)\developer\kmdecomp.exe "$(INSTALLPATH_KEYMANDEVELOPER)\kmdecomp.exe" - + !include ..\..\Target.mak diff --git a/windows/src/developer/samples/imsample/Makefile b/windows/src/developer/samples/imsample/Makefile index adcc8736db..07853d41f4 100644 --- a/windows/src/developer/samples/imsample/Makefile +++ b/windows/src/developer/samples/imsample/Makefile @@ -9,10 +9,15 @@ VERSION_TXT_PATH=..\.. build: dirs version.res $(MSBUILD) imsample.sln $(MSBUILD_BUILD) $(COPY) imsample.dll $(PROGRAM)\developer + $(COPY) imsample.pdb $(PROGRAM)\developer signcode: $(SIGNCODE) /d "Keyman IMX Sample" $(PROGRAM)\developer\imsample.dll +wrap-symbols: + $(SYMSTORE) $(PROGRAM)\developer\imsample.dll /t keyman-developer + $(SYMSTORE) $(DEBUGPATH)\developer\imsample.pdb /t keyman-developer + backup: $(WZZIP) $(BUILD)\developer\imsample.zip $(BACKUPDEFAULTS) imsample.dll diff --git a/windows/src/developer/setup/Makefile b/windows/src/developer/setup/Makefile index 4d1f563a6a..8aa0767d51 100644 --- a/windows/src/developer/setup/Makefile +++ b/windows/src/developer/setup/Makefile @@ -6,8 +6,8 @@ build: version.res manifest.res icons $(DCC32) setup.dpr - $(TDS2DBG) setup.exe $(SENTRYTOOL_DELPHIPREP) setup.exe -dpr setup.dpr + $(TDS2DBG) setup.exe $(COPY) setup.exe $(PROGRAM)\developer if exist setup.dbg $(COPY) setup.dbg $(DEBUGPATH)\developer\devsetup.dbg -del devsetup.dbg @@ -25,6 +25,13 @@ clean: def-clean signcode: rem SIGNCODE /d "Keyman Developer Setup" $(PROGRAM)\developer\setup.exe +wrap-symbols: + # This is slightly non-standard due to renamed devsetup.dbg above + # we should be able to clean this up in the future when we remove the + # zipped debug symbols + $(SYMSTORE) $(PROGRAM)\developer\setup.exe /t keyman-developer + $(SYMSTORE) $(ROOT)\src\developer\setup\setup.dbg /t keyman-developer + backup: $(WZZIP) $(BUILD)\developer\devsetup.zip $(BACKUPDEFAULTS) setup.exe diff --git a/windows/src/developer/setup/SetupStrings.pas b/windows/src/developer/setup/SetupStrings.pas index b5a4d65ec3..9d74219127 100644 --- a/windows/src/developer/setup/SetupStrings.pas +++ b/windows/src/developer/setup/SetupStrings.pas @@ -41,25 +41,16 @@ type ssErrorUnableToContactServer, ssErrorUnableToContactServerDetailed, - ssStatusCheckingWindowsInstaller, - ssStatusCheckingInternetExplorer, - ssStatusCheckingMSXML, ssStatusCheckingForUpdates, ssStatusInstalling, ssStatusComplete, - ssQueryUpdateWindowsInstaller, - ssQueryUpdateInternetExplorer, - ssQueryUpdateMSXML, - ssQueryUpdateVersion, ssQueryRestart, ssErrorUnableToAutomaticallyRestart, - ssRedistIEUpdateRequired, ssMustRestart, - ssRedistRequired, ssCheckForUpdatesError ); @@ -80,29 +71,18 @@ const 'Unable to contact server', 'Unable to contact server, error was: %0:s', - 'Checking Windows Installer version', - 'Checking Internet Explorer version', - 'Checking MSXML version', 'Checking for updates online', 'Installing Keyman Developer', 'Installation Complete', - 'An updated version of Windows Installer is required to install Keyman Developer. Do you want to download and install it now?', - 'Internet Explorer 5.5 or later is required to install Keyman Developer. Do you want to download it now?', - 'MSXML 3.0 is required to install Keyman Developer. Do you want to download it now?', - 'Version %1:s of Keyman Developer has been released and is available for download. This update is %0:dKB. '+ 'Do you want to download and install the updated version (recommended)?', 'You must restart Windows before Setup can complete. When you restart Windows, Setup will continue. Restart now?', 'Windows was not able to be automatically restarted. You should restart Windows before you try and start Keyman Developer.', - 'Internet Explorer 5.5 or later is required to install Keyman Developer.', - 'You must restart Windows to complete Setup. When you restart Windows, Setup will finish.', - 'A redistributable %0:s is required but is not available in the install path. This redistributable can be downloaded from the Keyman website.', - 'The online update check failed with an error: %0:s' ); diff --git a/windows/src/developer/setup/UfrmRun.pas b/windows/src/developer/setup/UfrmRun.pas index 504bf161fd..548f096b31 100644 --- a/windows/src/developer/setup/UfrmRun.pas +++ b/windows/src/developer/setup/UfrmRun.pas @@ -90,7 +90,6 @@ type procedure CheckNewVersion; function InstallMSI: Boolean; procedure Status(const Text: WideString = ''); - function CheckDependencies: Boolean; procedure DownloadRedistFile(AOwner: TfrmDownloadProgress; var Result: Boolean); function InstallNewVersion: Boolean; function IsNewerVersionInstalled(const NewVersion: WideString): Boolean; @@ -223,36 +222,6 @@ begin Result := (FInstalledVersion.Version <> '') and (CompareVersions(NewVersion, FInstalledVersion.Version) >= 0); end; -function TfrmRun.CheckDependencies: Boolean; -const - SInternetExplorerHome = 'https://www.microsoft.com/ie/'; -begin - Result := False; - - // Check Internet Explorer version - Status(FInstallInfo.Text(ssStatusCheckingInternetExplorer)); - with TRegistryErrorControlled.Create do // I2890 - try - RootKey := HKEY_LOCAL_MACHINE; - if not OpenKeyReadOnly('Software\Microsoft\Internet Explorer') or not ValueExists('Version') or - (CompareVersions(ReadString('Version'), '9.0') > 0) then - begin - if FSilent or (MessageDlgW(FInstallInfo.Text(ssQueryUpdateInternetExplorer), - mtConfirmation, mbOkCancel, 0) = mrCancel) then - begin - LogError(FInstallInfo.Text(ssRedistIEUpdateRequired), False); - Exit; - end; - TUtilExecute.URL(SInternetExplorerHome); - Exit; - end; - finally - Free; - end; - - Result := True; -end; - function TfrmRun.InstallNewVersion: Boolean; begin Result := False; @@ -423,8 +392,6 @@ end; function TfrmRun.DoInstall(Silent, PromptForReboot: Boolean): Boolean; // I1901 // I3355 // I3500 begin - Result := False; // I1901 - FPromptForReboot := PromptForReboot; // I3355 // I3500 FSilent := Silent; @@ -439,8 +406,6 @@ begin StatusMax := 6; - if not CheckDependencies then Exit; - SetupMSI; CheckInstalledVersion; diff --git a/windows/src/engine/inst/Makefile b/windows/src/engine/inst/Makefile index 434d7e5640..72bf68b4ab 100644 --- a/windows/src/engine/inst/Makefile +++ b/windows/src/engine/inst/Makefile @@ -22,6 +22,10 @@ backup: cd $(ROOT)\src\engine\inst\insthelper $(MAKE) backup +wrap-symbols: + cd $(ROOT)\src\engine\inst\insthelper + $(MAKE) symbols + msm: # # Copy files for installation diff --git a/windows/src/engine/inst/insthelper/Makefile b/windows/src/engine/inst/insthelper/Makefile index ee9ae9ed9c..59443cab32 100644 --- a/windows/src/engine/inst/insthelper/Makefile +++ b/windows/src/engine/inst/insthelper/Makefile @@ -8,9 +8,10 @@ VERSION_TXT_PATH=..\.. build: dirs version.res $(DCC32) insthelper.dpr - $(TDS2DBG) insthelper.dll $(SENTRYTOOL_DELPHIPREP) insthelper.dll -dpr insthelper.dpr + $(TDS2DBG) insthelper.dll $(COPY) insthelper.dll $(PROGRAM)\inst + $(COPY) insthelper.dbg $(DEBUGPATH)\inst clean: def-clean -del *.dll @@ -18,6 +19,10 @@ clean: def-clean signcode: $(SIGNCODE) /d "Keyman Engine Install Helper" $(PROGRAM)\inst\insthelper.dll +wrap-symbols: + $(SYMSTORE) $(PROGRAM)\inst\insthelper.dll /t keyman-windows + $(SYMSTORE) $(DEBUGPATH)\inst\insthelper.dbg /t keyman-windows + backup: $(WZZIP) $(BUILD)\inst\insthelper.zip $(BACKUPDEFAULTS) insthelper.dll diff --git a/windows/src/engine/keyman/Makefile b/windows/src/engine/keyman/Makefile index 5e69bdbb72..0c0b3c8f90 100644 --- a/windows/src/engine/keyman/Makefile +++ b/windows/src/engine/keyman/Makefile @@ -7,8 +7,8 @@ build: version.res manifest.res keymanmenuitem.res icons.res osktoolbar.res dirs rc langswitch\langswitchmanager.rc $(DCC32) keyman.dpr - $(TDS2DBG) keyman.exe $(SENTRYTOOL_DELPHIPREP) keyman.exe -dpr keyman.dpr + $(TDS2DBG) keyman.exe $(COPY) keyman.exe $(PROGRAM)\engine if exist keyman.dbg $(COPY) keyman.dbg $(DEBUGPATH)\engine @@ -17,6 +17,10 @@ clean: def-clean signcode: $(SIGNCODE) /d "Keyman Engine" $(PROGRAM)\engine\keyman.exe +wrap-symbols: + $(SYMSTORE) $(PROGRAM)\engine\keyman.dll /t keyman-engine-windows + $(SYMSTORE) $(DEBUGPATH)\engine\keyman.dbg /t keyman-engine-windows + backup: $(WZZIP) $(BUILD)\engine\keyman.zip $(BACKUPDEFAULTS) keyman.exe diff --git a/windows/src/engine/keyman32/Makefile b/windows/src/engine/keyman32/Makefile index b7ecb8b996..b57852a6cb 100644 --- a/windows/src/engine/keyman32/Makefile +++ b/windows/src/engine/keyman32/Makefile @@ -21,6 +21,10 @@ clean: def-clean signcode: $(SIGNCODE) /d "Keyman Engine" $(PROGRAM)\engine\keyman32.dll +wrap-symbols: + $(SYMSTORE) $(PROGRAM)\engine\keyman32.dll /t keyman-engine-windows + $(SYMSTORE) $(DEBUGPATH)\engine\keyman32.pdb /t keyman-engine-windows + backup: $(WZZIP) $(BUILD)\engine\keyman32.zip $(BACKUPDEFAULTS) keyman32.dll diff --git a/windows/src/engine/keyman64/Makefile b/windows/src/engine/keyman64/Makefile index 5597da5dbf..2547cf2d48 100644 --- a/windows/src/engine/keyman64/Makefile +++ b/windows/src/engine/keyman64/Makefile @@ -21,6 +21,10 @@ clean: def-clean signcode: $(SIGNCODE) /d "Keyman Engine x64" $(PROGRAM)\engine\keyman64.dll +wrap-symbols: + $(SYMSTORE) $(PROGRAM)\engine\keyman64.dll /t keyman-engine-windows + $(SYMSTORE) $(DEBUGPATH)\engine\keyman64.pdb /t keyman-engine-windows + backup: $(WZZIP) $(BUILD)\engine\keyman64.zip $(BACKUPDEFAULTS) keyman64.dll diff --git a/windows/src/engine/keymanmc/Makefile b/windows/src/engine/keymanmc/Makefile index 558b80a018..57b35df8ce 100644 --- a/windows/src/engine/keymanmc/Makefile +++ b/windows/src/engine/keymanmc/Makefile @@ -4,7 +4,7 @@ !include ..\..\Defines.mak -build: +build: mc -U keymanmc.mc rc keymanmc.rc link -dll -noentry keymanmc.res @@ -20,6 +20,9 @@ clean: def-clean signcode: $(SIGNCODE) /d "Keyman Engine" $(PROGRAM)\engine\keymanmc.dll +wrap-symbols: + rem no symbols + backup: $(WZZIP) $(BUILD)\engine\keymanmc.zip $(BACKUPDEFAULTS) keymanmc.dll diff --git a/windows/src/engine/keymanx64/Makefile b/windows/src/engine/keymanx64/Makefile index a322efee73..ca108c1a9f 100644 --- a/windows/src/engine/keymanx64/Makefile +++ b/windows/src/engine/keymanx64/Makefile @@ -22,6 +22,10 @@ clean: def-clean signcode: $(SIGNCODE) /d "Keyman Engine x64" $(PROGRAM)\engine\keymanx64.exe +wrap-symbols: + $(SYMSTORE) $(PROGRAM)\engine\keymanx64.exe /t keyman-engine-windows + $(SYMSTORE) $(DEBUGPATH)\engine\keymanx64.pdb /t keyman-engine-windows + backup: $(WZZIP) $(BUILD)\engine\keymanx64.exe $(BACKUPDEFAULTS) keymanx64.exe diff --git a/windows/src/engine/kmcomapi/Makefile b/windows/src/engine/kmcomapi/Makefile index 3885fed722..d39b830626 100644 --- a/windows/src/engine/kmcomapi/Makefile +++ b/windows/src/engine/kmcomapi/Makefile @@ -8,8 +8,8 @@ build: version.res manifest.res kbd_noicon.res dirs gentlb -Tkmcomapi.tlb kmcomapi.ridl $(DELPHI_MSBUILD) kmcomapi.dproj /p:Platform=Win32 - $(TDS2DBG) $(WIN32_TARGET_PATH)\kmcomapi.dll $(SENTRYTOOL_DELPHIPREP) $(WIN32_TARGET_PATH)\kmcomapi.dll -dpr kmcomapi.dpr + $(TDS2DBG) $(WIN32_TARGET_PATH)\kmcomapi.dll $(COPY) $(WIN32_TARGET_PATH)\kmcomapi.dll $(PROGRAM)\engine if exist $(WIN32_TARGET_PATH)\kmcomapi.dbg $(COPY) $(WIN32_TARGET_PATH)\kmcomapi.dbg $(DEBUGPATH)\engine @@ -44,6 +44,12 @@ install: $(COPY) $(PROGRAM)\engine\kmcomapi.x64.dll "$(INSTALLPATH_KEYMANENGINE)" cmd /c regsvr32 /s "$(INSTALLPATH_KEYMANENGINE)\kmcomapi.x64.dll" +wrap-symbols: + $(SYMSTORE) $(PROGRAM)\engine\kmcomapi.dll /t keyman-engine-windows + $(SYMSTORE) $(PROGRAM)\engine\kmcomapi.x64.dll /t keyman-engine-windows + $(SYMSTORE) $(DEBUGPATH)\engine\kmcomapi.dbg /t keyman-engine-windows + #TODO: $(SYMSTORE) $(PROGRAM)\engine\kmcomapi.x64.dbg /t keyman-engine-windows + backup: $(WZZIP) $(BUILD)\engine\kmcomapi.zip $(BACKUPDEFAULTS) $(WIN32_TARGET_PATH)\kmcomapi.dll $(WIN64_TARGET_PATH)\kmcomapi.x64.dll $(WIN32_TARGET_PATH)\kmcomapi.dbg diff --git a/windows/src/engine/kmcomapi/kmcomapi.dproj b/windows/src/engine/kmcomapi/kmcomapi.dproj index 1fead9b31b..8a8af8820a 100644 --- a/windows/src/engine/kmcomapi/kmcomapi.dproj +++ b/windows/src/engine/kmcomapi/kmcomapi.dproj @@ -84,7 +84,6 @@ vclie50;Vcl50;Inetdb50;Inet50;Vcldb50;Vclx50;Vclbde50;proide50;keyman_components;$(DCC_UsePackage) 1033 C:\keyman\7.0\src\keyman\kmshell\startup\;$(DebugSourcePath) - true .\$(Platform)\$(Config) .\$(Platform)\$(Config) true @@ -137,6 +136,7 @@ CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments= C:\Projects\keyman\open\windows\src\test\test-kmcomapi-win64\Win64\Debug\kmcomapi_win64_host.exe -r:Keyman.Test.Console.KeymanAPIHost.TKeymanAPITest.Test_IKeymanPackageInstalled,Keyman.Test.Console.KeymanAPIHost.TKeymanAPITest.Test_IKeymanPackageFile + true diff --git a/windows/src/engine/kmtip/Makefile b/windows/src/engine/kmtip/Makefile index 001e074dfc..e4795a185e 100644 --- a/windows/src/engine/kmtip/Makefile +++ b/windows/src/engine/kmtip/Makefile @@ -20,6 +20,12 @@ signcode: $(SIGNCODE) /d "Keyman Engine Text Service" $(PROGRAM)\engine\kmtip.dll $(SIGNCODE) /d "Keyman Engine Text Service" $(PROGRAM)\engine\kmtip64.dll +wrap-symbols: + $(SYMSTORE) $(PROGRAM)\engine\kmtip.dll /t keyman-engine-windows + $(SYMSTORE) $(PROGRAM)\engine\kmtip64.dll /t keyman-engine-windows + $(SYMSTORE) $(DEBUGPATH)\engine\kmtip.pdb /t keyman-engine-windows + $(SYMSTORE) $(DEBUGPATH)\engine\kmtip64.pdb /t keyman-engine-windows + backup: $(WZZIP) $(BUILD)\engine\kmtip.zip x86\kmtip.pdb $(BACKUPDEFAULTS) x86\kmtip.dll $(WZZIP) $(BUILD)\engine\kmtip64.zip x64\kmtip64.pdb $(BACKUPDEFAULTS) x64\kmtip64.dll diff --git a/windows/src/engine/mcompile/Makefile b/windows/src/engine/mcompile/Makefile index 07aa392e3b..979b775ce4 100644 --- a/windows/src/engine/mcompile/Makefile +++ b/windows/src/engine/mcompile/Makefile @@ -18,6 +18,10 @@ clean: def-clean signcode: $(SIGNCODE) /d "Keyman Engine Mnemonic Keyboard Recompiler" $(PROGRAM)\engine\mcompile.exe +wrap-symbols: + $(SYMSTORE) $(PROGRAM)\engine\mcompile.exe /t keyman-engine-windows + $(SYMSTORE) $(DEBUGPATH)\engine\mcompile.pdb /t keyman-engine-windows + backup: $(WZZIP) $(BUILD)\engine\mcompile.exe $(BACKUPDEFAULTS) mcompile.exe diff --git a/windows/src/engine/tsysinfo/Makefile b/windows/src/engine/tsysinfo/Makefile index b0e63d001c..7ebb2c3e87 100644 --- a/windows/src/engine/tsysinfo/Makefile +++ b/windows/src/engine/tsysinfo/Makefile @@ -17,8 +17,8 @@ build: version.res manifest.res dirs del tsysinfox64.bin $(DCC32) tsysinfo.dpr - $(TDS2DBG) tsysinfo.exe $(SENTRYTOOL_DELPHIPREP) tsysinfo.exe -dpr tsysinfo.dpr + $(TDS2DBG) tsysinfo.exe $(COPY) tsysinfo.exe $(PROGRAM)\engine if exist tsysinfo.dbg $(COPY) tsysinfo.dbg $(DEBUGPATH)\engine @@ -28,6 +28,10 @@ clean: def-clean signcode: $(SIGNCODE) /d "Keyman Engine Diagnostics" $(PROGRAM)\engine\tsysinfo.exe +wrap-symbols: + $(SYMSTORE) $(PROGRAM)\engine\tsysinfo.exe /t keyman-engine-windows + $(SYMSTORE) $(DEBUGPATH)\engine\tsysinfo.dbg /t keyman-engine-windows + backup: $(WZZIP) $(BUILD)\engine\tsysinfo.zip $(BACKUPDEFAULTS) tsysinfo.exe diff --git a/windows/src/engine/tsysinfox64/Makefile b/windows/src/engine/tsysinfox64/Makefile index 29e57ac409..9ec8e58049 100644 --- a/windows/src/engine/tsysinfox64/Makefile +++ b/windows/src/engine/tsysinfox64/Makefile @@ -6,7 +6,7 @@ build: version.res manifest.res dirs $(DELPHI_MSBUILD) tsysinfox64.dproj /p:Platform=Win64 - $(SENTRYTOOL_DELPHIPREP) $(WIN64_TARGET_PATH)\tsysinfox64.exe -dpr tsysinfox64.dpr + #$(SENTRYTOOL_DELPHIPREP) $(WIN64_TARGET_PATH)\tsysinfox64.exe -dpr tsysinfox64.dpr $(COPY) $(WIN64_TARGET_PATH)\tsysinfox64.exe $(PROGRAM)\engine clean: def-clean @@ -14,6 +14,10 @@ clean: def-clean signcode: $(SIGNCODE) /d "Keyman Engine x64 Diagnostics" $(PROGRAM)\engine\tsysinfox64.exe +wrap-symbols: + $(SYMSTORE) $(PROGRAM)\engine\tsysinfox64.exe /t keyman-engine-windows + #$(SYMSTORE) $(DEBUGPATH)\engine\tsysinfox64.dbg /t keyman-engine-windows + backup: $(WZZIP) $(BUILD)\engine\tsysinfox64.zip $(BACKUPDEFAULTS) $(WIN64_TARGET_PATH)\*.map $(WIN64_TARGET_PATH)\tsysinfox64.exe diff --git a/windows/src/ext/sentry/Sentry.Client.pas b/windows/src/ext/sentry/Sentry.Client.pas index 2e427cb733..9c0b27a4d3 100644 --- a/windows/src/ext/sentry/Sentry.Client.pas +++ b/windows/src/ext/sentry/Sentry.Client.pas @@ -5,7 +5,6 @@ interface uses System.AnsiStrings, - System.Math, System.SysUtils, Winapi.ImageHlp, Winapi.Windows, @@ -175,6 +174,25 @@ begin Result := True; end; +/// +/// This is a thread-safe version of Set8087CW that avoids the global +/// variable Default8087CW. We would get occasional situations where +/// exceptions were raised on 2 threads simultaneously, which could lead to a +/// race where the first thread set Default8087CW to $1340, and then the second +/// thread would read that and think that is the default to keep. We want to +/// avoid touching Default8087CW altogether here. +/// +/// See also https://stackoverflow.com/a/39684636/1836776 and RSP-13643. +/// +procedure Set8087CW_Threadsafe(ANewCW: Word); +var + L8087CW: Word; +asm + mov L8087CW, ANewCW + fnclex + fldcw L8087CW +end; + /// /// First chance exception handler. We just want to take a copy of the raw /// stack here. @@ -189,11 +207,12 @@ const {$ENDIF} var Skip: Integer; - LastMask: TArithmeticExceptionMask; + LastMask: WORD; begin // Floating point state may be broken here, so let's mask it out and continue // We'll restore state afterwards - LastMask := System.Math.SetExceptionMask([]); + LastMask := Get8087CW; + Set8087CW_Threadsafe($1332); if ExceptionInfo.ExceptionRecord.ExceptionCode = cDelphiException then Skip := DELPHI_FRAMES_TO_SKIP @@ -201,7 +220,7 @@ begin CaptureStackTraceForException(ExceptionInfo.ExceptionRecord.ExceptionAddress, ExceptionInfo, Skip); // Restore FP state - System.Math.SetExceptionMask(LastMask); + Set8087CW_Threadsafe(LastMask); Result := 0; //EXCEPTION_CONTINUE_SEARCH; end; diff --git a/windows/src/ext/sentry/test/Makefile b/windows/src/ext/sentry/test/Makefile index b683428b29..11cd159a76 100644 --- a/windows/src/ext/sentry/test/Makefile +++ b/windows/src/ext/sentry/test/Makefile @@ -8,10 +8,10 @@ build: dirs # version.res manifest.res $(DELPHI_MSBUILD) SentryClientTest.dproj /p:Platform=Win32 $(DELPHI_MSBUILD) SentryClientVclTest.dproj /p:Platform=Win32 - $(TDS2DBG) $(WIN32_TARGET_PATH)\SentryClientTest.exe - $(TDS2DBG) $(WIN32_TARGET_PATH)\SentryClientVclTest.exe $(SENTRYTOOL_DELPHIPREP) $(WIN32_TARGET_PATH)\SentryClientTest.exe -dpr SentryClientTest.dpr $(SENTRYTOOL_DELPHIPREP) $(WIN32_TARGET_PATH)\SentryClientVclTest.exe -dpr SentryClientVclTest.dpr + $(TDS2DBG) $(WIN32_TARGET_PATH)\SentryClientTest.exe + $(TDS2DBG) $(WIN32_TARGET_PATH)\SentryClientVclTest.exe upload-symbols: sentry-cli upload-dif -p keyman-windows --wait --include-sources . diff --git a/windows/src/ext/sentry/test/SentryClientTest.dproj b/windows/src/ext/sentry/test/SentryClientTest.dproj index 3b885fb715..b51856b09c 100644 --- a/windows/src/ext/sentry/test/SentryClientTest.dproj +++ b/windows/src/ext/sentry/test/SentryClientTest.dproj @@ -55,6 +55,7 @@ false System;Xml;Data;Datasnap;Web;Soap;$(DCC_Namespace) SentryClientTest + true DBXSqliteDriver;IndyIPCommon;RESTComponents;bindcompdbx;DBXInterBaseDriver;vcl;IndyIPServer;vclactnband;vclFireDAC;IndySystem;tethering;svnui;mbColorLibD10;dsnapcon;FireDACADSDriver;scFontCombo;DCPdelphi2009;FireDACMSAccDriver;fmxFireDAC;vclimg;Jcl;FireDAC;vcltouch;JvCore;vcldb;bindcompfmx;svn;FireDACSqliteDriver;FireDACPgDriver;inetdb;CEF4Delphi;soaprtl;DbxCommonDriver;fmx;FireDACIBDriver;fmxdae;xmlrtl;soapmidas;fmxobj;vclwinx;rtl;DbxClientDriver;CustomIPTransport;vcldsnap;dbexpress;IndyCore;vclx;bindcomp;appanalytics;dsnap;FireDACCommon;IndyIPClient;bindcompvcl;RESTBackendComponents;EmbeddedWebBrowser_XE;VCLRESTComponents;soapserver;dbxcds;VclSmp;JvDocking;adortl;JclVcl;vclie;bindengine;DBXMySQLDriver;CloudService;dsnapxml;FireDACMySQLDriver;dbrtl;IndyProtocols;inetdbxpress;keyman_components;FireDACCommonODBC;FireDACCommonDriver;inet;fmxase;$(DCC_UsePackage) @@ -85,7 +86,6 @@ 3 1033 ..\..\..\..\..\..\sentry-native\sentry-delphi-test\(None) - true false @@ -94,7 +94,6 @@ 0 - true 3 1033 ..\..\..\..\..\..\sentry-native\sentry-delphi-test\(None) diff --git a/windows/src/ext/sentry/test/SentryClientVclTest.dproj b/windows/src/ext/sentry/test/SentryClientVclTest.dproj index 0a05f1c7f3..43c94f070b 100644 --- a/windows/src/ext/sentry/test/SentryClientVclTest.dproj +++ b/windows/src/ext/sentry/test/SentryClientVclTest.dproj @@ -58,6 +58,7 @@ $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png SentryClientVclTest + true DBXSqliteDriver;IndyIPCommon;RESTComponents;bindcompdbx;DBXInterBaseDriver;vcl;IndyIPServer;vclactnband;vclFireDAC;IndySystem;tethering;svnui;mbColorLibD10;dsnapcon;FireDACADSDriver;scFontCombo;DCPdelphi2009;FireDACMSAccDriver;fmxFireDAC;vclimg;Jcl;FireDAC;vcltouch;JvCore;vcldb;bindcompfmx;svn;FireDACSqliteDriver;FireDACPgDriver;inetdb;CEF4Delphi;soaprtl;DbxCommonDriver;fmx;FireDACIBDriver;fmxdae;xmlrtl;soapmidas;fmxobj;vclwinx;rtl;DbxClientDriver;CustomIPTransport;vcldsnap;dbexpress;IndyCore;vclx;bindcomp;appanalytics;dsnap;FireDACCommon;IndyIPClient;bindcompvcl;RESTBackendComponents;EmbeddedWebBrowser_XE;VCLRESTComponents;soapserver;dbxcds;VclSmp;JvDocking;adortl;JclVcl;vclie;bindengine;DBXMySQLDriver;CloudService;dsnapxml;FireDACMySQLDriver;dbrtl;IndyProtocols;inetdbxpress;keyman_components;FireDACCommonODBC;FireDACCommonDriver;inet;fmxase;$(DCC_UsePackage) @@ -84,7 +85,6 @@ true PerMonitorV2 3 - true true 1033 @@ -98,7 +98,6 @@ true PerMonitorV2 true - true 3 2 true diff --git a/windows/src/global/Makefile b/windows/src/global/Makefile index 0193aeb492..842f8a178d 100644 --- a/windows/src/global/Makefile +++ b/windows/src/global/Makefile @@ -13,14 +13,14 @@ build: cd $(ROOT)\src\global\wix $(MAKE) $(TARGET) - + build-release: @rem clean: -del $(ROOT)\src\global\delphi\general\keymanversion_build.inc -del $(ROOT)\src\global\inc\keymanversion_build.h - + cd $(ROOT)\src\global\delphi $(MAKE) clean @@ -38,10 +38,13 @@ signcode: backup: @rem - + test-manifest: @rem - + +wrap-symbols: + @rem + install: cd $(ROOT)\src\global\delphi $(MAKE) install diff --git a/windows/src/global/delphi/general/kmxfileconsts.pas b/windows/src/global/delphi/general/kmxfileconsts.pas index f623a3720d..83531d768d 100644 --- a/windows/src/global/delphi/general/kmxfileconsts.pas +++ b/windows/src/global/delphi/general/kmxfileconsts.pas @@ -96,9 +96,10 @@ const VERSION_80 = $00000800; VERSION_90 = $00000900; VERSION_100 = $00000A00; + VERSION_140 = $00000E00; VERSION_MIN = VERSION_50; - VERSION_MAX = VERSION_100; + VERSION_MAX = VERSION_140; VERSION_MASK_MINOR = $00FF; VERSION_MASK_MAJOR = $FF00; diff --git a/windows/src/global/inc/Comperr.h b/windows/src/global/inc/Comperr.h index b46dd7000a..6d58335256 100644 --- a/windows/src/global/inc/Comperr.h +++ b/windows/src/global/inc/Comperr.h @@ -142,6 +142,7 @@ #define CERR_90FeatureOnlyEmbedCSS 0x00004060 #define CERR_90FeatureOnlyTargets 0x00004061 #define CERR_ContextAndIndexInvalidInMatchNomatch 0x00004062 +#define CERR_140FeatureOnlyContextAndNotAnyWeb 0x00004063 #define CWARN_TooManyWarnings 0x00002080 #define CWARN_OldVersion 0x00002081 diff --git a/windows/src/global/inc/Compiler.h b/windows/src/global/inc/Compiler.h index 2419c14dcb..b0ac68e9af 100644 --- a/windows/src/global/inc/Compiler.h +++ b/windows/src/global/inc/Compiler.h @@ -69,9 +69,10 @@ #define VERSION_80 0x00000800 #define VERSION_90 0x00000900 #define VERSION_100 0x00000A00 +#define VERSION_140 0x00000E00 #define VERSION_MIN VERSION_50 -#define VERSION_MAX VERSION_100 +#define VERSION_MAX VERSION_140 /* Special flag for WM_CHAR/WM_KEY???/WM_SYSKEY???: says that key has been diff --git a/windows/src/support/charident/Makefile b/windows/src/support/charident/Makefile index 0ef7e9f662..d3c91a1ca6 100644 --- a/windows/src/support/charident/Makefile +++ b/windows/src/support/charident/Makefile @@ -13,7 +13,11 @@ clean: def-clean signcode: $(SIGNCODE) /d "Character Identifier" $(PROGRAM)\support\charident.exe +wrap-symbols: + $(SYMSTORE) $(PROGRAM)\support\charident.exe /t keyman-windows + #TODO: $(SYMSTORE) $(DEBUGPATH)\support\charident.dbg /t keyman-windows + backup: - $(WZZIP) $(BUILD)\online\charident.zip $(BACKUPDEFAULTS) charident.exe + $(WZZIP) $(BUILD)\support\charident.zip $(BACKUPDEFAULTS) charident.exe !include ..\..\Target.mak diff --git a/windows/src/support/etl2log/Makefile b/windows/src/support/etl2log/Makefile index 0e8b041af4..6c5c9591bc 100644 --- a/windows/src/support/etl2log/Makefile +++ b/windows/src/support/etl2log/Makefile @@ -15,6 +15,10 @@ clean: def-clean signcode: $(SIGNCODE) /d "Keyman Engine Tools" $(PROGRAM)\support\etl2log.exe +wrap-symbols: + $(SYMSTORE) $(PROGRAM)\support\etl2log.exe /t keyman-windows + $(SYMSTORE) $(DEBUGPATH)\support\etl2log.pdb /t keyman-windows + backup: $(WZZIP) $(BUILD)\support\etl2log.zip $(BACKUPDEFAULTS) etl2log.exe diff --git a/windows/src/support/km_yim/Makefile b/windows/src/support/km_yim/Makefile index 5b883d8d01..661c17e12a 100644 --- a/windows/src/support/km_yim/Makefile +++ b/windows/src/support/km_yim/Makefile @@ -1,5 +1,5 @@ # -# KMShell Makefile +# TODO: remove this project # !include ..\..\Defines.mak @@ -7,7 +7,7 @@ build: # version.res $(DCC32) km_yim.dpr rem $(TDSPACK) $(PROGRAM)\desktop\km_yim.exe km_yim.tds - rem $(TDS2DBG) $(PROGRAM)\desktop\km_yim.exe + rem $(TDS2DBG) $(PROGRAM)\desktop\km_yim.exe $(WZZIP) inst_km_yim.zip km_yim.exe # $(WZSE) inst_km_yim -setup -t inst_km_yim.dialog.txt -st "Tavultesoft Keyman Desktop Yahoo Messenger Addin" -c km_yim.exe @@ -17,6 +17,8 @@ clean: def-clean signcode: $(SIGNCODE) /d "Tavultesoft Keyman Desktop Yahoo Messenger Addin" inst_km_yim.exe +wrap-symbols: + rem backup: $(WZZIP) $(BUILD)\desktop\km_yim.zip $(BACKUPDEFAULTS) km_yim.exe diff --git a/windows/src/support/kmkb0045/Makefile b/windows/src/support/kmkb0045/Makefile index e82b8185fd..b521bfd026 100644 --- a/windows/src/support/kmkb0045/Makefile +++ b/windows/src/support/kmkb0045/Makefile @@ -1,13 +1,13 @@ # -# KMKB0045 Makefile +# TODO: remove this project # !include ..\..\Defines.mak build: version.res manifest.res $(DCC32) kmkb0045.dpr - $(TDS2DBG) kmkb0045.exe $(SENTRYTOOL_DELPHIPREP) kmkb0045.exe -dpr kmkb0045.dpr + $(TDS2DBG) kmkb0045.exe $(COPY) kmkb0045.exe $(PROGRAM)\support clean: def-clean diff --git a/windows/src/support/oskbulkrenderer/Makefile b/windows/src/support/oskbulkrenderer/Makefile index 7e4ac4e1dc..c008301503 100644 --- a/windows/src/support/oskbulkrenderer/Makefile +++ b/windows/src/support/oskbulkrenderer/Makefile @@ -7,8 +7,8 @@ build: version.res dirs $(DELPHI_MSBUILD) oskbulkrenderer.dproj /p:Platform=Win32 - $(TDS2DBG) $(WIN32_TARGET_PATH)\oskbulkrenderer.exe $(SENTRYTOOL_DELPHIPREP) $(WIN32_TARGET_PATH)\oskbulkrenderer.exe -dpr oskbulkrenderer.dpr + $(TDS2DBG) $(WIN32_TARGET_PATH)\oskbulkrenderer.exe $(COPY) $(WIN32_TARGET_PATH)\oskbulkrenderer.exe $(PROGRAM)\support if exist $(WIN32_TARGET_PATH)\oskbulkrenderer.dbg $(COPY) $(WIN32_TARGET_PATH)\oskbulkrenderer.dbg $(DEBUGPATH)\support @@ -21,4 +21,7 @@ signcode: backup: rem No source code backup needed +wrap-symbols: + @rem + !include ..\..\Target.mak diff --git a/windows/src/support/oskbulkrenderer/oskbulkrenderer.dproj b/windows/src/support/oskbulkrenderer/oskbulkrenderer.dproj index 3e66ba000b..f92498fc7b 100644 --- a/windows/src/support/oskbulkrenderer/oskbulkrenderer.dproj +++ b/windows/src/support/oskbulkrenderer/oskbulkrenderer.dproj @@ -66,6 +66,7 @@ RESTComponents;FireDAC;FireDACSqliteDriver;soaprtl;FireDACIBDriver;soapmidas;FireDACCommon;RESTBackendComponents;soapserver;CloudService;FireDACCommonDriver;inet;$(DCC_UsePackage) System;Xml;Data;Datasnap;Web;Soap;Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;$(DCC_Namespace) oskbulkrenderer + true true @@ -118,7 +119,6 @@ false -f -x .kvks . c:\temp\x\kbdus\source - true 1033 (None) 3 @@ -130,7 +130,6 @@ 0 - true 1033 (None) 3 diff --git a/windows/src/support/unload_keyboards/unloadkeyboards.dproj b/windows/src/support/unload_keyboards/unloadkeyboards.dproj index 82280225b0..7088e131fa 100644 --- a/windows/src/support/unload_keyboards/unloadkeyboards.dproj +++ b/windows/src/support/unload_keyboards/unloadkeyboards.dproj @@ -57,6 +57,7 @@ false false unloadkeyboards + true IndyCore160;vcldbx;frx16;TeeDB;IndyProtocols160;EmbeddedWebBrowser_XE;tb2k_d12;vclib;inetdbbde;Tee;Rave100VCL;svnui;ibxpress;vclimg;DCPdelphi2009;frxDB16;intrawebdb_120_160;fmi;mbColorLibD10;fs16;vclactnband;FMXTee;vcldb;TeeUI;bindcompvcl;vcldsnap;vclie;vcltouch;Intraweb_120_160;websnap;vclribbon;VclSmp;frxe16;fsDB16;vcl;PBFolderDialogPackRun;CloudService;CodeSiteExpressPkg;IndySystem160;FmxTeeUI;dsnapcon;vclx;VCLZipD2009_4;webdsnap;svn;keyman_components;bdertl;SpTBXLib_d16;adortl;$(DCC_UsePackage) @@ -90,7 +91,6 @@ false Debug - true true true 1033