<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Ali MS</title>
    <description>The latest articles on DEV Community by Ali MS (@ali_ms_a400956ccbe447a39e).</description>
    <link>https://dev.to/ali_ms_a400956ccbe447a39e</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4223414%2Fbe1dbb6a-8ba6-473f-8f5d-f0e8a02fce7e.png</url>
      <title>DEV Community: Ali MS</title>
      <link>https://dev.to/ali_ms_a400956ccbe447a39e</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ali_ms_a400956ccbe447a39e"/>
    <language>en</language>
    <item>
      <title>I built a Mac app in Rust that turns the edges of the trackpad into controls</title>
      <dc:creator>Ali MS</dc:creator>
      <pubDate>Tue, 03 Nov 2026 04:31:43 +0000</pubDate>
      <link>https://dev.to/ali_ms_a400956ccbe447a39e/i-built-a-mac-app-in-rust-that-turns-the-edges-of-the-trackpad-into-controls-18bh</link>
      <guid>https://dev.to/ali_ms_a400956ccbe447a39e/i-built-a-mac-app-in-rust-that-turns-the-edges-of-the-trackpad-into-controls-18bh</guid>
      <description>&lt;p&gt;My MacBook trackpad has four edges I never touch. Meanwhile I kept reaching for the menu bar to change the volume or the brightness. So I built &lt;strong&gt;&lt;a href="https://zerowing.in/brink/" rel="noopener noreferrer"&gt;Brink&lt;/a&gt;&lt;/strong&gt;, a free menu bar app that turns those edges into controls:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Right edge:&lt;/strong&gt; slide for volume&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Left edge:&lt;/strong&gt; slide for brightness&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Top edge:&lt;/strong&gt; slide for keyboard light&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bottom edge:&lt;/strong&gt; swipe to skip a track&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Top-right corner:&lt;/strong&gt; double-tap to mute&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It shows the same HUD as the keyboard keys, ticks under your finger as you slide, and keeps the pointer still while you do it. Here's how it works.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reading raw touches
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;NSEvent&lt;/code&gt; gestures can't tell you that a finger is resting 3 mm from the right edge. You only get scrolls and swipes once macOS has already decided what the gesture is. Brink reads raw contact frames from the private &lt;code&gt;MultitouchSupport&lt;/code&gt; framework instead: &lt;code&gt;MTDeviceCreateList&lt;/code&gt;, &lt;code&gt;MTRegisterContactFrameCallback&lt;/code&gt;, &lt;code&gt;MTDeviceStart&lt;/code&gt;. Each frame lists every finger's normalized position, so the app can tell when a touch starts in an edge zone.&lt;/p&gt;

&lt;p&gt;Every symbol is resolved with &lt;code&gt;dlopen&lt;/code&gt;/&lt;code&gt;dlsym&lt;/code&gt;. A private API can change, so a missing symbol turns the feature off instead of crashing the app.&lt;/p&gt;

&lt;h2&gt;
  
  
  Telling a slide from a scroll
&lt;/h2&gt;

&lt;p&gt;This is the hard part. A finger near the edge might be the start of a slide, an ordinary two-finger scroll, a palm, or a tap. The engine is a small state machine:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;enum&lt;/span&gt; &lt;span class="n"&gt;State&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Idle&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;Candidate&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;zone&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Zone&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;i32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;x0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;f32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;f32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;t0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;frozen&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;corner&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;bool&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="nf"&gt;Sliding&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Slide&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;Lost&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;slide&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Slide&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;since&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;f64&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="n"&gt;Spent&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;frozen&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;bool&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Candidate:&lt;/strong&gt; one finger landed in a zone. It becomes a slide once it moves along the edge by more than &lt;code&gt;SLIDE_START&lt;/code&gt;, a swipe after &lt;code&gt;SWIPE_DISTANCE&lt;/code&gt;, or a tap if it lifts quickly without moving.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lost:&lt;/strong&gt; trackpads drop a finger for a frame or two mid-slide, so the slide waits 180 ms for the finger to come back before ending.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Spent:&lt;/strong&gt; a second finger arrived, or the gesture belongs to someone else. Brink ignores everything until all fingers lift.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A watchdog tick ends any slide that stops receiving frames. It's pure logic with no system calls, so the tests feed it synthetic frames.&lt;/p&gt;

&lt;h2&gt;
  
  
  Making it feel native
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;HUD:&lt;/strong&gt; volume and brightness changes are posted as system-defined &lt;code&gt;NSEvent&lt;/code&gt;s carrying the media-key codes (&lt;code&gt;NX_KEYTYPE_SOUND_UP&lt;/code&gt; and friends) through &lt;code&gt;CGEventPost&lt;/code&gt;. macOS draws its own HUD, exactly as if you'd pressed the key. With Shift and Option held you get quarter steps, just like the keyboard.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Haptics:&lt;/strong&gt; &lt;code&gt;MTActuatorCreateFromDeviceID&lt;/code&gt; and &lt;code&gt;MTActuatorActuate&lt;/code&gt; fire a light tick on every step, so you can feel the slider.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Holding the pointer still:&lt;/strong&gt; while a slide is live, an event tap (&lt;code&gt;CGEventTapCreate&lt;/code&gt;) swallows mouse-moved and drag events, so the cursor doesn't drift across the screen as your finger travels.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The panel
&lt;/h2&gt;

&lt;p&gt;Brink itself is Tauri 2 with a Rust core. The menu bar panel is a WebView styled as liquid glass, and on macOS 26 it sits on a real &lt;code&gt;NSGlassEffectView&lt;/code&gt;. To keep the text readable on any wallpaper, the backdrop is toned per pixel and a feathered mask darkens just the area behind the labels.&lt;/p&gt;

&lt;h2&gt;
  
  
  Shipping
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Universal binary (Apple silicon and Intel), signed and notarized&lt;/li&gt;
&lt;li&gt;Auto-updates with Tauri's updater and minisign-signed releases&lt;/li&gt;
&lt;li&gt;Homebrew: &lt;code&gt;brew trust muhammadalims/tap &amp;amp;&amp;amp; brew install --cask muhammadalims/tap/brink&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It's free, and it runs on macOS 13 or later: &lt;strong&gt;&lt;a href="https://zerowing.in/brink/" rel="noopener noreferrer"&gt;zerowing.in/brink&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you try it, I'd love to hear where the gesture detection gets it wrong for you, especially palm rejection on the bigger trackpads.&lt;/p&gt;

</description>
      <category>rust</category>
      <category>macos</category>
      <category>tauri</category>
      <category>showdev</category>
    </item>
  </channel>
</rss>
