Currently, widget doesn't show VKB when input context change is caused by JS.
However, if it's caused by an event handler of a user input, user may expect
to open VKB. For example, if a touch event in fake editor causes moving
focus to actual editable node, user expect to show VKB.
Therefore, InputContextAction should declare two causes. One is unknown but
occurred during handling non-keyboard event. The other is unknown but occurred
during handling keyboard event.
However, EventStateManager doesn't have an API to check if it's being handling
a keyboard event. Therefore, this patch adds it first.
AutoHandlingUserInputStatePusher sends event type to StartHandlingUserInput()
and StopHandlingUserInput() of EventStateManager and sUserKeyboardEventDepth
manages the number of nested keyboard event handling. Therefore,
EventStateManager::IsHandlingKeyboardInput() can return if it's handling a
keyboard event.
IMEStateManager uses this new API to adjust the cause of changes of input
context.
Finally, InputContextAction::IsUserInput() is renamed to IsHandlingUserInput()
for consistency with EventStateManager and starts to return true when the
input context change is caused by script while it's handling a user input.
MozReview-Commit-ID: 5JsLqdqeGah
Smart Location Bar (a.k.a URL bar) has some features, loading inputted URL
directly, searching bookmark items and history items, and search inputted words
with registered search engine.
So, it does not make sense its inputmode is "url". E.g., neither showing URL
specific software keyboard nor switching IME open state automatically for
typing URL may not be expected in most cases.
Unfortunately, there is no proper inputmode value for Smart Location Bar.
Therefore, this patch uses "mozAwesomebar" value and accepts the value only in
chrome documents. This value should be handled by each native IME handler
properly.
MozReview-Commit-ID: 7vUnbpg91F2
Some pages might use neither a default submit element nor rely on implicit submission and instead implement their form handling with JS key event listeners.
On Android, most IMEs won't allow sending an "Enter" key press if we're using an actionHint of "next" as our default, so we now use "go"/"search" for the last single line text/number input that is not disabled.
MozReview-Commit-ID: ACC15OYtcTF
IMEStateManager has a static instance of InputContext which has some nsString
instances. Then, their members will be released after XPCOM shutdown and
that is detected as unexpected destruction.
Therefore, IMEStateManager should release them by itself at XPCOM shutdown.
Using nsTSubstring::SetCapacity(0) is the simplest way to release only the
string buffers.
MozReview-Commit-ID: LMrQxQF9xPn
Currently, IMEStateManager::OnChangeFocusInternal() tries to sync the state
whether menu keyboard listener is installed between itself and active remote
process -- When menu keyboard listener is installed, it posts a message to
_only_ active remote process. When menu keyboard listener is uninstalled,
it posts a message to _only_ active remote process. So, it's not guaranteed
that active remote process at installing and uninstalling may be different.
If it's different, IMEStateManager in the old remote process believes that
menu keyboard listener is still installed. This is what the cause of IME
unavailable in a remote process.
Current approach must be wrong. IMEStateManager should manage menu keyboard
listener state only in the process which the listener is installed in. Then,
when menu keyboard listener is uninstalled, IMEStateManager needs to restore
the latest input context in the remote process without asking the remote
process.
Therefore, this patch does:
* stops IMEStateManager::OnChangeFocusInternal() posting message when menu
keyboard listener is installed and uninstalled.
* removes the message sender and receiver from PBrowser.
* cache the latest input context of active remote process in
IMEStateManager::SetInputContextForChildProcess().
* make IMEStateManager::SetInputContextForChildProcess() not set input context
when menu keyboard listener is installed in the process.
* tries to restore latest input context in the remote process in
IMEStateManager::OnChangeFocusInternal(). If there is no cached input
context, it does nothing and waits next SetInputContextForChildProcess() call.
* clears the cache when IMEStateManager::OnChangeFocusInternal() changes
active remote process to different one or nullptr.
So, this must improve performance at activating and inactivating memubar and
opening and closing popup menu in the main process.
MozReview-Commit-ID: EelKSPlaXdw
In some cases, sFocusedIMEWidget may be nullptr but oldWidget still has
composition since IMEStateManager doesn't guarantee that NOTIFY_IME_OF_BLUR
is sent after REQUEST_TO_COMMIT_COMPOSITION nor REQUEST_TO_CANCEL_COMPOSITION.
Therefore, when it tries to clean up old widget's composition, it should refer
the old widget's IME notification requests.
MozReview-Commit-ID: 8kZvJbHfs5z
When a remote process has focus and it loses focus,
IMEStateManager::OnChangeFocusInternal() sends NOTIFY_IME_OF_BLUR via
IMEStateManager::NotifyIMEOfBlurForChildProcess(). Therefore,
sFocusedIMETabParent and sFocusedIMEWidget are set to nullptr here. So, if a
window becomes active, REQUEST_IME_TO_COMMIT_COMPOSITION in
IMEStateManager::OnChangeFocusInternal() won't work because
IMEStateManager::NotifyIME() ignores the request because of coming from wrong
process.
Therefore, IMEStateManager::OnChangeFocusInternal() needs to send
REQUEST_TO_COMMIT_COMPOSITION with proper process information which is only
stored by TextComposition instance.
MozReview-Commit-ID: KNEvOoQtK1E
Android now supports telling an IME that it shouldn't store user-entered content into it's dictionary/language model/etc. and we want to automatically enable this in private browsing.
As the code that handles input on Android doesn't have any notion of tabs (and therefore of the difference between normal and private tabs), the best way to get that info across is to retrieve it directly within the IMEStateManager from the corresponding document and store it in the inputContext, which is then passed to Java for Fennec to handle.
Implementing this within Gecko also has the benefit that this part of the code can be used by other platforms as well should they want to support similar features in the future.
MozReview-Commit-ID: DsxjC4Ma7DR
Currently, IMEStateManager::OnChangeFocusInternal() sends blur notification to IME when a remote process has IME focus and focus is moving from the process. However, if IME wants to keep composition even during deactive and nobody will gets focus (i.e., all windows becomes deactive), IMEStateManager shouldn't send the blur notification because it causes committing composition.
Therefore, it should send blur notification only when focus is moving to a PresContext (that means that not all windows becomes deactive) or IME doesn't want to keep composition during deactive.
Then, even if another window becomes active next time, IMEStateManager can send "stop IME state management" message to the composing remote process and the remote process can commit composition normally.
Additionally, this patch ensures to send blur notification when IME focused TabParent or widget is being destroyed. This fixes new memory leak bug of this patch (sFocusedIMETabParent keeps grabbing the instance until shutting down in some mochitests).
MozReview-Commit-ID: KYiFGo970a8
We have a minimum requirement of VS 2015 for Windows builds, which supports
the z length modifier for format specifiers. So we don't need SizePrintfMacros.h
any more, and can just use %zu and friends directly everywhere.
MozReview-Commit-ID: 6s78RvPFMzv
This patch fixes a simple mistake which was written when we support IME in e10s mode.
IMEStateManager::OnChangeFocusInternal() already has code which makes the method doesn't set IME state again when focus is not being changed, input context of the widget was already set by a remote process and our process is being activated. However, the condition of checking if input context of the widget was set by which process is reversed.
MozReview-Commit-ID: 61ZH0VnKqPq
When focus is moving from a remote process to different process (including to the main process), destroying IMEContentObserver in the focused remote process occurs later. I.e., NOTIFY_IME_OF_BLUR will be notified later. However, it may be too late for new focused process especially when destroying the focused widget.
Therefore, this patch makes IMEStateManager notifies IME of blur in such case.
MozReview-Commit-ID: GkypubVjn3H
IME should receive notifications and requests only from proper process. E.g., IME shouldn't commit composition by a request which came from previous focused process.
This patch makes that IMEStateManager::NotifyIME() takes pointer to TabParent optionally. If the request or notification came from remote process, it should be non-nullptr. Then, this makes it ignore notifications and requests from unexpected process.
Note that this patch also touches some gfx headers because they use |ipc::| but compiler is confused at the ambiguousness between |mozilla::ipc::| and |mozilla::dom::ipc::|.
Finally, this patch changes the NS_ASSERTION in IMEHandler::OnDestroyWindow() to MOZ_ASSERT because the orange caused by the NS_ASSERTION was not realized since there was already an intermittent orange bug caused by different NS_ASSERTION.
MozReview-Commit-ID: 9CgKXQRJWmN
Currently, IMEStateManager always sets input context as set by current process even when it needs to adjust IME state when a tab parent for current focused IME process is removed. Then, input context for the widget is marked as for main process but the widget still have IME focus of a remote process.
For fixing this mismatch, IMEStateManager should set ORIGIN_CONTENT even when the tab parent is being destroyed.
MozReview-Commit-ID: C10YOAtkET4
When focus is moved from the main process to a remote process and there is active IME content observer (i.e., an editor in the main process has focus), IMEStateManager should destroy the active IME content observer because it may cause notifying NOTIFY_IME_OF_BLUR when the main process takes focus again.
MozReview-Commit-ID: BG3eZhxoWBW
TextComposition in the main process is destroyed when the main process sends eCompositionCommit(AsIs) to focused remote process. Therefore, ContentCacheInParent::mCompositionPendingCount is never 2 or more now.
It may cause ContentCacheInParent::Assign() setting older composition's start offset to current composition's start offset in the main process.
For making uplift the following patch easier, the wrong patch should be backed out first.
MozReview-Commit-ID: IHWc7qZBQtc
ContentCacheInParent::mPendingCompositionCount is now managed with composition events which TabParent received. However, TextComposition doesn't dispatch composition events after coming request to commit active composition. Therefore, composition is committed forcibly in a remote process over 255 times, the main process crashes.
It's the safest way to use TextComposition to manage ContentCacheInParent::mPendingCompositionCount.
MozReview-Commit-ID: DEhzYcK1zcW
IMEContentObserver can reduce the number of times to compute node offsets with caching all added nodes as a range. For that, it needs to know when it starts to update and ends updating the document.
nsIDocumentObserver is a subclass of nsIMutationObserver and IMEContentObserver is a mutation observer of editor's root content. Therefore, if we change IMEContentObserver to a document observer, each mutation observer method needs to check if the change occurs in the observing editor. Therefore, this patch implements document observer as its nested class and manages it as a member of IMEContentObserver.
MozReview-Commit-ID: HPSPfajxjnx
IMEStateManager should cache nsIWidget for sPresContext at caching sPresContext. Then, even if sPresContext has gone, IMEStateManager can clean up with the nsIWidget cache.
Unfortunately, editor has some bugs about calling IMEStateManager::UpdateIMEState(). That is, calling it *before* IMEStateManager::OnFocusChange(). In such case, this patch makes UpdateIMEState() ignore the call.
MozReview-Commit-ID: 1cydI03WyB8
This patch also renames:
EditorInputEventDispatcher -> mozilla::EditorInputEventDispatcher
And some variable names are renamed from aEditor or mEditor to aEditorBase or mEditorBase for making their types clearer.
MozReview-Commit-ID: 2FCXWpLMn8e
"ime-enabled-state-changed" notification was implemented for Android in bug 603848 but nobody currently observes this notification. Therefore, we can stop notify the observer service of this.
MozReview-Commit-ID: 3TNHf1xWo2l
For sending NOTIFY_IME_OF_COMPOSITION_EVENT_HANDLED after the other change notifications which was caused by the user input, we need to use IMEContentObserver::IMENotificationSender because it sends the notifications when it's safe to do it.
This patch makes TextComposition use IMEContentObserver to send the notification. However, if there is no active IMEContentObserver, e.g., composition events are fired on unfocused window, TextComposition sends it by itself (same as current implementation).
If IMEContentObserver stops observing when it has pending NOTIFY_IME_OF_COMPOSITION_EVENT_HANDLED, it cannot send the notification (i.e., it is discarded completely in such case). However, in such case, IMEContentObserver sends NOTIFY_IME_OF_BLUR. So, anyway, native IME handler should treat the blur notification as it including NOTIFY_IME_OF_COMPOSITION_EVENT_HANDLED.
On the other hand, we're buggy if composition events are fired in non-active window. Even in such case, IMEContentObserver should be created for active editor in each document and it notifies IME of the changes. But this is out of the scope of this bug.
MozReview-Commit-ID: 7Q0ZsJTh4hX