mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 705057 part.3 XP level code shouldn't call nsIWidget::ResetInputState() and nsIWidget::CancelIMEComposition() directly r=smaug+ehsan
This commit is contained in:
parent
892d596d9d
commit
a654e6725b
@ -89,6 +89,13 @@ TextComposition::SynthesizeCommit(bool aDiscard)
|
||||
composition.DispatchCompsotionEventRunnable(NS_COMPOSITION_END, data);
|
||||
}
|
||||
|
||||
nsresult
|
||||
TextComposition::NotifyIME(widget::NotificationToIME aNotification)
|
||||
{
|
||||
NS_ENSURE_TRUE(mPresContext, NS_ERROR_NOT_AVAILABLE);
|
||||
return nsIMEStateManager::NotifyIME(aNotification, mPresContext);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* TextComposition::CompositionEventDispatcher
|
||||
******************************************************************************/
|
||||
|
@ -61,6 +61,12 @@ public:
|
||||
*/
|
||||
void SynthesizeCommit(bool aDiscard);
|
||||
|
||||
/**
|
||||
* Send a notification to IME. It depends on the IME or platform spec what
|
||||
* will occur (or not occur).
|
||||
*/
|
||||
nsresult NotifyIME(widget::NotificationToIME aNotification);
|
||||
|
||||
private:
|
||||
// This class holds nsPresContext weak. This instance shouldn't block
|
||||
// destroying it. When the presContext is being destroyed, it's notified to
|
||||
|
@ -112,9 +112,10 @@ nsIMEStateManager::OnRemoveContent(nsPresContext* aPresContext,
|
||||
// to unsafe to run script (in PresShell::HandleEvent()).
|
||||
nsCOMPtr<nsIWidget> widget = aPresContext->GetNearestWidget();
|
||||
if (widget) {
|
||||
nsresult rv = widget->CancelIMEComposition();
|
||||
nsresult rv =
|
||||
storedComposition.NotifyIME(REQUEST_TO_CANCEL_COMPOSITION);
|
||||
if (NS_FAILED(rv)) {
|
||||
widget->ResetInputState();
|
||||
storedComposition.NotifyIME(REQUEST_TO_COMMIT_COMPOSITION);
|
||||
}
|
||||
// By calling the APIs, the composition may have been finished normally.
|
||||
compositionInContent =
|
||||
@ -220,8 +221,9 @@ nsIMEStateManager::OnChangeFocusInternal(nsPresContext* aPresContext,
|
||||
oldWidget = widget;
|
||||
else
|
||||
oldWidget = GetWidget(sPresContext);
|
||||
if (oldWidget)
|
||||
oldWidget->ResetInputState();
|
||||
if (oldWidget) {
|
||||
NotifyIME(REQUEST_TO_COMMIT_COMPOSITION, oldWidget);
|
||||
}
|
||||
}
|
||||
|
||||
// Update IME state for new focus widget
|
||||
@ -307,7 +309,7 @@ nsIMEStateManager::UpdateIMEState(const IMEState &aNewIMEState,
|
||||
}
|
||||
|
||||
// commit current composition
|
||||
widget->ResetInputState();
|
||||
NotifyIME(REQUEST_TO_COMMIT_COMPOSITION, widget);
|
||||
|
||||
InputContextAction action(InputContextAction::CAUSE_UNKNOWN,
|
||||
InputContextAction::FOCUS_NOT_CHANGED);
|
||||
@ -495,6 +497,44 @@ nsIMEStateManager::DispatchCompositionEvent(nsINode* aEventTargetNode,
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
nsresult
|
||||
nsIMEStateManager::NotifyIME(NotificationToIME aNotification,
|
||||
nsIWidget* aWidget)
|
||||
{
|
||||
NS_ENSURE_TRUE(aWidget, NS_ERROR_INVALID_ARG);
|
||||
|
||||
TextComposition* composition = nullptr;
|
||||
if (sTextCompositions) {
|
||||
composition = sTextCompositions->GetCompositionFor(aWidget);
|
||||
}
|
||||
switch (aNotification) {
|
||||
case NOTIFY_IME_OF_CURSOR_POS_CHANGED:
|
||||
return aWidget->ResetInputState();
|
||||
case REQUEST_TO_COMMIT_COMPOSITION:
|
||||
return composition ? aWidget->ResetInputState() : NS_OK;
|
||||
case REQUEST_TO_CANCEL_COMPOSITION:
|
||||
return composition ? aWidget->CancelIMEComposition() : NS_OK;
|
||||
default:
|
||||
MOZ_NOT_REACHED("Unsupported notification");
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
nsresult
|
||||
nsIMEStateManager::NotifyIME(NotificationToIME aNotification,
|
||||
nsPresContext* aPresContext)
|
||||
{
|
||||
NS_ENSURE_TRUE(aPresContext, NS_ERROR_INVALID_ARG);
|
||||
|
||||
nsIWidget* widget = aPresContext->GetNearestWidget();
|
||||
if (!widget) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
return NotifyIME(aNotification, widget);
|
||||
}
|
||||
|
||||
|
||||
// nsTextStateManager notifies widget of any text and selection changes
|
||||
// in the currently focused editor
|
||||
|
@ -7,6 +7,7 @@
|
||||
#define nsIMEStateManager_h__
|
||||
|
||||
#include "nscore.h"
|
||||
#include "nsEvent.h"
|
||||
#include "nsIWidget.h"
|
||||
|
||||
class nsDispatchingCallback;
|
||||
@ -96,6 +97,15 @@ public:
|
||||
nsEventStatus* aStatus,
|
||||
nsDispatchingCallback* aCallBack);
|
||||
|
||||
/**
|
||||
* Send a notification to IME. It depends on the IME or platform spec what
|
||||
* will occur (or not occur).
|
||||
*/
|
||||
static nsresult NotifyIME(mozilla::widget::NotificationToIME aNotification,
|
||||
nsIWidget* aWidget);
|
||||
static nsresult NotifyIME(mozilla::widget::NotificationToIME aNotification,
|
||||
nsPresContext* aPresContext);
|
||||
|
||||
protected:
|
||||
static nsresult OnChangeFocusInternal(nsPresContext* aPresContext,
|
||||
nsIContent* aContent,
|
||||
|
@ -2031,73 +2031,31 @@ nsEditor::GetPhonetic(nsAString& aPhonetic)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
static nsresult
|
||||
GetEditorContentWindow(dom::Element *aRoot, nsIWidget **aResult)
|
||||
{
|
||||
NS_ENSURE_TRUE(aRoot && aResult, NS_ERROR_NULL_POINTER);
|
||||
|
||||
*aResult = 0;
|
||||
|
||||
// Not ref counted
|
||||
nsIFrame *frame = aRoot->GetPrimaryFrame();
|
||||
|
||||
NS_ENSURE_TRUE(frame, NS_ERROR_FAILURE);
|
||||
|
||||
*aResult = frame->GetNearestWidget();
|
||||
NS_ENSURE_TRUE(*aResult, NS_ERROR_FAILURE);
|
||||
|
||||
NS_ADDREF(*aResult);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsEditor::GetWidget(nsIWidget **aWidget)
|
||||
{
|
||||
NS_ENSURE_TRUE(aWidget, NS_ERROR_NULL_POINTER);
|
||||
*aWidget = nullptr;
|
||||
|
||||
nsCOMPtr<nsIWidget> widget;
|
||||
nsresult res = GetEditorContentWindow(GetRoot(), getter_AddRefs(widget));
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
NS_ENSURE_TRUE(widget, NS_ERROR_NOT_AVAILABLE);
|
||||
|
||||
NS_ADDREF(*aWidget = widget);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
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 LookAndFeel to resolve this
|
||||
|
||||
#if defined(XP_MACOSX) || defined(XP_WIN) || defined(XP_OS2)
|
||||
// XXXmnakano see bug 558976, ResetInputState() has two meaning which are
|
||||
// "commit the composition" and "cursor is moved". This method name is
|
||||
// "ForceCompositionEnd", so, ResetInputState() should be used only for the
|
||||
// former here. However, ResetInputState() is also used for the latter here
|
||||
// because even if we don't have composition, we call ResetInputState() on
|
||||
// Linux. Currently, nsGtkIMModule can know the timing of the cursor move,
|
||||
// so, the latter meaning should be gone and we should remove this #if.
|
||||
if(! mInIMEMode)
|
||||
return NS_OK;
|
||||
#endif
|
||||
|
||||
nsCOMPtr<nsIWidget> widget;
|
||||
nsresult res = GetWidget(getter_AddRefs(widget));
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
|
||||
if (widget) {
|
||||
res = widget->ResetInputState();
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
nsCOMPtr<nsIPresShell> ps = GetPresShell();
|
||||
if (!ps) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
nsPresContext* pc = ps->GetPresContext();
|
||||
if (!pc) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
if (!mInIMEMode) {
|
||||
// XXXmnakano see bug 558976, ResetInputState() has two meaning which are
|
||||
// "commit the composition" and "cursor is moved". This method name is
|
||||
// "ForceCompositionEnd", so, ResetInputState() should be used only for the
|
||||
// former here. However, ResetInputState() is also used for the latter here
|
||||
// because even if we don't have composition, we call ResetInputState() on
|
||||
// Linux. Currently, nsGtkIMModule can know the timing of the cursor move,
|
||||
// so, the latter meaning should be gone.
|
||||
// XXX This may commit a composition in another editor.
|
||||
return nsIMEStateManager::NotifyIME(NOTIFY_IME_OF_CURSOR_POS_CHANGED, pc);
|
||||
}
|
||||
|
||||
return nsIMEStateManager::NotifyIME(REQUEST_TO_COMMIT_COMPOSITION, pc);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -388,10 +388,6 @@ protected:
|
||||
bool aGoForward,
|
||||
bool bNoBlockCrossing);
|
||||
|
||||
// Get nsIWidget interface
|
||||
nsresult GetWidget(nsIWidget **aWidget);
|
||||
|
||||
|
||||
// install the event listeners for the editor
|
||||
virtual nsresult InstallEventListeners();
|
||||
|
||||
|
@ -98,6 +98,13 @@ enum Modifier {
|
||||
|
||||
typedef uint16_t Modifiers;
|
||||
|
||||
// NotificationToIME is shared by nsIMEStateManager and TextComposition.
|
||||
enum NotificationToIME {
|
||||
NOTIFY_IME_OF_CURSOR_POS_CHANGED,
|
||||
REQUEST_TO_COMMIT_COMPOSITION,
|
||||
REQUEST_TO_CANCEL_COMPOSITION
|
||||
};
|
||||
|
||||
} // namespace widget
|
||||
} // namespace mozilla
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user