fix: manuel ve otomatik bölümlemede kök dizin boyutu hesaplama hatası

This commit is contained in:
Erkan IŞIK
2026-08-22 13:09:04 +03:00
parent fb905d9714
commit 91acde5317
5 changed files with 139 additions and 173 deletions
+1 -1
View File
@@ -63,7 +63,7 @@ pub fn all_passed(results: &[CheckResult]) -> bool {
fn check_ram() -> CheckResult {
let mut sys = System::new();
sys.refresh_memory();
let mb = sys.total_memory() / 1024 / 1024;
let mb = sys.total_memory() / 1_048_576;
if mb < 1024 {
CheckResult::fail(
+2 -2
View File
@@ -137,12 +137,12 @@ pub fn apply_to_state(af: &AnswerFile, state: &mut crate::installer::GlobalState
if let Some(info) = disk_info {
let is_uefi = std::path::Path::new("/sys/firmware/efi").exists();
let efi_mb = if is_uefi { 512u64 } else { 0 };
let total_mb = info.size_bytes / 1024 / 1024;
let total_mb = info.size_bytes / 1_048_576;
// Swap: RAM * 1.0, min 512 MB, max 2048 MB, ayrıca diskin %10'unu geçmesin
let mut sys = sysinfo::System::new();
sys.refresh_memory();
let ram_mb = sys.total_memory() / 1024 / 1024;
let ram_mb = sys.total_memory() / 1_048_576;
let disk_10pct = total_mb / 10;
let swap_mb = ram_mb.clamp(512, 2048).min(disk_10pct);
+116 -125
View File
@@ -7,6 +7,7 @@
use std::sync::mpsc;
use std::thread;
use std::time::{Duration, Instant};
use eframe::egui;
use rust_i18n::t;
@@ -24,6 +25,8 @@ pub struct ExecutionStep {
slideshow: Option<Slideshow>,
/// rsync kopyalama fazı aktifken tek ilerleme çubuğu gösterilir.
copy_active: bool,
/// Kurulum bitince tamamlandı ekranına otomatik geçiş için zaman damgası.
finished_at: Option<Instant>,
}
impl InstallerStep for ExecutionStep {
@@ -35,6 +38,7 @@ impl InstallerStep for ExecutionStep {
self.tx = Some(tx);
self.finished = false;
self.error_screen = None;
self.finished_at = None;
let desktop = std::env::var("XDG_CURRENT_DESKTOP")
.unwrap_or_else(|_| "default".to_string())
@@ -206,6 +210,7 @@ impl InstallerStep for ExecutionStep {
Ok(InstallMessage::Done) => {
state.install_progress = 1.0;
self.finished = true;
self.finished_at = Some(Instant::now());
}
Ok(InstallMessage::Error(e)) => {
self.error_screen = Some(ErrorScreen::new(
@@ -240,134 +245,108 @@ impl InstallerStep for ExecutionStep {
}
// ── Normal kurulum görünümü ────────────────────────────
// Üst: Slayt gösterisi | Alt: ilerleme + log
// Üst: Slayt gösterisi (kalan alanı doldurur) | Alt: ilerleme durumu
let available_w = ui.available_width();
let available_h = ui.available_height();
ui.vertical(|ui| {
// Üst kısım — slayt gösterisi
let slide_h = (available_h * 0.45).max(280.0);
ui.allocate_ui(egui::vec2(available_w, slide_h), |ui| {
ui.vertical(|ui| {
ui.add_space(8.0);
theme::section_heading(ui, &t!("execution_title"));
ui.label(
egui::RichText::new(t!("execution_description"))
.color(theme::c_text_dim())
.size(13.0),
);
ui.add_space(16.0);
// ── Üst kısım — başlık + slayt gösterisi (kalan alanı doldurur) ──
ui.add_space(8.0);
theme::section_heading(ui, &t!("execution_title"));
ui.label(
egui::RichText::new(t!("execution_description"))
.color(theme::c_text_dim())
.size(13.0),
);
ui.add_space(16.0);
if let Some(ref mut ss) = self.slideshow {
ss.show(ui);
ui.add_space(10.0);
// Manuel ileri/geri butonları
ui.horizontal(|ui| {
if ui.small_button("‹").clicked() { ss.previous(); }
if ui.small_button("›").clicked() { ss.advance(); }
});
}
});
// Alt kısım (ilerleme + durum) için ayrılan yükseklik.
// bottom_up layout en sonda olduğu için slayt alanını kalan
// yükseklikle sınırlandırıyoruz; aksi halde slayt gösterisi
// ekranın dışına itilir.
let bottom_h = 170.0;
let slide_h = (ui.available_height() - bottom_h).max(200.0);
ui.allocate_ui(egui::vec2(available_w, slide_h), |ui| {
ui.set_min_height(slide_h);
if let Some(ref mut ss) = self.slideshow {
ss.show(ui);
}
});
ui.add_space(16.0);
ui.separator();
ui.add_space(16.0);
// Alt kısım — ilerleme + log
let log_h = available_h - slide_h - 50.0;
ui.allocate_ui(egui::vec2(available_w, log_h), |ui| {
ui.vertical(|ui| {
ui.add_space(8.0);
// ── Alt kısım — ilerleme + durum (en altta) ──────────
ui.with_layout(egui::Layout::bottom_up(egui::Align::Min), |ui| {
ui.add_space(8.0);
// İlerleme çubuğu — yalnızca rsync kopyalama fazında
// tek bar gösterilir (eski YALI düzeni). Diğer adımlar
// (fstab, GRUB, temizlik vb.) metin + spinner olarak
// görünür.
let running = !self.finished
&& self.error_screen.is_none()
&& (self.copy_active || state.install_progress > 0.0);
// İlerleme çubuğu — yalnızca rsync kopyalama fazında
// tek bar gösterilir (eski YALI düzeni). Diğer adımlar
// (fstab, GRUB, temizlik vb.) metin + spinner olarak
// görünür.
let running = !self.finished
&& self.error_screen.is_none()
&& (self.copy_active || state.install_progress > 0.0);
egui::Frame::none()
.fill(theme::c_bg_widget())
.rounding(egui::Rounding::same(8.0))
.inner_margin(egui::Margin::same(12.0))
.show(ui, |ui| {
ui.set_width(available_w - 4.0);
let step_label = state.install_log.last()
.cloned()
.unwrap_or_default();
ui.label(
egui::RichText::new(&step_label)
.size(12.0)
.color(theme::c_text_dim()),
egui::Frame::none()
.fill(theme::c_bg_widget())
.rounding(egui::Rounding::same(8.0))
.inner_margin(egui::Margin::same(12.0))
.show(ui, |ui| {
ui.set_width(available_w - 4.0);
let step_label = state.install_log.last()
.cloned()
.unwrap_or_default();
ui.label(
egui::RichText::new(&step_label)
.size(12.0)
.color(theme::c_text_dim()),
);
if self.copy_active {
let pct = format!("{:.0}%", state.install_sub_progress * 100.0);
let bar = ui.add(
egui::ProgressBar::new(state.install_sub_progress)
.animate(running)
.desired_height(20.0),
);
ui.painter().text(
bar.rect.center(),
egui::Align2::CENTER_CENTER,
pct,
egui::FontId::proportional(14.0),
theme::c_text(),
);
if self.copy_active {
let pct = format!("{:.0}%", state.install_sub_progress * 100.0);
let bar = ui.add(
egui::ProgressBar::new(state.install_sub_progress)
.animate(running)
.desired_height(20.0),
);
ui.painter().text(
bar.rect.center(),
egui::Align2::CENTER_CENTER,
pct,
egui::FontId::proportional(14.0),
theme::c_text(),
);
if let Some(ref current_file) = state.install_current_file {
ui.add_space(4.0);
ui.label(
egui::RichText::new(format!("{}: {}", t!("install_current_file"), current_file))
.size(12.0)
.color(theme::c_text_dim()),
);
}
} else if running {
if let Some(ref current_file) = state.install_current_file {
ui.add_space(4.0);
ui.horizontal(|ui| {
ui.spinner();
ui.colored_label(theme::c_text_dim(), t!("install_in_progress"));
});
ui.label(
egui::RichText::new(format!("{}: {}", t!("install_current_file"), current_file))
.size(12.0)
.color(theme::c_text_dim()),
);
}
});
} else if running {
ui.add_space(4.0);
ui.horizontal(|ui| {
ui.spinner();
ui.colored_label(theme::c_text_dim(), t!("install_in_progress"));
});
}
});
// Durum etiketi
ui.add_space(8.0);
if self.finished {
theme::success_box(ui, &t!("install_done"));
} else if running {
ui.horizontal(|ui| {
ui.spinner();
ui.colored_label(theme::c_text_dim(), t!("install_in_progress"));
});
}
// Durum etiketi
ui.add_space(8.0);
if self.finished {
theme::success_box(ui, &t!("install_done"));
} else if running {
ui.horizontal(|ui| {
ui.spinner();
ui.colored_label(theme::c_text_dim(), t!("install_in_progress"));
});
}
ui.add_space(8.0);
// Log terminali
let terminal_h = if self.finished { log_h - 60.0 } else { log_h - 80.0 };
egui::ScrollArea::vertical()
.max_height(terminal_h.max(100.0))
.stick_to_bottom(true)
.id_source("exec_log")
.show(ui, |ui| {
egui::Frame::none()
.fill(egui::Color32::from_rgb(12, 12, 20))
.rounding(egui::Rounding::same(6.0))
.inner_margin(egui::Margin::same(10.0))
.show(ui, |ui| {
ui.set_width(available_w - 8.0);
for line in &state.install_log {
let color = log_color(line);
ui.colored_label(color, line);
}
});
});
});
ui.add_space(16.0);
ui.separator();
ui.add_space(16.0);
});
});
@@ -375,6 +354,18 @@ impl InstallerStep for ExecutionStep {
if !self.finished && self.error_screen.is_none() {
ui.ctx().request_repaint();
}
// Kurulum tamamlanınca kısa bir bekleyişten sonra otomatik olarak
// tamamlandı ekranına geç
if self.finished && self.error_screen.is_none() {
if let Some(at) = self.finished_at {
if at.elapsed() >= Duration::from_secs(2) {
state.current_step += 1;
} else {
ui.ctx().request_repaint_after(Duration::from_secs(1));
}
}
}
}
fn is_complete(&self, _state: &GlobalState) -> bool {
@@ -382,16 +373,16 @@ impl InstallerStep for ExecutionStep {
}
}
fn log_color(line: &str) -> egui::Color32 {
if line.starts_with('✗') {
theme::c_error()
} else if line.starts_with('✓') {
theme::c_success()
} else if line.starts_with('▶') {
theme::c_accent()
} else if line.starts_with('⚠') {
theme::c_warning()
} else {
egui::Color32::from_rgb(185, 185, 205)
}
}
// fn log_color(line: &str) -> egui::Color32 {
// if line.starts_with('✗') {
// theme::c_error()
// } else if line.starts_with('✓') {
// theme::c_success()
// } else if line.starts_with('▶') {
// theme::c_accent()
// } else if line.starts_with('⚠') {
// theme::c_warning()
// } else {
// egui::Color32::from_rgb(185, 185, 205)
// }
// }
+17 -10
View File
@@ -296,7 +296,7 @@ fn recommended_swap_mb() -> u64 {
use sysinfo::System;
let mut sys = System::new();
sys.refresh_memory();
let ram_mb = sys.total_memory() / 1024 / 1024;
let ram_mb = sys.total_memory() / 1_048_576;
let swap = if ram_mb <= 2048 {
ram_mb
} else if ram_mb <= 8192 {
@@ -312,7 +312,7 @@ fn make_plan(disk: &DiskInfo, is_uefi: bool) -> Option<PartitionPlan> {
if disk.size_gb < MIN_DISK_GB {
return None;
}
let total_mb = disk.size_bytes / 1024 / 1024;
let total_mb = disk.size_bytes / 1_048_576;
let efi_mb = if is_uefi { EFI_MB } else { 0 };
let swap_mb = recommended_swap_mb();
let overhead = efi_mb + swap_mb + 512;
@@ -489,7 +489,8 @@ impl PartitionStep {
if response.clicked() && !too_small {
state.selected_disk = Some(disk.name.clone());
self.selected_disk_size_mb = Some(disk.size_gb * 1024);
self.selected_disk_size_mb = Some(disk.size_bytes / 1_048_576);
eprintln!("DEBUG AUTO DISK SELECT: disk={} size_bytes={} size_mb={}", disk.name, disk.size_bytes, disk.size_bytes / 1_048_576);
state.partition_plan = make_plan(disk, self.is_uefi);
}
@@ -717,7 +718,8 @@ impl PartitionStep {
if response.clicked() {
state.selected_disk = Some(disk.name.clone());
self.selected_disk_size_mb = Some(disk.size_gb * 1024);
self.selected_disk_size_mb = Some(disk.size_bytes / 1_048_576);
eprintln!("DEBUG DISK SELECT: disk={} size_bytes={} size_mb={}", disk.name, disk.size_bytes, disk.size_bytes / 1_048_576);
state.custom_partitions = read_existing_partitions(&disk.name);
self.manual.error = None;
}
@@ -738,11 +740,8 @@ impl PartitionStep {
return;
}
};
let disk_size_gb = state.available_disks.iter()
.find(|d| d.name == disk)
.map(|d| d.size_gb)
.unwrap_or(256);
let max_mb = (disk_size_gb as f64) * 1024.0;
let max_mb = self.selected_disk_size_mb.unwrap_or(256 * 1024) as f64;
eprintln!("DEBUG MAX_MB: selected_disk_size_mb={:?} max_mb={}", self.selected_disk_size_mb, max_mb);
// ── Mevcut bölüm listesi tablosu ───────────────────────
ui.label(egui::RichText::new(t!("mp_plan_title")).strong().color(crate::ui::theme::c_text()));
@@ -1054,6 +1053,9 @@ impl PartitionStep {
.map(|(_, p)| p.size_mb)
.sum();
let avail_mb = (max_mb as u64).saturating_sub(used_mb).max(1);
eprintln!("DEBUG EDIT: max_mb={} used_mb={} avail_mb={} edit_idx={:?} partitions={:?}",
max_mb, used_mb, avail_mb, self.manual.edit_idx,
state.custom_partitions.iter().map(|p| (p.mountpoint.clone(), p.size_mb)).collect::<Vec<_>>());
let mut size_val = self.manual.add_size_str.trim().parse::<f64>().unwrap_or(0.0);
ui.add_space(2.0);
if ui.add(egui::Slider::new(&mut size_val, 0.0..=avail_mb as f64)
@@ -1190,8 +1192,13 @@ impl PartitionStep {
let size_mb: u64 = if size_str == "remaining" {
// Kalan alanı hesapla
if let Some(disk_size) = self.selected_disk_size_mb {
let used: u64 = state.custom_partitions.iter().map(|p| p.size_mb).sum();
let used: u64 = state.custom_partitions.iter()
.enumerate()
.filter(|(i, _)| Some(*i) != self.manual.edit_idx)
.map(|(_, p)| p.size_mb)
.sum();
let remaining = disk_size.saturating_sub(used);
eprintln!("DEBUG REMAINING: disk_size={} used={} remaining={}", disk_size, used, remaining);
if remaining > 0 { remaining } else { disk_size }
} else {
0
+3 -35
View File
@@ -109,12 +109,14 @@ impl Slideshow {
None
};
// Kart, kendisine ayrılan dikey alanı doldursun.
let fill_h = ui.available_height().max(180.0);
egui::Frame::none()
.fill(crate::ui::theme::c_bg_widget())
.rounding(egui::Rounding::same(10.0))
.inner_margin(egui::Margin::same(24.0))
.show(ui, |ui| {
ui.set_min_height(180.0);
ui.set_min_height(fill_h);
ui.vertical_centered(|ui| {
// Simge veya Görsel
if let Some(uri) = resolved_uri {
@@ -147,45 +149,11 @@ impl Slideshow {
.color(crate::ui::theme::c_text_dim()),
);
ui.add_space(16.0);
// Nokta göstergesi
ui.horizontal(|ui| {
let dot_size = egui::vec2(8.0, 8.0);
for i in 0..self.slides.len() {
let color = if i == self.current {
crate::ui::theme::c_accent()
} else {
crate::ui::theme::c_border()
};
let (rect, response) = ui.allocate_exact_size(dot_size, egui::Sense::click());
ui.painter().circle_filled(rect.center(), 4.0, color);
if response.clicked() {
self.current = i;
self.last_advance = Instant::now();
}
ui.add_space(4.0);
}
});
});
});
}
pub fn slide_count(&self) -> usize {
self.slides.len()
}
pub fn advance(&mut self) {
self.current = (self.current + 1) % self.slides.len();
self.last_advance = Instant::now();
}
pub fn previous(&mut self) {
if self.current == 0 {
self.current = self.slides.len() - 1;
} else {
self.current -= 1;
}
self.last_advance = Instant::now();
}
}