improve error handling
This commit is contained in:
@@ -136,8 +136,8 @@ impl GeneralConfig {
|
||||
}
|
||||
|
||||
fn post_load(&self) {
|
||||
GeneralConfig::sanitize_range("keyboard_scale", self.keyboard_scale, 0.0, 5.0);
|
||||
GeneralConfig::sanitize_range("desktop_view_scale", self.desktop_view_scale, 0.0, 5.0);
|
||||
GeneralConfig::sanitize_range("keyboard_scale", self.keyboard_scale, 0.05, 5.0);
|
||||
GeneralConfig::sanitize_range("desktop_view_scale", self.desktop_view_scale, 0.05, 5.0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -192,12 +192,31 @@ pub fn load_general() -> GeneralConfig {
|
||||
// Add files from conf.d directory
|
||||
let path_conf_d = get_conf_d_path();
|
||||
if let Ok(paths_unsorted) = std::fs::read_dir(path_conf_d) {
|
||||
let mut paths: Vec<_> = paths_unsorted
|
||||
.filter_map(|r| match r {
|
||||
Ok(entry) => Some(entry),
|
||||
Err(e) => {
|
||||
error!("Failed to read conf.d directory: {}", e);
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
// Sort paths alphabetically
|
||||
let mut paths: Vec<_> = paths_unsorted.map(|r| r.unwrap()).collect(); // TODO safe unwrap?
|
||||
paths.sort_by_key(|dir| dir.path());
|
||||
for path in paths {
|
||||
if !path.file_type().unwrap().is_file() {
|
||||
// TODO safe unwrap?
|
||||
let file_type = match path.file_type() {
|
||||
Ok(file_type) => file_type,
|
||||
Err(e) => {
|
||||
error!(
|
||||
"Failed to get file type of {}: {}",
|
||||
path.path().to_string_lossy(),
|
||||
e
|
||||
);
|
||||
continue;
|
||||
}
|
||||
};
|
||||
|
||||
if !file_type.is_file() {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -106,9 +106,7 @@ impl FontCache {
|
||||
}
|
||||
|
||||
let pattern_str = format!("{PRIMARY_FONT}-{size}:style=bold:charset={cp:04x}");
|
||||
|
||||
let mut pattern =
|
||||
OwnedPattern::from_str(&pattern_str).expect("Failed to create fontconfig pattern");
|
||||
let mut pattern = OwnedPattern::from_str(&pattern_str).unwrap(); // safe because PRIMARY_FONT is const
|
||||
self.fc
|
||||
.substitute(&mut pattern, fontconfig::MatchKind::Pattern);
|
||||
pattern.default_substitute();
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
use std::{
|
||||
f32::consts::PI,
|
||||
io::Cursor,
|
||||
ops::Add,
|
||||
process::{self, Child},
|
||||
sync::Arc,
|
||||
@@ -8,7 +7,6 @@ use std::{
|
||||
};
|
||||
|
||||
use glam::{Quat, Vec3A};
|
||||
use rodio::{Decoder, Source};
|
||||
use serde::Deserialize;
|
||||
|
||||
use crate::{
|
||||
@@ -613,11 +611,8 @@ fn run_window(window: &Arc<str>, action: &WindowAction, app: &mut AppState) {
|
||||
}
|
||||
}
|
||||
|
||||
const THUMP_AUDIO_WAV: &'static [u8] = include_bytes!("../../res/380885.wav");
|
||||
|
||||
fn audio_thump(app: &mut AppState) {
|
||||
if let Some(handle) = app.audio.get_handle() {
|
||||
let wav = include_bytes!("../../res/380885.wav");
|
||||
let cursor = Cursor::new(wav);
|
||||
let source = Decoder::new_wav(cursor).unwrap();
|
||||
let _ = handle.play_raw(source.convert_samples());
|
||||
}
|
||||
app.audio.play(THUMP_AUDIO_WAV);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
io::Cursor,
|
||||
process::{Child, Command},
|
||||
str::FromStr,
|
||||
};
|
||||
@@ -18,7 +17,6 @@ use crate::{
|
||||
use glam::{vec2, vec3a, Affine2, Vec4};
|
||||
use once_cell::sync::Lazy;
|
||||
use regex::Regex;
|
||||
use rodio::{Decoder, Source};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
const PIXELS_PER_UNIT: f32 = 80.;
|
||||
@@ -83,10 +81,14 @@ where
|
||||
verbs: key_events_for_macro(macro_verbs),
|
||||
});
|
||||
} else if let Some(exec_args) = LAYOUT.exec_commands.get(key) {
|
||||
if exec_args.is_empty() {
|
||||
log::error!("Keyboard: EXEC args empty for {}", key);
|
||||
continue;
|
||||
}
|
||||
maybe_state = Some(KeyButtonData::Exec {
|
||||
program: exec_args
|
||||
.first()
|
||||
.expect("Keyboard: Invalid EXEC args")
|
||||
.unwrap() // safe because we checked is_empty
|
||||
.clone(),
|
||||
args: exec_args.iter().skip(1).cloned().collect(),
|
||||
});
|
||||
@@ -227,18 +229,12 @@ struct KeyboardData {
|
||||
processes: Vec<Child>,
|
||||
}
|
||||
|
||||
const KEY_AUDIO_WAV: &'static [u8] = include_bytes!("../res/421581.wav");
|
||||
|
||||
impl KeyboardData {
|
||||
fn key_click(&mut self, app: &mut AppState) {
|
||||
if !app.session.config.keyboard_sound_enabled {
|
||||
return;
|
||||
}
|
||||
|
||||
if let Some(handle) = app.audio.get_handle() {
|
||||
// https://freesound.org/people/UberBosser/sounds/421581/
|
||||
let wav = include_bytes!("../res/421581.wav");
|
||||
let cursor = Cursor::new(wav);
|
||||
let source = Decoder::new_wav(cursor).unwrap();
|
||||
let _ = handle.play_raw(source.convert_samples());
|
||||
if app.session.config.keyboard_sound_enabled {
|
||||
app.audio.play(KEY_AUDIO_WAV);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -253,7 +249,7 @@ enum KeyButtonData {
|
||||
static LAYOUT: Lazy<Layout> = Lazy::new(Layout::load_from_disk);
|
||||
|
||||
static MACRO_REGEX: Lazy<Regex> =
|
||||
Lazy::new(|| Regex::new(r"^([A-Za-z0-1_-]+)(?: +(UP|DOWN))?$").unwrap());
|
||||
Lazy::new(|| Regex::new(r"^([A-Za-z0-1_-]+)(?: +(UP|DOWN))?$").unwrap()); // want panic
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
pub struct Layout {
|
||||
@@ -314,11 +310,17 @@ impl Layout {
|
||||
key = &key[3..];
|
||||
}
|
||||
if key.contains('_') {
|
||||
key = key.split('_').next().unwrap();
|
||||
key = key.split('_').next().unwrap_or_else(|| {
|
||||
log::error!(
|
||||
"keyboard.yaml: Key '{}' must not start or end with '_'!",
|
||||
key
|
||||
);
|
||||
"???"
|
||||
});
|
||||
}
|
||||
vec![format!(
|
||||
"{}{}",
|
||||
key.chars().next().unwrap().to_uppercase(),
|
||||
key.chars().next().unwrap().to_uppercase(), // safe because we checked is_empty
|
||||
&key[1..].to_lowercase()
|
||||
)]
|
||||
}
|
||||
|
||||
@@ -1,12 +1,9 @@
|
||||
use std::{
|
||||
io::Cursor,
|
||||
ops::Add,
|
||||
sync::{atomic::AtomicUsize, Arc},
|
||||
time::Instant,
|
||||
};
|
||||
|
||||
use rodio::{Decoder, Source};
|
||||
|
||||
use glam::vec3a;
|
||||
|
||||
use crate::{
|
||||
@@ -21,6 +18,7 @@ use crate::{
|
||||
const FONT_SIZE: isize = 16;
|
||||
const PADDING: (f32, f32) = (25., 7.);
|
||||
const PIXELS_TO_METERS: f32 = 1. / 2000.;
|
||||
const TOAST_AUDIO_WAV: &'static [u8] = include_bytes!("../res/557297.wav");
|
||||
|
||||
static AUTO_INCREMENT: AtomicUsize = AtomicUsize::new(0);
|
||||
|
||||
@@ -79,12 +77,7 @@ impl Toast {
|
||||
.enqueue_at(TaskType::DropOverlay(selector), destroy_at);
|
||||
|
||||
if has_sound {
|
||||
if let Some(handle) = app.audio.get_handle() {
|
||||
let wav = include_bytes!("../res/557297.wav");
|
||||
let cursor = Cursor::new(wav);
|
||||
let source = Decoder::new_wav(cursor).unwrap();
|
||||
let _ = handle.play_raw(source.convert_samples());
|
||||
}
|
||||
app.audio.play(TOAST_AUDIO_WAV);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
23
src/state.rs
23
src/state.rs
@@ -1,8 +1,8 @@
|
||||
use std::{path::PathBuf, sync::Arc};
|
||||
use std::{io::Cursor, path::PathBuf, sync::Arc};
|
||||
|
||||
use anyhow::bail;
|
||||
use glam::Vec3;
|
||||
use rodio::{OutputStream, OutputStreamHandle};
|
||||
use rodio::{Decoder, OutputStream, OutputStreamHandle, Source};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use smallvec::{smallvec, SmallVec};
|
||||
use vulkano::format::Format;
|
||||
@@ -126,18 +126,33 @@ impl AudioOutput {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_handle(&mut self) -> Option<&OutputStreamHandle> {
|
||||
fn get_handle(&mut self) -> Option<&OutputStreamHandle> {
|
||||
if self.audio_stream.is_none() && self.first_try {
|
||||
self.first_try = false;
|
||||
if let Ok((stream, handle)) = OutputStream::try_default() {
|
||||
self.audio_stream = Some((stream, handle));
|
||||
} else {
|
||||
log::error!("Failed to open audio stream");
|
||||
log::error!("Failed to open audio stream. Audio will not work.");
|
||||
return None;
|
||||
}
|
||||
}
|
||||
self.audio_stream.as_ref().map(|(_, h)| h)
|
||||
}
|
||||
|
||||
pub fn play(&mut self, wav_bytes: &'static [u8]) {
|
||||
let Some(handle) = self.get_handle() else {
|
||||
return;
|
||||
};
|
||||
let cursor = Cursor::new(wav_bytes);
|
||||
let source = match Decoder::new_wav(cursor) {
|
||||
Ok(source) => source,
|
||||
Err(e) => {
|
||||
log::error!("Failed to play sound: {:?}", e);
|
||||
return;
|
||||
}
|
||||
};
|
||||
let _ = handle.play_raw(source.convert_samples());
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ScreenMeta {
|
||||
|
||||
Reference in New Issue
Block a user