diff options
Diffstat (limited to '')
-rw-r--r-- | widget/windows/WinIMEHandler.h | 247 |
1 files changed, 247 insertions, 0 deletions
diff --git a/widget/windows/WinIMEHandler.h b/widget/windows/WinIMEHandler.h new file mode 100644 index 0000000000..410e1ebd22 --- /dev/null +++ b/widget/windows/WinIMEHandler.h @@ -0,0 +1,247 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef WinIMEHandler_h_ +#define WinIMEHandler_h_ + +#include "nscore.h" +#include "nsWindow.h" +#include "npapi.h" +#include <windows.h> +#include <inputscope.h> + +#define NS_WM_IMEFIRST WM_IME_SETCONTEXT +#define NS_WM_IMELAST WM_IME_KEYUP + +class nsWindow; + +namespace mozilla { +namespace widget { + +struct MSGResult; + +/** + * IMEHandler class is a mediator class. On Windows, there are two IME API + * sets: One is IMM which is legacy API set. The other is TSF which is modern + * API set. By using this class, non-IME handler classes don't need to worry + * that we're in which mode. + */ +class IMEHandler final { + private: + /** + * Initialize() initializes both TSF modules and IMM modules. Some TIPs + * may require a normal window (i.e., not message window) belonging to + * this process. Therefore, this is called immediately after first normal + * window is created. + */ + static void Initialize(); + + public: + static void Terminate(); + + /** + * Returns TSF related native data or native IME context. + */ + static void* GetNativeData(nsWindow* aWindow, uint32_t aDataType); + + /** + * ProcessRawKeyMessage() message is called before calling TranslateMessage() + * and DispatchMessage(). If this returns true, the message is consumed. + * Then, caller must not perform TranslateMessage() nor DispatchMessage(). + */ + static bool ProcessRawKeyMessage(const MSG& aMsg); + + /** + * When the message is not needed to handle anymore by the caller, this + * returns true. Otherwise, false. + */ + static bool ProcessMessage(nsWindow* aWindow, UINT aMessage, WPARAM& aWParam, + LPARAM& aLParam, MSGResult& aResult); + + /** + * IsA11yHandlingNativeCaret() returns true if a11y is handling + * native caret. In such case, IME modules shouldn't touch native caret. + **/ + static bool IsA11yHandlingNativeCaret(); + + /** + * NeedsToCreateNativeCaret() returns true if IME handler needs to create + * native caret for other applications which requests OBJID_CARET with + * WM_GETOBJECT and a11y module isn't active (if a11y module is active, + * it always creates native caret, i.e., even if no editor has focus). + */ + static bool NeedsToCreateNativeCaret() { + return sHasNativeCaretBeenRequested && !IsA11yHandlingNativeCaret(); + } + + /** + * CreateNativeCaret() create native caret if this has been created it. + * + * @param aWindow The window which owns the caret. + * @param aCaretRect The caret rect relative to aWindow. + */ + static bool CreateNativeCaret(nsWindow* aWindow, + const LayoutDeviceIntRect& aCaretRect); + + /** + * MaybeDestroyNativeCaret() destroies native caret if it has been created + * by IMEHandler. + */ + static void MaybeDestroyNativeCaret(); + + /** + * HasNativeCaret() returns true if there is native caret and it was created + * by IMEHandler. + */ + static bool HasNativeCaret() { return sNativeCaretIsCreated; } + + /** + * When there is a composition, returns true. Otherwise, false. + */ + static bool IsComposing(); + + /** + * When there is a composition and it's in the window, returns true. + * Otherwise, false. + */ + static bool IsComposingOn(nsWindow* aWindow); + + /** + * Notifies IME of the notification (a request or an event). + */ + static nsresult NotifyIME(nsWindow* aWindow, + const IMENotification& aIMENotification); + + /** + * Returns notification requests of IME. + */ + static IMENotificationRequests GetIMENotificationRequests(); + + /** + * Returns native text event dispatcher listener. + */ + static TextEventDispatcherListener* GetNativeTextEventDispatcherListener(); + + /** + * Returns IME open state on the window. + */ + static bool GetOpenState(nsWindow* aWindow); + + /** + * Called when the window is destroying. + */ + static void OnDestroyWindow(nsWindow* aWindow); + + /** + * Called when nsIWidget::SetInputContext() is called before the window's + * InputContext is modified actually. + */ + static void SetInputContext(nsWindow* aWindow, InputContext& aInputContext, + const InputContextAction& aAction); + + /** + * Associate or disassociate IME context to/from the aWindowBase. + */ + static void AssociateIMEContext(nsWindow* aWindowBase, bool aEnable); + + /** + * Called when the window is created. + */ + static void InitInputContext(nsWindow* aWindow, InputContext& aInputContext); + + /** + * This is called by TSFStaticSink when active IME is changed. + */ + static void OnKeyboardLayoutChanged(); + +#ifdef DEBUG + /** + * Returns true when current keyboard layout has IME. Otherwise, false. + */ + static bool CurrentKeyboardLayoutHasIME(); +#endif // #ifdef DEBUG + + /** + * Append InputScope values from inputmode string. + */ + static void AppendInputScopeFromInputMode(const nsAString& aHTMLInputMode, + nsTArray<InputScope>& aScopes); + + /** + * Append InputScope values from type attreibute string of input element + */ + static void AppendInputScopeFromType(const nsAString& aInputType, + nsTArray<InputScope>& aScopes); + + /** + * Return focused window if this receives focus notification and has not + * received blur notification yet. + */ + static nsWindow* GetFocusedWindow() { return sFocusedWindow; } + + private: + static nsWindow* sFocusedWindow; + static InputContextAction::Cause sLastContextActionCause; + + static bool sMaybeEditable; + static bool sForceDisableCurrentIMM_IME; + static bool sNativeCaretIsCreated; + static bool sHasNativeCaretBeenRequested; + + /** + * MaybeCreateNativeCaret() may create native caret over our caret if + * focused content is text editable and we need to create native caret + * for other applications. + * + * @param aWindow The window which owns the native caret. + */ + static bool MaybeCreateNativeCaret(nsWindow* aWindow); + + static decltype(SetInputScopes)* sSetInputScopes; + static void SetInputScopeForIMM32(nsWindow* aWindow, + const nsAString& aHTMLInputType, + const nsAString& aHTMLInputMode, + bool aInPrivateBrowsing); + static bool sIsInTSFMode; + // If sIMMEnabled is false, any IME messages are not handled in TSF mode. + // Additionally, IME context is always disassociated from focused window. + static bool sIsIMMEnabled; + + static bool IsTSFAvailable() { return sIsInTSFMode; } + static bool IsIMMActive(); + + static bool IsOnScreenKeyboardSupported(); + + static void MaybeShowOnScreenKeyboard(nsWindow* aWindow, + const InputContext& aInputContext); + enum class Sync { Yes, No }; + static void MaybeDismissOnScreenKeyboard(nsWindow* aWindow, + Sync aSync = Sync::No); + static bool WStringStartsWithCaseInsensitive(const std::wstring& aHaystack, + const std::wstring& aNeedle); + static bool NeedOnScreenKeyboard(); + static bool IsKeyboardPresentOnSlate(); + static bool IsInTabletMode(); + static bool AutoInvokeOnScreenKeyboardInDesktopMode(); + static bool NeedsToAssociateIMC(); + static bool NeedsSearchInputScope(); + + /** + * Show the Windows on-screen keyboard. Only allowed for + * chrome documents and Windows 8 and higher. + */ + static void ShowOnScreenKeyboard(nsWindow* aWindow); + + /** + * Dismiss the Windows on-screen keyboard. Only allowed for + * Windows 8 and higher. + */ + static void DismissOnScreenKeyboard(nsWindow* aWindow); +}; + +} // namespace widget +} // namespace mozilla + +#endif // #ifndef WinIMEHandler_h_ |