# 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** açı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` 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 ✓ - 2. 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.yaml` → `screen_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.dart` → `restore()` dışında, cascade hesabı için yardımcı fonksiyon: - `static Future 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)