diff --git a/android/history.md b/android/history.md
index ccc4e84519..22d96a690b 100644
--- a/android/history.md
+++ b/android/history.md
@@ -3,6 +3,12 @@
## 12.0 alpha
* Started work on Keyman for Android 12.
+## 2019-02-25 11.0.2100 stable
+* 11.0 Stable release
+
+## 2019-02-15 11.0.2062 beta
+* No changes.
+
## 2019-02-07 11.0.2061 beta
* Bug fix:
* Add notifications when keyboard or font fails to download from Keyman cloud (#1570)
diff --git a/ios/history.md b/ios/history.md
index bb415d7984..292942c1f8 100644
--- a/ios/history.md
+++ b/ios/history.md
@@ -1,8 +1,15 @@
# Keyman for iPhone and iPad Version History
## 12.0 alpha
+* Started work on Keyman for iPhone and iPad 12.
-## 2019 01-04 11.0.302 beta
+## 2019-02-25 11.0.320 stable
+* 11.0 Stable release
+
+## 2019-02-25 11.0.302 beta
+* Keyman now works again on iOS 9.3.5 (#1588)
+
+## 2019-01-04 11.0.301 beta
* Improves loading efficiency of system keyboard, helping prevent related crashes (#1475)
## 2019-01-02 11.0.300 beta
diff --git a/linux/history.md b/linux/history.md
index ab99512c4c..ac2698307a 100644
--- a/linux/history.md
+++ b/linux/history.md
@@ -3,22 +3,46 @@
## 12.0 alpha
* Started work on Keyman for Linux 12
+## 2019-02-25 11.0.120 stable
+* 11.0 Stable release
+
+## 2019-02-22 11.0.111 beta
+* Use lowercase ID and kmx filenames when installing .kmp packages (#1601)
+
+## 2019-02-19 11.0.110 beta
+* Update readme about launchpad (#1574)
+
## 2019-02-18 11.0.109 beta
-* create appstream appdata for keyman-config (#1543)
+* Create appstream appdata for keyman-config (#1543)
## 2019-02-15 11.0.108 beta
-* handle keyboard package install/uninstall when languages aren't defined (#1585)
+* Handle keyboard package install/uninstall when languages aren't defined (#1585)
## 2019-02-08 11.0.107 beta
-* add disco distribution information (#1572)
+* Add disco distribution information (#1572)
## 2019-02-05 11.0.106 beta
-* update readme about packaging and fix build.sh script (#1565)
+* Update readme about packaging and fix build.sh script (#1565)
+* Bugfix for potential utf overrun in Keyman Core (#1547)
## 2019-01-10 11.0.105 beta
-* add icons for km-config and .kmp files (#1495)
-* restart ibus as user and on gnome-shell (#1510,#1521)
-* build on xenial (#1518,#1477)
+* Restart ibus as user and on gnome-shell (#1510,#1521)
+* Build on xenial (#1518,#1477)
+* Remove debconf template not needed any more (#1497)
+
+## 2019-01-04 11.0.104 beta
+* Add km-config and .kmp icons (#1495)
+
+## 2019-01-04 11.0.103 beta
+* No changes.
+
+## 2019-01-04 11.0.102 beta
+* Initial build of Keyman Core on xenial (#1477)
+* Auto restart IBus when apt and kbp versioning (#1468)
+* Fix majorversion which broke download window (#1490)
+
+## 2019-01-03 11.0.101 beta
+* No changes.
## 2019-01-02 11.0.100 beta
* Initial beta release of Keyman for Linux
diff --git a/linux/keyman-config/keyman_config/ibus_util.py b/linux/keyman-config/keyman_config/ibus_util.py
index 9108656367..afa9acc9fa 100644
--- a/linux/keyman-config/keyman_config/ibus_util.py
+++ b/linux/keyman-config/keyman_config/ibus_util.py
@@ -30,6 +30,7 @@ def install_to_ibus(bus, keyboard_id):
preload_engines = ibus_settings.get_strv("preload-engines")
logging.debug(preload_engines)
if keyboard_id not in preload_engines:
+ # TODO: in the event preload_engines contains upper-case keyboards, we'll need to uninstall_from_ibus #1601
preload_engines.append(keyboard_id)
logging.debug(preload_engines)
ibus_settings.set_strv("preload-engines", preload_engines)
diff --git a/linux/keyman-config/keyman_config/install_kmp.py b/linux/keyman-config/keyman_config/install_kmp.py
index 9d02050eb0..5e9169fa5f 100755
--- a/linux/keyman-config/keyman_config/install_kmp.py
+++ b/linux/keyman-config/keyman_config/install_kmp.py
@@ -115,6 +115,10 @@ def check_keyman_dir(basedir, error_message):
raise InstallError(InstallStatus.Abort, error_message)
os.mkdir(keyman_dir)
+def extract_package_id(inputfile):
+ packageID, ext = os.path.splitext(os.path.basename(inputfile))
+ return packageID.lower()
+
def install_kmp_shared(inputfile, online=False):
"""
Install a kmp file to /usr/local/share/keyman
@@ -127,7 +131,7 @@ def install_kmp_shared(inputfile, online=False):
check_keyman_dir('/usr/local/share/doc', "You do not have permissions to install the documentation to the shared documentation area /usr/local/share/doc/keyman")
check_keyman_dir('/usr/local/share/fonts', "You do not have permissions to install the font files to the shared font area /usr/local/share/fonts")
- packageID, ext = os.path.splitext(os.path.basename(inputfile))
+ packageID = extract_package_id(inputfile)
packageDir = os.path.join('/usr/local/share/keyman', packageID)
kmpdocdir = os.path.join('/usr/local/share/doc/keyman', packageID)
kmpfontdir = os.path.join('/usr/local/share/fonts/keyman', packageID)
@@ -173,10 +177,17 @@ def install_kmp_shared(inputfile, online=False):
name, ext = os.path.splitext(f['name'])
ldmlfile = os.path.join(packageDir, name+".ldml")
output_ldml(ldmlfile, ldml)
- # Special handling of icon to convert to PNG
elif ftype == KMFileTypes.KM_ICON:
+ # Special handling of icon to convert to PNG
logging.info("Converting %s to PNG and installing both as keyman files", f['name'])
checkandsaveico(fpath)
+ elif ftype == KMFileTypes.KM_KMX:
+ # Sanitize keyboard filename if not lower case
+ kmx_id, ext = os.path.splitext(os.path.basename(f['name']))
+ for kb in keyboards:
+ if kmx_id.lower() == kb['id'] and kmx_id != kb['id']:
+ os.rename(os.path.join(packageDir, f['name']), os.path.join(packageDir, kb['id']+'.kmx'))
+
for kb in keyboards:
# install all kmx for first lang not just packageID
kmx_file = os.path.join(packageDir, kb['id'] + ".kmx")
@@ -191,7 +202,7 @@ def install_kmp_shared(inputfile, online=False):
raise InstallError(InstallStatus.Abort, message)
def install_kmp_user(inputfile, online=False):
- packageID, ext = os.path.splitext(os.path.basename(inputfile))
+ packageID = extract_package_id(inputfile)
packageDir=user_keyboard_dir(packageID)
if not os.path.isdir(packageDir):
os.makedirs(packageDir)
@@ -234,6 +245,13 @@ def install_kmp_user(inputfile, online=False):
elif ftype == KMFileTypes.KM_SOURCE:
#TODO for the moment just leave it for ibus-kmfl to ignore if it doesn't load
pass
+ elif ftype == KMFileTypes.KM_KMX:
+ # Sanitize keyboard filename if not lower case
+ kmx_id, ext = os.path.splitext(os.path.basename(f['name']))
+ for kb in keyboards:
+ if kmx_id.lower() == kb['id'] and kmx_id != kb['id']:
+ os.rename(os.path.join(packageDir, f['name']), os.path.join(packageDir, kb['id']+'.kmx'))
+
install_keyboards_to_ibus(keyboards, packageDir)
else:
logging.error("install_kmp.py: error: No kmp.json or kmp.inf found in %s", inputfile)
diff --git a/linux/scripts/launchpad.sh b/linux/scripts/launchpad.sh
index 815d8975b1..206e3d9e63 100755
--- a/linux/scripts/launchpad.sh
+++ b/linux/scripts/launchpad.sh
@@ -23,8 +23,9 @@ if [[ -z "${TIER}" ]]; then
# This is the tier that the latest version is currently found on
# This should be changed to stable before the first stable build
# In master branch this should be alpha and the debian/watch files should check alpha dir
- tier="beta"
-# tier="stable"
+# tier="alpha"
+# tier="beta"
+ tier="stable"
else
tier="${TIER}"
fi
diff --git a/mac/Keyman4MacIM/Keyman4MacIM.xcodeproj/project.pbxproj b/mac/Keyman4MacIM/Keyman4MacIM.xcodeproj/project.pbxproj
index b5a23b5c7d..a50fd02839 100644
--- a/mac/Keyman4MacIM/Keyman4MacIM.xcodeproj/project.pbxproj
+++ b/mac/Keyman4MacIM/Keyman4MacIM.xcodeproj/project.pbxproj
@@ -522,8 +522,8 @@
isa = PBXNativeTarget;
buildConfigurationList = 989C9C251A7876DE00A20425 /* Build configuration list for PBXNativeTarget "Keyman" */;
buildPhases = (
- 9A5A4B1321F78E0100B31301 /* Assert version number same as git branch */,
D2FF67BB6C749BA6861F5E25 /* [CP] Check Pods Manifest.lock */,
+ 9A5A4B1321F78E0100B31301 /* Assert version number same as git branch */,
E2588F2E1F2644850061C9C4 /* Run Script */,
989C9C041A7876DE00A20425 /* Sources */,
989C9C051A7876DE00A20425 /* Frameworks */,
diff --git a/mac/Keyman4MacIM/Keyman4MacIM/Info.plist b/mac/Keyman4MacIM/Keyman4MacIM/Info.plist
index 70f45ce08e..4a41c7574f 100644
--- a/mac/Keyman4MacIM/Keyman4MacIM/Info.plist
+++ b/mac/Keyman4MacIM/Keyman4MacIM/Info.plist
@@ -79,7 +79,7 @@
LSMinimumSystemVersion$(MACOSX_DEPLOYMENT_TARGET)NSHumanReadableCopyright
- $(COPYRIGHT_STRING_RIGHTS)
+ $(COPYRIGHT_STRING)NSMainNibFileMainMenuNSPrincipalClass
diff --git a/mac/Keyman4MacIM/Keyman4MacIM/KMAboutWindow/KMAboutWindowController.m b/mac/Keyman4MacIM/Keyman4MacIM/KMAboutWindow/KMAboutWindowController.m
index 45762ae55d..eec24f9478 100644
--- a/mac/Keyman4MacIM/Keyman4MacIM/KMAboutWindow/KMAboutWindowController.m
+++ b/mac/Keyman4MacIM/Keyman4MacIM/KMAboutWindow/KMAboutWindowController.m
@@ -14,6 +14,9 @@
@property (nonatomic, weak) IBOutlet NSTextField *versionLabel;
@property (nonatomic, weak) IBOutlet NSTextField *copyrightLabel;
@property (nonatomic, weak) IBOutlet NSButton *licenseButton;
+// not needed at the moment but might be:
+@property (nonatomic, weak) IBOutlet NSButton *closeButton;
+@property (nonatomic, weak) IBOutlet NSButton *configureButton;
@end
@implementation KMAboutWindowController
diff --git a/mac/Keyman4MacIM/Keyman4MacIM/KMAboutWindow/KMAboutWindowController.xib b/mac/Keyman4MacIM/Keyman4MacIM/KMAboutWindow/KMAboutWindowController.xib
index bfc57e988e..d358daf35c 100644
--- a/mac/Keyman4MacIM/Keyman4MacIM/KMAboutWindow/KMAboutWindowController.xib
+++ b/mac/Keyman4MacIM/Keyman4MacIM/KMAboutWindow/KMAboutWindowController.xib
@@ -1,8 +1,8 @@
-
+
-
+
@@ -16,7 +16,7 @@
-
+
@@ -41,36 +41,23 @@
-
-
+
-
+
-
+
-
-
+
+
-
-
+
+
@@ -78,29 +65,31 @@
diff --git a/mac/history.md b/mac/history.md
index 85b09bfa47..533eb4b50c 100644
--- a/mac/history.md
+++ b/mac/history.md
@@ -1,6 +1,15 @@
# Keyman for macOS Version History
## 12.0 alpha
+* Started work on Keyman for macOS 12.
+
+## 2019-02-25 11.0.220 stable
+* 11.0 Stable release
+
+## 2019-02-20 11.0.201 beta
+* Update version strings to 11.0.0 (#1583)
+* Workaround bug in macOS 10.13.1-10.13.3 which caused preferences dialog to fail to appear (#1447)
+* Fix broken About dialog (#1594)
## 2019-01-02 11.0.200 beta
* Initial beta release of Keyman for macOS 11
diff --git a/web/history.md b/web/history.md
index 69fe22edad..3c9d239077 100644
--- a/web/history.md
+++ b/web/history.md
@@ -8,16 +8,31 @@
* Centralizes code paths to improve parity between hardware and OSK-based keystrokes.
* In both cases above, significant unit testing was facilitated and has been added as a result, further improving code maintainability into the future.
+## 2019-02-25 11.0.220 stable
+* 11.0 Stable release
+
+## 2019-02-25 11.0.208 beta
+* KeymanWeb now works again in Safari on iOS 9.3.5 (#1588)
+
+## 2019-01-18 11.0.206 beta
+* Change: Update beta version and remove hardcoded version strings (#1537)
+
+## 2019-01-17 11.0.205 beta
+* New Feature: The `displayUnderlying` flag for showing base layout key caps is now available per-platform. (#1539)
+* Bug Fix: Fix missing text on spacebar and update Karma version (#1540)
+
+## 2019-01-15 11.0.204 beta
+* No changes
+
+## 2019-01-11 11.0.203 beta
+* Add default mapping for K_oE2 (102nd key) (#1491)
+
## 2019-01-04 11.0.202 beta
-* Bug Fix:
- * Fixed external keyboard keys "tab" and "backspace" for embedded platforms (#1474)
+* Bug Fix: Fixed external keyboard keys "tab" and "backspace" for embedded platforms (#1474)
## 2019-01-03 11.0.201 beta
-* New Feature:
- * Adds the alignInputs() API function to facilitate touch-alias element work-arounds in case of future issues. (#69)
-
-* Bug Fix:
- * Fixed keyboard layer transition bug on mobile devices. (#978)
+* New Feature: Adds the alignInputs() API function to facilitate touch-alias element work-arounds in case of future issues. (#69)
+* Bug Fix: Fixed keyboard layer transition bug on mobile devices. (#978)
## 2019-01-02 11.0.200 beta
* Initial beta release of KeymanWeb 11
diff --git a/windows/src/desktop/history.md b/windows/src/desktop/history.md
index ec2741c1fb..bdf8a51a3e 100644
--- a/windows/src/desktop/history.md
+++ b/windows/src/desktop/history.md
@@ -1,10 +1,29 @@
# Keyman Desktop Version History
## 12.0 alpha
+* Started work on Keyman Desktop 12.
-## 2019-02-13 11.0.1308.0 beta
+## 2019-02-25 11.0.1350.0 stable
+* 11.0 Stable release
+
+## 2019-02-25 11.0.1313.0 beta
+* Bug Fix: AltGr causes sticky Left Control when some Windows European layouts are installed. (#1621)
+
+## 2019-02-21 11.0.1312.0 beta
+* Bug Fix: Make sure backspace in Word (TSF) deletes both halves of surrogate pair for supplementary multilingual plane scripts (#1603)
+
+## 2019-02-20 11.0.1311.0 beta
+* Minor tweaks to Kannada localization (#1598)
+
+## 2019-02-19 11.0.1310.0 beta
+* No changes to Keyman Desktop
+
+## 2019-02-15 11.0.1309.0 beta
* Bug Fix: Upgrading from 9.0 to 11.0 did not preserve keyboards and settings (#1548)
+## 2019-02-14 11.0.1308.0 beta
+* No changes to Keyman Desktop
+
## 2019-02-01 11.0.1307.0 beta
* No changes to Keyman Desktop
diff --git a/windows/src/developer/history.md b/windows/src/developer/history.md
index 637df74a65..5dc10bb059 100644
--- a/windows/src/developer/history.md
+++ b/windows/src/developer/history.md
@@ -1,15 +1,34 @@
# Keyman Developer Version History
## 12.0 alpha
+* Started work on Keyman Developer 12.
-## 2019-02-14 11.0.1308.0 beta
-* Change: Adds option to check filename conventions (#1549)
+## 2019-02-25 11.0.1350.0 stable
+* 11.0 Stable release
+
+## 2019-02-25 11.0.1313.0 beta
+* No changes to Keyman Developer
+
+## 2019-02-21 11.0.1312.0 beta
+* Bug fix: Connect buttons to actions in Distribution tab in Project (#1606)
+* Bug fix: Fix crash saving new keyboard when missing files are referenced (#1605)
+* Bug fix: Fix resizing of text editor windows (#1607)
+
+## 2019-02-20 11.0.1311.0 beta
+* No changes to Keyman Developer
+
+## 2019-02-19 11.0.1310.0 beta
* Bug fix: Developer does not focus the text editor automatically after load (#1582)
+
+## 2019-02-15 11.0.1309.0 beta
* Bug fix: Developer was not maintaining project state between page loads (#1580)
* Bug fix: Developer now maintains the view state when switching between Design and Code views of touch layout editor (#1579)
* Bug fix: New Project Wizard wasn't adding metadata files to project (#1578)
* Bug Fix: Package RTL keyboard metadata was being overwritten if .kmx was after .js in package file list (#1576)
+## 2019-02-14 11.0.1308.0 beta
+* Change: Adds option to check filename conventions (#1549)
+
## 2019-02-01 11.0.1307.0 beta
* Change: Removed unused test window (#1560)
diff --git a/windows/src/engine/keyman32/keyman-debug-etw.man b/windows/src/engine/keyman32/keyman-debug-etw.man
index aea3d85447..e8c7331d3f 100644
--- a/windows/src/engine/keyman32/keyman-debug-etw.man
+++ b/windows/src/engine/keyman32/keyman-debug-etw.man
@@ -33,6 +33,7 @@
+
@@ -210,6 +211,7 @@
+
diff --git a/windows/src/engine/keyman32/serialkeyeventserver.cpp b/windows/src/engine/keyman32/serialkeyeventserver.cpp
index ffc0195082..a506950937 100644
--- a/windows/src/engine/keyman32/serialkeyeventserver.cpp
+++ b/windows/src/engine/keyman32/serialkeyeventserver.cpp
@@ -415,23 +415,90 @@ private:
*/
if (msg == wm_keyman_keyevent && flag_ShouldSerializeInput /*&& _td->lpActiveKeyboard*/) {
- INPUT input;
- input.type = INPUT_KEYBOARD;
- input.ki.wVk = (WORD)wParam;
- input.ki.wScan = (lParam & 0xFF0000) >> 16;
- input.ki.time = GetMessageTime();
- input.ki.dwExtraInfo = EXTRAINFO_FLAG_SERIALIZED_USER_KEY_EVENT;
- input.ki.dwFlags = lParam & 0xFFFF;
- if (!SendInput(1, &input, sizeof(INPUT))) {
- DebugLastError("SendInput");
+ if (wParam == VK_RMENU && (lParam & (KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP)) == (KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP) && GetKeyState(VK_LCONTROL) < 0) {
+ /*
+ When Windows has a European layout that uses AltGr installed, it can emit an additional LCtrl down via software
+ when RAlt is pressed. However, the corresponding LCtrl up is never received, seemingly because when Keyman
+ re-emits the LCtrl+RAlt, there are subtle differences in the event flags which we cannot duplicate -- specifically
+ the flag that emits WM_SYSKEYDOWN for the VK_LCONTROL, even though it is received before the VK_RALT event. It
+ appears that Windows figures this out by giving this VK_LCONTROL the scan code 0x21D instead of 0x1D. But we
+ are unable to emit that scan code: Windows truncates the scan code sent through SendInput so that we can only
+ send 0x1D.
+
+ So we simulate the release of the Left Control key ourselves when the release of the Right Alt is received,
+ using VK_CONTROL and scan 0x1D, and hope for the best.
+
+ The full Windows sequence is:
+
+ WM_SYSKEYDOWN VK_CONTROL 0x21D
+ WM_SYSKEYDOWN VK_MENU 0x38 EXTENDED_BIT
+ ...
+ WM_KEYUP VK_CONTROL 0x21D
+ WM_KEYUP VK_MENU 0x38 EXTENDED_BIT
+
+ The best Keyman can do is:
+
+ WM_KEYDOWN VK_CONTROL 0x1D
+ WM_KEYDOWN VK_MENU 0x38 EXTENDED_BIT
+ ...
+ WM_KEYUP VK_CONTROL 0x1D
+ WM_KEYUP VK_MENU 0x38 EXTENDED_BIT
+
+ There is a possibility that some apps may try and sniff that 0x21D scan code and get confused because Keyman
+ doesn't emit it. Hopefully this is rare.
+ */
+ INPUT input[2];
+ input[0].type = INPUT_KEYBOARD;
+ input[0].ki.wVk = VK_CONTROL;
+ input[0].ki.wScan = 0x21D; // Yeah, Windows chops this to 0x1D. Such is life.
+ input[0].ki.time = GetMessageTime();
+ input[0].ki.dwExtraInfo = EXTRAINFO_FLAG_SERIALIZED_USER_KEY_EVENT;
+ input[0].ki.dwFlags = KEYEVENTF_KEYUP;
+
+ input[1].type = INPUT_KEYBOARD;
+ input[1].ki.wVk = (WORD)wParam;
+ input[1].ki.wScan = (lParam & 0xFFF0000) >> 16;
+ input[1].ki.time = GetMessageTime();
+ input[1].ki.dwExtraInfo = EXTRAINFO_FLAG_SERIALIZED_USER_KEY_EVENT;
+ input[1].ki.dwFlags = lParam & 0xFFFF;
+
+ if (!SendInput(2, input, sizeof(INPUT))) {
+ DebugLastError("SendInput");
+ }
+
+ UpdateLocalModifierState(
+ (BYTE)input[0].ki.wVk,
+ input[0].ki.dwFlags & KEYEVENTF_EXTENDEDKEY ? TRUE : FALSE,
+ (BYTE)input[0].ki.wScan,
+ input[0].ki.dwFlags & KEYEVENTF_KEYUP ? TRUE : FALSE);
+
+ UpdateLocalModifierState(
+ (BYTE)input[1].ki.wVk,
+ input[1].ki.dwFlags & KEYEVENTF_EXTENDEDKEY ? TRUE : FALSE,
+ (BYTE)input[1].ki.wScan,
+ input[1].ki.dwFlags & KEYEVENTF_KEYUP ? TRUE : FALSE);
+ }
+ else {
+ INPUT input;
+ input.type = INPUT_KEYBOARD;
+ input.ki.wVk = (WORD)wParam;
+ input.ki.wScan = (lParam & 0xFFF0000) >> 16;
+ input.ki.time = GetMessageTime();
+ input.ki.dwExtraInfo = EXTRAINFO_FLAG_SERIALIZED_USER_KEY_EVENT;
+ input.ki.dwFlags = lParam & 0xFFFF;
+
+ if (!SendInput(1, &input, sizeof(INPUT))) {
+ DebugLastError("SendInput");
+ }
+
+ UpdateLocalModifierState(
+ (BYTE)input.ki.wVk,
+ input.ki.dwFlags & KEYEVENTF_EXTENDEDKEY ? TRUE : FALSE,
+ (BYTE)input.ki.wScan,
+ input.ki.dwFlags & KEYEVENTF_KEYUP ? TRUE : FALSE);
}
- UpdateLocalModifierState(
- (BYTE) input.ki.wVk,
- input.ki.dwFlags & KEYEVENTF_EXTENDEDKEY ? TRUE : FALSE,
- (BYTE) input.ki.wScan,
- input.ki.dwFlags & KEYEVENTF_KEYUP ? TRUE : FALSE);
}
return DefWindowProc(hwnd, msg, wParam, lParam);