RCC: add tray enable/disable, move app settings to page

This commit is contained in:
Luke D. Jones
2023-07-03 15:02:25 +12:00
parent 98dec6403c
commit 14d043bbc3
13 changed files with 152 additions and 73 deletions

View File

@@ -127,13 +127,12 @@ impl eframe::App for RogApp {
self.aura_page(&mut states, ctx);
return;
}
self.top_bar(&mut states, ctx, frame);
self.side_panel(ctx);
}
let page = self.page;
self.top_bar(ctx, frame);
self.side_panel(ctx);
let mut was_error = false;
if let Ok(mut states) = states.try_lock() {
@@ -163,16 +162,13 @@ impl eframe::App for RogApp {
if !was_error {
if let Ok(mut states) = states.try_lock() {
if page == Page::System {
self.system_page(&mut states, ctx);
} else if page == Page::AuraEffects {
self.aura_page(&mut states, ctx);
// TODO: Anime page is not complete
// } else if page == Page::AnimeMatrix {
// self.anime_page(ctx);
} else if page == Page::FanCurves {
self.fan_curve_page(&mut states, ctx);
}
match page {
Page::AppSettings => self.app_settings_page(&mut states, ctx),
Page::System => self.system_page(&mut states, ctx),
Page::AuraEffects => self.aura_page(&mut states, ctx),
Page::AnimeMatrix => todo!(),
Page::FanCurves => self.fan_curve_page(&mut states, ctx),
};
}
}
}

View File

@@ -14,6 +14,7 @@ const CFG_FILE_NAME: &str = "rog-control-center.cfg";
pub struct Config {
pub run_in_background: bool,
pub startup_in_background: bool,
pub enable_tray_icon: bool,
pub ac_command: String,
pub bat_command: String,
pub enable_notifications: bool,
@@ -28,6 +29,7 @@ impl Default for Config {
run_in_background: true,
startup_in_background: false,
enable_notifications: true,
enable_tray_icon: true,
dark_mode: true,
enabled_notifications: EnabledNotifications::default(),
ac_command: String::new(),
@@ -74,6 +76,9 @@ impl Config {
} else if let Ok(data) = toml::from_str::<Config>(&buf) {
info!("Loaded config file {path:?}");
return Ok(data);
} else if let Ok(data) = toml::from_str::<Config461>(&buf) {
info!("Loaded old v4.6.1 config file {path:?}");
return Ok(data.into());
} else if let Ok(data) = toml::from_str::<Config460>(&buf) {
info!("Loaded old v4.6.0 config file {path:?}");
return Ok(data.into());
@@ -127,6 +132,7 @@ impl From<Config455> for Config {
Self {
run_in_background: c.run_in_background,
startup_in_background: c.startup_in_background,
enable_tray_icon: true,
enable_notifications: c.enable_notifications,
enabled_notifications: c.enabled_notifications,
dark_mode: true,
@@ -151,6 +157,34 @@ impl From<Config460> for Config {
Self {
run_in_background: c.run_in_background,
startup_in_background: c.startup_in_background,
enable_tray_icon: true,
ac_command: c.ac_command,
bat_command: c.bat_command,
dark_mode: true,
enable_notifications: c.enable_notifications,
enabled_notifications: c.enabled_notifications,
}
}
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct Config461 {
pub run_in_background: bool,
pub startup_in_background: bool,
pub ac_command: String,
pub bat_command: String,
pub enable_notifications: bool,
pub dark_mode: bool,
// This field must be last
pub enabled_notifications: EnabledNotifications,
}
impl From<Config461> for Config {
fn from(c: Config461) -> Self {
Self {
run_in_background: c.run_in_background,
startup_in_background: c.startup_in_background,
enable_tray_icon: true,
ac_command: c.ac_command,
bat_command: c.bat_command,
dark_mode: true,

View File

@@ -47,6 +47,7 @@ pub const SHOW_GUI: u8 = 2;
#[derive(PartialEq, Eq, Clone, Copy)]
pub enum Page {
AppSettings,
System,
AuraEffects,
AnimeMatrix,

View File

@@ -189,7 +189,9 @@ fn main() -> Result<()> {
&supported,
)?;
init_tray(supported, states.clone());
if config.enable_tray_icon {
init_tray(supported, states.clone());
}
let mut bg_check_spawned = false;
loop {
@@ -210,35 +212,32 @@ fn main() -> Result<()> {
bg_check_spawned = false;
}
if !config.run_in_background || cli_parsed.board_name.is_some() || cli_parsed.layout_viewing
{
break;
if let Ok(lock) = states.try_lock() {
if !lock.run_in_bg || cli_parsed.board_name.is_some() || cli_parsed.layout_viewing {
break;
}
if lock.run_in_bg && running_in_bg.load(Ordering::Acquire) && !bg_check_spawned {
let running_in_bg = running_in_bg.clone();
thread::spawn(move || {
let mut buf = [0u8; 4];
// blocks until it is read, typically the read will happen after a second
// process writes to the IPC (so there is data to actually read)
loop {
if get_ipc_file().unwrap().read(&mut buf).is_ok() && buf[0] == SHOW_GUI {
running_in_bg.store(false, Ordering::Release);
debug!("Wait thread got from tray {buf:#?}");
break;
}
}
});
bg_check_spawned = true;
}
}
if config.run_in_background && running_in_bg.load(Ordering::Acquire) && !bg_check_spawned {
let running_in_bg = running_in_bg.clone();
thread::spawn(move || {
let mut buf = [0u8; 4];
// blocks until it is read, typically the read will happen after a second
// process writes to the IPC (so there is data to actually read)
loop {
if get_ipc_file().unwrap().read(&mut buf).is_ok() && buf[0] == SHOW_GUI {
running_in_bg.store(false, Ordering::Release);
debug!("Wait thread got from tray {buf:#?}");
break;
}
}
});
bg_check_spawned = true;
}
// Prevent hogging CPU
thread::sleep(Duration::from_millis(500));
}
// loop {
// // This is just a blocker to idle and ensure the reator reacts
// sleep(Duration::from_millis(1000)).await;
// }
Ok(())
}
@@ -255,6 +254,8 @@ fn setup_page_state_and_notifs(
keyboard_layout,
keyboard_layouts,
enabled_notifications.clone(),
config.enable_tray_icon,
config.run_in_background,
supported,
)?));

View File

@@ -0,0 +1,24 @@
use crate::system_state::SystemState;
use crate::widgets::app_settings;
use crate::RogApp;
impl RogApp {
pub fn app_settings_page(&mut self, states: &mut SystemState, ctx: &egui::Context) {
let Self { config, .. } = self;
egui::CentralPanel::default().show(ctx, |ui| {
egui::ScrollArea::vertical().show(ui, |ui| {
ui.spacing_mut().item_spacing = egui::vec2(8.0, 10.0);
let rect = ui.available_rect_before_wrap();
egui::Grid::new("grid_of_bits")
.min_col_width(rect.width() / 2.0)
.show(ui, |ui| {
ui.vertical(|ui| {
ui.separator();
app_settings(config, states, ui);
});
});
})
});
}
}

View File

@@ -1,9 +1,11 @@
mod anime_page;
mod app_settings;
mod aura_page;
mod fan_curve_page;
mod system_page;
pub use anime_page::*;
pub use app_settings::*;
pub use aura_page::*;
pub use fan_curve_page::*;
pub use system_page::*;

View File

@@ -1,17 +1,13 @@
use crate::system_state::SystemState;
use crate::widgets::{
anime_power_group, app_settings, aura_power_group, platform_profile, rog_bios_group,
};
use crate::widgets::{anime_power_group, aura_power_group, platform_profile, rog_bios_group};
use crate::RogApp;
impl RogApp {
pub fn system_page(&mut self, states: &mut SystemState, ctx: &egui::Context) {
let Self {
config, supported, ..
} = self;
let Self { supported, .. } = self;
egui::CentralPanel::default().show(ctx, |ui| {
ui.heading("Base settings");
ui.heading("Laptop settings");
egui::ScrollArea::vertical().show(ui, |ui| {
ui.spacing_mut().item_spacing = egui::vec2(8.0, 10.0);
@@ -31,10 +27,6 @@ impl RogApp {
});
ui.end_row();
ui.vertical(|ui| {
ui.separator();
app_settings(config, states, ui);
});
ui.vertical(|ui| {
ui.separator();
rog_bios_group(supported, states, ui);

View File

@@ -316,6 +316,8 @@ pub struct SystemState {
pub app_should_update: bool,
pub asus_dbus: RogDbusClientBlocking<'static>,
pub gfx_dbus: GfxProxyBlocking<'static>,
pub tray_enabled: bool,
pub run_in_bg: bool,
}
impl SystemState {
@@ -326,6 +328,8 @@ impl SystemState {
keyboard_layout: KeyLayout,
keyboard_layouts: Vec<PathBuf>,
enabled_notifications: Arc<Mutex<EnabledNotifications>>,
tray_enabled: bool,
run_in_bg: bool,
supported: &SupportedFunctions,
) -> Result<Self> {
let (asus_dbus, conn) = RogDbusClientBlocking::new()?;
@@ -390,6 +394,8 @@ impl SystemState {
app_should_update: true,
asus_dbus,
gfx_dbus,
tray_enabled,
run_in_bg,
})
}
@@ -449,6 +455,8 @@ impl Default for SystemState {
app_should_update: true,
asus_dbus,
gfx_dbus,
tray_enabled: true,
run_in_bg: true,
}
}
}

View File

@@ -2,7 +2,6 @@
//! commands over an MPSC channel.
use std::io::Write;
use std::sync::mpsc::{channel, Receiver};
use std::sync::{Arc, Mutex};
use std::time::Duration;
@@ -29,11 +28,6 @@ pub enum AppToTray {
DgpuStatus(GfxPower),
}
pub enum TrayToApp {
Open,
Quit,
}
pub struct RadioGroup(Vec<gtk::RadioMenuItem>);
impl RadioGroup {
@@ -418,13 +412,8 @@ impl ROGTray {
}
}
pub fn init_tray(
supported: SupportedFunctions,
states: Arc<Mutex<SystemState>>,
) -> Receiver<TrayToApp> {
let (send, recv) = channel();
let _send = Arc::new(Mutex::new(send));
/// The tray is controlled somewhat by `Arc<Mutex<SystemState>>`
pub fn init_tray(supported: SupportedFunctions, states: Arc<Mutex<SystemState>>) {
std::thread::spawn(move || {
let gtk_init = gtk::init().map_err(|e| {
error!("ROGTray: gtk init {e}");
@@ -538,6 +527,4 @@ pub fn init_tray(
trace!("Tray loop ticked");
}
});
recv
}

View File

@@ -4,8 +4,7 @@ use crate::config::Config;
use crate::system_state::SystemState;
pub fn app_settings(config: &mut Config, states: &mut SystemState, ui: &mut Ui) {
ui.heading("ROG GUI Settings");
// ui.label("Options are incomplete. Awake + Boot should work");
ui.heading("App Settings");
let mut enabled_notifications = if let Ok(lock) = states.enabled_notifications.lock() {
lock.clone()
@@ -15,8 +14,14 @@ pub fn app_settings(config: &mut Config, states: &mut SystemState, ui: &mut Ui)
ui.label("Application settings");
let app_changed = ui
.checkbox(&mut config.run_in_background, "Run in Background")
.checkbox(
&mut config.enable_tray_icon,
"Enable Tray Icon (restart required)",
)
.clicked()
|| ui
.checkbox(&mut config.run_in_background, "Run in Background")
.clicked()
|| ui
.checkbox(&mut config.startup_in_background, "Startup Hidden")
.clicked()
@@ -27,6 +32,10 @@ pub fn app_settings(config: &mut Config, states: &mut SystemState, ui: &mut Ui)
)
.clicked();
// if ui.button("Quit").clicked() {
// states.run_in_bg = false;
// }
ui.label("Notification settings");
let notif_changed = ui
.checkbox(
@@ -100,6 +109,9 @@ pub fn app_settings(config: &mut Config, states: &mut SystemState, ui: &mut Ui)
states.error = Some(err.to_string());
})
.ok();
states.tray_enabled = config.enable_tray_icon;
states.run_in_bg = config.run_in_background;
}
}
}

View File

@@ -49,6 +49,14 @@ impl RogApp {
// }
// }
ui.separator();
if ui
.selectable_value(page, Page::AppSettings, "App Settings")
.clicked()
{
*page = Page::AppSettings;
}
ui.with_layout(egui::Layout::bottom_up(egui::Align::LEFT), |ui| {
ui.horizontal(|ui| {
ui.spacing_mut().item_spacing.x = 0.0;

View File

@@ -1,15 +1,25 @@
use egui::{vec2, Align2, FontId, Id, Sense};
use crate::system_state::SystemState;
use crate::{RogApp, VERSION};
impl RogApp {
pub fn top_bar(&mut self, ctx: &egui::Context, frame: &mut eframe::Frame) {
pub fn top_bar(
&mut self,
states: &mut SystemState,
ctx: &egui::Context,
frame: &mut eframe::Frame,
) {
egui::TopBottomPanel::top("top_panel").show(ctx, |ui| {
// The top panel is often a good place for a menu bar:
egui::menu::bar(ui, |ui| {
ui.horizontal(|ui| {
self.dark_light_mode_buttons(ui);
egui::warn_if_debug_build(ui);
if ui.button("Quit app").clicked() {
states.run_in_bg = false;
frame.close();
}
});
// Drag area
@@ -35,9 +45,9 @@ impl RogApp {
);
// // Add the close button:
// let close_response = ui.put(
// Rect::from_min_size(titlebar_rect.right_top(),
// Vec2::splat(height)),
// Button::new(RichText::new("❌").size(height -
// egui::Rect::from_min_size(titlebar_rect.right_top(),
// egui::Vec2::splat(height)),
// egui::Button::new(egui::RichText::new("❌").size(height -
// 4.0)).frame(false), );
// if close_response.clicked() {
// frame.close();