Skip to content

Commit

Permalink
feat: add configure to tray menu (#104)
Browse files Browse the repository at this point in the history
  • Loading branch information
sigoden committed Apr 18, 2024
1 parent 44c0e58 commit fa89ffd
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 22 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ Tips: **Hold `Alt` and strike `Backtick/Tab` to cycle through, press `Alt + Back

## Configuration

The window-switcher supports custom shortcuts, enabling and disabling certain functions, and all of these can be set through the configuration file.
Window-Switcher offers various customization options to tailor its behavior to your preferences. You can define custom keyboard shortcuts, enable or disable specific features, and fine-tune settings through a configuration file.

The configuration file must be named `window-switcher.ini` and located in the same directory as `window-switcher.exe` for the changes to take effect.
To personalize Window-Switcher, you'll need a configuration file named `window-switcher.ini`. This file should be placed in the same directory as the `window-switcher.exe` file. Once you've made changes to the configuration, make sure to restart Window-Switcher so your new settings can take effect.

Here is the default configuration:

Expand Down
10 changes: 8 additions & 2 deletions src/app.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::config::Config;
use crate::config::{edit_config_file, Config};
use crate::foreground::ForegroundWatcher;
use crate::keyboard::KeyboardListener;
use crate::startup::Startup;
Expand Down Expand Up @@ -40,6 +40,7 @@ pub const WM_USER_MODIFIER_KEYUP: u32 = 6001;
pub const WM_USER_HOOTKEY: u32 = 6002;
pub const IDM_EXIT: u32 = 1;
pub const IDM_STARTUP: u32 = 2;
pub const IDM_CONFIGURE: u32 = 3;

pub fn start(config: &Config) -> Result<()> {
info!("start config={:?}", config);
Expand Down Expand Up @@ -254,6 +255,11 @@ impl App {
let app = get_app(hwnd)?;
app.startup.toggle()?;
}
IDM_CONFIGURE => {
if let Err(err) = edit_config_file() {
alert!("{err}");
}
}
_ => {}
}
}
Expand All @@ -274,7 +280,7 @@ impl App {
Ok(unsafe { DefWindowProcW(hwnd, msg, wparam, lparam) })
}

pub fn switch_windows(&mut self, hwnd: HWND, reverse: bool) -> Result<bool> {
fn switch_windows(&mut self, hwnd: HWND, reverse: bool) -> Result<bool> {
let windows = list_windows(self.config.switch_windows_ignore_minimal)?;
debug!(
"switch windows: hwnd:{hwnd:?} reverse:{reverse} state:{:?}",
Expand Down
45 changes: 43 additions & 2 deletions src/config.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::{collections::HashSet, path::PathBuf};
use std::{collections::HashSet, fs, path::PathBuf, process::Command};

use anyhow::{anyhow, Result};
use ini::Ini;
Expand All @@ -12,7 +12,9 @@ use crate::utils::get_exe_folder;
pub const SWITCH_WINDOWS_HOTKEY_ID: u32 = 1;
pub const SWITCH_APPS_HOTKEY_ID: u32 = 2;

#[derive(Debug, Clone)]
const DEFAULT_CONFIG: &str = include_str!("../window-switcher.ini");

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Config {
pub trayicon: bool,
pub log_level: LevelFilter,
Expand Down Expand Up @@ -255,6 +257,45 @@ impl Hotkey {
}
}

pub fn load_config() -> Result<Config> {
let filepath = get_config_path()?;
let conf = Ini::load_from_file(&filepath)
.map_err(|err| anyhow!("Failed to load config file '{}', {err}", filepath.display()))?;
Config::load(&conf)
}

pub(crate) fn edit_config_file() -> Result<bool> {
let filepath = get_config_path()?;
debug!("open config file '{}'", filepath.display());
if !filepath.exists() {
fs::write(&filepath, DEFAULT_CONFIG).map_err(|err| {
anyhow!(
"Failed to write config file '{}', {err}",
filepath.display()
)
})?;
}
let exit = Command::new("notepad.exe")
.arg(&filepath)
.spawn()
.map_err(|err| anyhow!("Failed to open config file '{}', {err}", filepath.display()))?
.wait()
.map_err(|err| {
anyhow!(
"Failed to close config file '{}', {err}",
filepath.display()
)
})?;

Ok(exit.success())
}

fn get_config_path() -> Result<PathBuf> {
let folder = get_exe_folder()?;
let config_path = folder.join("window-switcher.ini");
Ok(config_path)
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,4 @@ mod startup;
mod trayicon;

pub use crate::app::start;
pub use crate::config::Config;
pub use crate::config::{load_config, Config};
15 changes: 1 addition & 14 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,7 @@ use std::{
path::Path,
};

use ini::Ini;
use window_switcher::{
alert, start,
utils::{get_exe_folder, SingleInstance},
Config,
};
use window_switcher::{alert, load_config, start, utils::SingleInstance};

fn main() {
if let Err(err) = run() {
Expand All @@ -38,14 +33,6 @@ fn run() -> Result<()> {
start(&config)
}

fn load_config() -> Result<Config> {
let folder = get_exe_folder()?;
let ini_file = folder.join("window-switcher.ini");
let conf =
Ini::load_from_file(ini_file).map_err(|err| anyhow!("Failed to load ini file, {err}"))?;
Config::load(&conf)
}

fn prepare_log_file(path: &Path) -> std::io::Result<File> {
if path.exists() {
OpenOptions::new().append(true).open(path)
Expand Down
4 changes: 3 additions & 1 deletion src/trayicon.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::app::{IDM_EXIT, IDM_STARTUP, NAME, WM_USER_TRAYICON};
use crate::app::{IDM_CONFIGURE, IDM_EXIT, IDM_STARTUP, NAME, WM_USER_TRAYICON};

use anyhow::{anyhow, Result};
use windows::core::w;
Expand All @@ -14,6 +14,7 @@ use windows::Win32::UI::WindowsAndMessaging::{
};

const ICON_BYTES: &[u8] = include_bytes!("../assets/icon.ico");
const TEXT_CONFIGURE: PCWSTR = w!("Configure");
const TEXT_STARTUP: PCWSTR = w!("Startup");
const TEXT_EXIT: PCWSTR = w!("Exit");

Expand Down Expand Up @@ -87,6 +88,7 @@ impl TrayIcon {
let startup_flags = if startup { MF_CHECKED } else { MF_UNCHECKED };
unsafe {
let hmenu = CreatePopupMenu().map_err(|err| anyhow!("Failed to create menu, {err}"))?;
AppendMenuW(hmenu, MF_STRING, IDM_CONFIGURE as usize, TEXT_CONFIGURE)?;
AppendMenuW(hmenu, startup_flags, IDM_STARTUP as usize, TEXT_STARTUP)?;
AppendMenuW(hmenu, MF_STRING, IDM_EXIT as usize, TEXT_EXIT)?;
Ok(hmenu)
Expand Down

0 comments on commit fa89ffd

Please sign in to comment.