From 71e2ab382917167344945e30456ae6b333cf2980 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erkan=20I=C5=9EIK?= Date: Thu, 25 Jun 2026 01:33:51 +0300 Subject: [PATCH] chore: add English/Turkish changelog cross-links --- CHANGELOG.md | 30 ++++++- CHANGELOG_en.md | 176 ++++++++++++++++++++++++++++++++++++ README.md | 15 ++-- README1.md | 114 ++++++++++++++++++++++++ README_en.md | 112 +++++++++++++++++++++++ locales/en.toml | 4 + locales/tr.toml | 4 + src/installer.rs | 2 +- src/jobs/mod.rs | 32 ++++++- src/main.rs | 3 +- src/steps/bootloader.rs | 111 +++++++++++------------ src/steps/mod.rs | 3 +- src/steps/users.rs | 191 +++++++++++++++++++++++++++++++--------- src/ui/theme.rs | 17 ++-- 14 files changed, 694 insertions(+), 120 deletions(-) create mode 100644 CHANGELOG_en.md create mode 100644 README1.md create mode 100644 README_en.md diff --git a/CHANGELOG.md b/CHANGELOG.md index a849229..a5f8ea9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,32 @@ -# Changelog +# Changelog — [English](CHANGELOG_en.md) + +## [4.0.4] — 2026-06-25 + +### Added +- Kullanıcı adı doğrulama fonksiyonu `validate_username` (detaylı hata mesajları döndürür) +- Yasaklı sistem kullanıcı adları listesi (root, daemon, bin, sys, vb.) +- Türkçe karakter dönüşümleri büyük harfleri de kapsayacak şekilde genişletildi (Ş, Ğ, İ, Ö, Ü, Ç) +- Locale dosyalarına yeni kullanıcı adı doğrulama anahtarları (username_too_long, username_forbidden, username_invalid_start, username_invalid_chars) +- UsersStep struct'ına `autologin` alanı eklendi + +### Changed +- Kullanıcı adı, şifre doğrulama ve hostname input'ları için check/fail iconları input'un yanına alındı +- Hata mesajları inputların altında gösteriliyor (username doğrulama, şifre eşleşme) +- Önyükleyici (bootloader) sayfası form düzeni users sayfasındaki gibi güncellendi (Frame, form_label, form_input_text/password) +- Display manager adımı adım listesinden kaldırıldı (ISO'lar tek masaüstü ile geliyor) +- Autologin özelliği display manager adımından users adımına taşındı +- Display manager yapılandırması otomatik hale getirildi (desktop_environment otomatik tespit ediliyor) +- SDDM/GDM yapılandırmasında masaüstü ortamı seçimi kullanılıyor (xfce.desktop, gnome.desktop vb.) +- Autologin varsayılan değeri false olarak değiştirildi + +### Fixed +- Dark modda sidebar metin renginin kaybolması sorunu (SIDEBAR_TEXT beyaz olarak ayarlandı) +- derive_username fonksiyonunda yanlış karakter (ā → ğ) düzeltildi +- unused_mut warning (name değişkeni) +- unused variable warning (err değişkeni) +- unused import warning (DisplayManagerStep) + +--- ## [4.0.3] — 2026-06-23 diff --git a/CHANGELOG_en.md b/CHANGELOG_en.md new file mode 100644 index 0000000..0fd10e0 --- /dev/null +++ b/CHANGELOG_en.md @@ -0,0 +1,176 @@ +# Changelog — [Türkçe](CHANGELOG.md) + +## [4.0.4] — 2026-06-25 + +### Added +- Username validation function `validate_username` (returns detailed error messages) +- Forbidden system usernames list (root, daemon, bin, sys, etc.) +- Turkish character conversions extended to include uppercase letters (Ş, Ğ, İ, Ö, Ü, Ç) +- New username validation keys in locale files (username_too_long, username_forbidden, username_invalid_start, username_invalid_chars) +- `autologin` field added to UsersStep struct + +### Changed +- Check/fail icons for username, password validation, and hostname inputs moved next to input fields +- Error messages shown below inputs (username validation, password mismatch) +- Bootloader page form layout updated to match users page (Frame, form_label, form_input_text/password) +- Display manager step removed from step list (ISOs ship with single desktop environment) +- Autologin feature moved from display manager step to users step +- Display manager configuration made automatic (desktop_environment auto-detected) +- Desktop environment selection used in SDDM/GDM configuration (xfce.desktop, gnome.desktop, etc.) +- Autologin default value changed to false + +### Fixed +- Sidebar text color disappearing in dark mode (SIDEBAR_TEXT set to white) +- Incorrect character in derive_username function (ā → ğ) +- unused_mut warning (name variable) +- unused variable warning (err variable) +- unused import warning (DisplayManagerStep) + +--- + +## [4.0.3] — 2026-06-23 + +### Added +- Searchable keyboard layout/variant selector: egui `TextEdit` + `Area` popup custom implementation +- `color_from_hex(hex: u32)` helper (`combobox_stil.rs`) +- `layout_buf`, `variant_buf` fields (`KeyboardStep`) + +### Changed +- `egui-dropdown` dependency removed (no longer used) +- Layout/Variant selectors side-by-side → stacked, label width equalized to longest label +- Popup item height 28px → 32px, gradient background (`draw_gradient_bg`) in `combobox.rs` style +- `DROPDOWN_TEXT_COLOR` off-white → pure white (`color_from_hex(0xFFFFFF)`) +- All color constants converted to hex format (`color_from_hex`) + +### Fixed +- Popup not showing all items on first open due to old selection filter — buffer cleared on focus +- `t!()` return type `Cow` → `String` mismatch (`keyboard.rs`) + +### Changed +- Slider maximum value now equals available disk space (excluding other partitions) +- Selected partition capacity included in slider range in edit mode +- `form_input_text` size field directly connected to `add_size_str`, formatted MB display added +- Size label now in `"123.456 MB"` format instead of `"123 MB"` (for parseable values) + +### Fixed +- Value written to size input field not written back to `add_size_str` — text edit remained read-only + +--- + +## [4.0.1] — 2026-06-19 + +### Added +- `c_root_bg()` theme function +- `show_root_password`, `show_root_password_confirm` fields (`UsersStep`) +- `form_input_text` / `form_input_password` wrapped with `Frame` and `.frame(false)` + +### Changed +- `form_input_text`: Wrapped in Frame, added stroke/fill/rounding, height 32→10 +- `form_input_password`: SVG eye icons (instead of emoji), Frame wrapped, `override_text_color` +- Disk grid selection colors `theme::c_*()` → constant `(237,237,224,1)` +- Disk list header and column headers: `Align::Center` → `Align::LEFT`, `vertical_centered` removed +- Root password fields raw `TextEdit` → `form_input_password` (with eye icon + frame) +- User form Frame color `theme::c_bg_widget()` → `(240,243,198)` +- Manual disk list brand/model label ordering changed + +### Fixed +- `users.rs:154` — `Color32` import error (missing `egui::` prefix) + +--- + +## [4.0.0] — 2026-06-18 + +### Added +- `CHANGELOG.md` +- `src/ui/combobox.rs` — ComboBox helpers (`show_combo_box`, `selectable_value`, `selectable_value_custom`, `draw_gradient_bg`) +- `src/ui/combobox_stil.rs` — ComboBox visual constants and `apply_visuals()` +- `src/steps/location.rs` — Region/timezone selection step +- `src/steps/network.rs` — Network configuration step +- `src/steps/rescue.rs` — Rescue mode +- `xkbcommon` dependency +- Keyboard visual: XKB keymap → egui drawing (`compile_layout`, `draw_layout`, `keysym_to_label`) +- ISO‑105 key position mapping (function keys, numpad, navigation included) +- Single character display per key (uppercase preferred) + +### Changed +- Keyboard visual: KLE JSON download/parse → direct keymap compilation with xkbcommon +- `Cargo.toml`: `ureq`, `serde_json` removed; `xkbcommon` added +- ComboBox styles moved from `theme.rs` → `combobox_stil.rs` +- Comment lines added to `secondary_button` gradient colors +- `draw_gradient_bg` moved to `combobox_stil.rs` +- All ComboBox usages updated with `theme::show_combo_box` / `theme::selectable_value` +- Keyboard step (`keyboard.rs`): `ScrollArea`+`selectable_label` → ComboBox +- `TextEdit::multiline` background made with per-widget `Frame::group` +- `locale/` files updated +- Font sizes increased (label 9→12, secondary 7→9) + +### Removed +- `ureq`, `serde_json` dependencies +- `assets/keyboards/KLE_*.json` cache files +- `assets/keyboards/KB_*.svg` files +- Old keyboard SVG loading code +- KLE JSON download/cache logic +- Old button examples in demo page + +### Fixed +- `set_style`/`set_visuals` order: `set_style` called first +- Region/timezone labels vertically aligned +- Keyboard step `on_enter` not called on first render — layout also initialized in `show()` +- `xkbcommon::Keycode` iteration (conversion with `raw()`) +- `None::<&str>` → `None::` type mismatch + +--- + +## [4.0.0] — 2026-06-06 + +### Added +- Rescue mode (rescue step) +- Network configuration step (NetworkManager/Wicd) +- Netinstall step +- LVM and LUKS encryption support +- Demo mode (`--demo`) +- Automatic installation (`--auto-install answer.toml`) +- Multi-language support with `rust-i18n` (Turkish, English) +- Gradient buttons (`gradient_button`, `secondary_button`) +- Language selector (flag + label) +- SVG loading support (`egui_extras` + `image`) +- Slideshow (configurable with branding.toml) +- Step list in sidebar (processed steps green ✔️) +- Real-time installation file tracking +- Advanced partitioning UI (usage bar, LUKS indicator, mount-point selector) + +### Changed +- `pspec.xml`/`actions.py` → Cargo-based build +- `comar`/`mudur` calls → `zbus` D-Bus and direct command execution +- Shell-based password management → secure stdin piping (LUKS/GRUB) +- Automatic username derivation (real name → system username) +- Hostname validation/sanitization +- Cleanup operations: user deletion, pool management, boot directory cleanup +- Rsync command with dynamic exclusion +- Version 4.0.1 → 4.0.0 (Cargo.toml compatibility) + +### Fixed +- GRUB password writing security +- Dracut/Mkinitcpio LVM module addition +- EFI partition detection and mounting +- Password strength indicator colors +- Automatic partitioning (LVM/LUKS ordering) + +--- + +## [0.1.0] — 2026-05-20 + +### Added +- First stable release +- Project skeleton (egui + wgpu) +- Step-based installation wizard +- Automatic disk partitioning (GPT/MBR) +- User creation (with password strength check) +- Bootloader configuration (GRUB) +- Display manager selection +- Summary screen +- Basic color theme (light/dark) +- Customizable branding (branding.toml) +- Error screen for rescue purposes +- Job queue (JobQueue / async task management) +- YALI serialization (installer state save/load) diff --git a/README.md b/README.md index ee26dbd..4dcc883 100644 --- a/README.md +++ b/README.md @@ -2,9 +2,12 @@ Rust ve egui ile yeniden yazılmış **Pisi GNU/Linux** kurulum aracı. YALI, canlı ortamdan sistemi kurar, paketleri kurar ve temel yapılandırmayı gerçekleştirir. Orijinal Python/Qt sürümünün modern, hızlı ve bakımı kolay bir yeniden yazımıdır. +- [Changelog](CHANGELOG.md) +- [English README](README_en.md) + ## Özellikler -- **11 adımlı kurulum sihirbazı**: Hoş Geldiniz → Konum → Klavye → Ağ → Disk Bölümleme → Kullanıcılar → Bootloader → Görüntü Yöneticisi → Özet → Kurulum → Bitir +- **10 adımlı kurulum sihirbazı**: Hoş Geldiniz → Konum → Klavye → Ağ → Disk Bölümleme → Kullanıcılar → Bootloader → Özet → Kurulum → Bitir - **İki mod**: Grafik arayüz (varsayılan) ve cevap dosyasıyla otomatik kurulum (`--auto-install answer.toml`) - **Demo modu**: Sistem kontrollerini atlar, kurulumu simüle eder (`--demo`) - **Disk bölümleme**: Otomatik (GPT/MBR) veya manuel, LVM ve LUKS şifreleme desteği @@ -56,7 +59,6 @@ sudo cargo run --release -- --auto-install answer.toml │ │ ├── partition.rs # Disk bölümleme (otomatik + manuel + LVM) │ │ ├── users.rs # Kullanıcı hesabı oluşturma │ │ ├── bootloader.rs # GRUB yapılandırması -│ │ ├── display_manager.rs # Görüntü yöneticisi ve masaüstü seçimi │ │ ├── summary.rs # Kurulum özeti │ │ ├── execution.rs # Kurulum yürütme (ilerleme çubuğu, log) │ │ ├── finish.rs # Tamamlanma ekranı @@ -86,12 +88,11 @@ sudo cargo run --release -- --auto-install answer.toml 3. **Klavye** — Düzen/varyant seçimi, arama, canlı önizleme (setxkbmap) 4. **Ağ** — WiFi tarama, bağlantı, proxy 5. **Disk Bölümleme** — Otomatik (rehberli) veya manuel, LVM, LUKS -6. **Kullanıcılar** — Hesap oluşturma, parola gücü göstergesi, root parolası +6. **Kullanıcılar** — Hesap oluşturma, parola gücü göstergesi, root parolası, otomatik oturum açma 7. **Bootloader** — GRUB aygıtı, zaman aşımı, parola, çekirdek parametreleri -8. **Görüntü Yöneticisi** — SDDM/LightDM/GDM, masaüstü ortamı, otomatik oturum -9. **Özet** — Tüm seçimlerin gözden geçirilmesi -10. **Kurulum** — Slayt + ilerleme çubuğu + canlı log -11. **Bitir** — Başarılı kurulum, yeniden başlat veya canlı masaüstüne dön +8. **Özet** — Tüm seçimlerin gözden geçirilmesi +9. **Kurulum** — Slayt + ilerleme çubuğu + canlı log +10. **Bitir** — Başarılı kurulum, yeniden başlat veya canlı masaüstüne dön ## Bağımlılıklar diff --git a/README1.md b/README1.md new file mode 100644 index 0000000..ee26dbd --- /dev/null +++ b/README1.md @@ -0,0 +1,114 @@ +# YALI (Yet Another Linux Installer) — Rust / egui + +Rust ve egui ile yeniden yazılmış **Pisi GNU/Linux** kurulum aracı. YALI, canlı ortamdan sistemi kurar, paketleri kurar ve temel yapılandırmayı gerçekleştirir. Orijinal Python/Qt sürümünün modern, hızlı ve bakımı kolay bir yeniden yazımıdır. + +## Özellikler + +- **11 adımlı kurulum sihirbazı**: Hoş Geldiniz → Konum → Klavye → Ağ → Disk Bölümleme → Kullanıcılar → Bootloader → Görüntü Yöneticisi → Özet → Kurulum → Bitir +- **İki mod**: Grafik arayüz (varsayılan) ve cevap dosyasıyla otomatik kurulum (`--auto-install answer.toml`) +- **Demo modu**: Sistem kontrollerini atlar, kurulumu simüle eder (`--demo`) +- **Disk bölümleme**: Otomatik (GPT/MBR) veya manuel, LVM ve LUKS şifreleme desteği +- **Ağ yapılandırması**: WiFi tarama (nmcli), proxy ayarları +- **Önyükleyici**: GRUB aygıt/parola/zaman aşımı ayarları, çekirdek parametreleri +- **Kurtarma modu**: Chroot, GRUB yeniden kurulumu, Pisi geçmişe dönme +- **OEM modu**: Üretici ön kurulumu için ön tanımlı ayarlar +- **Uluslararasılaştırma**: Türkçe ve İngilizce (rust-i18n ile TOML locale dosyaları) +- **Markalama sistemi**: Çalışma zamanında yüklenebilir `branding.toml` ile logo, slayt, renk ayarları +- **Tema**: Koyu/açık tema, atomik renk yönetimi, özel gradient butonlar +- **Asenkron iş kuyruğu**: Tüm kurulum adımları ayrı `tokio` runtime'ında çalışır, `mpsc` kanalı ile UI güncellenir +- **Sistem kontrolleri**: RAM, disk alanı, internet, UEFI, CPU, NVMe gibi 8 ön kontrol +- **Slayt gösterisi**: 9 masaüstü ortamı için özel markalı slaytlar +- **Demo oturum temizliği**: Canlı ortam artifact'lerini kaldırır, üretim deposu ekler + +## Kullanım + +```bash +# Normal kurulum (root yetkisi gerekir) +sudo cargo run --release + +# Demo modu (root gerekmez) +cargo run --release -- --demo + +# Otomatik kurulum (cevap dosyası ile) +sudo cargo run --release -- --auto-install answer.toml +``` + +## Proje Yapısı + +``` +├── src/ +│ ├── main.rs # Giriş noktası, eframe App, GUI düzeni +│ ├── installer.rs # InstallerStep trait'i, GlobalState, WelcomeStep +│ ├── funct.rs # Paylaşılan UI yardımcıları (form alanları, dil seçici) +│ ├── branding.rs # Branding.toml yükleyici (logo, slayt, tema, OEM) +│ ├── ui/ +│ │ ├── theme.rs # Renkler, fontlar, Visuals, section_heading, error/warning/success kutuları +│ │ ├── buttons.rs # Gradient butonlar (primary, secondary, danger, vb.) +│ │ ├── combobox.rs # ComboBox yardımcıları (show_combo_box, selectable_value) +│ │ ├── combobox_stil.rs # ComboBox görsel sabitleri (weak_bg, border, text renkleri) +│ │ ├── slideshow.rs # Otomatik ilerleyen slayt gösterisi +│ │ └── error_screen.rs # Hata ekranı (log görüntüleyici, kopyala, yeniden dene) +│ ├── steps/ +│ │ ├── location.rs # Konum/saat dilimi + tarih/saat +│ │ ├── license.rs # Lisans sözleşmesi +│ │ ├── keyboard.rs # Klavye düzeni/varyant seçimi +│ │ ├── network.rs # Ağ yapılandırması (WiFi, proxy) +│ │ ├── partition.rs # Disk bölümleme (otomatik + manuel + LVM) +│ │ ├── users.rs # Kullanıcı hesabı oluşturma +│ │ ├── bootloader.rs # GRUB yapılandırması +│ │ ├── display_manager.rs # Görüntü yöneticisi ve masaüstü seçimi +│ │ ├── summary.rs # Kurulum özeti +│ │ ├── execution.rs # Kurulum yürütme (ilerleme çubuğu, log) +│ │ ├── finish.rs # Tamamlanma ekranı +│ │ ├── netinstall.rs # Ek paket grubu seçimi +│ │ └── rescue.rs # Kurtarma modu (chroot, GRUB, Pisi takeback) +│ ├── jobs/mod.rs # Asenkron iş kuyruğu ve tüm kurulum işleri +│ └── autoinstall/ +│ ├── mod.rs # Cevap dosyası yükleme ve state uygulama +│ └── checker.rs # Sistem ön kontrolleri +├── locales/ +│ ├── tr.toml # Türkçe çeviriler +│ └── en.toml # İngilizce çeviriler +├── assets/ +│ ├── icons/ # UI ikonları (YALI_icon_LIGHT.svg, language-icon.svg, vb.) +│ ├── flags/ # Ülke bayrakları (~250 SVG) +│ └── *.png # Slayt ve logo görselleri +├── branding.toml # Varsayılan markalama yapılandırması +├── branding_en.toml # İngilizce markalama +├── branding_tr.toml # Türkçe markalama +└── answer-example.toml # Örnek cevap dosyası +``` + +## Kurulum İş Akışı + +1. **Hoş Geldiniz** — Dil seçimi, sistem kontrolleri, kurtarma modu +2. **Konum / Zaman** — Saat dilimi seçimi (bölge/alan çift ComboBox), GeoIP, NTP veya manuel tarih/saat +3. **Klavye** — Düzen/varyant seçimi, arama, canlı önizleme (setxkbmap) +4. **Ağ** — WiFi tarama, bağlantı, proxy +5. **Disk Bölümleme** — Otomatik (rehberli) veya manuel, LVM, LUKS +6. **Kullanıcılar** — Hesap oluşturma, parola gücü göstergesi, root parolası +7. **Bootloader** — GRUB aygıtı, zaman aşımı, parola, çekirdek parametreleri +8. **Görüntü Yöneticisi** — SDDM/LightDM/GDM, masaüstü ortamı, otomatik oturum +9. **Özet** — Tüm seçimlerin gözden geçirilmesi +10. **Kurulum** — Slayt + ilerleme çubuğu + canlı log +11. **Bitir** — Başarılı kurulum, yeniden başlat veya canlı masaüstüne dön + +## Bağımlılıklar + +| Bağımlılık | Sürüm | Amaç | +|---|---|---| +| `eframe` | 0.27 (wgpu) | egui çatısı, WebGPU çıktısı | +| `egui_extras` | 0.27 (image, file, svg) | Görsel yükleme, dosya diyalogları, SVG | +| `image` | 0.24 | PNG kod çözme | +| `serde` / `toml` | 1.0 / 0.8 | Branding ve cevap dosyası serileştirme | +| `zbus` | 4.0 | D-Bus iletişimi (COMAR) | +| `tokio` | 1.0 (full) | Asenkron iş kuyruğu | +| `sysinfo` | 0.30 | Sistem bilgisi (RAM, disk, OS) | +| `rust-i18n` | 3.1 | Uluslararasılaştırma | +| `chrono` | 0.4 | Tarih/saat işlemleri | + +## Lisans + +GNU General Public License v3.0 + +Bu proje Pisi GNU/Linux ekibi tarafından geliştirilmektedir. diff --git a/README_en.md b/README_en.md new file mode 100644 index 0000000..5c385ee --- /dev/null +++ b/README_en.md @@ -0,0 +1,112 @@ +# YALI (Yet Another Linux Installer) — Rust / egui + +A rewritten **Pisi GNU/Linux** installation tool in Rust and egui. YALI installs the system from the live environment, installs packages, and performs basic configuration. It is a modern, fast, and maintainable rewrite of the original Python/Qt version. + +## Features + +- **10-step installation wizard**: Welcome → Location → Keyboard → Network → Disk Partitioning → Users → Bootloader → Summary → Installation → Finish +- **Two modes**: Graphical interface (default) and automatic installation with answer file (`--auto-install answer.toml`) +- **Demo mode**: Skips system checks, simulates installation (`--demo`) +- **Disk partitioning**: Automatic (GPT/MBR) or manual, LVM and LUKS encryption support +- **Network configuration**: WiFi scanning (nmcli), proxy settings +- **Bootloader**: GRUB device/password/timeout settings, kernel parameters +- **Rescue mode**: Chroot, GRUB reinstallation, Pisi rollback +- **OEM mode**: Predefined settings for manufacturer pre-installation +- **Internationalization**: Turkish and English (with rust-i18n via TOML locale files) +- **Branding system**: Runtime-loadable `branding.toml` for logo, slides, color settings +- **Theme**: Dark/light theme, atomic color management, custom gradient buttons +- **Async job queue**: All installation steps run in separate `tokio` runtime, UI updated via `mpsc` channel +- **System checks**: 8 pre-checks including RAM, disk space, internet, UEFI, CPU, NVMe +- **Slideshow**: Custom branded slides for 9 desktop environments +- **Demo session cleanup**: Removes live environment artifacts, adds production repository + +## Usage + +```bash +# Normal installation (requires root) +sudo cargo run --release + +# Demo mode (no root required) +cargo run --release -- --demo + +# Automatic installation (with answer file) +sudo cargo run --release -- --auto-install answer.toml +``` + +## Project Structure + +``` +├── src/ +│ ├── main.rs # Entry point, eframe App, GUI layout +│ ├── installer.rs # InstallerStep trait, GlobalState, WelcomeStep +│ ├── funct.rs # Shared UI helpers (form fields, language selector) +│ ├── branding.rs # Branding.toml loader (logo, slides, theme, OEM) +│ ├── ui/ +│ │ ├── theme.rs # Colors, fonts, Visuals, section_heading, error/warning/success boxes +│ │ ├── buttons.rs # Gradient buttons (primary, secondary, danger, etc.) +│ │ ├── combobox.rs # ComboBox helpers (show_combo_box, selectable_value) +│ │ ├── combobox_stil.rs # ComboBox visual constants (weak_bg, border, text colors) +│ │ ├── slideshow.rs # Auto-advancing slideshow +│ │ └── error_screen.rs # Error screen (log viewer, copy, retry) +│ ├── steps/ +│ │ ├── location.rs # Location/timezone + date/time +│ │ ├── license.rs # License agreement +│ │ ├── keyboard.rs # Keyboard layout/variant selection +│ │ ├── network.rs # Network configuration (WiFi, proxy) +│ │ ├── partition.rs # Disk partitioning (automatic + manual + LVM) +│ │ ├── users.rs # User account creation +│ │ ├── bootloader.rs # GRUB configuration +│ │ ├── summary.rs # Installation summary +│ │ ├── execution.rs # Installation execution (progress bar, log) +│ │ ├── finish.rs # Completion screen +│ │ ├── netinstall.rs # Extra package group selection +│ │ └── rescue.rs # Rescue mode (chroot, GRUB, Pisi takeback) +│ ├── jobs/mod.rs # Async job queue and all installation jobs +│ └── autoinstall/ +│ ├── mod.rs # Answer file loading and state application +│ └── checker.rs # System pre-checks +├── locales/ +│ ├── tr.toml # Turkish translations +│ └── en.toml # English translations +├── assets/ +│ ├── icons/ # UI icons (YALI_icon_LIGHT.svg, language-icon.svg, etc.) +│ ├── flags/ # Country flags (~250 SVG) +│ └── *.png # Slide and logo images +├── branding.toml # Default branding configuration +├── branding_en.toml # English branding +├── branding_tr.toml # Turkish branding +└── answer-example.toml # Example answer file +``` + +## Installation Workflow + +1. **Welcome** — Language selection, system checks, rescue mode +2. **Location / Time** — Timezone selection (region/area dual ComboBox), GeoIP, NTP or manual date/time +3. **Keyboard** — Layout/variant selection, search, live preview (setxkbmap) +4. **Network** — WiFi scanning, connection, proxy +5. **Disk Partitioning** — Automatic (guided) or manual, LVM, LUKS +6. **Users** — Account creation, password strength indicator, root password, autologin +7. **Bootloader** — GRUB device, timeout, password, kernel parameters +8. **Summary** — Review all selections +9. **Installation** — Slideshow + progress bar + live log +10. **Finish** — Successful installation, reboot or return to live desktop + +## Dependencies + +| Dependency | Version | Purpose | +|---|---|---| +| `eframe` | 0.27 (wgpu) | egui framework, WebGPU backend | +| `egui_extras` | 0.27 (image, file, svg) | Image loading, file dialogs, SVG | +| `image` | 0.24 | PNG decoding | +| `serde` / `toml` | 1.0 / 0.8 | Branding and answer file serialization | +| `zbus` | 4.0 | D-Bus communication (COMAR) | +| `tokio` | 1.0 (full) | Async job queue | +| `sysinfo` | 0.30 | System information (RAM, disk, OS) | +| `rust-i18n` | 3.1 | Internationalization | +| `chrono` | 0.4 | Date/time operations | + +## License + +GNU General Public License v3.0 + +This project is developed by the Pisi GNU/Linux team. diff --git a/locales/en.toml b/locales/en.toml index a10fc3c..bb05cd3 100644 --- a/locales/en.toml +++ b/locales/en.toml @@ -61,6 +61,10 @@ password_label = "Password (at least 8 characters...)" password_confirm_label = "Confirm password" hostname_label = "Computer name" username_invalid = "Invalid username. Must start with a lowercase letter or underscore, max 32 characters." +username_too_long = "Username too long (maximum 32 characters)" +username_forbidden = "This username is reserved by the system and is forbidden" +username_invalid_start = "Username must start with a lowercase letter or underscore" +username_invalid_chars = "Only lowercase letters, digits, underscore and hyphen are allowed" hostname_invalid = "Invalid hostname. Only letters, digits, and hyphens are allowed." passwords_no_match = "Passwords do not match" diff --git a/locales/tr.toml b/locales/tr.toml index 140a547..c4e97b3 100644 --- a/locales/tr.toml +++ b/locales/tr.toml @@ -61,6 +61,10 @@ password_label = "Parola (en az 8 karakter olmalıdır...)" password_confirm_label = "Parola (tekrar)" hostname_label = "Bilgisayar adı" username_invalid = "Geçersiz kullanıcı adı. Küçük harf veya alt çizgi ile başlamalı, en fazla 32 karakter." +username_too_long = "Kullanıcı adı çok uzun (maksimum 32 karakter)" +username_forbidden = "Bu kullanıcı adı sistem tarafından kullanılıyor ve yasaklı" +username_invalid_start = "Kullanıcı adı küçük harf veya alt çizgi ile başlamalı" +username_invalid_chars = "Sadece küçük harf, rakam, alt çizgi ve tire kullanılabilir" hostname_invalid = "Geçersiz bilgisayar adı. Yalnızca harf, rakam ve tire içerebilir." passwords_no_match = "Parolalar eşleşmiyor" diff --git a/src/installer.rs b/src/installer.rs index ef1e25b..f81360e 100644 --- a/src/installer.rs +++ b/src/installer.rs @@ -303,7 +303,7 @@ impl Default for GlobalState { oem_password_changed: false, selected_package_groups: Vec::new(), display_manager: "sddm".to_string(), - autologin: true, + autologin: false, desktop_environment: detect_desktop_environment(), branding_icons: std::collections::HashMap::new(), branding_pisi_dark: String::new(), diff --git a/src/jobs/mod.rs b/src/jobs/mod.rs index d80a50d..d3d74d1 100644 --- a/src/jobs/mod.rs +++ b/src/jobs/mod.rs @@ -1265,10 +1265,22 @@ impl Job for ConfigureDisplayManagerJob { match dm.as_str() { "sddm" => { let conf = format!("{}/usr/lib/sddm/sddm.conf.d/sddm.conf", self.mount); + let session = match self.desktop_environment.as_str() { + "plasma" => "plasmax11.desktop", + "xfce" => "xfce.desktop", + "gnome" => "gnome.desktop", + "cinnamon" => "cinnamon.desktop", + "budgie" => "budgie-desktop.desktop", + "lxde" => "LXDE.desktop", + "lxqt" => "lxqt.desktop", + "mate" => "mate.desktop", + "lumina" => "lumina-desktop.desktop", + _ => "plasmax11.desktop", + }; let content = if self.autologin { format!( - "[Autologin]\nUser={}\nSession=plasmax11.desktop\n\n[Theme]\nCurrent=pisilinux24\n", - self.username + "[Autologin]\nUser={}\nSession={}\n\n[Theme]\nCurrent=pisilinux24\n", + self.username, session ) } else { "[Autologin]\nUser=\nSession=\n\n[Theme]\nCurrent=pisilinux24\n".to_string() @@ -1299,10 +1311,22 @@ impl Job for ConfigureDisplayManagerJob { let dir = format!("{}/etc/gdm", self.mount); let _ = tokio::fs::create_dir_all(&dir).await; let conf = format!("{}/etc/gdm/custom.conf", self.mount); + let session = match self.desktop_environment.as_str() { + "plasma" => "plasmax11.desktop", + "xfce" => "xfce.desktop", + "gnome" => "gnome.desktop", + "cinnamon" => "cinnamon.desktop", + "budgie" => "budgie-desktop.desktop", + "lxde" => "LXDE.desktop", + "lxqt" => "lxqt.desktop", + "mate" => "mate.desktop", + "lumina" => "lumina-desktop.desktop", + _ => "gnome.desktop", + }; let content = if self.autologin { format!( - "[daemon]\nAutomaticLoginEnable=true\nAutomaticLogin={}\n", - self.username + "[daemon]\nAutomaticLoginEnable=true\nAutomaticLogin={}\nDefaultSession={}\n", + self.username, session ) } else { "[daemon]\n".to_string() diff --git a/src/main.rs b/src/main.rs index d7a4b7e..ef62488 100644 --- a/src/main.rs +++ b/src/main.rs @@ -7,7 +7,7 @@ mod branding; mod funct; use installer::{GlobalState, InstallerStep, WelcomeStep}; -use steps::{LocationStep, KeyboardStep, UsersStep, SummaryStep, ExecutionStep, FinishStep, PartitionStep, BootloaderStep, NetworkStep, DisplayManagerStep}; +use steps::{LocationStep, KeyboardStep, UsersStep, SummaryStep, ExecutionStep, FinishStep, PartitionStep, BootloaderStep, NetworkStep}; use eframe::egui; use rust_i18n::t; @@ -231,7 +231,6 @@ impl Default for YaliApp { Box::new(PartitionStep::default()), Box::new(UsersStep::default()), Box::new(BootloaderStep::default()), - Box::new(DisplayManagerStep::default()), Box::new(SummaryStep), Box::new(ExecutionStep::default()), Box::new(FinishStep), diff --git a/src/steps/bootloader.rs b/src/steps/bootloader.rs index 1d06933..a23a953 100644 --- a/src/steps/bootloader.rs +++ b/src/steps/bootloader.rs @@ -2,6 +2,7 @@ use eframe::egui; use rust_i18n::t; use crate::installer::{GlobalState, InstallerStep}; use crate::ui::theme; +use crate::funct::{form_label, form_input_text, form_input_password}; #[derive(Default)] pub struct BootloaderStep { @@ -26,77 +27,79 @@ impl InstallerStep for BootloaderStep { } fn show(&mut self, ui: &mut egui::Ui, state: &mut GlobalState) { - ui.heading(t!("bootloader_title")); - ui.label(t!("bootloader_description")); + theme::section_heading(ui, &t!("bootloader_title")); + ui.label( + egui::RichText::new(t!("bootloader_description")) + .color(theme::c_text_dim()) + .size(13.0), + ); ui.add_space(12.0); - egui::Grid::new("bootloader_grid") - .num_columns(2) - .spacing([12.0, 10.0]) + // ─── Önyükleyici Formu ────────────────────────────────── + egui::Frame::group(ui.style()) + .fill(theme::c_bg_widget()) + .rounding(6.0) + .inner_margin(egui::Margin::symmetric(10.0, 10.0)) .show(ui, |ui| { - // Hedef aygıt - ui.label(t!("bootloader_device_label")); - ui.horizontal(|ui| { - let mut device_list: Vec = state.available_disks.iter() - .map(|d| d.name.clone()) - .collect(); - if device_list.is_empty() { - device_list.push(state.bootloader_device.clone()); - } - let current = if state.bootloader_device.is_empty() { - device_list[0].clone() - } else { - state.bootloader_device.clone() - }; - theme::show_combo_box(ui, "boot_device_select", current.as_str(), ui.available_width(), |ui, w| { - for dev in &device_list { - theme::selectable_value(ui, &mut state.bootloader_device, dev.clone(), dev.as_str(), w); + ui.set_width(ui.available_width()); + ui.vertical(|ui| { + ui.add_space(10.0); + + // Hedef aygıt + form_label(ui, &t!("bootloader_device_label")); + ui.horizontal(|ui| { + let mut device_list: Vec = state.available_disks.iter() + .map(|d| d.name.clone()) + .collect(); + if device_list.is_empty() { + device_list.push(state.bootloader_device.clone()); } + let current = if state.bootloader_device.is_empty() { + device_list[0].clone() + } else { + state.bootloader_device.clone() + }; + theme::show_combo_box(ui, "boot_device_select", current.as_str(), ui.available_width(), |ui, w| { + for dev in &device_list { + theme::selectable_value(ui, &mut state.bootloader_device, dev.clone(), dev.as_str(), w); + } + }); }); ui.label( egui::RichText::new(t!("bootloader_device_hint")) .size(11.0) - .color(egui::Color32::from_rgb(120, 120, 140)), + .color(theme::c_text_dim()), ); - }); - ui.end_row(); + ui.add_space(6.0); - // Timeout - ui.label(t!("bootloader_timeout_label")); - ui.horizontal(|ui| { - ui.add(egui::Slider::new(&mut state.bootloader_timeout, 0..=60) - .text(t!("bootloader_timeout_suffix"))); - }); - ui.end_row(); + // Timeout + form_label(ui, &t!("bootloader_timeout_label")); + ui.horizontal(|ui| { + ui.add(egui::Slider::new(&mut state.bootloader_timeout, 0..=60) + .text(t!("bootloader_timeout_suffix"))); + }); + ui.add_space(6.0); - // GRUB şifresi - ui.label(t!("bootloader_password_label")); - ui.horizontal(|ui| { - if self.show_password { - ui.text_edit_singleline(&mut state.bootloader_password); - } else { - ui.add(egui::TextEdit::singleline(&mut state.bootloader_password).password(true)); - } - if ui.small_button(if self.show_password { "🙈" } else { "👁" }).clicked() { - self.show_password = !self.show_password; - } - if !state.bootloader_password.is_empty() { - ui.colored_label(egui::Color32::from_rgb(200, 180, 40), "⚠"); - } - }); - ui.end_row(); + // GRUB şifresi + form_label(ui, &t!("bootloader_password_label")); + ui.horizontal(|ui| { + let show_pwd = &mut self.show_password; + form_input_password(ui, &mut state.bootloader_password, show_pwd); + }); + ui.add_space(6.0); - // Kernel parametreleri - ui.label(t!("bootloader_kernel_label")); - ui.horizontal(|ui| { - ui.text_edit_singleline(&mut state.kernel_options); + // Kernel parametreleri + form_label(ui, &t!("bootloader_kernel_label")); + ui.horizontal(|ui| { + form_input_text(ui, &mut state.kernel_options); + }); ui.label( egui::RichText::new(t!("bootloader_kernel_hint")) .size(11.0) - .color(egui::Color32::from_rgb(120, 120, 140)), + .color(theme::c_text_dim()), ); + }); - ui.end_row(); }); } diff --git a/src/steps/mod.rs b/src/steps/mod.rs index 92986d0..ace9757 100644 --- a/src/steps/mod.rs +++ b/src/steps/mod.rs @@ -7,7 +7,7 @@ pub mod partition; pub mod bootloader; pub mod network; pub mod rescue; -pub mod display_manager; +//pub mod display_manager; pub mod netinstall; pub mod location; @@ -20,5 +20,4 @@ pub use partition::PartitionStep; pub use bootloader::BootloaderStep; pub use network::NetworkStep; pub use rescue::RescueStep; -pub use display_manager::DisplayManagerStep; pub use location::LocationStep; diff --git a/src/steps/users.rs b/src/steps/users.rs index dc6ded2..a5654d9 100644 --- a/src/steps/users.rs +++ b/src/steps/users.rs @@ -6,16 +6,18 @@ use crate::funct::{ form_input_text, form_input_password, form_label, form_check /// Kullanıcı adı, şifre, hostname ve yönetici (root) şifresi ayarları adımı. pub struct UsersStep { use_same_for_admin: bool, + autologin: bool, show_password: bool, show_password_confirm: bool, - show_root_password: bool, // <-- Eklendi - show_root_password_confirm: bool, // <-- Eklendi + show_root_password: bool, + show_root_password_confirm: bool, } impl Default for UsersStep { fn default() -> Self { Self { use_same_for_admin: true, + autologin: false, show_password: false, show_password_confirm: false, show_root_password: false, @@ -30,16 +32,22 @@ impl Default for UsersStep { /// - Boşlukları `-`'ye çevirir /// - Geçersiz karakterleri temizler fn derive_username(real_name: &str) -> String { - let mut name = real_name.to_lowercase(); - name = name + let name = real_name .replace('ş', "s") + .replace('Ş', "s") .replace('ğ', "g") + .replace('Ğ', "g") .replace('ı', "i") + .replace('İ', "i") .replace('ö', "o") + .replace('Ö', "o") .replace('ü', "u") + .replace('Ü', "u") .replace('ç', "c") + .replace('Ç', "c") .replace(' ', "-") - .replace('_', "-"); + .replace('_', "-") + .to_lowercase(); let valid: String = name.chars().filter(|c| c.is_ascii_alphanumeric() || *c == '-' || *c == '_').collect(); let trimmed = valid.trim_matches('-').to_string(); if trimmed.is_empty() { @@ -54,17 +62,44 @@ fn derive_username(real_name: &str) -> String { /// Kullanıcı adının geçerliliğini kontrol eder. /// Linux kuralları: küçük harf veya alt çizgi ile başlamalı, /// en fazla 32 karakter, yalnızca [a-z0-9_-] içermeli. -fn is_valid_username(s: &str) -> bool { - if s.is_empty() || s.len() > 32 { - return false; +/// Ayrıca sistem kullanıcı adları yasaklıdır. +/// Hata varsa hata mesajını döndürür, yoksa None döndürür. +fn validate_username(s: &str) -> Option { + if s.is_empty() { + return None; } + if s.len() > 32 { + return Some(t!("username_too_long").to_string()); + } + + // Yasaklı sistem kullanıcı adları + let forbidden = [ + "root", "daemon", "bin", "sys", "sync", "games", "man", "lp", + "mail", "news", "uucp", "proxy", "www-data", "backup", "list", + "irc", "gnats", "nobody", "systemd-timesync", "systemd-network", + "systemd-resolve", "systemd-bus-proxy", "messagebus", "sshd", + "ftp", "apache", "nginx", "mysql", "postgres", "docker", + ]; + if forbidden.contains(&s) { + return Some(t!("username_forbidden").to_string()); + } + let mut chars = s.chars(); // İlk karakter küçük harf veya alt çizgi olmalı match chars.next() { Some(c) if c.is_ascii_lowercase() || c == '_' => {} - _ => return false, + _ => return Some(t!("username_invalid_start").to_string()), } - chars.all(|c| c.is_ascii_lowercase() || c.is_ascii_digit() || c == '_' || c == '-') + if !chars.all(|c| c.is_ascii_lowercase() || c.is_ascii_digit() || c == '_' || c == '-') { + return Some(t!("username_invalid_chars").to_string()); + } + + None +} + +/// Kullanıcı adının geçerliliğini kontrol eder (basit bool versiyonu). +fn is_valid_username(s: &str) -> bool { + validate_username(s).is_none() } /// Hostname kuralları: 1-63 karakter, yalnızca [a-zA-Z0-9-], tire ile başlayamaz/bitemez. @@ -121,6 +156,9 @@ impl InstallerStep for UsersStep { } fn on_enter(&mut self, state: &mut GlobalState) { + // Autologin senkronizasyonu + self.autologin = state.autologin; + // Gerçek ad varsa ama kullanıcı adı yoksa türet if !state.real_name.is_empty() && state.username.is_empty() { state.username = derive_username(&state.real_name); @@ -168,27 +206,54 @@ impl InstallerStep for UsersStep { form_label(ui, &t!("real_name_label")); { let prev = state.real_name.clone(); - form_input_text(ui, &mut state.real_name); + ui.horizontal(|ui| { + form_input_text(ui, &mut state.real_name); + + + if !state.real_name.is_empty() { + ui.add( + egui::Image::new(egui::include_image!("../../assets/icons/check.svg")) + .max_width(18.0).max_height(18.0) + .tint(theme::c_success()) + ); + }else{ + ui.add( + egui::Image::new(egui::include_image!("../../assets/icons/fail-icon.svg")) + .max_width(18.0).max_height(18.0) + .tint(theme::c_error()) + ); + } + }); + if state.real_name != prev && !state.real_name.is_empty() { state.username = derive_username(&state.real_name); } } - if !state.real_name.is_empty() { - ui.colored_label(theme::c_success(), "✅"); - } else { - ui.colored_label(theme::c_error(), "❌"); - } ui.add_space(6.0); // Kullanıcı adı (otomatik türetilir, düzenlenebilir) form_label(ui, &t!("username_label")); - form_input_text(ui, &mut state.username); - if !state.username.is_empty() { - if is_valid_username(&state.username) { - ui.colored_label(theme::c_success(), "✅"); - } else { - ui.colored_label(theme::c_warning(), t!("username_invalid")); + + ui.horizontal(|ui| { + form_input_text(ui, &mut state.username); + if !state.username.is_empty() { + if let Some(_err) = validate_username(&state.username) { + ui.add( + egui::Image::new(egui::include_image!("../../assets/icons/fail-icon.svg")) + .max_width(18.0).max_height(18.0) + .tint(theme::c_error()) + ); + } else { + ui.add( + egui::Image::new(egui::include_image!("../../assets/icons/check.svg")) + .max_width(18.0).max_height(18.0) + .tint(theme::c_success()) + ); + } } + }); + if let Some(err) = validate_username(&state.username) { + ui.colored_label(theme::c_error(), err); } ui.add_space(6.0); @@ -221,27 +286,50 @@ impl InstallerStep for UsersStep { form_label(ui, &t!("password_confirm_label")); { let show_pwd = &mut self.show_password_confirm; - form_input_password(ui, &mut state.password_confirm, show_pwd); + ui.horizontal(|ui| { + form_input_password(ui, &mut state.password_confirm, show_pwd); + if !state.password_confirm.is_empty() { + if state.password == state.password_confirm { + ui.add( + egui::Image::new(egui::include_image!("../../assets/icons/check.svg")) + .max_width(18.0).max_height(18.0) + .tint(theme::c_success()) + ); + } else { + ui.add( + egui::Image::new(egui::include_image!("../../assets/icons/fail-icon.svg")) + .max_width(18.0).max_height(18.0) + .tint(theme::c_error()) + ); + } + } + }); } - if !state.password_confirm.is_empty() { - if state.password == state.password_confirm { - ui.colored_label(theme::c_success(), "✅"); - } else { - ui.colored_label(theme::c_warning(), t!("passwords_no_match")); - } + if !state.password_confirm.is_empty() && state.password != state.password_confirm { + ui.colored_label(theme::c_warning(), t!("passwords_no_match")); } ui.add_space(6.0); // Hostname form_label(ui, &t!("hostname_label")); - form_input_text(ui, &mut state.hostname); - if !state.hostname.is_empty() { - if is_valid_hostname(&state.hostname) { - ui.colored_label(theme::c_success(), "✅"); - } else { - ui.colored_label(theme::c_warning(), t!("hostname_invalid")); + ui.horizontal(|ui| { + form_input_text(ui, &mut state.hostname); + if !state.hostname.is_empty() { + if is_valid_hostname(&state.hostname) { + ui.add( + egui::Image::new(egui::include_image!("../../assets/icons/check.svg")) + .max_width(18.0).max_height(18.0) + .tint(theme::c_success()) + ); + } else { + ui.add( + egui::Image::new(egui::include_image!("../../assets/icons/fail-icon.svg")) + .max_width(18.0).max_height(18.0) + .tint(theme::c_error()) + ); + } } - } + }); }); ui.add_space(10.0); @@ -250,9 +338,13 @@ impl InstallerStep for UsersStep { ui.add_space(14.0); + // ─── Otomatik Oturum Açma ─────────────────────────────────────── + form_checkbox(ui, &mut self.autologin, &t!("display_manager_autologin")); + ui.add_space(8.0); + // ─── Yönetici (root) Ayarları ───────────────────────────────────── form_checkbox(ui, &mut self.use_same_for_admin, &t!("use_same_for_admin")); - + if self.use_same_for_admin { state.root_password = state.password.clone(); state.root_password_confirm = state.password_confirm.clone(); @@ -281,16 +373,33 @@ impl InstallerStep for UsersStep { // DÜZELTME: 3. parametre olarak show_root_password_confirm eklendi let show_root_pwd_conf = &mut self.show_root_password_confirm; - form_input_password(ui, &mut state.root_password_confirm, show_root_pwd_conf); + ui.horizontal(|ui| { + form_input_password(ui, &mut state.root_password_confirm, show_root_pwd_conf); + if !state.root_password_confirm.is_empty() { + if state.root_password == state.root_password_confirm { + ui.add( + egui::Image::new(egui::include_image!("../../assets/icons/check.svg")) + .max_width(18.0).max_height(18.0) + .tint(theme::c_success()) + ); + } else { + ui.add( + egui::Image::new(egui::include_image!("../../assets/icons/fail-icon.svg")) + .max_width(18.0).max_height(18.0) + .tint(theme::c_error()) + ); + } + } + }); - if state.root_password == state.root_password_confirm { - ui.colored_label(theme::c_success(), "✅"); - } else { + if !state.root_password_confirm.is_empty() && state.root_password != state.root_password_confirm { ui.colored_label(theme::c_error(), t!("passwords_no_match")); } }); } + // Autologin değerini state'e kaydet + state.autologin = self.autologin; } fn is_complete(&self, state: &GlobalState) -> bool { diff --git a/src/ui/theme.rs b/src/ui/theme.rs index 6d6a13d..5f0e873 100644 --- a/src/ui/theme.rs +++ b/src/ui/theme.rs @@ -60,28 +60,29 @@ pub fn set_theme_mode(is_dark: bool) { BG_PANEL.store(0x1A1A1E, Ordering::Relaxed); BG_WIDGET.store(0x242428, Ordering::Relaxed); BORDER.store(0x323238, Ordering::Relaxed); - TEXT.store(0xF3F3F5, Ordering::Relaxed); - TEXT_DIM.store(0x9E9EAF, Ordering::Relaxed); + TEXT.store(0xF3F3F5, Ordering::Relaxed); // #F3F3F5 + TEXT_DIM.store(0x9E9EAF, Ordering::Relaxed); // #9E9EAF SIDEBAR.store(0x0B0B0D, Ordering::Relaxed); + SIDEBAR_TEXT.store(0xffffff, Ordering::Relaxed); KEYBOARD_BG.store(0x000000, Ordering::Relaxed); BG_ROOT.store(0x1A1A1E, Ordering::Relaxed); } else { BG_FOOTER.store(0xf7f7f7, Ordering::Relaxed); BG_DARK.store(0xf7f7f7, Ordering::Relaxed); SIDEBAR.store(0x292f34, Ordering::Relaxed); - TEXT.store(0x000000, Ordering::Relaxed); - TEXT_DIM.store(0x000000, Ordering::Relaxed); + TEXT.store(0x000000, Ordering::Relaxed); // #000000 + TEXT_DIM.store(0x000000, Ordering::Relaxed); // #000000 SIDEBAR_TEXT.store(0xffffff, Ordering::Relaxed); KEYBOARD_BG.store(0xffffff, Ordering::Relaxed); BG_ROOT.store(0xf7f7f7, Ordering::Relaxed); - BG_DARK.store(0xF0F0F5, Ordering::Relaxed); + //BG_DARK.store(0xF0F0F5, Ordering::Relaxed); BG_PANEL.store(0xFFFFFF, Ordering::Relaxed); BG_WIDGET.store(0xE8E8EE, Ordering::Relaxed); BORDER.store(0xD0D0DA, Ordering::Relaxed); - TEXT.store(0x20202A, Ordering::Relaxed); - TEXT_DIM.store(0x60606A, Ordering::Relaxed); - SIDEBAR.store(0xE4E4EA, Ordering::Relaxed); + //TEXT.store(0x20202A, Ordering::Relaxed); // #20202A + //TEXT_DIM.store(0x60606A, Ordering::Relaxed); // #60606A + //SIDEBAR.store(0xE4E4EA, Ordering::Relaxed); } }