Skip to content

Commit d0f13b9

Browse files
committed
1.5.2 - Active Tray State
1 parent f69d6ac commit d0f13b9

File tree

4 files changed

+96
-44
lines changed

4 files changed

+96
-44
lines changed

Cargo.lock

Lines changed: 25 additions & 25 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[package]
22
name = "wooting-profile-switcher"
33
description = "Automatically switch Wooting keyboard profiles based on focused window"
4-
version = "1.5.1"
4+
version = "1.5.2"
55
authors = ["Shayne Hartford <shaybox@shaybox.com>"]
66
edition = "2021"
77
readme = "README.md"

src/main.rs

Lines changed: 69 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use anyhow::Result;
1212
use clap::Parser;
1313
use regex::Regex;
1414
use tauri::{
15+
AppHandle,
1516
Builder,
1617
CustomMenuItem,
1718
SystemTray,
@@ -27,6 +28,13 @@ use crate::config::{Config, Rule};
2728

2829
mod config;
2930

31+
const MENU_ITEMS: [(&str, &str); 4] = [
32+
("digital", "Digital"),
33+
("analog_1", "Analog 1"),
34+
("analog_2", "Analog 2"),
35+
("analog_3", "Analog 3"),
36+
];
37+
3038
#[derive(Debug, Parser)]
3139
#[command(author, version, about)]
3240
struct Args {
@@ -58,20 +66,27 @@ async fn main() -> Result<()> {
5866
let config = Arc::new(Config::load()?);
5967

6068
// Poll the active window in a background task
61-
let args_clone = args.clone();
62-
let config_clone = config.clone();
69+
let args_task = args.clone();
70+
let config_task = config.clone();
6371
tokio::spawn(async move {
64-
poll_active_window(args_clone, &config_clone).await.unwrap();
72+
poll_active_window(args_task, &config_task).unwrap();
6573
});
6674

67-
Builder::default()
75+
// Create the system tray menu and add the MENU_ITEMS
76+
let args_clone = args.clone();
77+
let config_clone = config.clone();
78+
let mut system_tray_menu = SystemTrayMenu::new();
79+
for (id, title) in MENU_ITEMS {
80+
let menu_item = CustomMenuItem::new(String::from(id), title).selected();
81+
system_tray_menu = system_tray_menu.add_item(menu_item);
82+
}
83+
84+
// Create the Tauri app and add the system tray menu
85+
#[cfg_attr(not(target_os = "macos"), allow(unused_mut))]
86+
let mut app = Builder::default()
6887
.system_tray(
6988
SystemTray::new().with_menu(
70-
SystemTrayMenu::new()
71-
.add_item(CustomMenuItem::new(String::from("digital"), "Digital"))
72-
.add_item(CustomMenuItem::new(String::from("analog_1"), "Analog 1"))
73-
.add_item(CustomMenuItem::new(String::from("analog_2"), "Analog 2"))
74-
.add_item(CustomMenuItem::new(String::from("analog_3"), "Analog 3"))
89+
system_tray_menu
7590
.add_native_item(SystemTrayMenuItem::Separator)
7691
.add_item(CustomMenuItem::new(String::from("pause"), "Pause"))
7792
.add_native_item(SystemTrayMenuItem::Separator)
@@ -86,34 +101,68 @@ async fn main() -> Result<()> {
86101
std::process::exit(0);
87102
}
88103
"pause" => {
89-
let paused = args.read().unwrap().paused;
104+
let paused = args_clone.read().unwrap().paused;
90105
let title = if paused { "Pause" } else { "Resume" };
91-
args.write().unwrap().paused = !paused;
106+
args_clone.write().unwrap().paused = !paused;
92107
item_handle.set_title(title).unwrap();
93108
}
94109
"digital" => {
95-
set_active_profile_index(0, config.send_sleep_ms);
110+
set_active_profile_index(0, config_clone.send_sleep_ms);
111+
args_clone.write().unwrap().profile_index = Some(0);
96112
}
97113
"analog_1" => {
98-
set_active_profile_index(1, config.send_sleep_ms);
114+
set_active_profile_index(1, config_clone.send_sleep_ms);
115+
args_clone.write().unwrap().profile_index = Some(1);
99116
}
100117
"analog_2" => {
101-
set_active_profile_index(2, config.send_sleep_ms);
118+
set_active_profile_index(2, config_clone.send_sleep_ms);
119+
args_clone.write().unwrap().profile_index = Some(2);
102120
}
103121
"analog_3" => {
104-
set_active_profile_index(3, config.send_sleep_ms);
122+
set_active_profile_index(3, config_clone.send_sleep_ms);
123+
args_clone.write().unwrap().profile_index = Some(3);
105124
}
106125
_ => {}
107126
}
108127
}
109128
})
110-
.run(tauri::generate_context!())?;
129+
.build(tauri::generate_context!())?;
130+
131+
#[cfg(target_os = "macos")] // Hide the macOS dock icon
132+
app.set_activation_policy(tauri::ActivationPolicy::Accessory);
133+
134+
// Run the Tauri app
135+
app.run(move |app, _event| {
136+
// Poll the args in a background task
137+
let app_clone = app.clone();
138+
let args_clone = args.clone();
139+
let config_clone = config.clone();
140+
tokio::spawn(async move {
141+
poll_args_profile(args_clone, &config_clone, &app_clone);
142+
});
143+
});
111144

112145
Ok(())
113146
}
114147

148+
/// Poll the args for profile index and update the system tray menu
149+
fn poll_args_profile(args: Arc<RwLock<Args>>, config: &Config, app: &AppHandle) {
150+
loop {
151+
std::thread::sleep(Duration::from_millis(config.loop_sleep_ms));
152+
153+
if let Some(profile_index) = args.read().unwrap().profile_index {
154+
MENU_ITEMS.iter().enumerate().for_each(|(i, (id, _title))| {
155+
let item_handle = app.tray_handle().get_item(id);
156+
item_handle
157+
.set_selected(i == profile_index as usize)
158+
.unwrap();
159+
})
160+
}
161+
}
162+
}
163+
115164
/// Poll the active window for matching rules and apply the profile
116-
async fn poll_active_window(args: Arc<RwLock<Args>>, config: &Config) -> Result<()> {
165+
fn poll_active_window(args: Arc<RwLock<Args>>, config: &Config) -> Result<()> {
117166
let device_info = unsafe {
118167
if !wooting_rgb_kbd_connected() {
119168
println!("Keyboard not connected.");
@@ -131,9 +180,11 @@ async fn poll_active_window(args: Arc<RwLock<Args>>, config: &Config) -> Result<
131180

132181
let mut last_active_window: ActiveWindow = Default::default();
133182
let mut last_profile_index = get_active_profile_index(device_info);
183+
args.write().unwrap().profile_index = Some(last_profile_index);
134184

135185
loop {
136186
std::thread::sleep(Duration::from_millis(config.loop_sleep_ms));
187+
137188
if args.read().unwrap().paused {
138189
continue;
139190
}
@@ -184,6 +235,7 @@ async fn poll_active_window(args: Arc<RwLock<Args>>, config: &Config) -> Result<
184235

185236
println!("Process Profile Index: {}", profile_index);
186237
set_active_profile_index(profile_index, config.send_sleep_ms);
238+
args.write().unwrap().profile_index = Some(profile_index);
187239
}
188240
}
189241

tauri.conf.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
},
99
"package": {
1010
"productName": "WootingProfileSwitcher",
11-
"version": "1.5.1"
11+
"version": "1.5.2"
1212
},
1313
"tauri": {
1414
"allowlist": {

0 commit comments

Comments
 (0)