mirror of
https://github.com/agent0ai/agent-zero.git
synced 2026-05-19 07:59:34 +00:00
Fix Desktop cursor and canvas resize handoff
Make the embedded Xpra Desktop use the browser cursor as the only visible cursor by suppressing the shadow pointer overlay and pointer-position renderer without blocking pointer input. Prefer the active Office host iframe when choosing the Desktop frame, then force resize recovery during modal-to-canvas docking so the Xpra desktop, window, and canvas refill the canvas after handoff.
This commit is contained in:
parent
74dcb32814
commit
2f5f98521d
2 changed files with 76 additions and 0 deletions
|
|
@ -28,11 +28,24 @@ export default async function registerOfficeSurface(canvas) {
|
|||
icon: "desktop_windows",
|
||||
order: 20,
|
||||
modalPath: "/plugins/_office/webui/main.html",
|
||||
async beginDockHandoff() {
|
||||
const office = globalThis.Alpine?.store?.("office");
|
||||
office?.beforeDesktopHostHandoff?.();
|
||||
},
|
||||
async finishDockHandoff(payload = {}) {
|
||||
const office = globalThis.Alpine?.store?.("office");
|
||||
if (payload.opened !== false) office?.afterDesktopHostShown?.({ source: "dock" });
|
||||
},
|
||||
async cancelDockHandoff() {
|
||||
const office = globalThis.Alpine?.store?.("office");
|
||||
office?.cancelDesktopHostHandoff?.();
|
||||
},
|
||||
async open(payload = {}) {
|
||||
const panel = await waitForElement('[data-surface-id="office"] .office-panel');
|
||||
const office = globalThis.Alpine?.store?.("office");
|
||||
await office?.onMount?.(panel, { mode: "canvas" });
|
||||
await office?.onOpen?.(payload);
|
||||
office?.afterDesktopHostShown?.({ source: payload?.source || "canvas" });
|
||||
},
|
||||
async close(payload = {}) {
|
||||
const office = globalThis.Alpine?.store?.("office");
|
||||
|
|
|
|||
|
|
@ -1043,6 +1043,8 @@ const model = {
|
|||
|
||||
desktopFrame(preferred = null) {
|
||||
if (this.isUsableDesktopFrame(preferred)) return preferred;
|
||||
const rootFrame = this._root?.querySelector?.("[data-office-desktop-frame]");
|
||||
if (this.isUsableDesktopFrame(rootFrame)) return rootFrame;
|
||||
const frames = this.desktopFrames();
|
||||
return frames
|
||||
.filter((frame) => this.isUsableDesktopFrame(frame))
|
||||
|
|
@ -1077,6 +1079,34 @@ const model = {
|
|||
}
|
||||
},
|
||||
|
||||
afterDesktopHostShown() {
|
||||
if (!this.hasOfficialOffice()) return;
|
||||
this._desktopResizeKey = "";
|
||||
this._desktopResizeSuspended = false;
|
||||
this._desktopResizePending = false;
|
||||
this.restoreDesktopFrames();
|
||||
this.requestDesktopViewportSync({ force: true, frame: this.desktopFrame() });
|
||||
for (const delay of [720, 1280]) {
|
||||
globalThis.setTimeout(() => {
|
||||
this.requestDesktopViewportSync({ force: true, frame: this.desktopFrame() });
|
||||
}, delay);
|
||||
}
|
||||
},
|
||||
|
||||
beforeDesktopHostHandoff() {
|
||||
this.stopDesktopResizeObserver();
|
||||
this.stopXpraDesktopPrime();
|
||||
this._desktopResizeKey = "";
|
||||
this._desktopResizeSuspended = true;
|
||||
this._desktopResizePending = true;
|
||||
},
|
||||
|
||||
cancelDesktopHostHandoff() {
|
||||
this._desktopResizeSuspended = false;
|
||||
this._desktopResizePending = false;
|
||||
this.requestDesktopViewportSync({ force: true, frame: this.desktopFrame() });
|
||||
},
|
||||
|
||||
onDesktopFrameLoaded(event = null) {
|
||||
if (event?.target?.getAttribute?.("src") === "about:blank") return;
|
||||
this.error = "";
|
||||
|
|
@ -1267,6 +1297,7 @@ const model = {
|
|||
const client = remoteWindow.client;
|
||||
if (!client) return false;
|
||||
this.installXpraDesktopClientPatches(remoteWindow, client);
|
||||
this.installXpraDesktopCursorPatches(remoteWindow, remoteDocument, client);
|
||||
this.installXpraDesktopKeyboardBridge(frame, remoteWindow, remoteDocument, client);
|
||||
const container = client.container || remoteDocument?.querySelector?.("#screen");
|
||||
if (!container) return false;
|
||||
|
|
@ -1439,6 +1470,11 @@ const model = {
|
|||
.windowbuttons {
|
||||
display: none !important;
|
||||
}
|
||||
#shadow_pointer {
|
||||
display: none !important;
|
||||
visibility: hidden !important;
|
||||
opacity: 0 !important;
|
||||
}
|
||||
.window,
|
||||
.window.border,
|
||||
.window.desktop,
|
||||
|
|
@ -1470,6 +1506,33 @@ const model = {
|
|||
remoteDocument.head?.appendChild(style);
|
||||
},
|
||||
|
||||
installXpraDesktopCursorPatches(remoteWindow, remoteDocument, client) {
|
||||
if (!remoteWindow || !remoteDocument || !client) return;
|
||||
const hideShadowPointer = () => {
|
||||
const pointer = remoteDocument.getElementById?.("shadow_pointer");
|
||||
pointer?.style?.setProperty("display", "none", "important");
|
||||
pointer?.style?.setProperty("visibility", "hidden", "important");
|
||||
pointer?.style?.setProperty("opacity", "0", "important");
|
||||
};
|
||||
hideShadowPointer();
|
||||
|
||||
const pointerPacket = remoteWindow.PACKET_TYPES?.pointer_position || "pointer-position";
|
||||
if (!client.__a0XpraDesktopCursorPatched) {
|
||||
if (typeof client._process_pointer_position === "function") {
|
||||
client.__a0OriginalProcessPointerPosition = client._process_pointer_position;
|
||||
}
|
||||
client._process_pointer_position = function patchedProcessPointerPosition(packet) {
|
||||
hideShadowPointer();
|
||||
this.__a0LastPointerPosition = packet;
|
||||
return false;
|
||||
};
|
||||
client.__a0XpraDesktopCursorPatched = true;
|
||||
}
|
||||
if (client.packet_handlers && pointerPacket) {
|
||||
client.packet_handlers[pointerPacket] = client._process_pointer_position;
|
||||
}
|
||||
},
|
||||
|
||||
installXpraDesktopFramePatches(remoteWindow, remoteDocument) {
|
||||
if (!remoteWindow || !remoteDocument) return;
|
||||
remoteWindow.__a0XpraDesktopFramePatches ||= {};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue