diff options
Diffstat (limited to 'dom/inputmethod')
-rw-r--r-- | dom/inputmethod/HardwareKeyHandler.cpp | 562 | ||||
-rw-r--r-- | dom/inputmethod/HardwareKeyHandler.h | 224 | ||||
-rw-r--r-- | dom/inputmethod/Keyboard.jsm | 16 | ||||
-rw-r--r-- | dom/inputmethod/moz.build | 23 | ||||
-rw-r--r-- | dom/inputmethod/nsIHardwareKeyHandler.idl | 142 |
5 files changed, 0 insertions, 967 deletions
diff --git a/dom/inputmethod/HardwareKeyHandler.cpp b/dom/inputmethod/HardwareKeyHandler.cpp deleted file mode 100644 index 737c30e5b..000000000 --- a/dom/inputmethod/HardwareKeyHandler.cpp +++ /dev/null @@ -1,562 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -#include "HardwareKeyHandler.h" -#include "mozilla/BasicEvents.h" -#include "mozilla/ClearOnShutdown.h" -#include "mozilla/dom/KeyboardEvent.h" -#include "mozilla/dom/TabParent.h" -#include "mozilla/EventDispatcher.h" -#include "mozilla/EventStateManager.h" -#include "mozilla/TextEvents.h" -#include "nsDeque.h" -#include "nsFocusManager.h" -#include "nsFrameLoader.h" -#include "nsIContent.h" -#include "nsIDOMHTMLDocument.h" -#include "nsIDOMHTMLElement.h" -#include "nsPIDOMWindow.h" -#include "nsPresContext.h" -#include "nsPresShell.h" - -namespace mozilla { - -using namespace dom; - -NS_IMPL_ISUPPORTS(HardwareKeyHandler, nsIHardwareKeyHandler) - -StaticRefPtr<HardwareKeyHandler> HardwareKeyHandler::sInstance; - -HardwareKeyHandler::HardwareKeyHandler() - : mInputMethodAppConnected(false) -{ -} - -HardwareKeyHandler::~HardwareKeyHandler() -{ -} - -NS_IMETHODIMP -HardwareKeyHandler::OnInputMethodAppConnected() -{ - if (NS_WARN_IF(mInputMethodAppConnected)) { - return NS_ERROR_UNEXPECTED; - } - - mInputMethodAppConnected = true; - - return NS_OK; -} - -NS_IMETHODIMP -HardwareKeyHandler::OnInputMethodAppDisconnected() -{ - if (NS_WARN_IF(!mInputMethodAppConnected)) { - return NS_ERROR_UNEXPECTED; - } - - mInputMethodAppConnected = false; - return NS_OK; -} - -NS_IMETHODIMP -HardwareKeyHandler::RegisterListener(nsIHardwareKeyEventListener* aListener) -{ - // Make sure the listener is not nullptr and there is no available - // hardwareKeyEventListener now - if (NS_WARN_IF(!aListener)) { - return NS_ERROR_NULL_POINTER; - } - - if (NS_WARN_IF(mHardwareKeyEventListener)) { - return NS_ERROR_ALREADY_INITIALIZED; - } - - mHardwareKeyEventListener = do_GetWeakReference(aListener); - - if (NS_WARN_IF(!mHardwareKeyEventListener)) { - return NS_ERROR_NULL_POINTER; - } - - return NS_OK; -} - -NS_IMETHODIMP -HardwareKeyHandler::UnregisterListener() -{ - // Clear the HardwareKeyEventListener - mHardwareKeyEventListener = nullptr; - return NS_OK; -} - -bool -HardwareKeyHandler::ForwardKeyToInputMethodApp(nsINode* aTarget, - WidgetKeyboardEvent* aEvent, - nsEventStatus* aEventStatus) -{ - MOZ_ASSERT(aTarget, "No target provided"); - MOZ_ASSERT(aEvent, "No event provided"); - - // No need to forward hardware key event to IME - // if key's defaultPrevented is true - if (aEvent->mFlags.mDefaultPrevented) { - return false; - } - - // No need to forward hardware key event to IME if IME is disabled - if (!mInputMethodAppConnected) { - return false; - } - - // No need to forward hardware key event to IME - // if this key event is generated by IME itself(from nsITextInputProcessor) - if (aEvent->mIsSynthesizedByTIP) { - return false; - } - - // No need to forward hardware key event to IME - // if the key event is handling or already handled - if (aEvent->mInputMethodAppState != WidgetKeyboardEvent::eNotHandled) { - return false; - } - - // No need to forward hardware key event to IME - // if there is no nsIHardwareKeyEventListener in use - nsCOMPtr<nsIHardwareKeyEventListener> - keyHandler(do_QueryReferent(mHardwareKeyEventListener)); - if (!keyHandler) { - return false; - } - - // Set the flags to specify the keyboard event is in forwarding phase. - aEvent->mInputMethodAppState = WidgetKeyboardEvent::eHandling; - - // For those keypress events coming after their heading keydown's reply - // already arrives, they should be dispatched directly instead of - // being stored into the event queue. Otherwise, without the heading keydown - // in the event queue, the stored keypress will never be withdrawn to be fired. - if (aEvent->mMessage == eKeyPress && mEventQueue.IsEmpty()) { - DispatchKeyPress(aTarget, *aEvent, *aEventStatus); - return true; - } - - // Push the key event into queue for reuse when its reply arrives. - KeyboardInfo* copiedInfo = - new KeyboardInfo(aTarget, - *aEvent, - aEventStatus ? *aEventStatus : nsEventStatus_eIgnore); - - // No need to forward hardware key event to IME if the event queue is full - if (!mEventQueue.Push(copiedInfo)) { - delete copiedInfo; - return false; - } - - // We only forward keydown and keyup event to input-method-app - // because input-method-app will generate keypress by itself. - if (aEvent->mMessage == eKeyPress) { - return true; - } - - // Create a keyboard event to pass into - // nsIHardwareKeyEventListener.onHardwareKey - nsCOMPtr<EventTarget> eventTarget = do_QueryInterface(aTarget); - nsPresContext* presContext = GetPresContext(aTarget); - RefPtr<KeyboardEvent> keyboardEvent = - NS_NewDOMKeyboardEvent(eventTarget, presContext, aEvent->AsKeyboardEvent()); - // Duplicate the internal event data in the heap for the keyboardEvent, - // or the internal data from |aEvent| in the stack may be destroyed by others. - keyboardEvent->DuplicatePrivateData(); - - // Forward the created keyboard event to input-method-app - bool isSent = false; - keyHandler->OnHardwareKey(keyboardEvent, &isSent); - - // Pop the pending key event if it can't be forwarded - if (!isSent) { - mEventQueue.RemoveFront(); - } - - return isSent; -} - -NS_IMETHODIMP -HardwareKeyHandler::OnHandledByInputMethodApp(const nsAString& aType, - uint16_t aDefaultPrevented) -{ - // We can not handle this reply because the pending events had been already - // removed from the forwarding queue before this reply arrives. - if (mEventQueue.IsEmpty()) { - return NS_OK; - } - - RefPtr<KeyboardInfo> keyInfo = mEventQueue.PopFront(); - - // Only allow keydown and keyup to call this method - if (NS_WARN_IF(aType.EqualsLiteral("keydown") && - keyInfo->mEvent.mMessage != eKeyDown) || - NS_WARN_IF(aType.EqualsLiteral("keyup") && - keyInfo->mEvent.mMessage != eKeyUp)) { - return NS_ERROR_INVALID_ARG; - } - - // The value of defaultPrevented depends on whether or not - // the key is consumed by input-method-app - SetDefaultPrevented(keyInfo->mEvent, aDefaultPrevented); - - // Set the flag to specify the reply phase - keyInfo->mEvent.mInputMethodAppState = WidgetKeyboardEvent::eHandled; - - // Check whether the event is still valid to be fired - if (CanDispatchEvent(keyInfo->mTarget, keyInfo->mEvent)) { - // If the key's defaultPrevented is true, it means that the - // input-method-app has already consumed this key, - // so we can dispatch |mozbrowserafterkey*| directly if - // preference "dom.beforeAfterKeyboardEvent.enabled" is enabled. - if (keyInfo->mEvent.mFlags.mDefaultPrevented) { - DispatchAfterKeyEvent(keyInfo->mTarget, keyInfo->mEvent); - // Otherwise, it means that input-method-app doesn't handle this key, - // so we need to dispatch it to its current event target. - } else { - DispatchToTargetApp(keyInfo->mTarget, - keyInfo->mEvent, - keyInfo->mStatus); - } - } - - // No need to do further processing if the event is not keydown - if (keyInfo->mEvent.mMessage != eKeyDown) { - return NS_OK; - } - - // Update the latest keydown data: - // Release the holding reference to the previous keydown's data and - // add a reference count to the current keydown's data. - mLatestKeyDownInfo = keyInfo; - - // Handle the pending keypress event once keydown's reply arrives: - // It may have many keypress events per keydown on some platforms, - // so we use loop to dispatch keypress events. - // (But Gonk dispatch only one keypress per keydown) - // However, if there is no keypress after this keydown, - // then those following keypress will be handled in - // ForwardKeyToInputMethodApp directly. - for (KeyboardInfo* keypressInfo; - !mEventQueue.IsEmpty() && - (keypressInfo = mEventQueue.PeekFront()) && - keypressInfo->mEvent.mMessage == eKeyPress; - mEventQueue.RemoveFront()) { - DispatchKeyPress(keypressInfo->mTarget, - keypressInfo->mEvent, - keypressInfo->mStatus); - } - - return NS_OK; -} - -bool -HardwareKeyHandler::DispatchKeyPress(nsINode* aTarget, - WidgetKeyboardEvent& aEvent, - nsEventStatus& aStatus) -{ - MOZ_ASSERT(aTarget, "No target provided"); - MOZ_ASSERT(aEvent.mMessage == eKeyPress, "Event is not keypress"); - - // No need to dispatch keypress to the event target - // if the keydown event is consumed by the input-method-app. - if (mLatestKeyDownInfo && - mLatestKeyDownInfo->mEvent.mFlags.mDefaultPrevented) { - return false; - } - - // No need to dispatch keypress to the event target - // if the previous keydown event is modifier key's - if (mLatestKeyDownInfo && - mLatestKeyDownInfo->mEvent.IsModifierKeyEvent()) { - return false; - } - - // No need to dispatch keypress to the event target - // if it's invalid to be dispatched - if (!CanDispatchEvent(aTarget, aEvent)) { - return false; - } - - // Set the flag to specify the reply phase. - aEvent.mInputMethodAppState = WidgetKeyboardEvent::eHandled; - - // Dispatch the pending keypress event - bool ret = DispatchToTargetApp(aTarget, aEvent, aStatus); - - // Re-trigger EventStateManager::PostHandleKeyboardEvent for keypress - PostHandleKeyboardEvent(aTarget, aEvent, aStatus); - - return ret; -} - -void -HardwareKeyHandler::DispatchAfterKeyEvent(nsINode* aTarget, - WidgetKeyboardEvent& aEvent) -{ - MOZ_ASSERT(aTarget, "No target provided"); - - if (!PresShell::BeforeAfterKeyboardEventEnabled() || - aEvent.mMessage == eKeyPress) { - return; - } - - nsCOMPtr<nsIPresShell> presShell = GetPresShell(aTarget); - if (NS_WARN_IF(presShell)) { - presShell->DispatchAfterKeyboardEvent(aTarget, - aEvent, - aEvent.mFlags.mDefaultPrevented); - } -} - -bool -HardwareKeyHandler::DispatchToTargetApp(nsINode* aTarget, - WidgetKeyboardEvent& aEvent, - nsEventStatus& aStatus) -{ - MOZ_ASSERT(aTarget, "No target provided"); - - // Get current focused element as the event target - nsCOMPtr<nsIContent> currentTarget = GetCurrentTarget(); - if (NS_WARN_IF(!currentTarget)) { - return false; - } - - // The event target should be set to the current focused element. - // However, it might have security issue if the event is dispatched to - // the unexpected application, and it might cause unexpected operation - // in the new app. - nsCOMPtr<nsPIDOMWindowOuter> originalRootWindow = GetRootWindow(aTarget); - nsCOMPtr<nsPIDOMWindowOuter> currentRootWindow = GetRootWindow(currentTarget); - if (currentRootWindow != originalRootWindow) { - NS_WARNING("The root window is changed during the event is dispatching"); - return false; - } - - // If the current focused element is still in the same app, - // then we can use it as the current target to dispatch event. - nsCOMPtr<nsIPresShell> presShell = GetPresShell(currentTarget); - if (!presShell) { - return false; - } - - if (!presShell->CanDispatchEvent(&aEvent)) { - return false; - } - - // In-process case: the event target is in the current process - if (!PresShell::IsTargetIframe(currentTarget)) { - DispatchToCurrentProcess(presShell, currentTarget, aEvent, aStatus); - - if (presShell->CanDispatchEvent(&aEvent)) { - DispatchAfterKeyEvent(aTarget, aEvent); - } - - return true; - } - - // OOP case: the event target is in the child process - return DispatchToCrossProcess(aTarget, aEvent); - - // After the oop target receives the event from TabChild::RecvRealKeyEvent - // and return the result through TabChild::SendDispatchAfterKeyboardEvent, - // the |mozbrowserafterkey*| will be fired from - // TabParent::RecvDispatchAfterKeyboardEvent, so we don't need to dispatch - // |mozbrowserafterkey*| by ourselves in this module. -} - -void -HardwareKeyHandler::DispatchToCurrentProcess(nsIPresShell* presShell, - nsIContent* aTarget, - WidgetKeyboardEvent& aEvent, - nsEventStatus& aStatus) -{ - EventDispatcher::Dispatch(aTarget, presShell->GetPresContext(), - &aEvent, nullptr, &aStatus, nullptr); -} - -bool -HardwareKeyHandler::DispatchToCrossProcess(nsINode* aTarget, - WidgetKeyboardEvent& aEvent) -{ - nsCOMPtr<nsIFrameLoaderOwner> remoteLoaderOwner = do_QueryInterface(aTarget); - if (NS_WARN_IF(!remoteLoaderOwner)) { - return false; - } - - RefPtr<nsFrameLoader> remoteFrameLoader = - remoteLoaderOwner->GetFrameLoader(); - if (NS_WARN_IF(!remoteFrameLoader)) { - return false; - } - - uint32_t eventMode; - remoteFrameLoader->GetEventMode(&eventMode); - if (eventMode == nsIFrameLoader::EVENT_MODE_DONT_FORWARD_TO_CHILD) { - return false; - } - - PBrowserParent* remoteBrowser = remoteFrameLoader->GetRemoteBrowser(); - TabParent* remote = static_cast<TabParent*>(remoteBrowser); - if (NS_WARN_IF(!remote)) { - return false; - } - - return remote->SendRealKeyEvent(aEvent); -} - -void -HardwareKeyHandler::PostHandleKeyboardEvent(nsINode* aTarget, - WidgetKeyboardEvent& aEvent, - nsEventStatus& aStatus) -{ - MOZ_ASSERT(aTarget, "No target provided"); - - nsPresContext* presContext = GetPresContext(aTarget); - - RefPtr<mozilla::EventStateManager> esm = presContext->EventStateManager(); - bool dispatchedToChildProcess = PresShell::IsTargetIframe(aTarget); - esm->PostHandleKeyboardEvent(&aEvent, aStatus, dispatchedToChildProcess); -} - -void -HardwareKeyHandler::SetDefaultPrevented(WidgetKeyboardEvent& aEvent, - uint16_t aDefaultPrevented) { - if (aDefaultPrevented & DEFAULT_PREVENTED) { - aEvent.mFlags.mDefaultPrevented = true; - } - - if (aDefaultPrevented & DEFAULT_PREVENTED_BY_CHROME) { - aEvent.mFlags.mDefaultPreventedByChrome = true; - } - - if (aDefaultPrevented & DEFAULT_PREVENTED_BY_CONTENT) { - aEvent.mFlags.mDefaultPreventedByContent = true; - } -} - -bool -HardwareKeyHandler::CanDispatchEvent(nsINode* aTarget, - WidgetKeyboardEvent& aEvent) -{ - nsCOMPtr<nsIPresShell> presShell = GetPresShell(aTarget); - if (NS_WARN_IF(!presShell)) { - return false; - } - return presShell->CanDispatchEvent(&aEvent); -} - -already_AddRefed<nsPIDOMWindowOuter> -HardwareKeyHandler::GetRootWindow(nsINode* aNode) -{ - // Get nsIPresShell's pointer first - nsCOMPtr<nsIPresShell> presShell = GetPresShell(aNode); - if (NS_WARN_IF(!presShell)) { - return nullptr; - } - nsCOMPtr<nsPIDOMWindowOuter> rootWindow = presShell->GetRootWindow(); - return rootWindow.forget(); -} - -already_AddRefed<nsIContent> -HardwareKeyHandler::GetCurrentTarget() -{ - nsFocusManager* fm = nsFocusManager::GetFocusManager(); - if (NS_WARN_IF(!fm)) { - return nullptr; - } - - nsCOMPtr<mozIDOMWindowProxy> focusedWindow; - fm->GetFocusedWindow(getter_AddRefs(focusedWindow)); - if (NS_WARN_IF(!focusedWindow)) { - return nullptr; - } - - auto* ourWindow = nsPIDOMWindowOuter::From(focusedWindow); - - nsCOMPtr<nsPIDOMWindowOuter> rootWindow = ourWindow->GetPrivateRoot(); - if (NS_WARN_IF(!rootWindow)) { - return nullptr; - } - - nsCOMPtr<nsPIDOMWindowOuter> focusedFrame; - nsCOMPtr<nsIContent> focusedContent = - fm->GetFocusedDescendant(rootWindow, true, getter_AddRefs(focusedFrame)); - - // If there is no focus, then we use document body instead - if (NS_WARN_IF(!focusedContent || !focusedContent->GetPrimaryFrame())) { - nsIDocument* document = ourWindow->GetExtantDoc(); - if (NS_WARN_IF(!document)) { - return nullptr; - } - - focusedContent = document->GetRootElement(); - - nsCOMPtr<nsIDOMHTMLDocument> htmlDocument = do_QueryInterface(document); - if (htmlDocument) { - nsCOMPtr<nsIDOMHTMLElement> body; - htmlDocument->GetBody(getter_AddRefs(body)); - nsCOMPtr<nsIContent> bodyContent = do_QueryInterface(body); - if (bodyContent) { - focusedContent = bodyContent; - } - } - } - - return focusedContent ? focusedContent.forget() : nullptr; -} - -nsPresContext* -HardwareKeyHandler::GetPresContext(nsINode* aNode) -{ - // Get nsIPresShell's pointer first - nsCOMPtr<nsIPresShell> presShell = GetPresShell(aNode); - if (NS_WARN_IF(!presShell)) { - return nullptr; - } - - // then use nsIPresShell to get nsPresContext's pointer - return presShell->GetPresContext(); -} - -already_AddRefed<nsIPresShell> -HardwareKeyHandler::GetPresShell(nsINode* aNode) -{ - nsIDocument* doc = aNode->OwnerDoc(); - if (NS_WARN_IF(!doc)) { - return nullptr; - } - - nsCOMPtr<nsIPresShell> presShell = doc->GetShell(); - if (NS_WARN_IF(!presShell)) { - return nullptr; - } - - return presShell.forget(); -} - -/* static */ -already_AddRefed<HardwareKeyHandler> -HardwareKeyHandler::GetInstance() -{ - if (!XRE_IsParentProcess()) { - return nullptr; - } - - if (!sInstance) { - sInstance = new HardwareKeyHandler(); - ClearOnShutdown(&sInstance); - } - - RefPtr<HardwareKeyHandler> service = sInstance.get(); - return service.forget(); -} - -} // namespace mozilla diff --git a/dom/inputmethod/HardwareKeyHandler.h b/dom/inputmethod/HardwareKeyHandler.h deleted file mode 100644 index 7520c40cd..000000000 --- a/dom/inputmethod/HardwareKeyHandler.h +++ /dev/null @@ -1,224 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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 mozilla_HardwareKeyHandler_h_ -#define mozilla_HardwareKeyHandler_h_ - -#include "mozilla/EventForwards.h" // for nsEventStatus -#include "mozilla/StaticPtr.h" -#include "mozilla/TextEvents.h" -#include "nsCOMPtr.h" -#include "nsDeque.h" -#include "nsIHardwareKeyHandler.h" -#include "nsIWeakReferenceUtils.h" // for nsWeakPtr - -class nsIContent; -class nsINode; -class nsIPresShell; -class nsPIDOMWindowOuter; -class nsPresContext; - -namespace mozilla { - -// This module will copy the events' data into its event queue for reuse -// after receiving input-method-app's reply, so we use the following struct -// for storing these information. -// RefCounted<T> is a helper class for adding reference counting mechanism. -struct KeyboardInfo : public RefCounted<KeyboardInfo> -{ - MOZ_DECLARE_REFCOUNTED_TYPENAME(KeyboardInfo) - - nsINode* mTarget; - WidgetKeyboardEvent mEvent; - nsEventStatus mStatus; - - KeyboardInfo(nsINode* aTarget, - WidgetKeyboardEvent& aEvent, - nsEventStatus aStatus) - : mTarget(aTarget) - , mEvent(aEvent) - , mStatus(aStatus) - { - } -}; - -// The following is the type-safe wrapper around nsDeque -// for storing events' data. -// The T must be one class that supports reference counting mechanism. -// The EventQueueDeallocator will be called in nsDeque::~nsDeque() or -// nsDeque::Erase() to deallocate the objects. nsDeque::Erase() will remove -// and delete all items in the queue. See more from nsDeque.h. -template <class T> -class EventQueueDeallocator : public nsDequeFunctor -{ - virtual void* operator() (void* aObject) - { - RefPtr<T> releaseMe = dont_AddRef(static_cast<T*>(aObject)); - return nullptr; - } -}; - -// The type-safe queue to be used to store the KeyboardInfo data -template <class T> -class EventQueue : private nsDeque -{ -public: - EventQueue() - : nsDeque(new EventQueueDeallocator<T>()) - { - }; - - ~EventQueue() - { - Clear(); - } - - inline size_t GetSize() - { - return nsDeque::GetSize(); - } - - bool IsEmpty() - { - return !nsDeque::GetSize(); - } - - inline bool Push(T* aItem) - { - MOZ_ASSERT(aItem); - NS_ADDREF(aItem); - size_t sizeBefore = GetSize(); - nsDeque::Push(aItem); - if (GetSize() != sizeBefore + 1) { - NS_RELEASE(aItem); - return false; - } - return true; - } - - inline already_AddRefed<T> PopFront() - { - RefPtr<T> rv = dont_AddRef(static_cast<T*>(nsDeque::PopFront())); - return rv.forget(); - } - - inline void RemoveFront() - { - RefPtr<T> releaseMe = PopFront(); - } - - inline T* PeekFront() - { - return static_cast<T*>(nsDeque::PeekFront()); - } - - void Clear() - { - while (GetSize() > 0) { - RemoveFront(); - } - } -}; - -class HardwareKeyHandler : public nsIHardwareKeyHandler -{ -public: - HardwareKeyHandler(); - - NS_DECL_ISUPPORTS - NS_DECL_NSIHARDWAREKEYHANDLER - - static already_AddRefed<HardwareKeyHandler> GetInstance(); - - virtual bool ForwardKeyToInputMethodApp(nsINode* aTarget, - WidgetKeyboardEvent* aEvent, - nsEventStatus* aEventStatus) override; - -private: - virtual ~HardwareKeyHandler(); - - // Return true if the keypress is successfully dispatched. - // Otherwise, return false. - bool DispatchKeyPress(nsINode* aTarget, - WidgetKeyboardEvent& aEvent, - nsEventStatus& aStatus); - - void DispatchAfterKeyEvent(nsINode* aTarget, WidgetKeyboardEvent& aEvent); - - void DispatchToCurrentProcess(nsIPresShell* aPresShell, - nsIContent* aTarget, - WidgetKeyboardEvent& aEvent, - nsEventStatus& aStatus); - - bool DispatchToCrossProcess(nsINode* aTarget, WidgetKeyboardEvent& aEvent); - - // This method will dispatch not only key* event to its event target, - // no mather it's in the current process or in its child process, - // but also mozbrowserafterkey* to the corresponding target if it needs. - // Return true if the key is successfully dispatched. - // Otherwise, return false. - bool DispatchToTargetApp(nsINode* aTarget, - WidgetKeyboardEvent& aEvent, - nsEventStatus& aStatus); - - // This method will be called after dispatching keypress to its target, - // if the input-method-app doesn't handle the key. - // In normal dispatching path, EventStateManager::PostHandleKeyboardEvent - // will be called when event is keypress. - // However, the ::PostHandleKeyboardEvent mentioned above will be aborted - // when we try to forward key event to the input-method-app. - // If the input-method-app consumes the key, then we don't need to do anything - // because the input-method-app will generate a new key event by itself. - // On the other hand, if the input-method-app doesn't consume the key, - // then we need to dispatch the key event by ourselves - // and call ::PostHandleKeyboardEvent again after the event is forwarded. - // Note that the EventStateManager::PreHandleEvent is already called before - // forwarding, so we don't need to call it in this module. - void PostHandleKeyboardEvent(nsINode* aTarget, - WidgetKeyboardEvent& aEvent, - nsEventStatus& aStatus); - - void SetDefaultPrevented(WidgetKeyboardEvent& aEvent, - uint16_t aDefaultPrevented); - - // Check whether the event is valid to be fired. - // This method should be called every time before dispatching next event. - bool CanDispatchEvent(nsINode* aTarget, - WidgetKeyboardEvent& aEvent); - - already_AddRefed<nsPIDOMWindowOuter> GetRootWindow(nsINode* aNode); - - already_AddRefed<nsIContent> GetCurrentTarget(); - - nsPresContext* GetPresContext(nsINode* aNode); - - already_AddRefed<nsIPresShell> GetPresShell(nsINode* aNode); - - static StaticRefPtr<HardwareKeyHandler> sInstance; - - // The event queue is used to store the forwarded keyboard events. - // Those stored events will be dispatched if input-method-app doesn't - // consume them. - EventQueue<KeyboardInfo> mEventQueue; - - // Hold the pointer to the latest keydown's data - RefPtr<KeyboardInfo> mLatestKeyDownInfo; - - // input-method-app needs to register a listener by - // |nsIHardwareKeyHandler.registerListener| to receive - // the hardware keyboard event, and |nsIHardwareKeyHandler.registerListener| - // will set an nsIHardwareKeyEventListener to mHardwareKeyEventListener. - // Then, mHardwareKeyEventListener is used to forward the event - // to the input-method-app. - nsWeakPtr mHardwareKeyEventListener; - - // To keep tracking the input-method-app is active or disabled. - bool mInputMethodAppConnected; -}; - -} // namespace mozilla - -#endif // #ifndef mozilla_HardwareKeyHandler_h_ diff --git a/dom/inputmethod/Keyboard.jsm b/dom/inputmethod/Keyboard.jsm index 22f87ffbc..51506c41f 100644 --- a/dom/inputmethod/Keyboard.jsm +++ b/dom/inputmethod/Keyboard.jsm @@ -24,12 +24,7 @@ XPCOMUtils.defineLazyGetter(this, "appsService", function() { }); XPCOMUtils.defineLazyGetter(this, "hardwareKeyHandler", function() { -#ifdef MOZ_B2G - return Cc["@mozilla.org/HardwareKeyHandler;1"] - .getService(Ci.nsIHardwareKeyHandler); -#else return null; -#endif }); var Utils = { @@ -50,17 +45,6 @@ var Utils = { }; this.Keyboard = { -#ifdef MOZ_B2G - // For receving keyboard event fired from hardware before it's dispatched, - // |this| object is used to be the listener to get the forwarded event. - // As the listener, |this| object must implement nsIHardwareKeyEventListener - // and nsSupportsWeakReference. - // Please see nsIHardwareKeyHandler.idl to get more information. - QueryInterface: XPCOMUtils.generateQI([ - Ci.nsIHardwareKeyEventListener, - Ci.nsISupportsWeakReference - ]), -#endif _isConnectedToHardwareKeyHandler: false, _formMM: null, // The current web page message manager. _keyboardMM: null, // The keyboard app message manager. diff --git a/dom/inputmethod/moz.build b/dom/inputmethod/moz.build index 504e2ebfc..84b3cb8ab 100644 --- a/dom/inputmethod/moz.build +++ b/dom/inputmethod/moz.build @@ -4,29 +4,6 @@ # 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/. -if CONFIG['MOZ_B2G']: - XPIDL_SOURCES += [ - 'nsIHardwareKeyHandler.idl', - ] - - XPIDL_MODULE = 'inputmethod' - - EXPORTS.mozilla += [ - 'HardwareKeyHandler.h', - ] - - SOURCES += [ - 'HardwareKeyHandler.cpp' - ] - - include('/ipc/chromium/chromium-config.mozbuild') - - FINAL_LIBRARY = 'xul' - LOCAL_INCLUDES += [ - '/dom/base', - '/layout/base', - ] - EXTRA_COMPONENTS += [ 'InputMethod.manifest', 'MozKeyboard.js', diff --git a/dom/inputmethod/nsIHardwareKeyHandler.idl b/dom/inputmethod/nsIHardwareKeyHandler.idl deleted file mode 100644 index 5bce4d980..000000000 --- a/dom/inputmethod/nsIHardwareKeyHandler.idl +++ /dev/null @@ -1,142 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -#include "nsISupports.idl" - -interface nsIDOMKeyEvent; - -%{C++ -#define NS_HARDWARE_KEY_HANDLER_CID \ - { 0xfb45921b, 0xe0a5, 0x45c6, \ - { 0x90, 0xd0, 0xa6, 0x97, 0xa7, 0x72, 0xc4, 0x2a } } -#define NS_HARDWARE_KEY_HANDLER_CONTRACTID \ - "@mozilla.org/HardwareKeyHandler;1" - -#include "mozilla/EventForwards.h" /* For nsEventStatus */ - -namespace mozilla { -class WidgetKeyboardEvent; -} - -using mozilla::WidgetKeyboardEvent; - -class nsINode; -%} - -/** - * This interface is used to be registered to the nsIHardwareKeyHandler through - * |nsIHardwareKeyHandler.registerListener|. - */ -[scriptable, function, uuid(cd5aeee3-b4b9-459d-85e7-c0671c7a8a2e)] -interface nsIHardwareKeyEventListener : nsISupports -{ - /** - * This method will be invoked by nsIHardwareKeyHandler to forward the native - * keyboard event to the active input method - */ - bool onHardwareKey(in nsIDOMKeyEvent aEvent); -}; - -/** - * This interface has two main roles. One is to send a hardware keyboard event - * to the active input method app and the other is to receive its reply result. - * If a keyboard event is triggered from a hardware keyboard when an editor has - * focus, the event target should be the editor. However, the text input - * processor algorithm is implemented in an input method app and it should - * handle the event earlier than the real event target to do the mapping such - * as character conversion according to the language setting or the type of a - * hardware keyboard. - */ -[scriptable, builtinclass, uuid(25b34270-caad-4d18-a910-860351690639)] -interface nsIHardwareKeyHandler : nsISupports -{ - /** - * Flags used to set the defaultPrevented's result. The default result - * from input-method-app should be set to NO_DEFAULT_PREVENTED. - * (It means the forwarded event isn't consumed by input-method-app.) - * If the input-method-app consumes the forwarded event, - * then the result should be set by DEFAULT_PREVENTED* before reply. - */ - const unsigned short NO_DEFAULT_PREVENTED = 0x0000; - const unsigned short DEFAULT_PREVENTED = 0x0001; - const unsigned short DEFAULT_PREVENTED_BY_CHROME = 0x0002; - const unsigned short DEFAULT_PREVENTED_BY_CONTENT = 0x0004; - - /** - * Registers a listener in input-method-app to receive - * the forwarded hardware keyboard events - * - * @param aListener Listener object to be notified for receiving - * the keyboard event fired from hardware - * @note A listener object must implement - * nsIHardwareKeyEventListener and - * nsSupportsWeakReference - * @see nsIHardwareKeyEventListener - * @see nsSupportsWeakReference - */ - void registerListener(in nsIHardwareKeyEventListener aListener); - - /** - * Unregisters the current listener from input-method-app - */ - void unregisterListener(); - - /** - * Notifies nsIHardwareKeyHandler that input-method-app is active. - */ - void onInputMethodAppConnected(); - - /** - * Notifies nsIHardwareKeyHandler that input-method-app is disabled. - */ - void onInputMethodAppDisconnected(); - - /** - * Input-method-app will pass the processing result that the forwarded - * event is handled or not through this method, and the nsIHardwareKeyHandler - * can use this to receive the reply of |forwardKeyToInputMethodApp| - * from the active input method. - * - * The result should contain the original event type and the info whether - * the default is prevented, also, it is prevented by chrome or content. - * - * @param aEventType The type of an original event. - * @param aDefaultPrevented State that |evt.preventDefault| - * is called by content, chrome or not. - */ - void onHandledByInputMethodApp(in DOMString aType, - in unsigned short aDefaultPrevented); - - /** - * Sends the native keyboard events triggered from hardware to the - * active input method before dispatching to its event target. - * This method only forwards keydown and keyup events. - * If the event isn't allowed to be forwarded, we should continue the - * normal event processing. For those forwarded keydown and keyup events - * We will pause the further event processing to wait for the completion - * of the event handling in the active input method app. - * Once |onHandledByInputMethodApp| is called by the input method app, - * the pending event processing can be resumed according to its reply. - * On the other hand, the keypress will never be sent to the input-method-app. - * Depending on whether the keydown's reply arrives before the keypress event - * comes, the keypress event will be handled directly or pushed into - * the event queue to wait for its heading keydown's reply. - * - * This implementation will call |nsIHardwareKeyEventListener.onHardwareKey|, - * which is registered through |nsIHardwareKeyEventListener.registerListener|, - * to forward the events. - * - * Returns true, if the event is handled in this module. - * Returns false, otherwise. - * - * If it returns false, we should continue the normal event processing. - */ - %{C++ - virtual bool ForwardKeyToInputMethodApp(nsINode* aTarget, - WidgetKeyboardEvent* aEvent, - nsEventStatus* aEventStatus) = 0; - %} -}; |