bug 582644 - IME event remoting, patch to content r=smaug blocking-fennec=2.0a1+

This commit is contained in:
Jim Chen 2010-08-16 14:48:32 -07:00
parent d5828b0749
commit 8053ee8f11
7 changed files with 166 additions and 1 deletions

View File

@ -1676,6 +1676,23 @@ public:
*/
static PRBool IsFocusedContent(nsIContent *aContent);
#ifdef MOZ_IPC
#ifdef ANDROID
static void SetActiveFrameLoader(nsFrameLoader *aFrameLoader)
{
sActiveFrameLoader = aFrameLoader;
}
static void ClearActiveFrameLoader(const nsFrameLoader *aFrameLoader)
{
if (sActiveFrameLoader == aFrameLoader)
sActiveFrameLoader = nsnull;
}
static already_AddRefed<nsFrameLoader> GetActiveFrameLoader();
#endif
#endif
private:
static PRBool InitializeEventTable();
@ -1765,6 +1782,12 @@ private:
static nsIInterfaceRequestor* sSameOriginChecker;
static PRBool sIsHandlingKeyBoardEvent;
#ifdef MOZ_IPC
#ifdef ANDROID
static nsFrameLoader *sActiveFrameLoader;
#endif
#endif
};
#define NS_HOLD_JS_OBJECTS(obj, clazz) \

View File

@ -266,6 +266,12 @@ PRBool nsContentUtils::sInitialized = PR_FALSE;
nsRefPtrHashtable<nsPrefObserverHashKey, nsPrefOldCallback>
*nsContentUtils::sPrefCallbackTable = nsnull;
#ifdef MOZ_IPC
#ifdef ANDROID
nsFrameLoader *nsContentUtils::sActiveFrameLoader = nsnull;
#endif
#endif
static PLDHashTable sEventListenerManagersHash;
class EventListenerManagerMapEntry : public PLDHashEntryHdr
@ -6209,6 +6215,17 @@ nsContentUtils::IsFocusedContent(nsIContent* aContent)
return fm && fm->GetFocusedContent() == aContent;
}
#ifdef MOZ_IPC
#ifdef ANDROID
// static
already_AddRefed<nsFrameLoader>
nsContentUtils::GetActiveFrameLoader()
{
return nsCOMPtr<nsFrameLoader>(sActiveFrameLoader).forget();
}
#endif
#endif
void nsContentUtils::RemoveNewlines(nsString &aString)
{
// strip CR/LF and null

View File

@ -1170,6 +1170,9 @@ nsFrameLoader::DestroyChild()
{
#ifdef MOZ_IPC
if (mRemoteBrowser) {
#ifdef ANDROID
nsContentUtils::ClearActiveFrameLoader(this);
#endif
mRemoteBrowser->SetOwnerElement(nsnull);
// If this fails, it's most likely due to a content-process crash,
// and auto-cleanup will kick in. Otherwise, the child side will
@ -1705,6 +1708,9 @@ nsFrameLoader::ActivateRemoteFrame() {
#ifdef MOZ_IPC
if (mRemoteBrowser) {
mRemoteBrowser->Activate();
#ifdef ANDROID
nsContentUtils::SetActiveFrameLoader(this);
#endif
return NS_OK;
}
#endif

View File

@ -44,6 +44,12 @@
*
* ***** END LICENSE BLOCK ***** */
#ifdef MOZ_IPC
#ifdef ANDROID
#include "mozilla/dom/PBrowserParent.h"
#endif
#endif
#include "nsCOMPtr.h"
#include "nsEventStateManager.h"
#include "nsEventListenerManager.h"
@ -159,6 +165,12 @@
#import <ApplicationServices/ApplicationServices.h>
#endif
#ifdef MOZ_IPC
#ifdef ANDROID
#include "nsFrameLoader.h"
#endif
#endif
//#define DEBUG_DOCSHELL_FOCUS
#define NS_USER_INTERACTION_INTERVAL 5000 // ms
@ -1369,6 +1381,40 @@ nsEventStateManager::PreHandleEvent(nsPresContext* aPresContext,
DoContentCommandScrollEvent(static_cast<nsContentCommandEvent*>(aEvent));
}
break;
#ifdef MOZ_IPC
#ifdef ANDROID
case NS_TEXT_TEXT:
{
nsTextEvent *textEvent = static_cast<nsTextEvent*>(aEvent);
if (IsTargetCrossProcess(textEvent)) {
// Will not be handled locally, remote the event
mozilla::dom::PBrowserParent *remoteBrowser = GetCrossProcessTarget();
if (remoteBrowser &&
remoteBrowser->SendTextEvent(*textEvent)) {
// Cancel local dispatching
*aStatus = nsEventStatus_eConsumeNoDefault;
}
}
}
break;
case NS_COMPOSITION_START:
case NS_COMPOSITION_END:
{
nsCompositionEvent *compositionEvent =
static_cast<nsCompositionEvent*>(aEvent);
if (IsTargetCrossProcess(compositionEvent)) {
// Will not be handled locally, remote the event
mozilla::dom::PBrowserParent *remoteBrowser = GetCrossProcessTarget();
if (remoteBrowser &&
remoteBrowser->SendCompositionEvent(*compositionEvent)) {
// Cancel local dispatching
*aStatus = nsEventStatus_eConsumeNoDefault;
}
}
}
break;
#endif
#endif
}
return NS_OK;
}
@ -3199,6 +3245,49 @@ nsEventStateManager::PostHandleEvent(nsPresContext* aPresContext,
}
break;
#endif
#ifdef MOZ_IPC
#ifdef ANDROID
case NS_QUERY_SELECTED_TEXT:
case NS_QUERY_TEXT_CONTENT:
case NS_QUERY_CARET_RECT:
case NS_QUERY_TEXT_RECT:
case NS_QUERY_EDITOR_RECT:
case NS_QUERY_CONTENT_STATE:
// We don't remote nsITransferable yet
//case NS_QUERY_SELECTION_AS_TRANSFERABLE:
case NS_QUERY_CHARACTER_AT_POINT:
{
nsQueryContentEvent *queryEvent =
static_cast<nsQueryContentEvent*>(aEvent);
// If local query failed, try remote query
if (queryEvent->mSucceeded)
break;
mozilla::dom::PBrowserParent *remoteBrowser = GetCrossProcessTarget();
if (remoteBrowser &&
remoteBrowser->SendQueryContentEvent(*queryEvent)) {
queryEvent->mWasAsync = PR_TRUE;
queryEvent->mSucceeded = PR_TRUE;
}
}
break;
case NS_SELECTION_SET:
{
nsSelectionEvent *selectionEvent =
static_cast<nsSelectionEvent*>(aEvent);
// If local handler failed, try remoting the event
if (selectionEvent->mSucceeded)
break;
mozilla::dom::PBrowserParent *remoteBrowser = GetCrossProcessTarget();
if (remoteBrowser &&
remoteBrowser->SendSelectionEvent(*selectionEvent))
selectionEvent->mSucceeded = PR_TRUE;
}
break;
#endif // ANDROID
#endif // MOZ_IPC
}
//Reset target frame to null to avoid mistargeting after reentrant event
@ -3207,6 +3296,27 @@ nsEventStateManager::PostHandleEvent(nsPresContext* aPresContext,
return ret;
}
#ifdef MOZ_IPC
#ifdef ANDROID
mozilla::dom::PBrowserParent*
nsEventStateManager::GetCrossProcessTarget()
{
nsCOMPtr<nsFrameLoader> fl = nsContentUtils::GetActiveFrameLoader();
NS_ENSURE_TRUE(fl, nsnull);
return fl->GetRemoteBrowser();
}
PRBool
nsEventStateManager::IsTargetCrossProcess(nsGUIEvent *aEvent)
{
nsQueryContentEvent stateEvent(PR_TRUE, NS_QUERY_CONTENT_STATE, aEvent->widget);
nsContentEventHandler handler(mPresContext);
handler.OnQueryContentState(&stateEvent);
return !stateEvent.mSucceeded;
}
#endif
#endif
NS_IMETHODIMP
nsEventStateManager::NotifyDestroyPresContext(nsPresContext* aPresContext)
{

View File

@ -331,6 +331,13 @@ protected:
nsresult DoContentCommandEvent(nsContentCommandEvent* aEvent);
nsresult DoContentCommandScrollEvent(nsContentCommandEvent* aEvent);
#ifdef MOZ_IPC
#ifdef ANDROID
mozilla::dom::PBrowserParent *GetCrossProcessTarget();
PRBool IsTargetCrossProcess(nsGUIEvent *aEvent);
#endif
#endif
PRInt32 mLockCursor;
nsWeakFrame mCurrentTarget;

View File

@ -1234,7 +1234,7 @@ private:
public:
nsQueryContentEvent(PRBool aIsTrusted, PRUint32 aMsg, nsIWidget *aWidget) :
nsGUIEvent(aIsTrusted, aMsg, aWidget, NS_QUERY_CONTENT_EVENT),
mSucceeded(PR_FALSE)
mSucceeded(PR_FALSE), mWasAsync(PR_FALSE)
{
}
@ -1262,6 +1262,7 @@ public:
}
PRBool mSucceeded;
PRPackedBool mWasAsync;
struct {
PRUint32 mOffset;
PRUint32 mLength;

View File

@ -228,6 +228,7 @@ struct ParamTraits<nsQueryContentEvent>
static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
{
aResult->mWasAsync = PR_TRUE;
return ReadParam(aMsg, aIter, static_cast<nsGUIEvent*>(aResult)) &&
ReadParam(aMsg, aIter, &aResult->mSucceeded) &&
ReadParam(aMsg, aIter, &aResult->mInput.mOffset) &&