Skip to content

Commit 233f56f

Browse files
committed
fix(tb): state being reset
1 parent dc05ef9 commit 233f56f

File tree

7 files changed

+56
-43
lines changed

7 files changed

+56
-43
lines changed

changelog.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@
1111
- log system.
1212
- icon pack extractor and cache system.
1313

14+
### fix
15+
16+
- toolbar and dock state resetting on widget reload.
17+
1418
## [2.5.3]
1519

1620
### fix

src/background/state/application/toolbar_items.rs

Lines changed: 9 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
1-
use std::{
2-
collections::HashSet,
3-
fs::{create_dir_all, OpenOptions},
4-
io::Write,
5-
};
1+
use std::collections::HashSet;
62

73
use seelen_core::{
84
resource::WidgetId,
95
state::{ToolbarItem, ToolbarItem2, ToolbarJsScope, ToolbarState},
106
};
117

12-
use crate::{error::Result, utils::constants::SEELEN_COMMON};
8+
use crate::{
9+
error::Result,
10+
utils::{atomic_write_file, constants::SEELEN_COMMON},
11+
};
1312

1413
use super::FullState;
1514

@@ -71,17 +70,9 @@ impl FullState {
7170
}
7271

7372
pub fn write_toolbar_items(&self, items: &ToolbarState) -> Result<()> {
74-
let dir = SEELEN_COMMON.widget_data_dir(&WidgetId::known_toolbar());
75-
create_dir_all(&dir)?;
76-
77-
let mut file = OpenOptions::new()
78-
.write(true)
79-
.create(true)
80-
.truncate(true)
81-
.open(dir.join("state.yml"))?;
82-
file.lock()?;
83-
file.write_all(serde_yaml::to_string(items)?.as_bytes())?;
84-
file.flush()?;
85-
Ok(())
73+
let path = SEELEN_COMMON
74+
.widget_data_dir(&WidgetId::known_toolbar())
75+
.join("state.yml");
76+
atomic_write_file(&path, serde_yaml::to_string(items)?.as_bytes())
8677
}
8778
}

src/background/state/application/weg_items.rs

Lines changed: 10 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,16 @@
1-
use std::{
2-
fs::{create_dir_all, OpenOptions},
3-
io::Write,
4-
};
5-
61
use seelen_core::{
72
handlers::SeelenEvent,
83
resource::WidgetId,
94
state::{WegItem, WegItems},
105
};
116

127
use crate::{
13-
app::emit_to_webviews, error::Result, modules::apps::application::msix::MsixAppsManager,
14-
trace_lock, utils::constants::SEELEN_COMMON, widgets::weg::weg_items_impl::SEELEN_WEG_STATE,
8+
app::emit_to_webviews,
9+
error::Result,
10+
modules::apps::application::msix::MsixAppsManager,
11+
trace_lock,
12+
utils::{atomic_write_file, constants::SEELEN_COMMON},
13+
widgets::weg::weg_items_impl::SEELEN_WEG_STATE,
1514
};
1615

1716
use super::FullState;
@@ -66,17 +65,9 @@ impl FullState {
6665
}
6766

6867
pub fn write_weg_items(&self, items: &WegItems) -> Result<()> {
69-
let dir = SEELEN_COMMON.widget_data_dir(&WidgetId::known_weg());
70-
create_dir_all(&dir)?;
71-
72-
let mut file = OpenOptions::new()
73-
.write(true)
74-
.create(true)
75-
.truncate(true)
76-
.open(dir.join("state.yml"))?;
77-
file.lock()?;
78-
file.write_all(serde_yaml::to_string(items)?.as_bytes())?;
79-
file.flush()?;
80-
Ok(())
68+
let path = SEELEN_COMMON
69+
.widget_data_dir(&WidgetId::known_weg())
70+
.join("state.yml");
71+
atomic_write_file(&path, serde_yaml::to_string(items)?.as_bytes())
8172
}
8273
}

src/background/state/infrastructure.rs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,12 @@ pub fn state_get_toolbar_items() -> ToolbarState {
2929
#[tauri::command(async)]
3030
pub fn state_write_toolbar_items(mut items: ToolbarState) -> Result<()> {
3131
items.sanitize();
32-
let guard = FULL_STATE.load();
33-
guard.write_toolbar_items(&items)
32+
FULL_STATE.rcu(|state| {
33+
let mut state = state.cloned();
34+
state.toolbar_items = items.clone();
35+
state
36+
});
37+
FULL_STATE.load().write_toolbar_items(&items)
3438
}
3539

3640
#[tauri::command(async)]
@@ -46,7 +50,12 @@ pub fn state_write_weg_items(window: tauri::Window, mut items: WegItems) -> Resu
4650
{
4751
return Ok(());
4852
}
49-
guard.write_weg_items(&items)
53+
FULL_STATE.rcu(|state| {
54+
let mut state = state.cloned();
55+
state.weg_items = items.clone();
56+
state
57+
});
58+
FULL_STATE.load().write_weg_items(&items)
5059
}
5160

5261
#[tauri::command(async)]

src/background/utils/mod.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ pub use winver::*;
1212

1313
use std::{
1414
collections::HashMap,
15+
fs::{create_dir_all, File},
16+
io::Write,
1517
path::{Path, PathBuf},
1618
sync::{atomic::AtomicBool, Arc, LazyLock},
1719
time::{Duration, Instant, SystemTime, UNIX_EPOCH},
@@ -26,6 +28,23 @@ use windows::{
2628

2729
use crate::{error::Result, get_tokio_handle};
2830

31+
/// Writes `content` to `path` atomically: writes to a sibling `.tmp` file first,
32+
/// syncs to disk, then renames into place. This guarantees the target file is
33+
/// never left empty or partially written, even if the process is killed mid-write.
34+
pub fn atomic_write_file(path: &Path, content: &[u8]) -> Result<()> {
35+
let dir = path.parent().ok_or("Path has no parent directory")?;
36+
create_dir_all(dir)?;
37+
38+
let tmp_path = path.with_extension("tmp");
39+
let mut file = File::create(&tmp_path)?;
40+
file.write_all(content)?;
41+
file.flush()?;
42+
file.sync_all()?;
43+
drop(file); // must close before rename on Windows
44+
std::fs::rename(&tmp_path, path)?;
45+
Ok(())
46+
}
47+
2948
pub fn pcwstr(s: &str) -> windows::core::PCWSTR {
3049
windows::core::PCWSTR::from_raw(s.encode_utf16().chain(Some(0)).collect_vec().as_ptr())
3150
}

src/background/widgets/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ use crate::{
2828
error::Result,
2929
resources::RESOURCES,
3030
state::application::FULL_STATE,
31-
utils::{constants::SEELEN_COMMON, lock_free::SyncHashMap},
31+
utils::{atomic_write_file, constants::SEELEN_COMMON, lock_free::SyncHashMap},
3232
widgets::{manager::WIDGET_MANAGER, webview::WidgetWebviewLabel},
3333
windows_api::{
3434
input::{Keyboard, Mouse},
@@ -190,7 +190,7 @@ pub fn write_data_file(
190190
) -> Result<()> {
191191
let base_path = widget_data_dir(&webview)?;
192192
let path = resolve_safe_path(&base_path, &filename)?;
193-
std::fs::write(path, content)?;
193+
atomic_write_file(&path, content.as_bytes())?;
194194
Ok(())
195195
}
196196

src/ui/react/toolbar/modules/shared/state/default.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ export function restoreStateToDefault() {
3636
right: [
3737
"@seelen/tb-system-tray" as PluginId,
3838
"@seelen/tb-keyboard-selector" as PluginId,
39-
"@seelen/keyboard-selector" as PluginId,
4039
"@seelen/tb-bluetooth-popup" as PluginId,
4140
"@seelen/tb-network-popup" as PluginId,
4241
"@seelen/tb-media-popup" as PluginId,

0 commit comments

Comments
 (0)