Talkback always reads application name when opening Jetpack Compose Dialog - accessibility

When opening a Dialog in Jetpack Compose, Talkback will always read the application label, before reading the Dialog title.
I have already tried setting the activity lable in the manifest to something different or just a space. While doing that, I noticed that talkback completely ignores the activity label and always goes for the outer application label.
Is there a way to stop Talkback from reading the application label entirely? And can I control what is read instead when opening a Dialog?

Related

Accessibility Role Application

Following is a dummy implementation of our web application
https://roleapplication.herokuapp.com/index.html
appArea element has role application as it contains highly complex widgets such as ms paint/editor/ms office.
Navigator contains standard web widgets such as dropdown and buttons
The HTML is something similar to as specified below.
<body>
<div class="appArea" role="application">
.......//Complex widgets
</div>
<div class="toolbar">
......//Buttons, dropdowns
</div>
</body>
Keyboard functionality of appArea is handled by its code and for toolbar we rely on keyboard handling with the screen reader as they work in web browser.
Issue - When user press escape in navigator area we blur the navigator so the focus by default goes to body.
Now as focus is in body then arrow keys moves the focus to toolbar and therefore user is never able to go into appArea. If focus is in appArea it works fine.
Expectation - When focus is on body then on pressing down arrow focus should inside the appArea and then appArea will get the key instead of screen reader.
Check the down arrow key functionality when page is loaded with and without screen reader.
Keyboard notes
Press f6 to go from widget 1 to widget 2 to navigator
You can use arrow/tab keys in widgets to navigate.
Move to navigator using f6 and press tab to go to any button and then press escape. Now focus is on body(check using
document.activeElement).
Without screen reader our widgets captures the key on body and process it even if they dont have focus.
However with screen reader, when body has focus and user press down arrow, screen reader consumes the key and move the focus to navigator instead of application area which has widgets and user is unable to go to appArea using arrow keys or other keys which screen reader consume.
Note -
If we give role application to complete application then default arrow key handling of navigator will stop working which is not desired
Removal of role application is not possible as appArea is quite complex with hundreds of widgets all having their keyboard handling.
There are three ways to interact with role="application".
Hit enter on the application element, exit out of edit mode (or forms mode) and use the application as if it is another web page. You can put other elements there and the screen reader will move through those elements in brows mode.
Hit enter on the application which pops the screen reader into edit mode where all keys are passed to the edit widget inside the application. and you handle everything within your application, probably on a keydown event.
Control the tabindex as the screen reader presses keys using a roving tabindex.
You currently have 1 and 3 which is really confusing. If you removed the application element, it would still work just fine. It sounds as if you want 2 though. 2 is highly discouraged unless you have a screen reader user constantly testing UX or building your app. Number 2 is mostly for games and is considered the "canvas" element for screen readers.
You do 2 by doing the following:
<div role="application">
<input type="button" autoFocus="true" value="Click me" />
<p aria-live="polite" id="spk"></p>
</div>
The spk element is to send messages to the screen reader which you need to do in this Window, Icon, Menu, Message (WIMM) interface. Remember that in this mode, you need to program everything and users get upset if expectations are not met.
You said you are making a word processor. This last option (number 2), is NOT meant to make a word processor. As a screen reader user, I have expectations and workflows for Word processors. You can't get that functionality with programming it manually in Javascript.
Instead, use the existing edit fields HTML provides for this reason, such as:
This text editor example
Please let me know if there is some reason why you would not want to use the above widget.
You could get away with using 3 along with normal widgets, but it is better to do what Google Drive does and allow users to enter edit mode when the page loads, or press a key, like escape, to enter the tabindex application area (which does not need to be in an application element, although it can be).
Edit: After reading your question again, it sounds as if you can't figure out how to enter the application element. You arrow to where the screen reader says "application" and hit enter. To get out, you either tab to the next tabindex element that is outside the application or press the special key command to exit out of the application. In NVDA, this key command is ctrl+nvda+space. On your application, the application element is the first element.
role='application' should be used on rare occasions. As you noted, it causes all keyboard events to skip the screen reader and go directly to your app. This causes the screen reader virtual cursor to not work. Typically, a screen reader will automatically go into "application" mode (often called "forms mode") for certain types of widgets, such as an input field. If you are using widget roles, you will get this "forms mode" for free.
When you say "arrow keys" are not working, are you talking about up/down arrows or left/right arrows? They have different behaviors for a screen reader.

How to "embed" one window inside another

I have inherited a Qt-based app that handles the master/detail relationship by presenting the detail screens as separate windows. The main window includes a list, and when you tap on a row a separate detail window is opened up.
In the code base, the detail windows are handled by a QML file and a matching .cpp file (the main window also has its own .cpp file). The problem I am facing is that a new client wants me to modify this application for them, except that they want everything to occur within a single window. They want the list to be shown on the left side, and then when a user taps a row, the detail screen is to be shown on the right side of the window in its own panel (but not in a separate window).
For various reasons I can't easily refactor this application. A quicker solution for me would be to continue to present the detail screen in its own window, but to make it a borderless window and position this borderless window over top of the main window (on the right) so that it appears to be a panel within the main window.
Is something like this possible with Qt? I have written Windows apps in the past that hooked into the Windows API to do something like, but I don't know whether this is even possible in a native Mac OS app, so I don't know whether Qt can handle it in some way automaticaly.
One thing you could try is to create a widget based "main" window and then use QWidget::createWindowContainer() to wrap the QtQuick windows for positioning them with QtWidget means, e.g. layouts.

Qt - Hiding window when the close button is hit

I am trying to implement a terminal in my application.
Currently, class Terminal inherits from QMainWindow, and all of its contents are lost if the close button is triggered. This does not affect the main application though.
I want the contents to stay and be accessible by the rest of the application. How can I achieve that?

Java FX 8 Popup does not move focus back to application

I have a Java FX application in which I show a Popup that contains a text field. I intentionally keep this popup visible even when the user clicks away from it. This works fine except for one case:
When the user has focus on the text field in the Popup, then clicks on a separate application, and then clicks back onto the text field. The FX application does not regain focus from the OS. If the user types on the keyboard, the other application will still receive the keyboard input. To work around this, the user has to click on the main FX application window outside of the popup.
The strange thing is that, in debugging, I can see that the text field in the Popup is getting focus, but the OS does not show that the FX application is now in focus. Is there a way that I can force the OS to move focus to my application?
This occurs on Windows and Mac. I tested with jdk 8 update 45 and jdk 8 update 92.
I did a test with a minimum Popup:
static class TestPopup extends Popup {
TestPopup() {
content.add(new TextField("Hello"))
}
}
and I show it by calling:
new TestPopup().show(somePaneInMainWindow, 0, 0)
After some research I found that this is expected behavior.
Answer found here:
http://bugs.java.com/bugdatabase/view_bug.do?bug_id=8123137
From the link:
This is the right behavior. All the JavaFX popup windows are
unfocusable, so they can receive input only if the owner window is
currently focused. Usually popups are set to auto hide, when the owner
gets unfocused, but this is not the case in this test, so the popup
just stays around.

Application.application.nativeWindow.activate() problem on Windows

I have an AIR application with a system tray icon. When clicked it shows and activates the app. This is working as expected when the app is hidden (docked), however if I select another application so my app is in the background clicking on the system tray icon does nothing.
Oddly I also have a contextual menu on the system tray icon, which has an option to restore, this calls the same event handler as ScreenMouseEvent.CLICK, yet works.
I expect it's something to do with the contextual menu changing the focus, perhaps it's a bug in how AIR works with the system tray, perhaps it's just something I'm missing. Would be good to know if that's the case.
Thanks in advance
Rob
//instead of just calling
activate();
//call
nativeApplication.activate()
//or even better
nativeApplication.activate(nativeWindow);
Update based on OP's input: if you have multiple windows open for the application, use:
nativeApplication.activate(nativeApplication.openedWindows[0]);
If you are not in the main WindowedApplication class, you can use the static property NativeApplication.nativeApplication to get a reference to the singleton object.
WindowedApplication.activate()
Activates the underlying NativeWindow (even if this application is not the active one).
NativeApplication.activate(window:NativeWindow = null)
Activates this application. If the operating system allows activation, then the specified window is activated and brought to the desktop foreground; that is, in front of the windows of other applications. (If the window parameter is null, then a visible window of this application is activated.)
livedocs is not clear on why this is happening. It says activate() activates the underlying native window - one would expect it to be brought to the front when it is activated, but that's not happening.

Resources