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)
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:
- Arayüz durumu yalnız ana iş parçacığında değişir. Slint pencereleri, modelleri ve özellikleri
Senddeğildir; ana iş parçacığından hiç çıkmazlar. - 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ıra | Ne ele alınır |
|---|---|
| 1 | Arayüz eylem kuyruğu: Slint geri çağrılarının eklediği düğme tıklamaları ve menü seçimleri |
| 2 | Genel kısayol tuşu olayları |
| 3 | Fare tetikleyici olayları: Windows’ta Win+sürükle seçimleri |
| 4 | Arka planda biten işlerin hataları; bir bildirim olarak gösterilir |
| 5 | Yükleme penceresinin düğmeleri ve biten yüklemeler; içe aktarılan .sxcu barındırıcıları |
| 6 | Arka planda PNG’den WebP’ye dönüştürülen snip’ler |
| 7 | Linux: oturum veri yolundaki (session bus) çağrılar (GNOME eklentisinden gelen Super+Alt+sürükle snip’leri, pencereyi isteyen ikinci bir başlatma) |
| 8 | Yakalama katmanı ve renk seçicinin bakımı; başlatılıp yarıda bırakılan yakalamalar için bekçi denetimleri |
| 9 | Açılmayı bekleyen yüzen pencereler |
| 10 | Yüzen pencere geri çağrıları: sürükleme konumları, yeniden boyutlandırma bitişleri, menü ve kapatma istekleri |
| 11 | Biten 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ışan | Platform | Geri bildirme yolu |
|---|---|---|
Alt düzey fare ve klavye kancaları (Win+sürükle) | Windows | Fare tetikleyici kanalı |
| Genel kısayol tuşları (Wayland’de masaüstü portalı üzerinden) | İkisi | HotkeyService::poll() |
| GNOME eklentisi için oturum veri yolu hizmeti | Linux | Veri yolu kanalı, tick içinde boşaltılır |
| Tepsi menüsü | İkisi | TrayCommand kanalı, tick’ten önce boşaltılır |
| OCR dizinleme | İkisi | Metni veritabanına yazar; galeri onu sonra alır |
| OCR + Çevir | İkisi | TranslatePopup::poll() |
| Yükleme | İkisi | Yükleme penceresinin okuduğu Outcome kanalı |
| PNG’den WebP’ye dönüştürme ve WebP’yi yeniden kodlama | İkisi | Dönüştürme kanalı |
Kaydet ve .sxcu dosya pencereleri | Linux | Arka 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ül | Sorumluluk |
|---|---|
src/app/ (mod.rs, input.rs, actions.rs, gallery.rs) | AppState, tık başına tarama, arayüz eylemleri, galeri modeli |
src/pump.rs | Boştayken uyuyan ana iş parçacığı pompası |
src/capture.rs, src/dxgi_capture.rs, src/screen.rs | Monitör yakalama (Windows’ta DXGI Desktop Duplication, GDI yedeğiyle) ve monitör geometrisi |
src/wayland_screencast.rs, src/pipewire_dl.rs | Linux: ScreenCast portalı ve PipeWire üzerinden yakalama |
src/mouse_trigger.rs, src/native_mouse_trigger.rs | Snip’leri başlatan ve yöneten alt düzey fare ve klavye kancaları |
src/slint_overlay.rs, ui/overlay.slint | Canlı ya da dondurulmuş tam ekran seçim katmanı |
src/floating.rs, ui/floating.slint | Yüzen snip pencereleri: sürükleme, yeniden boyutlandırma, kırpma, kenarlık |
src/window_env.rs | Pencere sisteminin neye izin verdiği (yerleştirme, üstte kalma, görev çubuğu); tek yerde karar verilir |
src/annotate.rs, ui/annotate.slint | Açıklama düzenleyici: tiny-skia ile birleştirme, HSV çarkı, yakınlaştırma |
src/collage.rs, ui/collage.slint | Kolaj düzenleyici |
src/loupe.rs, src/color.rs | Büyüteçli renk seçici |
src/ocr.rs | OCR: Windows’ta Windows.Media.Ocr, Linux’ta boru (pipe) üzerinden tesseract |
src/translate.rs, src/translate_popup.rs | OCR + Çevir ve penceresi |
src/share.rs, src/upload.rs | Paylaşı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.slint | ShareX özel yükleyicileri; yükleme penceresi (onay, ilerleme, sonuç) |
src/hotkeys.rs, src/portal_hotkeys.rs | Genel kısayol tuşları; Wayland’de masaüstü portalı üzerinden |
src/bus_service.rs | Linux: 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.rs | Tepsi 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.rs | Galerinin kalıcılığı (tam metin aramalı SQLite), ayarlar, dosya konumları |
src/image_files.rs, src/atomic_file.rs | Diskteki 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:
| Yol | Ne |
|---|---|
packaging/gnome-extension/[email protected]/ | GNOME Shell eklentisi (extension.js, metadata.json) |
packaging/linux/install.sh | Root gerektirmeden ~/.local altına kurar; --uninstall geri alır |
packaging/linux/install-from-source.sh | Derler, her dosyayı yeniden hazırlar ve install.sh’yi çalıştırır |
packaging/linux/com.revisetouch.Snipdeck.desktop | Menü 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 yolundakiSnipRegionile Snipdeck’e verir.Super+Altbileş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ğinicom.revisetouch.Snipdeck.desktopile eşleşencom.revisetouch.Snipdeckolarak 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
--autostartile başlatır. Bkz. Gizlilik ve güvenlik.
Ayrıca bakın
- Ayarlar: dosya konumları ve bütün
settings.jsonanahtarları - Diller: çeviri ekleme ve güncelleme
- Gizlilik ve güvenlik: nelerin yerelde kaldığı, nelerin makineden çıktığı
- Sorun giderme: yakalama, kısayol ve eklenti sorunları
Bu sayfada eksik ya da yanlış bir şey varsa [email protected] adresine yazın.