Files
valw/docs/vision.md
T

11 KiB
Raw Blame History

Original product vision, kept as written. The project was renamed from snapr to valw; phase designs live in docs/superpowers/specs/.

SPEC.md: macOS tarzı ekran görüntüsü + zoom aracı (niri / Wayland / NixOS)

Bu dosyayı projenin köküne SPEC.md (veya CLAUDE.md) olarak koy ve Claude Code'a "SPEC.md'yi oku, Faz 1'den başla" de. Proje adı şimdilik snapr, istediğin gibi değiştir.

1. Amaç

macOS'taki Cmd+Shift+3/4/5 deneyimini niri üzerinde birebir hissettiren, Rust ile yazılmış tek bir araç:

  • Bölge / pencere / tam ekran yakalama
  • macOS'taki gibi sağ altta beliren küçük önizleme (tıkla → düzenle, sürükle → bırak, kaydır → kapat)
  • Basit bir düzenleyici (ok, kutu, metin, kalem, bulanıklaştırma, kırpma)
  • Zoom / büyüteç modu (woomer benzeri: zoom, pan, flashlight)
  • Cmd+Shift+5 benzeri araç çubuğu

2. Hedef ortam ve kısıtlar

  • Compositor: niri (öncelikli). Diğer wlroots tabanlı compositor'larda çalışması bonus, zorunlu değil.
  • Shell: Noctalia. Doğrudan bir Noctalia API'sine bağımlı olma; entegrasyon CLI + standart Wayland protokolleri + freedesktop bildirimleri üzerinden olsun, böylece Noctalia'nın iç yapısı değişse de araç çalışır.
  • Dağıtım: NixOS. Proje bir flake olarak paketlenmeli.
  • Dil: Rust (stable). X11 desteği yok, sadece Wayland.

⚠️ Claude Code için: protokol ve IPC desteğini varsayma, doğrula. Kodlamaya başlamadan önce kullanıcının makinesinde niri --version, niri msg --help, wayland-info çıktılarına bak ve hangi protokollerin sunulduğunu raporla.

3. Teknik yaklaşım

Konu Tercih Not
Wayland istemcisi smithay-client-toolkit (SCTK) + wayland-client
Overlay yüzeyleri wlr-layer-shell Seçim ekranı, önizleme, zoom modu hepsi layer-shell yüzeyi
Ekran yakalama ext-image-copy-capture-v1 varsa onu, yoksa wlr-screencopy-unstable-v1 İkisini de bir trait arkasına soy
Pencere bilgisi niri-ipc crate'i ile niri IPC Pencere listesi, odaklı pencere, monitör bilgisi. Pencere geometrisi IPC'den alınamıyorsa pencere yakalamada niri'nin kendi screenshot-window aksiyonuna düş
Çizim tiny-skia (yazılımsal) Gerekirse sonradan wgpu'ya geçilebilir; zoom modunda performans yetmezse ilk aday orası
Metin cosmic-text veya fontdue
Pano wl-clipboard-rs PNG olarak kopyala
Bildirim notify-rust Önizleme penceresi yerine fallback olarak
Görüntü image crate'i (PNG kaydetme)
Config serde + toml, ~/.config/snapr/config.toml
CLI clap

HiDPI / kesirli ölçekleme en baştan düşünülmeli: wp-fractional-scale-v1 ve wp-viewporter kullan, yakalanan görüntü fiziksel piksel çözünürlüğünde olsun.

Çoklu monitör: Seçim modu tüm monitörlerde aynı anda açılmalı; bölge tek monitörle sınırlı olabilir (v1 için yeterli).

4. Özellikler

4.1 Yakalama modları (CLI alt komutları)

snapr region        # Cmd+Shift+4: sürükleyerek bölge seç
snapr window        # Cmd+Shift+4 + Space: üzerine gelinen pencere vurgulanır, tıkla → yakala
snapr screen        # Cmd+Shift+3: odaklı monitör (veya --all)
snapr toolbar       # Cmd+Shift+5: araç çubuğu
snapr zoom          # woomer benzeri zoom modu
snapr edit <dosya>  # düzenleyiciyi doğrudan aç

Ortak bayraklar: --clipboard-only, --no-preview, --delay <sn>, --output <yol>, --cursor.

4.2 Bölge seçimi (macOS davranışı)

  • Ekran donar (yakalanmış kare arka plan olarak gösterilir), hafif karartılır.
  • İmleç yanında koordinat / boyut göstergesi (örn. 640 × 480).
  • Sürüklerken:
    • Shift: sadece bir eksende genişlet
    • Alt: merkezden genişlet
    • Space basılı tut: seçimi taşı
  • Space (sürüklemeden önce): pencere moduna geç (macOS'taki kamera ikonu mantığı).
  • Esc: iptal.
  • Bırakınca yakala.

4.3 Pencere modu

  • İmlecin altındaki pencere mavi tonla vurgulanır.
  • Tıkla → yakala. Opsiyonel: pencere çevresine gölge ekleme (config ile, macOS'taki gibi, varsayılan kapalı).

4.4 Sağ alt önizleme (macOS'un "floating thumbnail"ı)

  • Yakalamadan sonra odaklı monitörün sağ alt köşesinde, layer-shell ile küçük bir önizleme belirir (kayarak girer).
  • Varsayılan 5 sn sonra kaybolur ve dosya kaydedilir (süre config'den).
  • Etkileşimler:
    • Sol tık → düzenleyicide aç
    • Sağ tık → küçük menü: Kaydet / Panoya kopyala / Klasörde göster / Sil / Düzenle
    • Sağa kaydır/sürükle → hemen kaydet ve kapat
    • Dışarı sürükle → wl_data_device ile sürükle-bırak (dosyayı başka bir uygulamaya bırakabilmek)
    • Üzerine gelince zamanlayıcı durur
  • Önizleme devre dışıysa notify-send benzeri bir bildirim gönder (resim + "Düzenle" aksiyonu). Noctalia bildirimleri bunu gösterecektir.

4.5 Düzenleyici

Normal bir pencere (xdg-toplevel). Araçlar:

  • Ok, dikdörtgen, elips, çizgi, serbest kalem, işaretleyici (yarı saydam)
  • Metin (font boyutu, renk)
  • Bulanıklaştır / pikselleştir (hassas bilgileri gizlemek için)
  • Numaralı işaret (1, 2, 3... baloncukları)
  • Kırp
  • Renk paleti + kalınlık
  • Geri al / yinele (Ctrl+Z / Ctrl+Shift+Z)
  • Ctrl+C panoya kopyala, Ctrl+S kaydet, Esc kapat

Alternatif: v1'de düzenleyiciyi yazmak yerine Satty'yi çağırmak mümkün. Faz planına bak.

4.6 Araç çubuğu (Cmd+Shift+5)

Ekranın altında ortalanmış yüzen bir çubuk:

[Tam ekran] [Pencere] [Bölge] | [Zoom] | Seçenekler ▾ | [Yakala]

Seçenekler: kayıt yeri (Masaüstü / Resimler / Pano / Özel), zamanlayıcı (yok / 5 sn / 10 sn), imleci göster, önizlemeyi göster, son seçimi hatırla.

Ekran kaydı (video) v1 kapsamı dışında. İleride gpu-screen-recorder veya wf-recorder çağrılarak eklenebilir.

4.7 Zoom modu (woomer'dan esinlenme)

  • Ekranın anlık görüntüsü üzerinde tam ekran layer-shell yüzeyi.
  • Fare tekerleği: imlecin olduğu noktaya doğru zoom
  • Sol tık + sürükle: pan
  • f: flashlight aç/kapat; Ctrl + tekerlek: flashlight yarıçapı
  • 0: sıfırla, Esc/q: çık
  • Yumuşak (animasyonlu) zoom ve pan
  • Bonus: zoom modundayken c tuşu → o anki görünümü yakala ve önizleme akışına gönder

⚠️ Lisans: woomer'dan kod kopyalanacaksa önce lisansını kontrol et ve uyumluysa atıf ekle. Tercih edilen yol: davranışı referans alıp kendi implementasyonunu yazmak. Böylece aynı yakalama ve çizim altyapısı paylaşılır, woomer'ın ayrı render bağımlılıklarına ihtiyaç kalmaz.

5. Config örneği

# ~/.config/snapr/config.toml
[save]
directory = "~/Pictures/Screenshots"
filename = "Screenshot %Y-%m-%d at %H.%M.%S.png"
copy_to_clipboard = true

[preview]
enabled = true
timeout_secs = 5
corner = "bottom-right"   # top-left | top-right | bottom-left | bottom-right
size = 220                # px, uzun kenar

[capture]
show_cursor = false
window_shadow = false

[editor]
backend = "builtin"       # builtin | satty
default_color = "#ff3b30"
stroke_width = 4

[zoom]
scroll_step = 1.15
flashlight_radius = 180

6. niri entegrasyonu

binds {
    Mod+Shift+3 { spawn "snapr" "screen"; }
    Mod+Shift+4 { spawn "snapr" "region"; }
    Mod+Shift+5 { spawn "snapr" "toolbar"; }
    Mod+Z       { spawn "snapr" "zoom"; }
}

Layer-shell yüzeylerinin namespace'leri sabit ve belgelenmiş olsun (snapr-overlay, snapr-preview, snapr-zoom), böylece gerekirse niri'de layer-rule ile özelleştirilebilir.

7. NixOS paketleme

  • flake.nix içinde:
    • packages.<system>.default: rustPlatform.buildRustPackage (veya crane)
    • devShells.<system>.default: rust toolchain, pkg-config, wayland, libxkbcommon, fontconfig, wayland-protocols
    • homeManagerModules.default: programs.snapr.enable + programs.snapr.settings (TOML'a çevrilir)
  • Runtime'da gereken kütüphaneler için doğru buildInputs/nativeBuildInputs ve gerekirse wrapProgram ile LD_LIBRARY_PATH.
  • nix build ve nix run . -- region kutudan çıktığı gibi çalışmalı.

8. Mimari

src/
  main.rs            # clap CLI, alt komut yönlendirme
  config.rs
  capture/
    mod.rs           # trait Capturer
    ext_copy.rs      # ext-image-copy-capture-v1
    wlr_screencopy.rs
  niri.rs            # niri-ipc sarmalayıcı (pencereler, monitörler, odak)
  overlay/
    region.rs        # bölge + pencere seçimi
    toolbar.rs
    zoom.rs
  preview.rs         # sağ alt önizleme
  editor/
    mod.rs
    tools.rs         # ok, kutu, metin, blur...
    history.rs       # undo/redo
  output.rs          # kaydetme, pano, bildirim
  render.rs          # tiny-skia yardımcıları
  • Her mod kendi başına çalışan kısa ömürlü bir süreç olabilir (daemon gerekmez). Önizleme yakalamadan sonra aynı süreçte yaşar ve zamanlayıcı bitince çıkar.
  • İki yakalama aynı anda başlatılırsa ikincisi birincinin bitmesini bekler veya iptal eder (lock dosyası: $XDG_RUNTIME_DIR/snapr.lock).

9. Faz planı

Faz 0: Keşif Kullanıcının sisteminde protokol desteğini tespit et, raporla. Boş SCTK + layer-shell yüzeyi açıp kapatan minimal örnek. flake.nix + devShell.

Faz 1: Çekirdek yakalama snapr screen ve snapr region (temel sürükle-seç, Esc iptal). PNG kaydetme + panoya kopyalama. Config dosyası.

Faz 2: Önizleme Sağ alt önizleme, zamanlayıcı, tık → (şimdilik) Satty'de aç, kaydır → kapat. Bildirim fallback'i.

Faz 3: Pencere modu + seçim inceliği niri IPC ile pencere vurgulama, Space ile mod değiştirme, Shift/Alt/Space modifikatörleri, boyut göstergesi, HiDPI doğruluğu.

Faz 4: Zoom modu woomer benzeri zoom/pan/flashlight, zoomdan yakalama.

Faz 5: Yerleşik düzenleyici Araçlar, undo/redo, kırpma, blur. editor.backend = "builtin" varsayılan olur.

Faz 6: Araç çubuğu + cila Cmd+Shift+5 çubuğu, zamanlayıcı, sürükle-bırak, home-manager modülü, README.

Her fazın sonunda: cargo clippy -- -D warnings, cargo fmt --check, nix build geçmeli ve fazın özelliği niri üzerinde elle test edilmiş olmalı.

10. Kabul kriterleri

  • 2 monitörlü, biri kesirli ölçekli (örn. 1.25) kurulumda bölge seçimi piksel-doğru yakalar.
  • Kısayola basmaktan seçim ekranının görünmesine kadar geçen süre < 150 ms hissi verir.
  • Önizleme odak çalmaz (klavye odağı almaz), sadece üzerine tıklanınca etkileşir.
  • Hiçbir mod ekranda takılı kalan bir overlay bırakmaz; çökme durumunda bile süreç ölünce yüzey kaybolur.
  • Noctalia'nın bildirimleriyle ve barıyla çakışmaz (layer z-sırası doğru).

11. Kapsam dışı (v1)

  • X11, GNOME, KDE desteği
  • Video / GIF kaydı
  • OCR, bulut yükleme
  • Kaydırmalı (scrolling) ekran görüntüsü