diff --git a/editor/base/nsEditor.cpp b/editor/base/nsEditor.cpp index 848f37a1c78a..59c918b96b8a 100644 --- a/editor/base/nsEditor.cpp +++ b/editor/base/nsEditor.cpp @@ -54,6 +54,9 @@ #include "nsICaret.h" #include "nsIStyleContext.h" #include "nsIEditActionListener.h" +#include "nsIKBStateControl.h" +#include "nsIWidget.h" +#include "nsIScrollbar.h" #include "nsICSSLoader.h" #include "nsICSSStyleSheet.h" @@ -824,6 +827,9 @@ nsEditor::SaveFile(nsFileSpec *aFileSpec, PRBool aReplaceExisting, PRBool aSaveC { if (!aFileSpec) return NS_ERROR_NULL_POINTER; + + ForceCompositionEnd(); + // get the document nsCOMPtr doc; @@ -1456,6 +1462,71 @@ nsEditor::SetCompositionString(const nsString& aCompositionString, nsIPrivateTex return NS_ERROR_NOT_IMPLEMENTED; } +nsIWidget * GetDeepestWidget(nsIView * aView) +{ + + PRInt32 count; + aView->GetChildCount(count); + if (0 != count) { + for (PRInt32 i=0;iGetChild(i, child); + nsIWidget * widget = GetDeepestWidget(child); + if (widget) { + return widget; + } else { + aView->GetWidget(widget); + if (widget) { + nsCOMPtr scrollbar(do_QueryInterface(widget)); + if (scrollbar) { + NS_RELEASE(widget); + } else { + return widget; + } + } + } + } + } + return nsnull; +} + +NS_IMETHODIMP +nsEditor::ForceCompositionEnd() +{ + +// We can test mInIMEMode and do some optimization for Mac and Window +// Howerver, since UNIX support over-the-spot, we cannot rely on that +// flag for Unix. +// We should use nsILookAndFeel to resolve this + +#if defined(XP_MAC) || defined(XP_WIN) + if(! mInIMEMode) + return NS_OK; +#endif + + nsresult res = NS_OK; + nsCOMPtr shell; + + GetPresShell(getter_AddRefs(shell)); + if (shell) { + nsCOMPtr viewmgr; + + shell->GetViewManager(getter_AddRefs(viewmgr)); + if (viewmgr) { + nsIView* view; + viewmgr->GetRootView(view); // views are not refCounted + nsIWidget *widget = GetDeepestWidget(view); + if (widget) { + nsCOMPtr kb = do_QueryInterface(widget); + if(kb) { + res = kb->ResetInputState(); + } + } + } + } + + return NS_OK; +} #ifdef XP_MAC #pragma mark - #pragma mark --- public nsEditor methods --- diff --git a/editor/base/nsEditor.h b/editor/base/nsEditor.h index f3e8b989045f..344976c90c7f 100644 --- a/editor/base/nsEditor.h +++ b/editor/base/nsEditor.h @@ -229,6 +229,7 @@ public: NS_IMETHOD QueryComposition(nsTextEventReply* aReply); NS_IMETHOD SetCompositionString(const nsString& aCompositionString, nsIPrivateTextRangeList* aTextRangeList,nsTextEventReply* aReply); NS_IMETHOD EndComposition(void); + NS_IMETHOD ForceCompositionEnd(void); public: diff --git a/editor/base/nsEditorEventListeners.cpp b/editor/base/nsEditorEventListeners.cpp index da89018bba13..74f9df2071f6 100644 --- a/editor/base/nsEditorEventListeners.cpp +++ b/editor/base/nsEditorEventListeners.cpp @@ -452,6 +452,12 @@ nsTextEditorMouseListener::MouseDown(nsIDOMEvent* aMouseEvent) return NS_OK; } + // If we got a mouse down inside the editing area, we should force the + // IME to commit before we change the cursor position + nsCOMPtr imeEditor = do_QueryInterface(mEditor); + if(imeEditor) + imeEditor->ForceCompositionEnd(); + nsCOMPtr editor (do_QueryInterface(mEditor)); if (!editor) { return NS_OK; } diff --git a/editor/base/nsHTMLEditor.cpp b/editor/base/nsHTMLEditor.cpp index 2e4e8a40bf6e..b0b1da6ad299 100644 --- a/editor/base/nsHTMLEditor.cpp +++ b/editor/base/nsHTMLEditor.cpp @@ -849,6 +849,7 @@ NS_IMETHODIMP nsHTMLEditor::SetInlineProperty(nsIAtom *aProperty, { if (!aProperty) { return NS_ERROR_NULL_POINTER; } if (!mRules) { return NS_ERROR_NOT_INITIALIZED; } + ForceCompositionEnd(); nsAutoEditBatch batchIt(this); @@ -1107,6 +1108,7 @@ NS_IMETHODIMP nsHTMLEditor::RemoveInlineProperty(nsIAtom *aProperty, const nsStr { if (!aProperty) { return NS_ERROR_NULL_POINTER; } if (!mRules) { return NS_ERROR_NOT_INITIALIZED; } + ForceCompositionEnd(); nsAutoEditBatch batchIt(this); nsAutoRules beginRulesSniffing(this, kOpRemoveTextProperty, nsIEditor::eNext); @@ -1355,6 +1357,7 @@ NS_IMETHODIMP nsHTMLEditor::InsertText(const nsString& aStringToInsert) NS_IMETHODIMP nsHTMLEditor::InsertHTML(const nsString& aInputString) { + ForceCompositionEnd(); nsAutoEditBatch beginBatching(this); nsAutoRules beginRulesSniffing(this, kOpInsertElement, nsIEditor::eNext); @@ -1545,6 +1548,7 @@ nsHTMLEditor::InsertElementAtSelection(nsIDOMElement* aElement, PRBool aDeleteSe if (!aElement) return NS_ERROR_NULL_POINTER; + ForceCompositionEnd(); nsAutoEditBatch beginBatching(this); nsAutoRules beginRulesSniffing(this, kOpInsertElement, nsIEditor::eNext); diff --git a/editor/libeditor/base/nsEditor.cpp b/editor/libeditor/base/nsEditor.cpp index 848f37a1c78a..59c918b96b8a 100644 --- a/editor/libeditor/base/nsEditor.cpp +++ b/editor/libeditor/base/nsEditor.cpp @@ -54,6 +54,9 @@ #include "nsICaret.h" #include "nsIStyleContext.h" #include "nsIEditActionListener.h" +#include "nsIKBStateControl.h" +#include "nsIWidget.h" +#include "nsIScrollbar.h" #include "nsICSSLoader.h" #include "nsICSSStyleSheet.h" @@ -824,6 +827,9 @@ nsEditor::SaveFile(nsFileSpec *aFileSpec, PRBool aReplaceExisting, PRBool aSaveC { if (!aFileSpec) return NS_ERROR_NULL_POINTER; + + ForceCompositionEnd(); + // get the document nsCOMPtr doc; @@ -1456,6 +1462,71 @@ nsEditor::SetCompositionString(const nsString& aCompositionString, nsIPrivateTex return NS_ERROR_NOT_IMPLEMENTED; } +nsIWidget * GetDeepestWidget(nsIView * aView) +{ + + PRInt32 count; + aView->GetChildCount(count); + if (0 != count) { + for (PRInt32 i=0;iGetChild(i, child); + nsIWidget * widget = GetDeepestWidget(child); + if (widget) { + return widget; + } else { + aView->GetWidget(widget); + if (widget) { + nsCOMPtr scrollbar(do_QueryInterface(widget)); + if (scrollbar) { + NS_RELEASE(widget); + } else { + return widget; + } + } + } + } + } + return nsnull; +} + +NS_IMETHODIMP +nsEditor::ForceCompositionEnd() +{ + +// We can test mInIMEMode and do some optimization for Mac and Window +// Howerver, since UNIX support over-the-spot, we cannot rely on that +// flag for Unix. +// We should use nsILookAndFeel to resolve this + +#if defined(XP_MAC) || defined(XP_WIN) + if(! mInIMEMode) + return NS_OK; +#endif + + nsresult res = NS_OK; + nsCOMPtr shell; + + GetPresShell(getter_AddRefs(shell)); + if (shell) { + nsCOMPtr viewmgr; + + shell->GetViewManager(getter_AddRefs(viewmgr)); + if (viewmgr) { + nsIView* view; + viewmgr->GetRootView(view); // views are not refCounted + nsIWidget *widget = GetDeepestWidget(view); + if (widget) { + nsCOMPtr kb = do_QueryInterface(widget); + if(kb) { + res = kb->ResetInputState(); + } + } + } + } + + return NS_OK; +} #ifdef XP_MAC #pragma mark - #pragma mark --- public nsEditor methods --- diff --git a/editor/libeditor/base/nsEditor.h b/editor/libeditor/base/nsEditor.h index f3e8b989045f..344976c90c7f 100644 --- a/editor/libeditor/base/nsEditor.h +++ b/editor/libeditor/base/nsEditor.h @@ -229,6 +229,7 @@ public: NS_IMETHOD QueryComposition(nsTextEventReply* aReply); NS_IMETHOD SetCompositionString(const nsString& aCompositionString, nsIPrivateTextRangeList* aTextRangeList,nsTextEventReply* aReply); NS_IMETHOD EndComposition(void); + NS_IMETHOD ForceCompositionEnd(void); public: diff --git a/editor/libeditor/html/nsHTMLEditor.cpp b/editor/libeditor/html/nsHTMLEditor.cpp index 2e4e8a40bf6e..b0b1da6ad299 100644 --- a/editor/libeditor/html/nsHTMLEditor.cpp +++ b/editor/libeditor/html/nsHTMLEditor.cpp @@ -849,6 +849,7 @@ NS_IMETHODIMP nsHTMLEditor::SetInlineProperty(nsIAtom *aProperty, { if (!aProperty) { return NS_ERROR_NULL_POINTER; } if (!mRules) { return NS_ERROR_NOT_INITIALIZED; } + ForceCompositionEnd(); nsAutoEditBatch batchIt(this); @@ -1107,6 +1108,7 @@ NS_IMETHODIMP nsHTMLEditor::RemoveInlineProperty(nsIAtom *aProperty, const nsStr { if (!aProperty) { return NS_ERROR_NULL_POINTER; } if (!mRules) { return NS_ERROR_NOT_INITIALIZED; } + ForceCompositionEnd(); nsAutoEditBatch batchIt(this); nsAutoRules beginRulesSniffing(this, kOpRemoveTextProperty, nsIEditor::eNext); @@ -1355,6 +1357,7 @@ NS_IMETHODIMP nsHTMLEditor::InsertText(const nsString& aStringToInsert) NS_IMETHODIMP nsHTMLEditor::InsertHTML(const nsString& aInputString) { + ForceCompositionEnd(); nsAutoEditBatch beginBatching(this); nsAutoRules beginRulesSniffing(this, kOpInsertElement, nsIEditor::eNext); @@ -1545,6 +1548,7 @@ nsHTMLEditor::InsertElementAtSelection(nsIDOMElement* aElement, PRBool aDeleteSe if (!aElement) return NS_ERROR_NULL_POINTER; + ForceCompositionEnd(); nsAutoEditBatch beginBatching(this); nsAutoRules beginRulesSniffing(this, kOpInsertElement, nsIEditor::eNext); diff --git a/editor/libeditor/text/nsEditorEventListeners.cpp b/editor/libeditor/text/nsEditorEventListeners.cpp index da89018bba13..74f9df2071f6 100644 --- a/editor/libeditor/text/nsEditorEventListeners.cpp +++ b/editor/libeditor/text/nsEditorEventListeners.cpp @@ -452,6 +452,12 @@ nsTextEditorMouseListener::MouseDown(nsIDOMEvent* aMouseEvent) return NS_OK; } + // If we got a mouse down inside the editing area, we should force the + // IME to commit before we change the cursor position + nsCOMPtr imeEditor = do_QueryInterface(mEditor); + if(imeEditor) + imeEditor->ForceCompositionEnd(); + nsCOMPtr editor (do_QueryInterface(mEditor)); if (!editor) { return NS_OK; } diff --git a/editor/public/nsIEditorIMESupport.h b/editor/public/nsIEditorIMESupport.h index 4ed533e17993..cca58a500cba 100644 --- a/editor/public/nsIEditorIMESupport.h +++ b/editor/public/nsIEditorIMESupport.h @@ -63,6 +63,10 @@ public: */ NS_IMETHOD QueryComposition(nsTextEventReply *aReply) = 0; + /** + * ForceCompositionEnd() force the composition end + */ + NS_IMETHOD ForceCompositionEnd() = 0; };