fix(mac): Modifier keys were resetting cached context

Fixes #2375.

For applications that do not provide context to Keyman, Keyman was losing
the context buffer whenever a modifier key was pressed or released. This
change modifies the cache reset to occur only when the Command modifier is
pressed.
This commit is contained in:
Marc Durdin 2020-02-05 19:32:03 +11:00
parent 81b2a164b0
commit f856785742
4 changed files with 72 additions and 18 deletions

View file

@ -525,8 +525,22 @@ NSRange _previousSelRange;
/*if (event.type == NSKeyDown)
[self.AppDelegate handleKeyEvent:event];*/
if (event.type == NSFlagsChanged) {
_contextOutOfDate = YES;
if (event.type == NSEventTypeFlagsChanged) {
// We mark the context as out of date only for the Command keys
switch([event keyCode]) {
case kVK_RightCommand:
case kVK_Command:
_contextOutOfDate = YES;
break;
case kVK_Shift:
case kVK_RightShift:
case kVK_CapsLock:
case kVK_Option:
case kVK_RightOption:
case kVK_Control:
case kVK_RightControl:
break;
}
return NO;
}

View file

@ -322,7 +322,7 @@
}
}
else {
[mStr appendString:[NSString stringWithFormat:@"%C", c]];
[mStr appendString:[NSString stringWithFormat:@"U+%x", c]];
i++;
}
}

View file

@ -1,16 +1,34 @@
# Keyman for macOS
## Mac Tools Requirements/Setup
Install Xcode 8.3.3 or later (it might also work to use an older version)
Install Xcode 11.3.1 or later (it might also work to use an older version)
Install [Carthage](https://github.com/Carthage/Carthage/blob/master/README.md) *see Homebrew note below
Install cocoapods (sudo gem install cocoapods) if not already installed.
## Keyman for macOS Development
Keyman for macOS can be built from a command line (preferred) or Xcode.
### Setting up your code signing and notarization environment.
With macOS 10.14 and later, Keyman must be signed then notarized by Apple, even for local
test builds. This requires additional configuration for your build environment.
With macOS 10.14 and later, Keyman must be notarized in order to be permitted to interact with
keyboard input. You have two options for local builds:
1. You can disable security checks for the system with the command:
`sudo spctl --master-disable`
This has obvious security implications and the risk is up to you. However, builds are
much, much, faster than with the alternative option below, and for extensive local
debugging is far less painful.
2. Or, you must sign and notarize every build. See below. (Use --deploy local)
### Signing and notarizing builds
Keyman must be signed then notarized by Apple, even for local test builds. This requires additional
configuration for your build environment.
1. First, open XCode, Preferences, Accounts, and select Manage Certificates for the identity
you wish to use for signing. Click **+** and select **Developer ID Application**. A
@ -37,6 +55,7 @@ test builds. This requires additional configuration for your build environment.
export APPSTORECONNECT_PASSWORD=<Password>
### Compiling from Command Line
To build Keyman for macOS, do the following:
1. Open a Terminal window.
2. cd to **keyman/mac**. **build.sh** must be run in the directory containing the script.
@ -48,15 +67,17 @@ To build Keyman for macOS, do the following:
Note: If Carthage prompts you to allow it access to your github credentials, it's fine to click Deny.
### Running Keyman
1. Deploy Keyman locally using `./build.sh -deploy local -deploy-only`.
* This will notarize the app, signing with your local credentials if not already signed, and copy **keyman/mac/Keyman4MacIM/build/Debug/Keyman.app** to **~/Library/Input Methods**
2. If running for the first time, follow the installation instructions at
[Installing Keyman for Mac OS X](https://help.keyman.com/products/mac/1.0/docs/start_download-install_keyman.php).
You can also use `./build.sh -no-codesign -deploy local` to do a single-step build, notarize,
and deploy.
and deploy (see above for faster options).
### Compiling from Xcode
To build using Xcode, you will need to build KeymanEngine4Mac first and then build Keyman4MacIM. The very _first_ time after getting the source code (and any time the Podfile is edited; e.g., to install new pods), you need to go to **keyman/mac/Keyman4MacIM** and run "pod install" in Terminal.
1. Launch Xcode
@ -71,16 +92,18 @@ To build using Xcode, you will need to build KeymanEngine4Mac first and then bui
6. Build the project. Refer to [Running Keyman](#running-keyman) on how to install the app.
### Testing
The Keyman4Mac project builds a test-bed app that can be used to test keyboards without installing the input method.
It can also be used as reference for the usage of Keyman Engine.
Keyman4Mac tests are run using `./build.sh -test -no-codesign`.
*note about Homebrew:
Installing Carthage directly from the pkg file is simple. Homebrew seemed simple, but it
changes a lot of settings and I think it messed up the build in a way that took me a long
time to sort out. One specific problem is that using Homebrew seems to mess up the
command-line tools, so you will probably get this error from xcodebuild:
Error: xcode-select: error: tool 'xcodebuild' requires Xcode, but active developer directory is a command line tools instance
To fix it run this command:
sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer
### A note about Homebrew and xcodebuild
If you get this error from xcodebuild:
`Error: xcode-select: error: tool 'xcodebuild' requires Xcode, but active developer directory is a command line tools instance`
Then run this command to fix the build environment:
`sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer`

View file

@ -14,6 +14,7 @@ display_usage() {
echo " -deploy DEST Deploys result of Keyman4MacIM. DEST options:"
echo " n|none (default) Not deployed."
echo " l|local $HOME/Library/Input Methods (kills running process if needed)"
echo " q|quicklocal Same as local but does not notarize the build (see README.md)"
echo " p|preprelease Builds a DMG and download_info file in output\upload."
echo " -deploy-only Suppresses build/clean/test for all targets."
echo " -tier TIER Used with -deploy p to specify tier: alpha (default), beta, or stable."
@ -128,6 +129,7 @@ BUILD_ACTIONS="build"
TEST_ACTION=""
CLEAN=false
QUIET=false
NOTARIZE=false
SKIP_BUILD=false
# Parse args
@ -142,9 +144,15 @@ while [[ $# -gt 0 ]] ; do
# the deployed version cannot be run in the debugger.
if [[ "$2" =~ ^(l(ocal)?)$ ]]; then
LOCALDEPLOY=true
NOTARIZE=true
CONFIG="Release"
elif [[ "$2" =~ ^(q(uick(local)?)?)$ ]]; then
LOCALDEPLOY=true
NOTARIZE=false
CONFIG="Release"
elif [[ "$2" =~ ^(p(rep(release)?)?)$ ]]; then
PREPRELEASE=true
NOTARIZE=true
CONFIG="Release"
elif ! [[ "$2" =~ ^(n(one)?)$ ]]; then
fail "Invalid deploy option. Must be 'none', 'local' or 'preprelease'."
@ -265,7 +273,16 @@ displayInfo "" \
### Validate notarization environment variables ###
if $LOCALDEPLOY || $PREPRELEASE ; then
if $LOCALDEPLOY && ! $NOTARIZE ; then
if [ "$(spctl --status)" == "assessments enabled" ]; then
echo
warn "WARNING: Notarization is disabled but SecAssessment security policy is still active. Keyman will not run correctly."
warn " Disable SecAssessment with 'sudo spctl --master-disable' (or do notarized builds)"
fail "Re-run with '-deploy local' or disable SecAssessment."
fi
fi
if $PREPRELEASE || $NOTARIZE ; then
if [ "${CODESIGNING_SUPPRESSION}" != "" ] && [ -z "${CERTIFICATE_ID}" ]; then
fail "Code signing must be configured for deployment. See build.sh -help for details."
fi
@ -370,9 +387,9 @@ if $DO_KEYMANTESTAPP ; then
execBuildCommand $TESTAPP_NAME "xcodebuild -project \"$KMTESTAPP_PROJECT_PATH\" $BUILD_OPTIONS $BUILD_ACTIONS"
fi
### Notarize the app for localdeploy and preprelease ###
### Notarize the app for preprelease ###
if $LOCALDEPLOY || $PREPRELEASE ; then
if $PREPRELEASE || $NOTARIZE; then
echo_heading "Notarizing app"
if [ "${CODESIGNING_SUPPRESSION}" != "" ] && [ -z "${CERTIFICATE_ID}" ]; then
fail "Notarization and signed executable is required for deployment, even locally. Specify CERTIFICATE_ID environment variable for custom certificate."