-
-
Save LCamel/c073f13bd7994afe8e646c2592570b24 to your computer and use it in GitHub Desktop.
xpra
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| cp -rL /usr/share/xpra $HOME/xpra_copy | |
| sed -i 's/getboolparam("swap_keys", Utilities\.isMacOS())/getboolparam("swap_keys", false)/' \ | |
| "$HOME/xpra_copy/www/index.html" | |
| xpra start --bind-tcp=0.0.0.0:8080 --html=$HOME/xpra_copy/www --start=emacs-lucid |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/bash | |
| set -euo pipefail | |
| WWW_SRC="/usr/share/xpra/www" | |
| XPRA_OVR="$HOME/.local/share/xpra" | |
| WWW_DST="$XPRA_OVR/www" | |
| # Prepare overlay: symlink everything, copy only the files we patch | |
| rm -rf "$XPRA_OVR" | |
| mkdir -p "$WWW_DST/js" | |
| # Top-level: symlink all except files we need to patch | |
| for item in "$WWW_SRC"/*; do | |
| name=$(basename "$item") | |
| case "$name" in | |
| index.html|connect.html|js) ;; # handle separately | |
| *) ln -s "$item" "$WWW_DST/$name" ;; | |
| esac | |
| done | |
| # js/: symlink all except Client.js (and its compressed variants) | |
| for item in "$WWW_SRC"/js/*; do | |
| name=$(basename "$item") | |
| case "$name" in | |
| Client.js|Client.js.*) ;; # skip compressed variants too | |
| *) ln -s "$item" "$WWW_DST/js/$name" ;; | |
| esac | |
| done | |
| # Copy the 3 files we need to patch | |
| cp "$WWW_SRC/index.html" "$WWW_DST/index.html" | |
| cp "$WWW_SRC/connect.html" "$WWW_DST/connect.html" | |
| cp "$WWW_SRC/js/Client.js" "$WWW_DST/js/Client.js" | |
| # Patch swap_keys defaults to false (even on Mac) | |
| sed -i 's/getboolparam("swap_keys", Utilities\.isMacOS())/getboolparam("swap_keys", false)/' \ | |
| "$WWW_DST/index.html" | |
| sed -i '/Utilities\.isMacOS()/{N;/swap_keys/{N;d;}}' \ | |
| "$WWW_DST/connect.html" | |
| sed -i 's/this\.swap_keys = Utilities\.isMacOS()/this.swap_keys = false/' \ | |
| "$WWW_DST/js/Client.js" | |
| # http-headers is resolved as www_dir/../http-headers (server_core.py:599) | |
| ln -s /usr/share/xpra/http-headers "$XPRA_OVR/http-headers" | |
| # Use XPRA_RESOURCES_DIR so --html=on finds our overlay first | |
| export XPRA_RESOURCES_DIR="$XPRA_OVR" | |
| xpra start \ | |
| --bind-tcp=0.0.0.0:8080 \ | |
| --html=on \ | |
| --start=emacs-lucid |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| ❯ 幫我分析一下 為什麼 xpra.sh 本來用簡單的 copy 不行, 但是現在用 copy + symlink 就可以? | |
| ● Read 1 file (ctrl+o to expand) | |
| ● 這是一個很好的問題。讓我分析腳本的結構來解釋。 | |
| 核心問題:預壓縮檔案 (pre-compressed variants) | |
| xpra 的 web server 會針對每個檔案提供預壓縮版本(.gz, .br)。當瀏覽器發送 Accept-Encoding: gzip, br 時,server 優先送出壓縮版。 | |
| 如果「簡單 copy」是指 cp -r 整個目錄再 sed | |
| cp -r /usr/share/xpra/www → overlay/www/ | |
| sed -i ... overlay/www/index.html | |
| sed -i ... overlay/www/js/Client.js | |
| 問題在於: | |
| - sed 只改了 Client.js(未壓縮版) | |
| - Client.js.gz 和 Client.js.br 仍然是原版內容 | |
| - 瀏覽器支援 gzip → server 送出 Client.js.gz → 你的 patch 完全沒生效 | |
| 為什麼 symlink + copy 能解決 | |
| 關鍵在第 24-28 行: | |
| case "$name" in | |
| Client.js|Client.js.*) ;; # ← 刻意跳過壓縮版! | |
| *) ln -s "$item" "$WWW_DST/js/$name" ;; | |
| esac | |
| 這個做法的效果是: | |
| ┌─────────────────┬───────────────────────┬─────────────────────┐ | |
| │ 檔案 │ overlay 裡的狀態 │ 結果 │ | |
| ├─────────────────┼───────────────────────┼─────────────────────┤ | |
| │ Client.js │ 實體複製 + sed 修改過 │ 有 patch │ | |
| ├─────────────────┼───────────────────────┼─────────────────────┤ | |
| │ Client.js.gz │ 不存在 │ server 找不到壓縮版 │ | |
| ├─────────────────┼───────────────────────┼─────────────────────┤ | |
| │ Client.js.br │ 不存在 │ server 找不到壓縮版 │ | |
| ├─────────────────┼───────────────────────┼─────────────────────┤ | |
| │ Utilities.js │ symlink → 原版 │ 原樣提供 │ | |
| ├─────────────────┼───────────────────────┼─────────────────────┤ | |
| │ Utilities.js.gz │ symlink → 原版 │ 原樣提供 │ | |
| └─────────────────┴───────────────────────┴─────────────────────┘ | |
| 因為壓縮版 不存在於 overlay 目錄,xpra 的 web server 被迫 fallback 到未壓縮的 Client.js — 也就是你改過的版本。 | |
| 第二個關鍵:http-headers | |
| 第 43-44 行也很重要: | |
| # http-headers is resolved as www_dir/../http-headers (server_core.py:599) | |
| ln -s /usr/share/xpra/http-headers "$XPRA_OVR/http-headers" | |
| xpra 的 server_core.py 會去 www/ 的上層目錄找 http-headers。如果只是單純 copy www/ 到自訂路徑,上層不會有 http-headers,可能導致 | |
| server 啟動失敗或回應缺少必要的 HTTP headers。 | |
| 總結 | |
| 「簡單 copy」失敗的根本原因是 壓縮版檔案覆蓋了你的 patch。Symlink + copy 的策略是: | |
| 1. Symlink — 大部分不需改的檔案直接 symlink,零成本引用原版(含壓縮版) | |
| 2. Copy — 只複製要改的 3 個檔案 | |
| 3. 排除壓縮版 — 刻意不 symlink 被 patch 檔案的 .gz/.br,強迫 server 送出未壓縮的修改版 | |
| 4. 補上 http-headers — symlink 確保 server 能找到必要的 HTTP header 設定 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment