Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
17 changes: 14 additions & 3 deletions apps/code/src/main/deep-links.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@ import { app } from "electron";
import { container } from "./di/container";
import { MAIN_TOKENS } from "./di/tokens";
import type { DeepLinkService } from "./services/deep-link/service";
import { logger } from "./utils/logger";
import { focusMainWindow } from "./window";

const log = logger.scope("deep-links");

let pendingDeepLinkUrl: string | null = null;

function getDeepLinkService(): DeepLinkService {
Expand All @@ -18,29 +21,37 @@ export function registerDeepLinkHandlers(): void {
// Handle deep link URLs on macOS
app.on("open-url", (event, url) => {
event.preventDefault();
log.info("open-url event received", { url, appReady: app.isReady() });

if (!app.isReady()) {
pendingDeepLinkUrl = url;
return;
}

getDeepLinkService().handleUrl(url);
focusMainWindow();
focusMainWindow("open-url deep link");
});

// Handle deep link URLs on Windows/Linux (second instance sends URL via command line)
app.on("second-instance", (_event, commandLine) => {
log.info("second-instance event received", {
commandLine: commandLine.join(" "),
argCount: commandLine.length,
});

const url = commandLine.find(
(arg) =>
arg.startsWith("posthog-code://") ||
arg.startsWith("twig://") ||
arg.startsWith("array://"),
);
if (url) {
log.info("Deep link URL found in second-instance args", { url });
getDeepLinkService().handleUrl(url);
focusMainWindow("second-instance deep link");
} else {
log.warn("second-instance fired with no deep link URL, ignoring focus");
}

focusMainWindow();
});
}

Expand Down
1 change: 1 addition & 0 deletions apps/code/src/main/services/notification/service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export class NotificationService {
const notification = new Notification({ title, body, silent });

notification.on("click", () => {
log.info("Notification clicked, focusing window", { title, taskId });
const mainWindow = getMainWindow();
if (mainWindow) {
if (mainWindow.isMinimized()) {
Expand Down
1 change: 1 addition & 0 deletions apps/code/src/main/services/task-link/service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ export class TaskLinkService extends TypedEventEmitter<TaskLinkEvents> {
}

// Focus the window
log.info("Deep link focusing window", { taskId, taskRunId });
const mainWindow = getMainWindow();
if (mainWindow) {
if (mainWindow.isMinimized()) {
Expand Down
12 changes: 11 additions & 1 deletion apps/code/src/main/window.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,11 @@ import { buildApplicationMenu } from "./menu";
import { setMainWindowGetter } from "./trpc/context";
import { trpcRouter } from "./trpc/router";
import { isDevBuild } from "./utils/env";
import { logger } from "./utils/logger";
import { type WindowStateSchema, windowStateStore } from "./utils/store";

const log = logger.scope("window");

declare const MAIN_WINDOW_VITE_DEV_SERVER_URL: string | undefined;
declare const MAIN_WINDOW_VITE_NAME: string;

Expand Down Expand Up @@ -63,8 +66,15 @@ export function getMainWindow(): BrowserWindow | null {
return mainWindow;
}

export function focusMainWindow(): void {
export function focusMainWindow(reason: string): void {
if (mainWindow) {
log.info("focusMainWindow called", {
reason,
isMinimized: mainWindow.isMinimized(),
isFocused: mainWindow.isFocused(),
isVisible: mainWindow.isVisible(),
stack: new Error().stack,
});
if (mainWindow.isMinimized()) mainWindow.restore();
mainWindow.focus();
}
Expand Down
Loading