diff --git a/Makefile b/Makefile index 602780e..c29e16b 100644 --- a/Makefile +++ b/Makefile @@ -131,8 +131,6 @@ install: release # .desktop girdisi install -Dm644 assets/yali.desktop $(DESTDIR)$(DESKTOPDIR)/yali.desktop - # Logo (pixmap) - install -Dm644 assets/yali.png $(DESTDIR)$(PIXMAPDIR)/yali.png @echo "$(BOLD)$(GREEN)✓ Kurulum tamamlandı$(RESET)" diff --git a/assets/yali.png b/assets/yali.png deleted file mode 100644 index 20c2cc3..0000000 Binary files a/assets/yali.png and /dev/null differ diff --git a/slides/slides_tr.toml b/slides/slides_tr.toml index 942629e..7c0178e 100644 --- a/slides/slides_tr.toml +++ b/slides/slides_tr.toml @@ -3,32 +3,32 @@ # ╚══════════════════════════════════════════════════════════════════╝ # Slayt geçiş süresi (saniye) -interval_secs = 6 +interval_secs = 12 [[items]] icon = "slides/img/pisilinux-logo.png" title = "Pisi GNU/Linux'a Hoş Geldiniz" -description = "Pisi; hız, kararlılık ve kullanım kolaylığını bir araya getiren Türkçe destekli bir GNU/Linux dağıtımıdır." +description = "Pisi GNU/Linux; Türkiye'nin ilk yerli paket yönetim sistemi olan, PiSi tabanlı, özgür yazılım topluluğu tarafından geliştirilen, kolay kurulum, kolay kullanım ve günlük masaüstü gereksinimlerini karşılamaya odaklanan, son kullanıcıya yönelik bir Linux dağıtımıdır." [[items]] icon = "slides/img/pisi-software-center.png" -title = "PISI Paket Yöneticisi" -description = "Binlerce pakete tek komutla erişin. `pisi install ` ile ihtiyacınız olan her şeyi kolayca kurabilirsiniz." +title = "Yerli Yazılım Bileşenleri" +description = "Yerli yazılım bileşenleriyle donatılmış olan Pisi GNU/Linux; kurulum yazılımı YALI, ayar sihirbazı KAPTAN, sistemin hızlı açılmasını sağlayan MÜDÜR ve donanım ayarları için kullanılan ÇOMAR gibi özgün teknolojileriyle öne çıkan yerli bir GNU/Linux dağıtımıdır." [[items]] icon = "slides/img/community.png" -title = "Topluluk Desteği" -description = "forum.pisilinux.org adresindeki aktif topluluğumuz sorularınızı yanıtlamak için hazır. Wiki sayfalarımız da her an erişilebilir." +title = "Geniş Yazılım Deposu" +description = "Pisi GNU/Linux, geniş yazılım deposu sayesinde kullanıcıların ihtiyaç duyduğu binlerce uygulamayı sunar ve bunları düzenli olarak güncel tutar." [[items]] icon = "slides/img/pisi_speed.png" -title = "Hız ve Performans" -description = "Optimize edilmiş çekirdek ve başlangıç servisleri sayesinde PisiLinux saniyeler içinde açılır ve minimum kaynak kullanır." +title = "Modern Masaüstü Deneyimi" +description = "Özgür ve açık kaynaklı Pisi GNU/Linux, varsayılan olarak modern ve kapsamlı özellikler sunan KDE Plasma masaüstü ortamıyla gelir. Daha düşük sistem kaynakları tüketen bir masaüstü tercih eden kullanıcılar için ise hafif, hızlı ve özelleştirilebilir XFCE masaüstü ortamı da alternatif olarak sunulmaktadır." [[items]] icon = "slides/img/securety.png" -title = "Güvenlik Önce Gelir" -description = "Düzenli güvenlik güncellemeleri, AppArmor profilleri ve güvenli varsayılan ayarlarla sisteminizi koruyun." +title = "Çok Yönlü Kullanım" +description = "Pisi GNU/Linux; evde, ofiste ve günlük kullanımda rahatlıkla kullanılabilen çok yönlü bir işletim sistemidir. Müzik, film, 3D modelleme, grafik tasarım ve profesyonel uygulamalar için güçlü bir altyapı sunarken, oyun tutkunları için de kapsamlı bir oyun platformu sağlar." [[items]] icon = "slides/img/customization.png" diff --git a/src/funct.rs b/src/funct.rs index f336711..7e3e0ec 100644 --- a/src/funct.rs +++ b/src/funct.rs @@ -25,7 +25,7 @@ pub fn form_input_text( ui.spacing_mut().button_padding = eframe::egui::vec2(10.0, 10.0); egui::Frame::none() .fill(egui::Color32::from_rgb(255, 255, 255)) - .stroke(egui::Stroke::new(1.0, egui::Color32::from_gray(200))) + .stroke(egui::Stroke::new(1.0_f32, egui::Color32::from_gray(200))) .rounding(4.0) .inner_margin(eframe::egui::Margin::symmetric(2.0, 2.0)) .show(ui, |ui| { @@ -61,7 +61,7 @@ pub fn form_input_password( eframe::egui::Frame::none() .fill(eframe::egui::Color32::WHITE) - .stroke(eframe::egui::Stroke::new(1.0, eframe::egui::Color32::from_rgb(200, 200, 200))) + .stroke(eframe::egui::Stroke::new(1.0_f32, eframe::egui::Color32::from_rgb(200, 200, 200))) .rounding(6.0) .inner_margin(eframe::egui::Margin::symmetric(2.0, 2.0)) .show(ui, |ui| { diff --git a/src/jobs/mod.rs b/src/jobs/mod.rs index f3b0d7d..7cee12f 100644 --- a/src/jobs/mod.rs +++ b/src/jobs/mod.rs @@ -13,6 +13,7 @@ use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::mpsc; +use std::time::Instant; use tokio::io::{AsyncBufReadExt, BufReader}; use tokio::process::Command; use rust_i18n::t; @@ -39,21 +40,43 @@ pub enum InstallMessage { } /// `mpsc::Sender` ile `egui::Context` birlikte taşır. -/// Her mesaj gönderiminde `request_repaint()` çağrısı UI'yi uyandırır. -#[derive(Clone)] +/// Mesaj gönderiminde `request_repaint()` çağrısı UI'yi uyandırır, +/// ancak en fazla saniyede ~30 kez (33ms aralıkla) olacak şekilde +/// throttle edilir. Bu, özellikle rsync gibi yoğun I/O işlemleri +/// sırasında Intel tümleşik GPU'lu (UMA) sistemlerde GPU belleği +/// rekabetini önler ve karakter bozulmasını engeller. pub struct UiSender { tx: mpsc::Sender, ctx: eframe::egui::Context, + last_repaint: std::sync::Arc>, +} + +impl Clone for UiSender { + fn clone(&self) -> Self { + Self { + tx: self.tx.clone(), + ctx: self.ctx.clone(), + last_repaint: self.last_repaint.clone(), + } + } } impl UiSender { pub fn new(tx: mpsc::Sender, ctx: eframe::egui::Context) -> Self { - Self { tx, ctx } + Self { + tx, + ctx, + last_repaint: std::sync::Arc::new(std::sync::Mutex::new(Instant::now())), + } } pub fn send(&self, msg: InstallMessage) { let _ = self.tx.send(msg); - self.ctx.request_repaint(); + let mut last = self.last_repaint.lock().unwrap(); + if last.elapsed() >= std::time::Duration::from_millis(33) { + self.ctx.request_repaint(); + *last = Instant::now(); + } } pub fn log(&self, s: impl Into) { @@ -301,6 +324,8 @@ impl Job for CopyFilesJob { let reader = BufReader::new(stdout); let mut lines = reader.lines(); let mut file_count: u64 = 0; + // Son UI güncellemesi — çok sık güncelleme GPU (özellikle Intel UMA) baskısını azaltır + let mut last_update = Instant::now(); while let Some(line) = lines.next_line().await .map_err(|e| format!("rsync çıktısı okunamadı: {}", e))? @@ -311,7 +336,15 @@ impl Job for CopyFilesJob { } file_count += 1; - ui.current_file(trimmed); + + let now = Instant::now(); + if now.duration_since(last_update) >= std::time::Duration::from_millis(50) + || file_count == 1 + || trimmed.contains("Packages") || trimmed.contains("package") + { + ui.current_file(trimmed); + last_update = now; + } if total_files > 0 { let p = (file_count as f32) / (total_files as f32); diff --git a/src/main.rs b/src/main.rs index 3497e6b..1f2333d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -438,7 +438,7 @@ impl eframe::App for YaliApp { egui::TopBottomPanel::bottom("footer") .frame(egui::Frame::none() .fill(ui::theme::c_footer_bg()) - .stroke(egui::Stroke::new(1.0, ui::theme::c_footer_bg()))) + .stroke(egui::Stroke::new(1.0_f32, ui::theme::c_footer_bg()))) .show(ctx, |ui| { ui.add_space(10.0); ui.horizontal(|ui| { diff --git a/src/steps/partition.rs b/src/steps/partition.rs index e595ecd..45989c7 100644 --- a/src/steps/partition.rs +++ b/src/steps/partition.rs @@ -438,7 +438,7 @@ impl PartitionStep { egui::Color32::from_rgba_unmultiplied(237, 237, 224, 1) }) .stroke(egui::Stroke::new( - if selected { 2.0 } else { 1.0 }, + if selected { 2.0_f32 } else { 1.0_f32 }, if selected { crate::ui::theme::c_accent() } else { crate::ui::theme::c_border() }, )) .rounding(egui::Rounding::same(8.0)) @@ -538,7 +538,7 @@ impl PartitionStep { }); egui::Frame::none() - .stroke(egui::Stroke::new(1.0, crate::ui::theme::c_border())) + .stroke(egui::Stroke::new(1.0_f32, crate::ui::theme::c_border())) .rounding(egui::Rounding::same(6.0)) .show(ui, |ui| { let tam = ui.available_width(); @@ -673,7 +673,7 @@ impl PartitionStep { egui::Color32::from_rgba_unmultiplied(237, 237, 224, 1) }) .stroke(egui::Stroke::new( - if selected { 2.0 } else { 1.0 }, + if selected { 2.0_f32 } else { 1.0_f32 }, if selected { crate::ui::theme::c_accent() } else { crate::ui::theme::c_border() }, )) .rounding(egui::Rounding::same(8.0)) @@ -747,7 +747,7 @@ impl PartitionStep { let tam_genislik = ui.available_width(); let header_color = egui::Color32::from_rgb(33, 37, 41); let header_text = egui::Color32::WHITE; - let _border_stroke = egui::Stroke::new(1.0, crate::ui::theme::c_border()); + let _border_stroke = egui::Stroke::new(1.0_f32, crate::ui::theme::c_border()); // ── Başlık satırı ───────────────────────────────── let headers: [String; 4] = [ @@ -767,7 +767,7 @@ impl PartitionStep { let child_ui = &mut ui.child_ui(rect, egui::Layout::top_down(egui::Align::Center)); egui::Frame::none() .fill(header_color) - .stroke(egui::Stroke::new(1.0, header_color)) + .stroke(egui::Stroke::new(1.0_f32, header_color)) .inner_margin(egui::Margin::symmetric(8.0, 4.0)) .show(child_ui, |ui| { ui.label(egui::RichText::new(h).strong().color(header_text).size(13.0)); @@ -900,7 +900,6 @@ impl PartitionStep { let next_num = state.custom_partitions.len() + 1; self.manual.add_size_str.clear(); self.manual.add_mountpoint.clear(); - self.manual.add_fstype = 0; self.manual.add_encrypt = false; self.manual.add_luks_password.clear(); self.manual.add_mountpoint = match next_num { @@ -911,6 +910,11 @@ impl PartitionStep { 3 => "/".to_string(), _ => String::new(), }; + self.manual.add_fstype = match self.manual.add_mountpoint.as_str() { + "swap" => FS_OPTIONS.iter().position(|(_, t)| *t == FsType::Swap).unwrap_or(0), + "/boot/efi" => FS_OPTIONS.iter().position(|(_, t)| *t == FsType::Fat32).unwrap_or(0), + _ => 0, + }; } // Düzenle @@ -1044,6 +1048,16 @@ impl PartitionStep { ); }); + // mountpoint "swap" seçildiğinde FS tipini otomatik swap yap + let mp = self.manual.add_mountpoint.trim().to_lowercase(); + let current_fs = FS_OPTIONS.get(self.manual.add_fstype).map(|x| &x.1); + let idx = |fs: FsType| FS_OPTIONS.iter().position(|(_, t)| *t == fs).unwrap_or(0); + if mp == "swap" && current_fs != Some(&FsType::Swap) { + self.manual.add_fstype = idx(FsType::Swap); + } else if mp == "/boot/efi" && current_fs != Some(&FsType::Fat32) { + self.manual.add_fstype = idx(FsType::Fat32); + } + ui.add_space(6.0); ui.separator(); diff --git a/src/ui/buttons.rs b/src/ui/buttons.rs index 88fc354..f68d5e4 100644 --- a/src/ui/buttons.rs +++ b/src/ui/buttons.rs @@ -56,7 +56,7 @@ fn gradient_button(ui: &mut egui::Ui, text: &str, top_color: Color32, bottom_col ui.painter().rect(strip_rect, Rounding::ZERO, c, Stroke::NONE); } - ui.painter().rect(rect, rounding, Color32::TRANSPARENT, Stroke::new(1.0, actual_border)); + ui.painter().rect(rect, rounding, Color32::TRANSPARENT, Stroke::new(1.0_f32, actual_border)); ui.painter().galley( egui::pos2(rect.center().x - galley.size().x / 2.0, rect.center().y - galley.size().y / 2.0), diff --git a/src/ui/combobox_stil.rs b/src/ui/combobox_stil.rs index 96f8480..8f0f18e 100644 --- a/src/ui/combobox_stil.rs +++ b/src/ui/combobox_stil.rs @@ -7,13 +7,13 @@ pub fn apply_visuals(v: &mut egui::Visuals) { v.widgets.hovered.weak_bg_fill = Color32::from_rgb(200, 200, 200); v.widgets.active.weak_bg_fill = Color32::from_rgb(180, 180, 180); - v.widgets.inactive.fg_stroke = Stroke::new(1.0, Color32::from_rgb(50, 50, 50)); - v.widgets.hovered.fg_stroke = Stroke::new(1.5, Color32::WHITE); - v.widgets.active.fg_stroke = Stroke::new(2.0, Color32::WHITE); + v.widgets.inactive.fg_stroke = Stroke::new(1.0_f32, Color32::from_rgb(50, 50, 50)); + v.widgets.hovered.fg_stroke = Stroke::new(1.5_f32, Color32::WHITE); + v.widgets.active.fg_stroke = Stroke::new(2.0_f32, Color32::WHITE); - v.widgets.inactive.bg_stroke = Stroke::new(1.0, Color32::from_rgb(155, 155, 155)); - v.widgets.hovered.bg_stroke = Stroke::new(1.0, Color32::from_rgb(155, 155, 155)); - v.widgets.active.bg_stroke = Stroke::new(1.0, Color32::from_rgb(155, 155, 155)); + v.widgets.inactive.bg_stroke = Stroke::new(1.0_f32, Color32::from_rgb(155, 155, 155)); + v.widgets.hovered.bg_stroke = Stroke::new(1.0_f32, Color32::from_rgb(155, 155, 155)); + v.widgets.active.bg_stroke = Stroke::new(1.0_f32, Color32::from_rgb(155, 155, 155)); } fn is_dark_ui(ui: &egui::Ui) -> bool { diff --git a/src/ui/error_screen.rs b/src/ui/error_screen.rs index 7d78a1c..0a528ec 100644 --- a/src/ui/error_screen.rs +++ b/src/ui/error_screen.rs @@ -68,7 +68,7 @@ impl ErrorScreen { // ── Hata mesajı ─────────────────────────────── egui::Frame::none() .fill(egui::Color32::from_rgba_unmultiplied(0xF4, 0x43, 0x36, 18)) - .stroke(egui::Stroke::new(1.0, theme::c_error())) + .stroke(egui::Stroke::new(1.0_f32, theme::c_error())) .rounding(egui::Rounding::same(8.0)) .inner_margin(egui::Margin::same(12.0)) .show(ui, |ui| { diff --git a/src/ui/slideshow.rs b/src/ui/slideshow.rs index 147ef47..ce63cbb 100644 --- a/src/ui/slideshow.rs +++ b/src/ui/slideshow.rs @@ -363,8 +363,50 @@ impl Slideshow { .rounding(egui::Rounding::same(8.0)), ); } else { + let emoji = match slide.icon { + "pisilogo" | "pisi" => "\u{1f427}", + "community" => "\u{1f465}", + "pisi_speed" => "\u{26a1}", + "securety" => "\u{1f512}", + "customization" => "\u{1f3a8}", + "budgie" => "\u{1f98e}", + "budgie_applets" => "\u{1f9e9}", + "budgie_raven" => "\u{1f426}", + "budgie_gtk_theme" => "\u{1f3ad}", + "cinnamon" => "\u{1f36e}", + "cinnamon_panel" => "\u{1f4cb}", + "cinnamon_settings" => "\u{2699}\u{fe0f}", + "cinnamon_desklets" => "\u{1f4cc}", + "gnome" => "\u{1f9d1}\u{200d}\u{1f4bb}", + "gnome_search" => "\u{1f50d}", + "gnome_extensions" => "\u{1f9e9}", + "kde" => "\u{1f48e}", + "file_manager" => "\u{1f4c1}", + "kde_connect" => "\u{1f4f1}", + "discover" => "\u{1f6cd}\u{fe0f}", + "lxde" => "\u{1f5a5}\u{fe0f}", + "lxde_openbox" => "\u{1f4e6}", + "lxde_lxpanel" => "\u{1f4ca}", + "lxde_pcmanfm" => "\u{1f4c2}", + "lxqt" => "\u{1f5a5}\u{fe0f}", + "lxqt_panel" => "\u{1f4cb}", + "lxqt_pcmanfm_qt" => "\u{1f4c2}", + "lumina" => "\u{1f31f}", + "lumina_applications" => "\u{1f4f1}", + "lumina_theme" => "\u{1f3a8}", + "lumina_panel" => "\u{1f4cb}", + "mate" => "\u{1f9c9}", + "mate_caja" => "\u{1f4c2}", + "mate_settings" => "\u{2699}\u{fe0f}", + "mate_applications" => "\u{1f4f1}", + "xfce" => "\u{1f42d}", + "xfce_panel" => "\u{1f4cb}", + "xfce_thunar" => "\u{1f4c2}", + "xfce_settings" => "\u{2699}\u{fe0f}", + _ => "\u{1f5bc}\u{fe0f}", + }; ui.label( - egui::RichText::new(slide.icon) + egui::RichText::new(emoji) .size(48.0), ); } diff --git a/src/ui/theme.rs b/src/ui/theme.rs index 5f0e873..9115376 100644 --- a/src/ui/theme.rs +++ b/src/ui/theme.rs @@ -187,7 +187,7 @@ fn build_visuals(is_dark: bool) -> Visuals { v.override_text_color = None; // ─── KENARLIKLAR (Calamares Uyumu için İnce İnce Yumuşatıldı) ─────────────────── - v.widgets.noninteractive.bg_stroke = Stroke::new(1.0, c_border()); + v.widgets.noninteractive.bg_stroke = Stroke::new(1.0_f32, c_border()); // ─── WIDGET DOLGULARI (Burası ComboBox ve Butonların Kaderini Belirliyor) ─────── v.widgets.noninteractive.bg_fill = c_bg_widget(); @@ -205,7 +205,7 @@ fn build_visuals(is_dark: bool) -> Visuals { crate::ui::combobox_stil::apply_visuals(&mut v); // ─── METİN RENKLERİ ──────────────────────────────────────────────────────────── - v.widgets.noninteractive.fg_stroke = Stroke::new(1.0, c_text()); + v.widgets.noninteractive.fg_stroke = Stroke::new(1.0_f32, c_text()); // ─── YUVARLAK KÖŞELER (Zaten 6.0'dı, Tam İstediğin Calamares Kıvamında) ───────── v.widgets.noninteractive.rounding = Rounding::same(6.0); @@ -215,13 +215,13 @@ fn build_visuals(is_dark: bool) -> Visuals { // Seçim rengi v.selection.bg_fill = c_accent_dim(); - v.selection.stroke = Stroke::new(1.0, c_accent()); + v.selection.stroke = Stroke::new(1.0_f32, c_accent()); // Hyperlink v.hyperlink_color = c_accent(); // Pencere kenarlığı - v.window_stroke = Stroke::new(1.0, c_border()); + v.window_stroke = Stroke::new(1.0_f32, c_border()); v.window_rounding = Rounding::same(8.0); v.interact_cursor = Some(egui::CursorIcon::PointingHand); @@ -268,7 +268,7 @@ pub fn section_heading(ui: &mut egui::Ui, text: &str) { let (rect, _) = ui.allocate_exact_size(Vec2::new(ui.available_width(), 1.0), egui::Sense::hover()); ui.painter().line_segment( [rect.left_center(), rect.right_center()], - Stroke::new(1.0, c_accent_dim()), + Stroke::new(1.0_f32, c_accent_dim()), ); ui.add_space(8.0); } @@ -277,7 +277,7 @@ pub fn section_heading(ui: &mut egui::Ui, text: &str) { pub fn error_box(ui: &mut egui::Ui, msg: &str) { egui::Frame::none() .fill(Color32::from_rgba_unmultiplied(0xF4, 0x43, 0x36, 20)) - .stroke(Stroke::new(1.0, c_error())) + .stroke(Stroke::new(1.0_f32, c_error())) .rounding(Rounding::same(6.0)) .inner_margin(egui::Margin::same(10.0)) .show(ui, |ui| { @@ -294,7 +294,7 @@ pub fn error_box(ui: &mut egui::Ui, msg: &str) { pub fn warning_box(ui: &mut egui::Ui, msg: &str) { egui::Frame::none() .fill(Color32::from_rgba_unmultiplied(0xFF, 0x98, 0x00, 20)) - .stroke(Stroke::new(1.0, c_warning())) + .stroke(Stroke::new(1.0_f32, c_warning())) .rounding(Rounding::same(6.0)) .inner_margin(egui::Margin::same(10.0)) .show(ui, |ui| { @@ -311,7 +311,7 @@ pub fn warning_box(ui: &mut egui::Ui, msg: &str) { pub fn success_box(ui: &mut egui::Ui, msg: &str) { egui::Frame::none() .fill(Color32::from_rgba_unmultiplied(0x4C, 0xAF, 0x50, 20)) - .stroke(Stroke::new(1.0, c_success())) + .stroke(Stroke::new(1.0_f32, c_success())) .rounding(Rounding::same(6.0)) .inner_margin(egui::Margin::same(10.0)) .show(ui, |ui| {