# Ctrl blog
> A personal blog mostly on everyday tech.
Public Ghost content for AI and LLM tooling. This file includes a bounded export of public pages first, then recent public posts.
Append `.md` to any post or page URL to get the content in Markdown (for example, `/example-post.md`).
## Pages
### About Ctrl blog
URL: https://www.ctrl.blog/about/
Last updated: 2026-08-24T17:54:11.000Z
*Ctrl blog* (“Control blog”) is the developer-focused blog of [Daniel Aleksandersen](https://www.ctrl.blog/author/daniel/) based in Oslo, Norway. This is my outlet for essays, tutorials, reviews, and technical notes and articles on a variety of topics.
This blog has previously been published under the names “Slight Future” and “Aeyoun’s blog”. This is my fourth an longest running attempt at blogging.
### Privacy Policy
URL: https://www.ctrl.blog/privacy-policy/
Last updated: 2026-08-24T17:40:10.000Z
Last updated 2026-08-24.
Ctrl blog (“the site”) is hosted by [Synaps Media](https://www.synapsmedia.com/?ref=ctrl.blog) (*Triofan ZZP;* Netherlands, Europe). Synaps Media uses European service providers for hosting, and web content- and email delivery on behalf of the site. See [Synaps Media’s list of service providers](https://www.synapsmedia.com/dpa-sub-processors/?ref=ctrl.blog).
## Cookies
There’s no cookie banner on the site because there are no cookies by default. Registered members use a session cookie to stay logged in to the site. Membership is required to leave comments and to receive the site’s email newsletter.
## Membership and newsletter
You need to login using your email address to become a Member and receive the email newsletter. Your email address is used to send you the email newsletter and verify your Membership when you login to the site.
## Comments
Membership is required to comment. Comments posted on the site are public. Whatever you write shows up on the page along with the name on your account.
## Audience metrics
The site counts its readership and visitors using cookie-less tracking scripts without using any persistent identifiers. There is no device fingerprinting or other sketchy surveillance shenanigans. Readership is counted through Ghost by Synaps Media and [StatCounter Ltd.](https://www.statcounter.com/?ref=ctrl.blog) (Republic of Ireland, Europe).
### Tags & Topics
URL: https://www.ctrl.blog/tag/
Last updated: 2026-08-29T01:06:01.000Z
Index of all tags on Ctrl blog.
## Posts
### Microsoft has not stopped forcing Edge on Windows 11 users
URL: https://www.ctrl.blog/entry/windows-system-components-default-edge/
Last updated: 2026-08-23T22:25:24.000Z
Microsoft published [a blog post on the Windows Insider Blog](https://blogs.windows.com/windows-insider/2023/08/25/announcing-windows-11-insider-preview-build-23531-dev-channel/?ref=ctrl.blog) in late August with a vague statement saying that “Windows system components“ were to begin respecting the default web browser setting. Windows 10 and 11 regularly bypass this setting and force-open links in Microsoft Edge instead. In my extensive testing, I haven’t found any changes in the new Windows Insider version.
You may have read stories in the tech media celebrating that Windows will finally respect the default browser setting. This reporting seems to have been done completely without verification and based entirely on a misunderstanding. The source of the confusion is this one highlighted but vague entry in the changelog for a recent Windows 11 Insider preview build:
> “In the European Economic Area (EEA), Windows system components use the default browser to open links.”
[Announcing Windows 11 Insider Preview Build 23531 (Dev Channel)](https://blogs.windows.com/windows-insider/2023/08/25/announcing-windows-11-insider-preview-build-23531-dev-channel/?ref=ctrl.blog), Amanda Langowski Brandon LeBlanc
The highlight makes it sound like Microsoft has finally caved to regulatory pressure from the European Union (EU). The software powerhouse has abused the dominant market position of its Windows operating system to promote its Edge web browser and services for too long.
I’ve followed this developing story closely over the years. I even developed the popular open-source [EdgeDeflector program](https://www.ctrl.blog/entry/edgedeflector-default-browser/) that hijacked web links destined for Microsoft Edge and directed them back to your default web browser. Microsoft finally reacted and [blocked EdgeDeflector from working](https://www.ctrl.blog/entry/microsoft-edge-protocol-competition/) once the Mozilla Firefox and Brave browsers began [building the functionality into their web browsers](https://www.ctrl.blog/entry/anti-competitive-browser-edges/).
Excitedly, I installed the new Windows Insider build and began testing the changes to see them in action. At first, I didn’t believe my findings. *Nothing* had changed from the current version of Windows 11.
- The new Windows version still strongly discourages changing the default browser away from Microsoft Edge.
- After system updates, the new version still aggressively prompts you with a captive full-screen experience on start-up to reset your default web browser to Microsoft Edge.
- Web links in primary surfaces still force-open Microsoft Edge — including links in the new Copilot, Start menu, Search on the taskbar and desktop, Windows Spotlight, first-party apps (Outlook, Teams, News, Weather, and more), and Widgets on the taskbar (formerly called News and Weather).
I’ve verified my findings in the Home and Professional editions of Windows and even the EU-specific “N” variants of each edition. I’ve tested in two configurations for Norway (EEA member) and Germany (EEA and EU member). For both tests, I installed devices with region and locale settings matching the desired country with IP addresses and geolocation sensor data to match.
I’ve checked, double-, and triple-checked my findings. *Nothing has changed.* Web links still force-open in Microsoft Edge instead of your default web browser.
Microsoft first announced the changes for Windows Insider build 23531 (Developer channel). I waited for two more releases and retested with builds 23536 and 23541, both from the Developer channel. I also retested with the Canary channel, which is even further ahead on the development tree than the Developer channel.
Microsoft sometimes gradually rolls out changes in the Windows Insider program to a limited set of users. It does not document publicly which new changes are gradually rolled out. However, there were only two new experiments in build 23531\. None of them are related to default browser settings or Microsoft Edge. The new changes to default browser handling may be a gradual rollout, though.
Microsoft was vague about the change, and neither its customers nor the tech media verified their assumptions before running with the story. Despite not having implemented the changes everyone assumed it had, it has received lots of positive press attention for doing the right thing.
I have not found anyone commenting on whether this change worked for them in the many and extensive discussions on Hacker News, Reddit, and other social media. I’ve also not found any traces of confirmation or checks in the hundreds of news sites that ran the story nor in their comment sections. There has also been no mention of it in the Insider Feedback Hub or any subsequent Windows Insider build announcements or changelogs.
I have *not* reached out to Microsoft for a comment on this story. Frankly, at this point, I rather assume they hate me personally more than they hate their average customers. Microsoft has also refused to make statements to [The Register](https://www.theregister.com/2023/08/30/microsoft%5Fwindows%5F11%5Fbing/?ref=ctrl.blog) and [The Verge](https://www.theverge.com/2023/9/5/23859537/microsoft-windows-11-default-browser-links-eu-eea-changes?ref=ctrl.blog) for their stories on the vague changes.
Disclaimer: I am an employee of *Vivaldi Technologies*, a competitor to Microsoft Edge. This website is my personal blog, and the views and findings expressed here do not represent my employer. I’m also the developer of EdgeDeflector, the circumvention program described in the article.
#### Sources
- [Announcing Windows 11 Insider Preview Build 23531 (Dev Channel)](https://blogs.windows.com/windows-insider/2023/08/25/announcing-windows-11-insider-preview-build-23531-dev-channel/?ref=ctrl.blog), 2023-08-25, Amanda Langowski and Brandon LeBlanc, Windows Insider Blog, Microsoft
### The trouble with decommissioning a used FIDO security key
URL: https://www.ctrl.blog/entry/security-key-decommission/
Last updated: 2026-08-23T22:21:47.000Z
Five years ago, I wrote [about adopting security keys](https://www.ctrl.blog/entry/firefox-u2f-google/) — small second-factor authentication token devices — to secure some of my most precious online accounts. In that article, I foresaw a future problem and detailed how I planned to mitigate it. The future is now, and I did not heed my own advice. 🤦♂️
My advice to others and myself from five years ago:
> “You should maintain a record of which security keys you register on which websites. If you lose or want to decommission a key, you’ll need this record to know where you need to log in and replace the key.”
In the intervening years, I’ve worn out the security key I always keep with me on my key chain. Over the last five years, the gold plating on the contact pins has worn off, and the copper alloy underneath has corroded. The key is still functional, but it requires some hefty jiggling after insertion before it works. It’s time to replace it.
The failing security key was a budget *ePass* model from Feitian. My other Feitian security key, the *MultiPass* with Bluetooth, [was recalled](https://www.ctrl.blog/entry/feitian-multipass-recall/) due to security problems. I bought a key from the — at the time — relatively unknown Feitian instead of the more well-known Yubico. Yubico prices their YubiKey products with a hefty market-leading premium, so they could really need some more competition.
In my experience, Yubico’s keys don’t corrode as easily, though. Therefore, I bought a [YubiKey 5C NFC](https://www.yubico.com/product/yubikey-5c-nfc/?ref=ctrl.blog) to replace the worn-out Feitian key. This new security key is my first USB Type-C key. All my devices have Type-C connectors now, and it’s time to say goodbye to Type-A.
The problem I have now, which I foresaw five years ago, is that I can never throw away my old key. I’ve logged in and replaced it everywhere I remember adding it, but I’m sure there are plenty more that I’ve forgotten.
Many services have neither let me add multiple keys, nor allowed me to remove my key once added. Essentially, the hardware I now want to decommission is the only way to log in to these services.
These services haven’t done a particularly good job of implementing two-factor authentication. Nothing prevents websites from letting users register multiple security keys to their accounts. For end users, it’s best practice to always register at least two different keys with each service. Then, you’ll have a backup if you lose your primary key.
I intended this article to serve as a reminder: security keys don’t last forever! Plan for when you need to decommission them, especially when using the same key for multiple services across the web. Keep a list of where you register your keys!
I hope I’ve learned my lesson now; maybe you have too. I’m keeping track of where I’ve registered my new security key. At least, this time, I’ve created and put some entries in a list inside my password manager!
### The deafening problem with the FreeStyle Libre 3 app for Android
URL: https://www.ctrl.blog/entry/freestyle-libre3-volume-level/
Last updated: 2026-08-23T22:30:28.000Z
I’ve finally begun using the Abbott FreeStyle Libre 3 continuous glucose monitoring (CGM) system a year after I [first wrote about it](https://www.ctrl.blog/entry/freestyle-libre3-cgm/). The newer sensor has been a significant upgrade except for a few issues. One of those issues could be damaging to your hearing.
The Libre 3 sensor must be paired with the companion app on an Android or iOS smartphone. You can read your current glucose levels from within the companion app. The app also issues alarms when glucose levels go critically low (hypoglycemia) or high (hyperglycemia). These early warnings are one of the key advantages of using a CGM system. They can help prolong long-term health outcomes and life expectancy for people with diabetes.
The app also increases the media output volume level to 75 % to ensure the alerts will be loud and audible. It changes the volume without regard for other currently-playing media or the output device.
The app will increase your media playback volume when you’re using headphones. It even ignores the headphone volume limiter. At this level, the alarm is painfully loud in my headphones. I try to tear off my headphones as quickly as possible when this happens. I’m surprised I haven’t yet thrown the headphones to the ground as I try to get away from the sudden earsplitting sound.
I usually listen at about 20 %, and that’s plenty loud enough. At 75 %, it’s loud enough for the phone to begin complaining about the loud listening volume. My volume is typically set to 10–15 % when I’ve paired the phone to my home media entertainment center. At 75 %, the media center gets terrifyingly loud.
The alarms can be embarrassing in social situations, and I can’t shut them off fast enough. It’s so distracting and loud that I forget to act on the alerts! I focus more on apologizing in every direction for the sudden loud ruckus.
This feature comes from a place of good intentions. But as the old saying goes: the road to hell is paved with good intentions.
No app — even for a medical alert — should significantly adjust the audio output volume. Especially not when the user is wearing headphones! For this app in particular, it should start with two soft beeps and vibrations. If the patient doesn’t react within \~20 seconds, the app could gradually increase the volume over the next minute or two.
This gradually-escalating audio design would give a much more pleasant experience. Some users, especially those already hard of hearing, might prefer to keep the current behavior. However, most patients would choose a more gentle approach with an escalating alarm.
The app requests the special Do Not Disturb (DND) management permission. It lets apps issue audible alerts even when DND is enabled or the device is silenced. The medical alerts from the app can indeed be critical, so it makes sense for the app to need these capabilities. Unfortunately, the app is poorly designed and misuses the permission.
The app will prevent the device from canceling DND mode after it has been set by a schedule (e.g., a bedtime routine). You must manually disable DND instead of relying on the scheduling to do it for you. Depending on how you use your phone, this can be detrimental to your work and personal life.
### Workarounds
You should enable your device’s media volume limiter if it’s supported. The option isn’t available on all Android devices and only limits the headphone and Bluetooth volume levels.
To enable it, search your phone settings for “volume limiter.” I can’t set my Samsung Galaxy phone’s volume limit below 60 %. It’s still much louder than my typical listening volume level, but at least the alerts aren’t painful at this level.
Other options are available, if your Android device doesn’t support setting media volume limits. The [Volume Lock Pro](https://play.google.com/store/apps/details?id=volumelock.vlocker.pro&ref=ctrl.blog) (4 Euro) app lets you set limits for each audio channel on your device. You can use it to limit the media- and Bluetooth audio channel volume levels.
Unfortunately, the Volume Lock Pro app has some issues of its own. Suppose you’ve configured a volume range in the app (e.g., 5–55 %). In that case, it sometimes randomly increases the volume to the maximum while you’re playing audio. It can also be slow to respond to volume level changes by other apps. It’s better than nothing if your phone doesn’t have the volume limiter option.
You can also work around the DND issues. However, doing so risks disabling the glucose level alerts from the app! These instructions will be intentionally vague to make you stop and think.
**Only attempt the following workaround** if you’re confident that you can carefully manage your phone settings. You must test to ensure these settings work as expected on your device. You should also retest after applying software updates to your phone and the FreeStyle Libre 3 app.
As discussed in an earlier article, you can [exclude specific apps from being silenced by the DND and sleep modes](https://www.ctrl.blog/entry/android-bedtime-mode-priority-alerts/). Begin by adding the FreeStyle Libre 3 app to the DND exclusion list in your device settings.
You can then revoke the app’s DND permission from the app-specific or system permission screens. Look for special permissions if it’s not listed along with the common system permissions on your device.
Once you’ve revoked the permissions, you must **never silence your phone** except by enabling DND mode! **Never lower the volume to silent!** The app will no longer be able to raise the volume level to ensure alerts are delivered.
The app will constantly display a warning message saying, “Alarms Unavailable.” It’ll also periodically send alert notifications that tell you the same thing. You can disable the periodic notifications from the app’s permission settings. Go to notifications: notification categories, and disable the “Errors” notification category.
Do make sure to contact Abbott and let them know about these issues! They’ve ignored my contact attempts, but there’s always strength in numbers!
### Phone Link relays your personal data through Microsoft servers
URL: https://www.ctrl.blog/entry/microsoft-phone-link-privacy/
Last updated: 2026-08-23T22:14:29.000Z
The Microsoft Phone Link (formerly known as “Your Phone”) app for Windows, Android, and iOS lets you access parts of your smartphone from within Windows. However, Microsoft has not built the service with your privacy in mind. Instead, the software behemoth relays your personal data through its servers, despite the app only working while your devices are connected to the same local network.
The [Microsoft Privacy Statement](https://web.archive.org/web/20230406235344/https://privacy.microsoft.com/en-us/privacystatement#mainyourphonemodule) (February 2023) doesn’t expressly state that Microsoft relays your personal data through its servers. The app‘s requirement for both devices to be on the same local network leads customers to believe that their data is transferred directly between their devices. That’s obviously how this should work, right?
However, in my testing, neither Windows nor Android made direct device connections when using most app features. Crucially, your personal data, such as text messages, clipboard contents, recent photos, and notifications, are not transferred directly over the local network. Notifications may contain sensitive information from your apps, such as the subject and contents of private messages and emails, security codes from authentication apps and texts, caller identities, etc.
I contacted the Microsoft Privacy Team and requested it to clarify some of the vaguer parts of the Microsoft Privacy Statement regarding the Phone Link feature.
> Once the Windows PC and phone are paired, a user’s content such as messages, photos, contacts, and notifications are relayed between the user’s devices (PC and Phone) through a Microsoft cloud service. This content is processed to transfer data between the requested devices and is not stored permanently on Microsoft servers. Incoming and outgoing phone calls are handled over Bluetooth. While using screen mirroring and virtualizing Android apps on Windows through the Phone Link app your shared clipboard and file transfers via drag/drop are sent directly peer-to-peer between the phone and PC. Notification content is sent to Microsoft cloud service simply to relay information between paired devices (PC and Phone) and this data is only processed to fulfill the user’s request and is not stored persistently after the request has completed.
>
> When you use the Phone Link app to mirror your phone’s screen on your Windows device, Microsoft may collect diagnostic data based on user diagnostic data collection control in Windows settings app. If Optional diagnostic data collection is turned on data collected may reflect when a phone screen mirroring session was initiated, whether there was engagement, and when the session was closed. When hosting an Android app from your phone onto your Windows device, the Android app will behave like any app running on a Windows device and Microsoft may collect app usage and performance data helping us troubleshoot issues and improve Microsoft product and services.
>
> Microsoft Privacy Team, (via email correspondence)
Privacy-conscious consumers will realize they have no guarantees that Microsoft doesn’t scan, retain, or do anything else with the data that needlessly passes through its servers. The most charitable interpretation of the same-network requirement is that Microsoft aspires to transfer data locally, but it hasn’t yet made it work.
The same-network requirement might be a privacy measure designed to prevent an abusive partner from spying on your usage of your phone while you’re away from your computer. Microsoft apparently did not consider it a problem that it can spy on all your data as it passes through its servers. It’s a feature; not a bug.
If you care about privacy, you might want to consider using alternatives to the Microsoft Phone Link app. The leading free and open-source contender is [KDE Connect](https://kdeconnect.kde.org/?ref=ctrl.blog). It transfers your data encrypted and directly between your devices over the local network. It even lets you connect multiple computers, not just your computer and a smartphone. However, KDE Connect doesn’t support screen mirroring, one of Phone Link’s key selling points. Other free and open-source apps for screen mirroring are available, but they’re more difficult to use than Phone Link.
### Norway’s BankID undermines anti-phishing best practices
URL: https://www.ctrl.blog/entry/bankid-iframe-phishing/
Last updated: 2026-08-23T22:02:06.000Z
Imagine a privatized nationwide authentication system used to access government services, confirm contracts and online payments, and everything else. Now, imagine that the system was designed to be extra friendly to imitation and credential theft (“phishing”). Here’s everything wrong with Norway’s BankID authentication system.
Norway’s banks jointly own and operate BankID. Citizens use BankID for everything from logging in to government services like taxes and health care, to digitally-sign private contracts, applying for loans and credit cards, and more on the private market.
The authentication scheme has multiple layers and uses a secondary authentication factor, either using a one-time code generated by a key fob or a tap in the BankID app on a trusted device. To log in with your BankID, you need to enter your national identity number — similar to a U.S. social security number — or your phone number, and your BankID password. The latter is often the same as your bank password, although your bank probably requires BankID anyway.
The problem with this solution is *when* and *where* you’re expected to enter your legally-binding credential details. A merchant or service provider embeds BankID directly onto its webpages through an inline frame (“iframe”). Your web browser will only display the domain and encryption certificate details of the top-level webpage, e.g., the merchant’s domain.
There’s no way of telling whether you’re giving your authentication credentials to BankID through a legitimate iframe or handing it off to masquerading criminals. A top-level webpage can also intercept keystrokes and clicks on any embedded iframes. Iframes simply weren’t designed to be used in a security-critical context!
Web browsers have largely focused their anti-phishing efforts on ensuring that their address fields can’t be faked. You can trust that the name you see in the address field is the website you’re visiting. You can thereby trust that you’re communicating with the right company or service.
The industry at large has focused on teaching its customers to check that they’re on the expected website before entering their credentials for that site. In an ill-advised effort to make the transaction seamless, BankID has inadvertently disregarded all the established best-practices. BankID’s customers are thought to trust anything that looks and acts like BankID, regardless of where on the web they encounter it.
The E.U. Payment Services Directive (PSD2) requires that all online payment transactions are carried out with Strong Customer Authentication (SCA). SCA is better known as “multi-factor authentication“ in the broader world outside E.U. regulatory texts. Norwegian debit- and credit card issuers have outsourced this task to BankID. So, whenever you’re making a purchase anywhere on the web, you’re presented with the BankID authentication iframe on the website of the merchant or service provider.
Upon receiving their BankID, consumers must sign a contract where they promise not to share their BankID credentials with third parties. Yet, the service’s design and implementation details make it impossible for people to verify who they’re handing those details over to.
I contacted BankID BankAxept (the company behind BankID) for comment on the issues discussed in this article. I initially didn’t hear anything, but I received a reply after Erlend Oftedal brought up the same problem [on Twitter](https://twitter.com/webtonull/status/1620321216535093249?ref=ctrl.blog).
> \[It would be\] advantageous if all communication with the user happens with `bankid.no` visible in the user’s address field. \[We’re transitioning to this solution\] and most sites with BankID currently use it. \[…\] We still need to work on transitioning all sites to this solution, but the work is underway.
>
> Hege Steinsland, Press Contact, BankID BankAxept, (translated from Norwegian)
I’m happy to hear BankID is working to improve its system. I’ve only seen this alternative new solution used on a handful of websites, whereas I engage with the less secure iframe-based solution everywhere online.
Regardless of BankID’s future plans, I don’t understand how an authentication-as-a-service provider could ever have designed and put the original iframe-based solution into production. BankID should never have asked its customers to trust and provide their login details anywhere but “`bankid.no`”.
Someone should have pushed the big red button at BankID before this got released into the world. You don’t need to make much effort to make a good-enough replica of the BankID iframe to fool people. I’m well aware of the problems, yet even I am reduced to blindly trusting that anything that looks like BankID on any website is legitimately BankID.
While spell-checking my email to BankID BankAxept, I received an email with a link to a phishing campaign that led to a perfect impersonation of the BankID iframe. It wasn’t even an iframe, just a form on a webpage with a border. Not that anyone could tell the difference anyway. It was “good” to get a timely confirmation that others have recognized and are actively exploiting the system’s weaknesses. [Report phishing SMS/emails!](https://www.ctrl.blog/entry/report-phishing/) Don’t just ignore them!
BankID could make its authentication system more challenging to imitate *today* without requiring every third-party payment processor and intermediary website to roll out updates. For example, the iframe could be changed to only contain a “Log in with BankID” button. The button should open a separate window under the trusted `bankid.no` website where the user would enter their authentication credentials.
Upon completion, the new window could communicate the authentication result to the iframe on the merchant website, close the new window, and return the user to the originating website. Throughout the process, customers could rely on their browsers’ built-in domain verification systems to ensure they didn’t share their credentials with a third party.
The above suggestion should be (relatively) easy to implement and deploy in the existing ecosystem. I’m sure there are good reasons why they’re not already doing it. However, BankID needs to get on top of this problem before its customers fall victim to BankID impersonation and phishing. BankID has already undermined and damaged the whole industry’s push to get people to verify the domain before entering their passwords!
BankID’s near-monopoly on authentication services in Norway will fall if its customers lose trust in its systems. *Get it together, guys!*
Please remember to [report instead of ignore phishing campaigns](https://www.ctrl.blog/entry/report-phishing/) that land in your inbox! You might recognize a phishing campaign, but others can miss the signs you spotted.
Disclosure: I work for the web browser vendor Vivaldi Technologies. A part of my work involves ensuring the reliability of the browser’s security indicators.
### I’ve joined Vivaldi Technologies
URL: https://www.ctrl.blog/entry/vivaldi-technologies/
Last updated: 2026-08-23T22:24:08.000Z
On November 1st, I joined familiar faces from [my days at Opera Software](https://www.ctrl.blog/entry/goodbye-opera-software/) and new colleges at [Vivaldi Technologies](https://vivaldi.com/?ref=ctrl.blog). I joined as a Quality Assurance Tester working on the Vivaldi web browser product for mobile and desktop.
I didn’t expect to ever work for a social media company. Two short weeks after I joined Vivaldi, it jumped on the decentralized social networking craze and launched a new Mastodon instance called [Vivaldi Social](https://social.vivaldi.net/?ref=ctrl.blog).
Vivaldi is a web browser, news feed reader, reading-later list, email and calendar client, note-taking app, machine-translation service, and more; all in a single super app. You may recognize these features as interests I’ve regularly covered on this blog.
I’m into [web browsers](https://www.ctrl.blog/tag/web-browsers/), [news feed readers](https://www.ctrl.blog/tag/syndication-feeds/), [note-taking apps](https://www.ctrl.blog/tag/note-taking/), [browser reading modes](https://www.ctrl.blog/entry/browser-reading-mode-parsers/) and read-later apps, [email clients](https://www.ctrl.blog/tag/email/), [calendar apps](https://www.ctrl.blog/tag/caldav/), and other productivity apps. It turns out a local company just down the road from where I live is taking on all of these in a single app.
Vivaldi can be your minimalist web browser with as few buttons, bells, and whistles as possible. It can also be your everything super-app that replaces your existing web browser, note-taking, email client, calendar and contacts, news feed reader, reading list, and any number of other tasks. (At least on desktop.)
Vivaldi for desktop has some window manager-esque features such as tab tiling, but the company isn’t yet trying to build a full-blown operating system. You can find Vivaldi preinstalled in some Android Auto-powered cars, but its primary distribution channel is users seeking it out and installing the app.
I’m struggling a bit to say what’s unique about Vivaldi as a web browser, though. It really is just another run-of-the-mill Chromium-powered browser, despite the overwhelming number of unique productivity features added on top.
Vivaldi’s most useful and unique built-in browser-related feature is probably web panels. Web Panels open as a narrow column next to the regular web view. They let you quickly access pages you want to keep an eye on throughout the day (such as social media and news feeds, some statistics or stocks, or maybe a podcast or audio player). It’s like having “the small internet“ that’s on your phone up on your big desktop screen next to your main browsing activity.
So, what does my new job mean for Ctrl blog? I’ll have less time for the blog, and there will be fewer updates. I expect to keep writing, though. I’ll likely have more to say about web browsers going forward.
### Sync issues finally drove me away from the Joplin note-taking app
URL: https://www.ctrl.blog/entry/joplin-notes-sync/
Last updated: 2026-08-28T16:40:31.000Z
My note-taking app of choice for the last three years has been [Joplin](https://joplinapp.org/?ref=ctrl.blog), an open-source note-taker for Android, Linux, MacOS, and Windows. As I discussed in [my app review](https://www.ctrl.blog/entry/review-joplin-notes/), the desktop app is good, but the Android app has some issues. In the last year, updates to the app have brought along more issues. I can no longer rely on it, and the time has come for me to migrate away from the Joplin app.
Joplin used to get cross-platform synchronization and conflict handling right. It was fast, reliable, and I would never lose a note to synchronization issues. For the last year, however, it’s been a different story.
The issues began with the release of Joplin version 2.6.3 for Android, released late in 2021. It updated to a newer version of the Android software development kit (SDK). The SDK imposed new restrictions on the application programming interface (API) used to access the file system. Joplin released the update with the new SDK without making the necessary changes to support the new file system API. See Joplin project [issue #5779](https://github.com/laurent22/joplin/issues/5779?ref=ctrl.blog "“Android filesystem sync is broken after 2.6.3 update”").
Until then, I’d synchronized my Joplin notes to a folder on my phone. The [Syncthing](https://syncthing.net/?ref=ctrl.blog) app would then keep the notes folder in sync on all my devices. It worked great with my thousands of notes, and the synchronization delay was only a couple of seconds at most.
Without access to the file system, I had to quickly make other plans for synchronizing my notes. The notes Joplin store remotely are end-to-end encrypted (E2EE), so I can use any of the cloud-based storage solutions it supports.
I initially set up a WebDAV server to handle the syncing but gave up after a few days due to various interoperability problems. I then switched to using my Microsoft OneDrive account. However, the synchronization with OneDrive was infuriatingly slow; it took over three minutes to sync a single new note. I switched again over to Dropbox.com. It brought the time required to sync down to roughly 45 seconds.
OneDrive and Dropbox.com worked fine on desktop, but the synchronization on Android was fraught with problems. Syncing would frequently fail, and I had to restart the synchronization to get it working manually.
After the most recent update to Joplin version 2.8.3, released in June 2022, things took a turn for the worse. Joplin now gets indefinitely stuck when synchronizing to any remote storage service. I can’t abort the synchronization once it starts; instead, I get stuck in an infinite cancellation state.
I can make the problem disappear by removing thousands of notes from my notebook. Joplin struggles with synchronization targets other than the local file system once you exceed approximately 600 notes.
The workaround I found requires me to force-quit the Android app, restart it, and quickly start synchronization from a desktop app. The Android app then detects that some other client is synchronizing and stops. Once in this state, I have to wait for the desktop client to complete the process and manually start the synchronization from the Android app again.
What frustrates me the most is that I really appreciate the user experience and workflow in Joplin’s desktop application. I don’t want to switch! I wish I could continue using the app and have it work on all my devices!
However, the Android app has never been as good as its desktop counterpart. It has serious performance issues when editing long notes and is slow to open. The app has overall been more functional than the competition, however. I don’t consider apps that sync to a cloud service without E2EE as a competitor to Joplin. Those apps are just voluntarily installed spyware apps.
I hoped the project would quickly fix the Android file system API issue. However, it has been over a year, and it’s still not fixed. The project has received code contributions to fix the issue, but has yet to release a new version with those fixes. At the time of writing, Joplin version 2.8.3 (released in June 2022) is still the most recent version for Android.
In an annoying coincidence, Joplin released its new [Joplin Cloud-storage subscription service](https://joplinapp.org/plans/?ref=ctrl.blog) a couple of months before the native file system syncing broke. I support this move, as it’s likely to bring in funding to help maintain the open-source project and keep it going. Other cloud-storage vendors are also still available in the app. However, losing my favorite cool self-hosted peer-to-peer (P2P) note-taking application still feels terrible.
Anyhow, I haven’t found a solution to the cloud-syncing issue, and local file system syncing support doesn’t seem to be coming back anytime soon. Losing quick and reliable note synchronization has significantly hampered my productivity over the last year. You can even see it in the reduction of new articles on the blog!
So, earlier today — I exported all my notes from Joplin and deleted the app from all my devices. Bye, bye, Joplin! Thanks for all the notes! I’m currently reviewing a few different options for a possible replacement. For the time being, I’ll be using individual plain-text files in a directory hierarchy that I sync with Syncthing.
Disclaimer: I recently took a position with one of Joplin’s competitors. (I’ll share more details on that soon.) I decided to stop using Joplin three weeks before I began any talks with my new employer. The two events are unrelated and didn’t influence each other.
### Don’t record your social life on an append-only social network
URL: https://www.ctrl.blog/entry/append-only-social/
Last updated: 2026-08-23T22:01:48.000Z
[Secure Scuttlebutt](https://scuttlebutt.nz/?ref=ctrl.blog) (SSB) is an alternative, self-governed, distributed social network without gatekeepers. You only see updates and mentions from people you follow, so moderation isn’t as much of an issue as on Twitter. However, the technology that powers the platform is ill-suited for sharing things with our ever-changing social circles.
Elon Musk’s acquisition of Twitter last week [kick-started a customer exodus](https://www.technologyreview.com/2022/11/03/1062752/twitter-may-have-lost-more-than-a-million-users-since-elon-musk-took-over/?ref=ctrl.blog) from the social network. These customers are either fed up with micro-blogging or looking for Twitter alternatives. SSB hasn’t gotten as much attention as [Mastodon](https://joinmastodon.org/?ref=ctrl.blog) (the “Fediverse”). However, SSB is worth considering as a serverless, self-governing, and self-hosted Twitter replacement.
The technology that powers SSB is entirely different from Twitter and Mastodon. You don’t need to register an account anywhere to get started. Your identity isn’t a username and doesn’t depend on a domain name or service provider. Instead, your username is a meaningless cryptographic hash that consists of random-looking numbers and letters. Your friends only need to know your hash to follow you, and you can keep it as public or private as you want. You must arrange a side channel such as QR codes or email to exchange hashes. There’s no single global feed in the network, and neither is there a global user directory.
All you need to get started is an SSB-compatible client app; you don’t even need an internet connection (except when pushing and pulling updates). Every update you publish, whether public or private, is stored in a local append-only database (AOD). The database exists primarily on your local device.
The network works by having its users synchronize with each other’s account databases. The databases get distributed through “pub” servers. Some SSB client apps can also exchange updates using other means, such as directly between devices using distributed peer-to-peer (P2P) connectivity. Users and pubs can pass along updates on behalf of mutual connections, so everyone doesn’t need to be online simultaneously for the network to function.
All of this sounds great, and you can completely discard any corporate overlords, censors, and other parties with misaligned incentives. It’s just you and your friends or audience talking directly to each other’s devices. Everything is encrypted and you can make what you share as private or public as you want.
The AOD functions like a blockchain where every update is cryptographically chained one after the other. This structure makes it easy to synchronize the database across devices.
You must break the blockchain and fall out of sync with everyone who follows you to delete or modify any past updates on the network. Any modification to existing updates on the blockchain creates a new blockchain where every following update must be re-appended to the new chain. The original will remain just as valid as the new blockchain, which causes conflicts and synchronization stalemates.
Append-only databases are acceptable for financial ledgers, contracts, and things we want to be persistent and immutable. Unfortunately, social graphs aren’t immutable. People fall out with each other over time: relationships end, friendships shift, and we change who we are as we age and move through life.
Maybe you posted something you later regretted and wanted to remove from the network. Or perhaps you don’t want to be reminded of a former acquaintance or relationship, so you want to remove messages and images with that person. Maybe your device storage is full from all the photos and videos your aunt shares with you.
Whatever the reason, people need to have some control and power to change — or at least delete — things as they move on in life. On SSB, you must create a new identity and start a new blockchain to escape your past mistakes and regrets.
The experimental P2P-focused Beaker Browser project also [experimented](https://github.com/pfrazee/citizen?ref=ctrl.blog) with building a distributed social network. Beaker uses the [Hypercore Protocol](https://hypercore-protocol.org/?ref=ctrl.blog) which uses an append-only storage system for its P2P network.
The open-source instant messaging client [Jami](https://jami.net/?ref=ctrl.blog) uses P2P and a blockchain to exchange and keep messages in sync between users and your devices. It uses one blockchain per contact or group conversation instead of a single database for everyone. [Jami uses Git](https://jami.net/swarm-introducing-a-new-generation-of-group-conversations/?ref=ctrl.blog "“Swarm: a new generation of group conversations”") — the popular version control utility – for its conversation blockchains. This design at least lets you unfriend someone and leave them behind when the time comes.
*Permanency* may sound like a neat feature and it lets developers take shortcuts when creating reliable distributed networks. When deployed correctly, it can help keep politicians and public figures accountable. However, it’s definitely not what you should look for in your social network.
### First look at Microsoft PC Manager and its conflicting interests
URL: https://www.ctrl.blog/entry/microsoft-pc-manager-conflicting-interests/
Last updated: 2026-08-25T21:09:09.000Z
Microsoft is testing a new app to compete with the many dubious “PC cleaner” software available on the market (like CCleaner and CleanMyMac). However, Microsoft’s new app looks out for the company’s interests before its customers’.
The PC (and Mac) cleaner software market is full of scams. Many cleaner apps over-promise and inflate the number of “problems” they detect. The detected problems are often parts of your operating system and software behaving as intended. Most of the “problems” they pretend to “correct” either have no impact whatsoever or negatively impact the stability of your computer and software. The goal is to over-sell and scare people into signing up for ongoing “cleaning” services.
Microsoft’s new PC Manager software does far less than its competitors. It can perform some spring cleaning among cache files. However, the app only provides a unified interface into functionality already available in the Windows operating system.
For example, it can help locate large files that take up a lot of storage space on your device. It does this by opening a File Explorer window and executing a search for large files.
Competitors typically try to clean out unused settings from the Windows System Registry. The registry stores app settings and information covering everything from installed printers to your network settings, wallpaper, and your favorite font. Just about all first-party and third-party apps rely on the system registry.
The registry can accumulate cruft over the years as you install and uninstall new software. Updates to existing software can also change what and how they store data in the registry. It does indeed accumulate cruft over time. However, there’s no way to programmatically and reliably determine what is safe to delete from the registry. For example, items in the registry don’t record the time and date they were last accessed. Technically speaking, a program can monitor the registry as you use your computer and record what is in use and what is not. Such behavioral profiling could reduce the risk of deleting something that would break your system. However, this would come at a significant performance cost, and I still wouldn’t advise using it.
A safe and thorough cleaning would require a forensic investigation of your operating system, all installed apps, and how you use them. That’s not what you get from a trialware app targeted at regular people.
There’s just too much happening in the registry; it’s constantly changing. No one, not even Microsoft, can safely “clean” it following a 20-second automatic analysis. Microsoft knows this, which is presumably why it **did not** include registry cleaning functionality in its PC Manager app. You can safely recommend this app to a family member without incurring undue tech-support duties down the line. At least in its current manifestation.
The PC Manager app can also clean the cache of Microsoft’s Edge web browser. It instructs Edge to clean itself rather than interfere with the normal operations of the browser. The norm in the industry is to force-quit your web browser, delete its cache and cookie files, and then restart the browser to let it sort itself out.
Many other cleaner software vendors also claim that every cookie stored in your web browser is either spyware, malware, or otherwise unwanted. This misclassification includes your login cookies, the cookie that stores your dark-theme preference, and many other website preferences. I can only assume that they must sell more software licenses when they can claim to clean a higher number of spyware infections from your computer.
The new Microsoft software also provides a method to change the default web browser and “protect” the setting from being changed. The default browser setting in any operating system is often a target for malware. Although, modern versions of Windows mostly [ignore the default browser setting](https://www.ctrl.blog/entry/edgedeflector-default-browser/) anyway. Surprisingly, this user interface is more straightforward and less user-hostile than what the company offers in the Windows Settings app. However, it only supports Microsoft Edge, Google Chrome, and Firefox. It can’t help you if you use Vivaldi, Brave, or any number of other alternative web browsers. Microsoft [seemingly no longer fears antitrust regulators](https://www.ctrl.blog/entry/microsoft-edge-protocol-competition/) for abusing its market position to promote its Edge browser aggressively.
There are clear indications of the company favoring its products and services within PC Manager. The most blatantly obvious feature where it has put its interests in front of its customers’ is the Startup apps manager.
The new Startup app manager lets you control what apps automatically start with your computer. Many software vendors want their software to start with your computer, whether or not you’re interested in always having it running.
The Startup app manager hides itself from the list of apps you can control. It also hides *all Microsoft apps* from the list! It will not touch Phone Link, Xbox App Services, To-Do, Office, Cortana, Terminal, OneDrive, and other Microsoft apps. The app does not appear to have a list of software to ignore, but it checks if the software publisher is Microsoft.
The new app is doing a disservice to Microsoft’s customers. Microsoft’s apps can slow down your PC, lower battery life, and increase startup times, just like apps from any other vendor can do. Microsoft should not favor its first-party apps and services in this way.
Microsoft PC Manager is currently available in beta from a [Microsoft portal page](https://pcmanager.microsoft.com/?ref=ctrl.blog). The website is in Chinese, but the software also includes an English translation. You probably neither want nor need the software, however.
**Via:** [The Verge](https://www.theverge.com/2022/10/21/23416070/microsoft-pc-manager-app-performance-systems-clean-up?ref=ctrl.blog)
### The frustrating RouterOS–WireGuard VPN peering bug
URL: https://www.ctrl.blog/entry/routeros-wireguard-peer-bug/
Last updated: 2026-08-23T22:21:23.000Z
I’ve wanted to move my home virtual private network (VPN) server from a virtual machine onto my physical [MikroTik router](https://www.ctrl.blog/entry/review-mikrotik-rb750gr3/). I use the VPN to connect back to my home network to reach internal devices and services when I’m out and about. The router runs the RouterOS operating system, which supports WireGuard, a modern VPN protocol. I wasted several afternoons and late evenings but didn’t manage to set it up. It would turn out that a bug caused all my hardship in the MikroTik web configuration interface.
The WireGuard protocol is relatively new and is an overall improvement compared to older VPN protocols. However, it’s more difficult to troubleshoot than those older protocols. The remote end of a WireGuard tunnel stays quiet unless you can successfully authenticate against it. This behavior makes it harder to distinguish an authentication error from a head-on collision with a firewall rule or other networking roadblocks. Older VPN protocols would aid troubleshooting efforts by emitting error messages when a client connected to it with incorrect credentials.
WireGuard uses the stateless User Datagram Protocol (UDP) instead of the stateful Transmission Control Protocol (TCP). This protocol difference reduces the transmission overhead. However, you also lose troubleshooting information on whether connections succeed or not.
The local WireGuard doesn’t have any idea why a connection attempt failed. It doesn’t know if it managed to connect to the remote end of the tunnel, and if it did — it doesn’t know if the authentication attempt failed. The WireGuard software only issued a generic error message: handshake did not complete after 5 seconds, retrying.
So, … what was causing my connection issues? I’d configured the WireGuard software in my router, set up the necessary routing rules, and opened the required ports in the firewall. I’d also double- and triple-checked that I’d set everything up correctly. Everything seemed fine on both ends of the VPN tunnel, but *most* of my road warriors couldn’t establish a VPN tunnel. A *road warrior* refers to any roaming remote client that is expected to connect to a trusted network.
Frustratingly, the third road warrior I had set up worked fine. It connected, authenticated, routed, and performed as expected when connecting to the VPN tunnel, both from inside and outside the local network. No other road warrior could connect in, however.
I failed to identify any differences between the road warriors that worked and those that didn’t. Two were even running the same version of the WireGuard app, on the same version of Android, on identical devices. Yet, only one of them would connect.
I wasted hours trying to troubleshoot the problem. I didn’t have much to go on as the RouterOS front-end to WireGuard doesn’t log anything either. Eventually, I stumbled upon the core issue.
The RouterOS web configuration (webfig) interface didn’t save my peer configuration properly! Whenever I added a new road warrior, I assigned it an IP address and saved its public cryptographic key in webfig. As road warriors, they aren’t expected to have fixed IP addresses, so I left the endpoint address field empty in webfig.
The empty fields incorrectly got saved as an empty value instead of no value! An empty value (`null`) and an empty string (`""`) mean very different things to software, even though humans consider a comparison between nothing and nothing to be equivalent. The underlying configuration read `endpoint-address=""`. This behavior caused WireGuard to refuse connections from peers with a trusted key because their source IP addresses never matched the expected empty address.
The problem did not affect the MikroTik WinBox software, an alternative to the RouterOS webfig. Neither the WinBox nor webfig user interfaces showed that the configuration contained a value for WireGuard peers’ endpoint addresses. They just appeared empty, so nothing seemed to be wrong.
The final workaround for the bug was to remove the empty configuration attributes from each of my WireGuard peers. I had to use the RouterOS command line interface (CLI) — RouterOS’ third and more verbose configuration option — to get the job done correctly.
I reported the issue to MikroTik, which fixed the bug a week later in RouterOS version 7.6 (released on 2022-10-17). I’ve confirmed that the problem is fixed, so no other MikroTik customers should have to waste their time on this problem.
### TP-Link network equipment hijacks some DNS requests
URL: https://www.ctrl.blog/entry/tplink-dns-hijacking/
Last updated: 2026-08-23T22:23:28.000Z
TP-Link network products — including Wi-Fi routers, repeaters, and access points (AP) — use deep packet inspection (DPI) to intercept specific domain name system (DNS) requests. Each product looks for one or two domain names and will hijack the request to issue a local response containing its own internet protocol (IP) address.
TP-Link wants to make it easier for its customers to get into the web administration interfaces of its products. No one wants to remember the IP address needed to access it, right? The IP address can also change over time, depending on your network configuration.
To address the need for easier-to-remember and persistent addresses, TP-Link has added DNS hijacking capabilities to its network products! What could possibly go wrong⸮
TP-Link network products will intercept all DNS requests as they pass through it. It will hijack any IPv4 lookup requests for a product-specific domain name and respond with its own current IP address.
Below is a list of the TP-Link web configuration domains I’ve identified. Some of them have a public-facing website when accessed over the internet instead of through a TP-Link product.
- `tplinkap.net`
- `tplinkeap.net`
- `tplinkwifi.net`
- `tplinkrepeater.net`
- `tplinkmodem.net`
- `tplinkplclogin.net`
Other actors have, of course, bought variations of these domains and linked them to various scams. Make sure you type in the correct domain name, and be wary of imitators.
TP-Link isn’t doing anything malicious with this capability. As the above list of domains suggests, it’s a convenience feature for its customers. It lets people discover the IP address needed to access their TP-Link product via the company’s apps or web administration interfaces.
However, the capability can make it easier for attackers to exploit the device. Attackers doesn’t need to bring their own DNS interception software when they can exploit what’s already available on the device. This is known as a “Living off the Land (LotL) attack, where an intruder abuse existing legitimate software and functions to achieve malicious ends.
TP-Link has “helpfully” made its domain name hijacker configurable. The `tp_domain.ko` kernel extension accepts a parameter to set an IPv4 address and whatever domain name you want to hijack. That’s all an attacker would need to redirect your bank’s website to a server the attacker controls.
This feature from TP-Link demonstrates the importance of using encrypted DNS — such as DNS over TLS or HTTPS — even within a private network. Attackers would have a much harder time hijacking an adequately encrypted DNS request.
### I miss del.icio.us – the web’s discovery-engine and link classifier
URL: https://www.ctrl.blog/entry/delicious-bookmarks/
Last updated: 2026-08-23T22:04:53.000Z
Delicious (stylized after its domain `del.icio.us`) was a social bookmarking website. It might not sound all that interesting, but it was one of the best websites in the early 2000s. Here’s why I miss this defunct website so much.
Delicious let users bookmark their favorite links and annotate them with comments and tags. You would primarily save links you valued enough to remember. The site’s true value was all the organizational work and link comments.
The resulting database was a constantly updated catalog of new and all-time hits on any topic you’d want to browse. You could discover great new reads on any tagged topic or combination of tags. You could also see what others had written about any given link and how the community had taxonomized it.
It’s a bit difficult to explain Delicious. If you’re curious, you can check out this [video demonstration of Delicious](https://www.youtube.com/watch?v=5evTMP8v6KA&ref=ctrl.blog) from 2007\. (It’s apparently recorded on a typewriter; I guess those were still fashionable in 2007.)
Yahoo bought the website in 2005\. The acquisition made sense at the time as Yahoo was still operating as an independent web index. Delicious’ link database must have looked like an irresistible human-curated database of the web’s greatest hits.
Yahoo abandoned its search engine a few years after the deal, and partnered with Microsoft to deliver its search results instead. Yahoo’s lackluster stewardship ultimately led to Delicious’ decay and caused the service to falter. This ultimately paved the way for competitors like Digg and Reddit.
There’s nothing quite like Delicious today. Google [dominates discovery and recommendations](https://www.ctrl.blog/entry/web-discovery/), and most social link-sharing has moved to Facebook, Reddit, and Twitter. None of these platforms focus on organizing and discovering links.
Reddit is a loose collection of disjointed communities. You have to share something that will be popular with a particular community or risk getting down-voted and lose community standing. The premise and experience are completely different.
Twitter lets you broadcast what links you like, but there’s no structure or organization to it. It’s not easy to find links, and you’ll mostly find hundreds of nearly identical messages with the same link. You also risk adverse reactions — or worse, having the link you share completely ignored.
You need to *perform* and be entertaining to an audience on Reddit and Twitter. You’re not just saving links with a service that coincidentally turns out to benefit the community. You might not have a good time on the websites even if your links meet your target community’s standards.
Delicious focused on being useful to *you* and *your links and interests*. It was a collaborative resource organizational tool and an excellent tool for discovery. You could use it as a self-contained archive of your favorite reads.
The closest thing I can find to Delicious today is [Pinboard](https://pinboard.in/?ref=ctrl.blog) (not to be confused with Pinterest, Flipboard, or the half-dozen other apps also called Pinboard). Pinboard is essentially a clone of Delicious. Pinboard also currently owns the Delicious brand and dataset.
Unlike Delicious, Pinboard isn’t free — it costs 22 USD per year. The subscription cost presumably keeps the lights on and helps keep bots and spam out of the community. On the other hand, it has also restricted the community’s growth.
You need a massive community with diverse interests to get an experience similar to Delicious at its peak. Pinboard claims to have 30 000 active users today, compared to Delicious’ 5,3 million in 2008.
Pinboard also offers a more expensive subscription tier with full-text link archival. The archival service lets Pinboard maintain its value over time as the open web’s rampant link-rot epidemic wrecks havoc on historical links.
Who’d want to pay for a website without being able to test it first? There’s no free trial or demo, so recruiting new users must be a constant uphill battle.
The Pinboard service also looks a bit outdated. It doesn’t need a radical redesign, but it needs to be updated to work with today’s many small- and medium-screen devices.
In the last few months, I’ve contacted Pinboard about broken functionality on the website. I’ve also reported a security issue, but have not heard back about either issues.
Pinboard isn’t on a path to replacing what Delicious once was. Delicious was incredibly popular in the days of the early web, while Pinboard is barely worth a footnote.
I believe that Delicious made the web of its day better and more enjoyable. It was so much easier to find stuff in its vast curated database of everything awesome. The web of yesteryear truly was *more delicious*.
Modern search engines can only do so much to help you discover new things. Today’s social websites are built to keep you on their platform and maximize interactions; linking out to other and more interesting things elsewhere goes against their business model.
#### Sources
- [Former Yahoo Engineers Shed Light On Why Delicious And Other Acquisitions Failed](https://techcrunch.com/2010/12/18/former-yahoo-engineers-shed-light-on-why-delicious-and-other-acquisitions-failed/?ref=ctrl.blog), 2010-12-18, Leena Rao, Techcrunch, Yahoo
- [Microsoft and Yahoo Are Linked Up. Now What?](https://www.nytimes.com/2009/07/30/technology/companies/30soft.html?ref=ctrl.blog), 2009-07-30, Steve Lohr, Technology column, New York Times
### A Sony Headphones app feature kills your phone’s battery life
URL: https://www.ctrl.blog/entry/sony-headphones-app-battery/
Last updated: 2026-08-23T22:22:12.000Z
I recently bought a pair of [Sony WH-1000XM4](https://electronics.sony.com/audio/headphones/headband/p/wh1000xm4-b?ref=ctrl.blog) wireless headphones. Many of the headphone’s capabilities are unlocked using the [Sony Headphones Connect](https://electronics.sony.com/headphones-connect-app?ref=ctrl.blog) (SHC) companion app. Unfortunately, the SHC app slashes hours off my phone’s battery life. Here’s what the app did wrong and how to rein in its energy consumption.
The noise-canceling and ambient-awareness modes are key selling points of Sony’s headphones and earbuds range. The companion app can switch between and adjust the modes based on your activity (sitting, walking, etc.) and location (home, work, etc.). You can manage this feature using the Adaptive Sound Control (ASC) option screen in the SHC app.
This capability was a key factor in why I decided to buy these headphones. (Hearing cars and not being run over by them is quite a useful feature.) I also liked the idea of the ambient noise canceling levels automatically adjusting based on my location.
Unfortunately, the SHC app consumes roughly 20–30 % of my phone’s battery after a two-hour walk with ASC enabled. The SHC app and Google Play Services (GoPS) consume the power. GoPS provides geolocation services to the operating system and apps. The battery drain is slightly lower when sitting still, but not by much. To be clear, the auto-switching ASC causes the battery drain, not noise-canceling or ambient-aware modes.
I initially believed the SHC app was updating my location way too often. Constant location updates keep the phone’s antennas on and prevent it from entering low-energy modes. However, I don’t believe that this is the only cause. I use other apps with similar usage profiles, which don’t drain the battery to the same degree.
Android usually restricts how often a background app can check your location. However, it makes exceptions for services belonging to “companion apps,” such as Sony’s headphone app.
I use an app called [WiGLE](https://wigle.net/?ref=ctrl.blog) that collects Wi-Fi and Bluetooth triangulation data. It triggers Wi-Fi scanning and records information broadcast by nearby access points every second. This app consumes 5–6 % of my battery over a two-hour walk. The WiGLE app was not running and didn’t interfere with my testing of the Sony Headphones app.
The WiGLE app can be considered a battery life worst-case for collecting location data. The SHC app doesn’t need to do the same scanning that the WiGLE app does. I would not expect the SHC app to consume 4–6 times more energy than the WiGLE app. I would estimate an app like this to only use 1–2 %.
GoPLS provides a geofencing system for Android that notifies interested apps when you enter and leave a predefined geographic area. This system is significantly more energy-efficient and doesn’t require apps to pull location information in the background constantly. You can set up geofence areas in the SHC app, but the app must have badly misimplemented the feature.
I also use both the Samsung Health and Google Fit apps. Both apps rely on the same activity detection system provided by GoPS. The two apps combined use less than 1 % of my battery over a typical day.
Sony’s app should manage to respond to activity detection and geofence events with minimal impact on battery life. I would expect the battery drain to be no more than 1 %.
The app uses location services from GoPLS globally but will switch to Baidu Location Services if you set its region to China. I can only speculate that Sony must have made some battery life compromises to accommodate the two different location services. For example, Sony might have picked a sub-optimal implementation that can accommodate differences between the two service providers.
I feel uncomfortable just knowing Sony has included the unnecessary Baidu component inside an app installed on my phone. However, that’s a whole other bag of cats that we’ll not delve into now.
The SHC app is optional, assuming you never want to change the headphone’s advanced options. Alternatively, you can keep the app and disable ASC to rein in its energy consumption.
You can cut the battery drain in half by leaving activity detection enabled and disabling all location-based ASC switching. If you completely disable ASC, the battery drain drops to about 1 % after 24 hours of use.
ASC is a neat safety feature, and you can tweak it to make yourself situationally more aware of your surroundings. However, it’s not worth cutting my phone’s battery life by *hours*. I guess I should just get used to either leaving ambient mode on all the time or turning it on when I’m on and about.
The automatic ASC switching can also be annoying. It sometimes unexpectedly switches between complete noise canceling and ambient mode while I’m sitting still in the same location. The unexpected automatic changes can bring background noises in and out of focus. I find this more distracting than a constant background noise.
You shouldn’t revoke the app’s location access controls, however. The app still needs it to pair with the headphones over Bluetooth. Apps can use Bluetooth device scanning to triangulate your location. So, Android doesn’t differentiate this permission from the more generic geolocation permission.
Note that the SHC app will periodically prompt you to re-enable ASC. The dialogs are deceptively designed, and it’s easy to accidentally enable the feature while you’re trying to dismiss the prompts.
#### Sources
- [Adapt your app by understanding what users are doing](https://developers.google.com/location-context/activity-recognition?ref=ctrl.blog), 2022-09-29, Activity Recognition API, Developer, Google
- Sony Headphones Connect APK, version 9.2.0, 2022-09-13, Sony
- [Background Location Limits](https://developer.android.com/about/versions/oreo/background-location-limits?ref=ctrl.blog), 2021-03-11, Android Developer Resources, Google
- [Geofence](https://developers.google.com/android/reference/com/google/android/gms/location/Geofence?ref=ctrl.blog), 2021-02-18, Play Services, Developer, Google
- [GeoFenceClient](https://lbsyun.baidu.com/cms/androidloc/v9%5F0%5F0/doc/com/baidu/geofence/GeoFenceClient.html?ref=ctrl.blog), 2020-07-08, Android Location SDK, Lbsyun, Baidu
### A closer look at Steam’s local network cache proxying protocol
URL: https://www.ctrl.blog/entry/steam-lancache-protocol/
Last updated: 2026-08-23T22:22:30.000Z
There’s no need to waste family game-night time waiting for the same Steam game to download over the internet! All you need is a local caching proxy server. Repeated downloads from a local cache are faster, and you free up your internet bandwidth for other things (like downloading other games). Steam clients will even auto-discover and self-configure to use your local cache.
Valve Software uses the industry-standard HyperText Transfer Protocol (HTTP) to download games via its Steam gaming client. The downloaded games can be intercepted and cached locally by an intermediary/transparent HTTP forwarding cache proxy.
This setup requires you to run a forward proxy server (e.g., [Squid](http://www.squid-cache.org/?ref=ctrl.blog)), and configure your network router to redirect outgoing HTTP connections to the proxy server. A forwarding proxy server compares incoming requests and returns cached results from its local store if it has recently seen and has cached the same request. The proxy will fetch all other requests from the origin server over the internet.
However, this setup will cache every unencrypted web connection and not just game downloads. Forwarding cache servers were often marketed as “web accelerators” in the years before every website switched to using encrypted and uncacheable connections. While most of the web is uncacheable by a proxy server, Steam downloads can still be cached.
The Steam client downloads games from many regional data centers; each of which under a unique domain name. It won’t get a response from the cache even though the rest of the download address — and indeed the downloaded file — is identical. Two people downloading the same game through the same proxy might not get it from the same server or data center. This causes what’s known as a cache miss, and the cache needlessly needs to re-download the same game twice.
Steam also supports a custom locally auto-configuring HTTP-based proxying protocol. You don’t need to configure the individual clients to use the local caching proxy. All you need is a specially configured caching proxy server and a local domain name system (DNS) server.
By default, the Steam client auto-discovers the presence of a local proxy by querying for a special domain name: `lancache.steamcontent.com`. You can configure your local DNS server to spoof this address and return the internet protocol (IP) address of your local cache server. This setup is similar to how an ad-blocking DNS server works.
Steam will treat the local proxy server as if it was a transparent forwarding proxy server. As opposed to using the industry standard HTTP proxy protocol. Clients typically use this protocol when configured to use a specific proxy server. Steam doesn’t switch over to the industry-standard HTTP proxy protocol when talking to your local caching proxy. Instead, it will treat it exactly as a transparent forwarding proxy server. So, it uses the HTTP `Host` header to inform the proxy server where it can download the data.
Each download from Steam, regardless of which data center or domain it was downloaded from, has a globally unique path (file name). The caching proxy should be set up to canonicalize (normalize) the request domain name and return cached downloads when identical download paths are requested from different upstream servers. This method will significantly increase the cache hit ratio.
Steam divides each download into file chunks of roughly 810 Kilobytes. This transfer strategy results in tens of thousands of transfer requests for a typical multi-Gigabyte game. The proxy server must implement HTTP connection pipelining to both the back-end servers and the local clients. Without it, it won’t achieve high transfer speeds. HTTP pipelining lets clients reuse server connections for multiple requests instead of opening a new connection per file transfer. This feature is optional in HTTP version 1.1\. Not all servers support nor enable it by default.
Steam doesn’t blindly trust a local caching server, however. Each downloaded chunk is accompanied by a cryptographic checksum. The Steam client uses it to verify that it has downloaded the correct file.
The Steam client will bypass the local caching proxy if the client can’t contact to it, or it repeatedly sends back error messages or corrupt/wrong downloads. Steam could not as easily have bypassed the proxy server in an environment with a transparent proxy server. It gives Valve more control over the user experience.
If you don’t want to roll your own setup, you can get a ready-to-deploy solution from [LANCache](https://lancache.net/?ref=ctrl.blog). It includes a pre-configured DNS server and caching proxy server. I’ve got experience running DNS and caching proxy servers. (I don’t need any more and possibly conflicting DNS servers on my network.)
My home network is setup for 2,5 Gigabit per second internal networking with a 1 Gbps internet connection. The first computer on my network to download a game or update get speeds up to 0,8 Gbps over the internet. The second computer to download the same title (within the next 60 days) gets it from the cache at nearly 2,5 Gbps!
It’s a complete over-kill for our two laptops and two dual-booting game stations (six total clients). However, it was fun to set up, and it’s a more environmentally friendly to keep everything up to date.
I would have preferred a solution where Steam used an auto-configuring peer-to-peer (P2P) solution. Wargaming, a competitor to Steam, uses BitTorrent to deliver games and updates. It automatically finds other running instances on the local network without the need for an always-on dedicated server. This would be the most preferable and easiest solution for home users.
Both Windows Update and Microsoft Store also use a similar delivery method when you enable [Delivery Optimization](https://www.ctrl.blog/entry/windows-delivery-optimization/). Delivery Optimization is enabled by default for Windows Home edition.
#### Sources
- [Steam client update released](https://store.steampowered.com/oldnews/57829?ref=ctrl.blog), 2020-01-20, News Hub, Steam, Valve Corporation
### You don’t want to be on Cloudflare’s naughty list
URL: https://www.ctrl.blog/entry/cloudflare-ip-blockade/
Last updated: 2026-08-23T22:03:32.000Z
I don’t know what I did wrong, but I’ve angered one of the titans of the internet! For the last six days, my home internet connection has been partially broken. Some apps and many websites either load slowly, partially, or not at all. Everywhere I go, I’m greeted by the same blockade message from Cloudflare.
Cloudflare is the market leader in shielding public websites from targeted traffic-saturation attacks, page load time acceleration, and content delivery network (CDN) services. The company plays a massive role in delivering everyday internet services. Roughly one in three of the top one-million websites is shielded and accelerated through Cloudflare’s massive global data centers, according to data from analytics firm BuiltWith.
Among other methods, Cloudflare uses a browser-challenge page to detect and thwart malicious and unauthorized bots. The page tests the capabilities of your web browser and tries to figure out whether you’re human. The page can be fully automated and only slows down your browsing. However, sometimes it includes a CAPTCHA challenge that prompts you to identify letters and numbers, or images.
For whatever reason, I must have done something that angered Cloudflare. Just about every website I visited from my home internet connection would result in a challenge page. The blockade lasted six days! My partner and I got uncomfortably acquainted with Cloudflare’s market dominance.
We luckily weren’t pestered by too many CAPTCHAs. However, the average webpage load time fell from the normal ≤ 4 seconds to 20–80 seconds. It felt like we’d been transported back to an earlier era with unbearably slow internet.
I’m unsure if my IP reputation was classified with a high bot score (likely automated requests) or given a high threat score (likely malicious request). Cloudflare doesn’t offer end-users any way to dispute or even check their IP reputation scores. The company doesn’t offer end-users any support at all. Everything is automated.
Unfortunately, not every web request can run the Cloudflare challenge page. Many websites only use Cloudflare with a secondary domain name that is only used to serve images, stylesheets, scripts, and other assets. So, while I could quickly load the main webpage, it often wouldn’t work properly because it couldn’t load critical assets.
Websites don’t just serve webpages and their assets, though. Roughly half my podcasts refused to update in my podcast app. The app didn’t know what to do when presented with a browser-challenge page instead of the podcast syndication feed files it expected. It just gave up and threw up error messages.
Plenty of other apps stopped working too. My partner still uses the [Bitwarden password manager](https://www.ctrl.blog/entry/bitwarden-3m-update/). It wouldn’t let them log in to their account to access their password vault because the login process was interrupted by a Cloudflare challenge page.
I’m using an offline password vault app called [KeePassXC](https://www.ctrl.blog/entry/keepass-vs-bitwarden-server/). I must admit that I was a bit gleeful when the effort I’ve put into not having to trust and rely on a hosted password manager finally paid off!
To be fair to Cloudflare, apps and podcasts aren’t allowed on its free product tier. Website administrators can configure exceptions in their Cloudflare accounts. They can mark certain web addresses as asset addresses and have them always bypass the challenge page. This option isn’t available to customers on the free tier, however.
Well into the second day of Cloudflare’s blockade of my home internet connection, Google Search also began blocking requests. It required me to resolve a CAPTCHA challenge for every other search. This luckily only lasted a day.
Cloudflare shares IP reputation data with partners like Google, coordinated through a program called the Bandwidth Alliance. So, my original offense might not even have been against Cloudflare. It might have received the reputation data from a partner, and it just propagated through the Bandwidth Alliance network.
It might not even have been a problem that originated from my IP address! One of my IP neighbors might have done something stupid and negatively affected the whole network neighborhood for a couple of days!
I had a terrible experience online for almost a week before everything cleared up. Automated decisions and backroom data-sharing had tossed a wrench into my entertainment, productivity, and online life.
Section 4 of the General Data Protection Regulation (GDPR) grants Europeans the right to object to automated individual decision-making, including profiling. There’s one paragraph from the regulation in particular that bears repeating:
> “\[Europeans\] shall have the right not to be subject to a decision based solely on automated processing, including profiling, which produces legal effects concerning \[them\] or similarly significantly affects \[them\].”
GDPR, Article 4, Paragraph 1
I’d say my experiences fit that description head-on. Cloudflare or one of its partner’s systems made an entirely automated decision that significantly negatively affected my online life. Come to think of it, an IP address is considered as a potentially personally identifying identifier. I’ve never agreed to data-sharing with the Bandwidth Alliance!
Unfortunately — and probably for the best — the GDPR also makes exceptions for data-sharing, processing, and — although I couldn’t find the verbatim — automated-decision making for the purposes of ensuring network and information security.
I’m no lawyer, but I probably don’t have a right to object to being misclassified as a bot by a security system. Even though it ruined my internet experience.
I don’t know what eventually cleared my IP reputation, but Cloudflare stopped blocking requests from my IP after six days. On day three, I install Cloudflare’s [Privacy Pass browser extension](https://privacypass.github.io/?ref=ctrl.blog) on all my desktop devices. The browser extension uses the same protocol as Apple and Cloudflare are working on integrating into MacOS and iOS.
The extension provides, what Cloudflare claims, is a privacy-preserving alternative to resolving CAPTCHAs on its challenge pages. This might have affected the situation, but again, I have no insight into Cloudflare’s automated decision-making.
My run-in against Cloudflare’s “security” blockade was an incredibly frustrating experience. I felt truly powerless against an unknowable algorithm that sat somewhere out there and decided to block my free movement on the web.
I can only imagine how painful it must be to try and develop a web crawling bot these days. It doesn’t matter if your intentions are good and your bot polite. It’ll probably be blocked everywhere sooner rather than later.
#### Sources
- [Cloudflare Usage Statistics](https://web.archive.org/web/20220920131239/https://trends.builtwith.com/cdn/Cloudflare), 2022-09-20, BuiltWith
- [Bot scores](https://developers.cloudflare.com/bots/concepts/bot-score/?ref=ctrl.blog), 2022-08-12, Concepts, Docs, Cloudflare
- [Private Access Tokens: eliminating CAPTCHAs on iPhones and Macs with open standards](https://blog.cloudflare.com/eliminating-captchas-on-iphones-and-macs-using-new-standard/?ref=ctrl.blog), 2022-08-06, Reid Tatoris and Maxime Guerreiro, Blog Cloudflare
- [Cleaning up bad bots (and the climate)](https://blog.cloudflare.com/cleaning-up-bad-bots/?ref=ctrl.blog), 2019-09-23, John Graham-Cumming, Blog, Cloudflare
- [REGULATION (EU) 2016/679 OF THE EUROPEAN PARLIAMENT AND OF THE COUNCIL](https://eur-lex.europa.eu/legal-content/EN/TXT/HTML/?uri=CELEX:32016R0679&from=EN&ref=ctrl.blog), 2016-04-27, The Official Journal of the European Union, EU Parliament and EU Council
### Review: Aqara indoor climate sensor (for home automation)
URL: https://www.ctrl.blog/entry/review-aqara-indoor-climate-sensor/
Last updated: 2026-08-23T22:17:23.000Z
The [Aqara Temperature and Humidity sensor](https://www.aqara.com/us/product/temperature-humidity-sensor/?ref=ctrl.blog) by Xiaomi is a popular option to capture indoor climate data for home-automation systems. The sensors are small, plainly designed, cheap, promise 2-year battery life, and run on the Zigbee mesh-network protocol. However, they’re also notoriously unreliable, which defeats the desired set-it-and-forget-it target for the sensor.
I had to lower my expectations of the sensor after unboxing and skimming through the [user manual](https://cdn.aqara.com/cdn/website/mainland/static/docs/Temperature-and-Humidity-Sensor%5FManuals%5FEU.pdf?ref=ctrl.blog "“Aqara Temperature and Humidity Sensor: Quick Start Guide”"). The manual says that the sensors don’t work in high-humidity environments (like a bathroom, basement, or refrigerator). The sensor isn’t suitable for use in fridges anyway, as they’re essentially faraday cages that block wireless signals. This limitation was quite unexpected. The sensor is unfit for its primary marketed purpose: it’s supposed to be a hygrometer!
The Aqara sensor communicates over the industry standard Zigbee protocol, and it should work with Zigbee hubs and devices from many different vendors. The Zigbee protocol will soon be rebranded as Thread for Matter. The new unified industry-wide standard for the internet of things (IoT). The Zigbee protocol shares, and thus interferes, with the same 2,4 GHz band as Wi-Fi. However, Zigbee devices maintain a separate mesh-powered network and don’t have access to my more security-critical Wi-Fi network.
Aqara states that you’re *required* to pair the sensor with an Aqara Hub (sold separately). Aqara doesn’t claim that it’s sensors are compatible with other hubs and controller devices. However, everyone buying these intends to use them with other home automation systems like [Home Assistant](https://www.home-assistant.io/?ref=ctrl.blog). I’ll get back to this point in greater detail in the review.
I’ve bought three Aqara sensors for use around my home, so I’ve had the opportunity to compare them to each other and other reference measuring tools. I don’t have any scientifically calibrated thermometers or hygrometers. However, I have half a dozen, and they all agree with each others readings.
The Aqara sensors’ temperature readings are very consistent. When placed right next to each other in temperature ranges between 13 and 29,4 ℃, they stayed within 0,3 ℃ of each other. At 25 ℃ all three sensors show on average 0,7 ℃ higher than my other reference thermometers.
This difference is to be expected for a sensor of this type, and it’s likely caused by the heat generated by its internal electronics. Read [Many indoor air quality sensor products are a scam](https://halestrom.net/darksleep/blog/048%5Findoorairsensing/?ref=ctrl.blog) by William Hales for details. The sensors are designed with a small air intake at the bottom facing down toward the floor. Heat raises, so this doesn’t help heat escape efficiently.
I’m more uncertain about the reliability of the hygrometer; accurately measuring relative humidity (RH) requires accurate temperature measurements. My three sensors’ RH readings are within 2,9 % of each other. The sensors that measure higher temperatures consistently report lower relative humidity. Their RH readings would probably be closer if I could correct them for the temperature difference. However, the sensors’ RH readings are 9–16 % higher than my two reference hygrometers. I’ve got one analog and one digital hygrometer, and their RH readings are within 2 % of each other. Aqara errs towards higher RH at higher temperatures.
The temperature readings are good enough for use as a data point for home automation. I wouldn’t rely on the RH readings without normalizing them based on data from a better reference hygrometer. You might be able to configure this through scripting in the home automation hub of your choice.
The sensors have been unreliable in my experience over four months with them. They stay connected to my local Zigbee network and keep sending low-level network traffic. However, they eventually stop sending new sensor data.
All three sensors worked flawlessly for the first three weeks. However, now they won’t stay connected for more than a few days, though never less than 42 minutes. I have not worked out the significance of the 42-minute time window. It’s the shortest and most common duration the sensor will continue to send data after having been re-paired to the Zigbee network.
I have to re-pair it with my Zigbee controller to get it to begin sending sensor data again. Pulling and reinserting the battery does restart it, but a restart isn’t enough to get it to send new readings.
The problem seems worse when the sensor’s battery voltage drops below 3,06 volts. It’s powered by a regular 3 Volt CR2032 coin battery, so the sensor should definitively work at and even quite a bit below 3 V. New 3 V CR2032 batteries start at 3,0–3,4 Volt. The voltage decreases to 2 V toward the end of their life.
I’m notably *not* using “required” Aqara Hub. I’m using another brand of Zigbee controller. I use the [zig-a-zig-ah!](https://electrolama.com/projects/zig-a-zig-ah/?ref=ctrl.blog) (CC2652R) from Electrolama with, as you might have guessed, Home assistant. That being said, the Aqara sensors work just fine with my controller until they eventually decide to stop sending more readings.
There’s plenty of online discourse about the unreliability of the Aqara sensors. People even describes the same problem with the Aqara Hub, as well as with other hubs and controllers. A Zigbee hub is a Zigbee controller that acts as a network gateway between your local Zigbee and Ethernet/Wi-Fi network. So, you can think of a Zigbee hub as an app-controlled Zigbee controller. In my opinion, adding an Aqara Hub to my setup would only add complexity without improving the sensors.
Most people in these discussions believe their sensors get disconnected from their Zigbee mesh networks. These observations don’t match my experiences. I’m unsure if others don’t know how to check if their sensors still communicate with their Zigbee mesh networks.
Whatever the reason, the sensors stop working over time. They require you to periodically re-pair them with your Zigbee controller, and often swap their almost-full batteries too. The Aqara climate sensors are not a set-it-and-forget-it for two-years solution for your home automation needs.
It’s incredibly misleading to market a product clearly intended to be a hygrometer that can’t be used in humid environments. They’re unfit to keep track of the humidity in rooms or environments where that capability would be the most useful. The Aqara sensor can still be used to control home heating and monitor typical indoor climate. Assuming you can get it to keep transmitting sensor readings, of course.
I’ve reviewed the Aqara Temperature and Humidity sensor model WSDCGQ11LM. This is the model you can still expect to find in stock everywhere. There’s also a newer WSDCGQ12LM (lightly branded “T1”) model available that is slowly replacing old inventory. There are many reports of problems with the newer models too, though.
**Reviewed:** [Aqara Temperature and Humidity Sensor](https://www.aqara.com/us/product/temperature-humidity-sensor/?ref=ctrl.blog)
**Review rating:** 2.5 / 10
### TP-Link band-steers 2,4 to 5 GHz Wi-Fi even when the radio is off
URL: https://www.ctrl.blog/entry/tplink-band-steering/
Last updated: 2026-08-23T22:23:28.000Z
My [TP-Link EAP653](https://www.tp-link.com/us/business-networking/ceiling-mount-access-point/eap653/?ref=ctrl.blog) Wi-Fi access point (AP) has some features that don’t work well together. Who would have thought that its proprietary extensions to the Wi-Fi standard would cause compatibility issues with clients?
I’ve configured the AP to power down the fast 5 GHz radio at night to reduce its power consumption. The 5 GHz band uses less power than 2,4 GHz (faster means shorter transmission time). However, not all devices are compatible with the former. The power savings is about the same during off-peak hours anyway. Clients should fall back to the slower 2,4 GHz network and remain connected throughout the night.
However, the AP’s proprietary band steering feature isn’t aware of its power-saving radio scheduling feature. This setup interaction results in frustrated client devices that don’t understand why they can’t connect to the 2,4 GHz network while the 5 GHz network is unavailable.
Wi-Fi band steering is a non-standard extension of the Wi-Fi standard (IEEE Standard 803.11). Other vendors use other names for the same feature, including “prefer 5 GHz” and “client steering”. As such, the exact technique deployed varies from vendor to vendor. The gist of band steering is that the AP will pretend that the 2,4 GHz network is unavailable to steer clients over to the faster and less congested 5 GHz network. The AP will attempt to detect 5 GHz-capable clients and may choose to respond slower (or not at all) to connection requests on the 2,4 GHz network.
Band-steering requires a dual- or tri-band network setup that operates with the same SSID and security settings on all bands. In 2,4/5 GHz dual-band networks, clients will normally automatically decide whether to connect to the 2,4 GHz or 5 GHz network. The 2,4 GHz band offers increased range and coverage, but at lower data transmission speeds than the 5 GHz band. Clients generally prefer to join the 2,4 GHz network but might decide to use the 5 GHz network if conditions are good.
TP-Link’s implementation of band steering drops the connection on the 2,4 GHz band during the AP association process immediately after it has been established. This design lets it get the client device’s real hardware (“MAC”) address. As opposed to the randomized privacy-preserving MAC addressed that might be used earlier in the connection process. The AP counts the number of connection attempts from the same MAC address to the 2,4 GHz band. If the client doesn’t get the hint and keeps attempting to connect to the 2,4 GHz band, the AP will allow the connection after 10 failed attempts. The failure counter is reset periodically.
Android clients also count the number of failed connection attempts to an AP. They assume the Wi-Fi password must be incorrect after five consecutive failed attempts. Android then temporarily disables the SSID; which is shared among the different bands in a multi-band configuration. It also prompts the user to correct what it believes is an incorrect Wi-Fi password.
Users will need to quickly type the correct password five times — without loosing faith that they’re indeed typing it correctly every time — to successfully join the network. This is a terrible user-experience that is bound to result in confusion, frustration, and support tickets.
To be clear, the AP never told the client there was anything wrong with the password. The client passed the authentication process and gets rejected during the following link association process. I can only assume Android adopted this error handling for compatibility with some unusual and buggy APs. At any rate, the user will surely be frustrated by being told the correct password to their Wi-Fi network is incorrect when that’s not the issue.
I’m surprised that TP-Link didn’t discover this problem with Android clients and set a lower “max failures” value by default. That this went unnoticed suggests to me that TP-Link only tested that the feature works as it expected under ideal conditions. It evidently didn’t bother to verify that the feature failed gracefully with clients running the world’s most popular consumer operating system.
You can fix this problem by either disabling band steering or power-scheduling on your AP. You can also leave both features enabled and change the AP’s band steering logic to give up after four errors instead of ten. The relevant setting in TP-Link products is found under Wireless: Band Steering: Max Failures.
Changing this setting fixes the compatibility issue with Android clients. Other devices may still experience faulty behavior depending on their network reconnection algorithms.
You could also disable the 2,4 GHz band instead of the 5 GHz band radio. However, even brand-new devices aren’t guaranteed to be equipped with a 5 GHz-capable radio. Some clients on your network, especially cheaper ones, will likely drop off the network if only the 5 GHz band remains available.
The proper fix is for TP-Link to automatically disable the band steering feature when the 5 GHz network is powered off. I’m guestimating that TP-Link is only missing about ten lines of code. It shouldn’t be difficult to patch. Alternatively, TP-Link could allow its customers to schedule the band steering feature on/off as well as the radio power schedule. At the very least, the AP should warn users about incompatible settings when enabling both power scheduling and band steering.
TP-Link has needlessly made its band steering feature a checkbox that can potentially break the product. A few conditional checks in the code could have safeguarded it from misconfiguration and bad interactions with other features. It’s incredibly lazy programming to blindly trigger the band steering logic on the 2,4 GHz band without first verifying that a suitable 5 GHz band is there to receive the client.
#### Sources
- [Android Wi-Fi Network Selection](https://source.android.com/docs/core/connect/wifi-network-selection?ref=ctrl.blog), 2022-08-03, Documentation, Android Open Source Project
- [MAC Randomization Behavior](https://source.android.com/docs/core/connect/wifi-mac-randomization-behavior?ref=ctrl.blog), 2022-08-03, Documentation, Android Open Source Project
- [How to Configure Band Steering on TP-Link](https://www.tp-link.com/us/support/faq/2092/?ref=ctrl.blog), 2022-06-27, Configuration Guide, Support, TP-Link
- [IEEE 802.11-2020](https://standards.ieee.org/ieee/802.11/7028/?ref=ctrl.blog), 2021-02-26, Standards, IEEE
- [802.11 Association Process Explained](https://documentation.meraki.com/MR/WiFi%5FBasics%5Fand%5FBest%5FPractices/802.11%5FAssociation%5FProcess%5FExplained?ref=ctrl.blog), 2020-10-05, WiFi Basics and Best Practices, Documentation, Meraki, Cisco
### Finally fixed my PC’s persistent graphics and audio stutters
URL: https://www.ctrl.blog/entry/troubleshoot-stuttering/
Last updated: 2026-08-23T22:23:36.000Z
I’ve set up my gaming computer with dual booting between Fedora Linux and Windows 11\. The Windows 11 installation doesn’t see much use these days since [PlanetSide 2 became available on Linux](https://www.ctrl.blog/entry/planetside2-on-linux/). For the last two months, the system has suffered from stuttering issues during regular use and gaming. The display stops painting or gets partially corrupted, audio goes silent, and all operations halt for 0,5–2 seconds. Sometimes, the system even crashes, but it usually recovers by itself.
The unusual thing about this problem is that it manifests the same on both Linux and Windows. In my earlier experience with similar problems, they’ve often been caused by driver issues. Drivers are operating system (OS) specific, and it’s unlikely that two different OSs should have the same problem. I feared it was a hardware issue, but I struggled to identify the problem.
I’ve run dozens of performance benchmarks, system stability and latency tests, and tests designed to detect specific hardware problems. Tests included MdRes, MemTest, LatencyMon, Prime95, PCMark, 3DMark, OCCT, BurnInTest, and others. Every test came back clean. I found it even stranger that the stutters didn’t negatively affect any performance benchmark tests. The problem was observable, but not measurable. *Oh, joy.*
It was difficult to rule anything out as an issue like this one can be caused by just about any component in the system. I’ve installed Windows and Linux on separate storage media, so I was just about the only component I could rule out. My ASUS mainboard has a bug where it randomly doesn’t initialize the first M.2 connector at boot. So, while storage issues complicated my troubleshooting it’s not the cause of this fault.
I tried removing hardware and changing different UEFI settings to see if anything could help to isolate the issue. You can waste days experimentally flipping switches and trying combinations of different settings. Unfortunately, nothing I tried made any positive difference.
However, I was put on the right track when checking whether there were any updates available for my ASUS PRIME X570-P mainboard. I had already installed the latest version, but the latest changelog mentioned that it had fixed an issue with the firmware-backed trusted platform module (fTPM) causing stuttering!
There is a [known problem with stuttering](https://www.techpowerup.com/292712/amd-isolates-windows-11-and-windows-10-performance-stuttering-issues-to-ftpm?ref=ctrl.blog) with some AMD-brand processors and mainboard combinations. I was a bit confused why this issue hadn’t shown up in my search results before; I must have tried a hundred keyword combinations that should have dug up this tidbit.
Anyhow, I ran out just before closing hours and snatched up compatible hardware Trusted Platform Module (TPM). I bought the [ASUS TPM\-SPI module](https://www.asus.com/motherboards-components/motherboards/accessories/tpm-spi/?ref=ctrl.blog). There are three different TPM connectors, so check that you get the right one! Minutes after I’d installed it onto my mainboard, I could confidently say that things had finally gotten better!
The stuttering didn’t go away completely, nor did it reduce how often it happen. the duration of the stuttering was significantly reduced on both Linux and Windows. Instead of lasting up to two seconds, the screen and audio only cut for a fraction of a second.
Microsoft made a TPM version 2.0 module a requirement to run Windows 11\. I had to audit my Linux installation to verify this, but it isn’t set up to use the TPM at all. I don’t understand how the fTPM should affect Linux, but its presence might cause some stability issues somewhere in the system. It could also have been introduced by the very mainboard firmware update that was supposed to address the issue.
I removed the hardware TPM, and the stuttering immediately got worse in both Linux and Windows. The mainboard reverts to fTPM if the hardware TPM is removed. It doesn’t have a way to disable the TPM. The stuttering got better again after I reinstalled the TPM. The fTPM clearly affects the system stability, even under an OS where it’s not in use.
I had finally made some progress after spending a dozen hours on the issue over several days. I still don’t know what the underlying problem is, but at least all my random trial and error had resulted in a change for the better.
On a whim, I tried reseating (unplugging and replugging) the memory modules. I was just about out of other things to test. I had run multiple memory speed and stability tests, and they had not detected any problems.
I first booted into Windows and didn’t notice any improvements. However, I immediately noticed improvements when I booted into Linux. The stuttering was *almost* completely gone!
The desktop still sporadically locks up for a fraction of a second now and then. Occasionally, it also hangs indefinitely or crashes. However, it doesn’t happen when playing games or watching videos anymore. Importantly, it now always recovers from the stuttering and no longer locks up indefinitely. Nevertheless, I jotted it down as a success.
I guess the lesson I learned from this experience was to not trust software-backed assessments of hardware. The slots for the memory modules on my mainboard are especially finicky to click into place. You need to apply an excessive amount of force to install the modules. I presumably must not have done it properly when I installed them two years ago. Replugging them shouldn’t have reset or influenced anything else on the mainboard.
I’ve previously experienced another [connector problem that caused subtle and difficult-to-troubleshoot problems](https://www.ctrl.blog/entry/m2-performance-fretting/). My gaming computer is stationary, so the connector problem must have been caused by something like thermal cycling. Whatever the cause, the faults must have been error-correctable at some level to a degree where no test tools noticed the issue. I haven’t got memory modules with error-correcting code (ECC). They’re too slow and too expensive for a gaming-focused system. However, modern memory modules are so dense that errors are expected, so they need to include some simpler internal error-correction mechanisms.
At this point, I pulled out the TPM and reverted to the fTPM again. I expected that it wouldn’t impact the system stability and the stuttering anymore. Country to my belief, this reintroduced the stuttering on Linux. I switched back to the hardware TPM, and the stuttering stopped. Whatever the underlying cause, it’s caused by a complex set of factors.
Windows was still stuttering, though. The stuttering must be caused by yet another issue. At this point — with two other underlying problems out of the way — I had more luck with a more traditional troubleshooting technique that I’d already tried and dismissed as ineffective.
I’ve been using the stable driver for my AMD Radeon RX 6700 XT graphic card (GPU). It was last updated nearly four months ago. AMD has released four beta releases since the last stable release. The changelog for all four betas mentioned that they address stuttering and stability issues.
I upgraded to the latest beta release and the stuttering on Windows disappeared completely. I had already tried using an earlier beta release but had reverted to the stable version after it didn’t fix the stuttering. A bit curious, I removed the hardware TPM one last time to see what would happen. The stuttering re-manifested with the fTPM, so I quickly reinstalled the hardware TPM.
I also needed to find a solution for the desktop crashes on Linux. As I’ve mentioned, it doesn’t crash when I’m watching videos or playing games. So, the system seems to handle high loads fine but not lower loads. I disabled Dynamic Power Management (DPM) in the Kernel, and that seemed to help a lot.
I went from experiencing one or two crashes every hour to maybe once every four hours when I disabled DPM. I’d already tried this workaround some weeks earlier, but it didn’t make a difference with all the other system issues. The AMDGPU driver has a history of stability issues with DPM. Disabling it is a commonly suggested workaround for any driver crashes.
I tried one more time to remove the TPM while DPM was disabled on the GPU. The system started stuttering again, so I quickly reinstalled the TPM. I expect that this is the last time I’ll ever attempt to remove it. It observably increases system stability for both Windows and Linux.
I’ll be the first to admit that I have no idea what’s going on inside my computer. It’s a common setup with average hardware components. Gaming and computer enthusiast forums are filled with people complaining about similar issues with identical or similar hardware. What works for some doesn’t work for others.
It took me weeks to fix these problems. Without any clear indications of what was wrong, I was left with random experimentation to see if I could influence the observed behavior. By the time my system was up and running reliably again, I expect most consumers would have given up and either bought a new computer or found another hobby.
I would probably not have gotten anywhere without decades’ worth of hard-fought-for experience. Even so, my three-part solution was mostly discovered by random chance and an unwillingness to admit defeat.
It’s incredibly difficult and time consuming to resolve this type of difficult-to-diagnose hardware problem. There simply aren’t any good tools or reliable methods to detect and diagnose hardware issues. Consumers are left to fend for themselves as they can’t even accurately point the finger at any one hardware vendor as being the culprit behind their hardware vows.
Consumers either need to spend hours and become experts in the field or find another hobby. The computer enthusiast and gaming markets will die unless vendors can come together to develop better standards for troubleshooting tools. We need better fault detection and reporting, more insights and logs, and it needs to come from every component and level.
I believe more in initiatives to make problems easier to diagnose than I believe the industry will magically overcome entropy and incompatibility issues. It can’t develop more reliable products without overcoming the same lack-of knowledge and insight that its consumers face on their own every day.
### Stop using DICT dictionary apps (such as GNOME/MATE Dictionary)
URL: https://www.ctrl.blog/entry/dict-protocol-privacy/
Last updated: 2026-08-23T22:05:00.000Z
The MATE Desktop for Linux installs a Dictionary app by default (a fork of the retired GNOME Dictionary app). The apps don’t protect your privacy, and you might want to stop using them.
With the apps’ default configuration, your word queries are looked up online via an arcane old internet protocol called DICT ([RFC 2229](https://www.rfc-editor.org/rfc/rfc2229.html?ref=ctrl.blog)). The protocol was standardized in 1997 and it doesn’t include any encryption or other privacy protections.
So, why is this a problem for dictionary lookups?, you might ask. Some knowledge is forbidden knowledge, depending on your local authorities. For example, it is inadvisable to look up information about abortion from within some U.S. states, war crime in Russia, or democracy and human rights in China.
The apps don’t warn you about their privacy implications when you launch them. They’re technically required to inform you about whom they share data with (the dictionary server providers) under the General Data Protection Regulation (GDPR) in the E.U.
The apps can be configured to use a local offline dictionary. This configuration requires setting up a DICT server and change the apps to only query your local server. You then need to maintain a server and source an up-to-date dictionary.
The GNOME Dictionary used to be a GNOME Core app. Core apps are installed automatically as default apps for the GNOME Desktop. However, you may still have the app installed if you’ve kept updating the same GNOME installation over the years. The app is also still often featured in the GNOME Software store.
The MATE Dictionary app is installed by default in Linux Mint MATE. In other Linux distributions, it’s also a dependency of the MATE Desktop meta-package. The findings in this article also apply to other DICT protocol clients such as GoldenDict.
It’s possible to set up a DICT server behind a Transport Layer Security (TLS) encryption proxy. This would provide network-interception protection and on-the-network privacy protections. The dictionary server provider would still see your queries, however. Neither GNOME Dictionary, MATE Dictionary, nor GoldenDict support the non-standard DICT over TLS set up.
You should consider the [Wordbook app](https://flathub.org/apps/com.github.fushinari.Wordbook?ref=ctrl.blog) if you’re interested in a privacy-friendly dictionary app that works offline. However, it only supports English. It automatically downloads the WordNet dictionary the first time you launch it. The [WordNet Project](https://wordnet.princeton.edu/?ref=ctrl.blog) is retired, so the dictionary will grow more out of date over time.
For a more up-to-date online and encrypted dictionary, you can consider [Quick Lookup](https://flathub.org/apps/com.github.johnfactotum.QuickLookup?ref=ctrl.blog). The app is less polished than Wordbook, but it supports 46 languages. It’s powered by [Wiktionary](https://www.wiktionary.org/?ref=ctrl.blog), a Wikimedia Foundation project. You can expand and contribute to the dictionary if something is missing!
### “Gigabit Router” doesn’t mean it can deliver gigabit internet speed
URL: https://www.ctrl.blog/entry/gigabit-router/
Last updated: 2026-08-23T22:08:19.000Z
Most manufacturers of consumer-grade network routers (both Ethernet and Wi-Fi) brand their products as “Gigabit Routers”. At the very least, it’ll say “Gigabit Ethernet”. However, neither term necessarily means the router can fully exploit your gigabit internet connection.
When shopping for a new router, you’ll notice that most manufacturers advertise every product as a “Gigabit Router” or at least “Gigabit Ethernet”. There are also a few budget Fast Ethernet (100 Mbps) options in the market. Informed consumers are generally satisfied if it says “gigabit” (1 Gbps or 1000 Mbps) somewhere on the box.
The only differentiating features — if you believe the manufacturers — are the number of Ethernet ports and the Wi-Fi speed. The quoted Wi-Fi speed is usually the theoretical maximum and not based on performance tests. However, Wi-Fi router speed is a story for another time.
However, you might not get the full speed advertised on the box. The Gigabit claim may refer to the router’s Gigabit Ethernet ports, the switching speed between the local-area network (LAN) ports, or the total switching speed between LAN; Wi-Fi LAN (WLAN); and the wide-area network (WAN, e.g., the internet).
Gigabit doesn’t necessarily refer to the routing speed between the LAN or WLAN and the WAN. This last metric is what most people would consider as their “internet speed”.
Gigabit Ethernet ports aren’t the only requirement for a device to deliver gigabit speeds. You also need fast enough hardware to handle the package routing. Switching between the LAN ports can be done almost entirely using hardware acceleration in the firmware. These chips are inexpensive, and most routers and switches will handle a full gigabit between the LAN ports.
However, the WLAN to LAN and WLAN/LAN to WAN speeds are less likely to reach gigabit speed with inexpensive hardware. WAN routing requires the router to do more work to send the traffic onward to its destination. In IPv4 networks, the router needs to rewrite the sending address (“masquerading”) and support more long-lived states to allow for replies to get back to the sender.
It might not sound like much, but parts of these processes generally happen in software on an underpowered processor rather than in firmware. The performance plummets and you can end up with speeds anywhere in the 200–800 Mbps range depending on the exact make and model.
So, how can you know which router to get that’ll max out a gigabit connection? You can’t rely on the manufacturer-provided marketing numbers on the box. They’ll almost always be theoretical max speeds and rarely based on the performance characteristics of the router in question.
Instead, you have to rely on reviewers to put the routers through performance tests. Unfortunately, many “reviews” uncritically repeat information from the manufacturer.
There’s not much interest in router reviews, so through ones are becoming rarer and rarer. You probably won’t find detailed enough reviews for the cheapest options on the market, but you might have more luck with prosumer and enterprise routers.
Ideally, you should find ones that mention routing speeds, and test with large (1500 bytes) and medium-sized (500 bytes) network packages. The two figures can vary greatly and reveals whether the router can handle different workloads. Alternatively, an internet speed test performed from a site with a confirmed gigabit connection can suffice.
You might need to buy your best candidate router and do the performance testing yourself. Make sure to buy it from a vendor with a generous return policy with enough time to do the testing.
It’s not difficult to test routing speeds, but it’s also easy to accidentally test the wrong thing (e.g., LAN switching or the Wi-Fi speed instead of WLAN/LAN to WAN). You can get a long way just by using an online speed test and comparing the speed you get when your computer is plugged directly into your internet connection versus when it’s connected through your router.
### TeamViewer installs suspicious font only useful for web fingerprinting
URL: https://www.ctrl.blog/entry/teamviewer-font-privacy/
Last updated: 2026-08-23T22:23:11.000Z
So, here’s a bit of a mystery: Why does TeamViewer – the popular remote desktop program – install a font it doesn’t use on your computer? The abstract font (shown in the above image) doesn’t seem to serve any purpose in the software. Intentional or not, it enables websites to detect if you have TeamViewer installed on your computer.
You can see an almost complete type specimen of the TeamViewer font in the above illustration. It contains the characters to write TeamViewer plus the digits 7 and 8\. The remaining 24 majuscules (uppercase) characters of the Latin alphabet are encoded as an apostrophe. The included characters feature a rather unique and mostly unreadable design.
It’s not uncommon for creative software — like Microsoft Office, LibreOffice, and the Adobe Creative Suite — to install complementary fonts. However, these fonts are all meant to enhance your use of the software by giving you more fonts options. You get the TeamViewer font as an option in all programs that support setting your own font (such as Microsoft Word).
Websites can detect the fonts you’ve installed on your computer. Font detection relies on brute-force testing. A webpage creates a hidden bit of text and measures how wide it is. It then changes the font to, say the TeamViewer font, and checks to see if the text changes width. If it does, then the website knows you’ve got that font installed on your computer — and by extension the software that installed it.
The odd and almost unreadable proportions of the TeamViewer font make it well-suited for fingerprinting. I believe this is also its true purpose. There’s no use case for installing a unique non-general purpose font like this along with your software other than enabling browser-based fingerprinting.
If the program needed this font for some obscure reason, it could load it from its own data directory. It doesn’t need to install the font as a generally available system font if it only served an internal use.
The TeamViewer client program doesn’t load the font file, list all the installed fonts, or reference the font file directly. As far as I can tell, the only TeamViewer software that references the font file is the TeamViewer installer and the uninstaller programs.
TeamViewer doesn’t bundle the font in its Mac and Linux versions. The font is only bundled alongside the Windows version. This tidbit of information is also why I’m convinced the font serves no purpose in the TeamViewer client software. Why would it be required on Windows but not the other supported platforms?
The current version of the font is called TeamViewer15\. TeamViewer releases a new version of the font with every major version number change. A quick query on GitHub reveals that many font fingerprinting libraries include references to the font names TeamViewer15, TeamViewer14, and TeamViewer13.
The font raises the risk of phishing and scams targeting TeamViewer customers. It leaks who TeamViewer’s customers are to every website they visit. This could enable more targeted social-engineering messaging based on the knowledge about whether the software is installed or not. There’s no need to waste time in a support scam asking the victim to install a remote-access tool when they’ve already got one set up and ready to abuse.
After I learned about the existence of the TeamViewer font, I expected to find it used on the TeamViewer website. I assumed the website used it to adapt its contents to whether you have the software installed or not.
The TeamViewer website could, for example, change the download button to a purchase button, or give support documentation relevant to your version of the software. However, this **is not the case**. No public part of the TeamViewer website tries to load the font.
**Update** (2022-07-20): A reader identified and documented a usecase for the font on the TeamViewer website in [a comment on Hacker News](https://news.ycombinator.com/item?id=32165103&ref=ctrl.blog). The website checks for the presence of font (and thereby whether you’ve got the software installed) when you follow a special screen-sharing session invitation link. The links are used to invite others to connect to your computer.
I haven’t examined archived versions of the TeamViewer website; it might have used the font in the past. It really raises questions about the font’s true purpose, though. Is it used by partnering ad networks to better target TeamViewer customers and non-customers with custom messaging?
> The TeamViewer font is used to implement a smooth user experience from web to the native client, e.g., when connecting via an invitation link, to offer an installation or initiate the connection directly. This has proven to be helpful to improve the user experience for all user groups; nevertheless, based on the raised concern, we have decided to review and change this approach within one of the next releases to prevent potential detection of a TeamViewer installation via the font.
Robert Haist, Chief Information Security Officer, TeamViewer
**Update** (2022-07-23): Updated with a statement from TeamViewer. The company has decided to remove the font in a future release.
#### Sources
- [Canvas Font Fingerprinting](https://privacycheck.sec.lrz.de/active/fp%5Fcf/fp%5Fcanvas%5Ffont.html?ref=ctrl.blog), 2019-02-21, Browserize, Leibniz Computing Centre
- [Fingerprinting web users through font metrics](https://www1.icsi.berkeley.edu/pubs/networking/fingerprintingweb15.pdf?ref=ctrl.blog), 2015-02-26, David Fifield and Serge Egelman, University of California; Berkeley
### On-device browser translations with Firefox Translations
URL: https://www.ctrl.blog/entry/firefox-translations/
Last updated: 2026-08-23T22:06:55.000Z
The Mozilla Firefox web browser is finally beginning to catch up in a market where every competitor has an online language translation service feature. Firefox recently debuted its long-awaited privacy-preserving on-device translation service.
The built-in integration with Google Translate has been one of the Google Chrome browser’s leading advantages over its competitors. The translation service grants you effortless access to international content in languages you don’t understand. It gives you access to more of the web.
[I attribute much of Google’s pan-European success](https://www.ctrl.blog/entry/googles-european-success/) to its translation services. Why would you want to switch to Chrome from a competitor like Firefox? Well, you can effortlessly access more of the web with Chrome than with Firefox.
Other web browsers — notably Microsoft Edge, Apple Safari, and Yandex Browser — have only recently added their own translation services. However, the Mozilla Firefox browser doesn’t currently have nor want its own online translation service.
Online translation services require you to either send the webpage address or contents of the page to the translation service provider. It translates the contents and sends it back to your device. This architecture sacrifices user privacy for convenience.
You can’t make an informed decision on whether you want to share the contents of a webpage or an email message with a translation service as you don’t know beforehand what the message says. This paradox can make you unintentionally compromise your privacy and the privacy of the sender.
Mozilla has gone in the opposite direction. Instead of relying on a centralized translation service, it’s hoping to perfect on-device translations. Mozilla has partnered with various European universities to develop on-device offline and privacy-preserving local translation services. The translation project was announced in 2019 as Project Bergamot.
The endeavor is funded by research grants from the European Union (EU). The EU is a natural supporter of this work with its 24 official languages and a total of 37 languages across the entire European Economic Area (EEA). Translation services are a necessity of European governance and commerce.
The first public release of Firefox Translations supports only eight languages with five additional languages in beta quality. The next version is expected to add two more languages plus one beta language. You can’t translate every supported language to and from every other support language.
It’s a far stretch from completely fulfilling the needs of the EU nor Firefox’s users. However, it’s a solid start and it hopefully will be developed to support more languages over time.
The Firefox Translations extension is available for free through the [Firefox Extensions portal](https://addons.mozilla.org/firefox/addon/firefox-translations/?ref=ctrl.blog). I expect we’ll see Firefox Translation included by default in a future version of Firefox.
The extension uses an experimental application programming interface (API) called `translationbar`. The user interface is provided natively by Firefox with the extension providing the language-translation models. Other translation services, online or offline, will, presumably, be allowed to hook into this API in the future.
If you’re not a Firefox user, you can assess the translation service quality of the [Mozilla Translate web front-end](https://mozilla.github.io/translate/?ref=ctrl.blog). Even though it’s a webpage, the translation happens on your device.
The translation models are all open-source. Outside the context of a web browser, this could be applied to provide privacy-preserving translations of chat messages and in other apps.
Apple’s Translator app on iOS and the Google Translator app on Android and iOS can optionally perform on-device translations when you’re offline. It’s not beyond the capabilities of these other actors to achieve on-device translation services. However, it — and by extension, your privacy — apparently isn’t a priority.
### How to set per-creator/channel playback speed on YouTube
URL: https://www.ctrl.blog/entry/youtube-per-channel-speed/
Last updated: 2026-08-23T22:26:10.000Z
You can find hundreds of browser extensions that let you fine-tune the playback speed for all YouTube videos. I’m happy with the default speed of 1× for most videos (and music). However, I want to speed up some channels without having to tweak the speed dial every time. Enter Samuel Li’s Speed Controller extension.
I tend to fine-tune the playback speed to somewhere between 1,05× and 1,35×. By default, YouTube only lets you increase the playback speed by increments of 0,25×. This design decision has led to the creation of hundreds of extensions for fine-tuning and setting speeds other than the defaults.
I tend to set the same speeds for videos from the same creators. For example, some podcasts talk fast, and others drag on forever. They can be just as interesting, but the slower ones are a bigger time commitment.
This got me thinking: Surely, there must be an extension that lets me set the default playback speed per-channel instead of the entire YouTube website? I decided to install every YouTube speed-setting extension in the Firefox Add-Ons catalog. Unfortunately, none of them offered the functionality I wanted.
However, the creator of one extension had included an open invitation to email them with feature suggestions. I sent an email to Samuel Li, and days later he’d implemented the functionality I wanted.
The Samuel Li’s Speed Controller (SLSC) extension now lets you set a global default playback speed for all of YouTube and per channel. I’ve left the global default at 1,0× and set custom higher speeds for some of my favorite podcasts and other channels.
SLSC also works when watching videos from playlists. I mention this because I also discovered that many extensions don’t work at all in playlists or only work for the first video. SLSC will automatically change the speed to match your defaults for the current video’s channel.
[](https://addons.mozilla.org/en-US/firefox/addon/youtube-speed-controller/?src=external-addonsbadge-ctrl.blog&ref=ctrl.blog)
The extension is exclusively available for Firefox on Mozilla Add-Ons. However, it’s open-source and it only uses cross-browser compatible Application Programming Interfaces (API). It should run fine in any Chromium (e.g., Google Chrome) and WebKit (e.g., Safari) web browsers.
### Review: Dygma Raise split mechanical keyboard for enthusiasts
URL: https://www.ctrl.blog/entry/review-dygma-raise-split-keyboard/
Last updated: 2026-08-23T22:18:14.000Z
**Sponsored:** Dygma provided the product for free. It had no editorial control of this review.
The [Dygma Raise](https://web.archive.org/web/20220615160753/https://dygma.com/products/dygma-raise) is a splittable 60 % mechanical keyboard; meaning it has no function key row, navigation keys, arrow keys, or numpad. It’s squarely targeted at keyboard enthusiasts willing to pay 350 USD for a keyboard with fewer standard keys plus a unique two-rowed eight-key space bar design.
You can program every key on the Raise with up to ten layers to make it fit your needs. It’s quite flexible, yet it’s the first keyboard I’ve ever used that didn’t work after I plugged it in. Its firmware leaves a lot to be desired.
I’ve already discussed [*the case for and against split keyboards* in an earlier article](https://www.ctrl.blog/entry/split-keyboard-accessibility/). I won’t repeat myself here, so have a read through that first if you’re curious if split keyboards are right for you. You may also be interested in my [keyboard form-factor guide](https://www.ctrl.blog/entry/keyboard-form-factor-guide/).
The Dygma Raise is available in matte black or silver and it’s available with ISO or ANSI key layouts. You can choose from eight popular key switches from Kalih and Cherry MX, and eight regional keycap sets.
The Raise consists of two keyboard halves that you can place as you want. Each half is intended for single-handed operation. You can use the Raise as a normal 64 % keyboard by pushing the two halves together. The connector makes a snug and secure fit.
The two halves of the Raise are wired using USB-C cables into a small box Dygma calls the “Neuron”. The Neuron stores your custom light effects, keyboard layout and layers, and your macros. You can plug it into any computer and it’ll remember your setup without the need to install and configure any software on every computer you use. The Neuron is wired to your computer using an included USB-C to A cable.
Along with the Raise, you also get a carrying case and an “enhancement kit”. The kit includes a keycap and switch puller, O-ring switch dampeners, a brush that’s too big to fit where it’s needed, two extra keycaps, and one extra of each key switch you were offered when ordering. The extra keycaps you get are one blank key and one layout specific E00 key (the key to the left of the 1 key).
The enhancement kit is a nice touch, but it doesn’t make sense to send a key switch sampler set *after* you’ve already decided and bought the keyboard. I guess the intention is to include an extra key switch instead of shipping out replacements later in case of a faulty switch.
It’s presumably cheaper to send everyone a complete set than to stock different sets per keyboard, but the sets are already complex with the extra keycaps in two colors plus the layout specific E00 replacement. However, it would make much more sense if you receive the kit first as a sampler and then could place the order for the keyboard.
Most of the keycaps, including the four upper space keys, are standard Cherry-compatibles. However, the bottom four buttons are custom, although the company has made available [3D models for printing](https://support.dygma.com/hc/en-us/articles/4468915916049-Can-you-3D-print-the-keycaps-for-the-thumbkeys?ref=ctrl.blog).
The lower four keys are my biggest gripe with Raise’s hardware. They’re about ⅖ the height of the regular keycaps, forming a tall barrier between the top four space-bar-replacement keys and the lower four. The profile of the space keys goes down to meet the other four keys, but there’s still a significant height difference.
My thumbs get stuck on the lower four keys as I repeatedly bump into the sides of the upper space keys. I need to make exaggerated and straining motions to compensate for the design. It’s difficult to get used to.
The bumps on the home row position keys (F and J) are shallow and positioned too close to the key edges; making them nearly useless when it comes to finding the home keys. Good positioning bumps are either tall near the edge or shallow but placed much nearer to the middle of the keycaps’ top surface.
I currently have 14 keyboards in the house and all of them but Dygma gets this right. The default keycaps are so bad that switching F and J to caps with proper bumps reduced my typing error rate by 14 %. I constantly have to look down to locate the position keys, something I haven’t needed to do regularly in twenty years.
I can only assume Dygma’s designers either didn’t realize why the bumps are there, or that they have super-sensitive fingertips. It’s fixable by purchasing better keycaps, but it feels disappointing to have to spend the extra money to fix Dygma’s design flaw. You’ll have no trouble finding compatible keycaps, but they’ll probably look slightly off from the rest of the set.
Some of the product photos on Dygma’s website show the keyboard raised off the table and tilting out from the middle at a 40° angle. This is a typical feature for split keyboards, offering even more ergonomic customization. Despite its name, the Raise’s stand is sold separately (90 USD).
The open design makes it easy to clean, although some potential customers might be disappointed by the reduced reverb and sound from an unenclosed keyboard. Cat owners will love it, though.
The keyboard unfortunately isn’t rated as being splash-proof. Accidents involving various drinks are known to happen around expensive keyboards. The chassis doesn’t feature drainage holes at the bottom, which can help to prevent or limit water damage. Holes in the chassis can impact the sound profile of a keyboard, but I’d be much happier with that compromise than someday having a wet and dead keyboard.
The Raise is a keyboard for people who want to customize how their keyboards work. I found some of the out-of-the-box defaults baffling; e.g. the Insert key isn’t mapped to anything even though all the other navigational keys are available. The default keyboard makes so many strange decisions that it’s not really an option to *not* customize/fix it.
For example, the keyboard has a Function key. You would expect this to work with the number keys to emulate the missing function keys. Instead, the Function key is only configured as a toggle for the light effects.
The default secondary layer uses the E (up), S (left), D (down), and F (right) keys as directional arrow keys. Millions of people are already familiar with using the W (up), A (left), S (down), and D (right) keys; as they are the default movement keys in every game. It seems incredibly strange to me to not go with WASD as the default.
You can customize every keyboard layout using Dygma’s Bazcor configurator software. You can restore the Function key, move the arrow keys to WASD, implement a Windows key lock (popular on gaming keyboards), and do all sorts of changes.
Bazcor is a complicated piece of software, but it makes customizing your keyboard relatively simple. You might be disappointed if you expect to customize key levels and groups, though. It only allows you to customize which key emits which keycode; think of it as moving any key anywhere else on the keyboard.
You can configure up to ten levels and set keys to switch (permanent) or swap (switch while holding a modifier key) to different keyboard layers. For example, I swap to a layer where the number keys are mapped to Function keys 1–12 while holding the Function key pressed. I’ve also set up my keyboard to switch to a layer where the Windows key is disabled by pressing the Function + Windows keys.
You can configure custom light colors for each key, and even use different colors for different keyboard layers. You can’t assign any lighting effects other than on/off and color, though, so you won’t be able to configure a Caps Lock key to indicate its state.
My first out-of-box experience (OOBE) with the Raise after plugging it in was what appeared to be a completely dead keyboard. No key presses seemed to register. I feared I’d received a defective product, but the issue was more subtle than that.
I’d plugged it into my computer while it was asleep, and expected it to wake up the computer when I pressed keys on the keyboard. You know, like a normal functioning keyboard works.
The Raise doesn’t work when the computer is asleep nor when it’s in UEFI/BIOS setup mode because of [blah-blah boring technical details](https://support.dygma.com/hc/en-us/articles/360007813538-Why-doesn-t-the-Raise-work-when-I-first-login-to-the-computer-or-when-it-s-on-Sleep-mode?ref=ctrl.blog "“Why doesn’t the Raise work when I first login to the computer or when it’s on Sleep mode?”"). The issue was fixed in firmware version 0.3.5 released in March 2022. The Dygma website still only links to version 0.3.3 today over four months later. The issue has also reappeared in version 1.0.beta14\.
It can’t start a sleeping device, and you need to have a different keyboard on hand if you’re doing something as exotic as interacting with your computer’s UEFI settings, dual-booting it, or run into the Windows- or BitLocker recovery screens. Dygma has sold a partially defective keyboard since its launch over two and a half years ago.
To be fair, I’ve got other keyboards where the Enter and Space keys don’t wake my PC from sleep. However, on those keyboards, I have at least 60 other keys that get the job done — and both Enter and Space work in BIOS mode.
The keyboard also occasionally restarts by itself while I’m using it. The lights distractingly flicker off and on again, and I might lose one keystroke when it happens. I’ve only noticed it happen five times in three months, so it’s not a huge issue. On the other hand, that’s also five times more than any other keyboard I’ve used.
Dygma has been open about its early [issues with its keyboards freezing up completely](https://dygma.com/blogs/product-development/a-keyboard-startups-worst-nightmare-freezing-issue-solved?ref=ctrl.blog). It initially solved the problem by adding a three-seconds-timeout-and-restart detection before finding a better solution. I assumed it was a loose cable or a poor connection before I read about Dygma’s earlier issues. I’m not sure if my issue is related to that issue, though.
The Caps Lock key is supposed to slowly fade on and off when enabled. The effect only updates when you press other keys on the keyboard, though. So, you might not be able to determine its state by looking at it, depending on where it is in its light cycle.
The Bazcor configurator also ran just fine on recent versions of both Fedora Linux and Ubuntu. It handled device communication, firmware updating, and even display scaling just fine. My only critique is that the firmware updates aren’t also distributed through the Linux Vendor Firmware Service (LVFS). You need to use the configurator to update the firmware.
Bazcor almost drove me nuts after the first use, though. I’d configured everything and sent the setup to the keyboard. I restarted my computer to apply some pending software updates but had trouble logging back in again.
It turned out something had gone wrong and every key on every layer had been moved by one position. The one key became two, the two key became three, and so on. I had to use my old keyboard to unlock my computer and figure out what had gone wrong with the Raise.
I was able to use Bazcor’s configurator to export my layers, fix them, and import them back onto the keyboard. It has only happened once and I don’t understand why it did. Most customers would have returned the keyboard at this point instead of writing a small program to fix the configuration files. Oh, and there’s no reset-to-defaults button in the configurator software.
On one hand, this shows the power and capabilities of a programmable keyboard. On the other hand, … it takes a very special kind of person to enjoy the programming challenge required to correct a problem like this one.
The Raise can be configured for basic mouse click and movement emulation. It also supports macros mixing keyboard and mouse interactions. The macro editor in Bazcor can take some time to get used to, but it’s within expectations given the complex nature of macros.
### Conclusions
The Dygma Raise scores high on durability, repairability, and the quality of the hardware. You can buy replacements for everything likely to wear out from Dygma’s website. Everything feels solid and well-built.
Though, I’m not convinced its unique hardware features are all that good. The high ridge between the lower and upper rows of space keys makes it uncomfortable to use the lower row. The shallow bumps on the positional keys make me want to toss out the default keycap set.
You’re required to poking around a lot to discover how to use it to its fullest. That’s also part of the experience you’ve bought. With great customization-power comes great complexity, and Bazcor does a fine job at preserving the former while reducing the latter. The Bazcor configurator needs a “restore defaults” button and possibly some sort of version control or “undo” functionality, but it’s mostly fine.
The firmware leaves a lot to be desired. The occasional restart isn’t as big of a problem as needing a different keyboard on hand to wake your computer and operate it in lower-level modes. Dygma has released one firmware version where it worked properly, so there’s still hope that future versions will get this right.
The hardware product is surprisingly polished despite being developed by a small team. It’s a specialty product for people who can’t meet their keyboard customization needs through software alone. Ultimately, the firmware flaws make it difficult to recommend the Dygma Raise.
**Reviewed:** [Dygma Raise](https://web.archive.org/web/20220615160753/https://dygma.com/products/dygma-raise)
**Review rating:** 5.5 / 10
### 7 simple bot detection methods that won’t inconvenience users
URL: https://www.ctrl.blog/entry/detect-non-browser-form-submission/
Last updated: 2026-08-23T22:04:57.000Z
Millions of (poorly coded) bots relentlessly crawl the web to detect and spew junk content into any form they find. The go-to countermeasure is to force everyone to complete a Completely Automated Public Turing test to tell Computers and Humans Apart (CAPTCHA). CAPTCHAs are those annoying user-hostile tests where you type in skewed letters or identify objects in photos. They require cultural familiarity, introduce accessibility barriers, and waste everyone’s time. Instead of using a CAPTCHA, you can detect and block many bot submissions using completely unobtrusive form validation methods.
The methods I’ll discuss in this article help identify whether the form was submitted via a standards-compatible modern web browser. They’re mini web standards compliance tests that don’t rely on the user doing anything but using a web browser of their choice. It won’t help (much) with forms submitted via browser automation, and they'll only delay bots written specifically to target your website.
Fortunately, the vast majority of comments are still submitted via scripted simpleton bots. They’re much faster and more economical than puppeteering a real web browser into spewing spam across the web.
This article is for developers; almost everything discussed requires modifying the client-side form and server-side validation. This article assumes some familiarity with HyperText Markup Language (HTML) and HyperText Transfer Protocol (HTTP) request headers. Without further ado, let’s get started.
**Drop support for obsolete HTTP versions.**All modern web browsers use version 3 or 2, with only limited use of HTTP/1.1 as a fallback. You can safely deprecate support for HTTP/0.9 and HTTP/1.0\. HTTP/0.9 was introduced in 1991 and HTTP/1.0 was introduced in 1996\. HTTP/1.1 was released the following year in 1997 with HTTP/2 not appearing until 2015\. Block any form submissions server-side that were sent over these legacy protocols. Many bots are incredibly poorly written and rely on primitive HTTP libraries. This measure is incredibly efficient at blocking the simplest bots.
**Append a `#hash` to the form’s action URL.** The action URL is the URL where the form submits data. This only requires a small change to your form and relies on weaponizing URL Standard-unaware clients’ [mishandling of URL #hashes](https://www.ctrl.blog/entry/recover-url-fragment-requests/). Bots will literally submit to the wrong URL whereas every browser will know exactly how to handle the situation.
**Include a hidden prefilled form field.** Bots are lazy and they might be bulk-submitting standard/common field names without bothering with the fields that are in your form. Include any hidden form field and check that it gets submitted to your server. There’s no need to waste resources trying to validate the rest of the form data if the data didn’t even originate from your form.
**Verify the Host and Origin request headers.** Bots frequently mess up or omit these request headers. They’re required with every form submission in modern browsers. They should match your website’s domain and scheme exactly; e.g. enforce the `https://` prefix and exactly match the host and origin of your form’s action URL.
**Set a test cookie and verify it gets included in the submission.** Bots frequently don’t bother with cookies, and the ultra-rare user who’ve disabled them completely are used to and know how to handle a broken web experience. You can use an HTTP response cookie for best compatibility, or a JavaScript cookie if you’re willing to display a “JavaScript required” message on your form.
**Swap the `name` attributes in the name and email fields.** Only bots will fill in these fields incorrectly, just swap the fields in your form and server-side validation. This approach is more effective than trying to obscure the field names because you can easily catch and block the malicious submissions.
To minimize the impact on users, set the appropriate `autocomplete` and `type` attributes for each field. These attributes will aid input on software keyboards and enable auto-complete and other functionality your visitors will expect. It makes it easier for bots to detect the misdirection, but they can already work out the correct order by string-matching your form’s human-readable labels.
**Verify the POST/Redirect/GET (PRG) chain.** PRG is a common pattern where a POST request is immediately redirected to a GET request. It helps prevent duplicate form submissions. All browsers will automatically follow redirects unless the user immediately closes the page or loses internet connectivity. You can include a token in a query parameter within the redirect request and verify that the token is sent back to the server.
You probably shouldn’t make blocking decisions based on this alone. Expect the occasional false positive, as described above. However, if the token isn’t returned within a couple of seconds, then it’s a strong indicator the submission was performed by a bot.
Those were my seven simple tips for detecting forms submitted by bots and not browsers. Here’s a bonus tip that requires a little more work to implement compared to the other tips.
**Block ancient versions of common browsers.**Bots often mimic the User-Agent of a common browser, but the version numbers used in the bots rarely change. Over time they drift farther and farther behind until a point (maybe two-year-old versions) where you can safely block them without inconveniencing legitimate users. GitHub just [published numbers](https://github.blog/2022-06-10-how-we-think-about-browsers/?ref=ctrl.blog "“How we think about browsers”") that show over 92 % of its visitors use the current browser version or are no more than 5 versions (roughly 20 weeks) behind.
I strongly discourage you from blocking or discriminating against unknown or uncommon browser User-Agent request headers. The web is weird and we as developers shouldn’t discourage it. However, you can take a sneak peek at it and identify the version number from the most common browsers. Armed with the [knowledge of the most recent versions of popular browsers](https://www.ctrl.blog/entry/latest-browser-versions-api/), you can block significantly outdated browsers.
In case of false positives, you should always display clear error messages to your users when you block their form submissions. Does your form require JavaScript, cookies, and a modern browser? Let them know! You may want to display a CAPTCHA or some secondary test to allow users to resubmit the form.
Do you know of any other unobtrusive bot detection methods? Share your ideas in the [comments](https://comment.ctrl.blog/discussion/detect-non-browser-form-submission?ref=ctrl.blog)!
### The Current Version of Popular Browsers API (powered by Wikidata)
URL: https://www.ctrl.blog/entry/latest-browser-versions-api/
Last updated: 2026-08-23T22:12:57.000Z
What’s the current stable version of Google Chrome, Firefox, and Safari? Your browser automatically checks for and keeps itself up to date. However, sometimes you need to find the latest version numbers for other uses. How do you get the latest version numbers of the most popular web browsers?
You could theoretically parse your server logs and get an approximate idea by observing the greatest of the most common version numbers. However, why bother to analyze and guesstimate data from logs when Wikidata (a sister project to Wikipedia) has the answer?
A quick plea before I proceed: Please don’t discriminate against people’s browser of choice. Don’t restrict access to your site or services based on the visitor’s User-Agent.
Mozilla is the only browser vendor that has an authoritative answer to the headliner question. You can query the current stable and extended support release of Firefox for desktop plus mobile releases through the [Product-Details JSON API](https://wiki.mozilla.org/Release%5FManagement/Product%5Fdetails?ref=ctrl.blog). Neither Apple nor Google offer a similar public API.
Fortunately, you can get the latest version information for all three from Wikidata. Wikidata is a linked data project from the Wikimedia Foundation (Wikipedia’s parent organization). The data is entered into the project by volunteers. These particular data entries don’t appear to use any automated sources or bots.
I analyzed Firefox’s release history and compared it to the Wikidata change history. I found that the wiki is usually never more than a few hours behind on releases. Past performance is not an indication of future performance (nor data reliance or stability). As the data source is a collaborative wiki, you can update it yourself if you spot a mistake or omission.
You can download data from Wikidata in any common linked metadata formats such as the Resource Description Framework (RDF). However, you don’t need to parse and extract the useful bits of data from the individual Firefox, Google Chrome, and Safari data entries on Wikidata.
Instead, you can use [this SPARQL query](https://query.wikidata.org/?ref=ctrl.blog#%23%20SPDX-License-Identifier%3A%20CC0-1.0%0A%0ASELECT%20%3FbrowserLabel%20%28max%28%3Fversion%29%20as%20%3FversionLabel%29%20%3FtypeLabel%0AWHERE%0A%7B%0A%20%20%3Fbrowser%20wdt%3AP31%20wd%3AQ6368%20%3B%20%20%20%20%20%23%20instance%20of%20web%20browser%0A%20%20%20%20%20%20%20%20%20%20%20p%3AP348%20%3Frelease%20.%20%20%20%20%20%20%23%20with%20a%20software%20version%20identifier%0A%20%20%3Frelease%20ps%3AP348%20%3Fversion%20%3B%20%20%20%20%20%23%20software%20version%20identifier%0A%20%20%20%20%20%20%20%20%20%20%20pq%3AP548%20%3Ftype%20%3B%20%20%20%20%20%20%20%20%23%20with%20a%20version%20type%0A%20%20%20%20%20%20%20%20%20%20%20wikibase%3Arank%20%3Franks%20.%20%23%20with%20a%20rank%0A%0A%20%20VALUES%20%3Fbrowser%20%7B%20wd%3AQ698%20wd%3AQ777%20wd%3AQ35773%20%7D%20%20%23%20Firefox%2C%20Chrome%2C%20and%20Safari%0A%20%20VALUES%20%3Ftype%20%7B%20wd%3AQ2804309%20wd%3AQ104243413%20%7D%20%20%20%20%20%23%20stable%20release%2C%20extended%20support%20release%0A%20%20VALUES%20%3Franks%20%7B%20wikibase%3APreferredRank%20%7D%20%20%20%20%20%20%20%23%20the%20PreferredRank%20is%20the%20current%20release%0A%20%20%0A%20%20SERVICE%20wikibase%3Alabel%20%7B%20bd%3AserviceParam%20wikibase%3Alanguage%20%22%5BAUTO%5FLANGUAGE%5D%2Cen%22%20%7D%0A%7D%0AGROUP%20BY%20%3FbrowserLabel%20%3FtypeLabel%0AORDER%20BY%20%3FbrowserLabel%20%3FtypeLabel) to round up the desired data in one API call. The link opens in the interactive Wikidata Query Service editor. Press the Run button to test the query and see its current output. Press the Link button to get a link to the SPARQL API endpoint for use in your application. You can hover predicates in the editor to look up their meaning.
The SPARQL Protocol and RDF Query Language (SPARQL, a recursive acronym) may be unfamiliar to you, but the response is a structured Extensible Markup Language (XML) document. It should be much easier to parse than the SPARQL query called to generate it!
You should absolutely log errors and trigger alerts if the API output changes (e.g. any missing/renamed fields). You probably shouldn’t rely on this API for anything business-critical (at least not without configuring logging and alerts).
Instead, you might want to consider using the [Browser Versions API](https://developers.whatismybrowser.com/api/features/web-browser-version-numbers?ref=ctrl.blog) from Long Way Research. (At least, you’ll have someone to yell at if it stops working or the data is outdated!)
Data from Wikidata is available under a permissive Creative Commons Zero license (a Public Domain deed). You don’t need to (but should) attribute the source. The API is free to use for any purpose, but make sure to cache responses and don’t be a hog. You should [donate monthly to the Wikimedia Foundation](https://donate.wikimedia.org/?ref=ctrl.blog) if the service creates value for your product or service.
### 5 options for auto-mounting network shares on MacOS
URL: https://www.ctrl.blog/entry/automount-netshare-macos/
Last updated: 2026-08-23T22:02:02.000Z
It can be annoying to have to constantly remount network drives and network shares. Some apps can fail to launch if they depend on files stored on an unmounted network share. Here are five different options for auto-mounting network share on MacOS.
MacOS supports a lot of different network share protocols: SMB, NFS, and WebDAV; plus the legacy AFP and FTP (read-only) protocols. All the options discussed in this article will be front ends built on top of what’s already built into MacOS.
I’ll list the different options in order of feature completeness and ease of use. What the best option is will depend on your needs and price sensitivity (most options are free).
The first and sleekest option is the [AutoMounter](https://automounter.app/?ref=ctrl.blog) app. It’s by far the most polished option, but it costs 10 USD on the Mac App Store. There is no free trial version available.
AutoMounter will attempt to mount all configured network shares when you log in to your Mac, wake it from sleep, or if the network conditions changes. It won’t attempt to reconnect shares if they disappear, and it has no options for retrying failed connections.
It can, however, attempt to power on devices that are kept in power-saving states using Wake-on-LAN (WoL). It’s also vaguely aware of your network condition and can be configured to only attempt to mount certain shares when connected to a named Wi-Fi network or when a Virtual Private Network (VPN) connection is available.
You can pay an additional 4 USD for “pro” features. These aren’t all too interesting, except for the option to customize the mount point. This feature lets you mount network shares anywhere on the filesystem and not just in the `/Volumes` directory.
If you’re looking to a free alternative to AutoMounter, then [ConnectMeNow](https://www.tweaking4all.com/os-tips-and-tricks/macosx-tips-and-tricks/connectmenow-v3/?ref=ctrl.blog) is your best bet. It’s donationware with similar capabilities to AutoMounter. Donationware means it’s free to download and use, but you’re strongly encouraged to donate any amount to the developer.
ConnectMeNow also supports WoL, and can optionally be configured to periodically attempt to reconnect unavailable connections. The app actively tries to discover if network shares are available on the current network by pinging the configured addresses.
Both AutoMounter and ConnectMeNow can leak information about your configured network shares on untrusted networks. As mentioned, AutoMounter can be made somewhat network aware based on Wi-Fi names (SSIDs).
Ideally, the apps should be network-aware and only attempt to connect on networks it recognizes and where it expects to find the configured shares. This should stop the data leaks and reduce the risks of you accidentally exposing your network share passwords. I left [a comment for the developer](https://www.tweaking4all.com/software/macosx-software/connectmenow-v3/?ref=ctrl.blog#comment-571577) of ConnetMeNow discussing this in more detail.
This is an inherent risk with any system that attempts to auto-mount a network share on an untrusted network. This is likely why this use case isn’t supported natively by MacOS. The two apps I’ve mentioned until now can be configured to at least attempt to not log in on untrusted networks. The remaining options do *not* and should be avoided (at least on laptops).
The third and probably simplest option to set up is to use a Login item. Start by mounting your network share as usual. Open the System Preferences app and go to Users & Groups: Login Items. Click the Plus button, select your network share, and press the Add button.
It won’t reconnect if your MacBook sleeps or you or the network share loses connectivity. This will also open a Finder window every time you power on your Mac. To avoid this last issue, you can use the following option instead:
The fourth option is to automate the mounting with AppleScript. You can find a complete [tutorial over at United PC](https://web.archive.org/web/20160623033204/https://www.united-pc.com/os-x-automatic-volume-mount/). It essentially boils down to pasting and customizing a small script into the built-in AppleScript Editor app, saving it as an app, and adding that new app to your login items.
The fifth and last option is the `autofs` subsystem. This is only suitable for advanced users. The `autofs` subsystem reverts all configuration changes after system upgrades. Back up your configuration! I’ll not instruct you on how to set this up. Instead, type man 5 auto\_master in the Terminal app and review the program’s manual page.
At the close, I’d just like to mention the [Mountain Duck](https://mountainduck.io/?ref=ctrl.blog) app. It does what’s discussed in this app but for cloud storage drives such as Dropbox, Google Drive, and Microsoft OneDrive. It doesn’t work for any of the protocols discussed in this article, however.
### How to stop a robot vacuum from getting stuck on the laundry rack
URL: https://www.ctrl.blog/entry/robot-vacuum-drying-rack/
Last updated: 2026-08-23T22:20:39.000Z
My robotic vacuum loves to ram itself onto and get stuck on my laundry drying rack. It has been doing it for years, and I haven’t had a good solution to the problem. Until now.
I’ve kept the Roomba out by putting boxes and other obstacles underneath the laundry rack. The robot is surprisingly strong and often manages to push them out of the way.
I’ve also attempted disastrous solutions involving lots of duck tape wrapped along the length of the bottom tubing. I essentially tried to form an admittedly soft physical barrier with the tape. It looked hideous and didn’t even work all that well.
Last week, I stumbled upon a much better solution. While looking for something completely unrelated, I found the 3D-printing recipe for a freely licensed [laundry rack raiser](https://www.printables.com/model/151700-laundry-rack-raiser-for-vacuum-robot-minimal-16mm-?ref=ctrl.blog). It’s just a set of feet you can camp on to the bottom tubing on a laundry rack.
It’s an ingenious solution. The laundry rack just needs to be lifted up from the floor enough for the bottom tubing to form a barrier tall enough to trigger the robot’s collision sensor.
I don’t own a 3D printer and the first available slot at the community 3D printer was in eight weeks. However, I didn’t need this precise plastic gadget to solve my problem.
I explored different other options for feet and adhesives. The best and simplest solution that got the job done turned out to be twine. I just spun a twine ball around the existing tiny plastic feet to pad the height about 20 mm. This raises it enough to trigger the collision sensor.
*Success!* The solution is completely obvious in hindsight but yet it managed to avoid me for the 13 years I’ve owned a robotic vacuum cleaner.
### Split keyboards give your hands a break but reduce typing flexibility
URL: https://www.ctrl.blog/entry/split-keyboard-accessibility/
Last updated: 2026-08-23T22:22:23.000Z
**Sponsored:** Dygma Labs provided its Raise keyboard for free. It had no editorial control of this article.
Split keyboards can offer greater flexibility and variety for your working posture and desktop arrangements. I’m talking about both wave keyboards that bend upward in the middle (typically branded as “ergonomic keyboards”) and keyboards that can literally split in two. However, you better agree with its designers on how to best use a keyboard.
Dygma Labs sent me one of its Dygma Raise split mechanical keyboards ([full review](https://www.ctrl.blog/entry/review-dygma-raise-split-keyboard/)). It’s a 64 % keyboard that can optionally be split down the middle, creating two single-hand keyboard surfaces. A 64 % keyboard is a variation on the more standard 60 % keyboard (no function keys, navigation keys, or a numpad) featuring some non-standard extra keys. The Raise has split the space bar into four keys and has also included four extra “thumb buttons” below those keys. You can position the two halves as you want to suit your needs.
As discussed in [my keyboard sizing guide](https://www.ctrl.blog/entry/keyboard-form-factor-guide/), a wider keyboard setup is best suited for people with broad shoulders. It may be more comfortable to split the keyboard to increase the distance resting position distance between your arms. However, the same wider setup may be uncomfortable for someone with narrow shoulders. People are different and so should our keyboards be.
Split keyboards might also be a suitable alternative for gamers — regardless of their body type — who might not need the right half of their keyboards. Many games are optimized for the right-hand holding the mouse and the left hand resting on the WASD keys. The WASD keys are used as arrow keys to move either the camera or a character around. They’re preferable to the actual arrow keys as they have more keys that can be used as hotkeys in the immediate vicinity. Few games bind common actions to keys on the right side of the keyboard. Getting rid of the left half of the keyboard leaves more room for better postures and for working with the mouse.
Split keyboards, including the Dygma Raise, are often marketed as explicitly being more ergonomic than your typical keyboards. That might be the case for some people. However, there’s a big limitation with these keyboards; and that’s the big old question: “where’s the middle of the keyboard?”
Keyboards are always split along the hand-separation rules commonly used with the touch-typing (“blind typing”) method. When typing with the touch-typing method, you’re not supposed to move your hands off their resting position. From each hand’s resting position, each finger can reach a couple of keys with a minimal amount of movement.
Split keyboards enforce the rules of the touch-typing method by design. There’s some leeway to make adaptations within each hand’s key responsibilities, but you’re out of luck if those adaptations cross the split keyboard divide.
Your left index finger should handle the B key and the right index finger should handle the Y key. However, which finger handles which key is an arbitrary decision. You may have been taught a different style or just prefer it the other way around.
I’ve got reduced mobility in my right index finger and compensate for it by using my left index finger to press both the B and Y keys. I ripped open my finger on a rusty nail while tossing planks into a lake. Childhood activities can be dangerous, kids! The scar looks amazing, but I can’t fully extend my finger during the chilly winter months. It’s never a problem when I use a regular keyboard, so I never think of it as a disability.
Stiffness and reduced finger mobility can also be caused by any number of conditions. People who suffer from finger arthritis are fortunate if it only affects one finger.
The design of split keyboards imposes an accessibility barrier that isn’t there with regular keyboards. The touch-typing method is meant as a best practice for reducing hand strain and not as a hard requirement. Split keyboards assume you’re using the touch-typing method and have a set of fully functional fingers on both hands.
For something to be truly ergonomic, it needs to be adjustable and adaptable to fit different people and needs. Split keyboards could be made more accessible in one of two ways:
They could duplicate the B and Y keys on both halves. This is impractical on something like the Dygma Raise that can be put together to form a regular keyboard. However, it’s a solid option for permanently split or wavy keyboards.
Alternatively, the B and Y keys could be made detachable and movable between the two sides. This design would clearly be more expensive, but it would also make split keyboards usable by more people.
Before you purchase a split keyboard; you should be conscious about how you type, and which fingers perform different tasks around the keyboard.
### Improve legibility and reduce layout shifts with x-height adjustments
URL: https://www.ctrl.blog/entry/font-size-adjust/
Last updated: 2026-08-23T22:07:28.000Z
There’s more to setting the text size on your webpages than just the CSS `font-size` property. It only controls the size of majuscule (“uppercase”, e.g. “A”) letters, numbers, and punctuation. The size of minuscule (“lowercase”, e.g. “a”) letters is left up to the font. A font’s minuscule size metric is referred to as x-height; the height of an “x” letter. However, you can control the size of the two independently — and here’s why you might want to do that.
The `font-size-adjust` property compliments the `font-size` property by letting you override the font’s x-height. Its value is a multiplier applied to latter to the `font-size`. For example, the CSS snippet `font-size: 16px; font-size-adjust: 0.5;` sets the x-height to 8 px.
Unfortunately, `font-size-adjust` is only supported in Firefox. It has been supported by this browser for over a decade already. It was implemented in Chrome for almost half a decade, but it has been left to rot behind the Experimental Web Platform features flag. It’s not implemented in Safari.
There’s another way that’s supported cross-browsers that lets you achieve even better results. However, I first need to explain the two main use cases for *why* you might want to adjust a font’s x-height.
The first use case is to increase legibility with your preferred font. A taller x-height (to a point) can increase reading speed, lower error-rates, and benefit readers with reduced vision. Tall x-heights leaves more room for each letter; which is especially beneficial for common double-story letters like the minuscule “a” and “e” that can otherwise appear cramped. Special-purpose fonts optimized for dyslexic readers feature a taller-than-normal x-height. However, [a notable study](https://www.ncbi.nlm.nih.gov/pmc/articles/PMC5934461/?ref=ctrl.blog) concluded that these fonts are no better than traditional fonts when accounting for the different x-heights.
Common fonts, such as the pre-installed fonts on most operating systems (“system fonts”), typically feature a low x-height. Depending on your stylistic font preferences, you might just want to bump up the x-height to improve the reading experience.
There’s now a medium-sized confused-looking elephant in the room, though. Why can’t you simply set a bigger `font-size` if you want the text to be bigger and more readable? The most commonly used fonts today, the typical system fonts based on their broad availability, are based on digitalization efforts of decades-old font designs.
Today, there’s simply a different design and reading preference when it comes to the size-relation between majuscule and minuscule letters. More recent font faces — such as Google’s Roboto, designed for a varying quality of mobile-display technologies — feature a tall x-height.
The other use case is to better match a fallback font, such as a system font, to your preferred font, such as a web font. It can also be useful to normalize the reading experience across a system font stack based on a selection of metrically diverse fonts. It’s particularly useful when mixing letters from more than one font, such as a text font and a symbols font.
This use case might even apply if you only rely on system fonts. For example, the sans-serif fonts Helvetica and Arial look roughly 10 % larger than serif Times and Times New Roman at the same `font-size`.
To meet the requirements of these use cases, you need to individually adjust the sizes of each font face. Enter the `@font-face { size-adjust }` property. It lets you override a given font face’s x-height by a given percentage value. Using a variable font? Check its documentation if it supports adjusting the x-height through `@font-face { font-variation-settings }` parameter. The `size-adjust` parameter might be ignored if it conflicts with the font’s internal settings. For example, `size-adjust: 105%` to increase the minuscule size by 5 %.
Both Firefox and Chrome added support for this property at the end of 2021\. There’s no support in Safari yet. However, this is still the best cross-browser method.
Okay, back on track. Here’s a quick example using [the perfect cross-platform sans-serif font stack](https://www.ctrl.blog/entry/font-stack-text/) (a cross-platform set of metrically compatible fonts) where I’ve increased the minuscule size by 5 %. Roboto, the only font available on Android, was designed with a taller x-height than the others. So, it needs to be tuned separately to match the other fonts.
```css
@font-face {
font-family: "helveticas-adjusted";
src: local("Helvetica Neue"),
local("Arial Nova"),
local("Liberation Sans"),
local("Helvetica"),
local("Arial");
size-adjust: 105.2%;
}
@font-face {
font-family: "roboto-adjusted";
src: local("Roboto");
size-adjust: 104.4%;
}
body {
font-family: "helveticas-adjusted",
"roboto-adjusted",
sans-serif;
}
```
The example shows that this is quite a bit more complex than the simpler single `font-size-adjust` parameter. However, it lets you optimize individual fonts for optical sizes rather than being constrained to a single absolute size for all fonts.
You can extrapolate from this example into more complex font stacks. Here’s an alternative featuring an ordered list of my favorite serif system fonts from Windows, MacOS, and Linux. Their sizes vary considerably, but the `size-adjust` parameter normalizes their x-heights to be the same as the above sans-serif font stack.
```css
@font-face {
font-family: "constantia-adjusted";
src: local("Constantia");
size-adjust: 117.6%;
}
@font-face {
font-family: "hoefler-text-adjusted";
src: local("Hoefler Text");
size-adjust: 121.6%;
}
@font-face {
font-family: "charter-adjusted";
src: local("Charis SIL"),
local("Charter Roman");
size-adjust: 112%;
}
@font-face {
font-family: "times-adjusted";
src: local("Liberation Serif"),
local("Tinos"),
local("Times"),
local("Times New Roman");
size-adjust: 115.4%;
}
@font-face {
font-family: "palatino-adjusted";
src: local("Domitian-Roman"),
local("P052-Roman"),
local("Palatino"),
local("Palatino Linotype");
size-adjust: 116%;
}
p {
font-family: "constantia-adjusted",
"hoefler-text-adjusted",
"charter-adjusted",
"palatino-adjusted",
"times-adjusted",
serif;
}
```
At first glance, this appears like quite a lot of style sheet bytes. It’s almost 1 kB uncompressed and 0,3 kB compressed by itself. You can expect the compressed size to shrink considerably when included as part of a larger style sheet. At any rate, it’s a tiny amount of data to fix up and normalize some system fonts compared to downloading a webfont file. Webfonts in 2022-Q1 had a median file size of 141 kB, according to the HTTP Archive.
Okay, so I’ve glossed over one subject so far: how do you figure out the number value for the `size-adjust` property for different fonts? Start by selecting your fonts and arranging your font stack. Once you’ve nailed it down, you can start measuring your fonts.
Adjust your primary font’s x-height until you get the size you want. In this article, I’ve argued for increasing x-heights to improve readability. But it’s your show: maybe you’re happy with your font’s default.
Create a test page with a minuscule “x” letter in three different sizes. Use your normal body text size, your headline size, and one extra-large size. Do the same for the font you want to size-match and overlay it on top of your reference size. It’ll be easier to compare the two if you assign the sets distinct colors.
Adjust the `size-adjust` property until the two match each other’s height (sans any serifs/ornamentation). It takes a bit of trial and error, but it shouldn’t take much time. It’s super-quick to repeat the process with different fonts after you’ve done it once.
You can find specialized tools to automate the job, but I wasn’t happy with the results and preferred doing it by hand. Automated tools may pick a mathematically optimal size adjustment, but it will fail to account for any perceived optical size differences between two fonts.
Once you’re done, you should double-check your design to make sure you’ve set aside sufficient line heights! The character boxes for your font’s minuscule characters will be stretched to accommodate their adjusted size. The new character box sizes will be the point size (`font-size`) multiplied by the `adjust-size`, e.g. 16 px \* 106.25 % = 17 px. Your `line-height` must be at least that tall plus leave enough room for comfortable reading.
This technique can significantly reduce layout shift and other eyesores when a fallback font is displayed initially and then later swapped out for a webfont (`font-display: swap` or `font-display: fallback`).
Okay, so what about Safari? Your only two options are to either set a larger `font-size` or to pick a font with a tall internal x-height. The open-source *Merriweather* font by Sorkin Type delivered as a webfont is one such alternative. However, you’re back to square one when it comes to its fallback font.
You may also want to avoid using MacOS and iOS system fonts with short x-heights, such as Hoefler Text. Users on iOS are forced to use Safari and users on MacOS are likely to use Safari until [WebKit bug #229726](https://bugs.webkit.org/show%5Fbug.cgi?id=229726&ref=ctrl.blog) is resolved. This isn’t a critique of that font design, but it’s unsuitable as its x-height requires significantly more upscaling than other fonts.
The issue with Safari highlights the importance of the `size-adjust` technique discussed in this article. It lets *you* decide what font you want to use, and adopt it to your needs; rather than the other way around.
#### Sources
- [font-size-adjust](https://developer.mozilla.org/en-US/docs/Web/CSS/font-size-adjust?ref=ctrl.blog), 2022-04-05, CSS, Web Docs, Developer Network, Mozilla
- [Report: Page Weight](https://httparchive.org/reports/page-weight?start=2022%5F01%5F01&end=latest&view=list&ref=ctrl.blog#bytesFont), 2022-04-04, HTTP Archive
- [CSS Fonts Module Level 5](https://www.w3.org/TR/2021/WD-css-fonts-5-20211221/?ref=ctrl.blog), 2021-12-21, Working Draft, World Wide Web Consortium (W3C)
- [Bug #229726: Implement font-face override descriptors](https://bugs.webkit.org/show%5Fbug.cgi?id=229726&ref=ctrl.blog), 2021-08-31, Myles C. Maxfield, Issue tracker, WebKit, Apple
- [Dyslexie font does not benefit reading in children with or without dyslexia](https://www.ncbi.nlm.nih.gov/pmc/articles/PMC5934461/?ref=ctrl.blog), 2017-12-04, Sanne M. Kuster; Marjolijn van Weerdenburg; Marjolein Gompel; and Anna M. T. Bosman, PubMed Central, US National Library of Medicine
- [Bug #15257: \[CSS3 Fonts\] Support font-size-adjust](https://bugs.webkit.org/show%5Fbug.cgi?id=15257&ref=ctrl.blog), 2016-01-21, Issue tracker, WebKit, Apple
### Syncthing: The data deduplication master
URL: https://www.ctrl.blog/entry/syncthing-deduplication-master/
Last updated: 2026-08-23T22:22:53.000Z
[Syncthing](https://syncthing.net/?ref=ctrl.blog) is an open-source encrypted peer-to-peer folder synchronization program. It uses deduplication techniques to reduce the amount of data it needs to transfer over the network; saving you bandwidth costs, energy, and time. You can now optionally also let it deduplicate data storage to reduce your storage costs.
You can think of Syncthing as cloud storage service like Dropbox or OneDrive but without any intermediary servers or costs. Your files are transferred directly among your devices. It lets you safely synchronize folders without having to trust a cloud storage provider with your data.
Syncthing chunks large files into blocks, similar to how a file system works. It compares which blocks have changed and will only send changed blocks over the network. The blocks can be reused between files and even between different synced folders. This saves transfer time, network bandwidth, and energy.
Syncthing collects usage data from its users. Among the collected data, it records how much data transfer is reduced because of this feature. As of the time of publishing, 56,48 % of synced data was reused from local files. The potential savings of Syncthing’s storage deduplication feature can be assumed to be near this figure.
The storage deduplication feature re-purposes this bandwidth-saving feature to save local disk space. The same mechanism is used to reuse identical on-disk blocks between files.
The feature can significantly reduce the disk space consumed by Syncthing’s file version system. File versionings preserves copies of modified files. This is likely why the deduplication rate in Syncthing’s network is so high. Depending on your usage and files, you may only make slight changes to your files. Syncthing might only need to store two different blocks of changed data instead of storing the entire file twice. This approach can be incredibly efficient with virtual machine disk files, log files and archive files where you append data on the end, and other append-only data structures.
The feature is supported on [most file systems that support cloning](https://www.ctrl.blog/entry/file-cloning/); including Btrfs, XFS, and EXT4 on Linux and Solaris, and ReFS on Windows. NTFS is the default file system on Windows. ReFS is only available in Windows Workstation and Server editions.
Neither the OpenZFS nor ZFS file systems are supported as they don’t expose any appropriate system calls (syscall). MacOS’ APFS isn’t supported either despite its `clonefile` syscall. This syscall can only clone whole files, unlike the block-level cloning available on Linux and Solaris.
The feature has the same limitations as normal file cloning. Clones must be created on the same disk/partition and cannot cross file system/partition boundaries. This limitation can lead to syncing errors as Syncthing can reuse blocks across synced folders and isn’t aware of file system boundaries.
Storage deduplication isn’t enabled by default, as of Syncthing version 1.19.1\. You can enable it per folder or set it as the default behavior from the Advanced settings dialog. Look for the Copy Range Method option and set it to a [supported value](https://docs.syncthing.net/advanced/folder-copyrangemethod.html?ref=ctrl.blog).
I recommend explicitly setting the option to `ioctl` (uses the `FICLONERANGE` syscall) on Linux as the `copy_file_range` option/syscall has caused me reduced system stability. The special `all` option first tries `ioctl`, then other methods, before eventually falling back to a regular copy. This option can reduce syncing errors (see the previous paragraph) but may cause system instability by calling `copy_file_range`.
The deduplication feature was added in Syncthing version 1.8.0 (July 2020) and is still considered experimental. It’ll probably remain that way for some time, as there’s a chance the functionality might introduce a bug that results in dataloss.
#### Sources
- [Data transfers totals to date](https://web.archive.org/web/20220505155823/https://data.syncthing.net/#totals-to-date), 2022-05-05, Usage Data, Syncthing, Wayback Machine (date snapshot), Internet Archive
- [\[copyRangeMethod\] invalid cross-device link](https://github.com/syncthing/syncthing/issues/8271?ref=ctrl.blog), issue #8271, 2022-04-12, Syncthing project, GitHub
- [Understanding Synchronization](https://docs.syncthing.net/users/syncing.html?ref=ctrl.blog), 2021-07-31, Documentation, Syncthing
- [copyRangeMethod](https://docs.syncthing.net/advanced/folder-copyrangemethod.html?ref=ctrl.blog), 2020-08-08, Advanced, Documentation, Syncthing
- [New copy-on-write stuff should support Darwin clonefile](https://github.com/syncthing/syncthing/issues/6755?ref=ctrl.blog), issue #6755, 2020-06-18, Syncthing project, GitHub
### The auto-save feature in GEdit vs the new GNOME Text Editor
URL: https://www.ctrl.blog/entry/gnome-text-editor-auto-save/
Last updated: 2026-08-23T22:08:32.000Z
I recently compared [GEedit’s auto-save to Kate’s swap-save feature](https://www.ctrl.blog/entry/kate-swp/). Both features try to achieve the same goal — to protect your unsaved work from power failures and crashes — but through different means.
The new GNOME 42 release replaces GEdit with [GNOME Text Editor](https://apps.gnome.org/app/org.gnome.TextEditor/?ref=ctrl.blog) (GTE) as the recommended default text editor. GTEd also has a feature like Kate’s swap-save, so I thought I’d revisit the topic.
GEdit has a feature to periodically auto-save your documents (off by default). The option does what it says on the tin: it automatically overwrites your saved document every couple of minutes. You can undo and restore earlier versions until you quit GEdit.
This approach is potentially destructive and can cause you to irrecoverably lose data. It’s a poor implementation mimicking Apple’s TextEdit app on Mac. TextEdit auto-saves your changes, yes, but it also keeps older versions of your documents. You can restore earlier versions of your documents in case you’ve overwritten something you didn’t intend to.
GEdit doesn’t have this, it just overwrites your documents — no questions asked. You can pair it with an external version-tracker tool, but the app doesn’t offer anything.
The new GTEd has a feature that more closely resembles Kate’s swap-recovery system. To recap, Kate store’s a “swap copy” of the unsaved working copy of your files next to the primary copy on your file system. The swap copy is deleted when you save your file, or when you exit Kate and confirm that you want to discard the unsaved changes. If Kate or the system crashes, Kate detects the swap copy and offers you to restore it.
GTEd’s auto-saving feature works more similarly to Kate than GEdit. Kate doesn’t save unsaved files; it only keeps swap copies for changes to files that have been saved at least once. GTEd saves every change in a swap copy, even for unsaved/draft files.
Unlike Kate, it’s stored in the program’s data directory instead of in the same directory as the saved file. GTEd’s approach keeps your directories clean of the hidden “dotfiles” that contain the swap copies. Some may prefer Kate’s approach as it works better with files stored on network shares.
Crucially, when GTEd detects unsaved work, it asks you if want to discard or restore it. However, you may be unclear about what you’re about to restore and what you’ll discard. Kate offers you to compare the two versions (the swap/working copy and the on-disk saved file). GTEd assumes you’re intimately familiar with the two versions; even though you’re not being shown either and have no information to make an informed decision on which to preserve.
Kate doesn’t handle this perfectly either. It differs from an external tool, such as KDIff, to make the comparisons. It should display it internally, so it would be clearer which version is which.
The auto-saving feature is enabled by default in GNOME Text Editor version 41 and newer. You can disable it from the Settings dialog: Behavior: Restore Session. Sort of.
You actually only disable the user interface prompts. Your unsaved documents are still saved to the program’s data directory. You’re not even prompted to restore them even if the app crashed. Since you’re never prompted to decide to discard the drafts, they just keep piling up in the data directory.
GTEd’s auto-save feature has many more bugs. E.g., you can open the same file in multiple windows and make conflicting changes; which makes it random which changes are preserved and which get discarded. Restoring a session with multiple windows with the same file will put you in a state where you can’t close the windows.
Frustratingly, discarded/deleted files and changes may reappear in your next session even if you selected to discard them in the previous session. This isn’t just frustrating but could potentially expose data you wish was never saved to disk. This is kind of out of your control anyway, as you can’t fully disable the behavior.
GNOME Text Editor version 42 reviewed. The projects mentioned here are logged in the project’s bug tracker.
### Common mistakes in BIMI early-adopter implementations
URL: https://www.ctrl.blog/entry/bimi-adoption/
Last updated: 2026-08-23T22:02:10.000Z
Two weeks ago, [I wrote about the new Brand Indicators for Message Identification](https://www.ctrl.blog/entry/bimi-intro/) (BIMI) *draft* internet standard. BIMI enables businesses to get their logos displayed next to their email messages in compatible email apps and webapps. As part of the research for that article, I queried the top 3 million domains to see how many had adopted the standard. I found 6647 domains with a default brand indicator, but far from all meet the BIMI requirements.
I only tested pay-level domains (e.g. `example.com`) and not subdomains. I only evaluated the default domain-level brand indicator (e.g. `default._bimi.example.com`. Domains may use other brand indicators, e.g. the [Ctrl blog newsletter](https://www.ctrl.blog/follow.html) uses `newsletter._bimi.ctrl.blog`. However, I can’t guess what the indicators might be without examining an outgoing email message from the domain. Domains like Ctrl blog without a default BIMI won’t be included in these results.
I queried the domain name system (DNS) for the default BIMI records for the top 3 million domains. I evaluated the responses, and fetched the BIMI image for domains with a valid BIMI record. I also evaluated other email policy DNS records used by BIMI; including Domain-based Message Authentication, Reporting, and Conformance (DMARC) and Sender Policy Framework (SPF). The DomainKeys Identified Mail (DKIM) records were not evaluated because this would require me to examine an email message sent from the domain.
Okay, on to the results! As mentioned, I found 6647 BIMI-like DNS records. This means any DNS text (TXT) record that contained the magic eyecatcher string `v=BIMI1`. The presence of that string was assumed to be an intention of wanting to publish a BIMI.
198 domains contained the magic string but didn’t match the required syntax. Almost all syntax errors contained the full line from the DNS zone file as the value in the TXT record. 6 contained a serialized JSON version of the expected DNS record.
BIMI has a few specific requirements for the image file indicated by the BIMI record. The image files must be square SVG version 1.2 image with the SVG Tiny Portable/Secure (Tiny-PS) profile. The image should work with a square and circle mask applied.
2156 domains linked to SVG images that didn’t use the Tiny PS profile. This was the most common problem with all the published BIMI records. 2002 of the images could have met the requirements of the Tiny-PS profile as-is with the addition of the required metadata.
1074 of the SVG images weren’t square. The median proportion of these images was 4:1\. Anecdotally, most of the square images contained a rectangle with a lot of vertical padding. 1404 images would cut off pixels other than the background color when applying a circle mask. (I’m not 100 % confident about my test methodology on this last metric.)
702 images were irretrievable with a web browser-like `User-Agent`. HTTP 404 Not Found was the most common error, followed by Cloudflare protection pages. An additional 5 images were irretrievable with a mail-agent like `User-Agent`.
73 domains linked to PNG and 2 to JPEG bitmap image files instead of SVG vectors as required by BIMI. 479 image files contained bitmaps within the SVG container.
17 domains served their images over the HyperText Transfer Protocol (HTTP) instead of Secure HTTP (HTTPS) as required by BIMI. 1 domain served the image over the legacy File Transfer Protocol (FTP). FTP support was removed from web browsers in 2020\.
42 domains contained explicit opt-outs. A BIMI opt-out is a valid BIMI record that contains an image address that points to an empty string. Publishing an explicit opt-out is essentially pointless, but it might enable clients to make better and longer-lasting caching decisions.
1343 domains had not published a DMARC policy. 308 domains had a too weak DMARC policy. All but 1 domain with a DMARC policy that contained a provision about SPF had published an SPF policy. 2708 domains contained a weak SPF policy (didn’t end with `-all`).
As mentioned in [my earlier article about BIMI](https://www.ctrl.blog/entry/bimi-intro/), Google Mail (GMail) requires that BIMI records also publish a Verified Mark Certificates (VMC). A VMC is a certificate file that is cryptographically signed by a Certificate Authority (CA). The CA verifies that the BIMI image is a logo that is a registered trademark belonging to the domain owner.
988 domains included a VMC parameter in their BIMI records. 568 linked to a certificate file as required by BIMI. I did not evaluate the validity of these certificates. 420 domains contained a VMC parameter with “self” as the value, presumably a left-over from an earlier draft of the BIMI standard.
Only 2324 domains (34,9 %) met all the requirements (excluding VMC). Apps and services consuming BIMI records can make their own decisions about which requirements to enforce. As mentioned, only GMail requires VMCs. Given these results, it would make sense to lift the SVG Tiny-PS profile requirement and apply a server-side conversion process.
Curious about your domain? You can check conformance and preview your image within the context of an email inbox (with a square and round mask) using the [BIMI Inspector](https://bimigroup.org/bimi-generator/?ref=ctrl.blog). The same tool can be used to generate a BIMI record.
#### Sources
- DNS survey performed on 2022-04-18.
- [Tranco list ID W9VK9](https://tranco-list.eu/list/W9VK9/full?ref=ctrl.blog), 2022-04-18, Tranco
- [General Guidance for Implementing Branded Indicators for Message Identification (BIMI)](https://datatracker.ietf.org/doc/html/draft-brotman-ietf-bimi-guidance-05?ref=ctrl.blog), Draft #5, 2022-04-11, Network Working Group, Internet Engineering Task Force
- [Brand Indicators for Message Identification (BIMI)](https://datatracker.ietf.org/doc/html/draft-blank-ietf-bimi-02?ref=ctrl.blog), Draft #2, 2021-03-08, Network Working Group, Internet Engineering Task Force
### Ruby 3.1’s incompatible changes to its YAML module (Psych 4)
URL: https://www.ctrl.blog/entry/ruby-psych4/
Last updated: 2026-08-23T22:21:29.000Z
The Ruby programming language released version 3.1 back in December 2021. Among the changes was a big update to Psych version 4.0, Ruby’s built-in YAML Ain’t a Markup Language (YAML, a recursive acronym) interpreter. A major version change indicates incompatible changes, and version 4 sure does deliver on that promise.
It broke everything from modules in the Ruby standard library and major frameworks like Ruby on Rails, to [Nanoc](https://nanoc.app/?ref=ctrl.blog): the static-site generator powering this blog. Let’s dive in and explore the changes!
For over a decade, Psych’s `load()` and `load_file()` method have (in practice) been aliases for the `unsafe_load()` and `unsafe_load_file()` methods. In version 4, these methods have changed to their `safe_` prefixed equivalents by default.
A safe load is better than an unsafe one, right? Yeah, it’s probably a good call to change the default. However, it has also broken a large number of Ruby packages.
Developers use the `load()` and `load_file()` method because they intuit its name and it works. (Intuitive method names are one of the Ruby language’s core strengths.) If developers had been aware of the `safe_load()` and `safe_load_file()` methods, they’d probably use them instead.
So, what’s the difference between the safe and unsafe methods? The former has a stricter syntax parser and won’t serialize as many data types as the latter does by default. The stricter parser is a better choice when loading untrusted and potentially malicious YAML files. (Interpreters are always at risk of misinterpreting unexpected data.)
Your use of YAML may be unaffected, or your program might fail after upgrading to Psych 4\. Here are some highlights of the differences between `safe_load()` and `unsafe_load()` in Psych 4:
- `safe_load()` disallows YAML aliases (a potentially recursive data structure) by default (override with the `aliases: true` argument).
- `safe_load()` only deserializes a handful of default classes (below; extend the list with the `permitted_classes: [Class]` argument).
Here‘s the default list of serializable classes when running in safe mode:
- `TrueClass`
- `FalseClass`
- `NilClass`
- `Integer`
- `Float`
- `String`
- `Array`
- `Hash`
That should have your basics covered, right? Well, you might not have noticed, but the class list is missing the `Date` and `Time` classes. Many programs also expect Psych to serialize `Symbol`.
Almost everything I’ve ever used YAML for in Ruby includes a date or time object. If you do try to load a YAML file containing a date, you’ll now get the following error message:
Psych::DisallowedClass: Tried to load unspecified class: Date
This is the same error you’d get with earlier versions if you explicitly used the `safe_load()` methods without allowing the classes. You can extend the list of allowed classes by adding a `permitted_classes: [Date]` argument. It’s not a big deal to add the argument once, but let’s just say I’ve had to add it to a lot of places after the update.
To further complicate matters, Psych 4 dropped support for legacy positional arguments and now requires the use of named arguments. If you used to rely on `safe_load(yaml, [Date])`, you now need to migrate to `safe_load(yaml, permitted_classes: [Date])`.
The change away from positional arguments had been noted in the Psych module documentation for some years already. However, the software itself never issued deprecation warnings.
I believe the changes in and of themselves are good. The changes came from a good place and nothing but good intentions. However, the execution and introduction of incompatible changes were poorly handled.
Ideally, Psych should have printed warnings to standard error output (STDERR) to notify developers of the upcoming changes. Developers should have been given a heads-up warning and time to migrate. Instead, developers probably first noticed the changes when their programs stopped working.
#### Sources
- [Ruby 3.1.0 Released](https://www.ruby-lang.org/en/news/2021/12/25/ruby-3-1-0-released/?ref=ctrl.blog), 2021-12-25, Yui Naruse, News, Ruby
- [Psych module](https://ruby-doc.org/stdlib-3.1.0/libdoc/psych/rdoc/Psych.html?ref=ctrl.blog), version 3.1, 2021-12-25, Std-lib, Ruby doc
- [Issue 17866; Incompatible changes with Psych 4.0.0](https://bugs.ruby-lang.org/issues/17866?ref=ctrl.blog), 2021-12-21, Hiroshi Shibata, Issue Tracker, Ruby
- [Pull request: 487: Use Psych.safe\_load by default](https://github.com/ruby/psych/pull/487?ref=ctrl.blog), 2021-05-13, Aaron Patterson, Ruby Psych project, GitHub
- [Psych module](https://ruby-doc.org/stdlib-3.0.0/libdoc/psych/rdoc/Psych.html?ref=ctrl.blog), version 3.0, 2020-12-25, Std-lib, Ruby doc
### SELinux is unmanageable; just turn it off if it gets in your way
URL: https://www.ctrl.blog/entry/selinux-unmanageable/
Last updated: 2026-08-23T22:21:51.000Z
Security-Enhanced Linux (SELinux) is a type of Mandatory Access Control (MAC) in the Linux kernel. It can prevent software from performing unexpected — such as abusive or malicious actions — on your Linux systems. However, … it’s also an unmanageable mess, and I have a much greater understanding of why people recommend that people disable it.
SELinux is one of many layers of security that helps protect your Linux servers (and desktops) from the lions, and tigers, and bears — *oh, my!* SELinux policies specify which programs, sockets, and files are allowed to interact with each other. It requires everything on the system to be properly labeled with a security context that gets enforced through a policy that maps which labels are allowed to interact.
That might all sound like gobbledygook. Okay, here’s a concrete example: The Lighttpd web server executable is stored at `/usr/sbin/lighttpd` and is labeled with labeled `httpd_exec_t`. It reads files from `/var/www/` which are labeled as `httpd_sys_content_t`. Every time Lighttpd wants to read a file, the Kernel checks the current policy set and verifies that `httpd_exec_t` is allowed to read files labeled `httpd_sys_content_t`. The Kernel denies the read if it isn’t and logs a policy denial.
Everything happens, mostly, invisible to the system administrator (sysadmin). Everything works seamlessly unless the sysadmin tries to do something not allowed by the current set of policies. Now, most sysadmins are probably not aware of SELinux nor its policy set until they can’t achieve something because it violates the policies.
People then seek advice on the web on how to fix the problem. I’ve always cringed at what I’ve perceived to be inexperienced users suggesting to others that they disable SELinux — which is a terrible idea, right? The right solution is to learn about SELinux, and then make a tiny tweak to the policies to specifically allow what they want to achieve.
I can’t provide easy-to-follow steps on how to solve the problem, though. You need to learn a full set of tools to have any hope of adjusting things. There are very few good documentation sources available that describe SELinux and how to manage it.
It doesn’t help that no one wants to be told: “stop what you’re doing, spend a week to learn this other thing, make a tiny change, and then return to your real job”. They’re looking for solutions — preferably quick ones — and not a week’s worth of study.
Over time, I’ve realized that the advice to turn it off isn’t necessarily bad advice. Either SELinux won’t give you any problems as you stay within the parameters of the system policy, or you need to decide between learning a complicated subject or turning off a security feature.
At the heart of the problem is that the SELinux policies themselves are sort of magical. The policies have probably been provided by the maintainers of your Linux distribution, e.g., Fedora Linux. There’s nowhere on the system where you can view the policies and look up why something might or might not work. The policies also change over time, without any warning.
Whatever the reason, you’ll likely encounter some software that stops working after a system update or after you’ve changed its configuration. The change resulted in an SELinux enforcement action causing something, like a file read operation, to be denied on the system.
The SELinux denial audit log messages are too vague. You’re told that a label was denied reading from another label. Okay, what do those labels mean? Which programs? Which files, sockets, or whatever? You’re given the right information about why something was denied, but it’s unactionable without context.
In the best-case scenario, you’ll get (bad) advice from the denial message. The denial message might tell you to run some magical commands to allow stuff to happen. *Great, that’s what you want!* So, you run the `audit2allow` command as instructed, and end up with some policy blob files.
God only knows what changes the blobs do; you can’t be expected to, nor are you given enough information to evaluate them. Then you’re told to install it with the `semodule` command. You say, “okay”, and your problems have gone away for now.
Then six months later, an update to the system made some changes to the default system policies. The module you installed earlier references some labels or something that’s no longer defined, or some other conflict occurs. Then what do you do? You don’t know what the module did, where it was installed, or how to remove it.
This isn’t just something that happens when you blindly follow suggestions to run `audit2allow`. Package updates and policy changes often happen out-of-sync. A package’s SELinux policy is — most often — not part of the package but is installed as part of a larger meta package containing tens of thousands of policies (e.g., the Fedora Linux project’s `selinux-policy` mega-package). So, you’ll end up with breakage from the delay between upstream project changes making their way into an updated package, and the policy package receiving its next update.
The solution? Keep updating your system and hope that, within a week or so, the problem will have been resolved. That’s not always an option with business (or fun) critical software.
You can downgrade the package to the earlier version. Downgrading a security patch isn’t advisable and not all software even supports running older versions on top of configuration and databases that have been tainted by a newer version of itself. You risk introducing more problems.
You can try to run the magical commands to create a local policy patch, but then you might run into problems again further down the line. The best option in this situation is to, at least temporarily, put SELinux into permissive mode. Permissive mode logs denials but doesn’t enforce them the way the regular enforcing mode does.
Red Hat Enterprise Linux (RHEL) has some of the most accessible [documentation on creating custom policies](https://access.redhat.com/documentation/en-us/red%5Fhat%5Fenterprise%5Flinux/8/html/using%5Fselinux/writing-a-custom-selinux-policy%5Fusing-selinux?ref=ctrl.blog). (Red Hat is the same organization that manages Fedora Linux.) The documentation essentially says to run some commands that auto-generate policies for you. The RHEL documentation is written in a way that makes it clear you’re expected to pay Red Hat for consultants to manage custom SELinux policy needs for you.
The thing I’ve started to realize over time is that it’s probably best to just leave SELinux in permissive mode. The enforcing mode might prevent malicious actors from taking advantage of a weak point in my system’s security. However, it’s definitely preventing me from getting my work done.
In the last two weeks, completely unrelated issues have cost me hours and days to troubleshoot and deploy fixes to issues introduced by SELinux. The issues seem to have developed on their own and out of my control. Some were caused by policy changes, some by software package changes, and some by my configuration changes. I keep up to date on changes in critical packages, but I didn’t anticipate faults introduced by the SELinux policy.
That’s because SELinux doesn’t enforce *my* policies. I rely on the Fedora Linux project to develop and maintain policies for the software I rely on. However, I’m not familiar with the policies that are in place on my system. There’s no configuration file or reference tool I can check to see or modify the policies. They’re just there.
The issues I’ve ran into lately have been severe, too. One system (with no custom policies) was left unbootable after. The server that handles my blog’s newsletter sent an empty newsletter as the email signing agent could no longer talk to the mail transport agent (MTA).
From my perspective, SELinux broke a perfectly functional system. My system was built on top of someone else’s expectations and policies, and I wasn’t even aware of them, nor was I given a heads up before they changed.
I also decided to try the Fedora Linux 36 Beta on my laptop the same week. It’s just a few days before the final release, so I figured it would be fine. After the update, I was locked out as the login screen no longer could read some files needed to authenticate my login. Disabling SELinux was the only quick solution. (Relabeling the system didn’t fix the problem.)
Magical incantations — whether repeated from an online tutorial, documentation, or generated by a management tool — doesn’t really address the fundamental problem: SELinux is just too damned difficult to configure! It’s time consuming and complex even to inspect and parse the default policies just to understand what’s going on in the system. Audit log messages that suggest you run some random commands is just a band-aid on a more serious usability problem.
I want more control of SELinux policies on my system, and I want much easier tools to manage them. Auto-generated magical modules that vanish deep into the system only to pop up causing issues months later simply won’t do. I’d much prefer some plain text configuration files kept in `/etc/selinux` with a simple rule syntax and the ability to comment on what the policy does.
Frankly, I much prefer the [security settings provided by systemd](https://www.ctrl.blog/entry/systemd-service-hardening/) for the services it manages. They don’t provide the same controls as SELinux, but they get much of the same job done and are far easier to observe, modify, and understand.
SELinux is essentially a bag of security magic tricks orchestrated by unseen puppeteers. All I can do to influence the show is to pull more and more blobs out of the red magician’s hats/utilities.
The only reliable alternative where you have any hope of staying on top of this is to scrap everything provided by your Linux distribution and start with a clean slate. That’ll cost you weeks of your life to set up even for a basic web server. The only rational option is to leave it on but turn it off if it ever gets in your way.
### Can you use a WebP file as an Open Graph Protocol image?
URL: https://www.ctrl.blog/entry/webp-ogp/
Last updated: 2026-08-23T22:24:17.000Z
The Open Graph Protocol (OGP) was created by and for Facebook in 2010\. OGP is a pseudo-standard set of metadata tags you can include on your webpages to describe its contents. By now, it’s become the primary data source for generated link previews across the web and apps.
OGP lets you specify a webpage’s title, description, and thumbnail image. The protocol also lets you express more metadata, but these three are its primary uses. These three metadata items are used by external services to generate link previews for your webpages.
OGP metadata is consumed by all the big tech companies; including Facebook, Google, and Apple. It’s also used by every search engine, sharing, social, and messaging apps such as Reddit, Twitter, What’s App, Signal, WordPress, and Quora.
The [OGP Specification](https://ogp.me/?ref=ctrl.blog) doesn’t require the use of any specific image formats. The specification allows you to set multiple images of different sizes, aspect ratios, and file formats for a webpage. However, support for this is virtually non-existent. Avoid including more than one OGP image on your webpages!
[Facebook’s documentation](https://developers.facebook.com/docs/sharing/webmasters/?ref=ctrl.blog) says it requires images to be either JPEG (lossy), PNG (lossless), or a still frame/non-animated GIF image file. This part of its documentation was last updated in 2014\. Contrary to what its documentation says, Facebook does support other file formats than the ones it has documented. More on that later.
Image compression technology has improved a lot in the years since that documentation was last updated. The WebP format, introduced by Google in 2010, is a better option for both lossy and lossless images than either JPEG or PNG. WebP can yield higher-quality images at smaller file sizes.
Websites have embraced the WebP format because it helps them deliver pages faster and saves them money by reducing bandwidth costs. Users can’t tell the difference between one image format and another, but they do appreciate pages that load faster.
WebP isn’t as universally supported as the legacy formats. Some apps and image libraries might not know how to open and display them. However, most web browsers have supported WebP since 2019, with Safari being the last browser to add support in 2020.
It has been considered best practice to provide images in WebP and a legacy format as a fallback for older clients. Historically, this meant “for Safari” but now it’s truly only about legacy clients. However, many websites still maintain images formatted specifically for use by OGP clients.
Which brings us to the title of this article: Can you use a WebP image file with the Open Graph Protocol? OGP is one of the last hold-outs for where you need to use a legacy image format. Using WebP for OGP would allow you to drop support for legacy image formats entirely and save on storage costs and encoding time. The short answer is “yes”, but the long answer is “sure, but it depends”.
According to [Facebook’s documentation](https://developers.facebook.com/docs/sharing/webmasters/?ref=ctrl.blog), the answer is “no”. The company claims it only supports JPEG, PNG, and GIF image files. However, the Facebook website and its apps — including Messenger and WhatsApp — also support link previews of webpages using WebP images.
[Twitter’s documentation](https://developer.twitter.com/en/docs/twitter-for-websites/cards/overview/summary-card-with-large-image?ref=ctrl.blog) says it supports JPG, PNG, GIF, and WebP. WebP images work great in the company’s apps and websites. Twitter only uses the first frame of an animated PNG, WebP, or GIFs.
Here’s a quick comparison table of which image file formats are supported by different OGP-consuming platforms and apps. Note that the GIF column refers to still images and not animated GIFs. No one supports AVIF yet. (WebP adoption has a more than a decade’s lead on it.) The SVG column was included for the sake of completeness, as it’s the fifth most common image file format on the web.
| App/Service | Image format | | | | |
| ----------- | ----------------------------------- | ---- | --- | ---- | --- |
| WebP | PNG | JPEG | GIF | AVIF | SVG |
| Facebook | Yes | Yes | No | | |
| Twitter | | | | | |
| Reddit | | | | | |
| Discord | | | | | |
| WhatsApp | | | | | |
| Outlook.com | | | | | |
| LinkedIn | No | | | | |
| Slack | | | | | |
| Signal | | | | | |
| Skype | | | | | |
| Quora | | | | | |
| Mastodon | Depends on the server and apps used | | | | |
The decentralized Mastodon social network doesn’t have a definitive answer. It might support any given image format and it might not. It depends on what image formats are supported by the server’s image processing library. JPEG and PNG are generally supported.
I expect the hold-outs will adopt WebP within a couple of years. As Facebook and Twitter support WebP in OGP, that’ll be the extent of testing most websites will receive. Adoption of WebP as the only format a website supports is likely to sky-rocket in the coming years. There’s little point in maintaining two or more image formats when one is objectively better and universally supported in all web browsers.
Alternatively, you could go more advanced and try to parse the HTTP `Accept` request header from OGP-consuming bots. However, nearly all bots either don’t send an `Accept` header or send unhelpful values like `image/*, */*` (as opposed to e.g. `image/webp, image/jpeg`). In the end, you’d still need to support multiple image formats; which you probably want to avoid.
The legacy image formats are still your best bet if it’s important to you that end-users see your images in link previews. You can absolutely use WebP and fallback to only show the title and description in nonsupporting apps. I would suggest you keep your existing image format implementation, but for future implementations: Go with WebP only!
#### Sources
- [A Guide to Sharing for Webmasters](https://developers.facebook.com/docs/sharing/webmasters/?ref=ctrl.blog), 2022, Developer Documentation, Facebook, Meta
- [Open Graph Protocol](https://ogp.me/?ref=ctrl.blog), 2021-11, Facebook
- [Cards Markup Tag Reference](https://developer.twitter.com/en/docs/twitter-for-websites/cards/overview/markup?ref=ctrl.blog), 2020, Developer Documentation, Twitter
### Get your logo into inboxes with BIMI and email best practices
URL: https://www.ctrl.blog/entry/bimi-intro/
Last updated: 2026-08-23T22:02:10.000Z
The new Brand Indicators for Message Identification (BIMI) internet standards *draft* lets businesses display their logos next to their emails (as the sender/contact photo). The new standard is developed as a carrot to incentivize the adoption of existing email-sender best practices and verification schemes. Is a slight increase in branding prominence enough to push the email ecosystem towards adopting stricter email-sender policies?
Email sender verification has been an all-sticks game where senders have been beaten over the head by recipients (delivered to Spam or rejected) if they fail to comply with sender-verification schemes. These schemes include Domain-based Message Authentication, Reporting, and Conformance (DMARC); Sender Policy Framework (SPF); and DomainKeys Identified Mail (DKIM).
To comply with these email standards, you must maintain records that precisely describe which servers are allowed to send emails on behalf of your domain. These descriptions are stored as machine-readable records in the Domain Name System (DNS). In the case of DKIM, you must also commit to cryptographically signing every outgoing message.
BIMI is a new addition to the DNS record acronym soup. It puts aside the stick and offers senders a carrot instead. In exchange for configuring your domain with a strict DMARC policy built on SPF or DKIM (or both), you *might* have your brand’s logo show up next to your messages in recipient inboxes. The logo shows up in a square or round frame next to the message sender’s name; a spot typically reserved for contact photos from your address book.
The exact technical requirements for a BIMI logo to be displayed are up to the recipient mailbox provider or client application (e.g. Google Mail or Thunderbird). The [BIMI specification](https://datatracker.ietf.org/doc/html/draft-blank-ietf-bimi-02?ref=ctrl.blog) outlines a set of requirements, but the enforcement is left entirely up to the recipient. Senders should aim to meet as many requirements as possible with as strict policies as achievable for the best chance of having their logos displayed.
FastMail and Pobox (collectively FastMail), Google Mail (GMail), and Yahoo! Mail and AOL Mail (collectively YMail) are on board with their web and mobile apps. YMail will show brand logos for bulk senders with a good sender reputation. FastMail hasn’t documented its BIMI policies, but appears to show BIMI logos for anyone that meets the basic requirements.
GMail is, as always, different. In addition to strict email sending policies, it also requires a Verified Mark Certificate (VMC) signed by a Certificate Authority (CA). A VMC is a digital file that confirms that the CA has verified that the logo is a registered trademark and that the domain in question is its rightful owner. The BIMI specification includes a framework for communicating this information to email recipients.
GMail’s VMC requirement introduce a significant legal, cost, and geographical restriction to BIMI adoption within its ecosystem. The BIMI specification can be abused to make scams look more legitimate. VMCs also raise the bar for scammers, so that not just any domain can claim its logo is the same as your bank’s or PayPal’s. However, a VMC is no guarantee of your logo being displayed — as outlined in the article [VMCs Aren’t a Golden Ticket for BIMI Logo Display](https://bimigroup.org/vmcs-arent-a-golden-ticket-for-bimi-logo-display/?ref=ctrl.blog).
However, I believe that evaluating the sender’s reputation and the permanency of their DMARC policies and BIMI logo is the better approach that works at internet scale. This seems to be the approach YMail has adopted.
Ideally, recipients should retain records of the current and historical logos of high-profile targets like PayPal, banks, and cryptocurrency wallets and exchanges. They could then use this information to identify scams by looking for BIMIs from other domains that match or closely match these logos. It could be used as a tool to fight scams and not just enable them.
Google has a history of outsourcing the responsibility of verifying third parties to CA organizations with the introduction of new (and expensive) special-purpose digital certificates. The Signed HTTP Exchanges Certificate (`CanSignHttpExchanges`) extension comes to mind.
Microsoft Outlook, 1&1, Apple Mail, and Mail.ru are notable mailbox providers that don’t yet support BIMI. Microsoft has its own business-to-business program for getting brand indicators into its customers’ mailboxes. Unlike BIMI, Microsoft’s scheme requires senders to establish relationships with individual mailbox providers.
In addition to these large email providers, BIMI is supported by the [FairMail](https://email.faircode.eu/?ref=ctrl.blog) email client app for Android. It’s off by default in the app, but users can enable BIMI indicators with any standard mailbox provider. The independent implementation verifies that BIMI isn’t just relevant for large mailbox providers. There are notably no plugins for the popular Roundcube or Thunderbird email clients.
BIMI allows for a domain-wide default logo or senders can suggest other logos by including a selector header in email messages (`BIMI-Selector`). This enables you to give your support desk, order updates/receipts, newsletter, and promotional emails different variations of your company logo. Or maybe something silly like changing the indicator to one with your logo featuring a Santa hat during Christmas.
Overly unique BIMI selectors could potentially be used to track whether a specific user has viewed the message or not. Mailbox providers can thwart this by proxying every request for a BIMI whether the mailbox exists or not. This way, BIMIs can’t be abused to check for active mail addresses no read confirmations.
These types of abuse are, probably, why YMail requires a certain volume of email before they allow BIMIs to load. Email apps like FairMail that can’t track sender-reputation at scale (since it only serves one person’ mailbox), so they can’t make reputation-based decisions on when to load BIMIs.
I surveyed the top 3 million domain names (according to [Tranco list W9VK9](https://tranco-list.eu/list/W9VK9/full?ref=ctrl.blog)) on 2022-04-20 and found that 6647 domains have published a default BIMI selector. I’ll write a follow-up article and more closely analyze the results of this survey next week.
Let me know in the comments if you see Ctrl blog’s BIMI in the newsletter! Not subscribed yet? [Sign-up now](https://www.ctrl.blog/follow.html), so you don’t miss my follow-up article where I examine [BIMI adoption (and common mistakes)](https://www.ctrl.blog/entry/bimi-adoption/) across the web!
#### Sources
- [General Guidance for Implementing Branded Indicators for Message Identification (BIMI)](https://datatracker.ietf.org/doc/html/draft-brotman-ietf-bimi-guidance-05?ref=ctrl.blog), Draft #5, 2022-04-11, Network Working Group, Internet Engineering Task Force
- [BIMI](https://senders.yahooinc.com/bimi/?ref=ctrl.blog), 2022-02-10, Sender Hub, Yahoo!
- [Implementation Guide](https://bimigroup.org/implementation-guide/?ref=ctrl.blog), 2021-11, BIMI Group, AuthIndicators Working Group
- [VMCs Aren’t a Golden Ticket for BIMI Logo Display](https://bimigroup.org/vmcs-arent-a-golden-ticket-for-bimi-logo-display/?ref=ctrl.blog), 2021-09-10, BIMI Group, AuthIndicators Working Group
- [Advancing email security for Gmail and beyond with BIMI](https://workspace.google.com/blog/product-announcements/bringing-bimi-to-gmail-in-google-workspace?ref=ctrl.blog), 2021-07-21, Neil Kumaran and Wei Chuang, Cloud Blog, Google
- [Brand Indicators for Message Identification (BIMI)](https://datatracker.ietf.org/doc/html/draft-blank-ietf-bimi-02?ref=ctrl.blog), Draft #2, 2021-03-08, Network Working Group, Internet Engineering Task Force
### Everything or Nothing: The missing James Bond theme song
URL: https://www.ctrl.blog/entry/everything-or-nothing/
Last updated: 2026-08-23T22:05:58.000Z
Every now and then I lament about the digital licensing hell that’s constantly eating our shared cultural history. Or maybe I’m just angry at entropy and lack of foresight with digital archiving? None the less, I’d like to talk about a 20-year-old James Bond song you probably haven’t heard before.
James Bond 007: Everything or Nothing is a third-person shooter game released by EA Games for PlayStation 2, Xbox, and GameCube in 2004\. It was the third James Bond game by EA Games to feature an original story and the second with its own signature Bond theme song.
The game’s theme song, Everything or Nothing, was performed by Mýa Harrison. Mýa also voiced and lent her likeness to the game character Mya Starling; an NSA agent and the story’s “Bond girl”.
The song is quite catching and a definite product of its time. It’s been two decades since I played the game, and I still occasionally hum the song’s chorus to myself.
Unfortunately, I can’t easily listen to the song to get it out of my head. It’s not currently available for sale or streaming on iTunes, Spotify, Tidal, or any of their many competitors.
The song has not been included on any 007 compilation albums or official playlists. None of the other video game-exclusive songs have made it onto a compilation album either. I guess they’re not considered canonical? In my heart, they’re just as much a Bond song as any of the Bond songs from the movies.
According to Mýa’s website, the song appeared on her album Moodring released in 2003\. However, modern versions of the album available on iTunes, Spotify, Amazon, and elsewhere don’t feature the song. The album’s page on Wikipedia and other sources also doesn’t list the song.
A single version appeared exclusively on the iTunes Music Store (ITMS) in the United States between 2013 and 2019\. It was promoted three times by the artist on Twitter in the last 2018\. It was delisted from the ITMS sometime between January and April 2019.
The song has a listing in the music catalog on the music streaming platform Spotify. The song isn’t currently available on the platform. I can’t find any data to suggest that the song has ever been available on the platform.
The song was available as a free download from the game’s page on the EA Games website between 2004 and 2007\. The promotional page was created in Macromedia Flash, and thus poorly archived by the Internet Archive’s Wayback Machine. The Wayback Machine did manage to archive a [low-fidelity MP3 version of the song](https://web.archive.org/web/20051031060953/http://www.japan.ea.com/bond%5Feon/radio/01eontheme.mp3) (32 kbps) from the Japanese promotional website. So, you can still give it a listen but it doesn’t sound all that good.
That Internet Archive link is the nearest you can get to a legal digital release of the song. This version of the song has been uploaded a thousand times on services like SoundCloud and YouTube. A slightly higher bit-rate version that was ripped from the game’s title screen can also be found. (I’m sure the users who uploaded them [didn’t intend any copyright infringements](https://www.ctrl.blog/entry/copyright-disclaimers/).) 🙄
EA Games’ early rights to distribute the song as a promotional item on the web might be part of why the song’s no longer available. The song is currently owned by Interscope Records, a Universal Music Group (UMG) subsidiary. Mýa’s newer music is released and managed by her own record label.
A lot of the music I liked in the early 2000s just isn’t available anywhere digitally. The music from that middle ground period when artists and record labels began securing digital distribution rights, but no one knew how the digital distribution channels would turn out yet. So, the songs are perpetually stuck in rightsholder limbo. No one wants to renegotiate the contracts to make a few cents off streaming.
The involvement of the 007 brand further complicates matters. Eon Productions, the company managing the 007 brand and producing the movies, guard the brand and rights like a hawk. The (defunct) MGM Interactive game studios and EA Games might also still hold some of the rights. I can only speculate, though.
The previous game in the series, James Bond 007: Nightfire (2002), featured another lost Bond song: Nearly Civilized by Esthero. It’s also not available on any digital music store or streaming service. (Low-fidelity versions can be found through … other channels.) The game is old enough that information about the song and its ownership simply doesn’t exist online.
Listenership information from Last.fm (includes data from 2002 onwards) only logged 1200 listeners for Nearly Civilized. Last.fm (formerly Audioscrobbler) was a hugely popular music recommendation service. Users “scrobbled” (recorded) their music listening history to the service in exchange for personalized recommendations and fancy graphs about their music taste. This might suggest the song was rare and difficult to obtain at the time. Everything or Nothing has had over 8000 listeners.
I’ve reached out to Mýa on Twitter and to her management team via email for comment. Her manager directed me to UMG who didn’t respond to my email.
I’ll end with the lyrics from the catchy chorus from Everything or Nothing:
> “Give me Everything or Nothing;
> Give me Everything or Nothing at all!”
#### Sources
- Email exchange with Marc Rosenthal, 2022-04-06, Hue Entertainment
- [Everything Or Nothing](https://www.last.fm/music/M%C3%BDa/%5F/Everything+Or+Nothing?ref=ctrl.blog), 2022-03-30, Mýa, Last.fm, CBS Interactive
- [Nearly Civilized](https://www.last.fm/music/Esthero/%5F/Nearly+Civilized?ref=ctrl.blog), 2022-03-30, Esthero, Last.fm, CBS Interactive
- [All about Mýa](https://www.myamya.com/all-about-mya/?ref=ctrl.blog), 2020-08-23, Mýa
- [#WaybackWednesday tweet](https://twitter.com/myaplanet9/status/1073030760817405957?ref=ctrl.blog), 2018-12-13, Mýa, Planet9, Twitter
- [Everything or Nothing (single)](https://web.archive.org/web/20130420185542/https://itunes.apple.com/us/album/everything-or-nothing-single/id26236457), 2016, Mýa, iTunes Music Store, Apple, Internet Archive
- [007 エブリシング オア ナッシング2【幸運を】](https://web.archive.org/web/20220406150707/https://game4.5ch.net/test/read.cgi/famicom/1076592415/833), 2004-02-27, Famicom forum archive, Loki Technology
- [007: Everything or Nothing Title song by Mya](https://www.neowin.net/forum/topic/141799-007-everything-or-nothing-title-song-by-mya/?ref=ctrl.blog), 2004-02-16, “SuperJediMedia”, Forums, Neowin
### Samsung devices incorrectly handle CSS @media hover queries
URL: https://www.ctrl.blog/entry/css-media-hover-samsung/
Last updated: 2026-08-23T22:04:10.000Z
The `hover` `@media` feature query lets you check if a device’s primary input device supports hovering interactive elements. It became part of the web platform as of CSS Media Queries Level 4\. The `hover: hover` query should match on devices with a mouse cursor (e.g. a touchpad), and `hover: none` should match touchscreens (mobile devices). Unfortunately, Samsung devices say their touchscreens are touchpads.
The media feature query let you detect and apply different styling when a device supports hover interactions. For example, you can collapse an expandable menu when the device supports hovering and expand it by default when it doesn’t.
The media query is supported in all leading web browsers and operating systems (OS). Except for Chromium on Samsung devices running Android. Chromium is the underlying engine used by the default Samsung Internet browser, Google Chrome, Microsoft Edge, Brave, and others.
Any device with a Samsung touchscreen (and the accompanying Android kernel driver) is affected; includes all Samsung devices since 2015 and some third-party Android devices that source their touchscreens from Samsung.
The problem seems to be that the touchscreen reports to the underlying system that it’s both a touchscreen and a mouse. Technically, the affected devices self-report that they have a touchscreen and a touchpad (like on a laptop). Inputs made on the touchscreen get processed as mouse inputs by the (non-existing) touchpad.
I’m not sure why it does this, but I suspect it has something to do with either the Samsung S Pen (a stylus) or Samsung DeX (a docking station that creates a desktop-like experience). These accessories — not compatible with all affected devices — either act like or can pair the device with a hover-capable mouse.
In these situations, the device does have a hover-capable input devices. However, Samsung doesn’t let the OS distinguish between the touchscreen and its other mouse-like input methods. This issue is particularly annoying on devices that aren’t even compatible with these accessories.
I’ve reached out to Samsung and asked them to fix its web compatibility issue. I don’t expect it to get fixed any time soon. This bug seems to be a deeply-rooted OS problem with how Samsung devices handle input. I also expect that many apps have grown to depend on things continuing to misbehave.
It would be possible for either Samsung or the Chromium team to work around the issue with a patch in Chromium. Such a workaround would probably come at the cost of compatibility with the S Pen, DeX, or whatever motivated Samsung’s weird implementation in the first place.
There aren’t any good alternatives to this media query. The best you can do is to assume that small screens are touchscreens, e.g. using `@media (max-width: 500px), (max-height: 500px)` instead of `@media (hover: none)`. (Replace `max` with `min` to substitute for `hover: hover`.)
Firefox for Android uses the same input capability detection method as Chromium. However, it discards the results and uses a non-hovering course pointer instead. Firefox will always match `@media (hover: none) and (pointer: coarse)`. Although not ideal, it means Firefox will be correct about the input device most of the time.
#### Sources
- [AndroidNativePointerCaptureProvider.java](https://github.com/moonlight-stream/moonlight-android/blob/8a63b614955a726fc27c89bcf3699022214756d7/app/src/main/java/com/limelight/binding/input/capture/AndroidNativePointerCaptureProvider.java?ref=ctrl.blog), commit 8a63b61495, 2022-02-19, Cameron Gutman, Moonlight project, GitHub
- [Hover Capability: the hover feature](https://www.w3.org/TR/2021/CRD-mediaqueries-4-20211225/?ref=ctrl.blog#hover) (candidate recommendation), 2021-12-25, Interaction Media Features, Media Queries Level 4, World Wide Web Consortium (W3C)
- [Some Androids reporting hover: hover](https://bugs.chromium.org/p/chromium/issues/detail?id=940256&ref=ctrl.blog), issue 940256, 2021-02-10, Issue tracker, Chromium project, Google
- [Android Input doesn’t work because two touchscreens are detected](https://forum.unity.com/threads/android-input-doesnt-work-because-two-touchscreens-are-detected.949599/?ref=ctrl.blog), 2020-03-23, Input Systems, Forums, Unity Technologies
### Should you trust a third-party bootloader to run newer MacOS versions?
URL: https://www.ctrl.blog/entry/macos-opencore-trust/
Last updated: 2026-08-23T22:13:56.000Z
Apple periodically drops support for its older hardware, and customers get left with an increasingly insecure and outdated system. The Hackintosh scene, a community dedicated to running MacOS on unsupported hardware, might help extend the life of your Mac. However, can you trust its community-developed software to the same degree as you blindly trust Apple?
My MacBook Pro (a 2013 model) won’t receive any more love (updates) from Apple as the company left it behind with the release of MacOS version 12 “Monterey”. However, the hardware is still perfectly capable of running Monterey. Sure, it has needed some [maintenance](https://www.ctrl.blog/entry/repaste-thermal-compound/#readme) and a [battery swap](https://www.ctrl.blog/entry/macbook-late2013-battery-replacement.html), but it’s otherwise in good condition.
A Hackintosh usually refers to a computer from another manufacturer running Apple software. Apple includes all sorts of software-based copy protections to make sure its software only runs on its hardware products. That’s more of an encouragement than anything to dedicated folks who want to do exactly that.
The current star in the Hackintosh community is the [OpenCore](https://github.com/acidanthera/OpenCorePkg?ref=ctrl.blog) UEFI emulator and bootloader project. The Unified Extensible Firmware Interface (UEFI) is low-level software that sits in between the hardware’s firmware and the operating system (OS) software. Among other things it’s responsible for booting the OS, and it also provides services to the OS afterwards.
OpenCore is a free and open-source replacement for Apple UEFI and iBoot (Apple’s bootloader) software. OpenCore works by replicating the behaviors MacOS expects from UEFI and iBoot on a supported Mac on an unsupported system. It can run on legacy Mac products and computers from other manufacturers.
It’s deeply weird to me that I have to turn my MacBook into a Hackintosh to continue running Apple’s latest software. I paid extra for the Apple experience. To me, the Apple experience doesn’t involve installing third-party UEFI and bootloaders.
The first software that runs on your computer after it’s been powered on runs in absolute unrestricted security (“God”) mode. It can do anything it wants on your computer. It *is* your computer.
You implicitly trust your hardware vendor’s firmware. Bought a Dell running Windows? Then you trust Dell and Microsoft. Bought a Mac? Then you trust Apple. Customers rarely think about the required trust levels. (It may be deeply uncomfortable to pause and give it some thought.)
Things get a bit more complicated if you’ve bought a computer and you run Linux on it. Linux is a free and open-source OS developed by a loosely organized collective of individual contributors and organizations. Linux users assume everything is fine and that enough skeptical eyes are scrutinizing every little contribution.
Linux runs on one of many community-developed bootloaders started from the UEFI by whoever happens to have developed the hardware. Trust is still absolute, but it can be quite unclear who you’re trusting.
The Linux ecosystem has layers of trust and validation. The software developers rarely delivers software directly to their end users. Instead, software developers release software which is then picked up by another group of people: package maintainers. The package maintainers prepare and package the software for a Linux distribution. The packaged software is staged for testing before eventually being pushed to end-users.
On top of this, security researchers eagerly await the release of key packages. Finding a vulnerability in a program that can be expected to be installed on millions of computers can be a huge carer boost.
OpenCore is a much smaller project where the software gets delivered directly to end-users. There are fewer eyes and steps from the project to its end users. Crucially, there are fewer (if any?) corporate users. There’s less time and money invested into scrutinizing the software and the project’s security practices.
You should always be distrustful of alternative firmware. You should always ask yourself: do I trust this firmware to not steal my email and passwords, credit cards and banking information, and cryptocurrency wallets? For most people, the answer should be: I don’t know and I’m not qualified to answer that question.
OpenCore documentation (from the project and third party) references “security audits”, but I haven’t found any indication of a security audit of the project. A security audit is a thorough, time-consuming, (and expensive) process where a specialist consulting agency reviews a software project. An audit typically involves validating security best practices, identifying unsafe/exploitable areas of the code, and suggesting other improvements to strengthen its resistance to exploitation
I’m not saying there’s any malicious intent from the OpenCore or other alternative UEFI or bootloader communities. However, even the best developers and intentions can make mistakes. That mistake could be exploitable.
The [OpenCore Legacy Patcher](https://dortania.github.io/OpenCore-Legacy-Patcher/?ref=ctrl.blog) app makes it easy for users on older versions of MacOS to download and prepare a USB drive that they can use to update their unsupported Macs to the latest version. Its first operation just downloads and installs the MacOS Installer from Apple onto the USB drive. It creates [verifiably genuine installers](https://www.ctrl.blog/entry/how-to-verify-macos-installer/).
In the second step, it installs OpenCore onto the USB drive. Now, it’s up to you to blindly trust it, restart your Mac, and hope for the best.
I’d recommend most users who’re considering a Hackintosh approach to install a popular Linux distribution instead. The Linux community is motivated to support your aging hardware instead of actively trying to break it with every update.
Apple actively wants to sabotage OpenCore and the Hackintosh community’s efforts. OpenCore works around and bypasses security measures, and it can prolong the life of your unsupported Apple products. However, you have no guarantee of how long it’ll last. Installing OpenCore may grant your Mac another lease on life, but you’ll always be on borrowed time.
Unfortunately, the WiFi chipset in this generation of MacBooks is poorly supported in Linux. Otherwise, I’d recommend you switch to Linux instead of continuing to use Apple’s OS. However, I too want to continue using MacOS and I don’t need another Linux computer. So, I went down the lesser-traveled OpenCore path.
Whether you install OpenCore or Linux (or even Windows) on your Mac, you should be prepared for [shark encounters](https://xkcd.com/349/?ref=ctrl.blog). You’re not an Apple customer anymore; the magic is no more.
In my opinion, hardware vendors should continue supporting their old hardware for at least 10–15 years. There’s no need for my MacBook to become electronics waste at this point in its life. Assuming I can run still-maintained and secure software on it, it still has years of use ahead of it.
### How to install additional spell check dictionaries for Flatpak apps
URL: https://www.ctrl.blog/entry/flatpak-locale-dictionaries/
Last updated: 2026-08-23T22:07:03.000Z
[Flatpak](https://flatpak.org/?ref=ctrl.blog) apps run inside a separate and isolated environment from your main system. This environment separation is what helps make apps portable between different Linux distributions. However, it also changes the approach required to complete tasks like installing multiple spell checker dictionaries for bilingual users.
By default, Flatpak downloads app-specific locale data (including translation files, locale and format settings, and dictionaries) for each app matching your system locale. However, Bilingual users likely want to install more than one dictionary for their spellchecker.
On Linux, you usually achieve this by installing additional dictionaries through Linux your distribution’s package repository. System dictionaries aren’t accessible to Flatpak apps inside their isolated Flatpak runtimes. You *could* tweak overrides for individual Flatpak apps to grant them access to the system dictionaries. However, there’s a better solution.
Flatpak doesn’t have many configuration options, but it has one for specifying what languages to download. Flatpak downloads and installs the default system language, locale and formatting data, and dictionaries by default. However, you can configure it to enable support for a list of languages.
The below command configures Flatpak for the current user with a semicolon-separated list of two-letter language codes (ISO 639-1). The first language is the primary language and gets used as the display- and spell checker language. The rest of the list is an ordered list of fallback languages. Flatpak will install spell check dictionaries for each listed language.
The following example command sets English as the display/primary language; and German and French as fallback languages. The second command triggers an update, which will instruct Flatpak to fetch any missing locale data after you’ve changed the configuration.
```sh
flatpak config languages --set "en;de;fr"
sudo flatpak update
```
Unfortunately, this option only accepts a list of two-letter language codes. Flatpak only supports meta-language groups like “English” (en) and not “American English” (en-US).
As an unfortunate side-effect, you can’t install just American English. You install the whole set of English variants with the “en” language code. The only disadvantage is that you get a cluttered language list when choosing your spell checker language, and you might not get the language variant you expect.
Double-check that the spell checker has selected your preferred regional language variant inside each app. There’s no way to specify the language locale variant globally for all Flatpak apps.
#### Sources
- [flatpak-config — Manage configuration](https://docs.flatpak.org/en/latest/flatpak-command-reference.html?ref=ctrl.blog#flatpak-config), 2021-11-19, Reference, Documentation, Flatpak
### How to run Windows 11 in GNOME Boxes (with UEFI and TPM2 emulation)
URL: https://www.ctrl.blog/entry/how-to-win11-in-gnome-boxes/
Last updated: 2026-08-23T22:11:18.000Z
My old tutorial for [installing Windows 10 in GNOME Boxes](https://www.ctrl.blog/entry/how-to-win10-in-gnome-boxes/) doesn’t work with Windows 11\. Here’s how to install Windows 11 as a virtual machine (VM) inside [GNOME Boxes](https://apps.gnome.org/app/org.gnome.Connections/?ref=ctrl.blog). (Some configuration file changes required.)
Windows 11 significantly raised its hardware requirements compared to Windows 10\. Among the changes, it requires more RAM and storage space. It also requires a Trusted Platform Module (TPM) version 2.0 and a UEFI boot environment.
GNOME Boxes doesn’t yet support TPM and UEFI environments. However, the underlying virtualization technology supports it. You just need to tweak a few configuration options along the way. *Read the instructions carefully!*
### Prerequisites
You’ll need to meet the following hardware requirements:
- Your processor must support hardware emulation, either AMD Virtualization (AMD-V) or Intel Virtualization Technology (VT-x). All but the cheapest processors should support virtualization. Check your BIOS to make sure it’s enabled! (It may be **off by default**.)
- The Windows guest system requires at least 8 GB of RAM. Your host system will also require at least 2 GB for itself and the emulation. Your system should have at least 12 GB of RAM.
- The Windows guest system requires at least 124 GB of storage space. The Windows install doesn’t need all this storage right away, but you’ll run into issues with Windows Update later.
You also need to prepare the following:
- A Windows 11 installation media file (“ISO”). It can be [downloaded for free from Microsoft](https://www.microsoft.com/en-us/software-download/windows11?ref=ctrl.blog "Windows 11 ISO Download Portal") (about 6 GB). Make sure you download the right edition and installation language.
- A valid Windows Product Key for OEM/Retail installations. The **Professional edition is preferred** (refer to the Post-installation section below). You can skip this during the installation, but you will need to provide a product key within 30 days of the installation.
You should also be familiar with installing software packages from your Linux distribution’s package repository from the terminal. This is the `dnf` tool on Fedora Linux; and the `apt` tool on Debian, Ubuntu, and their derivatives.
### Install GNOME Boxes and its prerequisites
1. Start by installing GNOME Boxes from your Linux distribution’s package repository. You cannot use the Flatpak/Flathub version as it doesn’t currently support emulating a TPM. The package is called `gnome-boxes` everywhere. You need **version 40** or newer!
2. Install the TianoCore Open Virtual Machine Firmware (OVMF) from your package repository. This will let your VM boot as a modern secure boot-enabled UEFI system instead of a legacy BIOS system. The package is called `edk2-ovmf` in Fedora Linux 34 and `ovmf` Ubuntu 22\.
3. Install the `swtpm` emulator (software TPM (SWTPM)) from your package repository. The package is called `swtpm-tools` in both Fedora Linux 34 and Ubuntu 22 (it’s found in the Universe repository).
4. As yout normal user (not root), run the SWTPM set up command in a terminal:
```sh
swtpm_setup --create-config-files skip-if-exist
```
You may need to log out and back in again if you’ve launched another VM in the current session. Unsure if this applies to you or just want to stay out of trouble? Just reboot your computer; it’s quick and easy anyway.
### Installing Windows 11 in GNOME Boxes
1. Start GNOME Boxes and click on the New button (top left) to create a new VM. The dialog can look a bit overwhelming, but it’s only asking you for one thing: an installation disk image file (“ISO”).
2. Select the Windows 11 ISO file you’ve downloaded from Microsoft. Do not trust ISO files from sources other than the official website of the software vendor. GNOME Boxes will list it at the top of the dialog (likely misidentified as Windows 10) if it’s stored in your Downloads folder. You can also use the select disk image option at the bottom of the dialog.
3. Do not accept the Express Installation option. Express installs are only available for some operating systems (OS) and don’t yet work with Windows 11\. This option is shown because current versions of Boxes misidentify Windows 11 as Windows 10\. Instead, click on the Next button in the top right corner.
4. On the next screen, assign the Windows guest system *at least* 8 GB of RAM and 124 GB of disk space. The virtual hard disk image won’t consume all that space right away, but grows dynamically as it gets used.
5. Click the Create button and wait. The Windows installer should boot up inside the VM and prompt you to select your preferred language and locale. **Do not proceed** with the installation! The VM is running in legacy BIOS mode and without a TPM. We need to correct that before proceeding.
The following steps **must be followed precisely** to fully shut down the VM. Unfortunately, there are a few design flaws in GNOME Boxes when you’re trying to do this in the middle of an OS installation. See GNOME Boxes [issue #773](https://gitlab.gnome.org/GNOME/gnome-boxes/-/issues/773?ref=ctrl.blog). GNOME Boxes may incorrectly show the VM as shutdown while it’s still running if you don’t follow these steps.
1. **Abort the installation** by clicking the Close button (top right) of the installer window inside the VM. You’ll get returned to Boxes main view.
2. Wait 20 seconds. The VM’s preview image will spin continuously.
3. Right-click on the VM and select Force Shutdown. The preview image will continue to spin.
4. Quit and restart GNOME Boxes. The preview image should now have stopped spinning and turned into the power symbol (⏻).
Hopefully, you haven’t completely lost faith in GNOME Boxes after following that sequence of steps to fully shut down the VM. GNOME Boxes expect to auto-restart the VM two times as part of the normal installation. We don’t want that, so we end up in buggy and uncharted waters.
At this point, you’ll need to make a few manual changes to the VM configuration before we jump back into the Windows Installer. Make sure to follow the instructions carefully.
1. Right-click on the VM and select Properties. Go to the Advanced tab and click on the Edit Config button (it may be called Edit XML in older versions).
2. Scroll down to the line that says ``. Scan the lines until it says `` for any mentions of a TPM. Skip this step if you find any. To enable the TPM emulator, insert a blank line after `` and paste the following snippet:
```xml
```
1. Scroll down to the line that says ``. Verify that the `type` element matches the below (the numbers in the `machine` attribute may differ). If it doesn’t match then you probably haven’t enabled virtualization in your BIOS. Fix that first, delete the VM, and try again.
```xml
hvm
```
1. Locate the newly installed OVMF secure boot firmware image file on your system. The file is called `OVMF_CODE.secboot.fd`, but the installation path is different between Linux distributions. It’s located in `/usr/share/edk2/ovmf/` in Fedora Linux 34 and in `/usr/share/OVMF/` in Ubuntu 22\.
2. Scan the lines until it says `` for any mentions of a loader. Skip this step if you find any. Insert a blank line after the `type` element, and paste the following (supply the correct full path from the previous step):
```xml
/PATH-HERE/OVMF_CODE.secboot.fd
```
1. Click the Apply button to save the changes. It may appear like your changes get reverted and you may receive a warning about failing to create a snapshot. You can ignore these problems.
2. Quit and restart GNOME Boxes again.
3. Right-click on the VM one last time and select Properties. Go to Devices and Shares: CD/DVD.
4. Click the Select button and reselect the Windows 11 ISO file. The image was removed automatically when the system was shut down during the aborted installation.
5. Close the properties dialog.
6. Double-click on the VM in Boxes to start it and resume the installation. Complete the Windows 11 installation by following the prompts. Here’s a neat trick to [install Windows without any bloatware](https://www.ctrl.blog/entry/windows-ooberegion-bloatware/).
### Post-installation
Once you’ve installed Windows 11, you can just use it as-is in GNOME Boxes. However, you’ll be stuck with low performance, 800×600 px screen resolution, and no clipboard integration. Let’s get those sorted out in order.
You can increase the performance of most I/O operations by installing the VirtIO guest agent and driver set. Inside the VM, download and install [VirtIO guest addons](https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/stable-virtio/?ref=ctrl.blog) (look for `virtio-win-gt-x64.msi`). Restart the VM afterward.
You have two options for higher screen resolutions and clipboard integration. You can either continue to use GNOME Boxes or switch to [GNOME Connections](https://apps.gnome.org/app/org.gnome.Connections/?ref=ctrl.blog). Connections is a version of Boxes that focuses on accessing remote desktops instead of VMs. The two apps look and feel very similar.
You can use Connections to connect to the VM using the Remote Desktop Protocol (RDP). This is the most performant and reliable option. However, it requires a license for Windows 11 Professional or Enterprise. Windows 11 Home doesn’t include the required RDP server component.
You can enable the RDP server from the Windows Settings app: System: Remote Desktop: Remote Desktop. After enabling a network service, take a moment to double-check your network firewalls and make sure that you have a strong and unique password. You may have exposed the service on the public internet. Note that networking into the VM also requires more configuration and is out of scope for this article.
Your other option is to keep using GNOME Boxes with a graphics driver optimized for use within VMs, and optionally the SPICE guest agent. To enable greater screen resolutions, you need to download and install the newest version of the [QXL-WDDM\-DoD driver](https://www.spice-space.org/download/windows/qxl-wddm-dod/?ref=ctrl.blog) (look for the newest date, then `QxlWddmDod_x64.msi`). The download link may lead to a page that looks like gobbledygook. If this happens: Go back, right-click, and select Save As. The QXL-WDDM-DoD driver works in Windows 11 but doesn’t officially support the OS.
Optionally, you can enable auto-resizing/adaptive screen resizing and clipboard integration by downloading and installing the [SPICE guest agent](https://www.spice-space.org/download/windows/vdagent/?ref=ctrl.blog) (look for the newest date, then `spice-vdagent-x64.msi`). Restart the VM afterward.
### Known issues
The SPICE display server can sometimes stop working under heavy processor loads. You need to restart the VM to get it back up and running. This isn’t an issue when using RDP.
Online snapshots don’t work with UEFI-based systems. You need to power off the VM before you can create a snapshot.
### Why it’s easier to recover unsaved documents in Kate than GEdit
URL: https://www.ctrl.blog/entry/kate-swp/
Last updated: 2026-08-23T22:12:26.000Z
A few years ago, I wrote about [how I recovered a GEdit document](https://www.ctrl.blog/entry/how-to-recover-gedit-documents/) from an unresponsive system. At the time, I couldn’t interact with the system using a keyboard and mouse. However, I could open a remote shell into the system and managed to retrieve and save the document.
I haven’t needed to do that since. My computer still occasionally becomes unresponsive, but I don’t lose hours’ worth of unsaved work anymore. I still occasionally need to [recover my emails from RAM](https://www.ctrl.blog/entry/restore-lost-email-from-ram/). So, what changed?
Shortly after GEdit crashed on me, I replaced it with [Kate](https://kate-editor.org/?ref=ctrl.blog) and [KWrite](https://apps.kde.org/kwrite/?ref=ctrl.blog). Kate has developer-oriented features whereas KWrite is a stripped-down version for general text editing. Both versions have the feature I’ll discuss in this article.
Kate has a feature that lets it recover your unsaved work from crashes and system crashes. It has two important caveats and I’ll get those out of the way first:
The recovery feature only works with documents that have been saved once and reside in a writable directory. Kate won’t be able to recover your never-saved novel or changes. The document needs to have a writable path on a file system.
When you make changes to a saved file on a local or remote file system in Kate, it auto-saves a swap-recovery file. The swap file contains all the differences between the original file on disk and the unsaved working copy you’re editing in Kate. It’s auto-saved to disk every 15 seconds. The swap-recovery file is saved to `.example.txt.kate-swp` in the same directory as the file. The leading dot hides the file in most file managers.
The swap file is removed when you save your document and make no further changes. However, if Kate or the system crashes, it’ll auto-detect the swap file when you reopen your file. Kate will prompt you to compare the current file with the unsaved changes and let you recover or discard them.
It’s a nice-to-have feature until the day when you really need it. It was really useful to me in the time before I fixed the [suspend-on-low-battery issue](https://www.ctrl.blog/entry/linux-laptop-low-battery-suspend/) that caused my laptop to crash fairly regularly (due to power failure).
I can hear some of my readers squirming in their chairs, ready to complain about the “unnecessary wear” on their solid-state drives (SSD). These occasional extra saves won’t wear out your SSD. SSD wear is caused by poorly designed programs that constantly write lots of data every millisecond for no apparent reason. Kate only saves the recovery file when there’s unsaved work to preserve; it doesn’t needlessly re-save it every 15 seconds.
You can turn off the swap-recovery feature or configure the auto-save interval in Kate Configuration: Open/Save: Advanced. You can also override where the swap file is saved. This last option can be useful if you’re editing files in a folder that is synced to other machines using a program like Syncthing or Dropbox.
#### Sources
- [Chapter 7: Configure KatePart](https://docs.kde.org/stable5/en/kate/katepart/config-dialog.html?ref=ctrl.blog), 2022-03-11, KatePart Handbook, Docs, KDE
### FreeStyle Libre 3 miniaturizes real-time glucose monitoring
URL: https://www.ctrl.blog/entry/freestyle-libre3-cgm/
Last updated: 2026-08-23T22:07:46.000Z
[I’ve worn the FreeStyle Libre 2](https://www.ctrl.blog/entry/freestyle-libre2-wear/) flash-glucose monitor (FGM) on my upper arm for the last three years. As a diabetic, I need to pay close attention to my glucose levels, and the Libre 2 was a revolution compared to finger-prick blood tests every couple of hours. The new Libre 3 system is a highly-anticipated update that massively improves on the Libre 2.
I don’t usually talk about products that I don’t have any first-hand experiences with, but I’m making an exception here. The Libre 3 isn’t yet available in my market, but I’m genuinely stoked about the next-generation FreeStyle *continuous* glucose monitor (CGM).
The Libre 2 continuously measures glucose levels and optionally sends alerts to your phone when the levels go out of range. To see the glucose readings, you needed to put a reader or your smartphone up to the sensor and hold it there for a few seconds. The last eight hours of glucose readings are transferred to your reader using near-field communication (NFC).
The new Libre 3 still uses NFC to pair and activate the sensor. However, it sends glucose readings every minute over Bluetooth Low Energy (BLE) to your smartphone. The readings can be automatically relayed via your smartphone to a guardian or another person, making it an excellent option for kids. It turns it into a CGM instead of a FGM.
I’m looking forward to not having to do battle with NFC throughout the day. I love my Libre 2, but it’s also frustrating to align two tiny NFC antennas by reaching behind the arm/shoulder. It’s not like I can see what’s going on, and NFC and the LibreLink app are quite unforgiving. *Beep! Beep! Beep! Try again.*
Better glucose management leads to better long-term health outcomes for diabetics. It’s literally a life-extending diagnostic tool. A CGM lets diabetics more quickly handle glucose events like critical hypoglycemia and hyperglycemia. Without a CGM, the best alternative is an expensive trained diabetes dog that can recognize these changes to your body from changes in your odor.
A CGM is nothing new; they’ve been around commercially since 1999\. The revolutionary change is the advances in miniaturization. The Libre 3 sensor is 21 mm × 2,9 mm and weighs 1,1 g. For comparison, the Libre 2 sensor is 35 mm × 5 mm and 5 g.
The FreeStyle Libre’s closest competitor is Dexcom. It has made CGMs for years, but the sensors are the size of a small toy car. Dexcom’s current model, the G6, is roughly four times the size and over five times the weight of the Libre 2\. Its upcoming model, the G7, is only slightly larger and heavier than the Libre 2\. Just as Dexcom is about to catch up with the Libre system, Abbott significantly increased its lead in the miniaturization of body-worn sensors.
The FreeStyle Libre 3 is currently only widely available in Germany with limited availability in the Netherlands. (Some availability in other regions through resellers of German stock.) Additionally, it should become available through the national health services in Finland, the Netherlands, and the United Kingdom sometime in 2022.
You can also find country-specific apps for Android on the Google Play Store for France, Norway, and Sweden. The Libre 3 is not yet available in any of these countries, however.
Abbott has focused on the European market when launching new FreeStyle Libre systems. The nationalized health care systems throughout Europe have enormous coordinated purchasing power compared to other countries like the United States.
The Libre 3 is compatible with Android in every launch market, and iOS in Germany. Most articles, blog posts, and reviews of the Libre 3 inaccurately claim that it’s incompatible with iOS. Country-specific documentation says the Libre 3 is *not compatible* with iOS, except in Germany. This suggests it’s an issue of red tape and staggered market roll-out, and not a technical limitation.
Additionally, Abbott now promotes that the FreeStyle Libre system supports some smartwatches: Fitbit Versa 3 (Android and iOS), Apple Watch Series 7 (iOS), and Samsung Galaxy Watch 4 (Android). The integration requires the paired smartphone to be within range to receive the glucose measurements. The phone receives the glucose measurement and then forwards it to the smartwatch. The feature relies on notification mirroring, and should be available through any smartwatch, app, or device that supports notification mirroring.
The Libre 3 has not improved at all on other important aspects of its ecosystem. Users are still obliged to agree with new lengthy shrink-wrap contracts every couple of months to continue using the system. A shrink-wrap contract is a legal document, e.g terms of service or a privacy policy, presented to the customer *after* they’ve already purchased a product or service.
The data from the sensor is still encrypted, and you’re required to use the FreeStyle Libre app. You can’t transfer your real-time or historical glucose measurements to other health platforms or diabetes treatment apps.
The Libre sensor is still an invasive measurement sensor; meaning it punctures the skin which can be painful and cause infections. The Libre 3 Sensor still only lasts two weeks before you need to replace it. The time limit is partially there to lower the risk of infection and give the skin time to heal.
Abbott has publicly stated that it will match the current price of the Libre 2, the most inexpensive FGM/CGM on the market. Abbott has not announced a stand-alone reader device for the Libre 3, so you need a current model of a mid- to high-tier smartphone to use the system. The Libre 2 Reader device has also been unavailable for months, likely because of the global microchip shortage.
The ongoing cost makes the Libre system unaffordable to many diabetics around the world. There are currently dozens of alternative noninvasive glucose monitor (NIGM) systems in development. An NIGM is the dream (and more affordable) solution. While we wait for NIGMs to hit the market, I’ll cherish a smaller CGM as a welcome improvement.
#### Sources
- Regional store listings from Abbott, 2022-03-15, Apple App Store and Google Play Store
- [FreeStyle Libre 3: Kompatibilität mit Mobilgeräten und Betriebssystemen](https://web.archive.org/web/20220314193445/https://freestyleserver.com/Payloads/IFU/2022/q1/ART43193-005%5Frev-F-web.pdf), 2022-03-09, Customer Documentation, Abbott
- [FreeStyle Libre 3: Mobile Device & OS Compatibility](https://web.archive.org/web/20220314175529/https://freestyleserver.com/Payloads/IFU/2022/q1/ART43193-006%5Frev-C%5FWeb.pdf), 2022-02-03, Customer Documentation, Abbott
- [FreeStyle Libre 3 Sets New Peak in Diabetes Care](https://www.abbott.com/corpnewsroom/diabetes-care/freeStyle-libre-3-sets-new-peak-in-diabetes-care.html?ref=ctrl.blog), 2020-09-20, Press Release, Abbott
### The HTML element and its (undefined) segment boundaries
URL: https://www.ctrl.blog/entry/html-meter-segment-boundaries/
Last updated: 2026-08-23T22:11:28.000Z
I recently found a use for the `` element: an element to represent a scalar measurement within a known range. (That’s the unappealing language the HTML Standard uses to describe a horizontal gauge bar.) However, I was dismayed to discover that different web browsers have vastly different interpretations of a vaguely defined aspect of the `` element. Here’s what I found and the workaround to get the same behavior in all browsers.
HTML Web Applications (“HTML5”) was all the rage in 2010, and browser vendors innovated left and right. One of those innovations was the HTML `` element. It may not have been as flashy as the new input fields or `