authorgravatar for lucenz@proton.meSimone <lucenz@proton.me> 2026-09-17 12:47:53+02:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2026-09-17 16:17:53+05:30
log1ab2dfb5a7bd2996f79407b5d02cae6132a7626c
tree731c3bd9ecba12d6414a1e40ae33676aed719172
parent298f8c95cd7c20ea7943a431f22e836fa637457b
signature Signed by PGP key B5690EEEBB952194

fix(desktop): keep preview picking active across subframe navigation (#9741)

Co-authored-by: Simone <185146821+Lucenx9@users.noreply.github.com> Co-authored-by: shivam <91240327+shivamhwp@users.noreply.github.com>

2 files changed, 21 insertions(+), 9 deletions(-)

apps/desktop/src/preview/Manager.test.ts+18-3
...@@ -3506,7 +3506,10 @@ describe("PreviewManager", () => {...@@ -3506,7 +3506,10 @@ describe("PreviewManager", () => {
3506 listeners.set(event, listener);3506 listeners.set(event, listener);
3507 }),3507 }),
3508 once: vi.fn((event: string, listener: (...args: unknown[]) => void) => {3508 once: vi.fn((event: string, listener: (...args: unknown[]) => void) => {
3509 listeners.set(event, listener);3509 listeners.set(event, (...args) => {
3510 listeners.delete(event);
3511 listener(...args);
3512 });
3510 }),3513 }),
3511 off: vi.fn(),3514 off: vi.fn(),
3512 ipc: { on: vi.fn(), off: vi.fn(), removeListener: vi.fn() },3515 ipc: { on: vi.fn(), off: vi.fn(), removeListener: vi.fn() },
...@@ -3528,11 +3531,23 @@ describe("PreviewManager", () => {...@@ -3528,11 +3531,23 @@ describe("PreviewManager", () => {
3528 const pick = yield* manager.pickElement("tab_1").pipe(Effect.forkChild);3531 const pick = yield* manager.pickElement("tab_1").pipe(Effect.forkChild);
3529 yield* Effect.yieldNow;3532 yield* Effect.yieldNow;
35303533
3531 listeners.get("did-start-navigation")?.({}, "about:blank", false, false);3534 listeners.get("did-start-navigation")?.({
3535 url: "about:blank",
3536 isSameDocument: false,
3537 isMainFrame: false,
3538 frame: null,
3539 });
3532 yield* Effect.yieldNow;3540 yield* Effect.yieldNow;
3533 expect(pick.pollUnsafe()).toBeUndefined();3541 expect(pick.pollUnsafe()).toBeUndefined();
35343542
3535 listeners.get("did-start-navigation")?.({}, "https://example.com/next", false, true);3543 listeners.get("did-start-navigation")?.({
3544 url: "https://example.com/next",
3545 isSameDocument: false,
3546 isMainFrame: true,
3547 frame: null,
3548 });
3549 yield* Effect.yieldNow;
3550 expect(pick.pollUnsafe()).toBeDefined();
3536 expect(yield* Fiber.join(pick)).toBeNull();3551 expect(yield* Fiber.join(pick)).toBeNull();
3537 }),3552 }),
3538 ),3553 ),
apps/desktop/src/preview/Manager.ts+3-6
...@@ -2566,12 +2566,9 @@ const makeNativeOperations = Effect.fn("PreviewManager.makeOperations")(function...@@ -2566,12 +2566,9 @@ const makeNativeOperations = Effect.fn("PreviewManager.makeOperations")(function
2566 };2566 };
2567 const onDestroyed = () => settle(null);2567 const onDestroyed = () => settle(null);
2568 const onNavigated = (2568 const onNavigated = (
2569 _event: Electron.Event,2569 event: Electron.Event<Electron.WebContentsDidStartNavigationEventParams>,
2570 _url: string,
2571 _isInPlace: boolean,
2572 isMainFrame: boolean,
2573 ) => {2570 ) => {
2574 if (isMainFrame) settle(null);2571 if (event.isMainFrame) settle(null);
2575 };2572 };
2576 const registerPickElement = Effect.fn("PreviewManager.registerPickElement")(function* () {2573 const registerPickElement = Effect.fn("PreviewManager.registerPickElement")(function* () {
2577 // Two picks on one tab can overlap. Swap this session in and cancel2574 // Two picks on one tab can overlap. Swap this session in and cancel
...@@ -2592,7 +2589,7 @@ const makeNativeOperations = Effect.fn("PreviewManager.makeOperations")(function...@@ -2592,7 +2589,7 @@ const makeNativeOperations = Effect.fn("PreviewManager.makeOperations")(function
2592 yield* attempt({ operation: "pickElement.register", tabId, webContentsId: wc.id }, () => {2589 yield* attempt({ operation: "pickElement.register", tabId, webContentsId: wc.id }, () => {
2593 wc.ipc.on(ELEMENT_PICKED_CHANNEL, onMessage);2590 wc.ipc.on(ELEMENT_PICKED_CHANNEL, onMessage);
2594 wc.once("destroyed", onDestroyed);2591 wc.once("destroyed", onDestroyed);
2595 wc.once("did-start-navigation", onNavigated);2592 wc.on("did-start-navigation", onNavigated);
2596 if (!wc.isFocused()) wc.focus();2593 if (!wc.isFocused()) wc.focus();
2597 wc.send(START_PICK_CHANNEL, annotationTheme);2594 wc.send(START_PICK_CHANNEL, annotationTheme);
2598 });2595 });