diff --git a/i18n/en/cachyos_hello.ftl b/i18n/en/cachyos_hello.ftl index d6ae6f6..decc143 100644 --- a/i18n/en/cachyos_hello.ftl +++ b/i18n/en/cachyos_hello.ftl @@ -25,6 +25,9 @@ advanced-btn-tooltip = Toggle an extended selection of packages reset-btn-tooltip = Reset your current selections... update-system-app-btn-tooltip = Apply your current selections to the system +# Troubleshooting page +troubleshooting = Troubleshooting + # Dns Connections page dns-settings = DNS Settings select-connection = Select Connection: @@ -116,6 +119,7 @@ outdated-version-warning = You are using an older version of CachyOS ISO, please testing-iso-warning = You are using a testing ISO, testing ISOs are not considered stable and ready for use tweaksbrowser-label = Apps/Tweaks appbrowser-label = Install Apps +troubleshooting-label = Troubleshooting launch-start-label = Launch at start welcome-title = Welcome to CachyOS! welcome-body = diff --git a/src/pages/i18n.rs b/src/pages/i18n.rs index 17ef8c2..63e2c7d 100644 --- a/src/pages/i18n.rs +++ b/src/pages/i18n.rs @@ -83,6 +83,10 @@ pub fn update_translations(builder: &Builder) { appbrowser_btn.set_label(&fl!("appbrowser-label")); appbrowser_btn.set_tooltip_text(Some(&fl!("appbrowser-label"))); + let troubleshooting_btn: gtk::Button = builder.object("troubleshooting").unwrap(); + troubleshooting_btn.set_label(&fl!("troubleshooting-label")); + troubleshooting_btn.set_tooltip_text(Some(&fl!("troubleshooting-label"))); + let stack: gtk::Stack = builder.object("stack").unwrap(); { if let Some(widget) = stack.child_by_name("tweaksBrowserpage") diff --git a/src/pages/mod.rs b/src/pages/mod.rs index 8f7c020..d6416a3 100644 --- a/src/pages/mod.rs +++ b/src/pages/mod.rs @@ -23,23 +23,18 @@ macro_rules! create_gtk_button { }}; } -fn create_fixes_section(builder: &Builder) -> gtk::Box { +fn create_utilities_section(builder: &Builder) -> gtk::Box { let topbox = gtk::Box::new(gtk::Orientation::Vertical, 2); let button_box_f = gtk::Box::new(gtk::Orientation::Horizontal, 10); let button_box_s = gtk::Box::new(gtk::Orientation::Horizontal, 10); let button_box_t = gtk::Box::new(gtk::Orientation::Horizontal, 10); - let button_box_frth = gtk::Box::new(gtk::Orientation::Horizontal, 10); let label = gtk::Label::new(None); label.set_line_wrap(true); label.set_justify(gtk::Justification::Center); label.set_text(&fl!("fixes")); - let removelock_btn = create_gtk_button!("remove-lock-title"); - let reinstall_btn = create_gtk_button!("reinstall-title"); - let resetkeyring_btn = create_gtk_button!("reset-keyrings-title"); let update_system_btn = create_gtk_button!("update-system-title"); let remove_orphans_btn = create_gtk_button!("remove-orphans-title"); - let clear_pkgcache_btn = create_gtk_button!("clear-pkgcache-title"); let rankmirrors_btn = create_gtk_button!("rankmirrors-title"); let install_gaming_btn = create_gtk_button!("install-gaming-title"); @@ -54,23 +49,9 @@ fn create_fixes_section(builder: &Builder) -> gtk::Box { let (dialog_tx, dialog_rx) = async_channel::unbounded(); // Connect signals. - let dialog_tx_clone = dialog_tx.clone(); let dialog_tx_gaming = dialog_tx.clone(); let dialog_tx_winboat = dialog_tx.clone(); let dialog_tx_vram_management = dialog_tx.clone(); - removelock_btn.connect_clicked(move |_| { - let dialog_tx_clone = dialog_tx_clone.clone(); - std::thread::spawn(move || { - actions::remove_dblock(dialog_tx_clone); - }); - }); - reinstall_btn.connect_clicked(move |_| { - // Spawn child process in separate thread. - std::thread::spawn(move || { - actions::reinstall_packages(crate::gui::run_command); - }); - }); - resetkeyring_btn.connect_clicked(on_resetkeyring_btn_clicked); update_system_btn.connect_clicked(on_update_system_btn_clicked); remove_orphans_btn.connect_clicked(move |_| { // Spawn child process in separate thread. @@ -79,7 +60,6 @@ fn create_fixes_section(builder: &Builder) -> gtk::Box { actions::remove_orphans(crate::gui::run_command, dialog_tx_clone); }); }); - clear_pkgcache_btn.connect_clicked(on_clear_pkgcache_btn_clicked); rankmirrors_btn.connect_clicked(move |_| { // Spawn child process in separate thread. std::thread::spawn(move || { @@ -113,7 +93,6 @@ fn create_fixes_section(builder: &Builder) -> gtk::Box { } // Setup receiver. - let removelock_btn_clone = removelock_btn.clone(); let remove_orphans_btn_clone = remove_orphans_btn.clone(); let install_gaming_btn_clone = install_gaming_btn.clone(); let install_winboat_btn_clone = install_winboat_btn.clone(); @@ -121,7 +100,6 @@ fn create_fixes_section(builder: &Builder) -> gtk::Box { glib::MainContext::default().spawn_local(async move { while let Ok(msg) = dialog_rx.recv().await { let widget_obj = match msg.action { - Action::RemoveLock => &removelock_btn_clone, Action::RemoveOrphans => &remove_orphans_btn_clone, Action::InstallGaming => &install_gaming_btn_clone, Action::InstallWinboat => &install_winboat_btn_clone, @@ -140,16 +118,12 @@ fn create_fixes_section(builder: &Builder) -> gtk::Box { topbox.pack_start(&label, true, false, 1); button_box_f.pack_start(&update_system_btn, true, true, 2); - button_box_f.pack_start(&reinstall_btn, true, true, 2); - button_box_f.pack_end(&resetkeyring_btn, true, true, 2); - button_box_s.pack_start(&removelock_btn, true, true, 2); - button_box_s.pack_start(&clear_pkgcache_btn, true, true, 2); - button_box_s.pack_end(&remove_orphans_btn, true, true, 2); - button_box_t.pack_end(&rankmirrors_btn, true, true, 2); - button_box_t.pack_end(&install_gaming_btn, true, true, 2); - button_box_t.pack_end(&install_winboat_btn, true, true, 2); + button_box_f.pack_end(&remove_orphans_btn, true, true, 2); + button_box_f.pack_end(&rankmirrors_btn, true, true, 2); + button_box_s.pack_end(&install_gaming_btn, true, true, 2); + button_box_s.pack_end(&install_winboat_btn, true, true, 2); if let Some(button) = &install_vram_management_btn { - button_box_frth.pack_end(button, true, true, 2); + button_box_s.pack_end(button, true, true, 2); } if Path::new("/usr/bin/nmcli").exists() { @@ -159,30 +133,18 @@ fn create_fixes_section(builder: &Builder) -> gtk::Box { let stack: gtk::Stack = builder.object("stack").unwrap(); stack.set_visible_child_name(&format!("{name}page")); })); - button_box_frth.pack_end(&dnsserver_btn, true, true, 2); + let row_to_add = + if install_vram_management_btn.is_some() { &button_box_t } else { &button_box_s }; + row_to_add.pack_end(&dnsserver_btn, true, true, 2); } button_box_f.set_halign(gtk::Align::Fill); button_box_s.set_halign(gtk::Align::Fill); button_box_t.set_halign(gtk::Align::Fill); - button_box_frth.set_halign(gtk::Align::Fill); - topbox.pack_end(&button_box_frth, true, true, 5); topbox.pack_end(&button_box_t, true, true, 5); topbox.pack_end(&button_box_s, true, true, 5); topbox.pack_end(&button_box_f, true, true, 5); - if utils::is_kwin_wayland() { - let kwinw_debug_btn = create_gtk_button!("show-kwinw-debug-title"); - kwinw_debug_btn.connect_clicked(move |_| { - // Spawn child process in separate thread. - std::thread::spawn(move || { - // do we even need to start that in separate thread. should be fine without - actions::launch_kwin_debug_window(); - }); - }); - button_box_frth.pack_end(&kwinw_debug_btn, true, true, 2); - } - topbox.set_hexpand(true); topbox } @@ -217,14 +179,86 @@ fn create_apps_section() -> Option { if box_collection.children().is_empty() { None } else { Some(topbox) } } -pub fn create_tweaks_page(builder: &Builder) { - let install: gtk::Button = builder.object("tweaksBrowser").unwrap(); - install.set_visible(true); - install.set_label(&fl!("tweaksbrowser-label")); +fn create_troubleshooting_section() -> gtk::Box { + let topbox = gtk::Box::new(gtk::Orientation::Vertical, 2); + let button_box_f = gtk::Box::new(gtk::Orientation::Horizontal, 10); + let button_box_s = gtk::Box::new(gtk::Orientation::Horizontal, 10); + let button_box_t = gtk::Box::new(gtk::Orientation::Horizontal, 10); + let label = gtk::Label::new(None); + label.set_line_wrap(true); + label.set_justify(gtk::Justification::Center); + label.set_text(&fl!("troubleshooting")); - // fire cache - systemd_units::refresh_cache(); + let removelock_btn = create_gtk_button!("remove-lock-title"); + let reinstall_btn = create_gtk_button!("reinstall-title"); + let resetkeyring_btn = create_gtk_button!("reset-keyrings-title"); + let clear_pkgcache_btn = create_gtk_button!("clear-pkgcache-title"); + + let (dialog_tx, dialog_rx) = async_channel::unbounded(); + let dialog_tx_clone = dialog_tx.clone(); + + removelock_btn.connect_clicked(move |_| { + let dialog_tx_clone = dialog_tx_clone.clone(); + std::thread::spawn(move || { + actions::remove_dblock(dialog_tx_clone); + }); + }); + reinstall_btn.connect_clicked(move |_| { + std::thread::spawn(move || { + actions::reinstall_packages(crate::gui::run_command); + }); + }); + resetkeyring_btn.connect_clicked(on_resetkeyring_btn_clicked); + clear_pkgcache_btn.connect_clicked(on_clear_pkgcache_btn_clicked); + + let removelock_btn_clone = removelock_btn.clone(); + glib::MainContext::default().spawn_local(async move { + while let Ok(msg) = dialog_rx.recv().await { + let widget_obj = match msg.action { + Action::RemoveLock => &removelock_btn_clone, + _ => panic!("Unexpected action!!"), + }; + let widget_window = + utils::get_window_from_widget(widget_obj).expect("Failed to retrieve window"); + let ui_comp = crate::gui::Gui::new(widget_window); + ui_comp.show_message(msg.msg_type, &msg.msg, msg.msg_type.to_string()); + } + }); + + topbox.pack_start(&label, true, false, 1); + + button_box_f.pack_start(&clear_pkgcache_btn, true, true, 2); + button_box_f.pack_start(&removelock_btn, true, true, 2); + button_box_f.pack_start(&resetkeyring_btn, true, true, 2); + + button_box_s.pack_start(&reinstall_btn, true, true, 2); + + if utils::is_kwin_wayland() { + let kwinw_debug_btn = create_gtk_button!("show-kwinw-debug-title"); + kwinw_debug_btn.connect_clicked(move |_| { + // Spawn child process in separate thread. + std::thread::spawn(move || { + // do we even need to start that in separate thread. should be fine without + actions::launch_kwin_debug_window(); + }); + }); + button_box_t.pack_end(&kwinw_debug_btn, true, true, 2); + } + + button_box_f.set_halign(gtk::Align::Fill); + button_box_s.set_halign(gtk::Align::Fill); + button_box_t.set_halign(gtk::Align::Fill); + + topbox.pack_end(&button_box_t, true, true, 5); + topbox.pack_end(&button_box_s, true, true, 5); + topbox.pack_end(&button_box_f, true, true, 5); + + topbox.set_hexpand(true); + topbox +} + +fn create_child_viewport>(child: &T, builder: &Builder, child_name: &str) { let viewport = gtk::Viewport::new(gtk::Adjustment::NONE, gtk::Adjustment::NONE); let image = gtk::Image::from_icon_name(Some("go-previous"), gtk::IconSize::Button); let back_btn = gtk::Button::new(); @@ -237,8 +271,34 @@ pub fn create_tweaks_page(builder: &Builder) { stack.set_visible_child_name(&format!("{name}page")); })); + let grid = gtk::Grid::new(); + grid.set_hexpand(true); + grid.set_margin_start(10); + grid.set_margin_end(10); + grid.set_margin_top(5); + grid.set_margin_bottom(5); + grid.attach(&back_btn, 0, 1, 1, 1); + + let box_collection_s = gtk::Box::new(gtk::Orientation::Vertical, 5); + box_collection_s.pack_start(&grid, false, false, 0); + box_collection_s.pack_start(child, false, false, 10); + viewport.add(&box_collection_s); + + let stack: gtk::Stack = builder.object("stack").unwrap(); + stack.add_named(&viewport, child_name); + viewport.show_all(); +} + +pub fn create_tweaks_page(builder: &Builder) { + let install: gtk::Button = builder.object("tweaksBrowser").unwrap(); + install.set_visible(true); + install.set_label(&fl!("tweaksbrowser-label")); + + // fire cache + systemd_units::refresh_cache(); + let options_section_box = tweaks::create_options_section(); - let fixes_section_box = create_fixes_section(builder); + let fixes_section_box = create_utilities_section(builder); let apps_section_box_opt = create_apps_section(); let child_name = "tweaksBrowserpage"; @@ -248,14 +308,6 @@ pub fn create_tweaks_page(builder: &Builder) { apps_section_box.set_widget_name(&format!("{child_name}_apps")); } - let grid = gtk::Grid::new(); - grid.set_hexpand(true); - grid.set_margin_start(10); - grid.set_margin_end(10); - grid.set_margin_top(5); - grid.set_margin_bottom(5); - grid.attach(&back_btn, 0, 1, 1, 1); - let box_collection_s = gtk::Box::new(gtk::Orientation::Vertical, 5); let box_collection = gtk::Box::new(gtk::Orientation::Vertical, 5); box_collection.set_widget_name(child_name); @@ -268,13 +320,8 @@ pub fn create_tweaks_page(builder: &Builder) { box_collection.set_valign(gtk::Align::Center); box_collection.set_halign(gtk::Align::Center); - box_collection_s.pack_start(&grid, false, false, 0); - box_collection_s.pack_start(&box_collection, false, false, 10); - viewport.add(&box_collection_s); - viewport.show_all(); - let stack: gtk::Stack = builder.object("stack").unwrap(); - stack.add_named(&viewport, child_name); + create_child_viewport(&box_collection, builder, child_name); } pub fn create_appbrowser_page(builder: &Builder) { @@ -293,6 +340,25 @@ pub fn create_appbrowser_page(builder: &Builder) { }); } +pub fn create_troubleshooting_page(builder: &Builder) { + let troubleshooting_button: gtk::Button = builder.object("troubleshooting").unwrap(); + troubleshooting_button.set_visible(true); + troubleshooting_button.set_label(&fl!("troubleshooting-label")); + + let child_name = "troubleshootingpage"; + + let content: gtk::Box = gtk::Box::new(gtk::Orientation::Vertical, 5); + content.set_widget_name(child_name); + + let section = create_troubleshooting_section(); + content.pack_start(§ion, false, false, 10); + + content.set_valign(gtk::Align::Center); + content.set_halign(gtk::Align::Center); + + create_child_viewport(&content, builder, child_name); +} + fn on_resetkeyring_btn_clicked(_: >k::Button) { // Spawn child process in separate thread. std::thread::spawn(move || { diff --git a/src/utils.rs b/src/utils.rs index bf28cde..57f2591 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -46,7 +46,7 @@ pub const fn const_min(v1: usize, v2: usize) -> usize { #[inline] pub const fn string_substr(src_str: &str, pos: usize, n: usize) -> Result<&str, str::Utf8Error> { let rlen = const_min(n, src_str.len() - pos); - + unsafe { // First, we build a &[u8]... let slice = slice::from_raw_parts(src_str.as_ptr().add(pos), rlen); diff --git a/src/window.rs b/src/window.rs index 3e07914..778c88b 100644 --- a/src/window.rs +++ b/src/window.rs @@ -198,6 +198,7 @@ impl HelloWindow { pages::create_appbrowser_page(&builder); pages::create_tweaks_page(&builder); + pages::create_troubleshooting_page(&builder); if Path::new("/usr/bin/nmcli").exists() { pages::dns::create_connections_page(&builder); diff --git a/ui/cachyos-hello.glade b/ui/cachyos-hello.glade index 2f0c958..0bbf783 100644 --- a/ui/cachyos-hello.glade +++ b/ui/cachyos-hello.glade @@ -424,6 +424,23 @@ We, the CachyOS Developers, hope that you will enjoy using CachyOS as much as we 1 + + + Troubleshooting + troubleshooting + True + True + Tools for resolving issues with the system + 15 + 15 + + + + False + True + 2 + + 0 diff --git a/ui/style.css b/ui/style.css index 3286b48..4a82568 100644 --- a/ui/style.css +++ b/ui/style.css @@ -3,7 +3,9 @@ window { border-bottom-right-radius: 7px; } -#tweaksBrowserpage button { +#tweaksBrowserpage button, +#troubleshootingpage button +{ padding: 5px 15px; border: none; border-radius: 5px 5px 5px 5px;