TurnOver - the OG alternative screenreader for mac is now opensource

By Oliver Kennett, 20 October, 2026

Forum
macOS and Mac Apps

Hello everyone!

So, after much soul searching, thinking about what I want for the future and whether I could make this a sustainable concern, I've decided TurnOver is now free and open source, under the GPL. Anyone can use it, read the code, check it, change it and build it themselves.

I started out with this on a whim. Safari and Word were unusable for me, so I set about fixing them for myself, and discovering it was possible to fix not only those two apps but improve the logic and layout of others, I realised there might be something here. It was exciting. It was wild! I was doing something many of us had hoped for for so long. Of course, it's a big undertaking. As pointed out by several commenters, maintaining the code base, keeping up with apps as they change and generally keeping the whole thing ticking along takes a significant amount of time, as it has. So, to make it sustainable, I thought, rightly or wrongly, I'd keep it closed and charge a small subscription to cover my time.

From speaking to others, I came to understand that most people won't pay for a screen reader when a free one is built in, so I wouldn't get enough to make it worthwhile. Also, I admit, other ventures on here did make me realise that even a half-baked free screen reader that's open source might be preferable to a fully functional, notarised one with a plan for sustained development. *mutter mutter mutter*

As it stands, I'm happy. I've got a screen reader that rocks. All I really wanted. I just thought others might want it more.

What this all means:

- TurnOver is free for everyone. No tester keys, no waiting list, no price.
- The code is on GitHub: https://github.com/TurnOver-For-Mac/turnover. Yes, it was written with an AI, and tested by hand, with a hundred-odd unit tests. It's all there to judge, and I'm hoping there's something useful in it for people to build out from.
- It's a spare-time project. I'll keep working on it a few hours a week, on what I can. No support or roadmap promises. I'm going to do what I should have done before: get on with finishing my book. It's amazing what procrastination can look like! This is still a project I care deeply about. There are areas of the Mac I still want to reach and fix. I'm a tinkerer and a maker, coding and 3D printing are my jam. It's just not going to be viable as a larger commitment.
- Bug reports and ideas go through GitHub's issue form now, not email.
- Fixes, plugins, guides and testing are all very welcome. Plugins are the easiest way in, no Swift needed.
- The released builds are still signed and notarised by me, and update themselves. Nobody else can ship an update to your copy.

If it's useful to you and you'd like to help with running costs, there's Ko-fi, no account needed: https://ko-fi.com/oliverkennett. It's in TurnOver's menu too, under Support TurnOver. GitHub Sponsors is coming.

Download and guides, as before: https://doll-eye.github.io/turnover-updates/

A massive thank you to the testers, who sent hundreds of careful reports and made TurnOver what it is. You are heroes, rocket men and women willing to climb onboard a wild ride. You rock.

Stay frosty

O

Options

Comments

By Choom on Wednesday, October 21, 2026 - 23:02

An option to avoid GitHub's web interface is to install its command-line tool called gh. I do so using MacPorts, but HomeBrew should have it too.

To install gh using MacPorts, type:

sudo port install gh

And then enter your password when prompted.

Next, generate an ssh key for authentication to GitHub if you don't have one already by typing:

ssh-keygen -t ed25519

And answer all the questions, making sure to remember both the name of the private key file and the passphrase.

Next, append the following to your ~/.ssh/config to make ssh authenticate using the new key:

Host *
    UseKeychain yes
    AddKeysToAgent yes
    IdentityFile ~/.ssh/id_ed25519

Replacing id_ed25519 with the file-name containing your private key.

Next, add the authentication key to the ssh-agent for automatic remote authentication as follows:

ssh-add --apple-use-keychain ~/.ssh/id_ed25519

Replacing id_ed25519 with the file-name with your private key, and entering the passphrase.

Next, authenticate gh to GitHub by typing:

gh auth login

And following the on-screen instructions.

The following is optional, and will make the mate utility from TextMate the default editor and pager, which are used by both git and gh, so install TextMate if you haven't already and install the mate utility from its preferences.

First, create a bin directory in your home directory by typing:

mkdir ~/bin

Next, create a file in ~/bin/lesser with the following content that removes all terminal control sequences from the output and pipes it to TextMate:

#!/bin/sh
perl -pe 's/\e\[[\x30-\x3f]*[\x20-\x2f]*[\x40-\x7e]//g' | col -xb | mate

Next, give executable permissions to the file that you've just created as follows:

chmod 755 ~/bin/lesser

Next, edit your ~/.zprofile and append the following two lines:

export EDITOR='/usr/local/bin/mate -w'
export PAGER=$HOME/bin/lesser

All done. Now you can interact with GitHub almost entirely from the command-line and get the output sent to TextMate.

The following command clones Turnover to a subdirectory in the current directory:

gh repo clone TurnOver-For-Mac/turnover

The following command lists all the issues in Turnover using TextMate as the pager, if you configured it as instructed earlier:

gh issue list

Or you can avoid TextMate and print directly to the console as follows:

gh issue list | cat

For example the following are the issues currently open for Turnover at the time of this comment:

jps@alpha turnover % gh issue list | cat
25  OPEN    Braille: NVDA's braille features (panning moves the cursor, focus context, review cursor, read by paragraph, settings)  idea    2026-10-21T16:14:56Z
14  OPEN    Issue with browsing for files   problem 2026-10-21T13:05:58Z
12  OPEN    Speech rate jumps when CoExist is turned on or off (Eloquence)  problem 2026-10-21T11:07:41Z
11  OPEN    Braille: the TurnOver menu is not shown on the display; it keeps showing the app behind problem 2026-10-21T11:07:39Z
10  OPEN    Braille: with CoExist off the display shows only VoiceOver off and nothing else (Focus 5)   problem2026-10-21T11:07:38Z
4   OPEN    Browse mode: timing of keys in the virtual buffer   problem 2026-10-20T15:25:06Z
3   OPEN    Reader state is hard to isolate in tests    idea    2026-10-20T15:25:05Z
2   OPEN    App-specific exceptions living in shared code   idea    2026-10-20T15:25:03Z
1   OPEN    Keys pile up while a slow page's buffer is built, then run all at once  problem 2026-10-20T15:23:28Z

Issue #1, for example, contains the following:

jps@alpha turnover % gh issue view 1 | cat
title:  Keys pile up while a slow page's buffer is built, then run all at once
state:  OPEN
author: Doll-Eye (Doll Eye)
labels: problem
comments:   0
assignees:  
projects:   
milestone:  
issue-type: 
parent: 
sub-issues: 
sub-issues-completed:   
blocked-by: 
blocking:   
number: 1
--
Seen in Safari on 20 Oct 2026 when Safari stopped answering accessibility questions: each rebuild of the page's reading buffer took about two seconds on the main thread, every key pressed meanwhile queued ("kb:tab answered after 2012 ms: its script runs now", five in a row), and they all ran together when the build finished.

Two parts:
1. Build the buffer without holding the main thread for seconds (a time budget, finishing in the background, or keeping the old buffer while a slow app is rested by AXHealth).
2. Repeats of the same navigation key that waited more than about a second should not all run: run the last one, say that the page was slow.

The log lines above come from InputManager and ScriptHandler.askMain; the buffer is built in WebBuffer/BrowseMode.

All gh commands have dedicated manual pages, so for example if you type:

man gh-issue-view

That will display the manual page for the view subcommand of the issue command, and the same works for git commands too.

Since the man command uses the configured pager, you will also get the manual pages displayed in TextMate, if you configured it earlier.

By Choom on Wednesday, October 21, 2026 - 23:11

In reply to by Mohammad Suliman

Buffering has two problems:

  1. You are no longer sourcing information from a single source of truth;
  2. It exchanges almost imperceptible delays in responses by a huge delay at the start for complex applications as all the content is queried for buffering.

Plus it's solving a non-existent problem which is the assumption that just querying the application as the single source of truth when needed is slow. VoiceOver does that and in my experience it's not slow unless applications themselves are slow to respond to queries. Therefore to me buffering only adds unnecessary complexity to the code.

By Oliver Kennett on Thursday, October 22, 2026 - 05:03

Regarding the buffer, it is the NVDA virtual buffer idea and only applies to webpages to keep the behaviour of the screenreader predictable.

I'll be the first to say, I'm not experienced at this. All I've done is vibe coded a screenreader to my specifications that by and large achieves what I want, to be better than voiceover. It's not complete by any means, it's more of a beginning, a proof of concept, an idea and, yes, a challenge.

I do agree that skils are needed for this beyond pushing money into a slot and asking for wishes which is why I want people to join in. It is also far further than anyone else has got in creating something that is a viable alternative to VoiceOver. It works. I'd like people onboard who push back, who critique, who have views counter to my own. I'm learning as I go but, I don't think that is enough. Please hop on board if you have value to add.

By Tyler on Thursday, October 22, 2026 - 06:12

Member of the AppleVis Editorial Team

Personally, one of the things that has prevented me from fully embracing TurnOver, even in apps where it's currently supported, is the fact that it runs alongside, rather than in place of, VoiceOver. Even if the two screen readers function similarly, it's still two separate screen readers running side by side, increasing the potential for bugs, conflicts, and user friction.

NVDA, on the other hand, is a full-featured screen reader, meaning that I can acclimate to one set of commands and concepts when using Windows, and apply them across the operating system. I don't need to think about what screen reader will work in one app versus another, unless I, for example, purposefully quit NVDA and turn on Narrator.

I think if TurnOver could eventually function as a full-featured screen reader, I could see myself using it full time. I know development is only beginning, but I think the ultimate, long-term goal of making it as full-featured as possible across apps could really move the Mac accessibility landscape forward in ways not thought possible a short time ago.

By ziixies on Thursday, October 22, 2026 - 06:31

completely aggree, this is the type of things i'd want apple to use.

By Soren on Thursday, October 22, 2026 - 06:45

Is it me, or is this ? buggy as hell? It gets stuck all the time for me, loses focus in apps, fails to interact, fails to announce windows in alt tab and so on.

By Ashley on Thursday, October 22, 2026 - 08:35

In reply to by Choom

The intent is to provide a virtural cursor, similar to NVDA or JAWS (or pretty much any windows screenreader) whereby the page is read like a document. They all achieve it by reading the content into a buffer and them browse / focus mode moves you in and out of that buffer for reading. However, if it's possible to reliably facilitate the same navigation without building a buffer first, then it would be something worth exploring as it would mean faster load times and better support for dynamic content..

By Oliver Kennett on Thursday, October 22, 2026 - 13:58

If you have bugs, please report them.

Turnover can be used exclusively, I've just set it up so there is a backup if an app isn't working as well as you like. Go into settings down to expirimental and turn off coexist. You can then turn off voiceover. You do need to make sure the option is set to turnover everywhere which is toggle by doing the turnover layer command control comma and then a.

the reasoning was to let people switch easily back and forth rather than simply giving up on turnover.

I feel I'm repeating myself. It's a beta. It has bugs. don't expect perfection. We'll get there, hopefully, but we're doing this in our free time. tell us what is going wrong, file a bug report and we can iron the issues out.

thanks

O

By Aleksandr on Sunday, October 25, 2026 - 14:06

In reply to by Soren

Have you made sure you’ve granted all the necessary permissions? I had a similar experience when I first launched TurnOver, but apparently not all the permission dialogs had appeared. It was really sluggish, copying my VoiceOver settings didn’t work, and VoiceOver itself went silent. I disabled TurnOver and somehow managed to get VoiceOver running again, only to discover that several permission dialogs were still waiting for me. Once I granted all the permissions, TurnOver actually started working smoothly.

There’s an app I need to use tomorrow where VoiceOver says “no open windows” before announcing the actual element every time I move the cursor. I was thinking about uninstalling the app and using the browser version instead, but now I’m going to give TurnOver a try.

By emperor limitless on Sunday, October 25, 2026 - 15:26

In reply to by Soren

yes, it's just you. It's much smoother than voiceover here, by a mile, not to say that some bugs don't exist, they do, especially with electron based apps and browse/focus mode switching and textfields being sometimes inconsistant in those electron apps *only*, but was planning to report those eventually and I doubt oliver doesn't already know about them, so probably an eventual thing, but still, the experience is miles better than voiceover. To the point I switched from windows completely to mac and can finally use the mac daily without losing my mind.

By Dominic on Sunday, October 25, 2026 - 15:35

i shoould get used to how it works. i haven't used it in a long r time, only use it when voiceover desides that it want's to, uh, kinda die? but for what i do it works pretty well even though i don't use it all that much

By Choom on Sunday, October 25, 2026 - 15:50

In reply to by Aleksandr

Have you made sure you’ve granted all the necessary permissions? I had a similar experience when I first launched TurnOver, but apparently not all the permission dialogs had appeared. It was really sluggish, copying my VoiceOver settings didn’t work, and VoiceOver itself went silent. I disabled TurnOver and somehow managed to get VoiceOver running again, only to discover that several permission dialogs were still waiting for me. Once I granted all the permissions, TurnOver actually started working smoothly.

It should only need accessibility permission. I'm aware that it's asking for input monitoring permission as well, which is already covered by accessibility thus making it redundant, but I had no idea that it was asking for even more permissions. What exactly is it asking for?

By Soren on Sunday, October 25, 2026 - 16:41

So, after continuing to try this for a while, I ran over one massive issue, when in a group, focus at times randomly jumps to top, even in the turnover settings dialogs. Others do not seem to have this issue so I suspect that some config or something on my mac causes it, what could it be?

By Khomus on Sunday, October 25, 2026 - 17:21

Installed, gave both permissions. Turnover starts speaking. Good so far. Arrow keys don't work. VO keys don't work. ctrl-cmd-comma doesn't get into the Turnover settings, I was planning on trying to change keyboard layouts. ctrl-cmd-period does work to turn it off, but then I don't get VO back. Reboot, try again, same thing. Reboot, again necessary to get VO working again, delete from apps folder.

That was short, at least.

By Oliver Kennett on Sunday, October 25, 2026 - 18:09

Hello all,

Build 22 is live. If you already have TurnOver it will offer the update itself; otherwise the download, the guides and the source are now all at https://turnoverformac.com. The old addresses still work and forward there.

What changed

  • CoExist is gone. TurnOver is now a full screen reader from the first launch, as Tyler asked for above. One reader speaks at a time: while TurnOver is on, VoiceOver is off. Command Control Period quits TurnOver and VoiceOver comes straight back; press it again (or the VoiceOver shortcut) and you swap back. If you'd rather each reader had its own switch and neither touched the other, there's one setting for that under Screen reader behaviour. Readers per app, the lists and the switching as you change apps, are folded away and off for new installs.
  • VoiceOver comes back reliably after a quit, a crash or a hang, including when macOS thinks it's on but it isn't running. Khomus, this is the one that bit you, and I'm sorry it did.
  • Pressing a control on a web page tells you what changed: on or off, checked, expanded, selected, even when the page takes a second or two to catch up.
  • The menu is short and in NVDA's shape, and every setting lives in the Settings window, in sections down the side. Command Control M opens the menu in one press.
  • Settings reads its switches properly on Tab, and the Settings window no longer pauses when you flip one.
  • Plenty more: voices per language, Steam switches in Settings, Finder fixes, Backspace speaking at once, braille with a Focus 5 by USB, a privacy fix so typed words never reach the log. The full list is in the changelog on the site.

Permissions, since that came up

TurnOver asks for two things, and more than one dialog may appear:

  • Accessibility, to read what's on screen.
  • Input Monitoring, so TurnOver can take its keys. Choom, you're right that in theory Accessibility covers event taps, but on current macOS a tap that is only Accessibility-trusted doesn't get keys from every app, and TurnOver also needs to see keys while another screen reader has them. Without it you get exactly what Khomus saw: TurnOver speaks, but arrows and the TurnOver key do nothing.

If keys don't respond after you grant Input Monitoring, quit and start TurnOver again (build 22 now notices the grant itself, but a restart is the sure way). You may also see an Automation prompt for one particular app, the first time a feature needs it: Word, Excel and Keynote (TurnOver asks them for the slide, the cell or the dictionary directly, because accessibility doesn't give it), and VoiceOver itself when you copy your VoiceOver settings across. Say no and only that one feature in that one app is lost; everything else carries on.

Bugs

Soren, the focus jumping to the top of a group isn't something I've seen. One thing to check first: Gesture control, under Tools in the TurnOver menu (or Command Control Comma, then G). If it's on, a brush of the trackpad moves TurnOver's focus, and a palm resting near it can look exactly like random jumps. Turn it off and see if the jumping stops. If it carries on, please file it on GitHub with the apps it happens in and attach a report (TurnOver menu, Tools, Send feedback, Send a report with what TurnOver said; it saves a zip and opens the problem form for you). emperor limitless, the Electron ones are known, but reports with a log still help pin them down.

Thanks to everyone who has reported, pulled and tested so far. This build already carries other people's work: Urh brought braille to a Focus 5 over USB, made a held braille message give way to the next command, fixed Tab landing on controls the Settings window had thrown away, and added the switch for the NVDA key layer; Ashley moved Word's spelling policy into its own module, sorted out the menu key assignments, and wrote the house rules and agent guidance that every change now follows.

Stay frosty and let me know how you get on with this one.

O

By Khomus on Sunday, October 25, 2026 - 18:36

1. How do you get to the dock in NVDA layout? I guess I could just hit cmd-space and use spotlight to find all of my apps, but still.

2. In settings, if I pick speech, the only setting I see is about ducking, I think. I want to change the voice. How do I do that?

3. Speaking of settings, somehow or other all of its windows went away and I had to force quit when I quit Turnover and started Voiceover. SO how do you get out of settings properly? I thought escape would do it, but apparently not.

4. Oh also, other things that happen because of VO keys, e.g. getting to the desktop, so far cmd-tabbing to the Finder window works but is there a way to get to specific places like that?

I will say, though it took a little bit, Voiceover did restart automatically after I quit Turnover. So that's nice.

By Tayo on Monday, October 26, 2026 - 03:06

Just turned over TurnOver. My initial impressions? it's promising but, for some reason, to me it feels a bit sluggish. That might be down to my particular habits, though--I use single-letter quick nav and arrow quick nav a lot in VoiceOver, and using it in TurnOver is rather slow--I keep getting "Please wait" announcements in place like the App Store, for example. I'll keep testing, and anything actionable I'll pipe up.

By Maldalain on Monday, October 26, 2026 - 03:19

In reply to by Khomus

1. Press the left Options key, this is to the left of the left CMD, same as left Windows on Microsoft Windows.
2. In Speech settings, there are almost 11 options to modify, so not sure why you are getting one only. You're sure you got the latest version?
3. Simply CMD+Q.

4. yes, and they are modifiable. Press CTRL+CMD+, then N, down arrow to Key>My Own Keys>Give a key to a command, then type desktop, you find what moves you to the desktop. Key combination will appear. To modify, press return, press your desired key combination then return.

Yep, build 22. If I pick speech in settings and then hit tab, which is the only thing that seems to move anywhere, I get the menu about ducking, that's it. So I'm not seeing how to get to any of the options.

I did change the voice, but docs say Turnover-shift-cmd- arrows, it's actually ctrl for me, not cmd.

For me, I could only access the "Voice"popup menu in TurnOver Speech Settings with VO-Right-Arrow; Tab only took me to the "Lower other sounds while TurnOver speaks" switch. I'm not currently sure if this is a bug or expected behavior.

In fairness to him, I also only have the one modifiable speech setting at least using the tab key. but tbf that's the same issue with every setting catigory now. using 2.0, 22.

Updated. The settings are there, but you can’t reach them using TurnOver’s Tab navigation. VoiceOver, however, navigates them just fine. 🙂

Every time I go into the TurnOver menu, VoiceOver gets turned off.
When I turn on VoiceOver, the TurnOver menu disappears.
bruh...

I can never win

By Dominic on Monday, October 26, 2026 - 06:17

Another issue. I tried to import my voiceover settings. It goes into VoiceOver Utility, but then it fails because apparently it can't find a voice? I'm using a voice? No idea why it's not working.
It also seems a bit slower when typing stuff, especially browsing by character and word

It also doesn't show me what I have written in Dictation when I have stopped speech. Not sure if this is a turnover issue or dictation issue.

By Aleksandr on Monday, October 26, 2026 - 06:35

Here are a few things I noticed within the first few minutes of testing:

VoiceOver keeps turning itself back on, even though I explicitly turn it off.

When I invoke the element’s context menu, a menu does open, but it seems to be the desktop context menu rather than the menu for the selected element. It contains options like “New Folder,” “Change Wallpaper,” and “Edit Widgets.”

A second speech voice keeps interrupting TurnOver’s speech. It sounds similar to Eloquence. For example, when I open Safari, this voice reads the webpage content, while TurnOver’s configured voice announces attributes such as links and headings. This happens even though I copied my VoiceOver settings, which are configured to use a single voice.

I also had a look through the source code because I was hoping to help with localization. I couldn’t find any localization files, and it looks like at least some of the user-facing strings are hardcoded in the Swift source. It would be great if localization support could be added.

By Khomus on Monday, October 26, 2026 - 13:25

Here's another issue, left-option does not go to the dock. It does nothing. This is 2.0.22, and I also have the settings issue with tab, i.e. I only get one setting, up/down opens the menu for that setting, e.g. "no", "always". Tab goes right back to the settings list, "general, speech", and so on.

Also, when hitting cmd-space for Spotlight, nothing reads. So you don't actually know that you're in the search field ready to type.

OK, so I was just messing around the settings and when going through the settings, you can't press tab you had to do control option right aro through them

By Urh Ĺ trakl on Monday, October 26, 2026 - 15:11

But it doesn't happen all the time, sometimes if I go to the speech settings I won't be able to tab around as normal, but other times it works completely fine.

By Lorien Darenya on Monday, October 26, 2026 - 15:34

So, typically I open a program, go to the Dock, and pull up the context menu to select "keep in Dock". This seems not to work with Turnover. Neither does the hotkey recommended in Voiceover *when* in Voiceover.

Frustrating.

Any tips?

Lorien

By Oliver Kennett on Monday, October 26, 2026 - 16:30

Settings and Tab (Khomus, Tyler, Dominic, Aleksandr, Urh)

Managed to reproduce it. macOS has a setting, Keyboard navigation (System Settings, Keyboard), off on every new Mac, and with it off Tab reaches text fields and lists only. VoiceOver users never notice because the VO keys don't need it; TurnOver's Tab did. Urh, that's why it came and went for you: it depends on that switch, not on luck. From 22.2 TurnOver Settings does its own Tab, sidebar first then every control in the section, whatever that switch says. Until then VO-Right works, as Tyler found, or turn Keyboard navigation on.

Spotlight (Khomus, Dominic)

On macOS 26 and 27 Spotlight's panel is drawn by a different process and TurnOver didn't follow it, so Command Space said nothing. Urh's fix for that is in 22.2.

Left Option for the Dock (Khomus)

It works on my MacBook, so something on yours differs. From 22.2, if the Dock doesn't take the focus TurnOver says so and names the macOS shortcut it relies on (Move focus to the Dock, in Keyboard Shortcuts). If you hear that, you'll know where to look; if you hear nothing at all, send a report and I'll see what the key did.

VoiceOver turning itself back on, and a second voice reading (Aleksandr)

Found it in my own log. When the Mac locks, TurnOver turns VoiceOver on for the login window; macOS delivers the "VoiceOver is on" notice only after the wake, and TurnOver took that for you turning VoiceOver on by hand, so it stayed off after the unlock, with VoiceOver (Eloquence, in your case) reading. Fixed in 22.2. Please tell me if it still happens after the update.

The context menu opening the desktop's (Aleksandr)

The old fallback was a key that opened nothing or the wrong thing. From 22.2 the shortcut menu opens the item's own menu, or right-clicks the item itself.

Siri voices (Dominic)

To be clear: TurnOver cannot use the Siri voices at all. Apple gives them to Siri and VoiceOver alone; no other program on the Mac is allowed to speak with them, and that is Apple's rule, not something I can code around. So when you copy your VoiceOver settings and VoiceOver is using a Siri voice, everything else copies and TurnOver keeps its own voice. It sounded like a failure because that note came first; it's reworded, and it now says where to pick a voice. The voices that do work are the system ones in Settings, Speech: Alex, the Enhanced and Premium voices you can download in System Settings, Accessibility, Spoken Content, and Eloquence.

The TurnOver menu turning VoiceOver off, and VoiceOver closing the menu (Dominic)

That's the swap doing its job: one reader at a time. Command Control M starts TurnOver if it's off, and VoiceOver coming on sends TurnOver, menu and all, out of the way. If you'd rather they left each other alone, Settings, Screen reader behaviour, turn the swap off; then each has its own switch.

Adding TurnOver to the Dock (Lorien)

TurnOver is a menu-bar app, so the Dock has no "Keep in Dock" for it. You shouldn't need it: Command Control Period starts and quits it from anywhere, and Settings, General, Open at login starts it with the Mac. To launch it otherwise, Spotlight and type TurnOver.

Sluggish quick nav and "please wait" in the App Store (Tayo)

"Please wait" means the app itself stopped answering accessibility questions for a few seconds; the App Store is the slowest app I know for that. Single-letter navigation is only as fast as the app's answers. A report from a slow moment (TurnOver menu, Tools, Send feedback) would show me where the time goes.

Typing slower, Dictation (Dominic)

Send me a report after a slow bit of typing and I'll look at the timings; I don't see it here.

Password fields (from a GitHub report)

In a password field macOS keeps every key from TurnOver, so VO-Left and VO-Right can't leave it; Tab and Shift Tab can. TurnOver now says so.

Localisation (Aleksandr)

The strings are in the Swift source, you're right. Proper localisation is a big job I can't start now, but a pull request that begins it is welcome.

Reports

Keep them coming, and attach the report when you can.

A gentle reminder

Everything above was found, fixed and tested in my own time. There is no company behind TurnOver, no grant, no salary. It's free and open. But every bug report that turns into a fix costs an afternoon, and the signing certificate, the notarisation, the domain and the compute cost real money.

If you've found TurnOver to be helpful, and a real alternative to VoiceOver that finally works in a way you want, baring in mind it is work in progress, then please consider putting something towards it. The best way is a monthly amount through GitHub Sponsors: https://github.com/sponsors/TurnOver-For-Mac, or the Sponsor button at the top of the repository. If you'd rather give once, Ko-fi takes a one-off with no account: https://ko-fi.com/oliverkennett. Both are in the TurnOver menu too, under Support TurnOver. The price of a coffee a month from a few dozen of you is what makes the difference between a project I can keep giving time to and one I can't.

And if money isn't the thing you have, contributing time with code are worth just as much. Urh and Ashley have already contributed and been a great help in keeping this going.

Stay frosty.

O

By Dominic on Monday, October 26, 2026 - 16:41

was loky thinkin bout dropping a 50 but coffei sucks. is there another way to donate? i tried looking at the menu but nothing

By Oliver Kennett on Monday, October 26, 2026 - 18:26

From here on, bugs go through GitHub’s issue form (link on turnoverformac.com) and that’s the only place I’ll be looking. I'll not be reading the forum for reports any more; it’s a few hours a week and critique of the project is getting rather boring. I rather spend my efforts on actually fixing issues than arguing, explaining or just feeling a bit sad.

I'd still love it for other contributers to get involved. I made it open source for just this reason.

thanks for your understanding and, for any who do post bugs and issues on here, please advise them how to submit reports.

By Dominic on Monday, October 26, 2026 - 18:37

yea but people who do wonna report issues are now in a bit of a tuf spot, because github sucks and most people here wouldn't wonna use the termonal so idk. and github is a bit more ment for devs and not the person who only would use this a few times.
but i guess, you can't win eiver way.

By Ashley on Monday, October 26, 2026 - 20:55

I know that github is not the easiest tool to use, especially for non devs. Even as a dev I am still getting my head around parts of it. However, submitting issues on Github really is very easy to do via the web interface, with no terminal use necessary. Here is a quick guide:

  1. Create a free account by clicking here if you don't have one already.
  2. Then, go to the Turnover Repository. The first heading on that page is "repository navigation", beneath which is a list of links. Choose issues from that list.
  3. Beneath the heading "issues" on that page, which is the first level 1 heading, you'll find the New Issue link.
    • You'll also find the search here. It's helpful if you can try a few search terms first, to see if your issue has already been reported.
    • The search form is pre-filled with the words "is:issue state:open". This line is simply a filter that searches for active, open issues. To perform a search, simply put your search term before this line, separated by a single space.
    • For example, searching for the phrase "Braille is:issue state:open" will find all of the open issues with "braille" in their title.
    • The search results appear as level 3 headings, and you can activate any of them to see the issue details.
  4. When you click 'New Issue', a dialogue will appear asking you to choose a category. The choices here are self explanatory. Use "something isn't right" for a bug report, use "An idea or request" for a feature suggestion. Submit 1 issue for each singular problem or request.
  5. Activating any of those options will present a dialogue with a form where you can provide further details. The questions here, again, are self explanatory. When you have filled in the requested information, press the "create" button at the bottom of the form, and your issue will be created. You will be taken to your issue's page on github, where you can view comments from others, add additional comments, reply to comments, or close the issue.

To make this even easier, you can use these direct links to go straight to the form to open an issue, assuming you are already signed into github. However, please do make use of the search feature, to help ensure we are not overrun with duplicate bug reports.

Please familiarise yourself with the Contributor Guide and the Code of conduct before submitting your issue. Those pages look busy, but in both cases you'll find the content beneath the final level 1 heading on each page, and the content is contained within an article landmark for easier navigation.

I will occasionally check in on this thread for those who don't want to use Github issues. However, I please ask that you do the following:

  1. add a subject to your comment relevant to your report.
  2. Provide details that will help reproduce your bug or track it down. Use this as a template:
    • What is the behaviour or issue you are experiencing?
    • What do you expect to happen instead?
    • What steps can we take to reproduce your bug? Include details of any apps you're using.
    • Is there any other relevant information? The specific synth / voice used, make / model of your braille display for example.

Simply criticising the project as "buggy as hell" or failing to provide useful information won't get anything fixed, and is quite demotivating and discouraging for those who are putting our own time and resources into building something here. Remember, this is a few weeks old, and was until recently the work of one person putting in a lot of hours. "Rome wasn't built in a day", as they say.

By Dominic on Monday, October 26, 2026 - 22:23

Before anyone takes this the wrong way, I'm not trying to attack Oliver or discourage development. I've already contributed to the project through PR #13, and Oliver has accepted one of the fixes from that audit. I genuinely want this project to succeed.

However, after looking through the code, I think some of Choom's concerns are worth taking seriously.

1. Concurrency and manual locking

In Sources/TurnOverSpeech/SpeechPlayer.swift, we have:

public final class SpeechPlayer: @unchecked Sendable {
    nonisolated(unsafe) public static var current: SpeechPlayer?
    private let settingsLock = NSLock()

Now, none of these things are inherently wrong.

However, @unchecked Sendable places responsibility for thread safety on the developer rather than having the compiler verify it. nonisolated(unsafe) also bypasses certain Swift concurrency protections.

There are similar patterns in other parts of the codebase.

This doesn't automatically mean there are race conditions, but it does mean additional care and testing are needed, particularly in a screen reader where speech, keyboard input and accessibility events are all interacting.

I think Choom has a reasonable point about using Swift's structured concurrency where practical, rather than relying so heavily on manual synchronisation.

2. Private macOS APIs

In Sources/TurnOverCore/DisclaimedSpawn.swift, there's this:

guard let f = dlsym(
    UnsafeMutableRawPointer(bitPattern: -2),
    "responsibility_spawnattrs_setdisclaim"
) else { return nil }

The implementation also uses unsafeBitCast to convert the returned pointer into a callable function.

From what I can tell, this is intended to prevent helper processes from inheriting TurnOver's accessibility-related permissions.

That's a legitimate security objective.

However, relying on an undocumented macOS symbol comes with compatibility risks. Apple could change or remove that functionality in a future release.

Again, this doesn't necessarily mean the implementation is currently broken, but it deserves attention.

3. Control-channel reliability

This is one of the more concrete problems identified during my earlier audit.

In Sources/TurnOverControl/ControlChannel.swift, the server sends messages like this:

private func send(_ message: [String: Any], to fd: Int32) {
    guard let data = ControlChannel.encode(message) else { return }
    queue.async { [weak self] in
        guard self?.clients[fd] != nil else { return }
        data.withUnsafeBytes { _ = write(fd, $0.baseAddress, data.count) }
    }
}

And broadcasts settings updates like this:

for fd in self.subscribers {
    data.withUnsafeBytes {
        _ = write(fd, $0.baseAddress, data.count)
    }
}

The problem here is that write() isn't guaranteed to send all the requested bytes in one operation.

It can return a partial write.

In these examples, the return value is ignored entirely.

Elsewhere, the client checks whether the number of bytes written matches the requested length, but doesn't retry if the write is incomplete.

Since the control channel exchanges newline-delimited JSON, incomplete writes could potentially result in malformed or incomplete messages.

This is something I'd like to see fixed with proper write loops, error handling and regression tests.

It's also one of the areas Oliver has asked me to resubmit as a separate pull request.

4. Complexity and long-term maintenance

This is probably my biggest concern.

TurnOver has multiple components dealing with speech, keyboard input, accessibility events, VoiceOver handover and recovery when something stops responding.

Some of this complexity is unavoidable. Developing a screen reader is not an easy task.

However, if those components become too tightly connected, fixing one issue can create problems somewhere else.

One example worth investigating further is how the control channel handles asynchronous responses and disconnected clients. Connections are tracked using file descriptors, which the operating system can eventually reuse.

Without appropriate safeguards, delayed operations could potentially interact with a different connection than originally intended.

I'm not claiming I've reproduced that failure, but it's something that deserves proper testing.

5. There are good things in the code too

I don't want to make this sound like TurnOver has absolutely no architecture.

It does have separate modules for speech, accessibility, braille, control communication and other functionality.

The control channel also includes checks intended to verify connecting processes.

There are existing tests, documented architecture concerns and mechanisms intended to restore VoiceOver if TurnOver becomes unresponsive.

So I wouldn't describe the entire project as hopelessly broken.

Overall

My concern isn't that TurnOver doesn't work. It clearly does work for some people, and in certain applications it can provide a better experience than VoiceOver.

My concern is whether the current implementation will remain maintainable as the project grows.

Choom's prediction that the project will eventually collapse is still a prediction, not an established fact.

But after reviewing the source, I don't think his underlying technical concerns should simply be dismissed.

I also think Oliver deserves credit for accepting outside contributions and being willing to improve the implementation. The build-script issue identified in my audit has already been addressed through a separate commit, according to his response to PR #13.

For anyone interested, my original contribution is here:

https://github.com/TurnOver-For-Mac/turnover/pull/13

And the official repository is here:

https://github.com/TurnOver-For-Mac/turnover

By Darren12 on Tuesday, October 27, 2026 - 08:17

I'm a windows user exclusively, but Oliver should be congratulated hugely for this. Sounds amazing, to be honest. A spirit of collaboration and good humour is needed here. Many of you have been very gracious, but don't burn this down, It is outstanding, just to have begun this adventure. Apple should hang their head in shame. I'd urge everyone to contribute, either financially or by helping from a coding perspective by lessening the load on one person. I'd never consider the Mac as a platform due to the current state of Voiceover, but with this, I may very well give It a second look, if this project continues and develops. Great stuff, Oliver.

Fixing these issues is exactly why contributions are needed. One of the things we need to figure out is who is doing what, so we don't duplicate efforts or spend time working on the same issues. Are you planning to take these on?

if People haven't gotten to it before I have then maybe. At the moment, I'm just working on other projects, so I have a bit less time to contribute. Which is why I'm not much of a github person, because I much prefer doing it here because it's a site I already know.

By Dominic on Tuesday, October 27, 2026 - 09:19

I agree with others here. Whilst I may have my own doubts over whether the project will succeed and actually be successful or not, plus my own little criticisms and other issues, I still think that we should be thankful that someone has actually tried to mess around with this, AI or not.
what Oliver has done here is absolutely commendable, some may say, even tremendous. What will happen after today we don't know. choom outright saying, the project will fail, in my opinion, is just absolutely beyond outlandish. I mean, it could happen, who am I to say whether it will or not. But it's only been three weeks. At least give it like three months or so before deciding whether a project will fail or not.

I am purely looking at this thread, just to read it for my own interests. But something very odd happened with this particular comment. All the instructions were being changed to a different voice voice for me as I was reading this. It started with my default voice, which is Catherine enhanced and every time there was different steps, followed by different links and things to change the interface that you’re using whenever it kept changing to Samantha enhanced. It was very odd. I just wanted to see if they had anything to do with maybe the way the directions are being written out or something but yeah, just thought if anybody else was experiencing that that I would at least let you know it’s kind of a odd thing that happened with this only one particular post on this particular thread.

By UÄźur GĂĽrbĂĽz on Tuesday, October 27, 2026 - 12:25

Hi All,
A while back, I mentioned on AppleVis that we should probably join forces and put all our energy into TurnOver. But after diving deep into the TurnOver repo and looking closely at the codebase, my perspective shifted a bit, and I wanted to share why.

Don't get me wrong—TurnOver has some impressive features already built out (like the Word support). But when you look under the hood, you can see how easily quick AI-driven coding ('vibecoding') takes a toll. A lot of app-specific rules, component definitions, and custom behaviors are tightly coupled right into the core. For an open-source screen reader that ultimately needs to support hundreds of different apps, that's a massive maintenance headache waiting to happen.

That said, I still believe we shouldn't split our energy across separate projects; uniting under one roof is definitely the right move. But for that to actually work, we need to be honest with ourselves: the project desperately needs a serious architectural refactor.

Instead of hardcoding every little workaround straight into the core, we need to shift toward a clean, data-driven, catalog-based model where app-specific logic lives safely outside the engine.

So, my open question to the team is: do you see this bottleneck as well, and are you ready to commit to a major refactor to build this the right way?

By Ashley on Tuesday, October 27, 2026 - 13:09

In reply to by UÄźur GĂĽrbĂĽz

This is Ollie's project and I can't speak for him. From my point i view I fully agree with you, and it is the direction I would take. However, to bring the current code in line is something that would require a dedicated contributor to do, and all to be onboard with. It would almost need development to pause while this was handled. It's certainly not something that I'd think could be handled with the current contribution model, 1 pull request at a time for small changes. Is it something you would undertake?

By Aleksandr on Tuesday, October 27, 2026 - 14:35

In reply to by Ashley

I think an experienced Swift developer could lead the architectural refactoring while using AI coding tools like Codex or Claude to do much of the implementation. With clear architectural guidelines, a well-defined scope, and proper human review, AI could significantly speed up the process. Rather than doing everything manually, an experienced developer could focus on the architecture, critical decisions, and code quality, while AI handles much of the repetitive work. This could make a major refactoring far more achievable with the limited time and resources available.