Skip to content

Instantly share code, notes, and snippets.

View jcsteh's full-sized avatar

James Teh jcsteh

View GitHub Profile
@jcsteh
jcsteh / readme.md
Last active October 18, 2026 07:02
ARIA: Name? Label? Contents?

Name? Label? Contents?

Background

The ARIA and Accessible Name and Description Computation specifications define when and how web browsers should expose the accessibility "name" of an element to accessibility APIs, and where that information should come from in various situations. Authors often intuit that if they override the name (e.g. via aria-label), they override what screen readers in particular will report to users. Unfortunately, this is not the case, resulting in confusion, frustration and brokenness for users, authors, browser implementers and spec writers. There is no clear guidance on how name and content should interact, and the behaviour is inconsistent across AT.

Name and content are not the same!

The fundamental issue is that name and content are two different things.

@jcsteh
jcsteh / notificationSounds.py
Created September 13, 2026 11:20
NVDA global plugin to play specific sounds for Windows notifications which match specific text.
"""NVDA global plugin to play specific sounds for Windows notifications which
match specific text.
This plugin reads a file called notificationSounds.conf in your NVDA
configuration directory; e.g. %appdata%\nvda\notificationSounds.conf.
Each line should contain a regular expression, followed by a tab, followed by
the full path to a .wav file to play if a notification contains the expression.
For example:
doorbell pressed C:\sounds\doorbell.wav
"""
@jcsteh
jcsteh / nvdaControllerSpeechInterruptFastResponse.py
Created December 21, 2025 12:58
A very hacky NVDA global plugin to make nvdaController_speakText interrupt speech and queue it for immediate execution for the fastest possible responsiveness.
from ctypes import WINFUNCTYPE, c_long, c_wchar_p
from globalPluginHandler import GlobalPlugin
import NVDAHelper
import queueHandler
import speech
@WINFUNCTYPE(c_long, c_wchar_p)
def nvdaController_speakText(text):
speech.cancelSpeech()
queueHandler.queueFunction(queueHandler.eventQueue, speech.speakText, text, _immediate=True)
@jcsteh
jcsteh / phoneexperiencehost.py
Created October 21, 2024 02:59
NVDA app module for Microsoft Phone Link
# Copyright 2024 James Teh
# License: GNU General Public License version 2.0
"""App module for Phone Link.
This does the following:
1. Works around the Phone Link crash when tabbing into the messages list.
2. Makes alt+1 focus the Conversations list when the Conversations view is
already active. Without this, alt+1 does nothing in this case. This makes it
much easier to switch conversations.
3. Adds alt+d to focus the message input text box. This is useful if you've
@jcsteh
jcsteh / logger.py
Created August 29, 2023 06:42
An NVDA synth driver which logs time stamped speech output.
import os
import time
from collections import OrderedDict
import wx
import synthDriverHandler
from synthDriverHandler import synthIndexReached, synthDoneSpeaking
from speech.commands import IndexCommand
import globalVars
class SynthDriver(synthDriverHandler.SynthDriver):
@jcsteh
jcsteh / spinCpu.cpp
Created February 10, 2022 05:38
Spin all threads of a CPU.
/*
* spinCpu: Spin all threads of a CPU.
* This is useful for testing how things behave when the CPU is fully utilised.
* Copyright 2022 James Teh
* License: Mozilla Public License version 2.0
*/
#include <iostream>
#include <thread>
#include <vector>
@jcsteh
jcsteh / playPauseMultiFunction.ahk
Last active October 24, 2023 13:03
AutoHotkey script to make the play/pause button on headsets skip to next/previous track when double/triple pressed
; Play/Pause Multi Function
; Copyright 2022 James Teh
; License: GNU General Public License
#SingleInstance Force
; Ensure we don't intercept our own sending of play/pause.
#If (!sendingPlayPause)
Media_Play_Pause::
{
@jcsteh
jcsteh / SiriInteractiveReader.js
Created August 24, 2021 11:11
iOS Scriptable script to allow line by line reading of text with Siri and/or Apple Watch
// Variables used by Scriptable.
// These must be at the very top of the file. Do not edit.
// icon-color: deep-purple; icon-glyph: magic;
// Author: James Teh <jamie@jantrid.net>
// Copyright 2021 James Teh
// License: GNU General Public License version 2.0
const fm = FileManager.iCloud();
const docs = fm.documentsDirectory();
@jcsteh
jcsteh / ZoomGlobalKeys.ahk
Last active March 23, 2020 22:51
AutoHotkey script to control Zoom with global keyboard shortcuts
; ZoomGlobalKeys.ahk:
; AutoHotkey script to control Zoom with global keyboard shortcuts
; Author: James Teh <jamie@jantrid.net>
; Copyright 2017-2019 James Teh
; License: GNU General Public License version 2.0
#!m::
{
ControlSend, , !a, ahk_class ZPContentViewWndClass
Return
@jcsteh
jcsteh / SpotifyGlobalKeys.ahk
Last active April 9, 2025 13:51
AutoHotkey script to control Spotify with global keyboard shortcuts
; SpotifyGlobalKeys.ahk:
; AutoHotkey script to control Spotify with global keyboard shortcuts
; Author: James Teh <jamie@jantrid.net>
; Copyright 2017-2018 James Teh
; License: GNU General Public License version 2.0
DetectHiddenWindows, On
; Get the HWND of the Spotify main window.
getSpotifyHwnd() {