diff --git a/home/roles/communication/default.nix b/home/roles/communication/default.nix index ea09995..106c06b 100644 --- a/home/roles/communication/default.nix +++ b/home/roles/communication/default.nix @@ -20,7 +20,7 @@ in pkgs.element-desktop # Re-enabled in 25.11 after security issues were resolved pkgs.fluffychat - pkgs.nextcloud-talk-desktop + pkgs.custom.nextcloud-talk-desktop ]; }; } diff --git a/packages/default.nix b/packages/default.nix index 495543a..8741ddc 100644 --- a/packages/default.nix +++ b/packages/default.nix @@ -6,4 +6,5 @@ mcrcon-rbw = pkgs.callPackage ./mcrcon-rbw {}; rclone-torbox-setup = pkgs.callPackage ./rclone-torbox-setup {}; pi-coding-agent = pkgs.callPackage ./pi-coding-agent {}; + nextcloud-talk-desktop = pkgs.callPackage ./nextcloud-talk-desktop {}; } diff --git a/packages/nextcloud-talk-desktop/default.nix b/packages/nextcloud-talk-desktop/default.nix new file mode 100644 index 0000000..8cb82de --- /dev/null +++ b/packages/nextcloud-talk-desktop/default.nix @@ -0,0 +1,60 @@ +# Patched Nextcloud Talk Desktop with Wayland screen sharing support +# Applies the core change from upstream draft PR #1022: +# https://github.com/nextcloud/talk-desktop/pull/1022 +# +# Patches the webpack bundle in app.asar to add setDisplayMediaRequestHandler +# with useSystemPicker: true, enabling native PipeWire/portal-based +# screen sharing on Wayland (Sway, Hyprland, etc.) +{ lib +, nextcloud-talk-desktop +, nodejs +, asar +}: + +nextcloud-talk-desktop.overrideAttrs (old: { + pname = "nextcloud-talk-desktop-patched"; + + nativeBuildInputs = (old.nativeBuildInputs or []) ++ [ asar nodejs ]; + + # Patch the asar after the main installPhase creates the output + postFixup = (old.postFixup or "") + '' + echo "Patching app.asar for Wayland screen sharing..." + ASAR_PATH="$out/opt/Nextcloud Talk-linux-x64/resources/app.asar" + + WORK=$(mktemp -d) + asar extract "$ASAR_PATH" "$WORK/app" + + # In the webpack bundle: + # session = l, desktopCapturer = a, app = n + # We inject setDisplayMediaRequestHandler right after n.whenReady().then((async()=>{ + # useSystemPicker: true makes Electron use the native system picker + # (PipeWire/xdg-desktop-portal on Wayland) + node -e " + const fs = require('fs'); + const p = '$WORK/app/.webpack/main/index.js'; + let c = fs.readFileSync(p, 'utf8'); + + if (c.includes('setDisplayMediaRequestHandler')) { + console.log('Already patched'); + process.exit(0); + } + + const marker = 'n.whenReady().then((async()=>{'; + const idx = c.indexOf(marker); + if (idx === -1) { + console.error('ERROR: Could not find whenReady marker in webpack bundle'); + process.exit(1); + } + + // Inject after the marker + const injection = 'l.defaultSession.setDisplayMediaRequestHandler(async(e,t)=>{const s=await a.getSources({types:[\"screen\",\"window\"]});s.length>0?t({video:s[0]}):t({})},{useSystemPicker:!0});'; + + c = c.slice(0, idx + marker.length) + injection + c.slice(idx + marker.length); + fs.writeFileSync(p, c, 'utf8'); + console.log('Successfully patched main bundle for Wayland screen sharing'); + " + + asar pack "$WORK/app" "$ASAR_PATH" + rm -rf "$WORK" + ''; +})