From 39ae61a8358cd7988c1d4c3b6c5d6ed323affbe7 Mon Sep 17 00:00:00 2001 From: sgschantz Date: Thu, 6 Jun 2024 16:31:11 +0700 Subject: [PATCH 01/35] fix(mac): add unit tests to confirm first calls to compliance check Also makes public the description method used for logging. A private description method may have been an issue with the older logging code. To build successfully with Xcode, it was necessary to change runOnlyForDeploymentPostprocessing=1. This was apparently needed because of the upgrade to Xcode 15 --- .../Keyman4MacIM.xcodeproj/project.pbxproj | 4 +- .../Keyman4MacIM/TextApiCompliance.h | 1 + .../Keyman4MacIM/TextApiCompliance.m | 2 +- .../KeymanTests/InputMethodTests.m | 53 +++++++++++++++++-- 4 files changed, 54 insertions(+), 6 deletions(-) diff --git a/mac/Keyman4MacIM/Keyman4MacIM.xcodeproj/project.pbxproj b/mac/Keyman4MacIM/Keyman4MacIM.xcodeproj/project.pbxproj index 35a362f261..8e0b973442 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM.xcodeproj/project.pbxproj +++ b/mac/Keyman4MacIM/Keyman4MacIM.xcodeproj/project.pbxproj @@ -114,13 +114,13 @@ }; E211CCF420B5FE7A00505C36 /* CopyFiles */ = { isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; + buildActionMask = 8; dstPath = ""; dstSubfolderSpec = 16; files = ( E211CCF620B600A500505C36 /* KeymanEngine4Mac.framework.dSYM in CopyFiles */, ); - runOnlyForDeploymentPostprocessing = 0; + runOnlyForDeploymentPostprocessing = 1; }; E27BA9CF202036BA00D273E7 /* CopyFiles */ = { isa = PBXCopyFilesBuildPhase; diff --git a/mac/Keyman4MacIM/Keyman4MacIM/TextApiCompliance.h b/mac/Keyman4MacIM/Keyman4MacIM/TextApiCompliance.h index 6c80417faf..81cc4c3b34 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/TextApiCompliance.h +++ b/mac/Keyman4MacIM/Keyman4MacIM/TextApiCompliance.h @@ -16,6 +16,7 @@ NS_ASSUME_NONNULL_BEGIN @property (readonly) NSString *clientApplicationId; -(instancetype)initWithClient:(id) client applicationId:(NSString *)appId; +-(NSString *)description; -(void)checkCompliance:(id) client; -(void) checkComplianceAfterInsert:(id) client delete:(NSString *)textToDelete insert:(NSString *)textToInsert; -(BOOL)isComplianceUncertain; diff --git a/mac/Keyman4MacIM/Keyman4MacIM/TextApiCompliance.m b/mac/Keyman4MacIM/Keyman4MacIM/TextApiCompliance.m index 0f62fa61a8..e83439794b 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/TextApiCompliance.m +++ b/mac/Keyman4MacIM/Keyman4MacIM/TextApiCompliance.m @@ -73,7 +73,7 @@ NSString *const kKMLegacyApps = @"KMLegacyApps"; -(NSString *)description { - return [NSString stringWithFormat:@"complianceUncertain: %d, hasCompliantSelectionApi: %d, canReadText: %d, canReplaceText: %d, mustBackspaceUsingEvents: %d, clientAppId: %@, client: %@", self.complianceUncertain, self.hasCompliantSelectionApi, [self canReadText], [self canReplaceText], [self mustBackspaceUsingEvents], _clientApplicationId, _client]; + return [NSString stringWithFormat:@"complianceUncertain: %d, hasCompliantSelectionApi: %d, canReadText: %d, canReplaceText: %d, mustBackspaceUsingEvents: %d, clientApplicationId: %@, client: %@", self.complianceUncertain, self.hasCompliantSelectionApi, [self canReadText], [self canReplaceText], [self mustBackspaceUsingEvents], _clientApplicationId, _client]; } /** test to see if the API selectedRange functions properly for the text input client */ diff --git a/mac/Keyman4MacIM/KeymanTests/InputMethodTests.m b/mac/Keyman4MacIM/KeymanTests/InputMethodTests.m index 8eb9d974ce..a2953c44cf 100644 --- a/mac/Keyman4MacIM/KeymanTests/InputMethodTests.m +++ b/mac/Keyman4MacIM/KeymanTests/InputMethodTests.m @@ -15,23 +15,27 @@ #import "TextApiCompliance.h" KMInputMethodEventHandler *testEventHandler = nil; +id testClient = nil; @interface InputMethodTests : XCTestCase @end @interface KMInputMethodEventHandler (Testing) - +@property (nonatomic, retain) TextApiCompliance* apiCompliance; +@property (nonatomic, retain) NSString* clientApplicationId; +@property BOOL contextChanged; - (instancetype)initWithClient:(NSString *)clientAppId client:(id) sender; - (NSRange) calculateInsertRangeForDeletedText:(NSString*)textToDelete selectionRange:(NSRange) selection; +- (void)checkTextApiCompliance:(id)client; @end @implementation InputMethodTests - (void)setUp { - id client = [[AppleCompliantTestClient alloc] init]; + testClient = [[AppleCompliantTestClient alloc] init]; NSString *clientAppId = @"com.compliant.app"; - testEventHandler = [[KMInputMethodEventHandler alloc]initWithClient:clientAppId client:client]; + testEventHandler = [[KMInputMethodEventHandler alloc]initWithClient:clientAppId client:testClient]; } - (void)tearDown { @@ -85,4 +89,47 @@ KMInputMethodEventHandler *testEventHandler = nil; XCTAssertTrue(correctResult, @"insert or replacement range expected to be {1,2}"); } +/** + * test compliance check of a KMInputMethodEventHandler with a nil client application ID + * not sure if this can ever happen, but the lifecycle of the input method is not 100% clear, + * and we would like this scenario, if it can occur, to not result in a crash + */ +- (void)testCheckCompliance_withUnknownApplicationId_createsComplianceObject { + id client = [[AppleCompliantTestClient alloc] init]; + //NSString *clientAppId = @"com.compliant.app"; + KMInputMethodEventHandler *eventHandler = [[KMInputMethodEventHandler alloc]initWithClient:nil client:client]; + [eventHandler checkTextApiCompliance:client]; + XCTAssertNotNil(eventHandler.apiCompliance, @"apiCompliance object was not created"); +} + +- (void)testCheckCompliance_withNilComplianceObject_createsComplianceObject { + [testEventHandler checkTextApiCompliance:testClient]; + XCTAssertNotNil(testEventHandler.apiCompliance, @"apiCompliance object was not created"); +} + +- (void)testCheckCompliance_withChangedClientApplicationId_createsNewComplianceObject { + // first call causes textApiCompliance object to be created + [testEventHandler checkTextApiCompliance:testClient]; + TextApiCompliance *originalComplianceObject = testEventHandler.apiCompliance; + + testEventHandler.clientApplicationId = @"com.different.app"; + // second call causes new textApiCompliance object to be created due to stale application ID + [testEventHandler checkTextApiCompliance:testClient]; + XCTAssertNotEqualObjects(originalComplianceObject, testEventHandler.apiCompliance, @"New TextApiCompliance object not created for new client application ID"); +} + +- (void)testCheckCompliance_withContextChanged_createsNewComplianceObject { + // first call causes textApiCompliance object to be created + [testEventHandler checkTextApiCompliance:testClient]; + TextApiCompliance *originalComplianceObject = testEventHandler.apiCompliance; + + testEventHandler.contextChanged = YES; + // second call causes new textApiCompliance object to be created due to setting contextChanged flag + [testEventHandler checkTextApiCompliance:testClient]; + XCTAssertNotEqualObjects(originalComplianceObject, testEventHandler.apiCompliance, @"New TextApiCompliance object not created after contextChanged flag set"); +} + + + + @end From 83c06299ba1bf1996511d762c6f0d093d4e36eb7 Mon Sep 17 00:00:00 2001 From: sgschantz Date: Fri, 7 Jun 2024 09:35:02 +0700 Subject: [PATCH 02/35] fix(mac): rollback runOnlyForDeploymentPostprocessing change break into separate PR --- mac/Keyman4MacIM/Keyman4MacIM.xcodeproj/project.pbxproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mac/Keyman4MacIM/Keyman4MacIM.xcodeproj/project.pbxproj b/mac/Keyman4MacIM/Keyman4MacIM.xcodeproj/project.pbxproj index 8e0b973442..f0af727d56 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM.xcodeproj/project.pbxproj +++ b/mac/Keyman4MacIM/Keyman4MacIM.xcodeproj/project.pbxproj @@ -114,13 +114,13 @@ }; E211CCF420B5FE7A00505C36 /* CopyFiles */ = { isa = PBXCopyFilesBuildPhase; - buildActionMask = 8; + buildActionMask = 12; dstPath = ""; dstSubfolderSpec = 16; files = ( E211CCF620B600A500505C36 /* KeymanEngine4Mac.framework.dSYM in CopyFiles */, ); - runOnlyForDeploymentPostprocessing = 1; + runOnlyForDeploymentPostprocessing = 0; }; E27BA9CF202036BA00D273E7 /* CopyFiles */ = { isa = PBXCopyFilesBuildPhase; From 2d59ee8a946aa1f4aad818b78b016b01e72d51ab Mon Sep 17 00:00:00 2001 From: Joshua Horton Date: Thu, 15 Aug 2024 13:18:05 +0700 Subject: [PATCH 03/35] change(ios): defer registration of fonts past initialization --- ios/engine/KMEI/KeymanEngine/Classes/Manager.swift | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/ios/engine/KMEI/KeymanEngine/Classes/Manager.swift b/ios/engine/KMEI/KeymanEngine/Classes/Manager.swift index 5b77f79307..d1d134b249 100644 --- a/ios/engine/KMEI/KeymanEngine/Classes/Manager.swift +++ b/ios/engine/KMEI/KeymanEngine/Classes/Manager.swift @@ -831,12 +831,22 @@ public class Manager: NSObject, UIGestureRecognizerDelegate { shared.copyUserDefaults(to: nonShared, withKeys: keysToCopy, shouldOverwrite: true) do { try shared.copyFiles(to: nonShared) - FontManager.shared.registerCustomFonts() } catch { let message = ("Failed to copy from shared container: \(error)") os_log("%{public}s", log:KeymanEngineLogger.settings, type: .error, message) SentryManager.capture(error, message:message) } + + // This operation has a surprisingly high cost and isn't critical + // for getting the keyboard loaded and available to the OS. + // + // We certainly want it done _soon_... but we don't want it to cause + // the primary, synchronous initialization call from the OS to run so + // long that the keyboard fails to start due to its enforced time + // constraints. + DispatchQueue.main.async { + FontManager.shared.registerCustomFonts() + } } } From 72da3d8099d2e890f3941acfa13001684b9da7a4 Mon Sep 17 00:00:00 2001 From: Joshua Horton Date: Fri, 16 Aug 2024 14:59:28 +0700 Subject: [PATCH 04/35] refactor(ios): optimize font registration --- .../Classes/Resource Data/FontManager.swift | 151 ++++++++++++------ 1 file changed, 102 insertions(+), 49 deletions(-) diff --git a/ios/engine/KMEI/KeymanEngine/Classes/Resource Data/FontManager.swift b/ios/engine/KMEI/KeymanEngine/Classes/Resource Data/FontManager.swift index d64019cc27..4a50650100 100644 --- a/ios/engine/KMEI/KeymanEngine/Classes/Resource Data/FontManager.swift +++ b/ios/engine/KMEI/KeymanEngine/Classes/Resource Data/FontManager.swift @@ -26,6 +26,17 @@ public class FontManager { fonts[url] = RegisteredFont(name: name, isRegistered: false) return name } + + private func cachedFont(at url: URL) -> RegisteredFont? { + if let font = fonts[url] { + return font + } + guard let name = readFontName(at: url) else { + return nil + } + fonts[url] = RegisteredFont(name: name, isRegistered: false) + return fonts[url] + } /// Registers all new fonts found in the font path. Call this after you have preloaded all your font files /// with `preloadFontFile(atPath:shouldOverwrite:)` @@ -33,8 +44,45 @@ public class FontManager { guard let keyboardDirs = Storage.active.keyboardDirs else { return } + + var fontSet: Set = [] for dir in keyboardDirs { - registerFonts(in: dir) + fontSet = fontSet.union(listFonts(in: dir)) + } + + registerListedFonts(fontSet) + } + + /** + * Iterates across all listed fonts, registering those not yet registered. + * Checks for, and filters out, any fonts already registered on the system. + */ + private func registerListedFonts(_ initialFontSet: Set) { + // If we are unable to read the font file's properties sufficiently, + // skip it. We also don't need to register anything already registered. + var fontSet = initialFontSet.filter { !(cachedFont(at: $0)?.isRegistered ?? true) } + + // The prior line filters out any entries where cachedFont(at: $0) would be nil. + // Batch-lookups all fonts lacking cache-confirmation of prior registration. + var fontNamesToRegister = missingFonts(from: Set(fontSet.map { cachedFont(at: $0)!.name })) + + for fontUrl in fontSet { + let fontName = cachedFont(at: fontUrl)!.name + + guard fontNamesToRegister.contains(fontName) else { + let message = "Did not register font at \(fontUrl) because font name \(fontName) is already registered" + os_log("%{public}s", log:KeymanEngineLogger.resources, type: .info, message) + continue + } + + let didRegister = _registerFont(at: fontUrl) + fonts[fontUrl] = RegisteredFont(name: fontName, isRegistered: didRegister) + + // We no longer need to register a font with this name, so drop it from + // the set to register. + if didRegister { + fontNamesToRegister.remove(fontName) + } } } @@ -43,6 +91,8 @@ public class FontManager { guard let keyboardDirs = Storage.active.keyboardDirs else { return } + // This doesn't use the expensive looped lookup operation seen in missingFonts, + // so there's no need to batch similar operations here. for dir in keyboardDirs { unregisterFonts(in: dir) } @@ -63,44 +113,29 @@ public class FontManager { } return name as String } + + private func _registerFont(at url: URL) -> Bool { + var errorRef: Unmanaged? + let fontName = fontName(at: url)! + let didRegister = CTFontManagerRegisterFontsForURL(url as CFURL, .none, &errorRef) + let error = errorRef?.takeRetainedValue() // Releases errorRef + if !didRegister { + let message = "Failed to register font \(fontName) at \(url) reason: \(String(describing: error))" + os_log("%{public}s", log:KeymanEngineLogger.resources, type: .error, message) + } else { + let message = "Registered font \(fontName) at \(url)" + os_log("%{public}s", log:KeymanEngineLogger.resources, type: .info, message) + } + + return didRegister + } /// - Parameters: /// - url: URL of the font to register /// - Returns: Font is registered. public func registerFont(at url: URL) -> Bool { - let fontName: String - if let font = fonts[url] { - if font.isRegistered { - return true - } - fontName = font.name - } else { - guard let name = readFontName(at: url) else { - return false - } - fontName = name - } - - let didRegister: Bool - if !fontExists(fontName) { - var errorRef: Unmanaged? - didRegister = CTFontManagerRegisterFontsForURL(url as CFURL, .none, &errorRef) - let error = errorRef?.takeRetainedValue() // Releases errorRef - if !didRegister { - let message = "Failed to register font \(fontName) at \(url) reason: \(String(describing: error))" - os_log("%{public}s", log:KeymanEngineLogger.resources, type: .error, message) - } else { - let message = "Registered font \(fontName) at \(url)" - os_log("%{public}s", log:KeymanEngineLogger.resources, type: .info, message) - } - } else { - didRegister = false - let message = "Did not register font at \(url) because font name \(fontName) is already registered" - os_log("%{public}s", log:KeymanEngineLogger.resources, type: .info, message) - } - let font = RegisteredFont(name: fontName, isRegistered: didRegister) - fonts[url] = font - return didRegister + registerListedFonts([url]) + return fonts[url]?.isRegistered ?? false } /// - Parameters: @@ -133,32 +168,50 @@ public class FontManager { return font.isRegistered } - - public func registerFonts(in directory: URL) { + + private func listFonts(in directory: URL) -> [URL] { guard let urls = try? FileManager.default.contentsOfDirectory(at: directory, includingPropertiesForKeys: nil) else { let message = "Could not list contents of directory \(directory)" os_log("%{public}s", log:KeymanEngineLogger.resources, type: .error, message) - return - } - for url in urls where url.lastPathComponent.hasFontExtension { - _ = registerFont(at: url) + return [] } + return urls.filter { $0.lastPathComponent.hasFontExtension } + } + + public func registerFonts(in directory: URL) { + let fontsToRegister = listFonts(in: directory) + registerListedFonts(Set(fontsToRegister)) } public func unregisterFonts(in directory: URL, fromSystemOnly: Bool = true) { - guard let urls = try? FileManager.default.contentsOfDirectory(at: directory, includingPropertiesForKeys: nil) else { - let message = "Could not list contents of directory \(directory)" - os_log("%{public}s", log:KeymanEngineLogger.resources, type: .error, message) - return - } - for url in urls where url.lastPathComponent.hasFontExtension { + let fontsToUnregister = listFonts(in: directory) + for url in fontsToUnregister { _ = unregisterFont(at: url, fromSystemOnly: fromSystemOnly) } } - private func fontExists(_ fontName: String) -> Bool { - return UIFont.familyNames.contains { familyName in - UIFont.fontNames(forFamilyName: familyName).contains(fontName) + /** + * Queries the system for existing registrations for the specified fonts with a single batch run. + * Only fonts that could not be found will be returned within the result set. + */ + private func missingFonts(from fontNames: Set) -> Set { + // Arrays are treated 'by value'; it's already a shallow copy. + var fontsToFind = fontNames + + UIFont.familyNames.forEach { familyName in + let familyFonts = UIFont.fontNames(forFamilyName: familyName) + + for font in familyFonts { + if let index = fontsToFind.firstIndex(where: { $0 == font }) { + fontsToFind.remove(at: index) + } + + if fontsToFind.count == 0 { + break + } + } } + + return fontsToFind } } From e28d8a341a02477cab1b7e841187679917d5048c Mon Sep 17 00:00:00 2001 From: Joshua Horton Date: Fri, 16 Aug 2024 15:15:32 +0700 Subject: [PATCH 05/35] change(ios): cleaner set-based fonts-to-find maintenance --- .../KMEI/KeymanEngine/Classes/Resource Data/FontManager.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ios/engine/KMEI/KeymanEngine/Classes/Resource Data/FontManager.swift b/ios/engine/KMEI/KeymanEngine/Classes/Resource Data/FontManager.swift index 4a50650100..6dd114d375 100644 --- a/ios/engine/KMEI/KeymanEngine/Classes/Resource Data/FontManager.swift +++ b/ios/engine/KMEI/KeymanEngine/Classes/Resource Data/FontManager.swift @@ -202,8 +202,8 @@ public class FontManager { let familyFonts = UIFont.fontNames(forFamilyName: familyName) for font in familyFonts { - if let index = fontsToFind.firstIndex(where: { $0 == font }) { - fontsToFind.remove(at: index) + if fontsToFind.contains(font) { + fontsToFind.remove(font) } if fontsToFind.count == 0 { From 289dda0fcab73ae94938e9a69ec599f2c7efb0cf Mon Sep 17 00:00:00 2001 From: Joshua Horton Date: Fri, 16 Aug 2024 15:17:05 +0700 Subject: [PATCH 06/35] change(ios): better early-exit if all font data found --- .../KMEI/KeymanEngine/Classes/Resource Data/FontManager.swift | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ios/engine/KMEI/KeymanEngine/Classes/Resource Data/FontManager.swift b/ios/engine/KMEI/KeymanEngine/Classes/Resource Data/FontManager.swift index 6dd114d375..9f0047d7f7 100644 --- a/ios/engine/KMEI/KeymanEngine/Classes/Resource Data/FontManager.swift +++ b/ios/engine/KMEI/KeymanEngine/Classes/Resource Data/FontManager.swift @@ -199,6 +199,10 @@ public class FontManager { var fontsToFind = fontNames UIFont.familyNames.forEach { familyName in + if fontsToFind.count == 0 { + return + } + let familyFonts = UIFont.fontNames(forFamilyName: familyName) for font in familyFonts { From c712d35984d4bad2d515a2852953af17d804ffe5 Mon Sep 17 00:00:00 2001 From: Joshua Horton Date: Mon, 19 Aug 2024 12:16:04 +0700 Subject: [PATCH 07/35] chore(ios): adjustments per review --- .../KeymanEngine/Classes/Resource Data/FontManager.swift | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/ios/engine/KMEI/KeymanEngine/Classes/Resource Data/FontManager.swift b/ios/engine/KMEI/KeymanEngine/Classes/Resource Data/FontManager.swift index 9f0047d7f7..6070de2c96 100644 --- a/ios/engine/KMEI/KeymanEngine/Classes/Resource Data/FontManager.swift +++ b/ios/engine/KMEI/KeymanEngine/Classes/Resource Data/FontManager.swift @@ -56,10 +56,15 @@ public class FontManager { /** * Iterates across all listed fonts, registering those not yet registered. * Checks for, and filters out, any fonts already registered on the system. + * Also initializes the registration cache per URL if needed. */ private func registerListedFonts(_ initialFontSet: Set) { // If we are unable to read the font file's properties sufficiently, - // skip it. We also don't need to register anything already registered. + // skip it. We also don't need to register anything already registered or + // that cannot be registered due to loading/parsing errors. + // + // Calls to `cachedFont` after the `.filter` below may be assumed to have + // non-nil return values. var fontSet = initialFontSet.filter { !(cachedFont(at: $0)?.isRegistered ?? true) } // The prior line filters out any entries where cachedFont(at: $0) would be nil. @@ -195,7 +200,6 @@ public class FontManager { * Only fonts that could not be found will be returned within the result set. */ private func missingFonts(from fontNames: Set) -> Set { - // Arrays are treated 'by value'; it's already a shallow copy. var fontsToFind = fontNames UIFont.familyNames.forEach { familyName in From 97697b695ff85eed11047489b08c1f9299f559ca Mon Sep 17 00:00:00 2001 From: "Joshua A. Horton" Date: Tue, 20 Aug 2024 14:19:14 +0700 Subject: [PATCH 08/35] fix(web): fix documentation-keyboard spacebar-text scaling Fixes: #12231 --- web/src/engine/osk/src/visualKeyboard.ts | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/web/src/engine/osk/src/visualKeyboard.ts b/web/src/engine/osk/src/visualKeyboard.ts index 26b269d7f2..0d529af651 100644 --- a/web/src/engine/osk/src/visualKeyboard.ts +++ b/web/src/engine/osk/src/visualKeyboard.ts @@ -1246,6 +1246,7 @@ export default class VisualKeyboard extends EventEmitter implements Ke const groupStyle = getComputedStyle(this.layerGroup.element); const isInDOM = computedStyle.height != '' && computedStyle.height != 'auto'; + const isGroupInDOM = groupStyle.height != '' && groupStyle.height != 'auto'; if (computedStyle.border) { this._borderWidth = new ParsedLengthStyle(computedStyle.borderWidth).val; @@ -1258,10 +1259,11 @@ export default class VisualKeyboard extends EventEmitter implements Ke this._computedHeight = this.height; } else if (isInDOM) { this._computedWidth = parseInt(computedStyle.width, 10); - if (!this._computedWidth) { - this._computedWidth = parseInt(groupStyle.width, 10); - } this._computedHeight = parseInt(computedStyle.height, 10); + } else if (isGroupInDOM) { + // May occur for documentation-keyboards, which are detached from their VisualKeyboard base. + this._computedWidth = parseInt(groupStyle.width, 10); + this._computedHeight = parseInt(groupStyle.height, 10); } else { // Cannot perform layout operations! return; @@ -1604,6 +1606,11 @@ export default class VisualKeyboard extends EventEmitter implements Ke // the page. kbdObj.appendStyleSheet(); + // Unset the width + height we used thus far; this method's consumer may choose to rescale + // the returned element. If so, we don't want to use our outdated value by mistake. + delete kbdObj._width; + delete kbdObj._height; + return classWrapper; } From 23e02d2a86812e7807fdad6304db99abf1d773de Mon Sep 17 00:00:00 2001 From: "Joshua A. Horton" Date: Tue, 20 Aug 2024 14:38:58 +0700 Subject: [PATCH 09/35] change(web): better way to re-establish default sizing --- web/src/engine/osk/src/visualKeyboard.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/web/src/engine/osk/src/visualKeyboard.ts b/web/src/engine/osk/src/visualKeyboard.ts index 0d529af651..a70c6b68ed 100644 --- a/web/src/engine/osk/src/visualKeyboard.ts +++ b/web/src/engine/osk/src/visualKeyboard.ts @@ -1608,8 +1608,7 @@ export default class VisualKeyboard extends EventEmitter implements Ke // Unset the width + height we used thus far; this method's consumer may choose to rescale // the returned element. If so, we don't want to use our outdated value by mistake. - delete kbdObj._width; - delete kbdObj._height; + kbdObj.setSize(); return classWrapper; } From 01ae0c0a9ac23df03482223390a1a8f0ceba3d43 Mon Sep 17 00:00:00 2001 From: "Joshua A. Horton" Date: Tue, 20 Aug 2024 14:40:24 +0700 Subject: [PATCH 10/35] chore(web): Revert "change(web): better way to re-establish default sizing" This reverts commit 23e02d2a86812e7807fdad6304db99abf1d773de. --- web/src/engine/osk/src/visualKeyboard.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/web/src/engine/osk/src/visualKeyboard.ts b/web/src/engine/osk/src/visualKeyboard.ts index a70c6b68ed..0d529af651 100644 --- a/web/src/engine/osk/src/visualKeyboard.ts +++ b/web/src/engine/osk/src/visualKeyboard.ts @@ -1608,7 +1608,8 @@ export default class VisualKeyboard extends EventEmitter implements Ke // Unset the width + height we used thus far; this method's consumer may choose to rescale // the returned element. If so, we don't want to use our outdated value by mistake. - kbdObj.setSize(); + delete kbdObj._width; + delete kbdObj._height; return classWrapper; } From 5c96f8f76921ef23f70a827eb483f5f60580b23a Mon Sep 17 00:00:00 2001 From: sgschantz Date: Tue, 20 Aug 2024 16:14:40 +0700 Subject: [PATCH 11/35] fix(mac): remove text from short bundle version string in info.plist for both input method and engine, remove the framing text so that it just contains the version number triplet Fixes: #12197 --- mac/Keyman4MacIM/Keyman4MacIM/Info.plist | 2 +- mac/KeymanEngine4Mac/KeymanEngine4Mac/Info.plist | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mac/Keyman4MacIM/Keyman4MacIM/Info.plist b/mac/Keyman4MacIM/Keyman4MacIM/Info.plist index 29451d4cce..49f532055e 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/Info.plist +++ b/mac/Keyman4MacIM/Keyman4MacIM/Info.plist @@ -36,7 +36,7 @@ CFBundlePackageType APPL CFBundleShortVersionString - Keyman $(PRODUCT_VERSION) for macOS + $(PRODUCT_VERSION) CFBundleSignature ???? CFBundleURLTypes diff --git a/mac/KeymanEngine4Mac/KeymanEngine4Mac/Info.plist b/mac/KeymanEngine4Mac/KeymanEngine4Mac/Info.plist index 970606a26a..3f42d3e63f 100644 --- a/mac/KeymanEngine4Mac/KeymanEngine4Mac/Info.plist +++ b/mac/KeymanEngine4Mac/KeymanEngine4Mac/Info.plist @@ -17,7 +17,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - Keyman Engine $(PRODUCT_VERSION) for macOS + $(PRODUCT_VERSION) CFBundleSignature ???? CFBundleVersion From 45dee1c504afdd40f5df000b08d07f7a810acbb3 Mon Sep 17 00:00:00 2001 From: "Joshua A. Horton" Date: Wed, 21 Aug 2024 09:05:48 +0700 Subject: [PATCH 12/35] docs(web): extends doc-comment per review comment --- web/src/engine/osk/src/visualKeyboard.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/web/src/engine/osk/src/visualKeyboard.ts b/web/src/engine/osk/src/visualKeyboard.ts index 0d529af651..3a439c1db4 100644 --- a/web/src/engine/osk/src/visualKeyboard.ts +++ b/web/src/engine/osk/src/visualKeyboard.ts @@ -1608,6 +1608,11 @@ export default class VisualKeyboard extends EventEmitter implements Ke // Unset the width + height we used thus far; this method's consumer may choose to rescale // the returned element. If so, we don't want to use our outdated value by mistake. + // + // While `kbdObj.setSize()` could be used in theory, it _also_ unsets the element styling. + // We actually wish to _leave_ this styling in place - one of our parameters is `height`, and + // it should remain in place in the styling on the output element as the default in case + // the consumer _doesn't_ add styling afterward. delete kbdObj._width; delete kbdObj._height; From dc434a776a59dcbf417730c3a3753fd97b44c04c Mon Sep 17 00:00:00 2001 From: Darcy Wong Date: Wed, 21 Aug 2024 10:51:35 +0700 Subject: [PATCH 13/35] fix(android): Use increment and decrement arrows on longpress delay --- .../src/main/res/layout/activity_adjust_longpress_delay.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/android/KMAPro/kMAPro/src/main/res/layout/activity_adjust_longpress_delay.xml b/android/KMAPro/kMAPro/src/main/res/layout/activity_adjust_longpress_delay.xml index ed0bed54a9..ef1ebd613b 100644 --- a/android/KMAPro/kMAPro/src/main/res/layout/activity_adjust_longpress_delay.xml +++ b/android/KMAPro/kMAPro/src/main/res/layout/activity_adjust_longpress_delay.xml @@ -23,7 +23,7 @@ android:layout_marginStart="5dp" android:layout_marginEnd="5dp" android:contentDescription="@string/ic_delay_time_down" - android:src="@drawable/ic_light_dialog_textsize_down" /> + android:src="@drawable/ic_action_decrement" /> + android:src="@drawable/ic_action_increment" /> From a26389bfeabe4313e77e4afad4530f90fa4ed907 Mon Sep 17 00:00:00 2001 From: sgschantz Date: Wed, 21 Aug 2024 11:12:43 +0700 Subject: [PATCH 14/35] test(mac): removed commented code --- mac/Keyman4MacIM/KeymanTests/InputMethodTests.m | 4 ---- 1 file changed, 4 deletions(-) diff --git a/mac/Keyman4MacIM/KeymanTests/InputMethodTests.m b/mac/Keyman4MacIM/KeymanTests/InputMethodTests.m index a2953c44cf..7372a2a548 100644 --- a/mac/Keyman4MacIM/KeymanTests/InputMethodTests.m +++ b/mac/Keyman4MacIM/KeymanTests/InputMethodTests.m @@ -96,7 +96,6 @@ id testClient = nil; */ - (void)testCheckCompliance_withUnknownApplicationId_createsComplianceObject { id client = [[AppleCompliantTestClient alloc] init]; - //NSString *clientAppId = @"com.compliant.app"; KMInputMethodEventHandler *eventHandler = [[KMInputMethodEventHandler alloc]initWithClient:nil client:client]; [eventHandler checkTextApiCompliance:client]; XCTAssertNotNil(eventHandler.apiCompliance, @"apiCompliance object was not created"); @@ -129,7 +128,4 @@ id testClient = nil; XCTAssertNotEqualObjects(originalComplianceObject, testEventHandler.apiCompliance, @"New TextApiCompliance object not created after contextChanged flag set"); } - - - @end From 17f903d4c70efb164fa29534acc6766c74373de9 Mon Sep 17 00:00:00 2001 From: Darcy Wong Date: Wed, 21 Aug 2024 15:08:51 +0700 Subject: [PATCH 15/35] fix(android): Fix navigation arrows in Info Activity for RTL --- .../src/main/res/layout/activity_info.xml | 52 +++++++++++-------- 1 file changed, 29 insertions(+), 23 deletions(-) diff --git a/android/KMAPro/kMAPro/src/main/res/layout/activity_info.xml b/android/KMAPro/kMAPro/src/main/res/layout/activity_info.xml index 3b71e87178..314a503412 100644 --- a/android/KMAPro/kMAPro/src/main/res/layout/activity_info.xml +++ b/android/KMAPro/kMAPro/src/main/res/layout/activity_info.xml @@ -1,12 +1,12 @@ + xmlns:tools="http://schemas.android.com/tools" + xmlns:app="http://schemas.android.com/apk/res-auto" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="vertical" + android:background="@color/ms_white" + tools:context=".InfoActivity" > - - + android:orientation="horizontal"> - + + + + + Date: Wed, 21 Aug 2024 18:57:45 +0200 Subject: [PATCH 16/35] docs: refresh windows.md @keymanapp-test-bot skip --- docs/build/windows.md | 177 +++++++++++++++++------------------------- 1 file changed, 72 insertions(+), 105 deletions(-) diff --git a/docs/build/windows.md b/docs/build/windows.md index dcb55ce4a4..bb8ce8f0fe 100644 --- a/docs/build/windows.md +++ b/docs/build/windows.md @@ -63,10 +63,6 @@ Dependencies: * [Base](#base-dependencies) * [Windows Platform](#windows-platform-dependencies) -**Note**: Keyman for Windows is currently built together with Keyman Developer. -We are working on splitting these projects. For now, you will need the Keyman -Developer dependencies as well. - Building: * [Building Keyman for Windows](../../windows/src/README.md) @@ -75,7 +71,7 @@ Building: Dependencies: * [Base](#base-dependencies) * [Web](#web-dependencies) -* [Windows Platform](#windows-platform-dependencies) +* [Windows Platform](#windows-platform-dependencies) (optional, for Windows-only components) Building: * [Building Keyman Developer](../../windows/src/README.md) @@ -94,42 +90,19 @@ Building: **Dependencies**: * [Base](#base-dependencies) * [Web](#web-dependencies) - -**Additional requirements**: -* Android SDK -* Android Studio -* Ant -* Gradle -* Maven -* Optional: OpenJDK 11 (https://learn.microsoft.com/en-us/java/openjdk/download) - -```ps1 -# Elevated PowerShell -choco install android-sdk android-studio ant gradle maven -# optionally install sdk images -sdkmanager "system-images;android-33;google_apis;armeabi-v7a" -sdkmanager --update -sdkmanager --licenses -``` - -* Run Android Studio once after installation to install additional components - such as emulator images and SDK updates. - -**Required environment variables**: -* [`JAVA_HOME`](#java_home) - -**Optional environment variables**: -* [`JAVA_HOME_11`](#java_home) +* [Android](#android-dependencies) Building: * [Building Keyman for Android](../../android/README.md) -## Prerequisites +--- + +## Dependencies and Prerequisites Many dependencies are only required for specific projects. We prefer [Chocolatey](https://chocolatey.org/install) at present for -installation of dependencies. Chocolatey should be run in an elevated +installation of most dependencies. Chocolatey should be run in an elevated PowerShell. ### Base Dependencies @@ -155,11 +128,9 @@ refreshenv **Environment variables**: * [`KEYMAN_ROOT`](#keyman_root) -* `PATH`: add your Python scripts folder to your path: it will normally be `%appdata%\Python\Python310\Scripts`. ```bat SET KEYMAN_ROOT=c:\Projects\keyman\keyman -SET PATH=%path%;%appdata%\Python\Python310\Scripts ``` To check whether environment variables are set, run `SET ` in command @@ -181,31 +152,37 @@ You can use Windows Settings to add these environment variables permanently: * KeymanWeb **Requirements**: -* emscripten 3.1.46 or later -* node.js 18+ -* [openjdk 11](https://learn.microsoft.com/en-us/java/openjdk/download#openjdk-11)+ +* Emscripten +* node.js -```ps1 -# Elevated PowerShell +#### Emscripten -# for *much* faster download, hide progress bar (PowerShell/PowerShell#2138) -$ProgressPreference = 'SilentlyContinue' +In an appropriate folder, e.g. `/c/Projects/keyman/`, in bash, run the following commands: -choco install emscripten --version 3.1.46 +```bash +git clone https://github.com/emscripten-core/emsdk +cd emsdk +emsdk install 3.1.58 +emsdk activate 3.1.58 ``` Note: emscripten very unhelpfully overwrites JAVA_HOME, and adds its own -versions of Python, Node and Java to the PATH. For best results, go ahead -and remove those paths from your PATH variable before continuing. +versions of Python, Node and Java to the PATH. For best results, restart +your shell after installing Emscripten so that you don't end up with the +wrong versions. There is no need to add emscripten to the path in order to build Keyman. However, you should set the EMSCRIPTEN_BASE variable to the path where `emcc` can be found, but always in the upstream\emscripten subdirectory where you -installed emsdk (most likely %LocalAppData%\emsdk\upstream\emscripten) +installed emsdk. **Environment variables**: * `EMSCRIPTEN_BASE`: `\upstream\emscripten` +**Optional environment variables**: +* `KEYMAN_USE_EMSDK`: `1` to let the Keyman build scripts control the + version of Emscripten installed on your computer. + After installing emscripten, you'll need to install node.js and openjdk. #### node.js @@ -214,30 +191,17 @@ Our recommended way to install node.js is to use [nvm-windows](https://github.com/coreybutler/nvm-windows). This makes it easy to switch between versions of node.js. -Alternatively, use Powershell + Chocolatey to install node.js: - -```ps1 -# Elevated PowerShell - -# for *much* faster download, hide progress bar (PowerShell/PowerShell#2138) -$ProgressPreference = 'SilentlyContinue' -choco install nodejs +``` +nvm install 20.16.0 +nvm use 20.16.0 ``` -See [node.md](node.md) for more information. - -#### openjdk - -Use Powershell + Chocolatey to install OpenJDK: - -```ps1 -# Elevated PowerShell - -# for *much* faster download, hide progress bar (PowerShell/PowerShell#2138) -$ProgressPreference = 'SilentlyContinue' -choco install openjdk -``` +**Optional environment variables**: +* `KEYMAN_USE_NVM`: `1` to let the Keyman build scripts control the + version of node.js installed and active on your computer. +See [node.md](node.md) for more information, including automatic selection +of appropriate node versions during builds. ### Windows Platform Dependencies @@ -260,8 +224,7 @@ choco install openjdk Start Delphi IDE once after installation as it will create various environment files and take you through required registration. - * Note: It is possible to build all components that do _not_ require Delphi by - adding the environment variable `NODELPHI=1` before starting the build. + * Note: It is possible to build all components that do _not_ require Delphi. Currently many components are Delphi-based, but if you are working just in Keyman Core, the compiler, or Keyman Engine's C++ components, you may be able to get away without building them. In this situation, we recommend @@ -291,13 +254,8 @@ choco install openjdk Keyman's design-time packages to load in Delphi. * [`KEYMAN_CEF4DELPHI_ROOT`](#keyman_cef4delphi_root) -**Optional environment variables**: -* [`GIT_BASH_FOR_KEYMAN`](#git_bash_for_keyman) -* [`USERDEFINES`](#userdefines) - ```bat SET KEYMAN_CEF4DELPHI_ROOT=c:\Projects\keyman\CEF4Delphi_Binary -SET GIT_BASH_FOR_KEYMAN="C:\Program Files\Git\bin\bash.exe" --init-file "c:\Program Files\Git\etc\profile" -l ``` **Additional requirements for release builds**: @@ -314,6 +272,46 @@ choco install wixtoolset --version=3.11.1 git clone https://github.com/keymanapp/CEF4Delphi_Binary C:\Projects\keyman\CEF4Delphi_Binary ``` +### Android dependencies + +**Projects**: +* Keyman for Android + +**Requirements**: +* Android SDK +* Android Studio +* Ant +* Gradle +* Maven +* Optional: OpenJDK 11 (https://learn.microsoft.com/en-us/java/openjdk/download) + +```ps1 +# Elevated PowerShell +choco install android-sdk android-studio ant gradle maven +# optionally install sdk images +sdkmanager "system-images;android-33;google_apis;armeabi-v7a" +sdkmanager --update +sdkmanager --licenses +``` + +#### openjdk + +Use Powershell + Chocolatey to install OpenJDK: + +```ps1 +# Elevated PowerShell + +# for *much* faster download, hide progress bar (PowerShell/PowerShell#2138) +$ProgressPreference = 'SilentlyContinue' +choco install openjdk +``` + +* Run Android Studio once after installation to install additional components + such as emulator images and SDK updates. + +**Required environment variables**: +* [`JAVA_HOME`](#java_home) + ## Certificates In order to make a release build, you need to sign all the executables. See @@ -349,41 +347,10 @@ release build, the common/windows/cef-checkout.sh script will checkout the corre branch of the repository automatically and extract any compressed files found in it. -### GIT_BASH_FOR_KEYMAN - -This environment variable is optional: the build will run bash in a separate -window in order to build KeymanWeb if it isn't present, but you'll lose logging -and have the annoyance of a window popping up halfway through the build. To -resolve both of those issues, set the environment variable to: - -```bat -SET GIT_BASH_FOR_KEYMAN="C:\Program Files\Git\bin\bash.exe" --init-file "c:\Program Files\Git\etc\profile" -l -``` - -You should verify the install location of Git on your computer as it may vary. - -### USERDEFINES - -You can specify defines that will not be added to the git repository and will be -used in the build in the UserDefines.mak file in the root folder. This is used -mostly for code signing certificates. If not specified, a test certificate will -be used to sign executables when you build a release. - -To include UserDefines.mak in the build, use the command line parameter -`-DUSERDEFINES`. You can also set an environment variable `USERDEFINES=1` to get -the same result. - ### JAVA_HOME This environment variable tells Gradle what version of Java to use for building Keyman for Android. -**Multiple versions of Java:** If you need to build Keyman for Android 16.0 or older versions, you can set `JAVA_HOME_11` to the OpenJDK 11 path and `JAVA_HOME` to the OpenJDK 8 path. This will build both versions correctly from command line. But note that you do need to update your `JAVA_HOME` env var to the associated version before opening Android Studio and loading any Android projects. `JAVA_HOME_11` is mostly used by CI. - -```bat -SET JAVA_HOME="path to OpenJDK 8" -SET JAVA_HOME_11="path to OpenJDK 11" -``` - ## Optional Tools * sentry-cli (optional) From 002970d7cb750b00c38757e91978db27bdfa00de Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Wed, 21 Aug 2024 19:10:56 +0200 Subject: [PATCH 17/35] Update windows.md --- docs/build/windows.md | 115 +++++++++++++++++++++++------------------- 1 file changed, 63 insertions(+), 52 deletions(-) diff --git a/docs/build/windows.md b/docs/build/windows.md index bb8ce8f0fe..83839f91a1 100644 --- a/docs/build/windows.md +++ b/docs/build/windows.md @@ -127,22 +127,32 @@ refreshenv ``` **Environment variables**: -* [`KEYMAN_ROOT`](#keyman_root) + +If you pull the entire `keyman.git` repo to `c:\keyman`, then the paths by +default will work without changes. Otherwise, you will need to set an +environment variable `KEYMAN_ROOT` to the root path of the Keyman repo. For +example: ```bat -SET KEYMAN_ROOT=c:\Projects\keyman\keyman +SETX KEYMAN_ROOT "c:\Projects\keyman\keyman" ``` -To check whether environment variables are set, run `SET ` in command -prompt. +> [!NOTE] +> The `SETX` command will set persistent environment variables but they do not +> impact the current shell environment. Start a new shell to see the variables. -You can use Windows Settings to add these environment variables permanently: - -1. In Windows Search, type "environment" and select "Edit System Environment - Variables" -2. Click `Environment Variables...` -3. You can add or edit variables in either User or System settings, as you - prefer. +> [!TIP] +> +> To check whether environment variables are set, run `SET ` in command +> prompt. +> +> You can use Windows Settings to add these environment variables permanently: +> +> 1. In Windows Search, type "environment" and select "Edit System Environment +> Variables" +> 2. Click `Environment Variables...` +> 3. You can add or edit variables in either User or System settings, as you +> prefer. ### Web Dependencies @@ -177,11 +187,19 @@ can be found, but always in the upstream\emscripten subdirectory where you installed emsdk. **Environment variables**: -* `EMSCRIPTEN_BASE`: `\upstream\emscripten` + +```bat +SETX EMSCRIPTEN_BASE "\upstream\emscripten" +``` **Optional environment variables**: -* `KEYMAN_USE_EMSDK`: `1` to let the Keyman build scripts control the - version of Emscripten installed on your computer. + +To let the Keyman build scripts control the version of Emscripten +installed on your computer: + +```bat +SETX KEYMAN_USE_EMSDK 1 +``` After installing emscripten, you'll need to install node.js and openjdk. @@ -191,14 +209,19 @@ Our recommended way to install node.js is to use [nvm-windows](https://github.com/coreybutler/nvm-windows). This makes it easy to switch between versions of node.js. -``` +```bat nvm install 20.16.0 nvm use 20.16.0 ``` **Optional environment variables**: -* `KEYMAN_USE_NVM`: `1` to let the Keyman build scripts control the - version of node.js installed and active on your computer. + +To let the Keyman build scripts control the version of node.js installed +and active on your computer: + +```bat +SETX KEYMAN_USE_NVM 1 +```` See [node.md](node.md) for more information, including automatic selection of appropriate node versions during builds. @@ -252,10 +275,27 @@ of appropriate node versions during builds. * Add the C:\Projects\keyman\keyman\windows\lib folder in the Keyman repository to your `PATH` environment variable. This is required for Keyman's design-time packages to load in Delphi. -* [`KEYMAN_CEF4DELPHI_ROOT`](#keyman_cef4delphi_root) + +### KEYMAN_CEF4DELPHI_ROOT + +Keyman and Keyman Developer use Chromium Embedded Framework. The source repo is +at https://github.com/keymanapp/CEF4Delphi. In order to build the installers, we +need to source the binary files from the +https://github.com/keymanapp/CEF4Delphi_binary repo. The +`KEYMAN_CEF4DELPHI_ROOT` environment variable should be set to the root of this +repo on your local machine. + +The version of CEF in use is determined by CEF_VERSION.md. This maps to a branch +prefixed with `v` e.g. `v89.0.18` in the CEF4Delphi_binary repository. During a +release build, the common/windows/cef-checkout.sh script will checkout the correct +branch of the repository automatically and extract any compressed files found in +it. + +The [`KEYMAN_CEF4DELPHI_ROOT`](#keyman_cef4delphi_root) variable is +used to specify the path to the CEF4Delphi binaries. ```bat -SET KEYMAN_CEF4DELPHI_ROOT=c:\Projects\keyman\CEF4Delphi_Binary +SETX KEYMAN_CEF4DELPHI_ROOT "c:\Projects\keyman\CEF4Delphi_Binary" ``` **Additional requirements for release builds**: @@ -309,8 +349,11 @@ choco install openjdk * Run Android Studio once after installation to install additional components such as emulator images and SDK updates. + ## Certificates @@ -319,38 +362,6 @@ In order to make a release build, you need to sign all the executables. See for details on how to create test code signing certificates or specify your own certificates for the build. -## Notes on Environment Variables - -### KEYMAN_ROOT - -If you pull the entire `keyman.git` repo to `c:\keyman`, then the paths by -default will work without changes. Otherwise, you will need to set an -environment variable `KEYMAN_ROOT` to the root path of the Keyman repo. For -example: - -```bat -SET KEYMAN_ROOT=c:\projects\keyman\keyman -``` - -### KEYMAN_CEF4DELPHI_ROOT - -Keyman and Keyman Developer use Chromium Embedded Framework. The source repo is -at https://github.com/keymanapp/CEF4Delphi. In order to build the installers, we -need to source the binary files from the -https://github.com/keymanapp/CEF4Delphi_binary repo. The -`KEYMAN_CEF4DELPHI_ROOT` environment variable should be set to the root of this -repo on your local machine. - -The version of CEF in use is determined by CEF_VERSION.md. This maps to a branch -prefixed with `v` e.g. `v89.0.18` in the CEF4Delphi_binary repository. During a -release build, the common/windows/cef-checkout.sh script will checkout the correct -branch of the repository automatically and extract any compressed files found in -it. - -### JAVA_HOME - -This environment variable tells Gradle what version of Java to use for building Keyman for Android. - ## Optional Tools * sentry-cli (optional) From b87b107966dab09840bab8503f58dd54355767c5 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Wed, 21 Aug 2024 22:12:00 +0200 Subject: [PATCH 18/35] Update windows.md --- docs/build/windows.md | 47 +++++++++++++++++++++++-------------------- 1 file changed, 25 insertions(+), 22 deletions(-) diff --git a/docs/build/windows.md b/docs/build/windows.md index 83839f91a1..47b3e8696d 100644 --- a/docs/build/windows.md +++ b/docs/build/windows.md @@ -6,13 +6,13 @@ On Windows, you can build the following projects: * [Keyman for Android](#keyman-for-android) * [Keyman for Windows](#keyman-for-windows) -* [Keyman Developer](#keyman-developer) (together with Keyman for Windows) +* [Keyman Developer](#keyman-developer) * [KeymanWeb](#keymanweb) The following libraries can also be built: -* Keyman Core (Windows, wasm targets) (aka core) -* Common/Web +* Keyman Core (Windows, wasm targets) +* Common libraries The following projects **cannot** be built on Windows: @@ -123,7 +123,6 @@ PowerShell. # for *much* faster download, hide progress bar (PowerShell/PowerShell#2138) $ProgressPreference = 'SilentlyContinue' choco install git jq python ninja pandoc meson -refreshenv ``` **Environment variables**: @@ -146,7 +145,8 @@ SETX KEYMAN_ROOT "c:\Projects\keyman\keyman" > To check whether environment variables are set, run `SET ` in command > prompt. > -> You can use Windows Settings to add these environment variables permanently: +> You can alternatively use Windows Settings to add these environment variables +> permanently: > > 1. In Windows Search, type "environment" and select "Edit System Environment > Variables" @@ -167,24 +167,26 @@ SETX KEYMAN_ROOT "c:\Projects\keyman\keyman" #### Emscripten -In an appropriate folder, e.g. `/c/Projects/keyman/`, in bash, run the following commands: +In bash, run the following commands: ```bash +cd /c/Projects/keyman git clone https://github.com/emscripten-core/emsdk cd emsdk emsdk install 3.1.58 emsdk activate 3.1.58 ``` -Note: emscripten very unhelpfully overwrites JAVA_HOME, and adds its own -versions of Python, Node and Java to the PATH. For best results, restart -your shell after installing Emscripten so that you don't end up with the -wrong versions. +> ![WARNING] +> Emscripten very unhelpfully overwrites `JAVA_HOME`, and adds its own +> versions of Python, Node and Java to the `PATH`. For best results, restart +> your shell after installing Emscripten so that you don't end up with the +> wrong versions. There is no need to add emscripten to the path in order to build Keyman. -However, you should set the EMSCRIPTEN_BASE variable to the path where `emcc` -can be found, but always in the upstream\emscripten subdirectory where you -installed emsdk. +However, you should set the `EMSCRIPTEN_BASE` variable to the path where `emcc` +can be found, in the `upstream\emscripten` subdirectory of where you installed +emsdk. **Environment variables**: @@ -259,10 +261,12 @@ of appropriate node versions during builds. ```ps1 choco install visualstudio2019community visualstudio2019-workload-nativedesktop visualstudio2019buildtools ``` + * Verify required build tools are installed * Run `Visual Studio Installer` * Check the `Individual components` tab - * Verify `MSVC v142 - VS 2019 c++ x64/x86 build tools (Latest)` is installed. If not, install it. + * Verify `MSVC v142 - VS 2019 c++ x64/x86 build tools (Latest)` is installed. + If not, install it. Recommended: configure Visual Studio to use two-space tab stops: 1. Open the options dialog: Tools > Options. @@ -272,7 +276,7 @@ of appropriate node versions during builds. **Required environment variables**: * `PATH` - * Add the C:\Projects\keyman\keyman\windows\lib folder in the Keyman + * Add the `C:\Projects\keyman\keyman\windows\lib` folder in the Keyman repository to your `PATH` environment variable. This is required for Keyman's design-time packages to load in Delphi. @@ -327,7 +331,12 @@ git clone https://github.com/keymanapp/CEF4Delphi_Binary C:\Projects\keyman\CEF4 ```ps1 # Elevated PowerShell -choco install android-sdk android-studio ant gradle maven +choco install android-sdk androidstudio ant gradle maven +``` + +Start a new shell to get the new paths and then update Android SDKs: + +```ps1 # optionally install sdk images sdkmanager "system-images;android-33;google_apis;armeabi-v7a" sdkmanager --update @@ -349,12 +358,6 @@ choco install openjdk * Run Android Studio once after installation to install additional components such as emulator images and SDK updates. - - ## Certificates In order to make a release build, you need to sign all the executables. See From f0dbcd639330416cbe20789f45fed0b998541825 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Thu, 22 Aug 2024 09:28:21 +0200 Subject: [PATCH 19/35] Update windows.md --- docs/build/windows.md | 47 +++++++++++++++++++++++++------------------ 1 file changed, 27 insertions(+), 20 deletions(-) diff --git a/docs/build/windows.md b/docs/build/windows.md index 47b3e8696d..663b68c2f8 100644 --- a/docs/build/windows.md +++ b/docs/build/windows.md @@ -203,8 +203,6 @@ installed on your computer: SETX KEYMAN_USE_EMSDK 1 ``` -After installing emscripten, you'll need to install node.js and openjdk. - #### node.js Our recommended way to install node.js is to use @@ -327,32 +325,41 @@ git clone https://github.com/keymanapp/CEF4Delphi_Binary C:\Projects\keyman\CEF4 * Ant * Gradle * Maven -* Optional: OpenJDK 11 (https://learn.microsoft.com/en-us/java/openjdk/download) +* JDK 11 (Temurin11) -```ps1 -# Elevated PowerShell -choco install android-sdk androidstudio ant gradle maven -``` +#### JDK 11 -Start a new shell to get the new paths and then update Android SDKs: - -```ps1 -# optionally install sdk images -sdkmanager "system-images;android-33;google_apis;armeabi-v7a" -sdkmanager --update -sdkmanager --licenses -``` - -#### openjdk - -Use Powershell + Chocolatey to install OpenJDK: +Use Powershell + Chocolatey to install JDK 11: ```ps1 # Elevated PowerShell # for *much* faster download, hide progress bar (PowerShell/PowerShell#2138) $ProgressPreference = 'SilentlyContinue' -choco install openjdk +choco install temurin11 +``` + +**Multiple versions of Java:** If you need to build Keyman for Android 16.0 or +older versions, you can set `JAVA_HOME_11` to the JDK 11 path and +`JAVA_HOME` to the JDK 8 path. This will build both versions correctly +from command line. But note that you do need to update your `JAVA_HOME` env +var to the associated version before opening Android Studio and loading any +Android projects. `JAVA_HOME_11` is mostly used by CI. + +#### Android Studio and friends + +```ps1 +# Elevated PowerShell +choco install androidstudio ant gradle maven android-sdk +``` + +Start a new shell to get the new paths and then update Android SDKs: + +```ps1 +# optionally install sdk images +sdkmanager --update +# sdkmanager "system-images;android-33;google_apis;armeabi-v7a" +sdkmanager --licenses ``` * Run Android Studio once after installation to install additional components From 012bbb4c69860caf9a139f25d08277fcbfb9dc83 Mon Sep 17 00:00:00 2001 From: Darcy Wong Date: Thu, 22 Aug 2024 14:24:16 +0700 Subject: [PATCH 20/35] fix(android): Add RTL assets for adjusting keyboard height menu --- .../main/res/drawable-ldrtl-hdpi/blank_osk.png | Bin 0 -> 8973 bytes .../res/drawable-ldrtl-land-hdpi/blank_osk.png | Bin 0 -> 9879 bytes .../drawable-ldrtl-sw600dp-land/blank_osk.png | Bin 0 -> 9268 bytes .../res/drawable-ldrtl-sw600dp/blank_osk.png | Bin 0 -> 8726 bytes .../drawable-ldrtl-sw720dp-land/blank_osk.png | Bin 0 -> 9281 bytes .../res/drawable-ldrtl-sw720dp/blank_osk.png | Bin 0 -> 8808 bytes 6 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 android/KMAPro/kMAPro/src/main/res/drawable-ldrtl-hdpi/blank_osk.png create mode 100644 android/KMAPro/kMAPro/src/main/res/drawable-ldrtl-land-hdpi/blank_osk.png create mode 100644 android/KMAPro/kMAPro/src/main/res/drawable-ldrtl-sw600dp-land/blank_osk.png create mode 100644 android/KMAPro/kMAPro/src/main/res/drawable-ldrtl-sw600dp/blank_osk.png create mode 100644 android/KMAPro/kMAPro/src/main/res/drawable-ldrtl-sw720dp-land/blank_osk.png create mode 100644 android/KMAPro/kMAPro/src/main/res/drawable-ldrtl-sw720dp/blank_osk.png diff --git a/android/KMAPro/kMAPro/src/main/res/drawable-ldrtl-hdpi/blank_osk.png b/android/KMAPro/kMAPro/src/main/res/drawable-ldrtl-hdpi/blank_osk.png new file mode 100644 index 0000000000000000000000000000000000000000..c5d555cacaebe0de05655e9c94b7b165390d5b36 GIT binary patch literal 8973 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 literal 0 HcmV?d00001 diff --git a/android/KMAPro/kMAPro/src/main/res/drawable-ldrtl-land-hdpi/blank_osk.png b/android/KMAPro/kMAPro/src/main/res/drawable-ldrtl-land-hdpi/blank_osk.png new file mode 100644 index 0000000000000000000000000000000000000000..3e41a359a03b58db80c1c62c895e5f327de53e58 GIT binary patch literal 9879 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 Z{{5rYrFPfpRMQSlC@ZPnK`T7*|357?>;?b; literal 0 HcmV?d00001 diff --git a/android/KMAPro/kMAPro/src/main/res/drawable-ldrtl-sw600dp-land/blank_osk.png b/android/KMAPro/kMAPro/src/main/res/drawable-ldrtl-sw600dp-land/blank_osk.png new file mode 100644 index 0000000000000000000000000000000000000000..282606a9d509fadbeeb4706725b947b72ee0afbd GIT binary patch literal 9268 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 QLH~t@iq_rYJ5PiE14n|qQUCw| literal 0 HcmV?d00001 diff --git a/android/KMAPro/kMAPro/src/main/res/drawable-ldrtl-sw600dp/blank_osk.png b/android/KMAPro/kMAPro/src/main/res/drawable-ldrtl-sw600dp/blank_osk.png new file mode 100644 index 0000000000000000000000000000000000000000..8246a641687a092571b1046ad5296621c2efb50c GIT binary patch literal 8726 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 literal 0 HcmV?d00001 From f082ddc0708b88b7c5568ce1d69d95f77c09a2c0 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Thu, 22 Aug 2024 13:20:52 +0200 Subject: [PATCH 21/35] chore(common): adjust build settings for windows clean builds --- common/windows/.gitignore | 1 + .../delphi/components/common_components.dproj | 63 ++++-------------- .../ext/cef4delphi/packages/CEF4Delphi.res | Bin 708 -> 0 bytes .../delphi/tools/certificates/build.sh | 2 + docs/build/linux-ubuntu.md | 26 ++++++-- docs/build/macos.md | 36 ++++++++-- docs/minimum-versions.md | 3 +- windows/src/.gitignore | 5 ++ windows/src/README.md | 6 +- windows/src/desktop/kmshell/kmshell.res | Bin 7036 -> 0 bytes windows/src/engine/keyman/build.sh | 1 + 11 files changed, 75 insertions(+), 68 deletions(-) delete mode 100644 common/windows/delphi/ext/cef4delphi/packages/CEF4Delphi.res delete mode 100644 windows/src/desktop/kmshell/kmshell.res diff --git a/common/windows/.gitignore b/common/windows/.gitignore index 7af23e7e1a..a6cb808a34 100644 --- a/common/windows/.gitignore +++ b/common/windows/.gitignore @@ -7,3 +7,4 @@ delphi/**/*.~* delphi/**/__recovery/ delphi/**/__history/ delphi/general/keymanversion_build.inc +delphi/ext/cef4delphi/packages/CEF4Delphi.res diff --git a/common/windows/delphi/components/common_components.dproj b/common/windows/delphi/components/common_components.dproj index 2bd91473ab..4ecda90464 100644 --- a/common/windows/delphi/components/common_components.dproj +++ b/common/windows/delphi/components/common_components.dproj @@ -13,31 +13,6 @@ true - - true - Base - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - true Base @@ -59,6 +34,12 @@ Base true + + true + Cfg_2 + true + true + .\obj\$(Platform)\$(Config) .\$(Platform)\$(Config) @@ -77,23 +58,6 @@ 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= - - None - android-support-v4.dex.jar;cloud-messaging.dex.jar;com-google-android-gms.play-services-ads-base.17.2.0.dex.jar;com-google-android-gms.play-services-ads-identifier.16.0.0.dex.jar;com-google-android-gms.play-services-ads-lite.17.2.0.dex.jar;com-google-android-gms.play-services-ads.17.2.0.dex.jar;com-google-android-gms.play-services-analytics-impl.16.0.8.dex.jar;com-google-android-gms.play-services-analytics.16.0.8.dex.jar;com-google-android-gms.play-services-base.16.0.1.dex.jar;com-google-android-gms.play-services-basement.16.2.0.dex.jar;com-google-android-gms.play-services-gass.17.2.0.dex.jar;com-google-android-gms.play-services-identity.16.0.0.dex.jar;com-google-android-gms.play-services-maps.16.1.0.dex.jar;com-google-android-gms.play-services-measurement-base.16.4.0.dex.jar;com-google-android-gms.play-services-measurement-sdk-api.16.4.0.dex.jar;com-google-android-gms.play-services-stats.16.0.1.dex.jar;com-google-android-gms.play-services-tagmanager-v4-impl.16.0.8.dex.jar;com-google-android-gms.play-services-tasks.16.0.1.dex.jar;com-google-android-gms.play-services-wallet.16.0.1.dex.jar;com-google-firebase.firebase-analytics.16.4.0.dex.jar;com-google-firebase.firebase-common.16.1.0.dex.jar;com-google-firebase.firebase-iid-interop.16.0.1.dex.jar;com-google-firebase.firebase-iid.17.1.1.dex.jar;com-google-firebase.firebase-measurement-connector.17.0.1.dex.jar;com-google-firebase.firebase-messaging.17.5.0.dex.jar;fmx.dex.jar;google-play-billing.dex.jar;google-play-licensing.dex.jar - - - None - android-support-v4.dex.jar;cloud-messaging.dex.jar;com-google-android-gms.play-services-ads-base.17.2.0.dex.jar;com-google-android-gms.play-services-ads-identifier.16.0.0.dex.jar;com-google-android-gms.play-services-ads-lite.17.2.0.dex.jar;com-google-android-gms.play-services-ads.17.2.0.dex.jar;com-google-android-gms.play-services-analytics-impl.16.0.8.dex.jar;com-google-android-gms.play-services-analytics.16.0.8.dex.jar;com-google-android-gms.play-services-base.16.0.1.dex.jar;com-google-android-gms.play-services-basement.16.2.0.dex.jar;com-google-android-gms.play-services-gass.17.2.0.dex.jar;com-google-android-gms.play-services-identity.16.0.0.dex.jar;com-google-android-gms.play-services-maps.16.1.0.dex.jar;com-google-android-gms.play-services-measurement-base.16.4.0.dex.jar;com-google-android-gms.play-services-measurement-sdk-api.16.4.0.dex.jar;com-google-android-gms.play-services-stats.16.0.1.dex.jar;com-google-android-gms.play-services-tagmanager-v4-impl.16.0.8.dex.jar;com-google-android-gms.play-services-tasks.16.0.1.dex.jar;com-google-android-gms.play-services-wallet.16.0.1.dex.jar;com-google-firebase.firebase-analytics.16.4.0.dex.jar;com-google-firebase.firebase-common.16.1.0.dex.jar;com-google-firebase.firebase-iid-interop.16.0.1.dex.jar;com-google-firebase.firebase-iid.17.1.1.dex.jar;com-google-firebase.firebase-measurement-connector.17.0.1.dex.jar;com-google-firebase.firebase-messaging.17.5.0.dex.jar;fmx.dex.jar;google-play-billing.dex.jar;google-play-licensing.dex.jar - - - None - - - None - - - None - Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) Debug @@ -113,6 +77,7 @@ false true 1033 + ..\..\lib false @@ -120,6 +85,11 @@ 0 0 + + ..\..\lib + true + 1033 + MainSource @@ -164,8 +134,6 @@ common_components.dpk - File c:\projects\keyman\app\windows\lib\DCPdelphi2009.bpl not found - File c:\projects\keyman\app\windows\lib\delphiprojectmanager.bpl not found Microsoft Office 2000 Sample Automation Server Wrapper Components Microsoft Office XP Sample Automation Server Wrapper Components @@ -944,13 +912,6 @@ - False - False - False - False - False - False - False True False diff --git a/common/windows/delphi/ext/cef4delphi/packages/CEF4Delphi.res b/common/windows/delphi/ext/cef4delphi/packages/CEF4Delphi.res deleted file mode 100644 index b9b013c2123fcf20e24680fc5ad3191fc452d216..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 708 zcmZ{i&q~8U5XQgO9IRfvd-32|A_PGYr5Gy(ZKal8CDvLCZBo*D^K>y3I?ZFSY*+-7ZI zn|uX7zmnlg4!>VHuVjSY^LM3BE^6>Cm209@W7sB|Y6NqtS7ii#xR_9pLY<=#HCRQV zcES4i0hnA1&>2XRQ=JgwRXWo?@y5G!v8fU=by#PdrE7RwFvpyxn(GZNlM?p;d!`q? zYY4tVZO28fzIEJYm76v8bV!XQW=uw_txZKHL-Nn)XTuv$k<~^sAYF^v$mc7QyTSm`Py^eJ3Ubc@nVYUlqm#pzNg71JYrVF$v_UP_TP4(gG W@|W(hn(Vhszt2x7<^TWN;c5kN0bbt# diff --git a/common/windows/delphi/tools/certificates/build.sh b/common/windows/delphi/tools/certificates/build.sh index 378723a125..10ab4c75ce 100755 --- a/common/windows/delphi/tools/certificates/build.sh +++ b/common/windows/delphi/tools/certificates/build.sh @@ -21,6 +21,8 @@ builder_describe_outputs \ function do_certificates() { rm -f KeymanTestCA-sha1.* KeymanTest-sha1.* KeymanTest-sha256.* KeymanTestCA-sha256.* + source "$KEYMAN_ROOT/resources/build/win/visualstudio_environment.inc.sh" + makecert -r -pe -n "CN=Keyman Test CA SHA1" -ss CA -sr CurrentUser -a sha1 -cy authority -sky signature -sv KeymanTestCA-sha1.pvk KeymanTestCA-sha1.cer certutil -user -addstore Root KeymanTestCA-sha1.cer makecert -pe -n "CN=Keyman Test Certificate SHA1" -a sha1 -cy end -sky signature -ic KeymanTestCA-sha1.cer -iv KeymanTestCA-sha1.pvk -sv KeymanTest-sha1.pvk KeymanTest-sha1.cer diff --git a/docs/build/linux-ubuntu.md b/docs/build/linux-ubuntu.md index 0107491dda..a45d9390ba 100644 --- a/docs/build/linux-ubuntu.md +++ b/docs/build/linux-ubuntu.md @@ -63,17 +63,33 @@ See [node.md](node.md) for more information. #### Emscripten -You'll also have to install `emscripten` (version 3.1.44 is known to work): +You'll also have to install `emscripten`: ```shell git clone https://github.com/emscripten-core/emsdk.git cd emsdk -./emsdk install 3.1.44 -./emsdk activate 3.1.44 -export EMSCRIPTEN_BASE=$(pwd)/upstream/emscripten +./emsdk install 3.1.58 +./emsdk activate 3.1.58 +export EMSCRIPTEN_BASE="$(pwd)/upstream/emscripten" +echo "export EMSCRIPTEN_BASE=\"$EMSCRIPTEN_BASE\"" >> .bashrc ``` -**NOTE:** Don't put EMSDK on the path, i.e. don't source `emsdk_env.sh`. +> ![WARNING] +> Don't put EMSDK on the path, i.e. don't source `emsdk_env.sh`. +> +> Emscripten very unhelpfully overwrites `JAVA_HOME`, and adds its own +> versions of Python, Node and Java to the `PATH`. For best results, restart +> your shell after installing Emscripten so that you don't end up with the +> wrong versions. + +**Optional environment variables**: + +To let the Keyman build scripts control the version of Emscripten installed on +your computer: + +```shell +export KEYMAN_USE_EMSDK=1 +``` ## Keyman Core diff --git a/docs/build/macos.md b/docs/build/macos.md index 81b1bcd0e7..25b0c1f82a 100644 --- a/docs/build/macos.md +++ b/docs/build/macos.md @@ -91,16 +91,38 @@ See [node.md](node.md) for more information. ### emscripten -To install emscripten: +The recommended way to install emscripten is with the official method, as that +then allows the build scripts to select the appropriate version automatically. -```shell -brew install emscripten +To install emscripten, `cd` to an appropriate path, and then: + +```bash +git clone https://github.com/emscripten-core/emsdk +cd emsdk +emsdk install 3.1.58 +emsdk activate 3.1.58 +export EMSCRIPTEN_BASE="$(pwd)/upstream/emscripten" +echo "export EMSCRIPTEN_BASE=\"$EMSCRIPTEN_BASE\"" >> .bashrc ``` -Note: if you install emscripten with brew on macOS, only emscripten binaries are -added to the path via symlinks. This makes it reasonably safe to have emscripten -on the path, unlike on other platforms where emscripten also ends up adding its -versions of node, python, and other binaries to the path. +You will want to add `EMSCRIPTEN_BASE` to your .bashrc. + +> ![WARNING] +> Don't put EMSDK on the path, i.e. don't source `emsdk_env.sh`. +> +> Emscripten very unhelpfully overwrites `JAVA_HOME`, and adds its own +> versions of Python, Node and Java to the `PATH`. For best results, restart +> your shell after installing Emscripten so that you don't end up with the +> wrong versions. + +**Optional environment variables**: + +To let the Keyman build scripts control the version of Emscripten installed on +your computer: + +```shell +export KEYMAN_USE_EMSDK=1 +``` ## Keyman for iOS Dependencies diff --git a/docs/minimum-versions.md b/docs/minimum-versions.md index a9a2ead26b..f582632007 100644 --- a/docs/minimum-versions.md +++ b/docs/minimum-versions.md @@ -49,7 +49,6 @@ https://help.keyman.com/developer/engine/android/latest-version/ | KEYMAN Variable | Value | |-----------------------------------|--------------| | KEYMAN_DEFAULT_VERSION_UBUNTU_CONTAINER | noble | -| KEYMAN_MAX_VERSION_EMSCRIPTEN | 3.1.58 | | KEYMAN_MIN_TARGET_VERSION_ANDROID | 5 | | KEYMAN_MIN_TARGET_VERSION_CHROME | 95.0 | | KEYMAN_MIN_TARGET_VERSION_IOS | 12.2 | @@ -58,7 +57,7 @@ https://help.keyman.com/developer/engine/android/latest-version/ | KEYMAN_MIN_TARGET_VERSION_WINDOWS | 10 | | KEYMAN_MIN_VERSION_ANDROID_SDK | 21 | | KEYMAN_MIN_VERSION_CPP | 17 | -| KEYMAN_MIN_VERSION_EMSCRIPTEN | 3.1.44 | +| KEYMAN_MIN_VERSION_EMSCRIPTEN | 3.1.58 | | KEYMAN_MIN_VERSION_MESON | 1.0.0 | | KEYMAN_MIN_VERSION_NODE_MAJOR | 20 | | KEYMAN_MIN_VERSION_NPM | 10.5.1 | diff --git a/windows/src/.gitignore b/windows/src/.gitignore index 350b7e4bdb..065f4a07f3 100644 --- a/windows/src/.gitignore +++ b/windows/src/.gitignore @@ -34,3 +34,8 @@ keyman-windows-coverity.tgz # This file is still generated by devtools. TODO: eliminate in future PathDefines.mak + +# .res files, generated during build +desktop/kmshell/kmshell.res +engine/keyman/keyman.res +engine/keyman32/version64.res diff --git a/windows/src/README.md b/windows/src/README.md index 1d057482bb..ae0090c340 100644 --- a/windows/src/README.md +++ b/windows/src/README.md @@ -45,8 +45,8 @@ build, you will need to obtain valid code signing certificates. See Certificates, below. Official release builds for Keyman are built in the Keyman project's CI environment. -1. Start 'Developer Command Prompt for VS 2019'. -2. Run `nmake release` from the **windows/src** folder. +1. Start bash +2. Run `./build.sh :publish` from the **windows/src** folder. 3. Artifacts from a successful build will be placed in **windows/release** folder. 4. **buildtools/help-keyman-com.sh** will push updated documentation to @@ -65,7 +65,7 @@ globally trusted. The environment variables `SC_PFX_SHA1` and `SC_PFX_SHA256` can be set to custom certificate paths. The Keyman repo can build test certificates for you. To build your own, run -`./build.sh certificates` from **common/windows/delphi/tools/certificates** to +`./common/windows/delphi/tools/certificates/build.sh certificates` to build and install your own local root CA "**KeymanTestCA**" certificates. If you specify a password for the certificate, you'll need to set that in the environment variable `SC_PWD`. diff --git a/windows/src/desktop/kmshell/kmshell.res b/windows/src/desktop/kmshell/kmshell.res deleted file mode 100644 index cfcbd309f137d6a5f5221aba48a1c759c0d56682..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7036 zcmeI1J!~7v6~~`s1u|_|P!*hAZ5EMn2(S`ACF(%RC)jrp6@LgheU!nHyOao#yBjVg zo)iR7mlS_n#!2}n!$--QQ1 zw}VKUad-O3=WLJru871Gadh$=T@Rj&BMP$9%qGz<#XB(zRY#^=#HP2+AL{#8-^a+g zf^j_WLSsz~4mQ`s$Iu3GG1DW)BRWJoD6BQh1`+Me%6}DUhy#9^LSC{pCb2-($ePa zZ9otyYiV#E4^IxM{`WtNd~z23bT;zJ4G&4J|JS2Gef1U9>K^T%d9+#cX!*#asRNIO zcHqU=_6gDYQ=;rcqG^{XIzzQ{@W`jJv-NeiQsM z_$ly1U`1r$2|R(v`XhWM&%qyq-vz$~-UYt^ehz$wPACmN0)7bmRq%E2XW(n#kH8;* z-vPe^ejEHc_$>Ho@KNv{cn`b>-UIJ}_rUY(1h1!fJ;ck!Yew*O@Mqv_;E%u`falS7 zKyQOy2b~2y4LXYP&%qyq-vz$~-UYt^ehz#Fd>VWN{1Eu7;4$w0KKM=W%iyQL4}mA} zo!LRw&cPpp-vz$~-UYt^ehz#Fd>Yw|Ae%$T=2h@@@Mqv_;E%u`fZqYX1AZI)I`}O3 zY4B0-9(WJD2i^nkf%m{8pc4f26mQo0sOlYRP*ZK&%oEf zAAvsrkK}YoPz{OL$F+%T8P^o9Aza-O^!DvrdiClRy?ptSUc7ig&!0c1Cr_Tx&dv@! ze*BoWx3}s3{rj}OzD|~9Q8t^U`T2R8o}Q+Oi3y5EqjdfHb-H%#8Vw8#U`4c-VOfZN zE(-Z(y)HYXO?4E}A#7pF4z{I{Y*jMr?`Us zY(susqo=cM;7b^N_#ze+?r8p?{S4lsgs`EZ@ZQE{&$o%%><9gh1bm&aqqXo4cn=hS z)FJzTuvzv2VGCITY)e@JZ2PhRU_<7e)2VU{up#?4V%Q6bxuuR6_Co9(=vCUo1`Hef zF#OTL-YaZ4umW3d&;$lHo%W)If?n9pz-h0-8#d#x>Gf%^Dkk7jAhWIT45ASB>t0m= zY(o}y06-SD53nq439u|}IR(qU&47@78-VZ*bi^R#Kvzk4L-*h2pG@@^95EC`BhPhx zBChVA19=|VkeGai59g5&=Mi2%AI>8m&Li?0;oW!tfZ|udIYpjUaNdvylmOx(0!f}{ z+H^jBv;%Ga!QrH3gjQY3?IX14f!qc(^`_hkH1t-v1qk$Zxe54sr`!OfE@l6W#V4&s z9)#|D3;m6_LzjtSJs7-07Xb7?mS?!8zZikv5OH|p0qbvsCFkc}RvR+w9GK{3)z<~U z9Qz3!wJ+m5hqE4&@d{=O19uh50_hB@aQZzmcYHd|4_gt7h3P*j8GN42M<4v~spluolzm z-0bICQdQiFZW(&fw#>A;X1eN)i7S^8@5P1ReA{footf3x_YM+MG4qv6ijp!+$FvMYx;6o`rK2+G z$0hrr1c7FNR|=Ii!Lv_g&A|gz3sx+uHaac6gw8v`0}L+|EW@t4!#C|x$+oncwpA(H zMYrkD$ld60m|soBS;-a)x!;&;v-YxyOqtGb)9R*{o( z^I;Wbr7)S}=S{15z37@v$$wl-Fw&TzbNbn z+zI8%rBF(D9K4$t$F@XADD?|Xn_V)M%q=Br7VWBnmBN7ODqt0N#c}L%MakP`#a~3q zd;uRNMbi*fD3tOE)42DAk}=ZiAIxYt5{W0qv`8X8s>Nfugr+C*rWOt-4bwDZMl2ux zqdM~5(~otZI+lpUlG$-xOBmyrI-fPPq!~3dJsOXPqtQfuJf`#1BJdyn;K}YY$MtAF znlxitB9O># zM6+5lW`y&jM%d8De$3pFaQCT`W;j2lN1|FbpN%2mW>Q1?6Iwi(HxgkzlF-LR!b71D zufCCv<(C?1Tc*6sM}jXp7}ytxQsR665`MS6jh$u|e^a@Kzk%IBYZCRZ@z Date: Thu, 22 Aug 2024 13:26:56 +0200 Subject: [PATCH 22/35] Update windows.md --- docs/build/windows.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/build/windows.md b/docs/build/windows.md index 663b68c2f8..3168bcd0ae 100644 --- a/docs/build/windows.md +++ b/docs/build/windows.md @@ -272,6 +272,10 @@ of appropriate node versions during builds. 3. Change 'Tab size' to 2 and 'Indent size' to 2. 4. Select 'Insert spaces'. +* Windows SDK (C++ Desktop Development) + + https://developer.microsoft.com/en-us/windows/downloads/windows-sdk/ + **Required environment variables**: * `PATH` * Add the `C:\Projects\keyman\keyman\windows\lib` folder in the Keyman From 5fb374341677db19b0b48c6503ef9cd4e050bb47 Mon Sep 17 00:00:00 2001 From: Keyman Build Agent Date: Thu, 22 Aug 2024 14:02:35 -0400 Subject: [PATCH 23/35] auto: increment master version to 18.0.96 --- HISTORY.md | 4 ++++ VERSION.md | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 7bb236717b..2ee27cd198 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,9 @@ # Keyman Version History +## 18.0.95 alpha 2024-08-22 + +* chore(common): allow build agents to automatically select emsdk version, and enable support for 3.1.60+ (#12243) + ## 18.0.94 alpha 2024-08-21 * fix(core): look for `emcc` instead of `emcc.py` (#12235) diff --git a/VERSION.md b/VERSION.md index a41e5425c0..998f9bf6fd 100644 --- a/VERSION.md +++ b/VERSION.md @@ -1 +1 @@ -18.0.95 \ No newline at end of file +18.0.96 \ No newline at end of file From d461c4872a43aa7b16abc08cc1abd78a8a2ea9aa Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Fri, 23 Aug 2024 07:01:33 +0200 Subject: [PATCH 24/35] chore(common): use `npm install` in emsdk update --- resources/locate_emscripten.inc.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/resources/locate_emscripten.inc.sh b/resources/locate_emscripten.inc.sh index f678e8449e..f20ac5d0e9 100644 --- a/resources/locate_emscripten.inc.sh +++ b/resources/locate_emscripten.inc.sh @@ -69,5 +69,6 @@ _select_emscripten_version_with_emsdk() { git pull ./emsdk install "$KEYMAN_MIN_VERSION_EMSCRIPTEN" ./emsdk activate "$KEYMAN_MIN_VERSION_EMSCRIPTEN" + npm install popd > /dev/null } From 47b952f9609594c86c2c050d6b3bd6aad03dbfb3 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Fri, 23 Aug 2024 07:10:48 +0200 Subject: [PATCH 25/35] chore(common): npm install should be in emscripten folder --- resources/locate_emscripten.inc.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/resources/locate_emscripten.inc.sh b/resources/locate_emscripten.inc.sh index f20ac5d0e9..3d470f7577 100644 --- a/resources/locate_emscripten.inc.sh +++ b/resources/locate_emscripten.inc.sh @@ -69,6 +69,7 @@ _select_emscripten_version_with_emsdk() { git pull ./emsdk install "$KEYMAN_MIN_VERSION_EMSCRIPTEN" ./emsdk activate "$KEYMAN_MIN_VERSION_EMSCRIPTEN" + cd upstream/emscripten npm install popd > /dev/null } From 046bd25f63fa2b1a6dab9f4f7963b56bba372217 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Fri, 23 Aug 2024 07:47:53 +0200 Subject: [PATCH 26/35] chore(developer): improve build order of operations so builds work on new machines --- developer/src/tike/build.sh | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/developer/src/tike/build.sh b/developer/src/tike/build.sh index 1ab9dbe320..fd81ca692d 100755 --- a/developer/src/tike/build.sh +++ b/developer/src/tike/build.sh @@ -19,7 +19,7 @@ source "$KEYMAN_ROOT/resources/build/win/environment.inc.sh" WIN32_TARGET="$WIN32_TARGET_PATH/tike.exe" builder_describe_outputs \ - configure:project /resources/build/win/delphi_environment_generated.inc.sh \ + configure:project /developer/src/tike/xml/layoutbuilder/keymanweb-osk.ttf \ build:project /developer/src/tike/$WIN32_TARGET #------------------------------------------------------------------------------------------------------------------- @@ -31,6 +31,7 @@ function do_configure() { mkdir -p "$DEVELOPER_PROGRAM" cp "$KEYMAN_ROOT/common/schemas/kps/kps.xsd" "$DEVELOPER_PROGRAM" cp "$KEYMAN_ROOT/common/resources/fonts/keymanweb-osk.ttf" "$DEVELOPER_ROOT/src/tike/xml/layoutbuilder/keymanweb-osk.ttf" + run_in_vs_env rc icons.rc } function do_monaco_copy() { @@ -52,8 +53,6 @@ function do_monaco_copy() { pushd "$DEVELOPER_ROOT/src/tike/xml/app/lib/sentry" replaceVersionStrings_Mkver init.js.in init.js popd - - run_in_vs_env rc icons.rc } KEYMANCORE_DLL=keymancore-2.dll From 74f586574590feb5b31e351e81a41a112de72a00 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Fri, 23 Aug 2024 15:10:43 +0200 Subject: [PATCH 27/35] docs(developer): update build documentation to refer to build.sh Fixes: #12270 --- developer/src/README.md | 40 +++++++++++++++++++++++++++++++++++++++- windows/src/README.md | 37 ++++++++++++++++++------------------- 2 files changed, 57 insertions(+), 20 deletions(-) diff --git a/developer/src/README.md b/developer/src/README.md index 7e7ea9d336..d789b63f08 100644 --- a/developer/src/README.md +++ b/developer/src/README.md @@ -2,6 +2,42 @@ This is the current home for Keyman Developer. +## Build Prerequisites + +* See [Windows Build Environment Configuration](../../docs/build/windows.md). + +## Building Keyman Developer + +1. Start 'Git Bash' (part of Git for Windows). +2. Run `developer/src/build.sh`. +3. Artifacts from a successful build will be placed in **developer/bin** folder. + +*Note*: running `build.sh` will currently reset the packages and path settings +in your Delphi environment. If you use Delphi for other projects, you should +consider building Keyman under a login user dedicated to it, or in a VM. + +Type `build.sh` to see build targets and actions. Common build actions are: + +* `build.sh build` +: builds Keyman Developer + +* `build.sh clean` +: remove temporary files and build artifacts + +* `build.sh publish` +: makes a release of all Keyman Developer projects + +* `build.sh install` +: install some or all components to Program Files (requires elevated command prompt). + +### Building without Delphi + +It is possible to build all components that do _not_ require Delphi. Currently a +few components are Delphi-based (TIKE, setup, a few others), but you may be able +to get away without building them. In this situation, we recommend copying the +relevant Delphi-built components into developer/bin folders from a compatible +installed version of Keyman Developer for testing and debugging purposes. + # Folders ## common @@ -106,4 +142,6 @@ testing and packing keyboards for distribution. ## tools -Various build-time tools for Keyman Developer. \ No newline at end of file +Various build-time tools for Keyman Developer. + + diff --git a/windows/src/README.md b/windows/src/README.md index 1d057482bb..1e66443ce7 100644 --- a/windows/src/README.md +++ b/windows/src/README.md @@ -1,40 +1,39 @@ -# Keyman for Windows and Keyman Developer +# Keyman for Windows ## Build Prerequisites * See [Windows Build Environment Configuration](../../docs/build/windows.md). -## Building Keyman for Windows and Keyman Developer +## Building Keyman for Windows -1. Start 'Developer Command Prompt for VS 2019'. -2. Run `nmake build` from the **windows/src** folder. +1. Start 'Git Bash' (part of Git for Windows). +2. Run `windows/src/build.sh`. 3. Artifacts from a successful build will be placed in **windows/bin** folder. -*Note*: running `nmake build` will currently reset the packages and path settings +*Note*: running `build.sh` will currently reset the packages and path settings in your Delphi environment. If you use Delphi for other projects, you should consider building Keyman under a login user dedicated to it, or in a VM. -Type `nmake` to see build targets. Common build targets are: +Type `build.sh` to see build targets and actions. Common build actions are: -* `nmake build` -: builds Keyman for Windows and Keyman Developer +* `build.sh build` +: builds Keyman for Windows -* `nmake clean` +* `build.sh clean` : remove temporary files and build artifacts -* `nmake release` +* `build.sh publish` : makes a release of all Keyman Windows projects -* `nmake install` +* `build.sh install` : install some or all components to Program Files (requires elevated command prompt). ### Building without Delphi -It is possible to build all components that do _not_ require Delphi by adding -the environment variable `NODELPHI=1` before starting the build. Currently many -components are Delphi-based, but if you are working just in Keyman Core, the -compiler, or Keyman Engine's C++ components, you may be able to get away without -building them. In this situation, we recommend copying the relevant Delphi-built +It is possible to build all components that do _not_ require Delphi. Currently +many components are Delphi-based, but if you are working just in Keyman Core, or +Keyman Engine's C++ components, you may be able to get away without building +them. In this situation, we recommend copying the relevant Delphi-built components into windows/bin folders from a compatible installed version of Keyman for testing and debugging purposes. @@ -45,8 +44,8 @@ build, you will need to obtain valid code signing certificates. See Certificates, below. Official release builds for Keyman are built in the Keyman project's CI environment. -1. Start 'Developer Command Prompt for VS 2019'. -2. Run `nmake release` from the **windows/src** folder. +1. Start 'Git Bash'. +2. Run `windows/src/build.sh publish`. 3. Artifacts from a successful build will be placed in **windows/release** folder. 4. **buildtools/help-keyman-com.sh** will push updated documentation to @@ -76,7 +75,7 @@ You do not need to install the **KeymanTest** certificates, only the **KeymanTestCA** certificates. If you have not already installed the **KeymanTestCA** certificates using the -`nmake` command above, to manually install the Keyman **KeymanTestCA** +`build.sh` command above, to manually install the Keyman **KeymanTestCA** certificates, do the following in **common/windows/delphi/tools/certificates**: 1. Open the certificate and click 'Install certificate...' to open the From 8457f9527a51a734b8fa8afb77ad1ba16a72a3eb Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Fri, 23 Aug 2024 17:53:48 +0200 Subject: [PATCH 28/35] chore(developer): extend timeouts for lm compiler tests to 5 secs Fixes: #12271 --- developer/src/kmc-model/test/test-compile-model.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/developer/src/kmc-model/test/test-compile-model.ts b/developer/src/kmc-model/test/test-compile-model.ts index e3074d697a..7de9d6d5da 100644 --- a/developer/src/kmc-model/test/test-compile-model.ts +++ b/developer/src/kmc-model/test/test-compile-model.ts @@ -9,6 +9,8 @@ import { KeymanFileTypes } from '@keymanapp/common-types'; describe('LexicalModelCompiler', function () { let callbacks = new TestCompilerCallbacks(); + this.timeout(5000); + // Try to compile ALL of the correct models. const MODELS = [ 'example.qaa.sencoten', From 9a8b6d1279e9070caf21103cdae6aa3db5e8c72e Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Fri, 23 Aug 2024 18:12:06 +0200 Subject: [PATCH 29/35] chore(windows): remove remaining unused Makefiles Fixes: #12247 --- common/windows/delphi/Defines.mak | 299 ------------------ common/windows/delphi/Header.mak | 59 ---- common/windows/delphi/Target.mak | 14 - resources/build/win/environment.inc.sh | 4 + windows/src/build.sh | 1 + windows/src/support/Makefile | 38 --- windows/src/support/build.sh | 22 ++ windows/src/support/charident/Makefile | 20 -- windows/src/support/etl2log/Makefile | 22 -- windows/src/support/etl2log/build.sh | 40 +++ windows/src/support/kdebug/Makefile | 21 -- windows/src/support/keycodetester/Makefile | 15 - windows/src/support/km_yim/Makefile | 24 -- windows/src/support/kmkb0045/Makefile | 19 -- windows/src/support/oskbulkrenderer/Makefile | 24 -- windows/src/support/oskbulkrenderer/build.sh | 39 +++ windows/src/support/richedit_examine/Makefile | 15 - windows/src/support/texteditor/Makefile | 36 --- windows/src/support/texteditor/build.sh | 44 +++ windows/src/support/windowinfo/Makefile | 15 - .../manual-tests/integration-tests/Makefile | 26 -- .../integration-tests/keymanapi/Makefile | 23 -- .../test/manual-tests/regressiontest/Makefile | 16 - .../regressiontest/tests/Makefile | 11 - .../manual-tests/test_httpuploader/Makefile | 18 -- 25 files changed, 150 insertions(+), 715 deletions(-) delete mode 100644 common/windows/delphi/Defines.mak delete mode 100644 common/windows/delphi/Header.mak delete mode 100644 common/windows/delphi/Target.mak delete mode 100644 windows/src/support/Makefile create mode 100755 windows/src/support/build.sh delete mode 100644 windows/src/support/charident/Makefile delete mode 100644 windows/src/support/etl2log/Makefile create mode 100755 windows/src/support/etl2log/build.sh delete mode 100644 windows/src/support/kdebug/Makefile delete mode 100644 windows/src/support/keycodetester/Makefile delete mode 100644 windows/src/support/km_yim/Makefile delete mode 100644 windows/src/support/kmkb0045/Makefile delete mode 100644 windows/src/support/oskbulkrenderer/Makefile create mode 100755 windows/src/support/oskbulkrenderer/build.sh delete mode 100644 windows/src/support/richedit_examine/Makefile delete mode 100644 windows/src/support/texteditor/Makefile create mode 100755 windows/src/support/texteditor/build.sh delete mode 100644 windows/src/support/windowinfo/Makefile delete mode 100644 windows/src/test/manual-tests/integration-tests/Makefile delete mode 100644 windows/src/test/manual-tests/integration-tests/keymanapi/Makefile delete mode 100644 windows/src/test/manual-tests/regressiontest/Makefile delete mode 100644 windows/src/test/manual-tests/regressiontest/tests/Makefile delete mode 100644 windows/src/test/manual-tests/test_httpuploader/Makefile diff --git a/common/windows/delphi/Defines.mak b/common/windows/delphi/Defines.mak deleted file mode 100644 index 50210e5fea..0000000000 --- a/common/windows/delphi/Defines.mak +++ /dev/null @@ -1,299 +0,0 @@ -# DEBUG=1 - -# TODO: this should be a shared Defines.mak for common,developer,windows. So we -# need to move any project-specific stuff into a defines-windows.mak, -# defines-etc.mak - -# -# Paths -# - -!IFNDEF KEYMAN_ROOT -!ERROR KEYMAN_ROOT must be defined! -!ENDIF - -# TODO: COMMON_ROOT should be common\windows -COMMON_ROOT=$(KEYMAN_ROOT)\common\windows\delphi -WINDOWS_ROOT=$(KEYMAN_ROOT)\windows -OUTLIB=$(WINDOWS_ROOT)\lib -COMMON_OUTLIB=$(KEYMAN_ROOT)\windows\lib -COMMON_BIN=$(KEYMAN_ROOT)\windows\bin - -# INCLUDE=$(ROOT)\src\global\inc;$(INCLUDE) - -!IFDEF DEBUG -GO_FAST=1 -MAKEFLAG_DEBUG="DEBUG=$(DEBUG)" -DELPHI_MSBUILD_FLAG_DEBUG="/p:Config=Debug" -!ELSE -!IFDEF TEAMCITY_PR_NUMBER -GO_FAST=1 -!ENDIF -DELPHI_MSBUILD_FLAG_DEBUG="/p:Config=Release" -!ENDIF - -!IFDEF USERDEFINES -MAKEFLAG_USERDEFINES="USERDEFINES=$(USERDEFINES)" -!ENDIF - -!IFDEF SC_TIMESTAMP -MAKEFLAG_SC_TIMESTAMP="SC_TIMESTAMP=$(SC_TIMESTAMP)" -!ENDIF - -!IFDEF BUILDHELP -MAKEFLAG_BUILDHELP="BUILDHELP=$(BUILDHELP)" -!ENDIF - -!IFDEF LINT -MAKEFLAG_LINT="LINT=$(LINT)" -!ENDIF - -!IFDEF NOUI -MAKEFLAG_QUIET="NOUI=$(NOUI)" -!ELSE -!IFDEF QUIET -MAKEFLAG_QUIET="QUIET=$(QUIET)" -!ENDIF -!ENDIF - -!IFDEF RELEASE_OEM -MAKEFLAG_RELEASE_OEM="RELEASE_OEM=$(RELEASE_OEM)" -!ENDIF - -# -# USERDEFINES allows the developer to specify overrides for various settings. We need a variable -# because Makefiles cannot test for file existence -# - -# TODO: can we eliminate this? - -!ifdef USERDEFINES -!include $(WINDOWS_ROOT)\src\UserDefines.mak -!endif - -# -# Delphi Compiler Configuration - Delphi 10.3.2 -# - -!IFNDEF DELPHI_VERSION -DELPHI_VERSION=20.0 -!ENDIF - -DCC32PATH=C:\Program Files (x86)\Embarcadero\Studio\$(DELPHI_VERSION)\bin - -# -# Pass local configuration through to sub-instances of MAKE -# - -MAKE="nmake" /C $(MAKEFLAG_QUICK_BUILD_KEYMAN) $(MAKEFLAG_USERDEFINES) $(MAKEFLAG_DEBUG) $(MAKEFLAG_BUILDHELP) $(MAKEFLAG_BUILDRTF) $(MAKEFLAG_SC_TIMESTAMP) $(MAKEFLAG_LINT) $(MAKEFLAG_QUIET) $(MAKEFLAG_RELEASE_OEM) - -# -# Delphi build commands -# - -!IFDEF DEBUG -TARGET_PATH=Debug -!ELSE -TARGET_PATH=Release -!ENDIF - -!IFDEF LINT -DELPHIWARNINGS=-W+MESSAGE_DIRECTIVE -W+IMPLICIT_STRING_CAST -W+IMPLICIT_STRING_CAST_LOSS -W+EXPLICIT_STRING_CAST -W+EXPLICIT_STRING_CAST_LOSS -W+CVT_WCHAR_TO_ACHAR -W+CVT_NARROWING_STRING_LOST -W+CVT_ACHAR_TO_WCHAR -W+CVT_WIDENING_STRING_LOST -W+UNICODE_TO_LOCALE -W+LOCALE_TO_UNICODE -W+IMPLICIT_VARIANTS -!ELSE -DELPHIWARNINGS=-W-MESSAGE_DIRECTIVE -W-IMPLICIT_STRING_CAST -W-IMPLICIT_STRING_CAST_LOSS -W-EXPLICIT_STRING_CAST -W-EXPLICIT_STRING_CAST_LOSS -W-CVT_WCHAR_TO_ACHAR -W-CVT_NARROWING_STRING_LOST -W-CVT_ACHAR_TO_WCHAR -W-CVT_WIDENING_STRING_LOST -W-UNICODE_TO_LOCALE -W-LOCALE_TO_UNICODE -W-IMPLICIT_VARIANTS -W-IMPLICIT_INTEGER_CAST_LOSS -W-IMPLICIT_CONVERSION_LOSS -W-COMBINING_SIGNED_UNSIGNED64 -W-COMBINING_SIGNED_UNSIGNED64 -!ENDIF - -DELPHIDPRPARAMS=-Q -B -GD -H -VT -^$C+ -^$D+ -^$J+ -^$L+ -^$O+ -^$Q- -^$R- -^$W+ -^$Y+ -E. $(DELPHIWARNINGS) -I$(DELPHIINCLUDES) -U$(DELPHIINCLUDES) -R$(DELPHIINCLUDES) -NSVcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;System;Xml;Web;Soap;Winapi;System.Win -NU.\obj\Win32\$(TARGET_PATH) -E.\bin\Win32\$(TARGET_PATH) -DELPHIDPRPARAMS64=-Q -B -GD -H -VT -^$C+ -^$D+ -^$J+ -^$L+ -^$O+ -^$Q- -^$R- -^$W+ -^$Y+ -E. $(DELPHIWARNINGS) -I$(DELPHIINCLUDES) -U$(DELPHIINCLUDES) -R$(DELPHIINCLUDES) -NSVcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;System;Xml;Web;Soap;Winapi;System.Win -NU.\obj\Win64\$(TARGET_PATH) -E.\bin\Win64\$(TARGET_PATH) -DELPHIDPKPARAMS=-Q -B -GD -VT -^$C+ -^$D+ -^$J+ -^$L+ -^$O+ -^$Q- -^$R- -^$W+ -^$Y+ -E. $(DELPHIWARNINGS) -I$(DELPHIINCLUDES) -U$(DELPHIINCLUDES) -R$(DELPHIINCLUDES) -NSVcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;System;Xml;Web;Soap;Winapi;System.Win -LE$(OUTLIB) -LN$(OUTLIB) -NSData -NUobj\Win32\$(TARGET_PATH) - -COMMON_DELPHIDPKPARAMS=-Q -B -GD -VT -^$C+ -^$D+ -^$J+ -^$L+ -^$O+ -^$Q- -^$R- -^$W+ -^$Y+ -E. $(DELPHIWARNINGS) -I$(DELPHIINCLUDES) -U$(DELPHIINCLUDES) -R$(DELPHIINCLUDES) -NSVcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;System;Xml;Web;Soap;Winapi;System.Win -LE$(COMMON_OUTLIB) -LN$(COMMON_OUTLIB) -NSData -NUobj\Win32\$(TARGET_PATH) - -# we are using cmd /c because dcc32/dcc64 are failing on direct execution -# from nmake -DCC32=cmd /c "$(DCC32PATH)\dcc32.exe" $(DELPHIDPRPARAMS) -DCC32DPK=cmd /c "$(DCC32PATH)\dcc32.exe" $(DELPHIDPKPARAMS) -COMMON_DCC32DPK=cmd /c "$(DCC32PATH)\dcc32.exe" $(COMMON_DELPHIDPKPARAMS) -DCC64=cmd /c "$(DCC32PATH)\dcc64.exe" $(DELPHIDPRPARAMS64) -N0x64\ -Ex64\ - -# -# Delphi MSBuild related commands and macros -# - -DELPHI_MSBUILD="$(COMMON_ROOT)\tools\msbuild-wrapper.bat" "$(DCC32PATH)" $(DELPHI_MSBUILD_FLAG_DEBUG) - -!IFDEF NODELPHI -DCC32=echo skipping -DCC32DPK=echo skipping -DCC64=echo skipping -DELPHI_MSBUILD=echo skipping -!ENDIF - -# Visual C++ x86, x64 -WIN32_TARGET_PATH=bin\Win32\$(TARGET_PATH) -X64_TARGET_PATH=bin\x64\$(TARGET_PATH) - -# Delphi x86, x64 -# WIN32_TARGET_PATH=... -WIN64_TARGET_PATH=bin\Win64\$(TARGET_PATH) - -# -# Shared devtools app for common Delphi source manipulation -# - -DEVTOOLS=$(COMMON_ROOT)\tools\devtools\$(WIN32_TARGET_PATH)\devtools.exe - -# -# Other program build commands -# - -BRCC32=rc.exe - -HHC="C:\Program Files (x86)\HTML Help Workshop\hhc.exe" -NMAKE=nmake.exe -CL=cl.exe -MSBUILD=msbuild.exe -# /maxcpucount see https://devblogs.microsoft.com/cppblog/precompiled-header-pch-issues-and-recommendations/ -MT=mt.exe -VCBUILD=error - -!IFDEF DEBUG -MSBUILD_BUILD=/t:Build /p:Configuration=Debug -MSBUILD_CLEAN=/t:Clean /p:Configuration=Debug -!ELSE -MSBUILD_BUILD=/t:Rebuild /p:Configuration=Release -MSBUILD_CLEAN=/t:Clean /p:Configuration=Release -!ENDIF - -COPY=copy -ISXBUILD=C:\PROGRA~1\INSTALLSHIELD\Express\System\IsExpCmdBld -WZZIPPATH="C:\program files\7-zip\7z.exe" -!IFDEF GO_FAST -WZZIP=$(WZZIPPATH) a -mx1 -!ELSE -WZZIP=$(WZZIPPATH) a -mx9 -!ENDIF -WZUNZIP=$(WZZIPPATH) e - -# we are using cmd /c because tds2dbg is failing on direct execution -# from nmake -TDS2DBG=cmd /c $(KEYMAN_ROOT)\common\windows\bin\tools\tds2dbg -SENTRYTOOL=$(COMMON_ROOT)\tools\sentrytool\$(WIN32_TARGET_PATH)\sentrytool.exe -SENTRYTOOL_DELPHIPREP=$(SENTRYTOOL) delphiprep -r $(KEYMAN_ROOT) -i $(DELPHIINCLUDES) - -WIXPATH="c:\program files (x86)\WiX Toolset v3.11\bin" -WIXCANDLE=$(WIXPATH)\candle.exe -wx -nologo - -!IFDEF LINT -WIXLIGHTLINT= -!ELSE -# we suppress ICE82 because it reports spurious errors with merge module keymanengine to do with duplicate sequence numbers. Safely ignored. -WIXLIGHTLINT= -sice:ICE82 -sice:ICE80 -!ENDIF - -!IFDEF GO_FAST -# for debug builds, we turn off compression because it is so hideously slow -# for test builds, we also turn off compression -WIXLIGHTCOMPRESSION=-dcl:none -!ELSE -WIXLIGHTCOMPRESSION=-dcl:high -!ENDIF - -WIXLIGHT=$(WIXPATH)\light.exe -wx -nologo $(WIXLIGHTLINT) $(WIXLIGHTCOMPRESSION) - -WIXLIT=$(WIXPATH)\lit.exe -wx -nologo -WIXHEAT=$(WIXPATH)\heat.exe - -LINKPATH=link.exe - -# -# Certificates and code signing -# - -!ifdef SIGNCODE_BUILD -MAKE=$(MAKE) "SIGNCODE_BUILD=$(SIGNCODE_BUILD)" -!else -MAKE=$(MAKE) -!endif - -# -# To get a .pfx from a .spc and .pvk, run pvk2pfx.exe -# - -!IFNDEF SC_PFX_SHA1 -SC_PFX_SHA1="$(COMMON_ROOT)\tools\certificates\keymantest-sha1.pfx" -!ENDIF - -!IFNDEF SC_PFX_SHA256 -SC_PFX_SHA256="$(COMMON_ROOT)\tools\certificates\keymantest-sha256.pfx" -!ENDIF - -!IFNDEF SC_URL -SC_URL="https://keyman.com/" -!ENDIF - -!IFNDEF SC_PWD -SC_PWD="" -!ENDIF - -SIGNCODE=@"$(KEYMAN_ROOT)\common\windows\signtime.bat" signtool.exe $(SC_PFX_SHA1) $(SC_PFX_SHA256) $(SC_URL) $(SC_PWD) - -# -# On some computers, the PLATFORM environment variable is set to x86. This can break msbuild -# with our projects. This may be resolvable in the future, but for now the easy fix is ... -# - -PLATFORM=Win32 - -# -# mkver commands. mkver determines tag from the local build environment variables -# in the same way as /resources/build/build-utils.sh. -# - -!ifdef GIT_BASH_FOR_KEYMAN -MKVER_SH=$(GIT_BASH_FOR_KEYMAN) $(KEYMAN_ROOT)\common\windows\mkver.sh -!else -MKVER_SH=start /wait $(KEYMAN_ROOT)\common\windows\mkver.sh -!endif - -MKVER_M=$(MKVER_SH) manifest.in manifest.xml -MKVER_U=$(MKVER_SH) - -# -# 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 - -CLEAN=-del /S /Q diff --git a/common/windows/delphi/Header.mak b/common/windows/delphi/Header.mak deleted file mode 100644 index 6c78b3724e..0000000000 --- a/common/windows/delphi/Header.mak +++ /dev/null @@ -1,59 +0,0 @@ -# -# 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 - -!IFNDEF KEYMAN_ROOT -!ERROR KEYMAN_ROOT must be defined! -!ENDIF - -# This path will need to be updated if the root path changes - -!include $(KEYMAN_ROOT)\common\windows\delphi\Defines.mak - -# -# The targets build, signcode, symbols are standard -# targets for all projects -# - -build: $(BUILDPREREQ) - $(MAKE) "TARGET=build" $(TARGETS) - -!IFNDEF NOTARGET_SIGNCODE -signcode: - $(MAKE) "TARGET=signcode" $(TARGETS) - -symbols: - $(MAKE) "TARGET=symbols" $(TARGETS) -!ELSE -signcode: - rem no signcode required - -symbols: - rem no symbols required -!ENDIF - -build-release: -!IFDEF RELEASE_TARGETS - $(MAKE) "TARGET=build-release" $(RELEASE_TARGETS) -!ELSE - @rem -!ENDIF - -clean: - $(MAKE) "TARGET=clean" $(TARGETS) $(CLEANS) - -install: - $(MAKE) "TARGET=install" $(TARGETS) - -test-manifest: -!IFDEF MANIFESTS - $(MAKE) "TARGET=test-manifest" $(MANIFESTS) -!ELSE - $(MAKE) "TARGET=test-manifest" $(TARGETS) -!ENDIF \ No newline at end of file diff --git a/common/windows/delphi/Target.mak b/common/windows/delphi/Target.mak deleted file mode 100644 index 777bd84beb..0000000000 --- a/common/windows/delphi/Target.mak +++ /dev/null @@ -1,14 +0,0 @@ -!CMDSWITCHES +S - -def-clean: - $(CLEAN) *.err *.stat *.dproj.local *.Build.CppClean.Log *.suo *.jdbg *.dbg *.dcu *.~* *.dsk *.exe *.rsm *.ncb *.opt *.pch *.plg *.aps *.001 *.sbr *.dep *.drc *.bak *.pdb *.lib *.cod *.ilk *.tds vc80.idb *.map *.bsc version.res manifest.xml manifest.res >nul 2>nul - $(CLEAN) ExcMagic.Debug *.wixpdb *.identcache *.embed.manifest *.embed.manifest.res *.intermediate.manifest error.log >nul 2>nul - if exist bin rd /s/q bin - if exist obj rd /s/q obj - -!CMDSWITCHES -S - -# This virtual rule forces targets which are folders, e.g. `kmshell` to -# always execute -.virtual: - rem always execute diff --git a/resources/build/win/environment.inc.sh b/resources/build/win/environment.inc.sh index d2b351fcbc..620e96146a 100644 --- a/resources/build/win/environment.inc.sh +++ b/resources/build/win/environment.inc.sh @@ -23,8 +23,10 @@ source "$KEYMAN_ROOT/resources/build/win/environment_generated.inc.sh" WINDOWS_ROOT="$KEYMAN_ROOT/windows" WINDOWS_PROGRAM_APP="$WINDOWS_ROOT/bin/desktop" WINDOWS_PROGRAM_ENGINE="$WINDOWS_ROOT/bin/engine" +WINDOWS_PROGRAM_SUPPORT="$WINDOWS_ROOT/bin/support" WINDOWS_DEBUGPATH_APP="$WINDOWS_ROOT/debug/desktop" WINDOWS_DEBUGPATH_ENGINE="$WINDOWS_ROOT/debug/engine" +WINDOWS_DEBUGPATH_SUPPORT="$WINDOWS_ROOT/debug/suppor" COMMON_ROOT="$KEYMAN_ROOT/common/windows/delphi" OUTLIB="$WINDOWS_ROOT/lib" @@ -141,6 +143,8 @@ create-windows-output-folders() { mkdir -p "$OUTLIB" mkdir -p "$WINDOWS_PROGRAM_APP" mkdir -p "$WINDOWS_PROGRAM_ENGINE" + mkdir -p "$WINDOWS_PROGRAM_SUPPORT" mkdir -p "$WINDOWS_DEBUGPATH_APP" mkdir -p "$WINDOWS_DEBUGPATH_ENGINE" + mkdir -p "$WINDOWS_DEBUGPATH_SUPPORT" } \ No newline at end of file diff --git a/windows/src/build.sh b/windows/src/build.sh index a1fc4d0e1a..4ef6da65b8 100755 --- a/windows/src/build.sh +++ b/windows/src/build.sh @@ -18,6 +18,7 @@ builder_describe \ ":engine Keyman Engine for Windows" \ ":desktop Keyman for Windows" \ ":components=global/delphi Delphi components" \ + ":support Support tools" \ ":test=test/unit-tests Shared unit tests" \ ":fv=../../oem/firstvoices/windows/src/inst OEM FirstVoices for Windows app" diff --git a/windows/src/support/Makefile b/windows/src/support/Makefile deleted file mode 100644 index 56609e21e4..0000000000 --- a/windows/src/support/Makefile +++ /dev/null @@ -1,38 +0,0 @@ -# -# Support Makefile -# - -!ifdef NODELPHI -TARGETS=etl2log texteditor -!else -TARGETS=oskbulkrenderer etl2log texteditor -!endif -CLEANS=clean-support - -!include ..\Header.mak - -# ---------------------------------------------------------------------- - -oskbulkrenderer: .virtual - cd $(ROOT)\src\support\oskbulkrenderer - $(MAKE) $(TARGET) - -etl2log: .virtual - cd $(ROOT)\src\support\etl2log - $(MAKE) $(TARGET) - -texteditor: .virtual - cd $(ROOT)\src\support\texteditor - $(MAKE) $(TARGET) - -# ---------------------------------------------------------------------- - -clean-support: - cd $(ROOT)\src\support - -del version.txt - -!include ..\Target.mak - -# ---------------------------------------------------------------------- -# EOF -# ---------------------------------------------------------------------- diff --git a/windows/src/support/build.sh b/windows/src/support/build.sh new file mode 100755 index 0000000000..f9f20f1716 --- /dev/null +++ b/windows/src/support/build.sh @@ -0,0 +1,22 @@ +#!/usr/bin/env bash +## START STANDARD BUILD SCRIPT INCLUDE +# adjust relative paths as necessary +THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")" +. "${THIS_SCRIPT%/*}/../../../resources/build/builder.inc.sh" +## END STANDARD BUILD SCRIPT INCLUDE + +builder_describe \ + "Keyman for Windows support tools" \ + \ + clean \ + configure \ + build \ + test \ + \ + :oskbulkrenderer \ + :etl2log \ + :texteditor + +builder_parse "$@" + +builder_run_child_actions clean configure build test publish install diff --git a/windows/src/support/charident/Makefile b/windows/src/support/charident/Makefile deleted file mode 100644 index cff6741677..0000000000 --- a/windows/src/support/charident/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -# -# charident Makefile -# - -!include ..\..\Defines.mak - -build: version.res dirs - $(DCC32) charident.dpr - $(COPY) charident.exe $(PROGRAM)\support - -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 - -!include ..\..\Target.mak diff --git a/windows/src/support/etl2log/Makefile b/windows/src/support/etl2log/Makefile deleted file mode 100644 index 48bdb1a592..0000000000 --- a/windows/src/support/etl2log/Makefile +++ /dev/null @@ -1,22 +0,0 @@ -# -# etl2log Makefile -# - -!include ..\..\Defines.mak - -build: version.res dirs - $(MSBUILD) etl2log.vcxproj $(MSBUILD_BUILD) - $(COPY) $(WIN32_TARGET_PATH)\etl2log.exe $(PROGRAM)\support - $(COPY) $(WIN32_TARGET_PATH)\etl2log.pdb $(DEBUGPATH)\support - -clean: def-clean - $(MSBUILD) etl2log.vcxproj $(MSBUILD_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 - -!include ..\..\Target.mak diff --git a/windows/src/support/etl2log/build.sh b/windows/src/support/etl2log/build.sh new file mode 100755 index 0000000000..e2fdee1acd --- /dev/null +++ b/windows/src/support/etl2log/build.sh @@ -0,0 +1,40 @@ +#!/usr/bin/env bash +## START STANDARD BUILD SCRIPT INCLUDE +# adjust relative paths as necessary +THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")" +. "${THIS_SCRIPT%/*}/../../../../resources/build/builder.inc.sh" +## END STANDARD BUILD SCRIPT INCLUDE + +builder_describe "etl2log" \ + clean configure build test + +builder_parse "$@" + +#------------------------------------------------------------------------------------------------------------------- + +source "$KEYMAN_ROOT/resources/build/win/environment.inc.sh" +WIN32_TARGET="$WIN32_TARGET_PATH/etl2log.exe" + +builder_describe_outputs \ + configure:project /resources/build/win/delphi_environment_generated.inc.sh \ + build:project /windows/src/support/etl2log/$WIN32_TARGET + +#------------------------------------------------------------------------------------------------------------------- + +function do_clean() { + vs_msbuild etl2log.vcxproj //t:Clean + clean_windows_project_files +} + +function do_build() { + create-windows-output-folders + build_version.res + vs_msbuild etl2log.vcxproj //t:Build "//p:Platform=Win32" + cp "$WIN32_TARGET" "$WINDOWS_PROGRAM_SUPPORT" + cp "$WIN32_TARGET_PATH/etl2log.pdb" "$WINDOWS_DEBUGPATH_SUPPORT" +} + +builder_run_action clean:project do_clean +builder_run_action configure:project configure_windows_build_environment +builder_run_action build:project do_build +# builder_run_action test:project do_test diff --git a/windows/src/support/kdebug/Makefile b/windows/src/support/kdebug/Makefile deleted file mode 100644 index 1a13a18ebe..0000000000 --- a/windows/src/support/kdebug/Makefile +++ /dev/null @@ -1,21 +0,0 @@ -# -# KDebug Makefile -# - -!include ..\..\Defines.mak - -!ifdef DEBUG - NMCFG=kdebug - Win32 Debug -!else - NMCFG=kdebug - Win32 Release -!endif - -install: dirs build - -build: version.res - $(NMAKE) /f kdebug.mak "CFG=$(NMCFG)" - -clean: def-clean - $(NMAKE) /f kdebug.mak "CFG=$(NMCFG)" CLEAN - -!include ..\..\Target.mak diff --git a/windows/src/support/keycodetester/Makefile b/windows/src/support/keycodetester/Makefile deleted file mode 100644 index 38687abaeb..0000000000 --- a/windows/src/support/keycodetester/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -# -# Keycodetester Makefile -# - -!include ..\..\Defines.mak - -install: dirs build - $(COPY) keycodetester.exe $(PROGRAM)\bldutil - -build: - $(DCC32) keycodetester.dpr - -clean: def-clean - -!include ..\..\Target.mak diff --git a/windows/src/support/km_yim/Makefile b/windows/src/support/km_yim/Makefile deleted file mode 100644 index 1aef5f80f0..0000000000 --- a/windows/src/support/km_yim/Makefile +++ /dev/null @@ -1,24 +0,0 @@ -# -# TODO: remove this project -# - -!include ..\..\Defines.mak - -build: -# version.res - $(DCC32) km_yim.dpr - rem $(TDSPACK) $(PROGRAM)\desktop\km_yim.exe km_yim.tds - 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 - -clean: def-clean - if exist inst_km_yim.zip del inst_km_yim.zip - -signcode: - $(SIGNCODE) /d "Tavultesoft Keyman Desktop Yahoo Messenger Addin" inst_km_yim.exe - -wrap-symbols: - rem - -!include ..\..\Target.mak diff --git a/windows/src/support/kmkb0045/Makefile b/windows/src/support/kmkb0045/Makefile deleted file mode 100644 index 3e914c8acd..0000000000 --- a/windows/src/support/kmkb0045/Makefile +++ /dev/null @@ -1,19 +0,0 @@ -# -# TODO: remove this project -# - -!include ..\..\Defines.mak - -build: version.res manifest.res - $(DCC32) kmkb0045.dpr - $(SENTRYTOOL_DELPHIPREP) kmkb0045.exe -dpr kmkb0045.dpr - $(TDS2DBG) kmkb0045.exe - $(COPY) kmkb0045.exe $(PROGRAM)\support - -clean: def-clean - -signcode: - $(SIGNCODE) /d "Tavultesoft KMKB0045" $(PROGRAM)\support\kmkb0045.exe - - -!include ..\..\Target.mak diff --git a/windows/src/support/oskbulkrenderer/Makefile b/windows/src/support/oskbulkrenderer/Makefile deleted file mode 100644 index 65b8e02ba6..0000000000 --- a/windows/src/support/oskbulkrenderer/Makefile +++ /dev/null @@ -1,24 +0,0 @@ -# -# oskbulkrenderer Makefile -# - -!include ..\..\Defines.mak - -build: version.res dirs - $(DELPHI_MSBUILD) oskbulkrenderer.dproj "/p:Platform=Win32" - - $(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 - -clean: def-clean - -rd /s/q Win32 - -signcode: - rem Not signing this utility - -wrap-symbols: - @rem - -!include ..\..\Target.mak diff --git a/windows/src/support/oskbulkrenderer/build.sh b/windows/src/support/oskbulkrenderer/build.sh new file mode 100755 index 0000000000..76fa8a4032 --- /dev/null +++ b/windows/src/support/oskbulkrenderer/build.sh @@ -0,0 +1,39 @@ +#!/usr/bin/env bash +## START STANDARD BUILD SCRIPT INCLUDE +# adjust relative paths as necessary +THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")" +. "${THIS_SCRIPT%/*}/../../../../resources/build/builder.inc.sh" +## END STANDARD BUILD SCRIPT INCLUDE + +builder_describe "oskbuildrenderer" \ + clean configure build test + +builder_parse "$@" + +#------------------------------------------------------------------------------------------------------------------- + +source "$KEYMAN_ROOT/resources/build/win/environment.inc.sh" +WIN32_TARGET="$WIN32_TARGET_PATH/oskbulkrenderer.exe" + +builder_describe_outputs \ + configure:project /resources/build/win/delphi_environment_generated.inc.sh \ + build:project /windows/src/support/oskbulkrenderer/$WIN32_TARGET + +#------------------------------------------------------------------------------------------------------------------- + +function do_clean() { + clean_windows_project_files +} + +function do_build() { + create-windows-output-folders + build_version.res + delphi_msbuild oskbulkrenderer.dproj "//p:Platform=Win32" + + cp "$WIN32_TARGET" "$WINDOWS_PROGRAM_SUPPORT" +} + +builder_run_action clean:project do_clean +builder_run_action configure:project configure_windows_build_environment +builder_run_action build:project do_build +# builder_run_action test:project do_test diff --git a/windows/src/support/richedit_examine/Makefile b/windows/src/support/richedit_examine/Makefile deleted file mode 100644 index adacba5901..0000000000 --- a/windows/src/support/richedit_examine/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -# -# richedit_examine Makefile -# - -!include ..\..\Defines.mak - -install: dirs build - $(COPY) richedit_examine.exe $(PROGRAM)\bldutil - -build: version.res - $(DCC32) richedit_examine.dpr - -clean: def-clean - -!include ..\..\Target.mak diff --git a/windows/src/support/texteditor/Makefile b/windows/src/support/texteditor/Makefile deleted file mode 100644 index 473bf57598..0000000000 --- a/windows/src/support/texteditor/Makefile +++ /dev/null @@ -1,36 +0,0 @@ -# -# Keyman Text Editor Makefile -# - -!include ..\..\Defines.mak - -build: - $(MSBUILD) editor.vcxproj $(MSBUILD_BUILD) /p:Platform=x86 - $(MSBUILD) editor.vcxproj $(MSBUILD_BUILD) /p:Platform=x64 - $(COPY) $(WIN32_TARGET_PATH)\editor32.exe $(PROGRAM)\support - $(COPY) $(WIN32_TARGET_PATH)\editor32.pdb $(DEBUGPATH)\support - $(COPY) $(X64_TARGET_PATH)\editor64.exe $(PROGRAM)\support - $(COPY) $(X64_TARGET_PATH)\editor64.pdb $(DEBUGPATH)\support - -clean: def-clean - $(MSBUILD) $(MSBUILD_CLEAN) editor.sln - -signcode: - $(SIGNCODE) /d "Text Editor for testing Keyman" $(PROGRAM)\support\editor32.exe - $(SIGNCODE) /d "Text Editor for testing Keyman" $(PROGRAM)\support\editor64.exe - -install: - $(COPY) $(PROGRAM)\support\editor32.exe "$(INSTALLPATH_KEYMANENGINE)" - $(COPY) $(PROGRAM)\support\editor64.exe "$(INSTALLPATH_KEYMANENGINE)" - -wrap-symbols: - $(SYMSTORE) $(PROGRAM)\support\editor32.exe /t keyman-windows - $(SYMSTORE) $(PROGRAM)\support\editor64.exe /t keyman-windows - $(SYMSTORE) $(DEBUGPATH)\support\editor32.pdb /t keyman-windows - $(SYMSTORE) $(DEBUGPATH)\support\editor64.pdb /t keyman-windows - - -!include ..\..\Target.mak -# ---------------------------------------------------------------------- -# EOF -# ---------------------------------------------------------------------- diff --git a/windows/src/support/texteditor/build.sh b/windows/src/support/texteditor/build.sh new file mode 100755 index 0000000000..312ee1d0f4 --- /dev/null +++ b/windows/src/support/texteditor/build.sh @@ -0,0 +1,44 @@ +#!/usr/bin/env bash +## START STANDARD BUILD SCRIPT INCLUDE +# adjust relative paths as necessary +THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")" +. "${THIS_SCRIPT%/*}/../../../../resources/build/builder.inc.sh" +## END STANDARD BUILD SCRIPT INCLUDE + +builder_describe "texteditor" \ + clean configure build test + +builder_parse "$@" + +#------------------------------------------------------------------------------------------------------------------- + +source "$KEYMAN_ROOT/resources/build/win/environment.inc.sh" +WIN32_TARGET="$WIN32_TARGET_PATH/editor32.exe" +X64_TARGET="$X64_TARGET_PATH/editor64.exe" + +builder_describe_outputs \ + configure:project /resources/build/win/delphi_environment_generated.inc.sh \ + build:project /windows/src/support/texteditor/$WIN32_TARGET + +#------------------------------------------------------------------------------------------------------------------- + +function do_clean() { + vs_msbuild Editor.vcxproj //t:Clean + clean_windows_project_files +} + +function do_build() { + create-windows-output-folders + # build_version.res + vs_msbuild Editor.vcxproj //t:Build "//p:Platform=Win32" + vs_msbuild Editor.vcxproj //t:Build "//p:Platform=x64" + cp "$WIN32_TARGET" "$WINDOWS_PROGRAM_SUPPORT" + cp "$X64_TARGET" "$WINDOWS_PROGRAM_SUPPORT" + cp "$WIN32_TARGET_PATH/editor32.pdb" "$WINDOWS_DEBUGPATH_SUPPORT" + cp "$X64_TARGET_PATH/editor64.pdb" "$WINDOWS_DEBUGPATH_SUPPORT" +} + +builder_run_action clean:project do_clean +builder_run_action configure:project configure_windows_build_environment +builder_run_action build:project do_build +# builder_run_action test:project do_test diff --git a/windows/src/support/windowinfo/Makefile b/windows/src/support/windowinfo/Makefile deleted file mode 100644 index ac7da2c182..0000000000 --- a/windows/src/support/windowinfo/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -# -# windowinfo Makefile -# - -!include ..\..\Defines.mak - -install: dirs build - $(COPY) windowinfo.exe $(PROGRAM)\bldutil - -build: version.res - $(DCC32) windowinfo.dpr - -clean: def-clean - -!include ..\..\Target.mak diff --git a/windows/src/test/manual-tests/integration-tests/Makefile b/windows/src/test/manual-tests/integration-tests/Makefile deleted file mode 100644 index 093dc44140..0000000000 --- a/windows/src/test/manual-tests/integration-tests/Makefile +++ /dev/null @@ -1,26 +0,0 @@ -# -# Integration Tests Makefile. -# - -# ---------------------------------------------------------------------- - -TARGETS=keymanapi - -test: - $(MAKE) "TARGET=test" $(TARGETS) - -!include ..\..\Header.mak - -# ---------------------------------------------------------------------- - -keymanapi: - cd $(ROOT)\src\test\integration-tests\keymanapi - $(MAKE) $(TARGET) - -# ---------------------------------------------------------------------- - -!include ..\..\Target.mak - -# ---------------------------------------------------------------------- -# EOF -# ---------------------------------------------------------------------- diff --git a/windows/src/test/manual-tests/integration-tests/keymanapi/Makefile b/windows/src/test/manual-tests/integration-tests/keymanapi/Makefile deleted file mode 100644 index 7becbb044d..0000000000 --- a/windows/src/test/manual-tests/integration-tests/keymanapi/Makefile +++ /dev/null @@ -1,23 +0,0 @@ -# -# Integration tests for keymanapi -# - -!include ..\..\..\Defines.mak - -!ifdef EXCLUDE_ELEVATED -TEST_MODE=--exclude:Elevated -!endif - -test: build - $(WIN32_TARGET_PATH)\keymanapi_test.exe -b -exit:continue $(TEST_MODE) - $(WIN64_TARGET_PATH)\keymanapi_test.exe -b -exit:continue $(TEST_MODE) - -build: - $(DELPHI_MSBUILD) "/p:Platform=Win32" keymanapi_test.dproj - $(DELPHI_MSBUILD) "/p:Platform=Win64" keymanapi_test.dproj - -clean: def-clean - -rd /s/q Win32 - -rd /s/q Win64 - -!include ..\..\..\Target.mak diff --git a/windows/src/test/manual-tests/regressiontest/Makefile b/windows/src/test/manual-tests/regressiontest/Makefile deleted file mode 100644 index dbfa70078c..0000000000 --- a/windows/src/test/manual-tests/regressiontest/Makefile +++ /dev/null @@ -1,16 +0,0 @@ -# -# REGRESSIONTEST Makefile -# - - -!include ..\..\Defines.mak - -build: dirs - $(DCC32) regressiontest.dpr - $(COPY) regressiontest.exe $(PROGRAM)\support - -clean: def-clean - cd tests - $(MAKE) clean - -!include ..\..\Target.mak diff --git a/windows/src/test/manual-tests/regressiontest/tests/Makefile b/windows/src/test/manual-tests/regressiontest/tests/Makefile deleted file mode 100644 index 01f8705399..0000000000 --- a/windows/src/test/manual-tests/regressiontest/tests/Makefile +++ /dev/null @@ -1,11 +0,0 @@ - -!include ..\..\..\Defines.mak - -all: - for %d in (*.kmn) do $(PROGRAM)\bin\kmc.cmd build "%d" - -.kmn.kmx: - &$(PROGRAM)\bin\kmc.cmd build $** - -clean: - -del *.kmx diff --git a/windows/src/test/manual-tests/test_httpuploader/Makefile b/windows/src/test/manual-tests/test_httpuploader/Makefile deleted file mode 100644 index b6250f4bfd..0000000000 --- a/windows/src/test/manual-tests/test_httpuploader/Makefile +++ /dev/null @@ -1,18 +0,0 @@ -# -# test_httpuploader Makefile -# - -!include ..\..\Defines.mak - -build: version.res manifest.res - $(DCC32) test_httpuploader.dpr - -icons: - rc icons.rc - -clean: def-clean - -signcode: - rem no signcode - -!include ..\..\Target.mak From 91465f22b3770d163f27f388d32e2b4d161cd30a Mon Sep 17 00:00:00 2001 From: Keyman Build Agent Date: Fri, 23 Aug 2024 14:03:25 -0400 Subject: [PATCH 30/35] auto: increment master version to 18.0.97 --- HISTORY.md | 9 +++++++++ VERSION.md | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 2ee27cd198..bf768c67d5 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,14 @@ # Keyman Version History +## 18.0.96 alpha 2024-08-23 + +* fix(android): Fix navigation arrows in Info Activity for RTL (#12244) +* fix(web): fix documentation-keyboard spacebar-text scaling (#12232) +* fix(android): Use increment and decrement arrows on longpress delay menu (#12242) +* fix(android): Add RTL assets for adjusting keyboard height menu (#12261) +* chore(common): use `npm install` in emsdk update (#12269) +* docs: refresh windows.md (#12248) + ## 18.0.95 alpha 2024-08-22 * chore(common): allow build agents to automatically select emsdk version, and enable support for 3.1.60+ (#12243) diff --git a/VERSION.md b/VERSION.md index 998f9bf6fd..2558c437be 100644 --- a/VERSION.md +++ b/VERSION.md @@ -1 +1 @@ -18.0.96 \ No newline at end of file +18.0.97 \ No newline at end of file From 6bfa8a438f76efa2e5f03bc1dad7e629a3602890 Mon Sep 17 00:00:00 2001 From: Eberhard Beilharz Date: Fri, 23 Aug 2024 15:30:40 +0200 Subject: [PATCH 31/35] refactor(linux): cleanup API of kvk2ldml.py Make methods private that are only used inside of kvk2ldml.py. --- linux/keyman-config/keyman_config/kvk2ldml.py | 70 +++++++++---------- 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/linux/keyman-config/keyman_config/kvk2ldml.py b/linux/keyman-config/keyman_config/kvk2ldml.py index 5b3ab85ae8..3b3aee281b 100755 --- a/linux/keyman-config/keyman_config/kvk2ldml.py +++ b/linux/keyman-config/keyman_config/kvk2ldml.py @@ -164,43 +164,43 @@ VKey_to_Iso = { } -def bytecheck(value, check): +def _bytecheck(value, check): if bytes([value & check[0]]) == check: return True else: return False -def get_nkey(file, fileContent, offset): +def _get_nkey(file, fileContent, offset): nkey = NKey() data = struct.unpack_from(" 256: @@ -224,7 +224,7 @@ def get_nstring(file, fileContent, offset): return stringdata.decode('utf-16'), offset + 2 + (2 * stringlength[0]) -def get_nbitmap(file, fileContent, offset): +def _get_nbitmap(file, fileContent, offset): bitmap = None bitmaplength = struct.unpack_from(" Date: Sat, 24 Aug 2024 00:15:33 +0200 Subject: [PATCH 32/35] fix(developer): find last matching key in LDML key bag when building KVK Fixes: #12056 --- .../src/compiler/visual-keyboard-compiler.ts | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/developer/src/kmc-ldml/src/compiler/visual-keyboard-compiler.ts b/developer/src/kmc-ldml/src/compiler/visual-keyboard-compiler.ts index 6182e6e2c8..4c51078af8 100644 --- a/developer/src/kmc-ldml/src/compiler/visual-keyboard-compiler.ts +++ b/developer/src/kmc-ldml/src/compiler/visual-keyboard-compiler.ts @@ -3,6 +3,23 @@ import { LDMLKeyboard, CompilerCallbacks } from "@keymanapp/developer-utils"; import { KeysCompiler } from "./keys.js"; import { LdmlCompilerMessages } from "./ldml-compiler-messages.js"; +// This is a partial polyfill for findLast, so not polluting Array.prototype +// +// TODO: remove and replace with Array.prototype.findLast when it is +// well-supported +function findLast(arr: any, callback: any) { + if (!arr) { + return undefined; + } + const len = arr.length >>> 0; + for (let i = len - 1; i >= 0; i--) { + if (callback(arr[i], i, arr)) { + return arr[i]; + } + } + return undefined; +} + export class LdmlKeyboardVisualKeyboardCompiler { public constructor(private callbacks: CompilerCallbacks) { } @@ -57,7 +74,8 @@ export class LdmlKeyboardVisualKeyboardCompiler { const keyId = key; x++; - let keydef = source.keyboard3.keys?.key?.find(x => x.id == key); + //@ts-ignore + let keydef = findLast(source.keyboard3.keys?.key, x => x.id == key); if (!keydef) { this.callbacks.reportMessage( From b0e8b903740f307bbcccdee3a1274a998f30f204 Mon Sep 17 00:00:00 2001 From: Keyman Build Agent Date: Sat, 24 Aug 2024 14:03:24 -0400 Subject: [PATCH 33/35] auto: increment master version to 18.0.98 --- HISTORY.md | 7 +++++++ VERSION.md | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index bf768c67d5..904e03468a 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,12 @@ # Keyman Version History +## 18.0.97 alpha 2024-08-24 + +* refactor(linux): cleanup API of kvk2ldml.py (#12276) +* chore(common): adjust build settings for windows clean builds (#12264) +* chore(windows): remove remaining unused Makefiles (#12274) +* docs(developer): update build documentation to refer to build.sh (#12272) + ## 18.0.96 alpha 2024-08-23 * fix(android): Fix navigation arrows in Info Activity for RTL (#12244) diff --git a/VERSION.md b/VERSION.md index 2558c437be..48b8081cd1 100644 --- a/VERSION.md +++ b/VERSION.md @@ -1 +1 @@ -18.0.97 \ No newline at end of file +18.0.98 \ No newline at end of file From 6353f926ba31f8d776a05cfd395770f580cd2dfd Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Mon, 26 Aug 2024 09:09:00 +0200 Subject: [PATCH 34/35] chore: Update developer/src/kmc-ldml/src/compiler/visual-keyboard-compiler.ts --- developer/src/kmc-ldml/src/compiler/visual-keyboard-compiler.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/developer/src/kmc-ldml/src/compiler/visual-keyboard-compiler.ts b/developer/src/kmc-ldml/src/compiler/visual-keyboard-compiler.ts index 4c51078af8..6d76bc403e 100644 --- a/developer/src/kmc-ldml/src/compiler/visual-keyboard-compiler.ts +++ b/developer/src/kmc-ldml/src/compiler/visual-keyboard-compiler.ts @@ -4,7 +4,7 @@ import { KeysCompiler } from "./keys.js"; import { LdmlCompilerMessages } from "./ldml-compiler-messages.js"; // This is a partial polyfill for findLast, so not polluting Array.prototype -// +// https://medium.com/@stheodorejohn/findlast-method-polyfill-in-javascript-bridging-browser-gaps-c3baf6aabae1 // TODO: remove and replace with Array.prototype.findLast when it is // well-supported function findLast(arr: any, callback: any) { From 8c959f7eb2697895e4e94bda9531fd0af736e435 Mon Sep 17 00:00:00 2001 From: Darcy Wong Date: Mon, 26 Aug 2024 14:35:54 +0700 Subject: [PATCH 35/35] chore(android): Cleanup stray debug statements in console --- android/KMEA/app/src/main/assets/android-host.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/android/KMEA/app/src/main/assets/android-host.js b/android/KMEA/app/src/main/assets/android-host.js index 62d396aae0..5e5d724123 100644 --- a/android/KMEA/app/src/main/assets/android-host.js +++ b/android/KMEA/app/src/main/assets/android-host.js @@ -117,7 +117,7 @@ function notifyHost(event, params) { function setLongpressDelay(delay) { if (keyman.osk) { keyman.osk.gestureParams.longpress.waitLength = delay; - console.debug('setLongpressDelay('+delay+')'); + console_debug('setLongpressDelay('+delay+')'); } else { window.console.log('setLongpressDelay error: keyman.osk undefined'); } @@ -304,7 +304,7 @@ function updateKMSelectionRange(start, end) { console_debug('result:\n' + build_context_string(context)); } else { - console.debug('range unchanged'); + console_debug('range unchanged'); } }