Repository navigation
Releases: sergeyerin/netspeed
Release list
NetSpeed 1.32
A narrower item that stops changing shape
Twenty-four points came off the figures, and the reading now looks the same
whatever it says.
The scale can step down to bytes. Its floor was kilobytes, which made an
idle link read 0 KB/s — a quiet lie, since something is nearly always
trickling — and forced a fourth column on the figure to cover the range the
unit could not reach. Free to step, the figure always lands between 1 and 999,
and three columns hold it: 412 B/s, 51.7 KB/s, 114.4 MB/s.
Nothing moving holds the scale where the traffic left it. Allowed to step,
a pause in a megabyte download walked the unit down to 0.0 B/s inside three
ticks — a reading in a unit with nothing to do with what was happening a second
earlier. Only an exact zero holds it; a trickle still steps it down, so a real
change of régime is never masked.
The tenth is always there, a size down. It used to come and go — present
below ten, absent above it, absent again at zero — so the figure changed shape
as well as value, and the eye re-read it every time. It keeps the figures' own
baseline, unlike the unit, because it is part of the number rather than a note
about it.
What that took, for anyone who follows
The suffix is padded to the width of the longest: B/s is a character shorter
than KB/s, and without it the item jumped a character wide whenever the scale
crossed a kilobyte — which, on an idle link, is constantly. The padding space
has to be set in the unit's smaller size, or it puts the width straight back.
And the space touching the unit is tightened exactly once: applied to each of
them, the pair before B/s pulled a kern further than the single one before
KB/s, and the width drifted again.
Universal build — Apple silicon and Intel in one image.
Gatekeeper will not open an unsigned app from the internet on the first try:
drag NetSpeed to Applications, then right-click it and choose Open.
NetSpeed 1.31
The figures come first now
The indicator moved to the right of them, which closed a hole nobody could
place. The rates are padded to a constant width, so a short one carries leading
spaces — and with the icon on the left those spaces sat between the two,
opening and closing with the traffic. On the right they fall at the outer edge,
where nothing tells them apart from the gap to the next item in the menu bar.
The icon also carries its own seven points of space now. A button sets its image
against its title with nothing between them, and the s of KB/s was touching
the first chevron.
Three type sizes, measured rather than guessed
The figures are 13 point, two up: they are the whole message, and they sat
smaller than the clock beside them. The unit is 77% of that and sits half a
point of ink below them.
Reaching even that takes a lift, not a drop — on a shared baseline the smaller
type already hangs a point lower, partly its metrics, partly the slash in
KB/s, which descends. A deliberate drop was tried first, after a speedometer,
and does not carry at this size: there the number is forty points tall.
Both numbers were measured on the rendered strip. The font's metrics say nothing
about the slash.
Tenths where they decide something
Gone from kilobytes, where the last digit changed every tick without ever
changing a decision — nobody acts on 52.9 against 53.1 KB/s.
Kept in megabytes while they fit, where dropping them costs a whole decade of
resolution: 1.1 and 1.9 MB/s would both read 1.
Always kilobytes
A new setting under Menu bar display, off by default.
Scaling is work the reader has to undo: 1.2 MB/s and 980 KB/s arrive a
second apart, and comparing them means converting one in your head. Pinned to
kilobytes, the figure only ever grows.
It is off by default because a gigabit link then reads 125000 KB/s — six
digits, sixteen points wider. On a mobile link the scale never leaves kilo
anyway, so there it costs nothing.
Universal build — Apple silicon and Intel in one image.
Gatekeeper will not open an unsigned app from the internet on the first try:
drag NetSpeed to Applications, then right-click it and choose Open.
NetSpeed 1.30
The app can tell you which build it is
A local build and a release carried the same version number and were otherwise
identical. Every build now carries what git describe said about it: a release
reads v1.30, anything else carries its distance from the tag or a -dirty
suffix. The menu says About NetSpeed — local build when it is one.
About is a window
Checking for updates takes a second or two, and a menu cannot wait — the click
that started the request also closed the menu, leaving the answer to arrive in
a row nobody was looking at. The window keeps the question and the answer in
one place: version, build, the check and its result, the daily-check setting
and the links, all of which were scattered across a submenu before.
The menu's tail has an order
It read as a heap because the order was accidental: the update row sat between
two unrelated submenus, the hotspot offer between About and Copy summary. Four
groups now, by who the item is about —
- news that wants an answer: a new release, a phone that could be asked to share
- actions on what the panel is showing: Traffic by process, Copy summary
- the app itself: Settings, About
- Quit, alone, where every Mac menu keeps it
The separator above the first group hides along with it, since both its rows are
usually absent.
"Ask the phone to share again" is offered only while disconnected. It asks a
phone to switch its hotspot back on, which has no subject while sitting on that
hotspot — that is the state the button exists to reach.
A row that explained a verdict with someone else's numbers
The latency line reported over the whole ring — twenty probes at ten seconds
apiece, better than three minutes — while the verdict above it is decided on the
last six. Both were labelled "loss" and they disagreed whenever the link was
changing, which is the only time anyone reads them. On a ring with a bad start
and a better finish, the two read 80% and 33%.
Everything in that row now comes from the window the verdict used.
Also
Every cellular type a tethered phone reports is logged with its time to
~/Library/Logs/NetSpeed/cellular-types.log. The enum behind those numbers is
undocumented, and the table naming them rests on two confirmed observations and
five inferences — the log means the next disagreement costs a glance at the
Wi-Fi menu rather than an investigation.
Universal build — Apple silicon and Intel in one image.
Gatekeeper will not open an unsigned app from the internet on the first try:
drag NetSpeed to Applications, then right-click it and choose Open.
NetSpeed 1.29
The top of the menu, gone over properly
Three type sizes with intent, instead of four that happened. The header
carried 13 bold, 12, 15 and 14 — and the largest thing on it was the pair of
arrows, which are markers rather than data. The figures are now the biggest,
because they are what gets read; the verdict follows as the headline in its own
colour; the arrows and the qualifier share a quiet third size.
The chart has margins. They were lopsided in a way that is obvious once
measured: the top label sat two points off the chart's frame, and the bottom
pair sat at y = 0 — flush against the view's own edge, and so against the
first row of the table below. Labels now clear the frame by the same amount at
both ends, with the same air beyond them.
The ↓ down ↑ up key is gone. It was painted in the darker inks that text
uses, not the bright fills it was labelling — a key in the wrong colours is
worse than none. And it explained what the header directly above already pairs:
the blue figure against the orange one. Direction is in the chart itself, which
puts download above the midline and upload below.
The verdict's tooltip left and came back. It was removed on the theory that it
was the pale box appearing over the chart's hover reading; measuring a
screenshot showed that box to be a bright window behind a translucent menu — a
forty-point gradient, which no flat fill in this app can produce.
Universal build — Apple silicon and Intel in one image.
Gatekeeper will not open an unsigned app from the internet on the first try:
drag NetSpeed to Applications, then right-click it and choose Open.
NetSpeed 1.28
One line where there were three
The menu's header carried an indicator, the verdict beside it, and the two
speeds on a row of their own.
The indicator went first. It sat a few points below the one in the menu bar and
repeated it — and since the chase only runs on the status item, repeated it
worse. Nothing was lost with it: its colour is on the verdict word, and its
chevron count is the figures beside it.
That left two short rows where one does. The verdict, its qualifier and both
speeds now share a line:
Good (phone: LTE) ↓ 1.2 MB/s ↑ 86.0 KB/s
The header drops from 68 points to 36, and the verdict starts on the same left
edge as every row beneath it rather than being pushed right by an icon.
Four type sizes meet on that row, so everything is placed from a shared
baseline — aligned by their tops, the small words would sit visibly high. The
qualifier takes whatever the figures leave and truncates rather than colliding
with them: Fair (weak 4G-like) beside two four-figure rates does not fit on
any width this menu has.
Universal build — Apple silicon and Intel in one image.
Gatekeeper will not open an unsigned app from the internet on the first try:
drag NetSpeed to Applications, then right-click it and choose Open.
NetSpeed 1.27
A label that had to be explained
The short form's country row read Appears from 🇳🇱 NL, which points the wrong
way — traffic appears from somewhere only to whoever is receiving it. From
here the sentence is "appears in the Netherlands", so the row now reads
Appears in 🇳🇱 NL.
It failed a plain test: the person who owns the app had to ask what it meant.
Universal build — Apple silicon and Intel in one image.
Gatekeeper will not open an unsigned app from the internet on the first try:
drag NetSpeed to Applications, then right-click it and choose Open.
NetSpeed 1.26
Where does my traffic come out
The short form of the menu carried two rows for this and neither was an answer:
VPN utun4 over en0
External IP 203.0.113.42 (🇳🇱 NL)
A pair of interface names is diagnostics, and an address is a number to copy
rather than to read. Both have moved to Show all details, where they were
anyway. One row takes their place, carrying the part anyone actually reads:
Appears from 🇳🇱 NL no tunnel
VPN 🇳🇱 NL a tunnel put it there
The VPN is also no longer mentioned twice in six lines — it used to appear
beside the network's name as well.
No "on" next to the flag: the row only exists while the tunnel does. The word
comes back in one case, where the country is not known yet and the value would
otherwise be blank, which reads as a fault rather than as brevity.
Universal build — Apple silicon and Intel in one image.
Gatekeeper will not open an unsigned app from the internet on the first try:
drag NetSpeed to Applications, then right-click it and choose Open.
Note that an unsigned app also gets a fresh identity with every release, so
macOS asks again for the Location permission behind network names after each
update. Nothing is lost by refusing — only that one row.
NetSpeed 1.25
The network was called <redacted>
It was not. That is the literal string macOS substitutes when an app may not
read the name of the Wi-Fi network, and the menu was passing it along as though
it were the name.
The app used to get the name from ipconfig getsummary, which answered without
any permission and, on current macOS, no longer does — it redacts the same way
CoreWLAN does. The fallback had quietly stopped being a fallback.
Hidden, and a way out where you can see it
The row now says the name is hidden and offers the one thing that fixes it,
right where the problem is:
| the row says | clicking it | |
|---|---|---|
| never asked | hidden — click to allow |
shows the system prompt |
| refused | hidden — open Settings |
opens Location Services |
| allowed | the network's name | — |
Three sentences for three states, because the prompt appears once and never
again: a row promising "click to allow" that then silently does nothing would
be worse than no row at all.
Why Location, of all things
macOS treats a network's name as location data, and fairly — knowing which
access point a Mac is joined to places it about as well as GPS would.
NetSpeed still asks for nothing at launch and works fully with nothing granted.
It never asks the system for a position; CoreLocation is here for its
authorisation status alone, and the prompt says so. Signal, noise, link rate,
channel, band, width, PHY mode and security need no permission and are there
either way.
Universal build — Apple silicon and Intel in one image.
Gatekeeper will not open an unsigned app from the internet on the first try:
drag NetSpeed to Applications, then right-click it and choose Open.
NetSpeed 1.24
The phone's details could vanish mid-session
The hotspot row and the network-type badge would disappear while still
connected to the hotspot, and not come back.
The reading came from LastTetherDevice, a snapshot macOS keeps in the dynamic
store — and macOS drops that key when the Mac rejoins the network. No key, no
phone, no badge.
CoreWLAN's live object had been answering the whole time, and answering better.
Asked in the same second about the same phone, the two disagreed:
| stored snapshot | live object | |
|---|---|---|
| battery | 50% | 75% |
The snapshot was an hour out of date. The live object is now asked first, and
the snapshot is kept only as a fallback for when it is missing.
This also settles something left open in 1.23, where the reported network type
disagreed with the phone's own screen and the figures looked frozen. They were
frozen — but only in the copy.
Universal build — Apple silicon and Intel in one image.
Gatekeeper will not open an unsigned app from the internet on the first try:
drag NetSpeed to Applications, then right-click it and choose Open.
NetSpeed 1.23
It said 5G while the phone said LTE
The hotspot's network type was one step too generous. A phone on LTE was
labelled 5G, both in the menu bar and in the menu.
macOS has no documented way to ask a tethered phone what network it is on. The
class that carries the answer, CWTetherDevice, exists in CoreWLAN's symbol
table and appears in none of its eleven public headers — no class, no method,
and nothing anywhere that says what the numbers mean. They have to be worked
out by watching.
The earlier reading came from ControlCenter, which holds seven labels for the
enum — 1x, GPRS, EDGE, 3G, 4G, LTE, 5G — taken as 1 through 7. That put LTE
at 6 and 5G at 7, and it was wrong.
LTE actually arrives as 7. For it to land there, two cases ahead of the
labelled ones must carry no label at all: nothing reported, and something
unrecognised. LTE is 7 and 5G is 8.
| raw | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
|---|---|---|---|---|---|---|---|---|---|
| shown | — | — | 1x |
G |
E |
3G |
4G |
LTE |
5G |
What settled it was seeing both at once: the system's own Wi-Fi menu naming the
device LTE in the same moment the raw value read 7. Nothing inside the app
could have caught this — the live CoreWLAN object reports the same number as
the stored one, so the two sources agree with each other and neither explains
what the number means.
Two points are now confirmed by observation: 7 is LTE, and 0 and 1 mean nothing
was reported. The rest of the table follows from the same reasoning but has not
been seen. If your phone shows a type the menu bar disagrees with, that is worth
reporting.
Both unlabelled cases now leave the badge empty rather than printing a dash,
which states nothing and costs room on a row that has none to spare.
Universal build — Apple silicon and Intel in one image.
Gatekeeper will not open an unsigned app from the internet on the first try:
drag NetSpeed to Applications, then right-click it and choose Open.