feat: support voiceover + "speak items under the cursor" (closes #1070)

This commit is contained in:
Louis Pontoise
2021-08-30 23:19:43 +09:00
parent c18aa4d91c
commit c7911f3f5c
5 changed files with 26 additions and 2 deletions
+9
View File
@@ -72,6 +72,15 @@ class Windows {
let focusedView = ThumbnailsView.recycledViews[focusedWindowIndex]
focusedView.highlight(true)
App.app.thumbnailsPanel.thumbnailsView.scrollView.contentView.scrollToVisible(focusedView.frame)
voiceOverFocusedWindow()
}
static func voiceOverFocusedWindow() {
guard App.app.appIsBeingUsed && App.app.thumbnailsPanel.isKeyWindow else { return }
let window = ThumbnailsView.recycledViews[focusedWindowIndex]
if window.window_ != nil && window.window != nil {
App.app.thumbnailsPanel.makeFirstResponder(window)
}
}
static func focusedWindow() -> Window? {
+1
View File
@@ -217,6 +217,7 @@ class App: AppCenterApplication, NSApplicationDelegate {
thumbnailsPanel.thumbnailsView.updateItemsAndLayout(currentScreen)
guard appIsBeingUsed else { return }
thumbnailsPanel.setContentSize(thumbnailsPanel.thumbnailsView.frame.size)
Windows.voiceOverFocusedWindow() // at this point ThumbnailViews are assigned to the window, and ready
thumbnailsPanel.display()
guard appIsBeingUsed else { return }
currentScreen.repositionPanel(thumbnailsPanel, .appleCentered)
+12
View File
@@ -22,6 +22,12 @@ class ThumbnailView: NSStackView {
var isShowingWindowControls = false
var windowlessIcon = FontIcon(.newWindow)
// for VoiceOver cursor
override var canBecomeKeyView: Bool { true }
override var acceptsFirstResponder: Bool { true }
override func isAccessibilityElement() -> Bool { true }
convenience init() {
self.init(frame: .zero)
setupView()
@@ -44,6 +50,7 @@ class ThumbnailView: NSStackView {
addWindowControls()
addDockLabelIcon()
thumbnail.addSubview(windowlessIcon, positioned: .above, relativeTo: nil)
setAccessibilityChildren([])
}
private func addDockLabelIcon() {
@@ -109,6 +116,7 @@ class ThumbnailView: NSStackView {
let thumbnailSize = NSSize(width: thumbnailWidth.rounded(), height: thumbnailHeight.rounded())
thumbnail.image?.size = thumbnailSize
thumbnail.frame.size = thumbnailSize
thumbnail.setAccessibilityLabel(element.title)
}
assignIfDifferent(&spacing, Preferences.hideThumbnails ? 0 : Preferences.intraCellPadding)
assignIfDifferent(&hStackView.spacing, Preferences.fontHeight == 0 ? 0 : Preferences.intraCellPadding)
@@ -117,12 +125,14 @@ class ThumbnailView: NSStackView {
let appIconSize = NSSize(width: Preferences.iconSize, height: Preferences.iconSize)
appIcon.image?.size = appIconSize
appIcon.frame.size = appIconSize
appIcon.setAccessibilityTitle(element.application.runningApplication.localizedName)
}
let labelChanged = label.string != element.title
if labelChanged {
label.string = element.title
// workaround: setting string on NSTextView changes the font (most likely a Cocoa bug)
label.font = Preferences.font
setAccessibilityTitle(element.title)
}
assignIfDifferent(&hiddenIcon.isHidden, !element.isHidden || Preferences.hideStatusIcons)
assignIfDifferent(&fullscreenIcon.isHidden, !element.isFullscreen || Preferences.hideStatusIcons)
@@ -169,8 +179,10 @@ class ThumbnailView: NSStackView {
let view = dockLabelIcon.subviews[1] as! ThumbnailFontIconView
if dockLabel > 30 {
view.setFilledStar()
view.setAccessibilityLabel("Red badge with star")
} else {
view.setNumber(dockLabel, true)
view.setAccessibilityLabel("Red badge with number \(dockLabel)")
}
dockLabelIcon.setFrameOrigin(NSPoint(x: appIcon.frame.maxX - dockLabelIcon.fittingSize.width - 1, y: appIcon.frame.maxY - dockLabelIcon.fittingSize.height + 4))
}
+2 -2
View File
@@ -14,8 +14,6 @@ class ThumbnailsPanel: NSPanel, NSWindowDelegate {
titleVisibility = .hidden
backgroundColor = .clear
contentView!.addSubview(thumbnailsView)
preservesContentDuringLiveResize = false
disableSnapshotRestoration()
// triggering AltTab before or during Space transition animation brings the window on the Space post-transition
collectionBehavior = .canJoinAllSpaces
// 2nd highest level possible; this allows the app to go on top of context menus
@@ -23,6 +21,8 @@ class ThumbnailsPanel: NSPanel, NSWindowDelegate {
level = .popUpMenu
// helps filter out this window from the thumbnails
setAccessibilitySubrole(.unknown)
// for VoiceOver
setAccessibilityLabel(App.name)
}
func windowDidResignKey(_ notification: Notification) {
@@ -14,6 +14,8 @@ class WindowControlView: NSImageView {
originalImage = image
hoveredImage = image.tinted(.init(white: 0, alpha: 0.25))
hovered(false)
setAccessibilityLabel(imageName)
setAccessibilityRole(.button)
}
func hovered(_ isHovered: Bool) {