From 38f800d8779623161db8a57ee5bc115f3073a9ff Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Thu, 11 Jul 2024 09:18:39 +0200 Subject: [PATCH] assure the multi-window lock actually works This includes the UI is responding to issues. --- app/src/routes/[projectId]/+layout.ts | 4 +++- crates/gitbutler-tauri/src/window.rs | 19 +++++++++++++++---- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/app/src/routes/[projectId]/+layout.ts b/app/src/routes/[projectId]/+layout.ts index 6a747fc7d..9d663bbbc 100644 --- a/app/src/routes/[projectId]/+layout.ts +++ b/app/src/routes/[projectId]/+layout.ts @@ -30,10 +30,12 @@ export async function load({ params, parent }) { // Getting the project should be one of few, if not the only await expression in // this function. It delays drawing the page, but currently the benefit from having this // synchronously available are much greater than the cost. + // However, what's awaited here is required for proper error handling, + // and by now this is fast enough to not be an impediment. let project: Project | undefined = undefined; try { project = await projectService.getProject(projectId); - invoke('set_project_active', { id: projectId }).then((_r) => {}); + await invoke('set_project_active', { id: projectId }).then((_r) => {}); } catch (err: any) { throw error(400, { message: err.message diff --git a/crates/gitbutler-tauri/src/window.rs b/crates/gitbutler-tauri/src/window.rs index 1065ad24b..c67a576c1 100644 --- a/crates/gitbutler-tauri/src/window.rs +++ b/crates/gitbutler-tauri/src/window.rs @@ -2,7 +2,7 @@ pub(super) mod state { use std::collections::BTreeMap; use std::sync::Arc; - use anyhow::{Context, Result}; + use anyhow::{bail, Context, Result}; use futures::executor::block_on; use gitbutler_project as projects; use gitbutler_project::ProjectId; @@ -135,18 +135,29 @@ pub(super) mod state { window: &WindowLabelRef, project: &projects::Project, ) -> Result<()> { + let mut state_by_label = block_on(self.state.lock()); + if let Some(state) = state_by_label.get(window) { + if state.project_id == project.id { + return Ok(()); + } + } let mut lock_file = fslock::LockFile::open(project.gb_dir().join(WINDOW_LOCK_FILE).as_os_str())?; - lock_file + let got_lock = lock_file .try_lock() - .context("Another GitButler Window already has the project opened")?; + .context("Failed to check if lock is taken")?; + if !got_lock { + bail!( + "Project '{}' is already opened in another window", + project.title + ); + } let handler = handler_from_app(&self.app_handle)?; let worktree_dir = project.path.clone(); let project_id = project.id; let watcher = gitbutler_watcher::watch_in_background(handler, worktree_dir, project_id)?; - let mut state_by_label = block_on(self.state.lock()); state_by_label.insert( window.to_owned(), State {