Releases: akshit-bansal11/edgepad
Release list
Edgepad v2.2.0
Three fixes and the first outside contribution. Nothing about the wire protocol moves:
it stays at version 3, so a 2.2.0 half and a 2.1.0 half still speak to each other.
Update both anyway -- the browser-title fix is on the laptop and what it corrects shows
up on the phone.
Fixed
- A service name matched inside an ordinary word named the wrong thing. The laptop reads
the service out of the browser's window title, and it matched with a plain substring test.
It also searches every visible browser window, not just the one playing, and returns on
the first title that matches anything — so a tab titled "Twitches (2005)" made the phone say
Twitch while the tab actually playing said YouTube right there in its own title. Each
name now has to stand as its own word. The trailing lookahead is deliberately not a second
word boundary: "Paramount+" and "Disney+" end in a non-word character, which has no boundary
after it, so the obvious spelling would have matched neither. All nineteen names and the
false positives are covered by tests.
Changed
- The trackpad stopped allocating on the touch path.
ControlSurfacebuilt a fresh pair of
FloatArrays for every touch sample handed to the gesture recogniser, and for every
historical sample inside each event. The surface asks for unbuffered dispatch, so samples
arrive as fast as the digitiser makes them: one finger dragging produced a steady stream of
short-lived garbage on the one path in the app written to be fast — the same defect fixed in
the gamepad in 1.0.0, which Android lint cannot see becauseDrawAllocationonly inspects a
method literally namedonDraw. It now fills one pair of buffers sized once at
MAX_POINTERSand passes an explicit finger count. No gesture, threshold or feel constant
moves, and the recogniser's tests are unchanged —countdefaults to the array's own size,
so every existing caller reads as it did.
Tests
- The shared protocol fixture now carries non-ASCII titles. Every
TEXTline in
protocol/frames.txtwas pure ASCII, so nothing proved the two codecs agreed on a
single multi-byte character -- andTEXTis the frame that carries track titles and
artist names, which routinely are not. Three lines added, two, four and three bytes of
UTF-8, each with a UTF-8 byte count that differs from its UTF-16 length: if either side
ever counted UTF-16 units, the length header would not match and both suites would fail
on the same line. Contributed by @wized2 in
#7 -- the first outside change to
Edgepad. Their three lines landed underTEXTkinds 4, 5 and 6, which are already
REFRESH_RATESandMACROSand, for 6, nothing at all; the codecs do not validate the
kind byte, so both suites passed and the documentation site would have published the
contradiction. Corrected to kind 0,NOW_PLAYING, keeping the characters exactly.
Edgepad v2.1.0
Both apps now carry a link to the documentation, and the documentation now exists. Nothing
about the wire protocol moves: it stays at version 3, so a 2.1.0 half and a 2.0.0 half
still speak to each other. Update both anyway, so both ends know where the manual is.
Added
- A link to the documentation in both apps. The phone gets a Documentation row under
Settings › Help, beneath the Guide; the laptop gets a Documentation item in its tray
menu. Both open https://edgepad-docs.vercel.app. One page, linked from both halves,
rather than each half explaining itself. Neither touches the wire protocol.
Documentation
- The README's tray-menu listing was stale. It had never mentioned Macros…, added in
2.0.0, and now also names Documentation. - A documentation site, in
site/. One page: what Edgepad is, how to install and use
it, the architecture of both halves, the wire protocol, the trust model, and the
developer guide. Its frame, action and control tables are generated from
protocol/frames.txtandprotocol/actions.txtat build time — the same two fixtures
both test suites read — so the page cannot drift from the apps the way a hand-typed
copy would. A fixture it cannot parse fails the build rather than rendering an empty
table. Next.js, checked by its own gate (Biome, ESLint, tsc) in its own workflow, which
runs only whensite/**orprotocol/**changes. SECURITY.mdclaimed the phone cannot send a key code. It can, and always could:
KEYcarries a raw Windows virtual-key code andTEXTkind 3 carries arbitrary text,
because that is what the phone's keyboard screen is. 2.0.0 corrected this claim in
three places and missed this one, which is the file a reader checks first. The action
and control table keeps the two halves independently versionable; it is not a
containment boundary. The trust boundary is the Bluetooth pairing plus
trust-on-first-use.
Edgepad v2.0.0
Macro buttons: the phone can now launch things on the laptop. That is the headline, and it is why this is a
major release rather than a minor one — the wire protocol is unchanged at version 3. The refresh-rate
dial and the macro buttons are new ids in tables that already existed, and an unknown id is dropped and
counted rather than treated as an error, so a 2.0.0 half and a 1.0.0 half still speak to each other. Update
both anyway: only the pair knows about the new controls.
Added
- Macro buttons. The laptop's tray menu gains a Macros editor: name an app, a document, a folder or a
URL, and it appears as a button on the phone — a 5x3 grid, fifteen of them. Fifteen is what one frame can
name, so a full grid always arrives labelled rather than trailing off into blank buttons. The phone sends
a slot number, never what the slot opens: a button cannot be repointed from the phone, and the laptop's
own list is the only thing that decides what runs. - A refresh-rate dial. Steps the laptop's display through the rates it actually offers, filtered to the
resolution and colour depth already in use so a rate can never drag the desktop to another size. The
switch is for this session only; a dial should not decide what the desktop boots at. - An on-screen readout on the laptop. Sliding volume, microphone or brightness from the phone now shows
a small panel on the laptop. Windows draws one for its own volume keys but not for a level set through
Core Audio or WMI, so until now brightness changed with no feedback at all. - Pointer speed and scroll speed are settings rather than constants, on the renamed Trackpad screen.
- A sensitivity of its own for each dial kind. Volume runs 0-100 under a thumb and wants a slow ruler
where the app switcher wants a fast one. A dial left on SHARED still follows the one slider.
Changed
- Two-finger gestures are fixed and no longer assignable. Drag to scroll, pinch to zoom, tap to
right-click. They are what a hand already expects from a trackpad, and a phone that answers them
differently reads as broken rather than as configured. Three and four fingers stay assignable. - A dial still goes in one of the four corners and nowhere else. Seven kinds now compete for those four
places, which is the corners screen's job to settle. - What the app says about its own security is now true. Three places — including a label in the Macros
window — claimed the phone "can never name a program of its own". It never could not: the phone's
keyboard sends a raw key code and arbitrary text straight to the laptop, because that is what a keyboard
screen is, and Win+R with a typed line is already arbitrary execution. The macro index is still worth
having, but it contains nothing the keyboard does not already allow. A paired phone is a trusted input
device, and the trust boundary is the Bluetooth pairing, not the macro list.
Fixed
- Two-finger scroll no longer starts late. Every sample advanced the last-seen position, including the
ones spent below the slop deciding scroll from pinch, so the travel spent deciding was dropped and every
stroke began 8 dp behind the finger. Pinch never had the bug, because it only advances its reference once
a mode is settled. - A macro added while the phone is connected appears at once. The names went out once at the handshake
and never again, so a new button needed the app closed and opened. - Reconnecting during a refresh-rate change could kill the tray app. The mode list was read twice while
a reconnect was emptying and refilling it; between the two reads it could be empty, and an unhandled
error on a background thread ends the process rather than the dial. - A phone flipping between two refresh rates could blank the screen for ever. A switch to the rate
already in force is now free. - OK in the Macros window could freeze the laptop app. It wrote to the Bluetooth socket on the thread
drawing the interface, so a phone that had stopped reading took the tray, the editor and the menu with it. - A fast dial drag could bog the laptop down. The on-screen readout queued a repaint per frame from a
higher-priority thread; it now keeps one in flight and draws the newest value. - The laptop's log stopped recording display failures after the first one, which was usually written at
startup — so the errors it exists for were the ones it silenced.
Documentation
- PROTOCOL.md records why new ids did not move the version, and what would.
Edgepad 1.0.0
Edgepad turns an Android phone into a trackpad, a media remote and a control panel for a Windows laptop, over a direct Bluetooth link. No account, no Wi-Fi, no cloud service in between.
This is the first stable release. If you have never used Edgepad, start here.
Install both halves
Edgepad is two programs that talk to each other, so install both from this release. Apps from different releases refuse each other at the handshake and say why.
Laptop — Windows 10 version 2004 or later, 64-bit
- Download
Edgepad.exebelow. It is a single self-contained file; nothing else needs installing. - Run it. It is not code-signed, so SmartScreen asks first: choose More info, then Run anyway.
- It lives in the system tray. Its menu has the version, whether a phone is connected, Start with Windows, Forget trusted phone, Open log and Quit.
Phone — Android 12 or later
- Download
Edgepad.apkbelow and open it. Allow installing from this source if your phone asks. - On the first run, allow the Nearby devices permission. Edgepad uses it to list the laptops already paired with your phone. It never scans for new ones.
Connect them
- Pair the phone and the laptop once, the ordinary way, in Windows Settings → Bluetooth & devices.
- Leave Edgepad running in the laptop's tray.
- Open Edgepad on the phone and tap your laptop.
The first phone to connect becomes that laptop's trusted phone; any other paired phone is refused until you choose Forget trusted phone from the tray menu. The phone remembers the laptop and reconnects when you open the app.
A five-page guide opens on the first run, and again from Settings → Help.
What you can do with it
- Corner rulers. Each corner of the phone holds a dial drawn as a ruler that wraps the bend. Slide along it, clockwise to raise: volume, brightness, media scrub, zoom, the app switcher, or microphone level. Settings decides what each corner holds.
- A trackpad. Everything between the corners moves the laptop's pointer. One finger moves and clicks, two scroll and pinch, three and four fingers do whatever you assign them — desktops, task view, media, volume, the app switcher.
- Media. What is playing, which app is playing it, how far in, with previous, play/pause and next. Drag the pieces anywhere on the surface.
- A keyboard and a gamepad. A full on-screen keyboard whose modifiers work held or tapped, and a gamepad with editable layouts and presets.
- Live state. The dials show the laptop's real volume, mute, brightness and playback position, and follow changes you make on the laptop itself.
How it works, briefly
The phone recognises the gesture and sends a small semantic frame — move the pointer this far, press this button, set volume to 55. The laptop owns the table of what each action means and carries it out. The phone can name an action; it can never send a key or a command line.
The transport is Bluetooth Classic RFCOMM: an ordered, encrypted stream between two devices that are already paired. There is no server, no discovery and no network. Nothing leaves the two devices, and it works with no internet connection at all.
docs/ARCHITECTURE.md describes both apps and their trust model. docs/PROTOCOL.md is the wire format. CHANGELOG.md lists what every release changed.
Known limits
- The laptop app is Windows only. There is no macOS or Linux build.
Edgepad.exeis not code-signed, hence the SmartScreen prompt above.- Bluetooth range is Bluetooth range: same room, not the next one.
- Windows will not let any app inject input into an elevated window or the lock screen, so the trackpad stops at a UAC prompt. That is Windows protecting itself, not a bug.
Found something wrong, or want to help? Open an issue — there are a few marked good first issue — or start a discussion.