|
|
@@ -249,6 +249,70 @@ except Exception as e:
|
|
|
},
|
|
|
};
|
|
|
|
|
|
+// ─── Linux: LibreOffice process manager ──────────────────────────────────────
|
|
|
+// Prompts the user to pick a presentation file via zenity (GTK file dialog),
|
|
|
+// launches LibreOffice with the UNO socket listener, and re-prompts when
|
|
|
+// the process exits.
|
|
|
+
|
|
|
+const UNO_PORT = 2002;
|
|
|
+let libreofficeProc: ReturnType<typeof Bun.spawn> | null = null;
|
|
|
+
|
|
|
+async function pickFile(): Promise<string | null> {
|
|
|
+ try {
|
|
|
+ const result = await run("zenity", [
|
|
|
+ "--file-selection",
|
|
|
+ "--title=Open Presentation",
|
|
|
+ ]);
|
|
|
+ return result || null;
|
|
|
+ } catch {
|
|
|
+ // zenity not available — fall back to terminal prompt
|
|
|
+ process.stdout.write("Enter path to presentation file: ");
|
|
|
+ for await (const line of console) {
|
|
|
+ return line.trim() || null;
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+async function launchLibreOffice(filePath: string): Promise<void> {
|
|
|
+ console.log(`Opening: ${filePath}`);
|
|
|
+ libreofficeProc = Bun.spawn([
|
|
|
+ "libreoffice",
|
|
|
+ `--accept=socket,host=localhost,port=${UNO_PORT};urp;StarOffice.ServiceManager`,
|
|
|
+ "--impress",
|
|
|
+ filePath,
|
|
|
+ ], { stdout: "inherit", stderr: "inherit" });
|
|
|
+
|
|
|
+ // Wait for UNO socket to become available (up to 10s)
|
|
|
+ for (let i = 0; i < 20; i++) {
|
|
|
+ await Bun.sleep(500);
|
|
|
+ try {
|
|
|
+ const status = await LinuxDriver.status();
|
|
|
+ if (status.total > 0) break;
|
|
|
+ } catch { /* not ready yet */ }
|
|
|
+ }
|
|
|
+
|
|
|
+ broadcast({ event: "presentation", status: "opened", file: filePath.split("/").pop() });
|
|
|
+
|
|
|
+ // Watch for process exit, then re-prompt
|
|
|
+ libreofficeProc.exited.then(async () => {
|
|
|
+ console.log("LibreOffice closed.");
|
|
|
+ broadcast({ event: "presentation", status: "closed" });
|
|
|
+ libreofficeProc = null;
|
|
|
+ await promptAndLaunch();
|
|
|
+ });
|
|
|
+}
|
|
|
+
|
|
|
+async function promptAndLaunch(): Promise<void> {
|
|
|
+ const file = await pickFile();
|
|
|
+ if (!file) {
|
|
|
+ console.log("No file selected. Waiting... (clients will be notified when a file is opened)");
|
|
|
+ broadcast({ event: "presentation", status: "none" });
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ await launchLibreOffice(file);
|
|
|
+}
|
|
|
+
|
|
|
// ─── Select driver based on platform ─────────────────────────────────────────
|
|
|
|
|
|
const driver: Driver = IS_LINUX ? LinuxDriver : WindowsDriver;
|
|
|
@@ -333,3 +397,7 @@ const server = Bun.serve({
|
|
|
});
|
|
|
|
|
|
console.log(`PPT Remote Server listening on ws://0.0.0.0:${PORT}`);
|
|
|
+
|
|
|
+// On Linux, prompt to open a presentation immediately
|
|
|
+if (IS_LINUX) promptAndLaunch();
|
|
|
+else console.log("Make sure PowerPoint is open with a presentation before connecting.");
|