summarylogtreecommitdiffstats
path: root/wechat-universal.sh
blob: 186c6b0350bafc9efabf9faccc9b80369d50c961 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
#!/bin/bash
# Data folder setup
# If user has declared a custom data dir, no need to query xdg for documents dir, but always resolve that to absolute path
if [[ "${WECHAT_DATA_DIR}" ]]; then
    WECHAT_DATA_DIR=$(readlink -f -- "${WECHAT_DATA_DIR}")
else
    XDG_DOCUMENTS_DIR="${XDG_DOCUMENTS_DIR:-$(xdg-user-dir DOCUMENTS)}"
    if [[ -z "${XDG_DOCUMENTS_DIR}" ]]; then
        echo 'Error: Failed to get XDG_DOCUMENTS_DIR, refuse to continue'
        exit 1
    fi
    WECHAT_DATA_DIR="${XDG_DOCUMENTS_DIR}/WeChat_Data"
fi
WECHAT_FILES_DIR="${WECHAT_DATA_DIR}/xwechat_files"
WECHAT_HOME_DIR="${WECHAT_DATA_DIR}/home"

# Runtime folder setup
XDG_RUNTIME_DIR="${XDG_RUNTIME_DIR:-$(xdg-user-dir RUNTIME)}"
if [[ -z "${XDG_RUNTIME_DIR}" ]]; then
    echo 'Error: Failed to get XDG_RUNTIME_DIR, refuse to continue'
    exit 1
fi
if [[ -z "${XAUTHORITY}" ]]; then
    echo 'Warning: No XAUTHORITY set, runnning in no-X environment? Generating it'
    export XAUTHORITY=$(mktemp "${XDG_RUNTIME_DIR}"/xauth_XXXXXX)
    echo "Info: Generated XAUTHORITY at '${XAUTHORITY}'"
fi

env_add() {
    BWRAP_ENV_APPEND+=(--setenv "$1" "$2")
}
BWRAP_ENV_APPEND=()
# wechat-universal only supports xcb
env_add QT_QPA_PLATFORM xcb
env_add QT_AUTO_SCREEN_SCALE_FACTOR 1
env_add PATH "/sandbox:${PATH}"

case "${XMODIFIERS}" in 
    *@im=fcitx*)
        echo "Workaround for fcitx applied"
        env_add QT_IM_MODULE fcitx
        env_add GTK_IM_MODULE fcitx    
        ;;
    *@im=ibus*)
        echo "Workaround for ibus applied"
        env_add QT_IM_MODULE ibus
        env_add GTK_IM_MODULE ibus
        env_add IBUS_USE_PORTAL 1
        ;;
esac

BWRAP_DEV_BINDS=()
for DEV_NODE in /dev/{nvidia{-uvm,ctl,*[0-9]},video*[0-9]}; do
    [[ -e "${DEV_NODE}" ]] && BWRAP_DEV_BINDS+=(--dev-bind "${DEV_NODE}"{,})
done

# Custom exposed folders
echo "Hint: Custom binds could be declared in '~/.config/wechat-universal/binds.list', each line a path, absolute or relative to your HOME"
BWRAP_CUSTOM_BINDS=()
if [[ -f ~/.config/wechat-universal/binds.list ]]; then
    mapfile -t CUSTOM_BINDS < ~/.config/wechat-universal/binds.list
    cd ~ # 7Ji: two chdir.3 should be cheaper than a lot of per-dir calculation
    for CUSTOM_BIND in "${CUSTOM_BINDS[@]}"; do
        CUSTOM_BIND=$(readlink -f -- "${CUSTOM_BIND}")
        echo "Custom bind: '${CUSTOM_BIND}'"
        BWRAP_CUSTOM_BINDS+=(--bind "${CUSTOM_BIND}"{,})
    done
    cd - > /dev/null
fi

mkdir -p "${WECHAT_FILES_DIR}" "${WECHAT_HOME_DIR}"
ln -snf "${WECHAT_FILES_DIR}" "${WECHAT_HOME_DIR}/xwechat_files"

BWRAP_ARGS=(
    # Drop privileges
    --unshare-all
    --share-net
    --cap-drop ALL
    --die-with-parent

    # /usr
    --ro-bind /usr{,}
    --symlink usr/lib /lib
    --symlink usr/lib /lib64
    --symlink usr/bin /bin
    --symlink usr/bin /sbin
    --bind /usr/bin/{true,lsblk}

    # /sandbox
    --ro-bind /{usr/lib/flatpak-xdg-utils,sandbox}/xdg-open
    --ro-bind /{usr/share/wechat-universal/usr/bin,sandbox}/dde-file-manager

    # /dev
    --dev /dev
    --dev-bind /dev/dri{,}
    --tmpfs /dev/shm

    # /proc
    --proc /proc

    # /etc
    --ro-bind /etc/machine-id{,}
    --ro-bind /etc/passwd{,}
    --ro-bind /etc/nsswitch.conf{,}
    --ro-bind /etc/resolv.conf{,}
    --ro-bind /etc/localtime{,}
    --ro-bind-try /etc/fonts{,}

    # /sys
    --dir /sys/dev # hack for Intel / AMD graphics, mesa calling virtual nodes needs /sys/dev being 0755
    --ro-bind /sys/dev/char{,}
    --ro-bind /sys/devices{,}

    # /tmp
    --tmpfs /tmp

    # /opt
    --ro-bind /opt/wechat-universal{,}
    --ro-bind-try /opt/lol{,} # Loong New World (WeChat) on Loong Old World (LoongArchLinux)

    # license fixups in various places
    --ro-bind {/usr/share/wechat-universal,}/usr/lib/license
    --ro-bind {/usr/share/wechat-universal,}/etc/lsb-release

    # /home
    --bind "${WECHAT_HOME_DIR}" "${HOME}"
    --bind "${WECHAT_FILES_DIR}"{,}
    --bind-try "${HOME}/.pki"{,}
    --ro-bind-try "${HOME}/.fontconfig"{,}
    --ro-bind-try "${HOME}/.fonts"{,}
    --ro-bind-try "${HOME}/.config/fontconfig"{,}
    --ro-bind-try "${HOME}/.local/share/fonts"{,}
    --ro-bind-try "${HOME}/.icons"{,}
    --ro-bind-try "${HOME}/.local/share/.icons"{,}

    # /run
    --dev-bind /run/dbus{,}
    --ro-bind /run/systemd/userdb{,}
    --ro-bind-try "${XAUTHORITY}"{,}
    --ro-bind "${XDG_RUNTIME_DIR}/bus"{,}
    --ro-bind "${XDG_RUNTIME_DIR}/pulse"{,}
)

exec bwrap "${BWRAP_ARGS[@]}" "${BWRAP_CUSTOM_BINDS[@]}" "${BWRAP_DEV_BINDS[@]}" "${BWRAP_ENV_APPEND[@]}" /opt/wechat-universal/wechat "$@"
echo "Error: Failed to exec bwrap, rerun this script with 'bash -x $0' to show the full command history"
exit 1