#!/bin/env bash

# Makes `waydroid show-full-ui` integrate nicely with KDE by disabling KDE gestures and
# reacting to screen rotation. Not tested with multi_windows.
#
# Run this script when signed into a wayland session, and not as root (don't use sudo).
# Re-run every time you change resolution or scaling.
#
# The Lineage OS boot animation will no longer be centered as a result of this script.
#
# IMPORTANT
# Mouse support in Waydroid gets broken by this. I believe it's because I'm marking the
# window fullscreen in KDE and re-positioning it. Touch works as expected.
# Find `waydroid.fullScreen = true` in this script and remove it if this is an issue for
# you. I haven't tried it since I only use the touch screen for Waydroid. No fullscreen
# means that KDE gestures will react to swipes, and panels are revealed when the cursor
# touches the edges of the screen.

if ! [[ -x $(command -v jq) ]]; then
	echo "This command requires jq."
	exit 1
fi

# No reason to let the user wait for granting sudo permission
sudo true

echo
echo "Fullscreen Waydroid on KDE"
echo

MONITORS=$(kscreen-doctor --json)

if [[ -z $MONITORS ]]; then
	echo
	echo "kscreen-doctor failed. This is usually a temporary thing, try running this program again a few times."
	echo
	exit 1
fi

MONITORS_COUNT=$(echo "$MONITORS" | jq '.outputs | length')
SELECTED_MONITOR_ID=1

if [[ $MONITORS_COUNT > 1 ]]; then
	kscreen-doctor -o | sed G
	echo
	echo "What monitor is going to render Waydroid? Enter its \"Output: {number}\""

	while true; do
		read -p "Output: " SELECTED_MONITOR_ID
		if [[ $SELECTED_MONITOR_ID -gt 0 && $SELECTED_MONITOR_ID -le $MONITORS_COUNT ]]; then
			break
		fi
		echo "That output doesn't exist."
	done
fi

SELECTED_MONITOR=$(echo "$MONITORS" | jq '.outputs[] | select(.id == $monitorId)' --argjson monitorId $SELECTED_MONITOR_ID)
WIDTH=$(echo "$SELECTED_MONITOR" | jq '.size.width')
HEIGHT=$(echo "$SELECTED_MONITOR" | jq '.size.height')
SCALE=$(echo "$SELECTED_MONITOR" | jq '.scale')
MAX_SIZE=$(($WIDTH > $HEIGHT ? $WIDTH : $HEIGHT))
WINDOW_SIZE=$(awk "BEGIN {print int(($MAX_SIZE/$SCALE) + 0.5)}")

echo
echo "Starting Waydroid and setting props. Expect a few retries."
echo

waydroid session start &
sleep 2
# This prop is necessary for KDE fullscreen. Something prevents the Waydroid UI from rendering without it.
waydroid prop set persist.waydroid.use_subsurface true
waydroid prop set persist.waydroid.width $WINDOW_SIZE
waydroid prop set persist.waydroid.height $WINDOW_SIZE

echo
echo "Writing script that reacts to device orientation and sets Waydroid's resolution accordingly."
echo

sudo tee /sbin/waydroid-set-resolution << EOF
#!/bin/env bash
set -e

WIDTH=$WIDTH
HEIGHT=$HEIGHT

function set_resolution {
        if ! waydroid status | grep -q "Session:.*RUNNING"; then
                return
        fi

        case \$1 in
                normal|bottom-up)
                        waydroid shell wm size \${WIDTH}x\${HEIGHT};;
                left-up|right-up)
                        waydroid shell wm size \${HEIGHT}x\${WIDTH};;
        esac
}

while IFS='$\n' read -r line; do
        rotation="\$(echo \$line | sed -En "s/.*(normal|left-up|right-up|bottom-up).*/\1/p")"
        [[ ! -z \$rotation ]] && set_resolution \$rotation
done < <(stdbuf -oL monitor-sensor --accel)
EOF

sudo chmod +x /sbin/waydroid-set-resolution

echo
echo "Creating systemd service that starts the script above."
echo

sudo tee /etc/systemd/system/waydroid-set-resolution.service << EOF
[Unit]
Description=Change Waydroid resolution when device is rotated.
After=iio-sensor-proxy.service waydroid-container.service

[Service]
ExecStart=/sbin/waydroid-set-resolution
Restart=always

[Install]
WantedBy=graphical.target
EOF

sudo systemctl enable waydroid-set-resolution
sudo systemctl start waydroid-set-resolution

echo
echo "Writing KWin script that re-positions the Waydroid window when orientation is changed."
echo

sudo mkdir -p /usr/share/kwin/scripts/waydroid-fullscreen/contents

sudo tee /usr/share/kwin/scripts/waydroid-fullscreen/metadata.json << EOF
{
        "KPackageStructure": "KWin/Script",
        "KPlugin": {
                "Authors": [{ "Name": "Jan Sommer" }],
		"Description": "Run Waydroid in fullscreen (to disable KDE edge gestures). Requires waydroid-set-resolution.",
                "Icon": "waydroid",
                "Id": "waydroid-fullscreen",
                "License": "Public Domain",
                "Name": "Waydroid Fullscreen"
        },
        "X-Plasma-API": "javascript",
        "X-Plasma-MainScript": "main.js"
}
EOF

echo

sudo tee /usr/share/kwin/scripts/waydroid-fullscreen/contents/main.js << EOF
let waydroid = undefined

function reposition() {
    if (!waydroid)
        return
    const ps = workspace.clientArea(KWin.PrimaryScreenArea, workspace.activeScreen, 0)
    const orientation = ps.width > ps.height ? "landscape" : "portrait"
    const geom = Object.assign({}, waydroid.frameGeometry)
    if (orientation === "landscape") {
        geom.y = -Math.round((waydroid.height - ps.height) / 2)
        geom.x = 0
    } else {
        geom.y = 0
        geom.x = -Math.round((waydroid.width - ps.width) / 2)
    }
    waydroid.frameGeometry = geom
}

workspace.clientAdded.connect(client => {
    if (client.caption !== "Waydroid")
        return
    waydroid = client
    waydroid.fullScreen = true
    reposition()
    workspace.virtualScreenGeometryChanged.connect(reposition)
})

workspace.clientRemoved.connect(client => {
    if (client.caption !== "Waydroid")
        return
    workspace.virtualScreenGeometryChanged.disconnect(reposition)
    waydroid = undefined
})
EOF

waydroid session stop

echo
echo "Done."
echo "Remember to enable the Waydroid Fullscreen KWin script in settings."
echo