Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions apps/desktop/src/app/DesktopLifecycle.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ function makeDesktopWindowLayer(
handleBackendReady: () => Effect.void,
handleBackendNotReady: Effect.void,
flushMainWindowBounds: input.flushMainWindowBounds ?? Effect.void,
preparePreviewTeardown: Effect.void,
dispatchMenuAction: () => Effect.void,
zoomMain: () => Effect.void,
syncAppearance: Effect.void,
Expand Down
39 changes: 28 additions & 11 deletions apps/desktop/src/app/DesktopLifecycle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,10 +84,15 @@ function addScopedListener<Args extends ReadonlyArray<unknown>>(
const requestDesktopShutdownAndWait = Effect.fn("desktop.lifecycle.requestShutdownAndWait")(
function* (
afterBoundsFlush: Effect.Effect<void> = Effect.void,
): Effect.fn.Return<void, never, DesktopShutdown.DesktopShutdown | DesktopWindow.DesktopWindow> {
): Effect.fn.Return<
void,
DesktopWindow.DesktopWindowError,
DesktopShutdown.DesktopShutdown | DesktopWindow.DesktopWindow
> {
const shutdown = yield* DesktopShutdown.DesktopShutdown;
const desktopWindow = yield* DesktopWindow.DesktopWindow;
yield* desktopWindow.flushMainWindowBounds;
yield* desktopWindow.preparePreviewTeardown;
Comment thread
macroscopeapp[bot] marked this conversation as resolved.
yield* afterBoundsFlush;
yield* shutdown.request;
yield* shutdown.awaitComplete;
Expand All @@ -114,7 +119,7 @@ function handleBeforeQuit(
}

event.preventDefault();
void runEffect(
const quit = runEffect(
Effect.gen(function* () {
const state = yield* DesktopState.DesktopState;
const electronWindow = yield* ElectronWindow.ElectronWindow;
Expand All @@ -128,15 +133,27 @@ function handleBeforeQuit(
),
);
}).pipe(Effect.withSpan("desktop.lifecycle.beforeQuit")),
).finally(() => {
markQuitAllowed();
void runEffect(
Effect.gen(function* () {
const electronApp = yield* ElectronApp.ElectronApp;
yield* electronApp.quit;
}).pipe(Effect.withSpan("desktop.lifecycle.quitAfterShutdown")),
);
});
);
void quit.then(
() => {
markQuitAllowed();
void runEffect(
Effect.gen(function* () {
const electronApp = yield* ElectronApp.ElectronApp;
yield* electronApp.quit;
}).pipe(Effect.withSpan("desktop.lifecycle.quitAfterShutdown")),
);
},
(error) => {
void runEffect(
Effect.gen(function* () {
const state = yield* DesktopState.DesktopState;
yield* Ref.set(state.quitting, false);
yield* logLifecycleError("preview teardown blocked desktop shutdown", { error });
Comment thread
macroscopeapp[bot] marked this conversation as resolved.
Outdated
}).pipe(Effect.withSpan("desktop.lifecycle.quitBlocked")),
);
},
);
Comment thread
cursor[bot] marked this conversation as resolved.
}

function quitFromSignal(
Expand Down
1 change: 1 addition & 0 deletions apps/desktop/src/backend/DesktopBackendPool.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ function makePoolLayer(
handleBackendReady: () => Effect.void,
handleBackendNotReady: Effect.void,
flushMainWindowBounds: Effect.void,
preparePreviewTeardown: Effect.void,
dispatchMenuAction: () => Effect.die("unexpected menu action"),
zoomMain: () => Effect.die("unexpected zoom"),
syncAppearance: Effect.void,
Expand Down
2 changes: 2 additions & 0 deletions apps/desktop/src/ipc/channels.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ export const SSH_PASSWORD_PROMPT_CANCELLED_RESULT = "ssh-password-prompt-cancell
export const PREVIEW_CREATE_TAB_CHANNEL = "desktop:preview-create-tab";
export const PREVIEW_CLOSE_TAB_CHANNEL = "desktop:preview-close-tab";
export const PREVIEW_REGISTER_WEBVIEW_CHANNEL = "desktop:preview-register-webview";
export const PREVIEW_PREPARE_WEBVIEW_REMOVAL_CHANNEL = "desktop:preview-prepare-webview-removal";
export const PREVIEW_NAVIGATE_CHANNEL = "desktop:preview-navigate";
export const PREVIEW_GO_BACK_CHANNEL = "desktop:preview-go-back";
export const PREVIEW_GO_FORWARD_CHANNEL = "desktop:preview-go-forward";
Expand Down Expand Up @@ -83,3 +84,4 @@ export const PREVIEW_RECORDING_SAVE_CHANNEL = "desktop:preview-recording-save";
export const PREVIEW_RECORDING_FRAME_CHANNEL = "desktop:preview-recording-frame";
export const PREVIEW_STATE_CHANGE_CHANNEL = "desktop:preview-state-change";
export const PREVIEW_POINTER_EVENT_CHANNEL = "desktop:preview-pointer-event";
export const PREVIEW_CAPTURE_RECOVERY_CHANNEL = "desktop:preview-capture-recovery";
32 changes: 22 additions & 10 deletions apps/desktop/src/ipc/methods/preview.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import {
DesktopPreviewConfigInputSchema,
DesktopPreviewNavigateInputSchema,
DesktopPreviewRecordingArtifactSchema,
DesktopPreviewRecordingSourceSchema,
DesktopPreviewRecordingSaveInputSchema,
DesktopPreviewRegisterWebviewInputSchema,
DesktopPreviewScreenshotArtifactSchema,
Expand Down Expand Up @@ -47,6 +46,9 @@ export const installPreviewEventForwarding = Effect.fn(
yield* manager.subscribePointerEvents((event) =>
electronWindow.sendAll(IpcChannels.PREVIEW_POINTER_EVENT_CHANNEL, event),
);
yield* manager.subscribeCaptureRecoveries((event) =>
electronWindow.sendAll(IpcChannels.PREVIEW_CAPTURE_RECOVERY_CHANNEL, event),
);
});

export const createTab = DesktopIpc.makeIpcMethod({
Expand Down Expand Up @@ -83,6 +85,19 @@ export const registerWebview = DesktopIpc.makeIpcMethod({
}),
});

export const prepareWebviewRemoval = DesktopIpc.makeIpcMethod({
channel: IpcChannels.PREVIEW_PREPARE_WEBVIEW_REMOVAL_CHANNEL,
payload: DesktopPreviewRegisterWebviewInputSchema,
result: Schema.Void,
handler: Effect.fn("desktop.ipc.preview.prepareWebviewRemoval")(function* ({
tabId,
webContentsId,
}) {
const manager = yield* PreviewManager.PreviewManager;
yield* manager.prepareWebviewRemoval(tabId, webContentsId);
}),
});

export const navigate = DesktopIpc.makeIpcMethod({
channel: IpcChannels.PREVIEW_NAVIGATE_CHANNEL,
payload: DesktopPreviewNavigateInputSchema,
Expand Down Expand Up @@ -174,15 +189,11 @@ export const cancelPickElement = tabMethod(
"desktop.ipc.preview.cancelPickElement",
(manager, tabId) => manager.cancelPickElement(tabId),
);
export const startRecording = DesktopIpc.makeIpcMethod({
channel: IpcChannels.PREVIEW_RECORDING_START_CHANNEL,
payload: DesktopPreviewTabInputSchema,
result: DesktopPreviewRecordingSourceSchema,
handler: Effect.fn("desktop.ipc.preview.startRecording")(function* ({ tabId }) {
const manager = yield* PreviewManager.PreviewManager;
return yield* manager.startRecording(tabId);
}),
});
export const startRecording = tabMethod(
IpcChannels.PREVIEW_RECORDING_START_CHANNEL,
"desktop.ipc.preview.startRecording",
(manager, tabId) => manager.startRecording(tabId),
);
export const stopRecording = tabMethod(
IpcChannels.PREVIEW_RECORDING_STOP_CHANNEL,
"desktop.ipc.preview.stopRecording",
Expand Down Expand Up @@ -378,6 +389,7 @@ export const methods = [
createTab,
closeTab,
registerWebview,
prepareWebviewRemoval,
navigate,
goBack,
goForward,
Expand Down
24 changes: 24 additions & 0 deletions apps/desktop/src/preload.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type {
DesktopBridge,
DesktopPreviewCaptureRecovery,
DesktopPreviewPointerEvent,
DesktopPreviewRecordingFrame,
DesktopPreviewTabState,
Expand Down Expand Up @@ -178,6 +179,11 @@ contextBridge.exposeInMainWorld("desktopBridge", {
closeTab: (tabId) => ipcRenderer.invoke(IpcChannels.PREVIEW_CLOSE_TAB_CHANNEL, { tabId }),
registerWebview: (tabId, webContentsId) =>
ipcRenderer.invoke(IpcChannels.PREVIEW_REGISTER_WEBVIEW_CHANNEL, { tabId, webContentsId }),
prepareWebviewRemoval: (tabId, webContentsId) =>
ipcRenderer.invoke(IpcChannels.PREVIEW_PREPARE_WEBVIEW_REMOVAL_CHANNEL, {
tabId,
webContentsId,
}),
navigate: (tabId, url) =>
ipcRenderer.invoke(IpcChannels.PREVIEW_NAVIGATE_CHANNEL, { tabId, url }),
goBack: (tabId) => ipcRenderer.invoke(IpcChannels.PREVIEW_GO_BACK_CHANNEL, { tabId }),
Expand Down Expand Up @@ -275,5 +281,23 @@ contextBridge.exposeInMainWorld("desktopBridge", {
return () =>
ipcRenderer.removeListener(IpcChannels.PREVIEW_POINTER_EVENT_CHANNEL, wrappedListener);
},
onCaptureRecovery: (listener) => {
const wrappedListener = (_event: Electron.IpcRendererEvent, recovery: unknown) => {
if (typeof recovery !== "object" || recovery === null) return;
const value = recovery as Partial<DesktopPreviewCaptureRecovery>;
if (
typeof value.tabId !== "string" ||
typeof value.webContentsId !== "number" ||
!Number.isInteger(value.webContentsId) ||
value.webContentsId <= 0
) {
return;
}
listener(value as DesktopPreviewCaptureRecovery);
};
ipcRenderer.on(IpcChannels.PREVIEW_CAPTURE_RECOVERY_CHANNEL, wrappedListener);
return () =>
ipcRenderer.removeListener(IpcChannels.PREVIEW_CAPTURE_RECOVERY_CHANNEL, wrappedListener);
},
},
} satisfies DesktopBridge);
Loading
Loading