Fix crash and session saving.
This commit is contained in:
1 parent
2a0e03cc41
commit
0e8bc70151
9 files changed
+353
-25
No files matched your search
+15
-5
@@ -23,7 +23,7 @@
|
||||
//!
|
||||
//! It lives in the *state* directory rather than beside `layouts.json` and
|
||||
//! `settings.json` in the config one. Those two are files a person writes;
|
||||
//! this one is written behind their back on every exit, and putting churn like
|
||||
//! this one is written behind their back every few seconds and on every exit, and putting churn like
|
||||
//! that in a config directory — which plenty of people keep in version control
|
||||
//! — would make every quit look like an edit. `$XDG_STATE_HOME` is where the
|
||||
//! spec puts exactly this: state that should carry across restarts but that
|
||||
@@ -276,27 +276,37 @@ pub const SaveError = error{ OutOfMemory, WriteFailed };
|
||||
/// nothing about that state worth offering to restore — so the offer should not
|
||||
/// appear at the next launch, and the stale one it would otherwise still be
|
||||
/// holding should not either.
|
||||
pub fn save(self: *Snapshot) SaveError!void {
|
||||
///
|
||||
/// `written` is a hash of what the caller last had written, and is updated to
|
||||
/// this one's. A snapshot that would write the same bytes again is skipped: the
|
||||
/// window is photographed every few seconds while it is open, and nearly every
|
||||
/// one of those photographs is the same as the last.
|
||||
pub fn save(self: *Snapshot, written: *u64) SaveError!void {
|
||||
var path_buf: [max_path]u8 = undefined;
|
||||
const path = statePath(&path_buf) orelse return error.WriteFailed;
|
||||
|
||||
if (!self.any()) {
|
||||
remove(path);
|
||||
written.* = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
const text = try self.serialize();
|
||||
defer self.arena.child_allocator.free(text);
|
||||
|
||||
const hash = std.hash.Wyhash.hash(0, text);
|
||||
if (hash == written.*) return;
|
||||
|
||||
var dir_buf: [max_path]u8 = undefined;
|
||||
const dir = stateDir(&dir_buf) orelse return error.WriteFailed;
|
||||
if (glib.mkdirWithParents(dir.ptr, 0o700) != 0) return error.WriteFailed;
|
||||
|
||||
const text = try self.serialize();
|
||||
defer self.arena.child_allocator.free(text);
|
||||
|
||||
var err: ?*glib.Error = null;
|
||||
if (glib.fileSetContents(path.ptr, text.ptr, @intCast(text.len), &err) == 0) {
|
||||
if (err) |e| e.free();
|
||||
return error.WriteFailed;
|
||||
}
|
||||
written.* = hash;
|
||||
}
|
||||
|
||||
/// Delete the file. Failures are ignored on purpose: the common one is it not
|
||||
|
||||
Reference in new issue
Block a user