Repository: nvaccess/nvda

Issue:
Windows 10 Action Center: Brightness percentage not reported for brightness quick action
### Steps to reproduce:

1. Ensure the Brightness quick action is enabled for the Action Center. This can be enabled in Settings -> System -> Notifications & actions -> Add or remove quick actions.
2. Open Action Center by pressing Windows+a.
3. Tab to the quick actions and press right arrow until you land on Brightness.
    - Expected: NVDA should report the brightness percentage.
    - Actual: NVDA reports only "Brightness  toggle button  not pressed".
4. Press space to change the brightness.
    - Expected: NVDA should report the new brightness percentage.
    - Actual: NVDA reports nothing.

### System configuration:

#### NVDA Installed/portable/running from source:
Installed.

#### NVDA version:
alpha-16157,526d6fca

#### Windows version:
Version 1809 (OS Build 17763.55)

### Additional info:

Even though Windows reports this as a toggle button, it isn't. The toggle state is always off. Narrator behaves as such too.

The percentage is exposed via the ItemStatus UIA property. IMO, this is inda weird, but at least it's exposed.

Because of the weirdness of this control, I'd suggest that rather than generically supporting ItemStatus as value for toggle buttons, we should just do it for this control (or at least this app). If we do it specifically for this control, we could also map it to button instead of toggle button, which is probably less confusing.

Relevant dev info for the control:

```
appModule: <'shellexperiencehost' (appName u'shellexperiencehost', ...>
UIA automationID: Microsoft.QuickAction.Brightness
UIA frameworkID: XAML
UIA providerDescription: [pid:17568,providerId:0x0 Main(parent link):Unidentified Provider (unmanaged:Windows.UI.Xaml.dll)]
UIA className: ToggleButton
UIA patterns available: LegacyIAccessiblePattern, InvokePattern, ScrollItemPattern, TogglePattern
```


Discussion:
Hi,

Note that this is also applicable to Focus Assist toggle state changes.

Technical: one way to implement this is through a combination of runtime object property coercion (event_NVDAObject_init) and state change events.

I'll introduce a proof of concept implementation in Windows 10 App Essentials in the next 30 minutes.

Thanks.
Hi,

I may have been too enthusiastic about this... This work may take a while - at least managed to let NVDA announce item status via state change, but will need to investigate why it is announcing the previous state sometimes.

Thanks.
Hi,

Technical: we need to tell NVDA to listen to item status property event from now on, as it can be used for brightness and other quick action toggle announcements.

Pull request to be sent in the next few days.

Thanks.

Resolving patch:
diff --git a/source/_UIAHandler.py b/source/_UIAHandler.py
--- a/source/_UIAHandler.py
+++ b/source/_UIAHandler.py
@@ -1,6 +1,6 @@
 #_UIAHandler.py
 #A part of NonVisual Desktop Access (NVDA)
-#Copyright (C) 2011-2018 NV Access Limited, Joseph Lee, Babbage B.V.
+#Copyright (C) 2011-2019 NV Access Limited, Joseph Lee, Babbage B.V.
 #This file is covered by the GNU General Public License.
 #See the file COPYING for more details.
 
@@ -134,6 +134,7 @@
 	UIA_ValueValuePropertyId:"valueChange",
 	UIA_RangeValueValuePropertyId:"valueChange",
 	UIA_ControllerForPropertyId:"UIA_controllerFor",
+	UIA_ItemStatusPropertyId:"UIA_itemStatus",
 }
 
 UIAEventIdsToNVDAEventNames={
diff --git a/source/appModules/shellexperiencehost.py b/source/appModules/shellexperiencehost.py
--- a/source/appModules/shellexperiencehost.py
+++ b/source/appModules/shellexperiencehost.py
@@ -1,13 +1,47 @@
 #A part of NonVisual Desktop Access (NVDA)
-#Copyright (C) 2015 NV Access Limited
+#Copyright (C) 2015-2019 NV Access Limited, Joseph Lee
 #This file is covered by the GNU General Public License.
 #See the file COPYING for more details.
 
+"""App module for Shell Experience Host, part of Windows 10.
+Shell Experience Host is home to a number of things, including Action Center and other shell features.
+"""
+
 import appModuleHandler
 from NVDAObjects.IAccessible import IAccessible, ContentGenericClient
+from NVDAObjects.UIA import UIA
+import controlTypes
+import ui
+
+class ActionCenterToggleButton(UIA):
+
+	# Somehow, item status property repeats when Action Center is opened more than once.
+	_itemStatusMessageCache = None
+
+	def _get_value(self):
+		return self.UIAElement.currentItemStatus
+
+	def event_UIA_itemStatus(self):
+		self.event_valueChange()
+
+	def event_valueChange(self):
+		# Do not repeat item status multiple times.
+		currentItemStatus = self.value
+		if currentItemStatus and currentItemStatus != self._itemStatusMessageCache:
+			ui.message(currentItemStatus)
+		self._itemStatusMessageCache = currentItemStatus
+
 
 class AppModule(appModuleHandler.AppModule):
 
+	def event_NVDAObject_init(self, obj):
+		if isinstance(obj, UIA):
+			# #8845: Brightness button in Action Center is a button, not a toggle button.
+			# Brightness control is now a slider in build 18277.
+			if obj.UIAElement.cachedAutomationID == "Microsoft.QuickAction.Brightness":
+				obj.role = controlTypes.ROLE_BUTTON
+				obj.states.discard(controlTypes.STATE_CHECKABLE)
+
 	def chooseNVDAObjectOverlayClasses(self,obj,clsList):
 		if isinstance(obj, IAccessible):
 			try:
@@ -16,3 +50,5 @@ def chooseNVDAObjectOverlayClasses(self,obj,clsList):
 				clsList.remove(ContentGenericClient)
 			except ValueError:
 				pass
+		elif isinstance(obj, UIA) and obj.role == controlTypes.ROLE_TOGGLEBUTTON and obj.UIAElement.cachedClassName == "ToggleButton":
+			clsList.insert(0, ActionCenterToggleButton)


Test patch: