iOS custom keyboard - preserve state between appearances - ios8

I'm having some performance problems with a custom keyboard I'm working on. Loading all the words in the spell correction tree takes quite a bit of time. This seems to be done each time the keyboard appears - is there any way to preserve the state of the keyboard? Apps can do suspend / resume etc - but I can't find any documentation on how to do this for extensions, or if there's any mechanism for doing this att all.
Thanks!

You are loading dictionary from Internet or from the disk?
For the first case NSUserDefaults, encoding (NsCopying) are the options to store info. You can load it in background.
According to the docs, os typically kills extension process, so, I think there is no way to prevent keyboard objects from deallocation (you may use nskeydarchiver).

Related

How to hook/remap an arbitrary keyboard event on OSX?

I would like to map:
CAPS-LOCK to Fn
Fn to Left-MOUSE
LSHIFT+3 to #
RSHIFT+3 to something else
etc.
I have searched exhaustively for any tool that offers complete freedom for remapping keyboard input, but cannot find one. (Windows has AutoHotkey).
I'm planning to write my own tool that parses a config file.
But how to actually dig in and do this?
Solving this problem will require a thorough understanding of the journey of a keystroke through the operating system, so as to intercept at the appropriate point.
I think I need to eat the event at a low-level, where it is still a virtual key code, then provide my own customised mapping system and inject an appropriate event further up the system.
But where (and how)?
Edit: I am detailing the results of my research in an answer below (which maybe should be migrated back into the question at some point).
I'm making this community wiki, please feel welcome to improve it.
Sub-Questions I've asked:
Make SHIFT+3 produce `#` not `£` on OSX by code
How to tap (hook) F7 through F12 and Power/Eject on a MacBook keyboard
How to tap/hook keyboard events in OSX and record which keyboard fires each event
-> https://github.com/Daij-Djan/DDHidLib
Trap each SHIFT key independently on OS X
In OSX, how to determine which keyboard generated an NSEvent?
I can intercept almost all keydown/keyup events at the bottom of the middle tier. Except for power, and also CAPSLOCK key-UP when it is transitioning from ON to OFF.
Pretty nasty!
Working at the bottom tier level, I can get all key up/down except for the PowerKey.
If it were not for that awkward 75% success rate for CapsLock I would have a good solution. It is vexing that handling a key in such a useful location massively escalates the required complexity.
I have found DDHidLib and am currently looking through it to figure out if it smoothes that problem.
Research
Googling "keyEventWithType CGEventTapCreate" seems like a good idea, as those are essential ingredients for Tapping the event and Re-Emitting it.
Yay! Modify keyDown output -- that code compiles, and with minor tweaking (CGEventMaskBit( kCGEventKeyDown ) | CGEventMaskBit( kCGEventFlagsChanged ),) I can pick up modifier keys also. I get different keycodes for LSHIFT and RSHIFT. Brilliant!
Problems with the above:
Tapping kCGEventKeyDown works for some function keys but not others. It looks as though Apple have only overloaded certain keys, and the overloaded ones seem to get caught at a lower level.
Power/Eject key doesn't get caught.
I don't see any way to disambiguate which device the keystroke is coming from.
How to tap (hook) F7 through F12 and Power/Eject on a MacBook keyboard
http://blog.tklee.org/2008/09/modifiers-across-keyboards.html
-> http://forums.macrumors.com/showthread.php?t=778484
-> https://github.com/maravillas/dual-keyboards
https://github.com/pkamb/PowerKey may provide some insight
-> https://github.com/pkamb/PowerKey/blob/master/PowerKey/PKPowerKeyEventListener.m
-> Apple Keyboard Media Key Event Handling -- Rogue Amoeba
... system wide shortcut for Mac OS X
-> http://snippets.aktagon.com/snippets/361-registering-global-hot-keys-with-cocoa-and-objective-c
Another problem is: LSHIFT-down RSHIFT-down&up LSHIFT-up. The RSHIFT events wouldn't get caught.
Looks like I need to dip down into IOKit
Using IOHIDManager to Get Modifier Key Events
-> https://github.com/candera/khordr/blob/master/src/c/keygrab/hid-scratch.c
kEventRawKeyDown in:
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/
Developer/SDKs/MacOSX10.10.sdk/System/Library/
Frameworks//Carbon.framework/Frameworks/HIToolbox.framework/
Headers/CarbonEvents.h
Resources
3-tier:
Cocoa/AppKit is a higher-level wrapper
Quartz takes the events from IOKit routes them to apps
Note: NSEvent is built over Quartz Event
IOKit -- talks to the hardware
Top Tier (Cocoa/AppKit)
https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/EventOverview/EventArchitecture/EventArchitecture.html -- this document is a must-see, and shows the above basic 3-tier architecture pic. However, it appears to only focus on the top tier (Cocoa/AppKit).
http://www.hcs.harvard.edu/~jrus/Site/Cocoa%20Text%20System.html <-- this article shows you 3 OSX config files that operate at an even higher level, letting you script your own mappings. This is documented here.
^ KeyBindingsEditor lets you make the above modifications.
Middle Tier (Quartz)
QuartzEventServicesRef
NSEvent -- specifically Creating Events
A couple of working code examples at this level. However, they all perform the same basic trick of receiving one virtual key code and emitting another. So you could use this technique for example to swap 'a' and 'z'.
Intercept keyboard input in OSX -- leads to Quartz Event Taps
Modify NSEvent to send a different key than the one that was pressed -- Dave De Long provide a working example, also using QET.
https://gist.github.com/wewearglasses/8313195 <-- "Global keyboard hook for OSX" -- another short working demo using QET.
Ukelele lets you choose which Unicode gets associated with a particular key, or Modifier+key. Doesn't allow remapping of modifiers, nor does it disambiguate left from right shift keys etc.
Keyboard input on OSX -- answer points towards addGlobalMonitorForEventsMatchingMask in NSEvent (in AppKit)
Base Tier (IOKit)
IOKitFundamentals <-- Also IOKit ("Interrupt Handling in the I/O Kit... Two types of events trigger an interrupt: ... Asynchronous events, such as keyboard presses")
https://developer.apple.com/library/mac/documentation/DeviceDrivers/Conceptual/AccessingHardware/AH_Other_APIs/AH_Other_APIs.html
How can Mac OS X games receive low-level keyboard input events? <-- gamers are interested in this!
http://phrack.org/issues/66/16.html#article -- sometimes the hackers present things most clearly, haven't read through this yet. IOKit again, it seems.
More Links...
How do you implement global keyboard hooks in Mac OS X? <-- links to an article.
OS X: Detect system-wide keyDown events? <-- slightly OT as this is just to do with global monitoring, i.e. read-only.
http://www.codeitive.com/7QHSeVjPWq/where-can-i-find-kcgkeyboardeventkeycode-list-of-key-codes-for-cyrillic-language.html
Have you checked out Karabiner (which does all that you want to do.. up till OSX 10.11 .. MacOS 10.12 changed the keyboard driver model, and the authors - mainly Tekezo- are still re writing Karabiner to take account of the new model - this is as of feb 2017)
Karabiner is open source, and you can download the code from Github and twiddle with it.
As part of the re-write they have released Karabiner-elements which works on 10.12 Sierra, but cannot yet do everything that karabiner did.
Karabiner is very powerful, and I miss it greatly on 10.12

Why does Flickring occurs on Win Forms when more control are present on the UI

If any one has got an explanation for why does flickering occur on a UI (for windows form) when it incorporates more sub controls (like, data grid's, images etc).
Thanks in advance.
Flickering is usually a problem that has to do with intensive graphics operations or custom draws. The best way to solve it is to make the flickering controls double buffered. Since you don't give us much to go by, that would be an obvious first choice. You could also manually invalidate controls triggered by certain events.
Here's an article that should get you started:
Double Buffering Windows Forms

How Imitate a [Ctrl+Left mouse click] on the center of the form or open another program and type in a word?

Babylon dictionary and a couple of other dictionaries allow to click on any word in any windows program
and automatically recognize the word under the cursor, and at once open the dictionary window while searching for that word in installed dictionaries.
You can on the other hand open your dictionary, type in your word and press Enter, the result will be the same.
There's a Delphi form, containing a text label, for example with the word "Automaton".
My question is:
How to send a word from my Delphi application right into the dictionary window, as if you typed it manually and pressed Enter?
The best solution is to send some message through the Windows mechanism, but if it is too complicated, there's another solution, and so the second answer: as I described, we need to model a [Ctrl+left mouse] click on a form where this word is displayed on a form [ a visual label on the screen of my Delphi application], to be exact, on some central pixel of this label.
Could you kindly give an advice how to do one thing or another in Delphi ?
** edit:
The problem with AppActivate is this: Babylon dict has a daemon part that seats in the tray.
In the task manager a real window where the text should be input also is named 'Babylon'.
So AppActivate('Babylon') tries to bring to front the non-visual part of the application.
Do you have any suggestion how to determine the windows handle or something of a real visual part of the application? In the task manager, I repeat both visual and non-visual parts are named 'Babylon'.
I cannot offer an answer so much as some insight and advice...
There are certain applications which "intercept" keyboard and mouse instructions, and essentially "nullify" them if they are being immitated by software. Generally-speaking, you'd only see this in proper AntiVirus software such as Kaspersky by design... however:
The way some (not many, but some) programs hook keyboard and mouse inputs, as a side-effect, behave the same way. If you have attempted all of the advice given as comments above, and cannot get Babylon to trigger an action as a result, it is likely Babylon behaves as I have described.
If what I suspect is true, then the method you are attempting is simply not possible (at least, not using any simple Pascal code on its own... ASM might be able to do it but that's beyond my knowledge).
A better solution may be to do a little research to see if any of the following options are available to you:
1) Does Babylon have a Pipeline or API you can use to interface your application(s) with it?
2) Is the particular functionality you require of Babylon accessible through one (or more) DLL files distributed as part of Babylon?
3) Is there an alternative to using Babylon for your needs?
I know it's not an answer as such (certainly not one you'd want to hear), but it may point you in a better direction.

Which Windows API controls filename editing?

When you press F2 to edit a filename in Windows Shell, there is a limited set of editing keys that is understood - e.g. CTRL+Arrow Keys, Home, End, CTRL+X. For example, when you type CTRL+Right Arrow, the cursor will stop right after a dash, but will not stop at a period. Are these actions customizable, and if so, how?
Any additional information not directly related but which you feel might help the topic will also be appreciated.
You can set a custom word-break procedure for your edit control using EM_SETWORDBREAKPROC; EditWordBreakProc is the corresponding callback function that the OS calls when it needs to find where a word break occurs.
From the docs:
Either a multiline or a single-line edit control might call this function when the user presses arrow keys in combination with the CTRL key to move the caret to the next word or previous word.
The key combinations themselves are not directly customizable, and for a good reason -- so that the user experience is uniform across all applications. Of course, you could subclass the edit control and handle keyboard messages yourself but I guess that's not the point here.
The Windows version matters, but in general this behavior is baked into SysListView32, the native list view control. No, keyboard handling is hard-baked. Subclassing the control is technically possible, just not practical since it lives inside Explorer.exe. And having no clue where the caret is located inside the label, there are no messages for it.
By "Windows Shell" I assume you mean Windows Explorer, but the answer is likely the same no matter what program you are talking about.
Explorer simply creates an EDIT control and moves it into position. The editing behavior comes from this stock system control, plus whatever additional logic Explorer adds to its own instance of it.
While you can easily alter the behavior of an EDIT control that belongs to a thread in your own process, doing so in another process requires a global hook. We will stipulate that you understand the amount of work involved in doing a global hook correctly, and which will function in both x86 and x64 environments.
You cannot directly interfere with the behavior of an EDIT control in another process with WH_CALLWNDPROC, but you can use WH_CALLWNDPROCRET to observe keyboard messages, check that the window is and EDIT control, check that the EDIT control belongs to Explorer, and then knowing precicesly how the EDIT control responded to that keyboard event, do something additional like backing up to that period.
Or maybe you could use a WH_CBT hook to monitor HCBT_CREATEWND and subclass the EDIT control each time it gets created.
The effort is probably not worth the benefit.

Is it possible to programmatically turn on the Macbook Pro's keyboard backlight for individual keys?

Although I have a feeling that this isn't technically possible, it's worth asking anyways. Is it possible to turn on the Macbook Pro's keyboard backlights for individual keys? I am working on a piece of grid-based software which allows the user to navigate around by pressing any key on the keyboard to position the cursor at that point in the grid. It would be very cool if I could somehow just turn on the backlight for certain keys to give the user an easy way to see the current position of the cursor.
Is it even possible for an application to control the keyboard backlighting at all, let alone for individual keys?
Yes, on programs controlling the backlight.
iTunes visualizer that pusles keyboard backlighting to music:
http://www.youtube.com/watch?v=LUXLkwlF9e8
How to manually adjust (via plugin):
http://osxdaily.com/2006/11/30/how-to-manually-adjust-the-macbook-pro-keyboard-backlight/
Not sure on programs controlling individual keys, but as that would require additional hardware to be installed on Mac's part, i doubt it.
Well after trawling the webs, it looks like the answer to that is no. But I'd like to point out that each key does have its own key- a tiny little LED (same kind they use under phone keypad buttons). Also, I've seen some people saying that flashing these lights on and off repeatedly is bad for them. Bullshit- all digital electronics control light output from LED's by flashing on and off many many times a second. Read up on PWM on wikipedia or something..
Anyways just had to get that out there :)
Thanks,
Nic

Resources