A blink of an eyeR0uter Input ToolIt's already the third generation,Surprisingly, I never seem to have seriously thought about the question in the title。I have always assumed that macOS and iOS The same is to create an input method instance for each input box,And the Controller of the third-party input method,only one globally,The system is responsible for XPC calls。
Later though I found out that the Controller doesn't destroy as soon as the input box loses focus,But I still think the system will generate a new Controller for each input box that gets focus。
There is not a lot of discussion online about the life cycle of macOS third-party input methods,Also because of my ambiguity in the above,Caused the new version of drop-off input method to encounter some intractable problems,This time, I completely figured out the work.。
First of all,we see IMKInputController statement of,it says inside:
The IMKServer class which is allocated in an input method’s main function creates a controller class for each input session created by a client application. Therefore for every input session there is a corresponding IMKInputController.
So actually there will be one Controller object per "input session",Although usually when we type, only the only input box gets the focus (you can't type on two input boxes at the same time, right?)
Then,What is this "input session"? After my actual test,In fact, it is the corresponding App,No matter how many input boxes there are,Generally, an app will have a session,In extreme cases, there may be two (this explains the strange situation of switching between Chinese and English in some drop-off input methods),But the actual use is still the latest generated one。
so,So comprehensively,The following conclusions can be drawn:
The input method is activated by the system,only one process。via system call,A session will be created for each app,The session will create the corresponding Controller,Then in general this Controller will always exist,until the app closes。
1 2 3 4 5 6 7 |
InputMethod---Server---Session---IMKController | | | |-------IMKController | |-----Session---IMKController | |-----Session---IMKController |
So this way,You have to be careful with global variables or singletons (since we really can't give focus to multiple input boxes at the same time),So it's safe in most cases),because in some cases,Once a race occurs,It is very likely that the key signal is obtained by multiple Controllers,These shared global variables will be affected。
But after understanding the life cycle of the input method,The solution is not difficult,In fact, the Controller has activation and deactivation callbacks,Although Controller objects are resident in memory,But we can rely on this callback to determine whether the user is currently using this Controller (that is, whether he is typing in this input box),If there is, func activateServer(_ sender: Any!) will be called,If the input box loses focus,The func deactivateServer(_ sender: Any!) will be called,We can create a property ourselves to track this state,This way when global notifications need to be handled,Determine if you are inactive,just don't respond。LogInput macOS 3 This is how to solve the problem of switching between Chinese and English.。
Speak the truth,I'm still using a global variable to keep track of the currently active Controller 😅 but the most important part has been replaced...
Original article written by LogStudio:R0uter's Blog » What is the life cycle of third-party input methods on the macOS platform?
Reproduced Please keep the source and description link:https://www.logcg.com/archives/3563.html