Files
hcie-rust-v3.05/hcie-egui-app/.kilo/plans/dock-stability-changes.md
T
2026-07-09 02:59:53 +03:00

9.7 KiB
Raw Blame History

Dock Sistemi Kararlılık ve Kullanılabilirlik İyileştirmeleri

1. default_dock_state() — Tekrarlanan Layout Kodunun Tekilleştirilmesi

Dosya: crates/hcie-gui-egui/src/app/mod.rs:699-714

Yeni fonksiyon:

fn default_dock_state() -> egui_dock::DockState<dock::HciePane> { ... }

Gerekçe: Dock layout kodu (split_left/split_right/split_below ile aynı panel yapısı) 3 farklı yerde manuel olarak tekrarlanıyordu:

  1. HcieApp::new() — ilk açılış
  2. AppEvent::ResetLayout handler'ı
  3. enforce_constraints() fallback

Her kopya arasında ufak farklar vardı (fallback'te Tools/Brushes/ColorBox/Layers farklı oranlardaydı). Bu, bir layout değişikliğinde 3 yerin de güncellenmesini zorunlu kılıyor ve tutarsızlık riski taşıyordu.

Değişen çağrılar:

  • mod.rs:863dock_state.unwrap_or_else(default_dock_state)
  • mod.rs:1210self.dock_state = default_dock_state()
  • mod.rs:2256*state = default_dock_state()

2. std::mem::replace → swap (CRITICAL)

Dosya: crates/hcie-gui-egui/src/app/mod.rs:1984

Eski kod:

let mut dock_state = std::mem::replace(&mut self.dock_state, egui_dock::DockState::new(vec![]));

Yeni kod:

let mut dock_state = default_dock_state();
std::mem::swap(&mut dock_state, &mut self.dock_state);

Gerekçe: Eski kod self.dock_state'i tamamen boş bir DockState (0 surface, 0 node) ile değiştiriyor, sonra 50+ satır işlem yapıp en sonda geri atıyordu (self.dock_state = dock_state). Bu aralıkta herhangi bir panic olursa self.dock_state permament olarak 0 surface'li boş state'te kalır — sonraki her main_surface_mut() panic üretir. Yeni kod default_dock_state() ile swap yaparak bu riski ortadan kaldırır.


3. dock_safe_remove_tab() — Panic-Safe Tab Silme

Dosya: crates/hcie-gui-egui/src/app/mod.rs:998-1023

İmza:

fn dock_safe_remove_tab(&mut self, pos: (SurfaceIndex, NodeIndex, TabIndex)) -> Option<HciePane>

Gerekçe: egui_dock::DockState::remove_tab() üç index'i de bounds-check'siz kullanır — OOB'de panic. Helper sırasıyla surface → node → tab index'lerini doğrular, geçersizse log::warn + None döndürür.


4. dock_find_tabs() — Enumeration Helper

Dosya: crates/hcie-gui-egui/src/app/mod.rs:1024-1043

İmza:

fn dock_find_tabs<F>(&self, predicate: F) -> Vec<(SurfaceIndex, NodeIndex, TabIndex)>

Gerekçe: AppEvent::DocClosed handler'ında 15 satırlık manuel 3-seviye enumerate kodu 2 satıra indirildi. Aynı desenin birden çok yerde tekrarlanması önlendi.

Kullanım: mod.rs:1153DocClosed'ta tab'leri bulmak için.


5. enforce_constraints() — Parametre Temizliği

Dosya: crates/hcie-gui-egui/src/app/mod.rs:2138

Eski imza (9 parametre):

fn enforce_constraints(
    _ctx: &egui::Context, state: &mut DockState<HciePane>,
    _available_width: f32, _last_window_width: &mut f32,
    _left_col1_w: &mut f32, _left_col2_w: &mut f32,
    _right_col1_w: &mut f32, _right_col2_w: &mut f32,
    _stable_frames: u32,
) -> Option<usize>

Yeni imza:

fn enforce_constraints(state: &mut DockState<HciePane>) -> Option<usize>

Çağrıldığı yer: mod.rs:2036

remove_tab validasyonu (satır 2192-2207): tab_to_move index'leri scan fazında toplanır, remove_tab öncesi iter_surfaces().nth(node_idx.0).map_or(false, |n| matches!(n, Node::Leaf { tabs, .. } if tab_idx.0 < tabs.len())) ile doğrulanır.


6. sync_active_doc_from_dock() — Stale active_doc Düzeltmesi

Dosya: crates/hcie-gui-egui/src/app/mod.rs:1047-1056

İmza:

pub fn sync_active_doc_from_dock(&mut self) { ... }

Çağrıldığı yerler:

  • mod.rs:1171AppEvent::DocClosed handling sonrası
  • mod.rs:2020ui_main_assembly içinde dock_state swap-back sonrası

Gerekçe: Document kapatıldığında veya dock yeniden düzenlendiğinde self.active_doc eski bir index'i gösterebilir. Fonksiyon dock tree'deki ilk geçerli document index'ini bularak active_doc'u günceller.


7. dock.rs TabViewer title() — Referans Ömrü Güvenliği

Dosya: crates/hcie-gui-egui/src/app/dock.rs:184-196

Eski kod:

if let Some(surface) = self.app.dock_state.iter_surfaces().nth(surf_idx.0) {
    if let Some(node) = surface.iter_nodes().nth(node_idx.0) {

Yeni kod:

let surface = self.app.dock_state.iter_surfaces().nth(surf_idx.0);
if let Some(surface) = surface {
    let node = surface.iter_nodes().nth(node_idx.0);
    if let Some(node) = node {

Gerekçe: Eski zincirleme if let'de borrow checker surface referansının ömrünü gereksiz yere uzatabiliyor. Ayrı let'ler referans ömürlerini netleştirir ve refactor durumunda borrow checker sorunlarını önler.


8. layout_solver.rs — Fraction Manipülasyonu Sadece Resize'da

Dosya: crates/hcie-gui-egui/src/app/layout_solver.rs (tamamen yeniden yazıldı, 336 satır → 188 satır)

Ana problem: Layout solver her stabil frame'de fraction'ları yeniden hesaplıyordu. Kullanıcı splitter'ı bırakır bırakmaz "stable + !pointer_down" branch'i Tools'u grid'e snap'liyor VE tüm column fraction'larını stored width'lere zorluyordu — kullanıcının elle ayarladığı genişlik sıfırlanıyordu.

Durum Eski Davranış Yeni Davranış
Pencere boyut değişikliği (≥1px) Her stabil frame'de enforcement Sadece width_changed ise enforcement
Splitter sürükleniyor Measure + store (3 frame) Measure + store (3 frame, aynı)
Splitter bırakıldı Snap + enforce → kullanıcıyı ezer Sadece measure + store (30 frame idle'da)
Fraction clamp 0.03..0.97 0.05..0.95
Utility panel yok Her Horizontal node'a müdahale (None, None) => return — atla

Kilit değişiklikler:

  • width_changed = (*last_window_width - available_width).abs() >= 1.0 — enforcement sadece resize'da
  • (None, None) => return — utility panel olmayan split'lere dokunma
  • stable_frames >= 30 idle persistence — sürekli ölçmek yerine 30 frame'de bir
  • *f = new_fraction.clamp(0.05, 0.95) — minimum %5 genişlik
  • measure_and_store_column() helper'ı ile find_column_width + store tek satırda

9. Dock Layout Profile Sistemi

Genel Bakış

Kullanıcılar panel düzenlerini (dock_state, column genişlikleri, pinned_panels) adlandırılmış profil olarak kaydedip geri yükleyebilir.

Veri Yapıları

DockProfilemod.rs:195-202

pub struct DockProfile {
    pub name: String,
    pub dock_state_json: String,
    pub left_col1_w: f32, pub left_col2_w: f32,
    pub right_col1_w: f32, pub right_col2_w: f32,
    pub last_window_width: f32,
    pub pinned_panels: Vec<String>,
}

Settings.dock_profilesmod.rs:214

#[serde(default)]
pub dock_profiles: Vec<DockProfile>,

Events (event_bus.rs:107-110)

Event Purpose
DockProfileSave(String) Mevcut layout'u adla kaydet
DockProfileApply(String) Kayıtlı profili yükle
DockProfileDelete(String) Profili sil
DockProfileRename(String, String) Profili yeniden adlandır

HcieApp Alanları (mod.rs:677-680)

pub show_dock_profile_dialog: bool,
pub dock_profile_new_name: String,
pub dock_profile_rename_target: Option<usize>,
pub dock_profile_rename_buf: String,

Dialog UI

Dosya: src/app/dock_profile_dialog.rs (yeni, 130 satır)

Modal dialog (egui::Area + dim_background) ile:

  • Profil listesi (scrollable): her satırda ad + Apply / Rename / Delete butonları
  • Rename modu: inline text edit + ✓ onay
  • "Save Current" bölümü: isim gir + Save (veya Enter)
  • Boş profil listesinde "No saved profiles yet." mesajı

Çağrıldığı yer: mod.rs:2067

Event Handlers (mod.rs:1817-1872)

  • DockProfileSave (satır 1817): DockState JSON'a serialize, width/pinned alınır, aynı isimde profil varsa üzerine yazılır, SaveSettings tetiklenir.
  • DockProfileApply (satır 1837): JSON'dan deserialize, tüm width/pinned değerler atanır, ctx.request_repaint().
  • DockProfileDelete (satır 1854): retain ile filtrele + SaveSettings.
  • DockProfileRename (satır 1863): Matching profile'in name field'ı güncellenir + SaveSettings.

Menu Entries (menus.rs:554-559)

  • Window → Dock Layout Profiles…: dialog'u açar
  • Window → Save Dock Layout As…: dialog'u açar + name input'u "My Layout" ile ön doldurur
  • Window → Reset Layout: mevcut

10. Ölü Kod Temizliği

Öğe Dosya Silinen satırlar
show_filter_dialog() filter_dialog.rs:453-466 14 satır
show_filter_dialog() re-export dialogs.rs:386-388 4 satır
FilterDialogState struct filter_dialog.rs:8-18 11 satır
show_filter, filter_dialog, filter_params_open, filter_preview_active mod.rs:615-618 4 field
draw_auto_hide_strips() mod.rs eski 2209-2322 114 satır
enforce_constraints doc comment (8 parametre) mod.rs eski 2048-2061 14 satır
3× tekrarlanan layout kodu → default_dock_state() mod.rs ~90 satır
adjust_pixel_widths_rec yeniden yazımı layout_solver.rs 336→188 satır

Değişiklik İstatistikleri (git diff --stat)

Dosya Eklenen Silinen Net
mod.rs +445 / -445
dock_profile_dialog.rs (yeni) 130 0 +130
layout_solver.rs +24 / -336
filter_dialog.rs 0 49 -49
dialogs.rs 0 4 -4
dock.rs 4 2 +2
menus.rs 7 0 +7
event_bus.rs 4 0 +4
Toplam ~290 ~560 ~-270

Build: 0 error, 0 new warning (cargo check clean).