EN

Mimari (katkıda bulunanlar için)

Snipdeck'in yapısı: tek iş parçacıklı Slint olay döngüsü ve onu boştayken uyutan pompa, çalışan iş parçacıkları ve kanallar, Windows ve Linux için modül haritası, görüntüleyiciler ve GNOME eklentisi.

Bu sayfada (6 başlık)
  1. Genel resim
  2. İş parçacıkları ve kanallar
  3. Modül haritası
  4. Görüntüleyiciler
  5. Süreç ve yaşam döngüsü
  6. Ayrıca bakın

Bu sayfa katkıda bulunanlar ve meraklı kullanıcılar içindir. Snipdeck’in nasıl bir araya geldiğini anlatır: tek iş parçacıklı bir Slint olay döngüsü bütün arayüzün sahibidir; işletim sistemi kancaları (hook) ve bekleten işler kendi iş parçacıklarında çalışır ve sonuçlarını ana iş parçacığının boşalttığı kanallar üzerinden geri verir. Kodu okumak ya da bir özellik eklemek istiyorsanız buradan başlayın.

Genel resim

Arayüze dokunan her şey tek bir iş parçacığında, Slint olay döngüsünün sahibi olan iş parçacığında çalışır. Onu bekletecek her iş (ekranı yakalamak, OCR, ağ istekleri, Linux’ta dosya pencereleri, işletim sisteminden girdi beklemek) başka bir iş parçacığında çalışır ve sonucunu bir kanal üzerinden bildirir.

Bundan iki kural çıkar ve bütün kod tabanı bunlara uyar:

  1. Arayüz durumu yalnız ana iş parçacığında değişir. Slint pencereleri, modelleri ve özellikleri Send değildir; ana iş parçacığından hiç çıkmazlar.
  2. Başka iş parçacıklarındaki iş, paylaşılan veriyi değiştirerek değil, mesajla geri döner. Bir çalışan sonucunu bir kanala gönderir; ana iş parçacığı onu bir sonraki geçişte okur.

Pompa

Ana iş parçacığının rutin işleri (kanalları boşaltmak, yüzen pencereleri açmak, bekçi denetimleri) eskiden hiç durmayan 8 ms’lik bir zamanlayıcıda çalışıyordu; Snipdeck tepside boşta dururken bile sürekli uyanıyordu. Artık src/pump.rs bu işi yalnız yapılacak bir şey varken çalıştırır:

  • 8 ms’lik zamanlayıcı, iş gelmeye devam ettikçe çalışır.
  • Kısa bir boşta bekleme süresinden sonra pompa zamanlayıcıyı durdurur ve olay döngüsü bir şey olana kadar uyur.
  • Snipdeck uyurken iş üretebilecek her kaynak (girdi kancası, tepsi, kısayol tuşları, yüzen pencere geri çağrıları, biten OCR, çeviri ve yükleme çalışanları, GNOME eklentisinin çağrıları) olayını kuyruğa koyduktan sonra pump::wake() çağırır. wake() her iş parçacığından çağrılabilir.

Pompa uyumadan önce bir geçiş daha yapar; böylece tam o anda gelen bir uyandırma kaybolmaz.

// src/main.rs (kısaltılmış)
pump::install(std::time::Duration::from_millis(8), move || {
    let mut active = false;
    // tepsi kanalını boşalt, sonra:
    if state.tick(&window) {
        active = true;
    }
    active // false, pompanın uyumasına izin verir
});

Bir tıkın boşalttıkları

src/app/mod.rs içindeki AppState::tick() her geçişte aynı sırayla ilerler:

SıraNe ele alınır
1Arayüz eylem kuyruğu: Slint geri çağrılarının eklediği düğme tıklamaları ve menü seçimleri
2Genel kısayol tuşu olayları
3Fare tetikleyici olayları: Windows’ta Win+sürükle seçimleri
4Arka planda biten işlerin hataları; bir bildirim olarak gösterilir
5Yükleme penceresinin düğmeleri ve biten yüklemeler; içe aktarılan .sxcu barındırıcıları
6Arka planda PNG’den WebP’ye dönüştürülen snip’ler
7Linux: oturum veri yolundaki (session bus) çağrılar (GNOME eklentisinden gelen Super+Alt+sürükle snip’leri, pencereyi isteyen ikinci bir başlatma)
8Yakalama katmanı ve renk seçicinin bakımı; başlatılıp yarıda bırakılan yakalamalar için bekçi denetimleri
9Açılmayı bekleyen yüzen pencereler
10Yüzen pencere geri çağrıları: sürükleme konumları, yeniden boyutlandırma bitişleri, menü ve kapatma istekleri
11Biten OCR + Çevir, açıklama ve kolaj sonuçları; ardından arayüz güncellenir

Bir istisna var: galerinin sütun sayısı geri çağrısı doğrudan main() içinde bağlanır. Windows’ta pencere canlı olarak yeniden boyutlandırılırken Win32 kendi kipli (modal) döngüsünü çalıştırır ve Slint’in zamanlayıcıları durur; kuyruğa konan bir eylem boyutlandırma bitene kadar beklerdi.

İş parçacıkları ve kanallar

Arayüze yalnız ana iş parçacığı dokunur. Diğer iş parçacıkları ve geri bildirme yolları:

ÇalışanPlatformGeri bildirme yolu
Alt düzey fare ve klavye kancaları (Win+sürükle)WindowsFare tetikleyici kanalı
Genel kısayol tuşları (Wayland’de masaüstü portalı üzerinden)İkisiHotkeyService::poll()
GNOME eklentisi için oturum veri yolu hizmetiLinuxVeri yolu kanalı, tick içinde boşaltılır
Tepsi menüsüİkisiTrayCommand kanalı, tick’ten önce boşaltılır
OCR dizinlemeİkisiMetni veritabanına yazar; galeri onu sonra alır
OCR + ÇevirİkisiTranslatePopup::poll()
YüklemeİkisiYükleme penceresinin okuduğu Outcome kanalı
PNG’den WebP’ye dönüştürme ve WebP’yi yeniden kodlamaİkisiDönüştürme kanalı
Kaydet ve .sxcu dosya pencereleriLinuxArka plan hata kanalı ve içe aktarma kanalı

Linux’ta dosya pencereleri başka bir sürece, masaüstü portalına aittir ve dosya penceresi kitaplığı onları iş parçacığını bekleterek bekler. Arayüz iş parçacığında bu, siz klasörlerde gezinirken bütün Snipdeck pencerelerini donduruyordu; bu yüzden Linux’ta bir çalışanda açılırlar. Windows’ta yerel pencere iş parçacığının pencerelerini yanıt verir halde tutar ve yerinde çalışır.

Modül haritası

ModülSorumluluk
src/app/ (mod.rs, input.rs, actions.rs, gallery.rs)AppState, tık başına tarama, arayüz eylemleri, galeri modeli
src/pump.rsBoştayken uyuyan ana iş parçacığı pompası
src/capture.rs, src/dxgi_capture.rs, src/screen.rsMonitör yakalama (Windows’ta DXGI Desktop Duplication, GDI yedeğiyle) ve monitör geometrisi
src/wayland_screencast.rs, src/pipewire_dl.rsLinux: ScreenCast portalı ve PipeWire üzerinden yakalama
src/mouse_trigger.rs, src/native_mouse_trigger.rsSnip’leri başlatan ve yöneten alt düzey fare ve klavye kancaları
src/slint_overlay.rs, ui/overlay.slintCanlı ya da dondurulmuş tam ekran seçim katmanı
src/floating.rs, ui/floating.slintYüzen snip pencereleri: sürükleme, yeniden boyutlandırma, kırpma, kenarlık
src/window_env.rsPencere sisteminin neye izin verdiği (yerleştirme, üstte kalma, görev çubuğu); tek yerde karar verilir
src/annotate.rs, ui/annotate.slintAçıklama düzenleyici: tiny-skia ile birleştirme, HSV çarkı, yakınlaştırma
src/collage.rs, ui/collage.slintKolaj düzenleyici
src/loupe.rs, src/color.rsBüyüteçli renk seçici
src/ocr.rsOCR: Windows’ta Windows.Media.Ocr, Linux’ta boru (pipe) üzerinden tesseract
src/translate.rs, src/translate_popup.rsOCR + Çevir ve penceresi
src/share.rs, src/upload.rsPaylaşım sayfası, e-posta ve görüntü düzenleyicisine verme; görüntü barındırıcısına yükleme
src/sxcu.rs, src/upload_window.rs, ui/upload.slintShareX özel yükleyicileri; yükleme penceresi (onay, ilerleme, sonuç)
src/hotkeys.rs, src/portal_hotkeys.rsGenel kısayol tuşları; Wayland’de masaüstü portalı üzerinden
src/bus_service.rsLinux: GNOME eklentisi ve ikinci bir başlatma için oturum veri yolunda com.revisetouch.Snipdeck
src/tray.rs, src/autostart.rs, src/single_instance.rs, src/elevate.rsTepsi simgesi, oturum açılınca başlatma, tek kopya koruması ve Windows’un tek seferlik “Yönetici olarak çalıştır” eylemi
src/snip.rs, src/settings.rs, src/paths.rsGalerinin kalıcılığı (tam metin aramalı SQLite), ayarlar, dosya konumları
src/image_files.rs, src/atomic_file.rsDiskteki snip görüntüleri: kayıpsız WebP, atomik yazma
src/i18n.rs, lang/Çalışma zamanı çevirisi ve gömülü gettext .po katalogları (23 dil)

Daha küçük modüller bütünü tamamlar: src/clipboard.rs (bütün süreç için tek pano), ui/context_menu.slint ile birlikte src/context_menu.rs (yüzen snip’lerin ve galeri kartlarının ortak sağ tık menüsü), src/window_metadata.rs (her snip’le saklanan pencere bilgisi) ve src/window_tamer.rs (Windows: açılış animasyonunu kapatma, görev çubuğu, ön plan izleme).

src/ dışında:

YolNe
packaging/gnome-extension/[email protected]/GNOME Shell eklentisi (extension.js, metadata.json)
packaging/linux/install.shRoot gerektirmeden ~/.local altına kurar; --uninstall geri alır
packaging/linux/install-from-source.shDerler, her dosyayı yeniden hazırlar ve install.sh’yi çalıştırır
packaging/linux/com.revisetouch.Snipdeck.desktopMenü girdisi; Wayland’de Snipdeck’e uygulama kimliğini adı verir

Yakalama

Windows’ta dxgi_capture.rs monitörü DXGI Desktop Duplication ile yakalar; çoğaltma kullanılamadığında ya da kare tamamen siyah geldiğinde GDI’ya geçer. Önce dondur (Win+Shift+Space), Space’e bastığınız anda bütün ekranı yakalar ve sürüklemede o kareyi kullanır; böylece fareyle üzerine gelince çıkan ipuçları görüntüde kalır. tick içindeki bir bekçi, kullanılmayan dondurulmuş kareyi bırakır; tam ekran bir arabellek bellekte kalmaz.

Linux’ta Wayland altında wayland_screencast.rs ekranı ScreenCast portalı üzerinden okur ve PipeWire’dan bellekte tek bir kare alır. libpipewire, bağlanmak yerine çalışma zamanında pipewire_dl.rs tarafından yüklenir; böylece derleme PipeWire’ın başlık dosyalarına ihtiyaç duymaz. Bulunmadığı yerde yakalama xcap kitaplığına döner.

GNOME eklentisi

Wayland bir programın kendi pencerelerini yerleştirmesine, üstte tutmasına ya da imleci genel olarak izlemesine izin vermez. GNOME Shell’in içindeki kod bunları yapabilir; bu yüzden eklenti Snipdeck için üç şey yapar:

  • Snipdeck’in snip pencerelerini başlıklarından tanır, yakalandıkları yere yerleştirir, diğer pencerelerin üstünde tutar, her çalışma alanında gösterir ve pencere değiştiricinin dışında tutar. Konum, bu kenarlıksız pencerelerde hiç görünmeyen pencere başlığında taşınır.
  • Super+Alt+sürükle hareketini sağlar: seçimi çizer, pikselleri GNOME Shell’in kendi ekran görüntüsü koduyla alır ve bölgeyi oturum veri yolundaki SnipRegion ile Snipdeck’e verir.
  • Super+Alt bileşimini yalnız Snipdeck veri yolundaki adının sahibiyken üstlenir; Snipdeck kapalıyken bileşim yeniden pencere taşımaya döner.

install.sh eklentiyi yalnız bir GNOME oturumunda kurar. GNOME onu bir sonraki oturum açılışında yükler.

Kalıcılık

src/snip.rs snip’leri tam metin dizinli bir SQLite veritabanında tutar; görüntüler ve küçük resimler bir önbellek klasöründe durur, src/paths.rs de her konumu çözer (bkz. Ayarlar).

src/image_files.rs, snip görüntülerine dokunan tek yerdir. Snip’ler kayıpsız WebP olarak saklanır; WebP’nin boyut sınırını aşan bir görüntü PNG olarak saklanır. Bir WebP önce en çabuk kayıpsız ayarla yazılır, sonra bir arka plan çalışanı onu daha küçük olacak şekilde yeniden kodlar. Her yolun, her yazma ve silmede artan bir kuşak numarası vardır; arka plan sonucu yalnız kuşak hâlâ başladığı kuşaksa yerine konur. Böylece daha yeni bir kırpmanın üzerine yazamaz ya da silinmiş bir snip’i geri getiremez.

src/atomic_file.rs önce yanına geçici bir dosya yazar, sonra onun adını hedefin adıyla değiştirir. Yazma sırasında bir çökme ya da dolan bir disk, yarım kalmış bir dosya değil, önceki dosyayı bırakır. Ayarlar da aynı yolla yazılır.

Yerelleştirme

lang/<kod>/LC_MESSAGES/ altında her dil için tek bir gettext .po dosyası hem Slint biçimlendirmesini (@tr("…") ile) hem Rust tarafındaki iletileri (i18n::t() ile) besler. Kataloglar derleme sırasında programın içine gömülür. Bkz. Diller.

Görüntüleyiciler

Snipdeck, Slint’in winit arka ucunu SLINT_BACKEND değişkeniyle seçmek yerine set_platform ile kendisi kurar. Uygulamanın ihtiyaç duyduğu WinitWindowAccessor arayüzünü açan budur. Görüntüleyici platforma göre değişir:

  • Windows: yazılım. Yakalama katmanı saydam bir penceredir ve GPU’da pencere saydamlığı ekran kartı sürücüsüne bağlıdır: birden çok ekran kartlı kurulumlarda katman bir monitörde opak, diğerinde saydam açılıyordu. Yazılım görüntüleyici sistemin standart birleştirme yolundan geçer ve her monitörde aynı görünür. Arayüzde animasyon ya da 3B olmadığından maliyeti görünmez; OpenGL bağlamı oluşmadığı için uygulama daha az bellek kullanır.
  • Linux: femtovg (GPU). Slint’in Wayland’deki yazılım yolu alfa kanalı olmayan bir yüzey biçimine çizer; katman ve sağ tık menüsü masaüstünün üzerinde düz siyah dikdörtgenler olarak çıkıyordu. GPU görüntüleyici alfa kanallı bir yüzey alır.

Cargo.toml, her platforma yalnız kullandığı görüntüleyiciyi derler.

Süreç ve yaşam döngüsü

  • Tek kopya. İlk olarak single_instance::acquire() çalışır. İkinci bir başlatma kısayollar ve girdi kancaları için ilkiyle çekişeceğinden çıkar; Linux’ta çıkmadan önce oturum veri yolu üzerinden çalışan Snipdeck’ten penceresini göstermesini ister.
  • Linux’ta uygulama kimliği. main(), ilk pencere açılmadan önce xdg uygulama kimliğini com.revisetouch.Snipdeck.desktop ile eşleşen com.revisetouch.Snipdeck olarak ayarlar; böylece masaüstü Snipdeck’in pencerelerini menü girdisine bağlar.
  • Windows’ta yüksek öncelik. Alt düzey kancaların çağrı başına katı bir süre sınırı vardır; normal öncelikte boşta duran bir süreçte sessiz bir aradan sonraki ilk olay düşebilir. Snipdeck, kanca zamanında yanıt versin diye önceliğini yükseltir.
  • Tepsiye kapanma. Ana pencereyi kapatmak onu tepsiye gizler; yalnız tepsideki Çıkış uygulamayı kapatır. Tepsinin olmadığı yerde (Linux bunu ancak çalışma zamanında bilebilir) pencereyi kapatmak uygulamadan çıkar; süreç geri dönüş yolu olmadan çalışır halde kalmaz.
  • Kayıt defteri olmadan oturum açılınca başlatma. Windows’ta Başlangıç klasöründe bir kısayol, Linux’ta bir XDG autostart girdisi; ikisi de Snipdeck’i tepside açması için --autostart ile başlatır. Bkz. Gizlilik ve güvenlik.

Ayrıca bakın

  • Ayarlar: dosya konumları ve bütün settings.json anahtarları
  • Diller: çeviri ekleme ve güncelleme
  • Gizlilik ve güvenlik: nelerin yerelde kaldığı, nelerin makineden çıktığı
  • Sorun giderme: yakalama, kısayol ve eklenti sorunları

Ok tuşlarıyla seçin, Enter ile gidin.