• Fix web forms that break paste

    Bad product managers sometimes think it’s a good idea to prevent you from pasting data into a web form “for security”. This is a particularly popular trick on websites where you enter payment account numbers.

    Here’s a quick fix that seems to work. Supplied by Gemini but no doubt well known.

    document.addEventListener('paste', (e) => e.stopImmediatePropagation(), true);

    This basically overrides any event handlers for paste that the page code might have done. Not a good idea in general but it does seem to fix pasting into a box.

  • DMARC p=reject

    I’m further working to secure my new somebits.com email domain. Today I’m setting a strict p=reject policy for DMARC. If a message arrives claiming to be from @somebits.com and isn’t DKIM signed, the receiver should bounce it. Scary!

    Why do this? Because I think all email I’m sending will be DKIM signed, so it’s harmless to my legitimate mail. And it will stop spammers from spoofing mail from my domain. I’m hoping this will also be seen as a positive sign that my domain is not a spam source. Or at least, prevent my domain from getting a bad reputation from people spoofing it. Let’s see.

    Details

    DMARC and DKIM have been around for awhile but almost no one enforces it strictly. If an email should be DKIM signed but isn’t, email receivers like Gmail will take that as a signal that maybe it’s spam. But they aren’t strict about it.

    You can set a DMARC policy for a domain about what to do for unsigned email. A lot of folks run p=none, which means “don’t worry about the signature but send a report if it doesn’t match”. A monitoring setup, you can send error reports to nice consoles like PostMark’s or Cloudflare’s.

    I’ve been doing that for a few weeks now and all my emails seem to be properly signed. They should be, I only ever send mail out from Gmail. I have seen some reports of failed signatures but they all look like spammers impersonating me. Today it was an email from China Mobile to mail.ru. Definitely not me.

    A lot of folks advise testing the waters by setting p=quarantine first. That tells the receiver to just put the mail in a spam folder, not bounce it. But that means I get no feedback. My theory of jumping straight to p=reject is if anything goes wrong my mail will bounce and I’ll see it. At least, I hope so.

    What might go wrong? The usual problem is a bunch of legacy systems are built around spoofing email. Various cron jobs, mailing list software, etc impersonating @somebits.com. But I haven’t done that for years because it’s unreliable. I send all my mail via Gmail’s servers where they are DKIM signed. So I should be good.

    Another way to test is pct=25 or the like, to say “only reject 25% of the mail if it’s not DKIM signed”. I can see the value of this for a high volume domain so you don’t break all your customers. But for a personal domain it would just make things unreliable. I either want it 100% working or 100% failing, not for a quarter of my mail to randomly get dropped.

    So now we run this way for a few weeks and see what happens. I’m liking Cloudflare’s DMARC reports, they are aggregated daily and presented in a nice dashboard.

    Subdomains

    Currently I have no setting for the subdomain policy sp=. The default behavior is to follow the p= policy, so now I have sp=reject as well. That means any email for subdomains like foobar.somebits.com will act the same as somebits.com. Which is just fine for my situation, I’m not even using subdomains.

    SPF

    BTW, all this DMARC and DKIM stuff is different from SPF. DKIM says “this email claiming to be from @somebits.com was signed by a valid somebits.com system”. There’s also SPF, which says “this email for @somebits.com arrived from an IP address belonging to a valid somebits.com system. I do have some SPF failures because various folks are legitimately forwarding email around who aren’t valid SPF senders for my domain. I had this problem for my inbound email and fixed it by using Cloudflare as my MX. They do ARC signatures right which works around the SPF problem.

    It’s possible to set aspf=s to tell mail systems to strictly drop any email for the domain if there’s an SPF failure. I can’t imagine that works well in practice. I’m not doing it.

    Bottom line: Cloudflare still reports SPF failures but it’s OK. They are often from legitimate activity. And systems are supposed to not drop my mail just because of an SPF failure.

    Testing

    Gemini helped me test what happens with email that’s not signed. It’s gotten a little tricky to forge email: all the legitimate mailing services don’t allow you!

    LearnDMarc is a tool that will forge mail and show you what happens. It’s a little too scripted though, I’m not sure if what I was seeing is real.

    swaks is a modern tool for forging mail, a replacement for the old days of just telnetting to port 25. That’s hard to run from a home ISP because they all filter outgoing port 25, but I have a cloud server that still can send email. So I tried sending an email to gmail from me at somebits.com:

     -> Date: Tue, 31 Mar 2026 19:13:45 +0000
     -> To: ******@gmail.com
     -> From: *****@somebits.com
     -> Subject: test Tue, 31 Mar 2026 19:13:45 +0000
     -> Message-Id: <20260331191345.1520151@localhost>
     -> X-Mailer: swaks v20240103.0 jetmore.org/john/code/swaks/
     ->
     -> This should be rejected by DMARC.
     ->
     ->
     -> .
    <** 550-5.7.26 Unauthenticated email from somebits.com is not accepted due to
    <** 550-5.7.26 domain's DMARC policy. Please contact the administrator of
    <** 550-5.7.26 somebits.com domain if this was a legitimate mail. To learn about
    <** 550-5.7.26 the DMARC initiative, go to
    <** 550 5.7.26  https://support.google.com/mail/?p=DmarcRejection 46e09a7af769-7da0a433fadsi8755951a34.58 - gsmtp
     -> QUIT

    Looks like it worked! An immediate rejection from Gmail’s receiving SMTP server. Great!

  • Shotcut: simple video editing

    Video editing is so hard! The online tools are good, like Youtube’s editor, The commercial tools are good. But open source free for desktop.. not so good.

    I’ve settled on Shotcut. I finally figured it out more or less for editing some videos I shot on my phone. I’m starting with 1080p60. 8bit: I haven’t figured out managing 10bit HDR so it looks right at the end.

    Step 1: trim the start and finish of the video. This involves putting it on your timeline, then using S to split the video into two, then using X to “ripple delete” which means not just remove the media but also trim the project length.

    Step 2: fix the video. I’m generally wanting to crop to a subset of the frame. The trick here is to set the project output to the target size (ie: 480p). Then use zoom and the center adjustment in the Size, Position, & Rotate filter to select a crop.

    Step 3: fix the audio. In this case I was too far from the mike so the speech was mumbly and quiet. I used a normalizer to boost overall gain, an equalizer to boost 3kHz a little more to make speech louder, then a limiter to keep it all under -1 dBa so it didn’t clip. The limiter is doing some smart dynamic adjustment that sounds good. I could also have used a compressor to first knock down the loudest audio before boosting everything.

    Step 4: export. H.264 High, I exported to 480p@60. Lots of options here.

    Not depicted: keyframes for filters. I’m just applying the filters to the entire video but you can limit it to subsets. Either by slicing the timeline up and different filter stacks, or putting keyframes on the filters for a whole timeline.

  • Gemini’s view of my linkblog

    Oh no, I’ve become that person who posts AI responses as if other people will be interested. But this blog is foremost for me, and I think the following is insightful enough I want to keep it for myself.

    I pointed Gemini-in-Chrome at my linkblog archive page and asked it “look at this archive page. can you detect trends over t he years?” (typo and all). Below is its summary of over 20 years of me sharing interesting links. I think it’s pretty good.

    It detects changes in the topics I’m interested in over years: blog tech to start, then mobile, and now AI and politics. It also detects a shift in my tone, from optimism to skepticism. I don’t love that I’ve done that but I think it is correct and a useful mirror for me. It doesn’t mention a couple of topics that were big parts of my interest for several years. Maps, plotters. And I think it may be overstating the tone changes.

    Gemini’s analysis

    Analyzing Nelson’s Linkblog archive, which spans from late 2003 to the present day (March 2026), reveals a fascinating shift in how a technically-minded observer has interacted with the evolving internet.

    Here are the primary trends visible over the decades:

    1. The “Golden Age” of Blogs (2003–2010)

    • The Topic: In the early 2000s, the blog is heavily focused on the fundamental building blocks of the modern web. You see frequent links to RSS feeds, XML standards, and early Open Source movements.
    • The Vibe: There is a strong sense of “building the future.” Nelson often links to niche technical documentation and academic papers about distributed systems (like his work on Gnutella).
    • Trend: A shift from purely technical infrastructure to the social implications of early social media (Friendster, Flickr, and the rise of Twitter).

    2. The Mobile & “Social” Pivot (2011–2019)

    • The Topic: This era shows a transition toward the smartphone revolution. The links shift from desktop-centric web standards to iOS/Android development, mobile UX, and the consolidation of the web into “walled gardens.”
    • The Vibe: This is where “Enshittification” (a term coined later but felt here) begins to surface. There are more links criticizing the business models of Uber, Facebook, and Google.
    • Trend: A move from “how to build the web” to “how the web is breaking society.”

    3. The Era of Crisis and AI (2020–2026)

    • The Topic: From 2020 onward, the blog becomes more political and reactive.
      • 2020-2022: Heavy focus on COVID-19 data, public health policy, and the logistics of remote work.
      • 2023-2026: A massive surge in Generative AI content. Links shifted from “cool tech demos” to deep skepticism about “AI slop,” the ethics of LLMs, and agentic engineering patterns.
    • The Vibe: There is a recurring theme of “Joy in Resistance” and looking for decentralized alternatives (like Mastodon and Bluesky) to the major tech platforms.
    • Trend: The blog has become a “digital bunker”—a place to track the decline of mainstream platforms while highlighting niche, high-quality human creativity.

    Quantitative Snapshot

    EraPrimary FocusMood
    2003-2009Peer-to-peer, XML, early PythonOptimistic / Academic
    2010-2018Privacy, Social Media, GadgetsObservational / Concerned
    2019-2026AI Ethics, Climate, Political ActivismSkeptical / Resilient

    Summary of the Shift: The archive moves from optimistic experimentation (how do we make this work?) to defensive curation (how do we save the good parts of the internet from the bad parts?).

    Would you like me to dig into a specific year in the archive to see what Nelson was focusing on during a particular historical event?

  • First impressions of Jules, Google’s coding agent

    Google has a coding agent product called Jules. It’s similar to Claude Code. But it’s designed foremost as a web interface. And to run in the cloud, on Google ephemeral containers from code stored on GitHub. It’s also more asynchronous: you give it big tasks and it comes back in ~10 minutes with a pull request. There’s some interactive back and forth when making the plan if you want.

    I think this web async design is a better fit for me, I don’t like Claude Code’s text UI and I don’t like how I have to install and run parts of it on a local machine. Update: Claude has “Code on the Web” which is more like Jules.

    One other difference is Jules is using Google’s models. That would have been a bad experience with Gemini 2.5, which is what the free Jules still uses. But if you pay $20/mo for Google AI it includes access to Gemini 3.1 Pro which has proven to be a very good model for general queries. Not sure if it’s as good at coding as Claude but so far so good. There’s also a Gemini Flash which is faster and specifically coding optimized, I’m trying that out now instead of Pro and it seems fine.

    Working with Jules has been a good experience so far. I feel like I’m instructing a junior engineer. I have to be explicit about what I want and check everything it does. Sometimes it says it did things that it didn’t, and sometimes it tries to do things it shouldn’t. Sometimes it does things wrong. But it’s very good at doing a lot of things and the use of GitHub pull requests as a review mechanism lets me fix things t hat are problems. It sure looks like Jules is doing high-order reasoning about algorithms and side effects and how systems work. I think I can trust Jules to understand this code better than I do.

    A project

    I’m using Jules to work on Feditrends, a simple scraper / link ranker that I maintain. I’ve never really touched this code, I took it over from someone else, and honestly I wasn’t excited to get my hands deep into it. Perfect thing to experiment with an AI instead.

    I started by asking it to read all the code and make suggestions for what to change. Then I had it make a simple test suite. (It’s not great, but it’s a start. I’m a fan of test driven development and ordinarily would have more tests. I think that’s important for AI coding but we gotta start somewhere.) All that done, now I’m having it make one improvement at a time as it suggests things.

    Here’s an example pull request for a very simple change: reformat a list of server names and then remove a duplicate. The code change is trivial and I was quite pedantic about it, building trust. But not shown here… Jules spotted this little code problem itself when I asked it to review the code and make suggestions. It found the duplicate. It also correctly reasoned about how this change might affect the algorithm (it doesn’t)

    AI chat transcript (partial)

    Nelson: I want to work on your suggestion “Fix Server Duplication: Remove the duplicate sfba.social in fetch.py.” look at the code and verify that the server is duplicated. then tell me, if we remove that does it change the algorithm results significantly? I’m guessing sfba.social gets double weighting in the ranking because it’s done twice.

    Jules: Regarding your question about the algorithm results: The ranking algorithm in mastodon/build.py uses count(distinct instance) to calculate the number of instances a link appears on. Because of the distinct keyword, having the same instance name twice in the database for the same snapshot should not increase the “instance count” part of the score.

    Jules: It also uses max(uses_1d) and max(rank). If the data on sfba.social changes slightly between the two fetch cycles, max(uses_1d) would take the higher value and max(rank) would take the higher (which means numerically larger, but lower/worse ranking) value. So if anything, it might slightly penalize a link if its rank drops during those few seconds, or slightly boost it if uses_1d increases, but it certainly doesn’t “double” the weighting in a straightforward way.

    Nelson: let’s go ahead and proceed with the plan to remove it. but before you remove it: please reformat the code so the list of instances in fetch.py is no longer all one line. break it up into one line per server name. but keep the duplicate. make a pull request for me to be sure you did it right. we will then remove the duplicate later, as a second change.

    It did exactly what I wanted in this case, a good result. Some other changes it gets wrong at the start and I have to catch it in review but so far I’ve been able to redirect it to success every time.

    Update: CoPilot

    A friend encouraged me to compare Jules to CoPilot Agents, built into GitHub. Roughly speaking they are very similar. CoPilot has nicer integration with GitHub, so some of the git stuff feels a bit more reliable and featureful. Different set of models of course, with CoPilot mostly being OpenAI models. It’s $10 or $20/mo to use and has some limits. I’m already getting Jules as part of my Google $20/mo AI subscription and it has no disclosed limits but only a choice of two Gemini models.

    I suspect there are meaningful differences in the two products, particularly in how they manage code environments and the details of the prompt engineering. I’m not equipped to compare them very deeply. Jules is doing well for me so far so I’ll stick with it.

  • Email woes again, CloudFlare setup

    A few months ago I gave up using monkey.org for my email and moved my email setup to my personal domain somebits.com. I was using Google Workspace as the MX entry for receiving mail for that domain; as of today I’m using CloudFlare. So far so good.

    Google Workspace problems

    The setup I was using was to pay for Google Workspace and have them receive all mail for my domain via an MX entry. Google Workspace was then told to forward all of it to my personal @gmail.com account. This worked pretty well but every once in awhile friends @yahoo.com or @hotmail.com would complain that a message bounced.

    The problem turns out to be the way Google Workspace forwards email to Gmail. They don’t do it right! I’m not confident but I think they’re not doing SRS or ARC correctly. So Gmail receives this mail claiming to be from some random @yahoo.com person and to me@gmail.com, but the mail isn’t correctly signed and so Gmail rejects it as spam. It didn’t happen often, not as often as my old monkey.org setup, but it happened enough to annoy me. Google should be able to forward mail to itself reliably!

    It’s possible I could have fixed this by not using Google Workspace to forward the whole domain and instead just to forward individually from my name @somebits.com to my personal Gmail. Some reports suggest ARC/SRS works better in this configuration. I didn’t try it.

    CloudFlare Email

    Instead I followed an AI’s advice and have switched to using CloudFlare as my MX provider, a feature they call “Email Routing”. (The other option was forwardemail.net). It’s simple but seems good. The free tier is all I need. You can have CloudFlare forward email to specific names @ your domain to specific destination email addresses. There’s also a Catch All forwarding option that’s off by default.

    The key thing is CloudFlare seems to be doing ARC and SRS stuff correctly. Email I send to myself from yahoo mail arrives fully intact and properly signed as far as Gmail is concerned. Yay!

    As part of this change I also made CloudFlare the nameserver of record for my domain instead of Porkbun. I’m not sure that’s 100% necessary but it makes things easier on CloudFlare. Also they are the best in the business at providing DNS so why not?

    One gotcha: CloudFlare email routing doesn’t support subdomains, at least not easily. I wanted to test all this just for test.somebits.com at first but it was either all of somebits.com or nothing.

    Another gotcha: CloudFlare rewrites the SPF record for your domain saying only CloudFlare is authorized to deliver email for your domain. This isn’t a total disaster, it’s a soft fail, but it means that Gmail can’t sign mail it sends for you. The solution is to hand edit the SPF record to include both Gmail and Cloudflare as authorized senders. The test address auth-results@verifier.port25.com was a big help in figuring this problem out.

    (It’s a bit weird that CloudFlare injects itself in the SPF records because CloudFlare doesn’t yet offer a service that delivers email for you. Ie, no outgoing SMTP. You have to send your mail out via Gmail or someone else. The AI says that ClouldFlare still needs an SPF record so that the mail forwarding is allowed and properly signed. Anyway a hybrid SPF record seems to work fine.)

    Update: Cloudflare is better

    Cloudflare’s email forwarding is better. All my forwarded email used to show up in my Gmail with failing SPF. Now it shows as passing. I can no longer understand email headers, particularly all the signature stuff, but apparently the difference is Cloudflare is doing the Sender Rewriting Scheme (SRS) whereas Google Workspace does not. According to Gemini the crucial difference is the Return-Path header, which reflects the data sent on the MAIL FROM part of the SMTP exchange:

    FeatureEmail 1 (Failed SPF)Email 2 (Passed SPF)
    Return-Pathsomeone@hotmail.comSRS0=tzui=rb=hotmail.com=someone@somebits.com
    SPF CheckChecked against hotmail.comChecked against somebits.com
    ResultFail (Google isn’t a Hotmail server)Pass (Cloudflare is allowed for somebits.com)

    I don’t really understand all this stuff. But Workspace seems to be just forging mail when it forwards it to Gmail, pretending to be sending on behalf of hotmail.com. Cloudflare is being more honest that the email is really from my domain somebits.com but still mentions the hotmail addresses. The actual From header is hotmail in either case, that’s the one I most care about since it’s what is displayed.

    I still think Gmail should have special rules for accepting email from Google Workspace. But I can see why they don’t, both for technical reasons and for anti-trust reasons. Failing that, why isn’t Workspace doing SRS?

  • Bidet, floor heater power usage

    I got some upgrades in my bathroom: a Toto S5 Washlet bidet and a Schluter electric heated floor. They use power! Here’s how much.

    The Toto uses 5–10W when idle. That powers a little light and a toilet seat heater (set to low). It peaks at about 500W for a minute or so when you are using heated water. We’re averaging about 0.25kWh a day for two of us, or just $0.10 a day. That seems very low!

    A Toto C5 I have was about 0.08kWh a day. That model has a water tank, not instant heat, and no seat heater nor light.

    The floor heater is set to turn on 7am-11am to 82°. It’s been 40-60° outside, the furnace heats the air inside to 68°. The bathroom is about 200 sq.ft. The heater draws a full 1300W for a couple of hours to bring the floor up to temperature, then 700Wh an hour to maintain the temperature for a couple more hours. Overall it’s about 3.5kWh a day, or about $1.50 a day. It doesn’t seem to heat the air in the room much so I think all this heat is wasted, not saving us furnace usage.

  • Notes on keyboards

    For years I’ve been using Apple’s external keyboards, the classic A1243. But mine failed so I am looking to replace it. I ended up buying some new old stock of A1243s from eBay.

    Mechanical switch keyboards are what all the keyboard hipsters like. Some folks like very loud clicky keys, ugh. But even with “silent” keys they are still noisy devices because of the physical action and motion. The other common quality option are scissor switch keyboards. That’s what Apple uses, also pretty much every laptop. Other switches in the mix.. Membrane keyboards, generally low quality. Butterfly switch keyboards, which Apple recently introduced and everyone hated. And optical switches, which kind of get lumped in with mechanical but are different. I’ve seen Hall effect keyboards advertised too.

    Keyboards come in all sorts of layouts. Keychron has a nice summary of popular layouts. I prefer the Tenkeyless (TKL) layout, which they call “80%”. 65% and 75% compact keyboards are also popular, particularly on laptops. Nothing wrong with a full 100% keyboard if you have the space, but the problem is it pushes the mouse further to the right. I never use the tenkey pad so prefer to not have it.

    Good keyboards have features called “anti-ghosting” and “n key rollover” which make typing better. The problem is when you press several keys at once, particularly gaming. What happens? With ghosting you press two keys and the keyboard registers some completely third keystroke. Rollover refers to how many keys you can press at once and have them recognized. This site lets you test it your rollover. USB devices are limited to 6 keys at once, a protocol limitation. Keychron delivers the full 6 keys. My Apple 1324 delivers somewhere between 3 and 5 depending on which key you press. A Cherry keyboard I tried sometimes only sends 2. It also has ghosting. It is cheap.

    Keyboards come wired, Bluetooth, or proprietary 2.4GHz wireless. The Bluetooth ones historically have been laggier and have worse battery life. Folks get all twisted up about keyboard latency but I think in practice it’s like 4ms or better in any practical setup. Anti-ghosting adds lag too, or maybe it’s debouncing.

    Keychron is a good option for well made relatively inexpensive mechanical keyboards. I have a K1 Pro that I like pretty well. Even with low profile keycaps it still sits taller than an Apple scissor switch keyboard. And even with the red silent switches it’s still kind of noisy, a meaty thunk as each key bottoms out. I gather you can stuff foam inside the keyboard to quiet that.

    I cannot find a good scissor switch keyboard other than Apple’s. Apple’s is unusual in having just 0.9mm travel, very very slim. Also their manufacturing is just impeccable. Unfortunately the new keyboards are like $200 and have features I can’t use. That’s why I may buy some used ones.

    Matias scissor keyboards comes close but there’s something about their keycaps that constantly has me mis-keying when I type. I wrote their support and they said compared to Apple their keyboards has 2.0mm travel (not my problem) and something about the dome design meant you had to hit the keys in the middle (probably my problem).

    The Cherry Stream is popular as a cheap quality scissor keyboard. It is well made for the price. But the keys feel heavy and squishy and the keycaps have this weirdly angled design that makes it hard to type on.

    There are other scissor options I haven’t pursued yet. I’ve mostly been looking for Tenkeyless layouts and those are rare. May need to give up on that.

    I ended up ordering a couple of new-in-box Apple A1243s on eBay. They stopped making these in 2017. I found some for about $70 delivered which is a pretty good price for new. Used seem to be $30-$100 depending on which order you look at. Amazon has refurbished ones for about $80. The new ones that arrived do appear to be genuine and work.

    Totally different thing but I love these tiny palmtop keyboards. Smaller than a game controller. Definitely not for real typing but great for a PC plugged in to your TV where you occasionally have to press one or two keys.

  • Portable monitor for desktop use

    There’s a new class of “portable monitors” that are small: 14″, 15.6″, etc. But high density, often 4K resolution, and surprisingly bright. These are basically laptop screens in a package to use as standalone monitors. They’re intended to be used portably with a little cover / stand but you can use one for your desktop too. It’s just not simple to mount them! Read on for notes on finding a small second monitor and mounting it on a VESA stand.

    Here’s my new setup. At left is the 31.5″ 6K screen, an ASUS ProArt. At right is a UPERFECT 15.6″ 4K display mounted on a FeeLazy 75mm VESA mount. I am using that as a second screen for side distractions, like Slack or Signal. (I used to have a 34″ ultrawide, just one screen, but the new 16:9 monitor isn’t wide enough to let me have a main window and then something useful to the side.)

    Portable monitors

    Portable monitors are a new product category to me. They take USB power in and HDMI or DisplayPort or USB-C/Thunderbolt for the video. No battery in the ones I’ve seen but they are designed to be portable and easy to set up anywhere.

    NewEgg has a wide selection but if you look closely the brand UPERFECT dominates. They are astonishingly cheap: I paid $130 for a 15.6″ 4K display with superior brightness (450 nits) and good color. It’s only 8 bit SDR, and 60Hz, but within those constraints it’s great. Let’s see how long it lasts, there are reports this kind of hardware tends to overheat and have a short lifespan.

    UPERFECT has a wide variety of portable displays for different needs: low density, high density, high refresh for gaming. They sell via NewEgg and direct but not via Amazon. The one I picked seemed particularly good for cheap desktop use.

    Portable monitor stands

    The one drawback is it doesn’t come with a stand. It has a little magnetic cover that can fold back and hold it up in landscape mode. But I wanted this mounted like a desktop monitor, and in portrait mode. That proved surprisingly difficult.

    The good thing is UPERFECT monitors have VESA mounting holes. Not all portable monitors do. Mine has four M3 screw holes at 75mm x 75mm VESA spacing. The screw holes are very shallow, they recommend 6mm screws and I think the hole itself is probably just 4mm deep. That makes mounting difficult. (The manual claims the screws are M4 6mm but that is not true: it’s M3 6mm).

    The first stand I tried is well built but too big for the application. The whole thing is just big, it’s designed for full size monitors. Also it supports both 75×75 and 100×100 VESA mounts. That’s nice but the 100×100 hangs off the edge of the monitor! Not great. (If you do try to use a bigger mount like this, note that M3 screws are tiny: you will need large washers to work with the big mounting holes.)

    The stand I’m using is a FeeLazy stand designed for portable monitors. The build quality is not great. The monitor plate is plastic, the mount joint is a screwy ball-and-socket thing that does not feel terribly secure. But it’s OK for a small light monitor. It’s working well enough and feels right-sized for the screen. Other small stand options include this JUNEBOX or maybe a stand from UPERFECT.

    Overall I’m happy with this setup. With the new 16:9 monitor I was missing a place out of the way to put small windows. Now I have one.

  • Chromebooks identify USB C details

    I learned something neat from a Google engineer on Reddit the other day: Chromebooks have superpowers when diagnosing USB-C connections that PCs don’t have. Including reading the e-marker built into the cable that identifies its capabilities.

    Modern USB is a remarkably complex thing, with both the cable and the device on the other end negotiating capabilities like speeds, power for charging, etc. Most of that isn’t particularly visible to the user, not without USB debugging hardware. But turns out on a Chromebook it’s as simple as plugging in the USB device, going to chrome://system, and reading the info from typec_connector_class. At the bottom is an example with my Chromebook plugged into an Anker 65W charger, charging at 37W on a cable that nominally supports 100W.

    Yeah I’ve got no idea what all that debug dump means either. I asked Gemini and it identifies the charger as doing Power Delivery 3.0 and that it offers various charging power settings including a programmable power up to 11V at 4.55A.

    As for the cable, Gemini says that Vbus Current Handling: 0x2 is the cable’s way of saying it can handle 3A at most, which makes me wonder about that 100W claim on the cable. The product_type_vdo1: 0x84050 is a bitmask identifying various cable capabilities. This one is USB 2.0 only, 3A max. Ie: a “charging cable” and not a very good one at that. (The neat thing about this cable is it has a little display built in, that’s what says it’s charging at 37W. Maybe 15V or 20V and not at full 3A draw?)

    The Reddit discussion has more detail. The Linux typec driver is doing a bunch of work along with a typec daemon in userspace. Unfortunately it requires cooperation from the firmware on the computer to make this information available to the kernel and PC hardware doesn’t do it.

    port0
    uevent: DEVTYPE=typec_port
    TYPEC_PORT=port0
    vconn_source: yes
    supported_accessory_modes: none
    power_role: source [sink]
    data_role: [host] device
    preferred_role: source
    power_operation_mode: usb_power_delivery
    usb_power_delivery_revision: 0.0
    usb_typec_revision: 0.0
    waiting_for_supplier: 0
    port0-partner
    uevent: DEVTYPE=typec_partner
    accessory_mode: none
    usb_power_delivery_revision: 3.0
    type: not_ufp
    number_of_alternate_modes: 0
    supports_usb_power_delivery: yes
    identity
    id_header: 0x180ffff
    USB Vendor ID: 0xffff
    Reserved: 0x0
    Product Type (DFP): 0x3
    Modal Operation Supported: 0x0
    Product Type (UFP/Cable Plug): 0x0
    USB Capable as a USB Device: 0x0
    USB Capable as a USB Host: 0x0
    product: 0xffffffff
    bcdDevice: 0xffff
    USB Product ID: 0xffff
    cert_stat: 0x0
    XID: 0x0
    product_type_vdo1: 0x0
    Port Number: 0x0
    Reserved: 0x0
    Host Capability: 0x0
    Reserved: 0x0
    DFP VDO Version: 0x0
    product_type_vdo2: 0x0
    product_type_vdo3: 0x0
    pd0
    uevent: DEVTYPE=usb_power_delivery
    revision: 3.0
    sink-capabilities
    uevent:
    source-capabilities
    uevent:
    4:fixed_supply
    uevent:
    maximum_current: 2050mA
    voltage: 20000mV
    1:fixed_supply
    uevent:
    dual_role_power: 0
    unconstrained_power: 1
    usb_communication_capable: 0
    unchunked_extended_messages_supported: 0
    maximum_current: 3000mA
    usb_suspend_supported: 0
    dual_role_data: 1
    voltage: 5000mV
    2:fixed_supply
    uevent:
    maximum_current: 3000mA
    voltage: 9000mV
    3:fixed_supply
    uevent:
    maximum_current: 2730mA
    voltage: 15000mV
    5:programmable_supply
    uevent:
    pps_power_limited: 1
    minimum_voltage: 3300mV
    maximum_voltage: 11000mV
    maximum_current: 4550mA
    port0-cable
    uevent: DEVTYPE=typec_cable
    usb_power_delivery_revision: 2.0
    type: passive
    plug_type: type-c
    identity
    id_header: 0x18000000
    USB Vendor ID: 0x0
    Reserved: 0x0
    Modal Operation Supported: 0x0
    Product Type: 0x3
    USB Capable as a USB Device: 0x0
    USB Capable as a USB Host: 0x0
    product: 0x0
    bcdDevice: 0x0
    USB Product ID: 0x0
    cert_stat: 0x0
    XID: 0x0
    product_type_vdo1: 0x84050
    USB Speed: 0x0
    SOP'' Controller Present: 0x0
    Vbus Through Cable: 0x1
    Vbus Current Handling: 0x2
    SSRX2 Directionality Support: 0x0
    SSRX1 Directionality Support: 0x0
    SSTX2 Directionality Support: 0x0
    SSTX1 Directionality Support: 0x0
    Cable Termination Type: 0x0
    Cable Latency: 0x2
    Reserved: 0x0
    USB Type-C Plug to USB Type: 0x2
    Reserved: 0x0
    Firmware Version: 0x0
    HW Version: 0x0
    product_type_vdo2: 0x0
    product_type_vdo3: 0x0
    port0-plug0
    uevent: DEVTYPE=typec_plug
    number_of_alternate_modes: 0
    physical_location
    panel: left
    horizontal_position: left