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) NSMainNibFile MainMenu NSPrincipalClass 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);