Skip to content

Plonk 0.3.0

Choose a tag to compare

@github-actions github-actions released this 18 Aug 09:20
· 50 commits to main since this release
4b36df6

The first minor since 0.2. Rectangle users can bring their bindings across,
the zone sets can be seen as a list, there is a ruler for the screen, and the
app can keep a Mac awake through a meeting. Under it, every string moved into
one catalog and a hand-edited config is held to the same limits as the sliders.

Added

  • Switching from Rectangle costs nothing now. The ten placement shortcuts
    were already the same keys in both apps — ⌃⌥ and an arrow, a corner letter,
    return or C — because that is the one combination macOS leaves alone and both
    landed on it. What was missing was everything either side of that: a changed
    binding had to be re-entered by hand, and a rectangle://execute-action URL
    sitting in a Raycast script or on a Stream Deck button did nothing at all.

    Plonk looks once at launch, and a Mac with a Rectangle setup on it gets the
    offer on the Home page rather than a button on a settings page nobody opens
    first. Taking it or turning it down settles it for good, and a Mac with no
    Rectangle is shown nothing.

    Shortcuts → Import from Rectangle reads the preferences of an installed
    copy, or a RectangleConfig.json exported from an old machine, and takes the
    bindings that mean the same thing here: the halves, the corners, maximize,
    centre, restore, and the window gap. Rectangle's thirds, sixths, eighths and
    ninths are deliberately left behind and named instead of imported. They are a
    fixed grid; the equivalent here is a zone set, and there is no way to know
    which numbered zone a "first third" should be without knowing what set that
    screen is wearing. If an imported key was already doing something — ⌃⌥T
    copies text out of a region — the imported binding wins and the app says what
    lost it, and a Rectangle whose bindings are all fixed-grid is told apart
    from one that is not there at all.

    URLs answer to the same verb and the same names:
    open -g "plonk://execute-action?name=left-half". The ten placements are
    spelled exactly as Rectangle spells them and restore is accepted alongside
    unsnap, so an existing script is one sed away. Past that the vocabulary is
    this app's own: zone-1 to zone-9, zone-set-1 to zone-set-9,
    cycle-zone, focus-left, capture-text, ruler, and one name for every
    other shortcut. Asking for a fixed-grid action, or for next-display, says so
    on screen rather than failing quietly — the nearest thing to next-display
    here moves the pointer and not the window, and answering to the name while
    doing something else would be worse than not answering.

    rectangle:// is declared as well, but answering it is a switch on the
    Shortcuts page and it is off. A scheme belongs to one app at a time, so
    turning it on takes those URLs from an installed Rectangle and its own stop
    working, with nothing to say so. Off is not passive: declaring a scheme is
    enough for macOS to hand it over on install, so a rectangle:// URL arriving
    while the switch is off makes Plonk give the scheme back to Rectangle and run
    that one URL anyway. The switch reads its state back from macOS rather than
    from config, so it shows what is true rather than what was asked for.

    docs/from-rectangle.md is the whole of it, including
    what happens when both apps are running and hold the same key.

  • Stay active, a page of its own under Settings, for the thing keep-awake
    was never able to do: stop Slack and Teams showing you as Away. They do not
    ask whether the Mac is asleep, they ask how long it is since the last
    keypress, and a power assertion does not touch that number. Stay active
    resets it with a Shift every two minutes. Run it by hand with a timeout, on a
    schedule of hours and weekdays, or while a chosen app is open. The schedule is
    read from the clock rather than fired by a timer, so a Mac that slept through
    09:00 and woke at 11:00 is inside the window rather than waiting for tomorrow,
    and a window may cross midnight. Off on battery unless you allow it, and it
    needs Accessibility — without the permission the page says so instead of
    quietly sending nothing. Agents get set_active.

  • The zone sets, as a list you can see. ⌃⌥L draws every set available for
    the screen the cursor is on, each one as a small picture of itself, with the
    one that screen is wearing marked. Arrows or the digit picks, return puts it
    on the screen, E opens it in the fullscreen editor, N starts a new one,
    Escape leaves everything as it was.

    ⌃⌥⇧1⌃⌥⇧9 already swapped a set, but only for someone who remembers which
    set is number four. The digits in the list are those same numbers, so the list
    is also the thing that teaches them. Editing from here duplicates a built-in
    template first, exactly as the Zones window does, so the shipped sets stay
    intact.

  • A ruler for the screen. ⌃⌥R, then hover: Plonk photographs the screen
    once, walks out from the pointer in all four directions until one pixel is
    unlike the one beside it, and draws each run as a dimension line with its own
    number. That is the width of a row, the height of a bar, the size of the gap
    between two things, without anybody aiming a drag at a corner. Drag instead
    and it measures a straight line. Points and pixels both, because a 44-point
    tap target is 88 pixels and only one of those numbers is in the asset. A click
    copies, Space takes a fresh picture of the screen, Escape ends it.

    Two numbers on two lines rather than a box: the run across and the run down
    are separate answers, often about different things, and a rectangle drawn
    round them would claim they are the sides of one object — the one thing
    pixels cannot say.

    Borrowed from PowerToys' Screen Ruler, tolerance setting included, on the
    Ruler page under Capture. Ten out of 255 suits an interface: gradients and
    shadows step by less, borders by more. Raise it for a photograph or a video,
    where every pixel differs a little from the last.

  • measure_screen for agents, and plonk measure for a shell. The same
    measurement without a person: hand it a point and it answers with the two
    runs through it, or two points and it answers with the distance. The reply
    carries the points, the display's own pixels, and the fraction of the screen
    ready to hand back to apply_layout. An agent that would have taken a
    screenshot and guessed at sizes can ask for the number instead, at a fraction
    of the tokens. interactive: true hands the ruler to the user and waits for
    what they measure. Needs Screen Recording, like every other capture.

Changed

  • A hand-edited config.json is held to the same limits the sliders are.
    A gap of 100, an opacity of 0.02 or an edge span of 200 used to be honoured
    verbatim and could leave zones you could not see or windows with nothing left
    of them. They are now brought inside the same bounds on load, wherever the
    value came from. Nothing else about the file changed: it is written exactly
    as before.

  • A null in config.json costs you that one setting, not all of them.
    Any field written as null — by hand, or by a tool that spells "unset" that
    way — used to make the whole file unreadable, which set it aside and reset
    every setting, workspace and zone set you had. It now reads as "not set" and
    falls back to that field's default, which is what a missing key has always
    done.

  • The window looks like the rest of Plonk now. Colour is the zone number
    everywhere it is drawn, so the sidebar, the Zones page, the website and the
    README all say the same thing the same way. The sidebar lists every page under
    the heading it belongs to instead of hiding ten of them behind groups that
    expanded, the selected row is the accent rather than a grey fill, and the
    Zones page opens with the set named in full, what it is running under it, and
    each zone printing the fraction an agent would send for it.

  • The README and the docs dropped the screen recordings that still showed
    the old single-accent overlay. What replaced them is drawn to the same palette
    as the app, so a picture cannot go stale the next time the interface moves.

  • Every word the app says now lives in one file. The text was written into
    the views that draw it, spread across sixty-odd Swift files, which meant a
    second language would have had to start by unpicking all of them. It is a
    string catalog now — Resources/en.lproj/Localizable.strings, with counted
    things in Localizable.stringsdict so plural rules belong to the language
    rather than to the code — and the source holds keys. Adding a language is one
    new folder beside the English one and no Swift at all.

    Nothing looks different, and that is the point: this is the groundwork, not
    the translation. Two things did have to change underneath. A shortcut's group
    ("Halves", "Numbered zones") was both the heading on screen and the value the
    pages filtered on, so translating it would have quietly emptied those lists;
    the two are separate now. And a handful of sentences are read by a person and
    by an agent both — the update status, the keep-awake status, why an app in a
    workspace did not land — so those reach the API in whatever language the app
    is running in. Every machine-readable field beside them is untouched: ids,
    route names and phase stay English, because that is the half a client
    actually branches on.

    The two permission dialogs macOS draws are covered too, through an
    InfoPlist.strings beside the catalog, since Info.plist itself cannot be
    translated.

Fixed

  • An update check that failed offline runs again when the network is back.
    It stopped at "The update check failed: The Internet connection appears to be
    offline", and that is where it stayed: nothing watched for the network
    returning, so the next attempt was the daily timer or the Check Now button. A
    copy launched away from a network sat on a day-old error next to a version it
    had never managed to check. Only that failure is retried, and only while
    automatic checks are on — a Wi-Fi hop does not re-ask GitHub about a feed that
    answered badly, and with checks turned off the buttons are still the only way
    a connection is opened.

Built from 4b36df6ce97cbda097cc38ee8c85d72210e1b78e by this run.
Verify it against that commit before installing:

gh attestation verify Plonk-0.3.0.zip -R ostapondo/Plonk

The attestation is also on this release as Plonk-0.3.0.zip.sigstore.json.

sha256: 94c998cbc72e11409e223b0e2d6761003120c037942ef3355632717ef0a2c449

Install: brew install --cask ostapondo/plonk/plonk