mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1166436 part.3 mozilla::ContentCache should store active composition information and TabParent should use them r=m_kato
This commit is contained in:
parent
8dffab649c
commit
549eff0114
@ -262,10 +262,6 @@ TabParent::TabParent(nsIContentParent* aManager,
|
||||
: TabContext(aContext)
|
||||
, mFrameElement(nullptr)
|
||||
, mWritingMode()
|
||||
, mIMEComposing(false)
|
||||
, mIMECompositionEnding(false)
|
||||
, mIMEEventCountAfterEnding(0)
|
||||
, mIMECompositionStart(0)
|
||||
, mIMECompositionRectOffset(0)
|
||||
, mRect(0, 0, 0, 0)
|
||||
, mDimensions(0, 0)
|
||||
@ -2311,47 +2307,12 @@ TabParent::SendCompositionEvent(WidgetCompositionEvent& event)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (event.CausesDOMTextEvent()) {
|
||||
return SendCompositionChangeEvent(event);
|
||||
}
|
||||
|
||||
mIMEComposing = !event.CausesDOMCompositionEndEvent();
|
||||
mIMECompositionStart = mContentCache.SelectionStart();
|
||||
if (mIMECompositionEnding) {
|
||||
mIMEEventCountAfterEnding++;
|
||||
if (!mContentCache.OnCompositionEvent(event)) {
|
||||
return true;
|
||||
}
|
||||
return PBrowserParent::SendCompositionEvent(event);
|
||||
}
|
||||
|
||||
/**
|
||||
* During REQUEST_TO_COMMIT_COMPOSITION or REQUEST_TO_CANCEL_COMPOSITION,
|
||||
* widget usually sends a NS_COMPOSITION_CHANGE event to finalize or
|
||||
* clear the composition, respectively
|
||||
*
|
||||
* Because the event will not reach content in time, we intercept it
|
||||
* here and pass the text as the EndIMEComposition return value
|
||||
*/
|
||||
bool
|
||||
TabParent::SendCompositionChangeEvent(WidgetCompositionEvent& event)
|
||||
{
|
||||
if (mIMECompositionEnding) {
|
||||
mIMECompositionText = event.mData;
|
||||
mIMEEventCountAfterEnding++;
|
||||
return true;
|
||||
}
|
||||
|
||||
// We must be able to simulate the selection because
|
||||
// we might not receive selection updates in time
|
||||
if (!mIMEComposing) {
|
||||
mIMECompositionStart = mContentCache.SelectionStart();
|
||||
}
|
||||
mContentCache.SetSelection(mIMECompositionStart + event.mData.Length());
|
||||
mIMEComposing = !event.CausesDOMCompositionEndEvent();
|
||||
|
||||
return PBrowserParent::SendCompositionEvent(event);
|
||||
}
|
||||
|
||||
bool
|
||||
TabParent::SendSelectionEvent(WidgetSelectionEvent& event)
|
||||
{
|
||||
@ -2430,19 +2391,11 @@ TabParent::RecvEndIMEComposition(const bool& aCancel,
|
||||
nsString* aComposition)
|
||||
{
|
||||
nsCOMPtr<nsIWidget> widget = GetWidget();
|
||||
if (!widget)
|
||||
if (!widget) {
|
||||
return true;
|
||||
|
||||
mIMECompositionEnding = true;
|
||||
mIMEEventCountAfterEnding = 0;
|
||||
|
||||
widget->NotifyIME(IMENotification(aCancel ? REQUEST_TO_CANCEL_COMPOSITION :
|
||||
REQUEST_TO_COMMIT_COMPOSITION));
|
||||
|
||||
mIMECompositionEnding = false;
|
||||
*aNoCompositionEvent = !mIMEEventCountAfterEnding;
|
||||
*aComposition = mIMECompositionText;
|
||||
mIMECompositionText.Truncate(0);
|
||||
}
|
||||
*aNoCompositionEvent =
|
||||
!mContentCache.RequestToCommitComposition(widget, aCancel, *aComposition);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -470,8 +470,6 @@ protected:
|
||||
const int32_t& aX, const int32_t& aY,
|
||||
const int32_t& aCx, const int32_t& aCy) override;
|
||||
|
||||
bool SendCompositionChangeEvent(mozilla::WidgetCompositionEvent& event);
|
||||
|
||||
bool InitBrowserConfiguration(const nsCString& aURI,
|
||||
BrowserConfiguration& aConfiguration);
|
||||
|
||||
@ -481,13 +479,6 @@ protected:
|
||||
static TabParent *mIMETabParent;
|
||||
ContentCache mContentCache;
|
||||
mozilla::WritingMode mWritingMode;
|
||||
bool mIMEComposing;
|
||||
bool mIMECompositionEnding;
|
||||
uint32_t mIMEEventCountAfterEnding;
|
||||
// Buffer to store composition text during ResetInputState
|
||||
// Compositions in almost all cases are small enough for nsAutoString
|
||||
nsAutoString mIMECompositionText;
|
||||
uint32_t mIMECompositionStart;
|
||||
|
||||
uint32_t mIMECompositionRectOffset;
|
||||
InfallibleTArray<LayoutDeviceIntRect> mIMECompositionRects;
|
||||
|
@ -6,9 +6,21 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "mozilla/ContentCache.h"
|
||||
#include "mozilla/TextEvents.h"
|
||||
#include "nsIWidget.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
using namespace widget;
|
||||
|
||||
ContentCache::ContentCache()
|
||||
: mCompositionStart(UINT32_MAX)
|
||||
, mCompositionEventsDuringRequest(0)
|
||||
, mIsComposing(false)
|
||||
, mRequestedToCommitOrCancelComposition(false)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
ContentCache::Clear()
|
||||
{
|
||||
@ -28,4 +40,65 @@ ContentCache::SetSelection(uint32_t aAnchorOffset, uint32_t aFocusOffset)
|
||||
mSelection.mFocus = aFocusOffset;
|
||||
}
|
||||
|
||||
bool
|
||||
ContentCache::OnCompositionEvent(const WidgetCompositionEvent& aEvent)
|
||||
{
|
||||
if (!aEvent.CausesDOMTextEvent()) {
|
||||
MOZ_ASSERT(aEvent.message == NS_COMPOSITION_START);
|
||||
mIsComposing = !aEvent.CausesDOMCompositionEndEvent();
|
||||
mCompositionStart = SelectionStart();
|
||||
// XXX What's this case??
|
||||
if (mRequestedToCommitOrCancelComposition) {
|
||||
mCommitStringByRequest = aEvent.mData;
|
||||
mCompositionEventsDuringRequest++;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// XXX Why do we ignore following composition events here?
|
||||
// TextComposition must handle following events correctly!
|
||||
|
||||
// During REQUEST_TO_COMMIT_COMPOSITION or REQUEST_TO_CANCEL_COMPOSITION,
|
||||
// widget usually sends a NS_COMPOSITION_CHANGE event to finalize or
|
||||
// clear the composition, respectively.
|
||||
// Because the event will not reach content in time, we intercept it
|
||||
// here and pass the text as the DidRequestToCommitOrCancelComposition()
|
||||
// return value.
|
||||
if (mRequestedToCommitOrCancelComposition) {
|
||||
mCommitStringByRequest = aEvent.mData;
|
||||
mCompositionEventsDuringRequest++;
|
||||
return false;
|
||||
}
|
||||
|
||||
// We must be able to simulate the selection because
|
||||
// we might not receive selection updates in time
|
||||
if (!mIsComposing) {
|
||||
mCompositionStart = SelectionStart();
|
||||
}
|
||||
// XXX This causes different behavior from non-e10s mode.
|
||||
// Selection range should represent caret position in the composition
|
||||
// string but this means selection range is all of the composition string.
|
||||
SetSelection(mCompositionStart + aEvent.mData.Length());
|
||||
mIsComposing = !aEvent.CausesDOMCompositionEndEvent();
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
ContentCache::RequestToCommitComposition(nsIWidget* aWidget,
|
||||
bool aCancel,
|
||||
nsAString& aLastString)
|
||||
{
|
||||
mRequestedToCommitOrCancelComposition = true;
|
||||
mCompositionEventsDuringRequest = 0;
|
||||
|
||||
aWidget->NotifyIME(IMENotification(aCancel ? REQUEST_TO_CANCEL_COMPOSITION :
|
||||
REQUEST_TO_COMMIT_COMPOSITION));
|
||||
|
||||
mRequestedToCommitOrCancelComposition = false;
|
||||
aLastString = mCommitStringByRequest;
|
||||
mCommitStringByRequest.Truncate(0);
|
||||
return mCompositionEventsDuringRequest;
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
@ -10,8 +10,12 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/EventForwards.h"
|
||||
#include "nsString.h"
|
||||
|
||||
class nsIWidget;
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
/**
|
||||
@ -23,12 +27,37 @@ namespace mozilla {
|
||||
class ContentCache final
|
||||
{
|
||||
public:
|
||||
ContentCache();
|
||||
|
||||
void Clear();
|
||||
|
||||
void SetText(const nsAString& aText);
|
||||
const nsString& Text() const { return mText; }
|
||||
uint32_t TextLength() const { return mText.Length(); }
|
||||
|
||||
/**
|
||||
* OnCompositionEvent() should be called before sending composition string.
|
||||
* This returns true if the event should be sent. Otherwise, false.
|
||||
*/
|
||||
bool OnCompositionEvent(const WidgetCompositionEvent& aCompositionEvent);
|
||||
/**
|
||||
* RequestToCommitComposition() requests to commit or cancel composition to
|
||||
* the widget. If it's handled synchronously, this returns the number of
|
||||
* composition events after that.
|
||||
*
|
||||
* @param aWidget The widget to be requested to commit or cancel
|
||||
* the composition.
|
||||
* @param aCancel When the caller tries to cancel the composition, true.
|
||||
* Otherwise, i.e., tries to commit the composition, false.
|
||||
* @param aLastString The last composition string before requesting to
|
||||
* commit or cancel composition.
|
||||
* @return The count of composition events ignored after a call of
|
||||
* WillRequestToCommitOrCancelComposition().
|
||||
*/
|
||||
uint32_t RequestToCommitComposition(nsIWidget* aWidget,
|
||||
bool aCancel,
|
||||
nsAString& aLastString);
|
||||
|
||||
void SetSelection(uint32_t aCaretOffset)
|
||||
{
|
||||
SetSelection(aCaretOffset, aCaretOffset);
|
||||
@ -49,6 +78,13 @@ public:
|
||||
private:
|
||||
// Whole text in the target
|
||||
nsString mText;
|
||||
// This is commit string which is caused by our request.
|
||||
nsString mCommitStringByRequest;
|
||||
// Start offset of the composition string.
|
||||
uint32_t mCompositionStart;
|
||||
// Count of composition events during requesting commit or cancel the
|
||||
// composition.
|
||||
uint32_t mCompositionEventsDuringRequest;
|
||||
|
||||
struct Selection final
|
||||
{
|
||||
@ -71,6 +107,9 @@ private:
|
||||
return Reversed() ? mAnchor - mFocus : mFocus - mAnchor;
|
||||
}
|
||||
} mSelection;
|
||||
|
||||
bool mIsComposing;
|
||||
bool mRequestedToCommitOrCancelComposition;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
Loading…
Reference in New Issue
Block a user