Opened 3 months ago

Last modified 2 months ago

#19222 new defect

labels for accessibility cannot be associated with wxSpinCtrlDouble

Reported by: lukaszgo1 Owned by:
Priority: normal Milestone:
Component: wxMSW Version: 3.0.5
Keywords: Accessibility Cc: l.golonka@…
Blocked By: Blocking:
Patch: no

Description

Currently it is impossible to associate a label with wxSpinCtrlDouble in a way which is recognized by screen readers on Windows. The problem can be reproduced as follows:

  1. Start the attached sample (I've used wxPython here since it was just easier)
  2. Run Accessibility Inspect, ensure that in the Options menu MSAA mode is checked and explore hierarchy of the accessible objects in the sample applications started in step 1.
  3. Verify that wxSpinCtrl is properly labeled whereas for wxSpinCtrlDouble name is none.
  4. Compare the way in which objects are placed for a standard wxSpinCtrl and for a wxSpinCtrlDouble.

The reason why wxSpinCtrlDouble has no accessible name even though there is the static text with the label to its left is because of the additional window with the role ROLE_SYSTEM_CLIENT named "wxSpinCtrlDouble" which encloses both the edit field and the spinbox. When accessed via MSAA edit fields attempts to retrieve their name from their parent by asking about the static text directly to the left which in this case does not exist. Furthermore it is impossible to workaround that using wxAccessible. I'm pretty sure that if not for this additional panel which encloses both edit field and the spinBox the label would be properly picked up.
In much older version of wxPython 2.9.5 in which there is no panel and both edit field and the spinBox are direct descendants of the main window wxSpinCtrlDouble can be properly labeled.

Attachments (1)

wx_spin_demo.pyw download (2.1 KB) - added by lukaszgo1 3 months ago.
Sample application

Download all attachments as: .zip

Change History (8)

Changed 3 months ago by lukaszgo1

Sample application

comment:1 follow-up: Changed 3 months ago by vadz

Thanks for reporting this, but unfortunately I don't know what would be the best way to fix this.

Is there some way to tell MSAA to ignore this parent window, i.e. make it "transparent" for it? Changing the code to avoid it would be quite annoying and we use similar approach in several/many different places...

comment:2 in reply to: ↑ 1 Changed 3 months ago by lukaszgo1

  • Cc l.golonka@… added

Replying to vadz:

Is there some way to tell MSAA to ignore this parent window, i.e. make it "transparent" for it?

None that I'm aware of unfortunately.

Changing the code to avoid it would be quite annoying and we use similar approach in several/many different places...

In NVDA screen reader we're using wxVidgets via wxPython quite extensively and SpinCtrlDouble is the first control ever for which this occurs- what other vidgets follow this patter? It is also worth pointing out that only edit control and comboboxes are retrieving their label from the parent so for other types of controls the additional panel causes no issues at all. By the way what this panel is for - as I said in the first comment in older versions of wx it was not there at least for SpinCtrlDouble.

comment:3 follow-up: Changed 3 months ago by vadz

what other widgets follow this pattern?

I thought everything using wxCompositeWindow could suffer from this problem.

It is also worth pointing out that only edit control and comboboxes are retrieving their label from the parent so for other types of controls the additional panel causes no issues at all.

But taking this into account, I think only wxSearchCtrl could be affected by this.

I still don't know what to do about this one (or these two), however. The trouble is that wxSpinCtrlDouble must appear as a single window from the point of wx API, and the simplest way to make this work is to actually make it a single window. But it needs 2 windows for its implementation, so the only solution is to make these 2 windows children of this window itself.

Could we do what MSAA does and look for a preceding wxStaticText in our own code and use its label to identify this control perhaps?

comment:4 in reply to: ↑ 3 ; follow-up: Changed 2 months ago by lukaszgo1

Replying to vadz:

The trouble is that wxSpinCtrlDouble must appear as a single window from the point of wx API, and the simplest way to make this work is to actually make it a single window. But it needs 2 windows for its implementation, so the only solution is to make these 2 windows children of this window itself.

Why wxSpinCtrlDouble needs to appear as a single window whereas wxSpinCtrl does not? Since the latter can be properly labeled without any trouble perhaps it would be possible to simply follow the same pattern which is used for wxSpinCtrl for wxSpinCtrlDouble?

Could we do what MSAA does and look for a preceding wxStaticText in our own code and use its label to identify this control perhaps?

That is the main problem - if it were possible to label an edit field ourselves for MSAA I would be able to use wxAccessible myself and call it a day. But as I explained above edit fields cannot be labeled programmatically except by placing static text with the label directly to its left.

comment:5 in reply to: ↑ 4 ; follow-up: Changed 2 months ago by vadz

Replying to lukaszgo1:

Replying to vadz:

The trouble is that wxSpinCtrlDouble must appear as a single window from the point of wx API, and the simplest way to make this work is to actually make it a single window. But it needs 2 windows for its implementation, so the only solution is to make these 2 windows children of this window itself.

Why wxSpinCtrlDouble needs to appear as a single window whereas wxSpinCtrl does not?

It does, too, but it's not a problem for it.

Since the latter can be properly labeled without any trouble perhaps it would be possible to simply follow the same pattern which is used for wxSpinCtrl for wxSpinCtrlDouble?

wxSpinCtrl maps to the native window, wxSpinCtrlDouble under MSW is implemented as a combination of 2 windows because there is no native control providing this functionality. We could indeed reimplement it using MSW-specific code, but this is not really satisfactory as it would be quite a bit of work and, worse, we'd really like generic implementation to work correctly from accessibility point of view.

Could we do what MSAA does and look for a preceding wxStaticText in our own code and use its label to identify this control perhaps?

That is the main problem - if it were possible to label an edit field ourselves for MSAA I would be able to use wxAccessible myself and call it a day. But as I explained above edit fields cannot be labeled programmatically except by placing static text with the label directly to its left.

Yes, but this is without doing anything special in our code. We could implement a custom wxAccessible for wxSpinCtrlDouble and implement its GetDescription() to return the text of the previous wxStaticText if any. If wxDataViewCtrl works correctly for you, it should work with this control too.

comment:6 in reply to: ↑ 5 ; follow-up: Changed 2 months ago by lukaszgo1

Replying to vadz:

wxSpinCtrl maps to the native window, wxSpinCtrlDouble under MSW is implemented as a combination of 2 windows because there is no native control providing this functionality. We could indeed reimplement it using MSW-specific code, but this is not really satisfactory as it would be quite a bit of work and, worse, we'd really like generic implementation to work correctly from accessibility point of view.

As far as I understand wxAccessible currently works only under MSW so any implementation using it would benefit only Windows. If I'm correct there seems to be no advantage to using wxAccessible as compared to creating a native implementation of wxSpinCtrlDouble.

Yes, but this is without doing anything special in our code. We could implement a custom wxAccessible for wxSpinCtrlDouble and implement its GetDescription() to return the text of the previous wxStaticText if any. If wxDataViewCtrl works correctly for you, it should work with this control too.

As I've explained several times before it is impossible to programatically overwrite label of edit field for MSAA so it would not work. Overwriting the description is no substitute for labeling the edit field and would result in a very unusual experience.

comment:7 in reply to: ↑ 6 Changed 2 months ago by vadz

Replying to lukaszgo1:

As far as I understand wxAccessible currently works only under MSW so any implementation using it would benefit only Windows. If I'm correct there seems to be no advantage to using wxAccessible as compared to creating a native implementation of wxSpinCtrlDouble.

Isn't the problem itself MSW-specific?

Yes, but this is without doing anything special in our code. We could implement a custom wxAccessible for wxSpinCtrlDouble and implement its GetDescription() to return the text of the previous wxStaticText if any. If wxDataViewCtrl works correctly for you, it should work with this control too.

As I've explained several times before it is impossible to programatically overwrite label of edit field for MSAA so it would not work. Overwriting the description is no substitute for labeling the edit field and would result in a very unusual experience.

Could we override navigation logic instead?

Sorry, I don't have a solution, so I'm just trying to think of some way to do it.

Note: See TracTickets for help on using tickets.