Closed kamholz closed 4 years ago
Linux: This pull request is from an external repo and will not automatically be built. The build must still be passed before it can be merged. Ask one of the team members to make a manual build of this PR.
Mac: This pull request is from an external repo and will not automatically be built. The build must still be passed before it can be merged. Ask one of the team members to make a manual build of this PR.
Keymanweb:This pull request is from an external repo will not automatically be built. The build must still be passed before it can be merged. Ask one of the team members to make a manual build of this PR.
iOS: This pull request is from an external repo and will not automatically be built. The build must still be passed before it can be merged. Ask one of the team members to make a manual build of this PR.
Windows:This pull request is from an external repo will not automatically be built. The build must still be passed before it can be merged. Ask one of the team members to make a manual build of this PR.
Keymanweb:This pull request is from an external repo will not automatically be built. The build must still be passed before it can be merged. Ask one of the team members to make a manual build of this PR.
Windows:This pull request is from an external repo will not automatically be built. The build must still be passed before it can be merged. Ask one of the team members to make a manual build of this PR.
Keymanweb:This pull request is from an external repo will not automatically be built. The build must still be passed before it can be merged. Ask one of the team members to make a manual build of this PR.
Android:This pull request is from an external repo and will not automatically be built. The build must still be passed before it can be merged. Ask one of the team members to make a manual build of this PR.
Thank you for your pull request! This is great :)
I've had a quick review but may not have time to do a full review for a week because I am about to hop on a plane to fly to Canada for a conference.
We don't currently run the full set of keyboard unit tests on macOS, so would you be able to test these changes against the tests in common/engine/keyboardprocessor/tests/unit/kmx? The .kmx files there are in the repo to avoid having to build them on systems without kmcomp, so you should be able to rely on them working.
The macOS engine is not really factored for running tests automatically and in the roadmap we plan to replace this engine with the common Keyman Core engine (in common/engine) so I don't think we need to try automating the tests, just running them manually and confirming that they pass is fine.
One potential issue that I can see is that it doesn't appear that CODE_SAVEOPT
is persisting the store across user sessions, which is the intention of the option. If that's a huge change, I'd still be inclined to accept this PR as the functionality it introduces is better than no functionality. Let me know.
Sure, I'm happy to test against those keyboards. I didn't know about Keyman Core -- great that this will all be consolidated eventually, but this provides some of the functionality meanwhile, as you say.
I'll look into what it would take to persist save()
across user sessions. I'm learning as I go -- this was my first time coding in Objective C -- but maybe we can hook into the same mechanism for persisting preferences.
Mac: This pull request is from an external repo and will not automatically be built. The build must still be passed before it can be merged. Ask one of the team members to make a manual build of this PR.
The tests revealed a bug for keyboards where the right-hand side of a rule contains only some combination of set
/reset
/save
and no explicit nul
. I solved this by generating a Q_NUL
action for such cases, so the engine knows the key was processed.
It doesn't look like a simple fix to make save()
persist. I guess we'd have to re-write the .kmx file where it's stored? I don't really know.
I also found some dead key issues while testing. Submitting another PR momentarily that fixes those.
Mac: This pull request is from an external repo and will not automatically be built. The build must still be passed before it can be merged. Ask one of the team members to make a manual build of this PR.
OK, now supports persisting across sessions as well. Tested.
Mac: This pull request is from an external repo and will not automatically be built. The build must still be passed before it can be merged. Ask one of the team members to make a manual build of this PR.
I note that an exception came through for 12.0 (debug build) which means it most likely came from you?
Not sure if you have already addressed this but wanted to make sure it didn't go through to the keeper.
# Crashlytics - plaintext stacktrace downloaded by Marc Durdin at Sat, 22 Jun 2019 16:34:35 GMT
# URL: https://fabric.io/keyman/mac/apps/keyman.inputmethod.keyman/issues/24d7c0c0f9a78dc27a15d22f86514de3?time=last-ninety-days/sessions/600bcdf445dd4eb3adf1a8454505c865_DNE_0_v2
# Organization: Keyman-Debug
# Platform: mac_os_x
# Application: Keyman
# Version: 12.0
# Bundle Identifier: keyman.inputmethod.Keyman
# Issue ID: 24d7c0c0f9a78dc27a15d22f86514de3
# Session ID: 600bcdf445dd4eb3adf1a8454505c865_DNE_0_v2
# Date: 2019-06-21T14:59:00Z
# OS Version: 10.14.5 (18F132)
# Device: MacBook Pro Retina, 13", Early 2015
# RAM Free: 3.2%
# Disk Free: 11.9%
#0. Crashed: com.apple.main-thread
0 libobjc.A.dylib 0x7fff5bbba697 objc_msgSend + 23
1 CoreFoundation 0x7fff314943a5 +[__NSSingleEntryDictionaryI __new:::] + 80
2 CoreFoundation 0x7fff314a3534 -[NSDictionary initWithObjectsAndKeys:] + 767
3 KeymanEngine4Mac 0x1091baa42 -[KMEngine processKey:event:] (KMEngine.m:550)
4 KeymanEngine4Mac 0x1091b82f6 -[KMEngine processGroup:event:] (KMEngine.m:351)
5 KeymanEngine4Mac 0x1091b6afe -[KMEngine processEvent:] (KMEngine.m:120)
6 Keyman 0x108ecec50 -[KMInputMethodEventHandler handleKeymanEngineActions:in:] (KMInputMethodEventHandler.m:320)
7 Keyman 0x108ed087d -[KMInputMethodEventHandler handleEvent:client:] (KMInputMethodEventHandler.m:526)
8 Keyman 0x108ee0bdc -[KMInputController handleEvent:client:] (KMInputController.m:54)
9 InputMethodKit 0x10905d45a -[IMKServer handleEvent_Common:characterIndex:edge:clientWrapper:controller:] + 2296
10 InputMethodKit 0x109051fbd __63-[IMKServer handleEvent:characterIndex:edge:asyncClient:reply:]_block_invoke_2 + 690
11 ViewBridge 0x7fff58f0af8e +[NSServiceViewController withHostProcessIdentifier:invoke:] + 41
12 InputMethodKit 0x109051d00 __63-[IMKServer handleEvent:characterIndex:edge:asyncClient:reply:]_block_invoke + 143
13 InputMethodKit 0x10905e7da __IMKXPCPerformBlockOnMainThread_block_invoke + 25
14 CoreFoundation 0x7fff314a5164 __CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK__ + 12
15 CoreFoundation 0x7fff31468887 __CFRunLoopDoBlocks + 394
16 CoreFoundation 0x7fff314685e4 __CFRunLoopRun + 2772
17 CoreFoundation 0x7fff314678be CFRunLoopRunSpecific + 455
18 HIToolbox 0x7fff3075396b RunCurrentEventLoopInMode + 292
19 HIToolbox 0x7fff307536a5 ReceiveNextEventCommon + 603
20 HIToolbox 0x7fff30753436 _BlockUntilNextEventMatchingListInModeWithFilter + 64
21 AppKit 0x7fff2eaed987 _DPSNextEvent + 965
22 AppKit 0x7fff2eaec71f -[NSApplication(NSEvent) _nextEventMatchingEventMask:untilDate:inMode:dequeue:] + 1361
23 AppKit 0x7fff2eae683c -[NSApplication run] + 699
24 Keyman 0x108ec9309 main (main.m:21)
25 Keyman 0x108ebf8b4 start + 52
--
#0. Crashed: com.apple.main-thread
0 libobjc.A.dylib 0x7fff5bbba697 objc_msgSend + 23
1 CoreFoundation 0x7fff314943a5 +[__NSSingleEntryDictionaryI __new:::] + 80
2 CoreFoundation 0x7fff314a3534 -[NSDictionary initWithObjectsAndKeys:] + 767
3 KeymanEngine4Mac 0x1091baa42 -[KMEngine processKey:event:] (KMEngine.m:550)
4 KeymanEngine4Mac 0x1091b82f6 -[KMEngine processGroup:event:] (KMEngine.m:351)
5 KeymanEngine4Mac 0x1091b6afe -[KMEngine processEvent:] (KMEngine.m:120)
6 Keyman 0x108ecec50 -[KMInputMethodEventHandler handleKeymanEngineActions:in:] (KMInputMethodEventHandler.m:320)
7 Keyman 0x108ed087d -[KMInputMethodEventHandler handleEvent:client:] (KMInputMethodEventHandler.m:526)
8 Keyman 0x108ee0bdc -[KMInputController handleEvent:client:] (KMInputController.m:54)
9 InputMethodKit 0x10905d45a -[IMKServer handleEvent_Common:characterIndex:edge:clientWrapper:controller:] + 2296
10 InputMethodKit 0x109051fbd __63-[IMKServer handleEvent:characterIndex:edge:asyncClient:reply:]_block_invoke_2 + 690
11 ViewBridge 0x7fff58f0af8e +[NSServiceViewController withHostProcessIdentifier:invoke:] + 41
12 InputMethodKit 0x109051d00 __63-[IMKServer handleEvent:characterIndex:edge:asyncClient:reply:]_block_invoke + 143
13 InputMethodKit 0x10905e7da __IMKXPCPerformBlockOnMainThread_block_invoke + 25
14 CoreFoundation 0x7fff314a5164 __CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK__ + 12
15 CoreFoundation 0x7fff31468887 __CFRunLoopDoBlocks + 394
16 CoreFoundation 0x7fff314685e4 __CFRunLoopRun + 2772
17 CoreFoundation 0x7fff314678be CFRunLoopRunSpecific + 455
18 HIToolbox 0x7fff3075396b RunCurrentEventLoopInMode + 292
19 HIToolbox 0x7fff307536a5 ReceiveNextEventCommon + 603
20 HIToolbox 0x7fff30753436 _BlockUntilNextEventMatchingListInModeWithFilter + 64
21 AppKit 0x7fff2eaed987 _DPSNextEvent + 965
22 AppKit 0x7fff2eaec71f -[NSApplication(NSEvent) _nextEventMatchingEventMask:untilDate:inMode:dequeue:] + 1361
23 AppKit 0x7fff2eae683c -[NSApplication run] + 699
24 Keyman 0x108ec9309 main (main.m:21)
25 Keyman 0x108ebf8b4 start + 52
#1. com.twitter.crashlytics.mac.MachExceptionServer
0 Keyman 0x108f067be CLSProcessRecordAllThreads + 193
1 Keyman 0x108f06bb9 CLSProcessRecordAllThreads + 1212
2 Keyman 0x108ef6131 CLSHandler + 45
3 Keyman 0x108ef167c CLSMachExceptionServer + 1241
4 libsystem_pthread.dylib 0x7fff5d58a2eb _pthread_body + 126
5 libsystem_pthread.dylib 0x7fff5d58d249 _pthread_start + 66
6 libsystem_pthread.dylib 0x7fff5d58940d thread_start + 13
#2. com.apple.NSEventThread
0 libsystem_kernel.dylib 0x7fff5d4cb22a mach_msg_trap + 10
1 libsystem_kernel.dylib 0x7fff5d4cb76c mach_msg + 60
2 CoreFoundation 0x7fff31468bee __CFRunLoopServiceMachPort + 328
3 CoreFoundation 0x7fff3146815c __CFRunLoopRun + 1612
4 CoreFoundation 0x7fff314678be CFRunLoopRunSpecific + 455
5 AppKit 0x7fff2eaf56a6 _NSEventThread + 175
6 libsystem_pthread.dylib 0x7fff5d58a2eb _pthread_body + 126
7 libsystem_pthread.dylib 0x7fff5d58d249 _pthread_start + 66
8 libsystem_pthread.dylib 0x7fff5d58940d thread_start + 13
#3. com.apple.NSURLConnectionLoader
0 libsystem_kernel.dylib 0x7fff5d4cb22a mach_msg_trap + 10
1 libsystem_kernel.dylib 0x7fff5d4cb76c mach_msg + 60
2 CoreFoundation 0x7fff31468bee __CFRunLoopServiceMachPort + 328
3 CoreFoundation 0x7fff3146815c __CFRunLoopRun + 1612
4 CoreFoundation 0x7fff314678be CFRunLoopRunSpecific + 455
5 CFNetwork 0x7fff303db380 -[__CoreSchedulingSetRunnable runForever] + 210
6 Foundation 0x7fff336c16d2 __NSThread__start__ + 1194
7 libsystem_pthread.dylib 0x7fff5d58a2eb _pthread_body + 126
8 libsystem_pthread.dylib 0x7fff5d58d249 _pthread_start + 66
9 libsystem_pthread.dylib 0x7fff5d58940d thread_start + 13
#4. JavaScriptCore bmalloc scavenger
0 libsystem_kernel.dylib 0x7fff5d4ce86a __psynch_cvwait + 10
1 libsystem_pthread.dylib 0x7fff5d58d56e _pthread_cond_wait + 722
2 libc++.1.dylib 0x7fff5a5c8a0a std::__1::condition_variable::wait(std::__1::unique_lock<std::__1::mutex>&) + 18
3 JavaScriptCore 0x7fff34944122 void std::__1::condition_variable_any::wait<std::__1::unique_lock<bmalloc::Mutex> >(std::__1::unique_lock<bmalloc::Mutex>&) + 82
4 JavaScriptCore 0x7fff3494820b bmalloc::Scavenger::threadRunLoop() + 139
5 JavaScriptCore 0x7fff34947a39 bmalloc::Scavenger::threadEntryPoint(bmalloc::Scavenger*) + 9
6 JavaScriptCore 0x7fff349493a7 void* std::__1::__thread_proxy<std::__1::tuple<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct> >, void (*)(bmalloc::Scavenger*), bmalloc::Scavenger*> >(void*) + 39
7 libsystem_pthread.dylib 0x7fff5d58a2eb _pthread_body + 126
8 libsystem_pthread.dylib 0x7fff5d58d249 _pthread_start + 66
9 libsystem_pthread.dylib 0x7fff5d58940d thread_start + 13
#5. Thread
0 libsystem_kernel.dylib 0x7fff5d4ccbfe __workq_kernreturn + 10
1 libsystem_pthread.dylib 0x7fff5d5896e6 _pthread_wqthread + 634
2 libsystem_pthread.dylib 0x7fff5d5893fd start_wqthread + 13
3 (Missing) 0x54485244 (Missing)
#6. Thread
0 libsystem_kernel.dylib 0x7fff5d4ccbfe __workq_kernreturn + 10
1 libsystem_pthread.dylib 0x7fff5d589636 _pthread_wqthread + 458
2 libsystem_pthread.dylib 0x7fff5d5893fd start_wqthread + 13
3 (Missing) 0x0 (Missing)
Yes, that was me. Keyman crashed a few times while I was developing fixes. Not aware of any crashing code in the pull requests.
Mac: This pull request is from an external repo and will not automatically be built. The build must still be passed before it can be merged. Ask one of the team members to make a manual build of this PR.
Last commit fixes case where a store value is saved and restored across sessions, then reset()
is called. It would have reset to the default value rather than the saved value.
By the way, it would be pretty easy to detect whether a kmx
file has any set/reset/save
commands and only copy store
to storeSaved
in that case. Is that worth it or too much trouble? I don't know how much the memory savings would be, or how important that is compared to the (minor) cost of scanning the output fields in each key.
By the way, it would be pretty easy to detect whether a
kmx
file has anyset/reset/save
commands and only copystore
tostoreSaved
in that case. Is that worth it or too much trouble?
I'm inclined to think it would not be worth the added complexity (because that increases risk of bugs, etc.) as the cost is not significant, especially as most keyboards are typically less than 100kb. Optimisation can wait until we know it's needed.
-1/2 035 Tests basic option rules with save reset+set+reset [again, a mostly bad test which cannot execute half of the rules] [0 and 3 work, but 1 cannot be reached, nor 2 as only 1 sets 2]
Yes, these tests have a different input state which we cannot currently test on macOS. I'm inclined to not worry about them at this point.
Keyman for Mac 11.0.2 contains this fix.
This addresses #1832 by implementing support for
if()
,set()
,reset()
, andsave()
on macOS. These now behave as expected and there is no more garbage output.In order to support
reset()
andsave()
, I had to add another array of stores toKMXFile
(with saved values) and implementcopyWithZone
onKMCompStore
, so that it's easy to duplicate the initial array of stores.