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 { fn check_ram() -> CheckResult {
let mut sys = System::new(); let mut sys = System::new();
sys.refresh_memory(); sys.refresh_memory();
let mb = sys.total_memory() / 1024 / 1024; let mb = sys.total_memory() / 1_048_576;
if mb < 1024 { if mb < 1024 {
CheckResult::fail( 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 { if let Some(info) = disk_info {
let is_uefi = std::path::Path::new("/sys/firmware/efi").exists(); let is_uefi = std::path::Path::new("/sys/firmware/efi").exists();
let efi_mb = if is_uefi { 512u64 } else { 0 }; 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 // Swap: RAM * 1.0, min 512 MB, max 2048 MB, ayrıca diskin %10'unu geçmesin
let mut sys = sysinfo::System::new(); let mut sys = sysinfo::System::new();
sys.refresh_memory(); 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 disk_10pct = total_mb / 10;
let swap_mb = ram_mb.clamp(512, 2048).min(disk_10pct); let swap_mb = ram_mb.clamp(512, 2048).min(disk_10pct);
+45 -54
View File
@@ -7,6 +7,7 @@
use std::sync::mpsc; use std::sync::mpsc;
use std::thread; use std::thread;
use std::time::{Duration, Instant};
use eframe::egui; use eframe::egui;
use rust_i18n::t; use rust_i18n::t;
@@ -24,6 +25,8 @@ pub struct ExecutionStep {
slideshow: Option<Slideshow>, slideshow: Option<Slideshow>,
/// rsync kopyalama fazı aktifken tek ilerleme çubuğu gösterilir. /// rsync kopyalama fazı aktifken tek ilerleme çubuğu gösterilir.
copy_active: bool, copy_active: bool,
/// Kurulum bitince tamamlandı ekranına otomatik geçiş için zaman damgası.
finished_at: Option<Instant>,
} }
impl InstallerStep for ExecutionStep { impl InstallerStep for ExecutionStep {
@@ -35,6 +38,7 @@ impl InstallerStep for ExecutionStep {
self.tx = Some(tx); self.tx = Some(tx);
self.finished = false; self.finished = false;
self.error_screen = None; self.error_screen = None;
self.finished_at = None;
let desktop = std::env::var("XDG_CURRENT_DESKTOP") let desktop = std::env::var("XDG_CURRENT_DESKTOP")
.unwrap_or_else(|_| "default".to_string()) .unwrap_or_else(|_| "default".to_string())
@@ -206,6 +210,7 @@ impl InstallerStep for ExecutionStep {
Ok(InstallMessage::Done) => { Ok(InstallMessage::Done) => {
state.install_progress = 1.0; state.install_progress = 1.0;
self.finished = true; self.finished = true;
self.finished_at = Some(Instant::now());
} }
Ok(InstallMessage::Error(e)) => { Ok(InstallMessage::Error(e)) => {
self.error_screen = Some(ErrorScreen::new( self.error_screen = Some(ErrorScreen::new(
@@ -240,15 +245,11 @@ impl InstallerStep for ExecutionStep {
} }
// ── Normal kurulum görünümü ──────────────────────────── // ── 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_w = ui.available_width();
let available_h = ui.available_height();
ui.vertical(|ui| { ui.vertical(|ui| {
// Üst kısım — slayt gösterisi // ── Üst kısım — başlık + slayt gösterisi (kalan alanı doldurur) ──
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); ui.add_space(8.0);
theme::section_heading(ui, &t!("execution_title")); theme::section_heading(ui, &t!("execution_title"));
ui.label( ui.label(
@@ -258,26 +259,23 @@ impl InstallerStep for ExecutionStep {
); );
ui.add_space(16.0); ui.add_space(16.0);
// 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 { if let Some(ref mut ss) = self.slideshow {
ss.show(ui); 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(); }
});
} }
}); });
});
ui.add_space(16.0);
ui.separator();
ui.add_space(16.0); ui.add_space(16.0);
// Alt kısım — ilerleme + log // ── Alt kısım — ilerleme + durum (en altta) ──────────
let log_h = available_h - slide_h - 50.0; ui.with_layout(egui::Layout::bottom_up(egui::Align::Min), |ui| {
ui.allocate_ui(egui::vec2(available_w, log_h), |ui| {
ui.vertical(|ui| {
ui.add_space(8.0); ui.add_space(8.0);
// İlerleme çubuğu — yalnızca rsync kopyalama fazında // İlerleme çubuğu — yalnızca rsync kopyalama fazında
@@ -346,28 +344,9 @@ impl InstallerStep for ExecutionStep {
}); });
} }
ui.add_space(8.0); ui.add_space(16.0);
ui.separator();
// Log terminali ui.add_space(16.0);
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);
}
});
});
});
}); });
}); });
@@ -375,6 +354,18 @@ impl InstallerStep for ExecutionStep {
if !self.finished && self.error_screen.is_none() { if !self.finished && self.error_screen.is_none() {
ui.ctx().request_repaint(); 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 { fn is_complete(&self, _state: &GlobalState) -> bool {
@@ -382,16 +373,16 @@ impl InstallerStep for ExecutionStep {
} }
} }
fn log_color(line: &str) -> egui::Color32 { // fn log_color(line: &str) -> egui::Color32 {
if line.starts_with('✗') { // if line.starts_with('✗') {
theme::c_error() // theme::c_error()
} else if line.starts_with('✓') { // } else if line.starts_with('✓') {
theme::c_success() // theme::c_success()
} else if line.starts_with('▶') { // } else if line.starts_with('▶') {
theme::c_accent() // theme::c_accent()
} else if line.starts_with('⚠') { // } else if line.starts_with('⚠') {
theme::c_warning() // theme::c_warning()
} else { // } else {
egui::Color32::from_rgb(185, 185, 205) // egui::Color32::from_rgb(185, 185, 205)
} // }
} // }
+17 -10
View File
@@ -296,7 +296,7 @@ fn recommended_swap_mb() -> u64 {
use sysinfo::System; use sysinfo::System;
let mut sys = System::new(); let mut sys = System::new();
sys.refresh_memory(); 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 { let swap = if ram_mb <= 2048 {
ram_mb ram_mb
} else if ram_mb <= 8192 { } 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 { if disk.size_gb < MIN_DISK_GB {
return None; 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 efi_mb = if is_uefi { EFI_MB } else { 0 };
let swap_mb = recommended_swap_mb(); let swap_mb = recommended_swap_mb();
let overhead = efi_mb + swap_mb + 512; let overhead = efi_mb + swap_mb + 512;
@@ -489,7 +489,8 @@ impl PartitionStep {
if response.clicked() && !too_small { if response.clicked() && !too_small {
state.selected_disk = Some(disk.name.clone()); 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); state.partition_plan = make_plan(disk, self.is_uefi);
} }
@@ -717,7 +718,8 @@ impl PartitionStep {
if response.clicked() { if response.clicked() {
state.selected_disk = Some(disk.name.clone()); 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); state.custom_partitions = read_existing_partitions(&disk.name);
self.manual.error = None; self.manual.error = None;
} }
@@ -738,11 +740,8 @@ impl PartitionStep {
return; return;
} }
}; };
let disk_size_gb = state.available_disks.iter() let max_mb = self.selected_disk_size_mb.unwrap_or(256 * 1024) as f64;
.find(|d| d.name == disk) eprintln!("DEBUG MAX_MB: selected_disk_size_mb={:?} max_mb={}", self.selected_disk_size_mb, max_mb);
.map(|d| d.size_gb)
.unwrap_or(256);
let max_mb = (disk_size_gb as f64) * 1024.0;
// ── Mevcut bölüm listesi tablosu ─────────────────────── // ── Mevcut bölüm listesi tablosu ───────────────────────
ui.label(egui::RichText::new(t!("mp_plan_title")).strong().color(crate::ui::theme::c_text())); 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) .map(|(_, p)| p.size_mb)
.sum(); .sum();
let avail_mb = (max_mb as u64).saturating_sub(used_mb).max(1); 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); let mut size_val = self.manual.add_size_str.trim().parse::<f64>().unwrap_or(0.0);
ui.add_space(2.0); ui.add_space(2.0);
if ui.add(egui::Slider::new(&mut size_val, 0.0..=avail_mb as f64) 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" { let size_mb: u64 = if size_str == "remaining" {
// Kalan alanı hesapla // Kalan alanı hesapla
if let Some(disk_size) = self.selected_disk_size_mb { 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); 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 } if remaining > 0 { remaining } else { disk_size }
} else { } else {
0 0
+3 -35
View File
@@ -109,12 +109,14 @@ impl Slideshow {
None None
}; };
// Kart, kendisine ayrılan dikey alanı doldursun.
let fill_h = ui.available_height().max(180.0);
egui::Frame::none() egui::Frame::none()
.fill(crate::ui::theme::c_bg_widget()) .fill(crate::ui::theme::c_bg_widget())
.rounding(egui::Rounding::same(10.0)) .rounding(egui::Rounding::same(10.0))
.inner_margin(egui::Margin::same(24.0)) .inner_margin(egui::Margin::same(24.0))
.show(ui, |ui| { .show(ui, |ui| {
ui.set_min_height(180.0); ui.set_min_height(fill_h);
ui.vertical_centered(|ui| { ui.vertical_centered(|ui| {
// Simge veya Görsel // Simge veya Görsel
if let Some(uri) = resolved_uri { if let Some(uri) = resolved_uri {
@@ -147,26 +149,6 @@ impl Slideshow {
.color(crate::ui::theme::c_text_dim()), .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);
}
});
}); });
}); });
} }
@@ -174,18 +156,4 @@ impl Slideshow {
pub fn slide_count(&self) -> usize { pub fn slide_count(&self) -> usize {
self.slides.len() 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();
}
} }