Jantrid
https://www.jantrid.net/
The musings and ramblings of Jamie Teh.
フィード

Moving a Row in Google Sheets with the Keyboard
Jantrid
Sometimes, it is necessary to move a row up or down in a Google Sheet. For example, I might be maintaining a list of tasks ordered from highest to lowest priority and realise that a task later in the sheet is actually higher priority than earlier tasks. This Google support article says you can do this by selecting the row and then choosing Move row up (or down) from the Edit menu. However, when I selected the cells in the row, these Move row items still didn’t appear in the Edit menu. The solution is to press shift+space twice to select the row, after which the Move sub-menu will appear in the Edit menu, from which you can choose Row up or Row down. Shift+space is the keyboard shortcut to select a row, but the first press only selects the cells in the row. To select the row itself, which you must do in order to move it, you need to press it again. Putting it all together, the entire keyboard sequence to move a row up in Firefox on Windows is shift+space, shift+space, alt+shift+e, m, k.
18日前

Pasting Numbers Without Punctuation or Spaces
Jantrid
Everyone loves paying bills, right? One of the best parts about paying bills is surely that they usually provide all the amounts, billing codes, reference numbers, etc. with punctuation and spaces; e.g. amount $1,234, reference code 123 456-789. But banking and payment portals - sometimes even the payment portal for the organisation issuing the bill! - won’t accept spaces and punctuation! This means you can’t simply copy and paste the numbers, which is really annoying. Wouldn’t it be awesom if there were some easy, automatic way to strip out everything except numbers and the decimal point before pasting? I recently started using Ditto, an absolutely superb clipboard manager for Windows. It turns out you can do this with Ditto using a paste script. I originally thought that paste scripts always ran, which I wouldn’t want in this case, but it turns out that they actually appear as items in the Special Paste menu. To set this up, go to Ditto -> Options -> General -> Advanced ->
23日前

Cache the World: Turbo Charging Firefox Accessibility Performance and Maintainability
Jantrid
The Firefox accessibility engine is responsible for providing assistive technologies like screen readers with the information they need to access web page content. For the past couple of years, the Firefox accessibility team have been working on a major re-architecture of the accessibility engine to significantly improve its speed, reliability and maintainability. We call this project “Cache the World”. In this post, I explain the reasons for such a massive undertaking and describe how the new architecture solves these issues. The need for speed The biggest motivation for this project is to make Firefox faster when used with screen readers and other assistive technologies, particularly on Windows. Let’s start by taking a look at some numbers. The table below provides the approximate time taken to perform various tasks with Firefox and the NVDA screen reader, both before and after this re-architecture. Before (no cache) After (with cache) Load nsCSSFrameConstructor.cpp on Searchfox, whi
2年前

Making the Play/Pause Button on Earpods Skip to Next/Previous Track on Windows
Jantrid
I recently got a new laptop: Dell XPS15 9510. While this is a pretty nice machine overall, its audio drivers are an abomination. Among other things, the Waves MaxxAudio software it ships with eventually leaks all of your system memory if you use audio constantly for hours, which is the case for screen reader users. I eventually got fed up and disabled the Waves crap, but this makes it impossible for me to use the headset mic on my Earpods. To work around that, I bought an Apple USB-C to 3.5-mm Headphone Jack Adapter. As well as supporting the mic on the Earpods, this adapter also supports the volume and play/pause buttons! However, play/pause only plays or pauses. In contrast, on the iPhone, pressing it twice skips to the next track and pressing it thrice skips to the previous track. I discovered that these buttons simply get sent as media key presses. So, I wrote a little AutoHotkey script to intercept the play/pause button and translate double and triple presses into next track and p
3年前

Reading Recipes with Siri or Apple Watch
Jantrid
I’m finally learning to cook some decent food, so I need to be able to read recipes. For a while, I was reading them out of Simplenote on my iPhone. However, I encountered several frustrations with this approach (and this applies to any notes or text app really): When you’re not editing, Simplenote shows the note such that each line is an item for VoiceOver; i.e. you flick right to read the next line. However, if you bump the screen or perform the wrong gesture accidentally, you can easily lose your position. If the screen locks or you have to switch apps, you lose your position completely, since VoiceOver doesn’t restore focus to the last focused item in apps. When editing, you can review the note line by line using the rotor. The advantage here is that the cursor doesn’t get lost when you switch apps or the screen locks. However, lines can be smaller than is ideal due to the screen size, so one recipe instruction might get split across multiple lines. Also, moving the editing cursor
4年前

Tab Keywords in Firefox
Jantrid
Introduction An awesome feature in Firefox that has existed forever is the ability to assign keywords to bookmarks. For example, I could assign the word “bank” to take me directly to the login page for my bank. Then, all I have to do is type “bank” into the address bar and press enter, and I’m there. Another awesome feature in Firefox is the ability to use the address bar to switch to open tabs. For example, if I want to switch to my Twitter tab, I can type “% twitter” into the address bar, then press down arrow and enter, and I’m there. Inspired by these two features, I started to wonder: what if you could have tab keywords to quickly switch to tabs you use a lot? If you only have 8 tabs you use a lot, you can switch to the first 8 tabs with control+1 through control+8. If you have more than that, you can search them with the address bar, but that gets messy if you have multiple pages with similar titles or a page title doesn’t contain keywords that are quick to search. For example, i
5年前

Open Source Access to Math for NVDA: The Beginning
Jantrid
At CSUN this year, I attended the open source math accessibility sprint co-hosted by the Shuttleworth Foundation and Benetech, where major players in the field gathered to discuss and hack on various aspects of open source math accessibility. My team, which also included Kathi Fletcher, Volker Sorge and Derek Riemer, tackled reading of mainstream math with open source tools.Last year, NVDA introduced support for reading and interactive navigation of math content in web browsers and in Microsoft Word and PowerPoint. To facilitate this, NVDA uses MathPlayer 4 from Design Science. While MathPlayer is a great, free solution that is already helping many users, it is closed source, proprietary software, which severely limits its future potential. Thus, there is a great need for a fully open source alternative.Some time ago, Volker Sorge implemented support for math in ChromeVox and later forked this into a separate project called Speech Rule Engine (SRE). There were two major pieces to our t
9年前

Woe-ARIA: aria-describedby: To Report or Not to Report?
Jantrid
IntroductionIn my last post, I waxed lyrical about the surprising complexity of the seemingly simple aria-label/ledby. Thanks to those who took the time to read it and provide their valuable thoughts. In particular, Steve Faulkner commented that he’d started working on “doc/test files suggesting what screen readers should announce from accname/description info“. Talk about responsive! Thanks Steve! His inclusion of description opened up another can of worms for me, so I thought I’d continue the trend and let the worms spill out right here. Thankfully, this particular can is somewhat smaller than the first one!What are you on about this time?Steve’s new document suggests that for an a tag with an href, screen readers should:Announce accname + accdescription (if present and different from acc name), ignore element content.I don’t agree with the “ignore element content” bit in all cases; see the “Why not just use the accessible name?” section of my label post for why. However, the bit of
9年前

Woe-ARIA: The Surprisingly but Ridiculously Complicated World of aria-label/ledby
Jantrid
IntroductionWAI-ARIA is one of the best things ever to happen to web accessibility. It paved the way to free us from a world where JavaScript and any widget that didn’t have an HTML tag equated to inaccessibility. Aside from it being deployed by authors, I’ve even managed to majorly improve the accessibility of various websites using Greasemonkey scripts. I love ARIA.But sometimes, I hate ARIA. Yes, you heard me. I said it. Sometimes, it drives me truly insane.Let’s take aria-label and aria-labelledby. They’re awesome. Authors can just use them to make screen readers speak the right thing. Simple, right?Not at all. I wish it were that simple, but it is so, so much more complicated than that. I’ve had a ridiculous number of discussions/arguments about aria-label/aria-labelledby over the years. Frankly, when I hear about aria-label/ledby, it just makes me cringe and groan and, depending on the day, consider quitting my job. (Okay, perhaps that last part is a bit melodramatic.)The most fr
9年前

Deploying a Flask Web App as a Dynamic uWSGI App with Multiple Threads
Jantrid
I recently had to deploy a Flask web app for Hush Little Baby Early Childhood Music Classes (shameless plug) with uWSGI. (Sidenote: Flask + SQLAlchemy + WTForms = awesome.) I ran into an extremely exasperating issue which I thought I'd document here in case anyone else runs into it.Despite the fact that uWSGI recommends that you run a separate instance for each app, I prefer the dynamic app approach. While i certainly understand why separate instances are recommended, I think per-app instances waste resources, especially when they have a lot of common dependencies, including Python itself. I also set uWSGI to use multiple threads. Unfortunately, with Flask, this is a recipe for disaster.As soon as Flask is imported by a dynamic app in this configuration, uWSGI instantly hangs and stops responding altogether. The only option is to kill -9. After hours of late night testing, debugging, muttering, cursing, finally going to bed and then more of the same the next day, I finally thought to t
11年前