Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
3d78ffd
split macos tauri config and move native dialogs into platform module
onza Jun 25, 2026
6b5186f
add rfd file dialogs for non-macos platforms
onza Jun 26, 2026
d9f956d
add windows bundle config, icon.ico generation, and gifsicle paths
onza Jun 26, 2026
54b07ec
add windows ci matrix and platform-specific ui behavior
onza Jun 26, 2026
d347993
ci: trigger checks
onza Jun 26, 2026
11a8b7e
merge main into feature/cross-platform
onza Jun 26, 2026
9f8e993
fix windows ci by skipping prepare-resources without gifsicle
onza Jun 26, 2026
136ae8e
fix merge conflict
onza Jun 26, 2026
2ea8402
install dav1d via vcpkg on windows ci
onza Jun 26, 2026
731ad31
fix windows build by adjusting tauri macos-private-api config
onza Jun 26, 2026
29f8236
add gitkeep placeholder for windows ci gifsicle skip
onza Jun 26, 2026
b230065
fix windows ci by gating macos-only runevent and heic tests
onza Jun 26, 2026
f2fbfa7
fix heic test by restoring std::fs import on macos
onza Jun 26, 2026
64f4445
fix windows ci by adding dav1d dll to path & cleaning lib.rs
onza Jun 26, 2026
e42329d
fix summary tests to use platform-aware format_bytes expectations
onza Jun 26, 2026
3a50773
fix vcpkg cache path on windows ci
onza Jun 26, 2026
41def4a
add windows publish workflow
onza Jun 27, 2026
dfada21
fix windows publish for manual test draft
onza Jun 27, 2026
1aa9b27
install gifsicle in publish via msys2
onza Jun 27, 2026
c84242f
build gifsicle from source in publish workflow
onza Jun 27, 2026
6a30016
fix gifsicle build
onza Jun 27, 2026
675a12e
fix gifsicle build
onza Jun 27, 2026
4826d97
bundle dav1d.dll in windows installer
onza Jun 27, 2026
a6a649f
fix windows ci by copying dav1d.dll when gifsicle is skipped
onza Jun 27, 2026
32e6a27
bundle msvc runtime dlls for vcpkg dav1d on windows
onza Jun 28, 2026
2507bba
fix windows runtime dll discovery in ci
onza Jun 28, 2026
eacc7d1
fix windows window title and size
onza Jun 29, 2026
20b0803
fix windows gif optimization with static gifsicle build
onza Jun 29, 2026
612be0c
bundle mingw runtime dlls next to gifsicle on windows
onza Jun 29, 2026
7865e24
fix windows ci mingw runtime dlls for gifsicle bundle
onza Jun 29, 2026
a6a012b
fix windows gif by bundling gifsicle mingw dlls in publish
onza Jun 29, 2026
0ab110c
fix windows resource bundle to preserve gifsicle directory layout
onza Jun 30, 2026
990d40b
add Windows installation
onza Jun 30, 2026
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
50 changes: 45 additions & 5 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,21 @@ jobs:
test:
needs: changes
if: needs.changes.outputs.rust == 'true'
runs-on: macos-latest
strategy:
fail-fast: false
matrix:
include:
- os: macos-latest
gifsicle-path: vendor/gifsicle/gifsicle
skip_gifsicle: ''
# todo: prebuilt gifsicle.exe for ci and windows release
- os: windows-latest
gifsicle-path: vendor/gifsicle/gifsicle.exe
skip_gifsicle: '1'

runs-on: ${{ matrix.os }}
env:
CI_SKIP_GIFSICLE: ${{ matrix.skip_gifsicle }}

steps:
- name: Checkout
Expand All @@ -74,21 +88,47 @@ jobs:
workspaces: src-tauri

- name: Cache Homebrew
uses: actions/cache@v4
if: runner.os == 'macOS'
uses: actions/cache@v5
with:
path: ~/Library/Caches/Homebrew
key: brew-${{ runner.os }}-${{ runner.arch }}
restore-keys: |
brew-${{ runner.os }}-

- name: Install system dependencies
- name: Install dav1d (macOS)
if: runner.os == 'macOS'
run: brew install dav1d

- name: Cache vcpkg (Windows)
if: runner.os == 'Windows'
uses: actions/cache@v5
with:
path: ${{ env.VCPKG_INSTALLATION_ROOT }}/installed/x64-windows
key: vcpkg-dav1d-x64-windows-1
restore-keys: |
vcpkg-dav1d-x64-windows-

- name: Install dav1d (Windows)
if: runner.os == 'Windows'
shell: pwsh
run: |
choco install pkgconfiglite -y
vcpkg install dav1d:x64-windows
Add-Content -Path $env:GITHUB_ENV -Value "PKG_CONFIG_PATH=$env:VCPKG_INSTALLATION_ROOT\installed\x64-windows\lib\pkgconfig"
Add-Content -Path $env:GITHUB_ENV -Value "PATH=$env:VCPKG_INSTALLATION_ROOT\installed\x64-windows\bin;$env:PATH"

- name: Set VC runtime path (Windows)
if: runner.os == 'Windows'
shell: pwsh
run: ./scripts/set-vc-runtime-env.ps1

- name: Cache gifsicle binary
uses: actions/cache@v4
if: runner.os == 'macOS'
uses: actions/cache@v5
id: gifsicle-cache
with:
path: vendor/gifsicle/gifsicle
path: ${{ matrix.gifsicle-path }}
key: gifsicle-${{ runner.os }}-${{ runner.arch }}-1.96

- name: Install dependencies
Expand Down
148 changes: 148 additions & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
name: publish

on:
workflow_dispatch:
inputs:
test_tag:
description: draft tag for this windows test build
required: true
default: v1.3.1-windows-test1

jobs:
publish-windows:
permissions:
contents: write
runs-on: windows-latest

steps:
- name: Checkout
uses: actions/checkout@v5

- name: Setup Node.js
uses: actions/setup-node@v5
with:
node-version-file: .nvmrc
cache: npm

- name: Install Rust stable
uses: dtolnay/rust-toolchain@stable

- name: Rust cache
uses: Swatinem/rust-cache@v2
with:
workspaces: src-tauri

- name: Cache vcpkg
uses: actions/cache@v5
with:
path: ${{ env.VCPKG_INSTALLATION_ROOT }}/installed/x64-windows
key: vcpkg-dav1d-x64-windows-1
restore-keys: |
vcpkg-dav1d-x64-windows-

- name: Install dav1d
shell: pwsh
run: |
choco install pkgconfiglite -y
vcpkg install dav1d:x64-windows
Add-Content -Path $env:GITHUB_ENV -Value "PKG_CONFIG_PATH=$env:VCPKG_INSTALLATION_ROOT\installed\x64-windows\lib\pkgconfig"
Add-Content -Path $env:GITHUB_ENV -Value "PATH=$env:VCPKG_INSTALLATION_ROOT\installed\x64-windows\bin;$env:PATH"

- name: Set VC runtime path
shell: pwsh
run: ./scripts/set-vc-runtime-env.ps1

- name: Setup MSYS2
uses: msys2/setup-msys2@v2
with:
msystem: MINGW64
update: true
install: >-
msys/make
mingw-w64-x86_64-gcc
mingw-w64-x86_64-gcc-libs
mingw-w64-x86_64-winpthreads
mingw-w64-x86_64-make
autoconf
automake
libtool
pkg-config

- name: Cache gifsicle binary
uses: actions/cache@v5
with:
path: vendor/gifsicle
key: gifsicle-${{ runner.os }}-${{ runner.arch }}-1.96-mingw-3

- name: Install dependencies
run: npm ci --ignore-scripts
env:
HUSKY: 0

- name: Install gifsicle
shell: msys2 {0}
run: |
set -euo pipefail
export PATH="/mingw64/bin:$PATH"
ROOT="$GITHUB_WORKSPACE"
GIFSICLE_DIR="$ROOT/vendor/gifsicle"
GIFSICLE="$GIFSICLE_DIR/gifsicle.exe"
MINGW_DLLS=(libwinpthread-1.dll libgcc_s_seh-1.dll)

verify_gifsicle() {
if [ ! -f "$GIFSICLE" ]; then
return 1
fi
"$GIFSICLE" --version | grep -F 1.96
for dll in "${MINGW_DLLS[@]}"; do
if [ ! -f "$GIFSICLE_DIR/$dll" ]; then
echo "gifsicle: missing bundled $dll"
return 1
fi
done
}

bundle_mingw_dlls() {
for dll in "${MINGW_DLLS[@]}"; do
cp "/mingw64/bin/$dll" "$GIFSICLE_DIR/"
echo "gifsicle: bundled $dll"
done
}

if verify_gifsicle; then
echo "gifsicle: cache hit"
exit 0
fi

export LDFLAGS="-static -static-libgcc"
MAKE="$(command -v mingw32-make || command -v make)"
VERSION=1.96
mkdir -p "$ROOT/vendor/source" "$GIFSICLE_DIR"
cd "$ROOT/vendor/source"
if [ ! -f "gifsicle-$VERSION.tar.gz" ]; then
curl -fsSL -o "gifsicle-$VERSION.tar.gz" "https://www.lcdf.org/gifsicle/gifsicle-$VERSION.tar.gz"
fi
rm -rf "gifsicle-$VERSION"
tar xzf "gifsicle-$VERSION.tar.gz"
cd "gifsicle-$VERSION"
./configure --disable-gifview --disable-gifdiff --disable-dependency-tracking \
--prefix="$GIFSICLE_DIR" --bindir="$GIFSICLE_DIR" "MAKE=$MAKE" \
"LDFLAGS=$LDFLAGS"
"$MAKE" install
bundle_mingw_dlls
"$GIFSICLE" --version
verify_gifsicle

- name: Build and release
uses: tauri-apps/tauri-action@v0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }}
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }}
with:
tagName: ${{ github.event.inputs.test_tag }}
releaseName: 'DropSlim Windows test (${{ github.event.inputs.test_tag }})'
releaseBody: 'Windows test build only — not a full release. App version remains 1.3.1.'
releaseDraft: true
prerelease: true
args: '--bundles nsis'
1 change: 1 addition & 0 deletions .github/workflows/trigger-website.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ on:

jobs:
dispatch:
if: github.event.release.prerelease == false
runs-on: ubuntu-latest
steps:
- name: Notify DropSlim_Website
Expand Down
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ dist/
dist-ui/
src-tauri/target/
src-tauri/resources/
src-tauri/dav1d.dll
src-tauri/vcruntime140.dll
src-tauri/vcruntime140_1.dll
src-tauri/msvcp140.dll
src-tauri/gen/

vendor/gifsicle/gifsicle
Expand All @@ -15,6 +19,7 @@ build/icon.iconset/
build/icon.icns
src-tauri/icons/icon.icns
src-tauri/icons/icon.png
src-tauri/icons/icon.ico

.env
.release.env
Expand Down
36 changes: 25 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,29 @@

[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE.md) [![CI](https://github.com/onza/DropSlim/actions/workflows/ci.yml/badge.svg)](https://github.com/onza/DropSlim/actions/workflows/ci.yml)

Make large image files **small** — on your Mac, with drag & drop. Local, fast, privacy, free, and open source.
Make large image files **small** — on your computer, with drag & drop. Local, fast, private, free, and open source.

Drop your images. DropSlim crunches the numbers. Done. Everything stays on your Mac — no account, no server.
Drop your images. DropSlim crunches the numbers. Done. Everything stays on your machine — no account, no server.

<br>

## Why DropSlim

- **Drag & drop** — drop files or folders on the window; whole folders are processed recursively
- **Small and fast** — lightweight app, fast compression; built with imagequant, oxipng, zenjpeg, OXVG, gifsicle, WebP, and AVIF encoders
- **Runs offline** — no internet required; compression runs entirely on your Mac
- **Runs offline** — no internet required; compression runs entirely on your computer
- **Privacy** — no upload, no tracking; your images never leave your machine
- **Batch processing** — hundreds of files in one go; new file alongside the original, or replace in place
- **All common formats** — PNG, JPEG, HEIC, GIF, SVG, WebP, and AVIF
- **Open with DropSlim** — right-click an image in Finder → **Open With** → DropSlim
- **Review results** in a simple list and reveal outputs in Finder
- **Common formats** — PNG, JPEG, GIF, SVG, WebP, and AVIF. **HEIC on macOS only**
- **Open with DropSlim** (macOS) — right-click an image in Finder → **Open With** → DropSlim
- **Review results** in a simple list and reveal outputs in Finder or File Explorer
- **Open source** — [MIT](LICENSE.md)
- **Languages** — English, German, French, Spanish, Italian, Japanese, Brazilian Portuguese

### Where the optimized file is saved depends on your settings

- **`.min` suffix on** (default): writes a new file next to the original, e.g. `photo.png` → `photo.min.png`. The source file stays untouched.
- **`.min` suffix off**: replaces the original file in place with the optimized version.
- **`.min` suffix off**: overwrites the original in place when saving in the same folder and **`minified` subfolder** is off. With the subfolder on, the optimized file goes into `minified/` under the original filename and the source stays untouched.
- **`minified` subfolder**: saves into a `minified/` folder (with or without `.min`, depending on the suffix setting).
- **Custom save folder**: turn off **Save optimized files in same folder** in Settings — **Choose folder** appears; click **Open** to pick a destination.

Expand All @@ -42,6 +42,20 @@ Requires macOS 11 (Big Sur) or later and an **Apple Silicon** Mac (M1 or newer).

<br>

## Install (Windows)

Requires **Windows 10 or later** (64-bit).

1. Download **`DropSlim_*_x64-setup.exe`** from **[GitHub Releases](https://github.com/onza/DropSlim/releases)**.
2. If your browser blocks the download, choose **Keep** or **Keep anyway**.
3. Run the installer.
4. If **Microsoft Defender SmartScreen** shows _"Windows protected your PC"_:
- Click **More info**
- Click **Run anyway**
5. Follow the setup wizard and start DropSlim from the Start menu or desktop shortcut.

<br>

## Translations

UI translations were **generated with AI** and may contain errors or awkward wording. **Corrections are welcome** — if you spot a mistake, please [open an issue](https://github.com/onza/DropSlim/issues) or submit a pull request with an updated string in `ui/i18n/locales/`.
Expand All @@ -50,13 +64,13 @@ UI translations were **generated with AI** and may contain errors or awkward wor

## A Frustrating Side Note

DropSlim is open source and free. Nevertheless, in the Apple ecosystem, it apparently costs money just to download an app, drag it into the “Applications” folder, and open it without any further hassle.
DropSlim is open source and free. Nevertheless, it appears that on both major desktop platforms, it costs developers money to allow users to simply download, install and open an app without any further hassle.

That’s because Apple requires me to join its paid Developer Program, which costs 99 EUR per year. On top of that: identity verification with a wait time of 5 days, certificate signing requests, Developer ID certificates, app-specific passwords, authorizations, and a registration process that feels like the administration from Asterix Conquers Rome digitized the A38 pass to make breathing fresh air subject to approval.
**On macOS**, Apple requires a paid Developer Program (99 EUR per year). On top of that: identity verification with a wait time of 5 days, certificate signing requests, Developer ID certificates, app-specific passwords, authorizations, and a registration process that feels like the administration from "Asterix Conquers Rome" digitized the A38 pass to make breathing fresh air subject to approval. This project covers that fee, so Mac users get a normal install.

None of this makes the app any better. It merely serves to satisfy Gatekeeper so that app users aren’t greeted with _“Apple couldn’t verify…”_ and a useless “Done” button, only to then have to click an “Open Anyway” button buried deep in the security settings.
**On Windows**, SmartScreen treats unsigned installers as suspicious. A commercial code-signing certificate (roughly 100+ EUR per year, from a certificate authority or cloud signing service) is the paid entry ticket to a smoother path; even then, reputation builds slowly and rarely helps a small open-source project. This project does not pay for Windows signing — use **More info** → **Run anyway** (steps above). The installer is still safe if you download it from this repository or the [project website](https://dropslim.app/).

This project covers that fee, so you don’t have to worry about it. If any developer knows a trick to bypass the Developer Program without compromising the installation process, I’d be very happy to hear from you :)
None of this makes the app any better. It only buys a smoother install experience. If you know a legitimate way around either gate without compromising security, I’d be happy to hear from you :)

<br>

Expand Down
Loading
Loading