|
#!/bin/bash |
|
set -euo pipefail |
|
|
|
# virtual-slack: Manage Slack variants with separate config dirs and deep-link routing |
|
# |
|
# Usage: |
|
# virtual-slack create <number> |
|
# virtual-slack remove <number> |
|
# virtual-slack make-default <number> # make this variant handle slack:// links |
|
# virtual-slack restore-default # restore original Slack as handler |
|
|
|
SRC_BIN="/usr/lib/slack/slack" |
|
APP_DIR="$HOME/.local/share/applications" |
|
|
|
create_slack() { |
|
NUM="$1" |
|
DST_BIN="/usr/lib/slack/slack-$NUM" |
|
VAR_ROOT="$HOME/.local/share/virtual-slack-$NUM" |
|
VAR_BIN="$VAR_ROOT/bin" |
|
LAUNCHER="$VAR_ROOT/launch-slack-$NUM.sh" |
|
CONFIG_DIR="$HOME/.config-$NUM" |
|
DESKTOP_FILE="$APP_DIR/slack-$NUM.desktop" |
|
|
|
echo "[1/6] Copying Slack binary to $DST_BIN ..." |
|
sudo cp -rp "$SRC_BIN" "$DST_BIN" |
|
|
|
echo "[2/6] Patching window class string ..." |
|
if sudo grep -aq $'\x00browser-window\x00' "$DST_BIN"; then |
|
sudo sed -i 's/\x00browser-window\x00/\x00browser-windox\x00/g' "$DST_BIN" |
|
else |
|
echo "Note: 'browser-window' marker not found; skipping patch." |
|
fi |
|
|
|
echo "[3/6] Creating per-variant shims ..." |
|
mkdir -p "$VAR_BIN" |
|
|
|
SYS_XDG_OPEN="$(command -v xdg-open || true)" |
|
SYS_GIO="$(command -v gio || true)" |
|
[ -z "$SYS_XDG_OPEN" ] && SYS_XDG_OPEN="/usr/bin/xdg-open" |
|
[ -z "$SYS_GIO" ] && SYS_GIO="/usr/bin/gio" |
|
|
|
cat > "$VAR_BIN/xdg-open" <<'EOF' |
|
#!/bin/sh |
|
# Ensure child apps (browsers etc.) use normal user config, not the virtual Slack's config. |
|
unset XDG_CONFIG_HOME |
|
exec /usr/bin/xdg-open "$@" |
|
EOF |
|
chmod +x "$VAR_BIN/xdg-open" |
|
|
|
cat > "$VAR_BIN/gio" <<'EOF' |
|
#!/bin/sh |
|
unset XDG_CONFIG_HOME |
|
exec /usr/bin/gio "$@" |
|
EOF |
|
chmod +x "$VAR_BIN/gio" |
|
|
|
[ "$SYS_XDG_OPEN" != "/usr/bin/xdg-open" ] && sed -i "s|/usr/bin/xdg-open|$SYS_XDG_OPEN|g" "$VAR_BIN/xdg-open" |
|
[ "$SYS_GIO" != "/usr/bin/gio" ] && sed -i "s|/usr/bin/gio|$SYS_GIO|g" "$VAR_BIN/gio" |
|
|
|
echo "[4/6] Creating launcher ..." |
|
mkdir -p "$VAR_ROOT" |
|
cat > "$LAUNCHER" <<EOF |
|
#!/bin/sh |
|
export PATH="$VAR_BIN:\$PATH" |
|
export XDG_CONFIG_HOME="$CONFIG_DIR" |
|
exec "$DST_BIN" --gtk-version=3 -s "\$@" |
|
EOF |
|
chmod +x "$LAUNCHER" |
|
|
|
echo "[5/6] Writing desktop entry ..." |
|
mkdir -p "$APP_DIR" |
|
cat > "$DESKTOP_FILE" <<EOF |
|
[Desktop Entry] |
|
Name=Slack $NUM |
|
Comment=Slack using alternate config directory $NUM |
|
Exec=$LAUNCHER %u |
|
Icon=slack |
|
Type=Application |
|
Terminal=false |
|
Categories=Network;Chat; |
|
StartupWMClass=browser-windox |
|
MimeType=x-scheme-handler/slack; |
|
EOF |
|
|
|
echo "[6/6] Refreshing menus ..." |
|
command -v update-desktop-database >/dev/null 2>&1 && update-desktop-database "$APP_DIR" || true |
|
command -v kbuildsycoca5 >/dev/null 2>&1 && kbuildsycoca5 || true |
|
|
|
echo "✅ Slack $NUM installed (virtual-slack-$NUM)." |
|
echo "" |
|
echo "Tip: To login into workspaces using this slack instance," |
|
echo " you need to make this instance to be able to capture" |
|
echo " slack:// links by runnning:" |
|
echo "" |
|
echo " virtual-slack make-default $NUM" |
|
echo "" |
|
echo " Once you have logged in successfully, you need to restore the" |
|
echo " original slack handler by running:" |
|
echo "" |
|
echo " virtual-slack restore-default" |
|
echo "" |
|
} |
|
|
|
remove_slack() { |
|
NUM="$1" |
|
DST_BIN="/usr/lib/slack/slack-$NUM" |
|
VAR_ROOT="$HOME/.local/share/virtual-slack-$NUM" |
|
DESKTOP_FILE="$APP_DIR/slack-$NUM.desktop" |
|
CONFIG_DIR="$HOME/.config-$NUM" |
|
|
|
echo "[1/4] Removing cloned binary..." |
|
[ -f "$DST_BIN" ] && sudo rm -f "$DST_BIN" && echo "Deleted $DST_BIN" || echo "Not found: $DST_BIN" |
|
|
|
echo "[2/4] Removing virtual-slack runtime dir..." |
|
[ -d "$VAR_ROOT" ] && rm -rf "$VAR_ROOT" && echo "Deleted $VAR_ROOT" || echo "Not found: $VAR_ROOT" |
|
|
|
echo "[3/4] Removing desktop entry..." |
|
[ -f "$DESKTOP_FILE" ] && rm -f "$DESKTOP_FILE" && echo "Deleted $DESKTOP_FILE" || echo "Not found: $DESKTOP_FILE" |
|
|
|
echo "[4/4] Removing config dir..." |
|
[ -d "$CONFIG_DIR" ] && rm -rf "$CONFIG_DIR" && echo "Deleted $CONFIG_DIR" || echo "Not found: $CONFIG_DIR" |
|
|
|
command -v update-desktop-database >/dev/null 2>&1 && update-desktop-database "$APP_DIR" || true |
|
command -v kbuildsycoca5 >/dev/null 2>&1 && kbuildsycoca5 || true |
|
|
|
echo "✅ Slack $NUM fully removed." |
|
} |
|
|
|
make_default() { |
|
NUM="$1" |
|
DESKTOP_FILE="slack-$NUM.desktop" |
|
echo "Setting $DESKTOP_FILE as default handler for slack:// ..." |
|
xdg-mime default "$DESKTOP_FILE" x-scheme-handler/slack |
|
update_desktop_cache |
|
echo "✅ Now, browser OAuth deep links (slack://) will open in Slack $NUM." |
|
} |
|
|
|
restore_default() { |
|
echo "Restoring original Slack as default handler for slack:// ..." |
|
xdg-mime default slack.desktop x-scheme-handler/slack |
|
update_desktop_cache |
|
echo "✅ Restored original Slack as the handler." |
|
} |
|
|
|
update_desktop_cache() { |
|
command -v update-desktop-database >/dev/null 2>&1 && update-desktop-database "$APP_DIR" || true |
|
command -v kbuildsycoca5 >/dev/null 2>&1 && kbuildsycoca5 || true |
|
} |
|
|
|
# --- Main --- |
|
if [ $# -lt 1 ]; then |
|
echo "Usage: $0 {create|remove|make-default|restore-default} [number]" |
|
exit 1 |
|
fi |
|
|
|
CMD="$1" |
|
case "$CMD" in |
|
create) |
|
[ $# -lt 2 ] && { echo "Usage: $0 create <number>"; exit 1; } |
|
create_slack "$2" |
|
;; |
|
remove) |
|
[ $# -lt 2 ] && { echo "Usage: $0 remove <number>"; exit 1; } |
|
remove_slack "$2" |
|
;; |
|
make-default) |
|
[ $# -lt 2 ] && { echo "Usage: $0 make-default <number>"; exit 1; } |
|
make_default "$2" |
|
;; |
|
restore-default) |
|
restore_default |
|
;; |
|
*) |
|
echo "Unknown command: $CMD" |
|
echo "Usage: $0 {create|remove|make-default|restore-default} [number]" |
|
exit 1 |
|
;; |
|
esac |