Browse Source

and another one

xdw 2 months ago
parent
commit
fdeb5ce76d
1 changed files with 93 additions and 17 deletions
  1. 93 17
      server/index.ts

+ 93 - 17
server/index.ts

@@ -146,34 +146,110 @@ async function libreofficeWinId(): Promise<string> {
   return run("xdotool", ["search", "--name", "LibreOffice Impress"]);
 }
 
+// Navigate via UNO PresentationController (slideshow mode)
+// or fall back to xdotool if not in slideshow
+function pyUnoNav(direction: "next" | "prev" | "start" | "end"): Promise<string> {
+  const actions: Record<string, string> = {
+    next: `
+        if hasattr(controller, 'gotoNextSlide'):
+            controller.gotoNextSlide()
+        elif hasattr(controller, 'gotoNextEffect'):
+            controller.gotoNextEffect()
+        else:
+            raise Exception("no next method on controller")
+    `,
+    prev: `
+        if hasattr(controller, 'gotoPreviousSlide'):
+            controller.gotoPreviousSlide()
+        elif hasattr(controller, 'gotoPreviousEffect'):
+            controller.gotoPreviousEffect()
+        else:
+            raise Exception("no prev method on controller")
+    `,
+    start: `
+        pres = comp.Presentation
+        pres.start()
+        import time; time.sleep(1.2)
+        # re-fetch controller after slideshow starts
+        controller = comp.getCurrentController()
+    `,
+    end: `
+        if hasattr(controller, 'deactivate'):
+            controller.deactivate()
+        else:
+            pres = comp.Presentation
+            pres.end()
+    `,
+  };
+
+  return pyUno(`
+import sys, time
+try:
+    import uno
+    from com.sun.star.beans import PropertyValue
+    localCtx = uno.getComponentContext()
+    resolver = localCtx.ServiceManager.createInstanceWithContext(
+        "com.sun.star.bridge.UnoUrlResolver", localCtx)
+    ctx = resolver.resolve(
+        "uno:socket,host=localhost,port=2002;urp;StarOffice.ComponentContext")
+    smgr = ctx.ServiceManager
+    desktop = smgr.createInstanceWithContext("com.sun.star.frame.Desktop", ctx)
+    comp = desktop.getCurrentComponent()
+    controller = comp.getCurrentController()
+    print(f"[nav] controller type: {type(controller).__name__}", file=sys.stderr)
+    ${actions[direction]}
+    time.sleep(0.3)
+    # read position after nav
+    controller = comp.getCurrentController()
+    draw = comp.DrawPages
+    total = draw.Count
+    current = 0
+    if hasattr(controller, 'getCurrentSlideIndex'):
+        current = controller.getCurrentSlideIndex() + 1
+        print(f"[nav] slideshow mode after ${direction}, index={current}", file=sys.stderr)
+    elif hasattr(controller, 'getCurrentPage'):
+        page = controller.getCurrentPage()
+        for i in range(draw.Count):
+            if draw.getByIndex(i) == page:
+                current = i + 1
+                break
+        print(f"[nav] editor mode after ${direction}, index={current}", file=sys.stderr)
+    print(f"{current}/{total}")
+except Exception as e:
+    import traceback
+    print(f"[nav] error: {e}", file=sys.stderr)
+    traceback.print_exc(file=sys.stderr)
+    print("0/0")
+`);
+}
+
 const LinuxDriver: Driver = {
   async next() {
-    const wid = (await libreofficeWinId()).split("\n")[0].trim();
-    await run("xdotool", ["key", "--window", wid, "Right"]);
-    await Bun.sleep(300);
-    return LinuxDriver.status();
+    console.log("[linux] next: navigating via UNO");
+    const raw = await pyUnoNav("next");
+    console.log(`[linux] next raw: "${raw}"`);
+    return parseSlide(raw);
   },
 
   async prev() {
-    const wid = (await libreofficeWinId()).split("\n")[0].trim();
-    await run("xdotool", ["key", "--window", wid, "Left"]);
-    await Bun.sleep(300);
-    return LinuxDriver.status();
+    console.log("[linux] prev: navigating via UNO");
+    const raw = await pyUnoNav("prev");
+    console.log(`[linux] prev raw: "${raw}"`);
+    return parseSlide(raw);
   },
 
   async start() {
-    // F5 starts the slideshow from the beginning; Shift+F5 from current slide
-    const wid = (await libreofficeWinId()).split("\n")[0].trim();
-    await run("xdotool", ["key", "--window", wid, "shift+F5"]);
-    await Bun.sleep(1000);
-    return LinuxDriver.status();
+    console.log("[linux] start: starting presentation via UNO");
+    const raw = await pyUnoNav("start");
+    console.log(`[linux] start raw: "${raw}"`);
+    return parseSlide(raw);
   },
 
   async end() {
-    const wid = (await libreofficeWinId()).split("\n")[0].trim();
-    await run("xdotool", ["key", "--window", wid, "Escape"]);
-    await Bun.sleep(300);
-    const { total } = await LinuxDriver.status();
+    console.log("[linux] end: ending presentation via UNO");
+    const raw = await pyUnoNav("end");
+    console.log(`[linux] end raw: "${raw}"`);
+    const { total } = parseSlide(raw);
     return { current: 0, total };
   },