Files
imajviewer/docs/pencere-cascade-yerlesim.md
Alhan a65bdc152c feat: jfif/jpe/wbmp format destegi, pencere cascade yerlesimi, konum kaydi duzeltmesi
- file_handler/image_manager: jfif, jpe, wbmp uzantilari
- .desktop + install.sh MimeType: image/vnd.wap.wbmp eklendi
- main.dart: yeni pencere oncekinin saginda acilir (screen_retriever ile ekran tespiti)
- viewer_screen: 2sn polling kaldirildi, konum kaydi tek akisa oturtuldu (acilis + move/resize debounce + close senkron)
- dist/rebuild-deb.sh: .desktop kaynaktan kopyalanir (MimeType/StartupWMClass guncel kalir)
- .deb guncellendi, docs: session-2026-08-03 + plan dokumanlari
2026-08-03 06:44:57 +03:00

5.2 KiB
Raw Blame History

Pencere Cascade Yerleşimi Planı

Tarih: 2026-08-03 · Değerlendirme + implementasyon planı (henüz kod değişikliği yapılmadı)

1. Sorun

imajViewer'a yeni bir resim açıldığında pencere hep aynı koordinat ve boyuttaılıyor (önceki pencerenin üstüne biniyor). İstenen davranış:

  • Yeni pencere, önceki pencerenin x + width kadar sağına açılsın (yan yana)
  • Ekrandan taşacaksa alt satıra, satır başından (x baştan) açılsın

Bu, Windows'un klasik "cascade windows" davranışının basit hali.

2. Mevcut Durum Analizi

Pencere açılış akışı (lib/main.dart)

main(args)
  → WindowPersistence.restore()      // window.json'dan son konum/boyut
  → windowOptions = WindowOptions(size: saved ?? 1280x800)
  → waitUntilReadyToShow:
      saved varsa  → setPosition(saved.position) + setSize(saved.size)
      saved yoksa  → center()
  → runApp(ImajViewerApp(initialFiles: args))

Konum kaydetme akışı (lib/screens/viewer_screen.dart + lib/services/window_persistence.dart)

  • _startPolling(): 2 saniyede bir windowManager.getBounds()WindowPersistence.saveSync()~/.config/imajviewer/window.json (Linux) / %APPDATA%/imajviewer/window.json (Windows)
  • onWindowEvent (move/resize/close) → debounce'lu _doSave()

Sorunun kökü

  • Her yeni pencere window.json'daki son kaydedilen konumu okuyor → aynı yere açılıyor
  • Cascade mantığı yok; ekran genişliği bilgisi hiç sorgulanmıyor

3. Teknik Araştırma (doğrulandı)

window_manager 0.4.3 (mevcut bağımlılık)

  • setPosition, setSize, getBounds, getPosition, getSize, center() → var
  • Ekran/display API'si → YOK (getScreen/getPrimaryDisplay yok)

window_manager 0.5.2 (güncel)

  • Ekran API'si yine yok — screen_retriever'ı bağımlılık olarak içeriyor ama expose etmiyor

screen_retriever 0.2.2 (pub.dev, window_manager'ın zaten bağımlısı)

  • ScreenRetriever.instance.getPrimaryDisplay()Display
  • getAllDisplays()List<Display>
  • Display alanları:
    • size (ekran tam boyutu, logical px)
    • visiblePosition (Offset — çalışma alanı başlangıcı)
    • visibleSize (Size — görev çubuğu hariç çalışma alanı)
    • scaleFactor
  • Linux (X11) + Windows desteği var

Karar: screen_retriever doğrudan bağımlılık olarak eklenir (window_manager sürümü değişmez).

4. Önerilen Algoritma

main.dart'ta, windowOptions oluşturulmadan önce:

1. saved = WindowPersistence.restore()
2. display = await ScreenRetriever.instance.getPrimaryDisplay()
   workArea = display.visiblePosition + display.visibleSize  (yoksa display.size)
3. Eğer saved != null:
     newX = saved.x + saved.width        // önceki pencerenin sağına
     newY = saved.y

     // Yatay taşma → alt satıra, satır başına
     if (newX + pencereGenişliği > workArea.right):
         newX = workArea.left
         newY = saved.y + saved.height

     // Dikey taşma da varsa → en başa sar (0,0)
     if (newY + pencereYüksekliği > workArea.bottom):
         newX = workArea.left
         newY = workArea.top

     position = Offset(newX, newY)
4. saved yoksa → center() (mevcut davranış)

Örnek

  • Ekran 1920×1080, pencere 1280×800, önceki pencere (100, 50)
    1. yeni: (1380, 50) — yan yana ✓
    1. yeni: (100+1280*2 = hesaplanır) → 1380+1280=2660 > 1920 → (0, 850) — alt satır başı

Not: saved her 2 saniyede bir güncellendiği için "önceki pencere" = en son kaydedilmiş konum. Bu, en son açılan pencerenin konumu olur — istenen davranışla uyumlu.

5. Yapılacaklar (sıralı)

  1. pubspec.yamlscreen_retriever: ^0.2.2 ekle, flutter pub get
  2. lib/main.dart → cascade hesabı ekle (yeni bir servis fonksiyonuna taşınabilir)
  3. lib/services/window_persistence.dartrestore() dışında, cascade hesabı için yardımcı fonksiyon:
    • static Future<Offset?> cascadePosition({required Size windowSize}) (opsiyonel, temizlik için)
  4. Ekran boyutu alınamazsa (hata / çoklu monitör) → mevcut davranışa düş (saved veya center)
  5. Test: ardışık 3-4 resim aç → yan yana dizilim + taşınca alt satır

6. Riskler / Açık Sorular

  • Çoklu monitör: getPrimaryDisplay birincil ekranı verir. İmleç hangi ekrandaysa oraya açılsın mı? (başlangıç: primary)
  • Pencere kapatılıp yenisi açılırsa: window.json son kapanan pencerenin konumunu tutar; yeni pencere onun yanına açılır — boşluk oluşabilir, kabul edilebilir
  • Tam ekran / maximize durumu: saved boyut maximize ise cascade hesabı yine de eski boyutla yapılır; window.json sadece normal durumda yazıldığı için risk düşük
  • Pencere ekrandan tamamen dışarıdaysa: restore() zaten x < -1000 || y < -1000 guard'ı var (window_persistence.dart:44) — yine de sağlamlaştırılabilir

7. Kabul Kriterleri

  • Ardışık 2 pencere: ikincisi birincinin hemen sağında
  • Yatay taşma: yeni pencere alt satıra, satır başından başlar
  • İlk açılışta (kayıt yok) pencere yine ortalanır
  • Pencere boyutu/konumu kaydetme davranışı bozulmaz
  • Linux ve Windows'ta çalışır (screen_retriever her ikisini destekliyor)