From 72b5afddb9a47084850af9a403c4a1823336b5cf Mon Sep 17 00:00:00 2001 From: Jan-Arve Saether Date: Fri, 2 Mar 2012 16:51:26 +0100 Subject: Fix get_accFocus() to return CHILDID_SELF when it returns itself. This means that the AT client knows it should not have to ask for the focus child anymore. Previously, some clients (NVDA) kept on asking infinitely because of this. Change-Id: Ia2bd2e1088a899f7d1a0c9189024accdacfd693b Reviewed-by: Frederik Gladhorn --- .../platforms/windows/qwindowsaccessibility.cpp | 48 ++++++++++++++++++---- 1 file changed, 41 insertions(+), 7 deletions(-) (limited to 'src/plugins/platforms') diff --git a/src/plugins/platforms/windows/qwindowsaccessibility.cpp b/src/plugins/platforms/windows/qwindowsaccessibility.cpp index 4c24cdd8d0..1a8f593609 100644 --- a/src/plugins/platforms/windows/qwindowsaccessibility.cpp +++ b/src/plugins/platforms/windows/qwindowsaccessibility.cpp @@ -121,6 +121,21 @@ void accessibleDebugClientCalls_helper(const char* funcName, const QAccessibleIn typedef QSharedPointer QAIPointer; +static bool compareAccessible(QAccessibleInterface *one, QAccessibleInterface *other) +{ + if (one == other) return true; + if (!one || !other) return false; + + if (one->object() && other->object() && (one->object() == other->object())) + return true; + QAIPointer onePar(one->parent()); + QAIPointer otherPar(other->parent()); + + if (compareAccessible(onePar.data(), otherPar.data())) + return onePar->indexOfChild(one) == otherPar->indexOfChild(other); + return false; +} + // This stuff is used for widgets/items with no window handle: typedef QMap > NotifyMap; Q_GLOBAL_STATIC(NotifyMap, qAccessibleRecentSentEvents) @@ -1221,7 +1236,22 @@ HRESULT STDMETHODCALLTYPE QWindowsAccessible::accSelect(long flagsSelect, VARIAN return res ? S_OK : S_FALSE; } -// moz: [important] +/*! + \internal + Can return: + + +-------------+------------------------------------------------------------------------------+ + | VT_EMPTY | None. Neither this object nor any of its children has the keyboard focus. | + +-------------+------------------------------------------------------------------------------+ + | VT_I4 | lVal is CHILDID_SELF. The object itself has the keyboard focus. | + +-------------+------------------------------------------------------------------------------+ + | VT_I4 | lVal contains the child ID of the child element that has the keyboard focus. | + +-------------+------------------------------------------------------------------------------+ + | VT_DISPATCH | pdispVal member is the address of the IDispatch interface for the child | + | | object that has the keyboard focus. | + +-------------+------------------------------------------------------------------------------+ + moz: [important] +*/ HRESULT STDMETHODCALLTYPE QWindowsAccessible::get_accFocus(VARIANT *pvarID) { accessibleDebugClientCalls(accessible); @@ -1229,16 +1259,20 @@ HRESULT STDMETHODCALLTYPE QWindowsAccessible::get_accFocus(VARIANT *pvarID) return E_FAIL; if (QAccessibleInterface *acc = accessible->focusChild()) { - QWindowsAccessible* wacc = new QWindowsAccessible(acc); - IDispatch *iface = 0; - wacc->QueryInterface(IID_IDispatch, (void**)&iface); - if (iface) { + if (compareAccessible(acc, accessible)) { + (*pvarID).vt = VT_I4; + (*pvarID).lVal = CHILDID_SELF; + delete acc; + return S_OK; + } else { + QWindowsAccessible* wacc = new QWindowsAccessible(acc); + IDispatch *iface = 0; + wacc->QueryInterface(IID_IDispatch, (void**)&iface); (*pvarID).vt = VT_DISPATCH; (*pvarID).pdispVal = iface; return S_OK; - } else { - delete wacc; } + delete acc; } (*pvarID).vt = VT_EMPTY; return S_FALSE; -- cgit v1.2.3