#!/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