Skip to content

Desktop: Isolate CEF-rendered UI in a separate crate and process#4321

Open
timon-schelling wants to merge 6 commits into
masterfrom
desktop-ui-crate
Open

Desktop: Isolate CEF-rendered UI in a separate crate and process#4321
timon-schelling wants to merge 6 commits into
masterfrom
desktop-ui-crate

Conversation

@timon-schelling

Copy link
Copy Markdown
Member
  • New graphite-desktop-ui crate runs CEF in its own host process
  • Main process spawns controls the host over IPC
  • Frames returned via shared memory, or shared GPU textures
  • Fixes a bunch of problems that come with running CEF in-process

TL;DR: I got tired of dealing with CEF so I isolated it

@timon-schelling

timon-schelling commented Jul 10, 2026

Copy link
Copy Markdown
Member Author

!build desktop (Run ID 29061690651)

@gemini-code-assist

Copy link
Copy Markdown
Contributor

Warning

Gemini encountered an error creating the review. You can try again by commenting /gemini review.

cubic-dev-ai[bot]

This comment was marked as outdated.

@github-actions

Copy link
Copy Markdown
📦 Mac Build Complete for f526630
Download binary

@github-actions

github-actions Bot commented Jul 10, 2026

Copy link
Copy Markdown
📦 Linux Build Complete for f526630
Download binary
Download Flatpak

@github-actions

Copy link
Copy Markdown
📦 Windows Build Complete for f526630
Download binary

@timon-schelling

timon-schelling commented Jul 10, 2026

Copy link
Copy Markdown
Member Author

!build desktop (Run ID 29065912212)

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2 issues found across 18 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="desktop/ui/src/dirs.rs">

<violation number="1" location="desktop/ui/src/dirs.rs:12">
P2: Replacing the panic with `tracing::error!` avoids crashing, but callers of `app_tmp_dir()` now have no way to know that directory creation failed. The function still returns the path as if it were valid, so downstream code may hit less-obvious IO failures later. Consider propagating the error by changing the return type to `io::Result<PathBuf>` (and updating `temp_dir_root()` accordingly), so callers can handle the failure explicitly.</violation>
</file>

<file name="desktop/ui/src/remote/spawn.rs">

<violation number="1" location="desktop/ui/src/remote/spawn.rs:256">
P2: Replacing `.expect()` with `?` here introduces a partial-startup risk: `InstanceReceivers` has already been consumed from the `HostHandle`, so if this or a subsequent thread spawn fails, earlier threads remain running while the caller gets no `shutdown_complete_receiver` and cannot call `start_instance` again (it would return `InstanceLimit`). Consider ensuring cleanup of already-spawned threads on error, or deferring `receivers.take()` until all spawns succeed.</violation>
</file>

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

Comment thread desktop/ui/src/remote/host.rs Outdated
Comment thread desktop/ui/src/dirs.rs

pub(crate) fn app_tmp_dir() -> PathBuf {
let path = std::env::temp_dir().join(APP_DIRECTORY_NAME);
if let Err(e) = fs::create_dir_all(&path) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Replacing the panic with tracing::error! avoids crashing, but callers of app_tmp_dir() now have no way to know that directory creation failed. The function still returns the path as if it were valid, so downstream code may hit less-obvious IO failures later. Consider propagating the error by changing the return type to io::Result<PathBuf> (and updating temp_dir_root() accordingly), so callers can handle the failure explicitly.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At desktop/ui/src/dirs.rs, line 12:

<comment>Replacing the panic with `tracing::error!` avoids crashing, but callers of `app_tmp_dir()` now have no way to know that directory creation failed. The function still returns the path as if it were valid, so downstream code may hit less-obvious IO failures later. Consider propagating the error by changing the return type to `io::Result<PathBuf>` (and updating `temp_dir_root()` accordingly), so callers can handle the failure explicitly.</comment>

<file context>
@@ -9,8 +9,8 @@ const APP_DIRECTORY_NAME: &str = "Graphite";
 	let path = std::env::temp_dir().join(APP_DIRECTORY_NAME);
-	if !path.exists() {
-		fs::create_dir_all(&path).unwrap_or_else(|_| panic!("Failed to create directory at {path:?}"));
+	if let Err(e) = fs::create_dir_all(&path) {
+		tracing::error!("Failed to create temp directory at {path:?}: {e}");
 	}
</file context>

std::thread::Builder::new()
.name("cef-frames".to_string())
.spawn(move || crate::frames::receive::plane_receiver_loop(receiver, consumer))
.map_err(|e| UiError::Bootstrap(format!("failed to spawn the frame receiver thread: {e}")))?;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Replacing .expect() with ? here introduces a partial-startup risk: InstanceReceivers has already been consumed from the HostHandle, so if this or a subsequent thread spawn fails, earlier threads remain running while the caller gets no shutdown_complete_receiver and cannot call start_instance again (it would return InstanceLimit). Consider ensuring cleanup of already-spawned threads on error, or deferring receivers.take() until all spawns succeed.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At desktop/ui/src/remote/spawn.rs, line 256:

<comment>Replacing `.expect()` with `?` here introduces a partial-startup risk: `InstanceReceivers` has already been consumed from the `HostHandle`, so if this or a subsequent thread spawn fails, earlier threads remain running while the caller gets no `shutdown_complete_receiver` and cannot call `start_instance` again (it would return `InstanceLimit`). Consider ensuring cleanup of already-spawned threads on error, or deferring `receivers.take()` until all spawns succeed.</comment>

<file context>
@@ -247,7 +253,7 @@ pub(crate) fn start_instance(handle: &HostHandle, surface: FrameSurface, events:
 			.name("cef-frames".to_string())
 			.spawn(move || crate::frames::receive::plane_receiver_loop(receiver, consumer))
-			.expect("Failed to spawn CEF frame receiver thread");
+			.map_err(|e| UiError::Bootstrap(format!("failed to spawn the frame receiver thread: {e}")))?;
 	}
 
</file context>

@github-actions

Copy link
Copy Markdown
📦 Mac Build Complete for 24c5cb2
Download binary

@github-actions

github-actions Bot commented Jul 10, 2026

Copy link
Copy Markdown
📦 Linux Build Complete for 24c5cb2
Download binary
Download Flatpak

@github-actions

Copy link
Copy Markdown
📦 Windows Build Complete for 24c5cb2
Download binary

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant