Bug 1741792 part 1: Cache the caret in the parent process using caret events. r=eeejay

As well as the caret offset, we also need to cache whether the caret is at the end of a line.
Therefore, this information has been added to caret events.

Differential Revision: https://phabricator.services.mozilla.com/D132097
This commit is contained in:
James Teh 2021-12-01 04:48:33 +00:00
Родитель 8166483436
Коммит 934c9cb61c
11 изменённых файлов: 77 добавлений и 28 удалений

Просмотреть файл

@ -244,9 +244,9 @@ already_AddRefed<nsIAccessibleEvent> a11y::MakeXPCEvent(AccEvent* aEvent) {
if (eventGroup & (1 << AccEvent::eCaretMoveEvent)) {
AccCaretMoveEvent* cm = downcast_accEvent(aEvent);
xpEvent = new xpcAccCaretMoveEvent(type, ToXPC(acc), ToXPCDocument(doc),
node, fromUser, cm->GetCaretOffset(),
cm->IsSelectionCollapsed());
xpEvent = new xpcAccCaretMoveEvent(
type, ToXPC(acc), ToXPCDocument(doc), node, fromUser,
cm->GetCaretOffset(), cm->IsSelectionCollapsed(), cm->IsAtEndOfLine());
return xpEvent.forget();
}

Просмотреть файл

@ -341,12 +341,13 @@ class AccReorderEvent : public AccTreeMutationEvent {
class AccCaretMoveEvent : public AccEvent {
public:
AccCaretMoveEvent(LocalAccessible* aAccessible, int32_t aCaretOffset,
bool aIsSelectionCollapsed,
bool aIsSelectionCollapsed, bool aIsAtEndOfLine,
EIsFromUserInput aIsFromUserInput = eAutoDetect)
: AccEvent(::nsIAccessibleEvent::EVENT_TEXT_CARET_MOVED, aAccessible,
aIsFromUserInput),
mCaretOffset(aCaretOffset),
mIsSelectionCollapsed(aIsSelectionCollapsed) {}
mIsSelectionCollapsed(aIsSelectionCollapsed),
mIsAtEndOfLine(aIsAtEndOfLine) {}
virtual ~AccCaretMoveEvent() {}
// AccEvent
@ -359,11 +360,13 @@ class AccCaretMoveEvent : public AccEvent {
int32_t GetCaretOffset() const { return mCaretOffset; }
bool IsSelectionCollapsed() const { return mIsSelectionCollapsed; }
bool IsAtEndOfLine() { return mIsAtEndOfLine; }
private:
int32_t mCaretOffset;
bool mIsSelectionCollapsed;
bool mIsAtEndOfLine;
};
/**

Просмотреть файл

@ -148,9 +148,9 @@ void SelectionManager::ProcessTextSelChangeEvent(AccEvent* aEvent) {
selection->FocusOffset());
mAccWithCaret = caretCntr;
if (mCaretOffset != -1) {
RefPtr<AccCaretMoveEvent> caretMoveEvent =
new AccCaretMoveEvent(caretCntr, mCaretOffset, selection->IsCollapsed(),
aEvent->FromUserInput());
RefPtr<AccCaretMoveEvent> caretMoveEvent = new AccCaretMoveEvent(
caretCntr, mCaretOffset, selection->IsCollapsed(),
caretCntr->IsCaretAtEndOfLine(), aEvent->FromUserInput());
nsEventShell::FireEvent(caretMoveEvent);
}
}

Просмотреть файл

@ -954,7 +954,8 @@ nsresult LocalAccessible::HandleAccEvent(AccEvent* aEvent) {
case nsIAccessibleEvent::EVENT_TEXT_CARET_MOVED: {
AccCaretMoveEvent* event = downcast_accEvent(aEvent);
ipcDoc->SendCaretMoveEvent(id, event->GetCaretOffset(),
event->IsSelectionCollapsed());
event->IsSelectionCollapsed(),
event->IsAtEndOfLine());
break;
}
case nsIAccessibleEvent::EVENT_TEXT_INSERTED:

Просмотреть файл

@ -20,4 +20,9 @@ interface nsIAccessibleCaretMoveEvent: nsIAccessibleEvent
* Return true if there is no selection.
*/
readonly attribute bool isSelectionCollapsed;
/**
* Return true if the caret is at the end of a line.
*/
readonly attribute bool isAtEndOfLine;
};

Просмотреть файл

@ -300,7 +300,8 @@ mozilla::ipc::IPCResult DocAccessibleParent::RecvCaretMoveEvent(
#if defined(XP_WIN)
const LayoutDeviceIntRect& aCaretRect,
#endif // defined (XP_WIN)
const int32_t& aOffset, const bool& aIsSelectionCollapsed) {
const int32_t& aOffset, const bool& aIsSelectionCollapsed,
const bool& aIsAtEndOfLine) {
if (mShutdown) {
return IPC_OK();
}
@ -311,6 +312,10 @@ mozilla::ipc::IPCResult DocAccessibleParent::RecvCaretMoveEvent(
return IPC_OK();
}
mCaretId = aID;
mCaretOffset = aOffset;
mIsCaretAtEndOfLine = aIsAtEndOfLine;
#if defined(XP_WIN)
ProxyCaretMoveEvent(proxy, aCaretRect);
#else
@ -326,8 +331,9 @@ mozilla::ipc::IPCResult DocAccessibleParent::RecvCaretMoveEvent(
nsINode* node = nullptr;
bool fromUser = true; // XXX fix me
uint32_t type = nsIAccessibleEvent::EVENT_TEXT_CARET_MOVED;
RefPtr<xpcAccCaretMoveEvent> event = new xpcAccCaretMoveEvent(
type, xpcAcc, doc, node, fromUser, aOffset, aIsSelectionCollapsed);
RefPtr<xpcAccCaretMoveEvent> event =
new xpcAccCaretMoveEvent(type, xpcAcc, doc, node, fromUser, aOffset,
aIsSelectionCollapsed, aIsAtEndOfLine);
nsCoreUtils::DispatchAccEvent(std::move(event));
return IPC_OK();

Просмотреть файл

@ -42,7 +42,10 @@ class DocAccessibleParent : public RemoteAccessible,
mTopLevel(false),
mTopLevelInContentProcess(false),
mShutdown(false),
mFocus(0) {
mFocus(0),
mCaretId(0),
mCaretOffset(-1),
mIsCaretAtEndOfLine(false) {
sMaxDocID++;
mActorID = sMaxDocID;
MOZ_ASSERT(!LiveDocs().Get(mActorID));
@ -103,7 +106,8 @@ class DocAccessibleParent : public RemoteAccessible,
#if defined(XP_WIN)
const LayoutDeviceIntRect& aCaretRect,
#endif
const int32_t& aOffset, const bool& aIsSelectionCollapsed) final;
const int32_t& aOffset, const bool& aIsSelectionCollapsed,
const bool& aIsAtEndOfLine) final;
virtual mozilla::ipc::IPCResult RecvTextChangeEvent(
const uint64_t& aID, const nsString& aStr, const int32_t& aStart,
@ -288,6 +292,25 @@ class DocAccessibleParent : public RemoteAccessible,
return const_cast<DocAccessibleParent*>(this)->GetAccessible(mFocus);
}
/**
* Get the HyperText Accessible containing the caret and the offset of the
* caret within. If there is no caret in this document, returns
* {nullptr, -1}.
*/
std::pair<RemoteAccessible*, int32_t> GetCaret() const {
if (mCaretOffset == -1) {
return {nullptr, -1};
}
RemoteAccessible* acc =
const_cast<DocAccessibleParent*>(this)->GetAccessible(mCaretId);
if (!acc) {
return {nullptr, -1};
}
return {acc, mCaretOffset};
}
bool IsCaretAtEndOfLine() const { return mIsCaretAtEndOfLine; }
private:
~DocAccessibleParent() {
LiveDocs().Remove(mActorID);
@ -352,6 +375,9 @@ class DocAccessibleParent : public RemoteAccessible,
nsTHashSet<RefPtr<dom::BrowserBridgeParent>> mPendingOOPChildDocs;
uint64_t mFocus;
uint64_t mCaretId;
int32_t mCaretOffset;
bool mIsCaretAtEndOfLine;
static uint64_t sMaxDocID;
static nsTHashMap<nsUint64HashKey, DocAccessibleParent*>& LiveDocs() {

Просмотреть файл

@ -96,7 +96,8 @@ parent:
async ShowEvent(ShowEventData data, bool aFromuser);
async HideEvent(uint64_t aRootID, bool aFromUser);
async StateChangeEvent(uint64_t aID, uint64_t aState, bool aEnabled);
async CaretMoveEvent(uint64_t aID, int32_t aOffset, bool aIsSelectionCollapsed);
async CaretMoveEvent(uint64_t aID, int32_t aOffset,
bool aIsSelectionCollapsed, bool aIsAtEndOfLine);
async TextChangeEvent(uint64_t aID, nsString aStr, int32_t aStart, uint32_t aLen,
bool aIsInsert, bool aFromUser);
async SelectionEvent(uint64_t aID, uint64_t aWidgetID, uint32_t aType);

Просмотреть файл

@ -199,21 +199,23 @@ bool DocAccessibleChild::SendFocusEvent(const uint64_t& aID,
bool DocAccessibleChild::SendCaretMoveEvent(const uint64_t& aID,
const int32_t& aOffset,
const bool& aIsSelectionCollapsed) {
const bool& aIsSelectionCollapsed,
const bool& aIsAtEndOfLine) {
return SendCaretMoveEvent(aID, GetCaretRectFor(aID), aOffset,
aIsSelectionCollapsed);
aIsSelectionCollapsed, aIsAtEndOfLine);
}
bool DocAccessibleChild::SendCaretMoveEvent(
const uint64_t& aID, const LayoutDeviceIntRect& aCaretRect,
const int32_t& aOffset, const bool& aIsSelectionCollapsed) {
const int32_t& aOffset, const bool& aIsSelectionCollapsed,
const bool& aIsAtEndOfLine) {
if (IsConstructedInParentProcess()) {
return PDocAccessibleChild::SendCaretMoveEvent(aID, aCaretRect, aOffset,
aIsSelectionCollapsed);
return PDocAccessibleChild::SendCaretMoveEvent(
aID, aCaretRect, aOffset, aIsSelectionCollapsed, aIsAtEndOfLine);
}
PushDeferredEvent(MakeUnique<SerializedCaretMove>(
this, aID, aCaretRect, aOffset, aIsSelectionCollapsed));
this, aID, aCaretRect, aOffset, aIsSelectionCollapsed, aIsAtEndOfLine));
return true;
}

Просмотреть файл

@ -51,11 +51,13 @@ class DocAccessibleChild : public DocAccessibleChildBase {
bool SendStateChangeEvent(const uint64_t& aID, const uint64_t& aState,
const bool& aEnabled);
bool SendCaretMoveEvent(const uint64_t& aID, const int32_t& aOffset,
const bool& aIsSelectionCollapsed);
const bool& aIsSelectionCollapsed,
const bool& aIsAtEndOfLine);
bool SendCaretMoveEvent(const uint64_t& aID,
const LayoutDeviceIntRect& aCaretRect,
const int32_t& aOffset,
const bool& aIsSelectionCollapsed);
const bool& aIsSelectionCollapsed,
const bool& aIsAtEndOfLine);
bool SendFocusEvent(const uint64_t& aID);
bool SendFocusEvent(const uint64_t& aID,
const LayoutDeviceIntRect& aCaretRect);
@ -173,22 +175,24 @@ class DocAccessibleChild : public DocAccessibleChildBase {
struct SerializedCaretMove final : public DeferredEvent {
SerializedCaretMove(DocAccessibleChild* aTarget, uint64_t aID,
const LayoutDeviceIntRect& aCaretRect, int32_t aOffset,
bool aIsSelectionCollapsed)
bool aIsSelectionCollapsed, bool aIsAtEndOfLine)
: DeferredEvent(aTarget),
mID(aID),
mCaretRect(aCaretRect),
mOffset(aOffset),
mIsSelectionCollapsed(aIsSelectionCollapsed) {}
mIsSelectionCollapsed(aIsSelectionCollapsed),
mIsAtEndOfLine(aIsAtEndOfLine) {}
void Dispatch(DocAccessibleChild* aIPCDoc) override {
Unused << aIPCDoc->SendCaretMoveEvent(mID, mCaretRect, mOffset,
mIsSelectionCollapsed);
Unused << aIPCDoc->SendCaretMoveEvent(
mID, mCaretRect, mOffset, mIsSelectionCollapsed, mIsAtEndOfLine);
}
uint64_t mID;
LayoutDeviceIntRect mCaretRect;
int32_t mOffset;
bool mIsSelectionCollapsed;
bool mIsAtEndOfLine;
};
struct SerializedFocus final : public DeferredEvent {

Просмотреть файл

@ -59,7 +59,8 @@ parent:
async HideEvent(uint64_t aRootID, bool aFromUser);
async StateChangeEvent(uint64_t aID, uint64_t aState, bool aEnabled);
async CaretMoveEvent(uint64_t aID, LayoutDeviceIntRect aCaretRect,
int32_t aOffset, bool aIsSelectionCollapsed);
int32_t aOffset, bool aIsAtEndOfLine,
bool aIsSelectionCollapsed);
async TextChangeEvent(uint64_t aID, nsString aStr, int32_t aStart, uint32_t aLen,
bool aIsInsert, bool aFromUser);
sync SyncTextChangeEvent(uint64_t aID, nsString aStr, int32_t aStart,