Closed Bug 441553 Opened 16 years ago Closed 5 years ago

ROLE_WINDOW should be a natural part of the hierarchy

Categories

(Core :: Disability Access APIs, defect)

x86
Windows XP
defect
Not set
normal

Tracking

()

RESOLVED WONTFIX

People

(Reporter: aaronlev, Unassigned)

References

(Blocks 1 open bug)

Details

(Keywords: access)

Whenever we have an accParent that goes to a ROLE_WINDOW, the next parent up is not correct. That's because we rely on oleacc to handle OBJID_WINDOW, and it doesn't know about our hierarchy.

If we handle OBJID_WINDOW ourselves and create a window accessible for it, we should hopefully be able to fix this.

Note that we need the ROLE_WINDOW objects in there so that WindowFromAccessibleObject() works correctly. If it wasn't for that we could possibly skip having these objects altogether.

Before implementing this solution I think we should check with the IA2 list and contacts at Microsoft accessibility to ensure that it will work.
As far as I have been able to determine, you don't need to have ROLE_WINDOW objects if you implement IOleWindow on your IAccessibles. WindowFromAccessibleObject() just keeps moving up the hierarchy until it can QI to IOleWindow and call IOleWindow::GetWindow(). The default ROLE_WINDOW objects implement IOleWindow, which is why they can always be used as a fallback.
James, should we have separate accessible object for window or the document accessible could be a window accessible the same time?
(In reply to comment #2)
> James, should we have separate accessible object for window or the document
> accessible could be a window accessible the same time?
As far as NVDA is concerned, it doesn't matter; it doesn't use the window accessibles directly. We actually use IAccessible2::get_windowHandle to get the window handle for IAccessible2 objects, but even if we didn't, WindowFromAccessibleObject should work as long as you support IOleWindow somewhere in the hierarchy.

Note that IAccessible2::get_windowHandle still intermittently fails with E_FAIL in Mozilla. We've never been able to work out why this happens or how to reproduce it exactly. If you use the same code to implement IOleWindow::GetWindow, we may run into trouble. The correct solution would be to fix this code, but unfortunately, this is going to be hard without a better idea of why it fails.
So the window is an accessible having HWND? I mean if the accessible document hasn't own HWND then it shouldn't implement IOleWindow, right?
(In reply to comment #4)
> So the window is an accessible having HWND? I mean if the accessible document
> hasn't own HWND then it shouldn't implement IOleWindow, right?
There are two ways you can look at this:
1. The way you suggest. In that case, only the root accessible for the window should implement IOleWindow. Btw, this is the way UIA does it; UIA returns NULL for window handle except for the root accessible of that window.
2. You could also say that every accessible is part of a window and therefore has an associated hwnd, even if it isn't the root. For example, IAccessible2::get_windowHandle returns a window handle for all accessibles, not just the window root. In theory, this is faster for MSAA clients, as WindowFromAccessibleObject doesn't have to crawl the hierarchy to find an accessible which implements IOleWindow.
Either way, WindowFromAccessibleObject will return the same thing in the end. I don't personally mind (and nor does NVDA), but note that option 2 is possibly faster. Having said that, option 1 allows clients to determine the root accessible for the window very easily. I'm not sure whether other ATs need that.
James, http://www.mozilla.org/access/windows/msaa-server#WindowFromAccessibleObject said WindowFromAccessibleObject looks for ROLE_WINDOW. Isn't it true? Does it look IOleWindow actually? How is it related with handling of WM_GETOBJECT messages for OBJID_WINDOW?
(In reply to comment #6)
> http://www.mozilla.org/access/windows/msaa-server#WindowFromAccessibleObject
> said WindowFromAccessibleObject looks for ROLE_WINDOW. Isn't it true? Does it
> look IOleWindow actually?
From what I've been able to determine, it searches the parents looking for an accessible which can QI to IOleWindow. The reason that oleacc's ROLE_WINDOW objects are used is that they support IOleWindow. This can be seen in QT, where accParent never returns a ROLE_WINDOW object (even at the top of the hierarchy), but WindowFromAccessibleObject still works. Further investigation revealed that all of their objects implement IOleWindow.

> How is it related with handling of WM_GETOBJECT
> messages for OBJID_WINDOW?
These still need to return ROLE_WINDOW objects, as they do already. oleacc will take care of that.
The MSDN documentation for WindowFromAccessibleObject at http://msdn.microsoft.com/en-us/library/dd373876%28VS.85%29.aspx says the out variable is an:

Address of a variable that receives a handle to the window containing the object specified in pacc. If this value is NULL after the call, the object is not contained within a window; for example, the mouse pointer is not contained within a window.

This would indicate that option 2 is the correct implementation and that the UIA behavior described in comment 5 is not correct.

BTW, does Mozilla only have an hwnd for the top level window?  If there are other non-root HWNDs then the AT would not be able to rely on querying just any accessible to find the root HWND.
(In reply to comment #8)

> BTW, does Mozilla only have an hwnd for the top level window?

Iirc yes. However window plugins (like flash) can be part of Firefox hierarchy but they handle messages on own side so we're not responsible for their accessible objects.

> If there are
> other non-root HWNDs then the AT would not be able to rely on querying just any
> accessible to find the root HWND.

The question probably is if AT needs this.
(In reply to comment #8)
> The MSDN documentation for WindowFromAccessibleObject... says:
> Address of a variable that receives a handle to the window containing the
> object specified in pacc. If this value is NULL after the call, the object is
> not contained within a window
> This would indicate that option 2 is the correct implementation and that the
> UIA behavior described in comment 5 is not correct.
Just to clarify, UIA returns NULL for the UIA nativeWindowHandle property, not for WindowFromAccessibleObject. It was probably an invalid analogy on my part.
(In reply to comment #9)
> > BTW, does Mozilla only have an hwnd for the top level window?
> Iirc yes.
I don't think this is correct. Documents get their own hwnd, for example.

> > If there are
> > other non-root HWNDs then the AT would not be able to rely on querying just any
> > accessible to find the root HWND.
Of course not, but the AT can never do this. If you want the root hwnd, you should get the hwnd for an accessible and call GetAncestor(hwnd, GA_ROOT).
(In reply to comment #11)
> (In reply to comment #9)
> > > BTW, does Mozilla only have an hwnd for the top level window?
> > Iirc yes.
> I don't think this is correct. Documents get their own hwnd, for example.

I thought it was fixed. Thanks, Jamie.
Jamie, should we answer for OBJID_WINDOW when we receive WM_GETOBJECT?
(In reply to comment #13)
> Jamie, should we answer for OBJID_WINDOW when we receive WM_GETOBJECT?
Probably not. If you do, you should probably return a ROLE_SYSTEM_WINDOW object that behaves very similarly to the native window accessibles. This is especially important for the top level window, as it implements accNavigate such that you can navigate to sibbling top level windows.
(In reply to comment #14)
> (In reply to comment #13)
> > Jamie, should we answer for OBJID_WINDOW when we receive WM_GETOBJECT?
> Probably not.

Isn't this bug about this?

> If you do, you should probably return a ROLE_SYSTEM_WINDOW object
> that behaves very similarly to the native window accessibles. This is
> especially important for the top level window, as it implements accNavigate
> such that you can navigate to sibbling top level windows.

I guess we could add new object for window, that returns system_window role and implements accNavigate to get sibling top level windows. Plus implement OBJID_WINDOW handling. But is there a way to get native title bar accessible or we should implement ourself?
(In reply to comment #15)
> > > Jamie, should we answer for OBJID_WINDOW when we receive WM_GETOBJECT?
> > Probably not.
> Isn't this bug about this?
Sort of. Aaron notes in comment #0:
> Note that we need the ROLE_WINDOW objects in there so that
WindowFromAccessibleObject() works correctly. If it wasn't for that we could
possibly skip having these objects altogether.

NVDA (and I suspect other ATs) doesn't really care about any ROLE_WINDOW objects except at the top level. What they do care about is that WindowFromAccessibleObject() works. However, as i noted in comment #1, I'm pretty sure that WindowFromAccessibleObject() uses IOleWindow, so implementing this will achieve the same. In other words, you could possibly remove all ROLE_WINDOW objects from the hierarchy (except for real top level windows) as long as you implement IOleWindow.

> But is there a way to get native title bar accessible or
> we should implement ourself?
Just return AccessibleObjectFromWindow with OBJID_TITLEBAR as needed.
No longer blocks: 191a11y
Do we need to do anything further on this bug?
Flags: needinfo?(surkov.alexander)
Flags: needinfo?(jamie)
TL;DR: I don't really care and it seems no one else does either.

When not in window emulation mode, I think the only time Gecko returns an oleacc window object is for the top level frame. Most of Gecko is in a single HWND now anyway. This does mean WindowFromAccessibleObject will return the wrong window handle for the few cases that do get their own HWND (e.g. drop-downs and menus). However, anyone using Gecko accessibility seriously will use IAccessible2::windowhandle anyway, plus these cases are rare.

I can't speak for window emulation mode, since NVDA doesn't use it. Looking at the code, it seems the hierarchy might still be broken there, since a tab document will return an oleacc window object. That said, it doesn't seem like other AT vendors are complaining.
Flags: needinfo?(jamie)
Agreed, the windows emulation is at risk. However the AT from the list must be figured out how to deal with it. I guess we could keep this open as it contains useful conversations, in case if we will be required to reveal the issue later. If we end up with no emulation in couple years, then we can safely close this bug.
Flags: needinfo?(surkov.alexander)

While we still have AT using window emulation, we haven't had any requests for this ROLE_WINDOW functionality. Rather than adding more functionality to this legacy support, I think we should encourage AT needing additional functionality from us to switch away from window emulation.

Status: NEW → RESOLVED
Closed: 5 years ago
Resolution: --- → WONTFIX
You need to log in before you can comment on or make changes to this bug.