Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 42 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,8 @@ them as if they were one device:

**Requirements:** Android 10+ phone · Linux with BlueZ (Ubuntu/Debian, Fedora,
Arch, openSUSE) · Bluetooth (BLE) on both devices. Build tools (Rust/Node) are
installed by the script itself.
installed by the script itself. A Windows build is available too, cross-built
from Linux — see [step 7](#7-laptop-windows--experimental).

### 1. Laptop (Linux)

Expand Down Expand Up @@ -220,6 +221,46 @@ lets Vortex keep one keyboard for the whole session, so you see the notification
once instead of on every crossing. The notification itself can also be switched
off: long-press it → turn off that category. Nothing else uses it.

### 7. Laptop (Windows) — experimental

There is no Windows installer yet. The app is **cross-built from Linux**: if
you already build the Linux app on this machine, one more script produces the
Windows `.exe` from the same checkout.

```bash
./install_windows.sh # toolchain + vortex-ui-tauri.exe
./install_windows.sh --installer # also an NSIS setup.exe
```

It installs what is missing (clang/lld/llvm, the `x86_64-pc-windows-msvc` Rust
target, `cargo-xwin`, node) and builds. The first run additionally downloads
Microsoft's CRT and Windows SDK — a few hundred MB, once, into
`~/.cache/cargo-xwin`; `cargo-xwin` accepts Microsoft's licence for that
download on your behalf, so build on Windows instead if you would rather not.
The result lands in
`linux/ui-tauri/src-tauri/target/x86_64-pc-windows-msvc/release/`.

Copy the `.exe` to the Windows machine and run it — there is nothing to
install, it sits in the tray like the Linux build, and pairing is the same BLE
flow from the same phone app.

**What works:** pairing, reconnect, notification mirroring, clipboard, file
transfer, Universal Control.

**What does not:** screen mirror/cast, the continuity camera and the earbuds
hand-off. Those are GStreamer/GTK/PulseAudio/BlueZ and have no Windows
implementation, so they are compiled out rather than shipped broken.

**Two things to expect on first run.** The binary is unsigned, so SmartScreen
warns — *More info → Run anyway*. And on Windows 10 the window can open blank:
that is a missing **WebView2 runtime** (Windows 11 ships it). Install
Microsoft's Evergreen WebView2 Runtime and relaunch.

> ⚠ **Experimental, and less tested than Linux.** The BLE layer here is a
> separate implementation against a platform seam (WinRT rather than BlueZ),
> and it has had far less real-world use. Treat it as a preview and please
> report what breaks.

## 🔐 Security

All device-to-device traffic is **end-to-end encrypted**:
Expand Down
30 changes: 30 additions & 0 deletions android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,36 @@
</intent-filter>
</activity>

<!-- "Vortex" in the text-selection toolbar, beside Copy and Share:
select text anywhere, tap it, and the text is on the laptop's
clipboard. One tap, no share sheet, no app picker.

The system passes the selection in EXTRA_PROCESS_TEXT, so unlike
every other inbound path this one needs no clipboard read at all —
which matters because a background read is refused outright (see
ClipboardAccess) and even the tile has to bounce through a
foreground trampoline to get focus first.

android:label is what the toolbar shows, NOT app_name: the strip
is tight on space and truncates, so it is deliberately one word. -->
<activity
android:name=".core.clipboard.ProcessTextActivity"
android:excludeFromRecents="true"
android:exported="true"
android:label="@string/process_text_label"
android:noHistory="true"
android:taskAffinity=""
android:theme="@style/Theme.Vortex.ClipboardOverlay">
<intent-filter>
<action android:name="android.intent.action.PROCESS_TEXT" />
<category android:name="android.intent.category.DEFAULT" />
<!-- text/plain only: the toolbar deals in selected text, and a
wildcard here would offer Vortex for selections it cannot
actually send. -->
<data android:mimeType="text/plain" />
</intent-filter>
</activity>

<!-- Quick Settings tile: tap to send this phone's clipboard to the
laptop (the user gesture Android's read restriction requires). -->
<service
Expand Down
Loading
Loading