From c84633bbd29762c7ace063ae06cc9bcc8ee6fa56 Mon Sep 17 00:00:00 2001 From: thekk1 Date: Sat, 27 Jul 2024 13:30:32 +0200 Subject: [PATCH 01/29] Add script to monitor and disconnect Bluetooth gamepads and corresponding Systemd service This is a workaround for #1289 and should be removed if there comes a native solution from https://github.com/ValveSoftware/steam-for-linux/issues/8678 - Added `bazzite-bluetooth-ds4-ds5-workaround` script to monitor PS4 and PS5 controllers - Script checks for connected gamepads, extracts their MAC addresses, and starts a monitoring process - The monitoring process listens for specific button combinations (Home + Triangle) to disconnect the gamepad - Includes cleanup functionality to stop monitoring processes for disconnected gamepads - Created Systemd service `bazzite-bluetooth-ds4-ds5-workaround.service` - Service description and dependencies defined in `[Unit]` section - `[Service]` section specifies script execution, restart policy, user, and group - `[Install]` section enables the service to start on boot - Added instructions to load, start, and enable the service - Included commands for reloading Systemd, starting the service, and enabling it on boot - Provided guidance on checking the service status and logs for troubleshooting Author: thekk1 Version: 1.0 --- Containerfile | 1 + ...zzite-bluetooth-ds4-ds5-workaround.service | 13 ++ .../bazzite-bluetooth-ds4-ds5-workaround | 170 ++++++++++++++++++ 3 files changed, 184 insertions(+) create mode 100644 system_files/desktop/shared/usr/lib/systemd/system/bazzite-bluetooth-ds4-ds5-workaround.service create mode 100755 system_files/desktop/shared/usr/libexec/bazzite-bluetooth-ds4-ds5-workaround diff --git a/Containerfile b/Containerfile index dbc2f3b98b..2209eb4da3 100644 --- a/Containerfile +++ b/Containerfile @@ -668,6 +668,7 @@ RUN rm -f /etc/profile.d/toolbox.sh && \ systemctl enable tailscaled.service && \ systemctl enable dev-hugepages1G.mount && \ systemctl disable joycond.service && \ + systemctl --global enable bazzite-bluetooth-ds4-ds5-workaround.service && \ systemctl --global enable bazzite-user-setup.service && \ systemctl --global enable podman.socket && \ systemctl --global enable systemd-tmpfiles-setup.service && \ diff --git a/system_files/desktop/shared/usr/lib/systemd/system/bazzite-bluetooth-ds4-ds5-workaround.service b/system_files/desktop/shared/usr/lib/systemd/system/bazzite-bluetooth-ds4-ds5-workaround.service new file mode 100644 index 0000000000..d03857023c --- /dev/null +++ b/system_files/desktop/shared/usr/lib/systemd/system/bazzite-bluetooth-ds4-ds5-workaround.service @@ -0,0 +1,13 @@ +[Unit] +Description=Disconnect DS4 and DS5 controller on shortcut HOME + triangle +After=network.target +ConditionFileIsExecutable=/usr/libexec/bazzite-bluetooth-ds4-ds5-workaround + +[Service] +Type=oneshot +ExecCondition=/usr/bin/systemctl is-enabled bluetooth.service +ExecStart=/usr/libexec/bazzite-bluetooth-ds4-ds5-workaround +TimeoutSec=10s + +[Install] +WantedBy=multi-user.target diff --git a/system_files/desktop/shared/usr/libexec/bazzite-bluetooth-ds4-ds5-workaround b/system_files/desktop/shared/usr/libexec/bazzite-bluetooth-ds4-ds5-workaround new file mode 100755 index 0000000000..3f18f7f5e7 --- /dev/null +++ b/system_files/desktop/shared/usr/libexec/bazzite-bluetooth-ds4-ds5-workaround @@ -0,0 +1,170 @@ +#!/bin/bash + +# Script Name: bazzite-bluetooth-ds4-ds5-workaround +# Author: https://github.com/thekk1 +# Version: 1.0 +# +# Related issues: +# https://github.com/ublue-os/bazzite/issues/1289 +# https://github.com/ValveSoftware/steam-for-linux/issues/8678 +# +# Description: +# This script monitors connected PS4 and PS5 gamepad devices and disconnects +# the Bluetooth connection if specific button combinations are detected (Home and Triangle buttons). +# The script handles background processes for each device and maintains a record of process IDs +# to ensure proper cleanup of processes associated with devices that are no longer present. +# +# This script should be removed if there is a native solution under one of the mentioned issues. +# +# Usage: +# ./disconnect_bt_gamepad.sh [-d] +# -d: Enable debug mode + +DEBUG=false +MONITOR_FILE="/var/tmp/monitored_devices.txt" +echo "" > $MONITOR_FILE + +# Check for the debug flag +while getopts "d" opt; do + case ${opt} in + d ) DEBUG=true ;; + \? ) echo "Usage: $0 [-d]" ;; + esac +done + +# Function to find gamepad devices (PS4 and PS5) +find_gamepad_devices() { + local devices=() + local base_path="/sys/class/input" + + for entry in "$base_path"/*; do + if [[ $(basename "$entry") == event* ]]; then + local device_path="$entry/device" + local uevent_path="$device_path/uevent" + + if [[ -f "$uevent_path" ]]; then + local devicename + devicename=$(grep "NAME" "$uevent_path" | cut -d'=' -f2 | tr -d '"') + if [[ "$devicename" == "Wireless Controller" || "$devicename" == "DualSense Wireless Controller" ]]; then + devices+=("$(basename "$entry")") + fi + fi + fi + done + echo "${devices[@]}" +} + +# Function to get MAC address from uevent file +get_mac_address_from_uevent() { + local device="$1" + local uniq_path="/sys/class/input/$device/device/uevent" + + if [[ -f "$uniq_path" ]]; then + local mac_address + mac_address=$(grep "UNIQ" "$uniq_path" | cut -d'=' -f2 | tr -d '"') + echo "$mac_address" + else + echo "" + fi +} + +# Function to monitor the gamepad and disconnect Bluetooth connection +monitor_gamepad() { + local device_path="$1" + local bluetooth_mac_address="$2" + local process_name="monitor_gamepad_$bluetooth_mac_address" + + $DEBUG && echo "Starting monitoring on device: $device_path" + + # Check if process is already running + if pgrep -f "$process_name" > /dev/null; then + $DEBUG && echo "Process for $bluetooth_mac_address is already running." + return + fi + + # Run the monitoring process with a specific process name + (cat "$device_path" | xxd -p -c 24 | awk -v mac="$bluetooth_mac_address" -v pname="$process_name" ' + BEGIN { home_pressed=0; triangle_pressed=0 } + { + event_part=substr($0,33); + if(substr(event_part,1,2)=="01") { + code=substr(event_part,5,4); + value=substr(event_part,9,2); + if((code=="3301" || code=="3c01") && value=="01") { + if(code=="3301") home_pressed=1; + if(code=="3c01") triangle_pressed=1; + if(home_pressed && triangle_pressed) { + system("bluetoothctl disconnect " mac); + home_pressed=0; + triangle_pressed=0; + } + } + } + }' & echo $! > "/var/tmp/$process_name.pid") > /dev/null 2>&1 + + $DEBUG && echo "Started monitoring process for $bluetooth_mac_address with process name $process_name." +} + +# Function to clean up processes +cleanup_processes() { + # List of currently monitored MAC addresses + local monitored_macs=$(cat "$MONITOR_FILE") + + # Iterate through all monitored MAC addresses + while IFS= read -r mac; do + process_name="monitor_gamepad_$mac" + pid_file="/var/tmp/${process_name}.pid" + + if [[ -f "$pid_file" ]]; then + pid=$(cat "$pid_file") + if ! ps -p "$pid" > /dev/null; then + $DEBUG && echo "Stopping process for $mac as it's no longer running." + pkill -f "$process_name" + rm -f "$pid_file" + # Remove the MAC address from the monitor file + sed -i "/$mac/d" "$MONITOR_FILE" + fi + else + $DEBUG && echo "No PID file found for $mac." + fi + done <<< "$monitored_macs" +} + +# Main loop of the script +while true; do + # Find currently connected gamepad devices + gamepad_devices=$(find_gamepad_devices) + + # Get current MAC addresses from the monitor file + current_macs=$(cat "$MONITOR_FILE") + + if [[ -z "$gamepad_devices" ]]; then + $DEBUG && echo "No PS4 or PS5 controllers found." + else + $DEBUG && echo "Found devices: $gamepad_devices" + # Convert the list of devices into an array + IFS=' ' read -r -a devices_array <<< "$gamepad_devices" + + # Loop over the found devices + for device in "${devices_array[@]}"; do + device_path="/dev/input/$device" + mac_address=$(get_mac_address_from_uevent "$device") + + if [[ -n "$mac_address" ]]; then + # Check if this device is already being monitored + if ! grep -q "$mac_address" "$MONITOR_FILE"; then + echo "$mac_address" >> "$MONITOR_FILE" + $DEBUG && echo "Monitoring device: $device_path" + monitor_gamepad "$device_path" "$mac_address" + fi + else + echo "No MAC address found for $device." + fi + done + fi + + # Clean up processes that are no longer needed + cleanup_processes + + sleep 5 # Wait before searching for new devices +done From bb1be24ad26f7a27d55e4b788184f02d462f340f Mon Sep 17 00:00:00 2001 From: thekk1 Date: Sat, 27 Jul 2024 17:29:37 +0200 Subject: [PATCH 02/29] Removed type=oneshot from service file, because this service should run all the time. --- .../bazzite-bluetooth-ds4-ds5-workaround.service | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/system_files/desktop/shared/usr/lib/systemd/system/bazzite-bluetooth-ds4-ds5-workaround.service b/system_files/desktop/shared/usr/lib/systemd/system/bazzite-bluetooth-ds4-ds5-workaround.service index d03857023c..1fd7bd084f 100644 --- a/system_files/desktop/shared/usr/lib/systemd/system/bazzite-bluetooth-ds4-ds5-workaround.service +++ b/system_files/desktop/shared/usr/lib/systemd/system/bazzite-bluetooth-ds4-ds5-workaround.service @@ -1,13 +1,15 @@ [Unit] Description=Disconnect DS4 and DS5 controller on shortcut HOME + triangle -After=network.target +After=bluetooth.target ConditionFileIsExecutable=/usr/libexec/bazzite-bluetooth-ds4-ds5-workaround [Service] -Type=oneshot +User=root ExecCondition=/usr/bin/systemctl is-enabled bluetooth.service -ExecStart=/usr/libexec/bazzite-bluetooth-ds4-ds5-workaround -TimeoutSec=10s +ExecStart=/bin/bash /usr/libexec/bazzite-bluetooth-ds4-ds5-workaround +Restart=on-failure +RestartSec=5 +TimeoutSec=5s [Install] WantedBy=multi-user.target From d87580f1c6fb45aba9a51457e718b58356ef64e1 Mon Sep 17 00:00:00 2001 From: thekk1 Date: Sat, 27 Jul 2024 22:02:33 +0200 Subject: [PATCH 03/29] Using /tmp instead of /var/tmp to avoid the need of root --- .../shared/usr/libexec/bazzite-bluetooth-ds4-ds5-workaround | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system_files/desktop/shared/usr/libexec/bazzite-bluetooth-ds4-ds5-workaround b/system_files/desktop/shared/usr/libexec/bazzite-bluetooth-ds4-ds5-workaround index 3f18f7f5e7..70b8ea63dc 100755 --- a/system_files/desktop/shared/usr/libexec/bazzite-bluetooth-ds4-ds5-workaround +++ b/system_files/desktop/shared/usr/libexec/bazzite-bluetooth-ds4-ds5-workaround @@ -21,7 +21,7 @@ # -d: Enable debug mode DEBUG=false -MONITOR_FILE="/var/tmp/monitored_devices.txt" +MONITOR_FILE="/tmp/monitored_devices.txt" echo "" > $MONITOR_FILE # Check for the debug flag From b8f4745f8c6352c1ac513e7a60f6567a580ff678 Mon Sep 17 00:00:00 2001 From: thekk1 Date: Sat, 27 Jul 2024 22:13:46 +0200 Subject: [PATCH 04/29] Changed script name in the usage description. --- .../shared/usr/libexec/bazzite-bluetooth-ds4-ds5-workaround | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system_files/desktop/shared/usr/libexec/bazzite-bluetooth-ds4-ds5-workaround b/system_files/desktop/shared/usr/libexec/bazzite-bluetooth-ds4-ds5-workaround index 70b8ea63dc..fe2917b230 100755 --- a/system_files/desktop/shared/usr/libexec/bazzite-bluetooth-ds4-ds5-workaround +++ b/system_files/desktop/shared/usr/libexec/bazzite-bluetooth-ds4-ds5-workaround @@ -17,7 +17,7 @@ # This script should be removed if there is a native solution under one of the mentioned issues. # # Usage: -# ./disconnect_bt_gamepad.sh [-d] +# ./bazzite-bluetooth-ds4-ds5-workaround [-d] # -d: Enable debug mode DEBUG=false From 0a025186fff0f1f4ef4a10b5f5b8b757dabd5fbc Mon Sep 17 00:00:00 2001 From: thekk1 Date: Sun, 28 Jul 2024 07:31:33 +0200 Subject: [PATCH 05/29] Fixed some problem with PID files --- .../libexec/bazzite-bluetooth-ds4-ds5-workaround | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/system_files/desktop/shared/usr/libexec/bazzite-bluetooth-ds4-ds5-workaround b/system_files/desktop/shared/usr/libexec/bazzite-bluetooth-ds4-ds5-workaround index fe2917b230..71cfbbb43c 100755 --- a/system_files/desktop/shared/usr/libexec/bazzite-bluetooth-ds4-ds5-workaround +++ b/system_files/desktop/shared/usr/libexec/bazzite-bluetooth-ds4-ds5-workaround @@ -2,7 +2,7 @@ # Script Name: bazzite-bluetooth-ds4-ds5-workaround # Author: https://github.com/thekk1 -# Version: 1.0 +# Version: 1.2 # # Related issues: # https://github.com/ublue-os/bazzite/issues/1289 @@ -22,7 +22,7 @@ DEBUG=false MONITOR_FILE="/tmp/monitored_devices.txt" -echo "" > $MONITOR_FILE +truncate -s 0 $MONITOR_FILE # Check for the debug flag while getopts "d" opt; do @@ -100,7 +100,7 @@ monitor_gamepad() { } } } - }' & echo $! > "/var/tmp/$process_name.pid") > /dev/null 2>&1 + }' & echo $! > "/tmp/$process_name.pid" & disown) > /dev/null 2>&1 $DEBUG && echo "Started monitoring process for $bluetooth_mac_address with process name $process_name." } @@ -113,7 +113,11 @@ cleanup_processes() { # Iterate through all monitored MAC addresses while IFS= read -r mac; do process_name="monitor_gamepad_$mac" - pid_file="/var/tmp/${process_name}.pid" + pid_file="/tmp/${process_name}.pid" + + if [[ -z "$mac" ]]; then + continue + fi if [[ -f "$pid_file" ]]; then pid=$(cat "$pid_file") @@ -158,7 +162,7 @@ while true; do monitor_gamepad "$device_path" "$mac_address" fi else - echo "No MAC address found for $device." + $DEBUG && echo "No MAC address found for $device." fi done fi From c347ed3d9e0960b707cf5145a3f90459b71f83ea Mon Sep 17 00:00:00 2001 From: Kyle Gospodnetich Date: Sat, 27 Jul 2024 22:40:28 -0700 Subject: [PATCH 06/29] Revert "fix: Remove pip installed packages and use newly made rpm packages, fixes python errors when layering some packages." This reverts commit 5ec9e555f8241214333cc28ec697033ae56dc52f. --- Containerfile | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Containerfile b/Containerfile index 9a4cb382c7..9b61350c3e 100644 --- a/Containerfile +++ b/Containerfile @@ -374,8 +374,9 @@ RUN --mount=type=cache,dst=/var/cache/rpm-ostree \ cockpit-navigator \ cockpit-storaged \ ydotool \ - lsb_release \ - yafti \ + lsb_release && \ + pip install --prefix=/usr topgrade && \ + rpm-ostree install \ ublue-update && \ mkdir -p /usr/etc/xdg/autostart && \ sed -i '1s/^/[include]\npaths = ["\/etc\/ublue-os\/topgrade.toml"]\n\n/' /usr/share/ublue-update/topgrade-user.toml && \ @@ -621,6 +622,7 @@ RUN rm -f /etc/profile.d/toolbox.sh && \ echo "import \"/usr/share/ublue-os/just/84-bazzite-virt.just\"" >> /usr/share/ublue-os/justfile && \ echo "import \"/usr/share/ublue-os/just/85-bazzite-image.just\"" >> /usr/share/ublue-os/justfile && \ echo "import \"/usr/share/ublue-os/just/90-bazzite-de.just\"" >> /usr/share/ublue-os/justfile && \ + pip install --prefix=/usr yafti && \ sed -i 's/stage/none/g' /etc/rpm-ostreed.conf && \ sed -i 's@enabled=1@enabled=0@g' /etc/yum.repos.d/_copr_ublue-os-akmods.repo && \ sed -i 's@enabled=1@enabled=0@g' /etc/yum.repos.d/_copr_kylegospo-bazzite.repo && \ From 5633fed57ac23ac783d05eef28e64e5d5658c72d Mon Sep 17 00:00:00 2001 From: Kyle Gospodnetich Date: Sun, 28 Jul 2024 02:09:46 -0700 Subject: [PATCH 07/29] chore: Match upstream --- Containerfile | 1 - 1 file changed, 1 deletion(-) diff --git a/Containerfile b/Containerfile index d351be7be8..0b7025b40a 100644 --- a/Containerfile +++ b/Containerfile @@ -623,7 +623,6 @@ RUN rm -f /etc/profile.d/toolbox.sh && \ echo "import \"/usr/share/ublue-os/just/84-bazzite-virt.just\"" >> /usr/share/ublue-os/justfile && \ echo "import \"/usr/share/ublue-os/just/85-bazzite-image.just\"" >> /usr/share/ublue-os/justfile && \ echo "import \"/usr/share/ublue-os/just/90-bazzite-de.just\"" >> /usr/share/ublue-os/justfile && \ - pip install --prefix=/usr yafti && \ sed -i 's/stage/none/g' /etc/rpm-ostreed.conf && \ sed -i 's@enabled=1@enabled=0@g' /etc/yum.repos.d/_copr_ublue-os-akmods.repo && \ sed -i 's@enabled=1@enabled=0@g' /etc/yum.repos.d/_copr_kylegospo-bazzite.repo && \ From b8f47bf6c4a89c70c16052d089b924810dd094e4 Mon Sep 17 00:00:00 2001 From: thekk1 Date: Sun, 28 Jul 2024 19:39:55 +0200 Subject: [PATCH 08/29] Minor performance improvement and fixed behavior bug. --- .../bazzite-bluetooth-ds4-ds5-workaround | 37 ++++++++++--------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/system_files/desktop/shared/usr/libexec/bazzite-bluetooth-ds4-ds5-workaround b/system_files/desktop/shared/usr/libexec/bazzite-bluetooth-ds4-ds5-workaround index 71cfbbb43c..87479bbdf3 100755 --- a/system_files/desktop/shared/usr/libexec/bazzite-bluetooth-ds4-ds5-workaround +++ b/system_files/desktop/shared/usr/libexec/bazzite-bluetooth-ds4-ds5-workaround @@ -2,7 +2,7 @@ # Script Name: bazzite-bluetooth-ds4-ds5-workaround # Author: https://github.com/thekk1 -# Version: 1.2 +# Version: 1.3 # # Related issues: # https://github.com/ublue-os/bazzite/issues/1289 @@ -37,17 +37,15 @@ find_gamepad_devices() { local devices=() local base_path="/sys/class/input" - for entry in "$base_path"/*; do - if [[ $(basename "$entry") == event* ]]; then - local device_path="$entry/device" - local uevent_path="$device_path/uevent" + for entry in "$base_path"/event*; do + local device_path="$entry/device" + local uevent_path="$device_path/uevent" - if [[ -f "$uevent_path" ]]; then - local devicename - devicename=$(grep "NAME" "$uevent_path" | cut -d'=' -f2 | tr -d '"') - if [[ "$devicename" == "Wireless Controller" || "$devicename" == "DualSense Wireless Controller" ]]; then - devices+=("$(basename "$entry")") - fi + if [[ -f "$uevent_path" ]]; then + local devicename + devicename=$(grep "NAME" "$uevent_path" | cut -d'=' -f2 | tr -d '"') + if [[ "$devicename" == "Wireless Controller" || "$devicename" == "DualSense Wireless Controller" ]]; then + devices+=("$(basename "$entry")") fi fi done @@ -87,14 +85,19 @@ monitor_gamepad() { BEGIN { home_pressed=0; triangle_pressed=0 } { event_part=substr($0,33); - if(substr(event_part,1,2)=="01") { + if(substr(event_part,1,4)=="0100") { code=substr(event_part,5,4); value=substr(event_part,9,2); - if((code=="3301" || code=="3c01") && value=="01") { - if(code=="3301") home_pressed=1; - if(code=="3c01") triangle_pressed=1; - if(home_pressed && triangle_pressed) { - system("bluetoothctl disconnect " mac); + if(code=="3301" || code=="3c01") { + if(value=="01") { + if(code=="3301") home_pressed=1; + if(code=="3c01") triangle_pressed=1; + if(home_pressed && triangle_pressed) { + system("bluetoothctl disconnect " mac); + home_pressed=0; + triangle_pressed=0; + } + } else { home_pressed=0; triangle_pressed=0; } From c829b76aed8073c35cc8ce5a0661807044c3c2c6 Mon Sep 17 00:00:00 2001 From: thekk1 Date: Mon, 29 Jul 2024 07:29:42 +0200 Subject: [PATCH 09/29] Fix for systems with multiple BT controllers. --- .../libexec/bazzite-bluetooth-ds4-ds5-workaround | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/system_files/desktop/shared/usr/libexec/bazzite-bluetooth-ds4-ds5-workaround b/system_files/desktop/shared/usr/libexec/bazzite-bluetooth-ds4-ds5-workaround index 87479bbdf3..9ffdd4aa3b 100755 --- a/system_files/desktop/shared/usr/libexec/bazzite-bluetooth-ds4-ds5-workaround +++ b/system_files/desktop/shared/usr/libexec/bazzite-bluetooth-ds4-ds5-workaround @@ -2,7 +2,7 @@ # Script Name: bazzite-bluetooth-ds4-ds5-workaround # Author: https://github.com/thekk1 -# Version: 1.3 +# Version: 1.4 # # Related issues: # https://github.com/ublue-os/bazzite/issues/1289 @@ -80,8 +80,11 @@ monitor_gamepad() { return fi + # Define the command to disconnect all controllers + disconnect_cmd="for controller in \$(bluetoothctl list | awk '/Controller/ {print \$2}'); do bluetoothctl select \$controller; bluetoothctl disconnect $bluetooth_mac_address; done" + # Run the monitoring process with a specific process name - (cat "$device_path" | xxd -p -c 24 | awk -v mac="$bluetooth_mac_address" -v pname="$process_name" ' + (cat "$device_path" 2>&1 | xxd -p -c 24 | awk -v mac="$bluetooth_mac_address" -v pname="$process_name" -v cmd="$disconnect_cmd" -v debug="$DEBUG" ' BEGIN { home_pressed=0; triangle_pressed=0 } { event_part=substr($0,33); @@ -93,7 +96,12 @@ monitor_gamepad() { if(code=="3301") home_pressed=1; if(code=="3c01") triangle_pressed=1; if(home_pressed && triangle_pressed) { - system("bluetoothctl disconnect " mac); + # Print a message before executing the disconnect command + if (debug == "true") { + print "Disconnect command issued for MAC address: " mac; + } + # Execute the disconnect command only once + system(cmd); home_pressed=0; triangle_pressed=0; } @@ -103,7 +111,7 @@ monitor_gamepad() { } } } - }' & echo $! > "/tmp/$process_name.pid" & disown) > /dev/null 2>&1 + }' >&1) & echo $! > "/tmp/$process_name.pid" & disown $DEBUG && echo "Started monitoring process for $bluetooth_mac_address with process name $process_name." } From c64447e773a2c21a969064baf856d8458ef7a216 Mon Sep 17 00:00:00 2001 From: thekk1 Date: Mon, 29 Jul 2024 19:16:45 +0200 Subject: [PATCH 10/29] Enable system service globally. --- Containerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/Containerfile b/Containerfile index 7f72bb5d7c..b5ee5e0be3 100644 --- a/Containerfile +++ b/Containerfile @@ -684,6 +684,7 @@ RUN rm -f /etc/profile.d/toolbox.sh && \ systemctl enable bazzite-hardware-setup.service && \ systemctl enable tailscaled.service && \ systemctl enable dev-hugepages1G.mount && \ + systemctl --global enable bazzite-bluetooth-ds4-ds5-workaround.service && \ systemctl --global enable bazzite-user-setup.service && \ systemctl --global enable podman.socket && \ systemctl --global enable systemd-tmpfiles-setup.service && \ From 7c0ab973293be6e81648f9b7577f458cb91db6de Mon Sep 17 00:00:00 2001 From: thekk1 Date: Mon, 29 Jul 2024 21:37:57 +0200 Subject: [PATCH 11/29] Use parsing multiple commands to bluetoothctl instead of call every single command. --- .../shared/usr/libexec/bazzite-bluetooth-ds4-ds5-workaround | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/system_files/desktop/shared/usr/libexec/bazzite-bluetooth-ds4-ds5-workaround b/system_files/desktop/shared/usr/libexec/bazzite-bluetooth-ds4-ds5-workaround index 9ffdd4aa3b..33e7819c7e 100755 --- a/system_files/desktop/shared/usr/libexec/bazzite-bluetooth-ds4-ds5-workaround +++ b/system_files/desktop/shared/usr/libexec/bazzite-bluetooth-ds4-ds5-workaround @@ -2,7 +2,7 @@ # Script Name: bazzite-bluetooth-ds4-ds5-workaround # Author: https://github.com/thekk1 -# Version: 1.4 +# Version: 1.5 # # Related issues: # https://github.com/ublue-os/bazzite/issues/1289 @@ -81,7 +81,7 @@ monitor_gamepad() { fi # Define the command to disconnect all controllers - disconnect_cmd="for controller in \$(bluetoothctl list | awk '/Controller/ {print \$2}'); do bluetoothctl select \$controller; bluetoothctl disconnect $bluetooth_mac_address; done" + disconnect_cmd="for controller in \$(bluetoothctl list | awk '/Controller/ {print \$2}'); do echo -e \"select \$controller\ndisconnect $bluetooth_mac_address\n\" | bluetoothctl; done" # Run the monitoring process with a specific process name (cat "$device_path" 2>&1 | xxd -p -c 24 | awk -v mac="$bluetooth_mac_address" -v pname="$process_name" -v cmd="$disconnect_cmd" -v debug="$DEBUG" ' From 5b0e61bb27d9fee4949e23632da80ce07567a81a Mon Sep 17 00:00:00 2001 From: Zeglius <33781398+Zeglius@users.noreply.github.com> Date: Tue, 30 Jul 2024 18:21:07 +0200 Subject: [PATCH 12/29] refactor: handle dualshock detection with udev rules --- ...ice => bazzite-bluetooth-ds4-ds5-workaround@.service} | 9 +++------ .../udev/rules.d/80-bazzite-ps-controller-sleep.rules | 3 +++ 2 files changed, 6 insertions(+), 6 deletions(-) rename system_files/desktop/shared/usr/lib/systemd/system/{bazzite-bluetooth-ds4-ds5-workaround.service => bazzite-bluetooth-ds4-ds5-workaround@.service} (55%) create mode 100644 system_files/desktop/shared/usr/lib/udev/rules.d/80-bazzite-ps-controller-sleep.rules diff --git a/system_files/desktop/shared/usr/lib/systemd/system/bazzite-bluetooth-ds4-ds5-workaround.service b/system_files/desktop/shared/usr/lib/systemd/system/bazzite-bluetooth-ds4-ds5-workaround@.service similarity index 55% rename from system_files/desktop/shared/usr/lib/systemd/system/bazzite-bluetooth-ds4-ds5-workaround.service rename to system_files/desktop/shared/usr/lib/systemd/system/bazzite-bluetooth-ds4-ds5-workaround@.service index 1fd7bd084f..50c762b79e 100644 --- a/system_files/desktop/shared/usr/lib/systemd/system/bazzite-bluetooth-ds4-ds5-workaround.service +++ b/system_files/desktop/shared/usr/lib/systemd/system/bazzite-bluetooth-ds4-ds5-workaround@.service @@ -1,15 +1,12 @@ [Unit] Description=Disconnect DS4 and DS5 controller on shortcut HOME + triangle After=bluetooth.target +Requires=bluetooth.target ConditionFileIsExecutable=/usr/libexec/bazzite-bluetooth-ds4-ds5-workaround [Service] User=root -ExecCondition=/usr/bin/systemctl is-enabled bluetooth.service -ExecStart=/bin/bash /usr/libexec/bazzite-bluetooth-ds4-ds5-workaround +Type=simple +ExecStart=/usr/libexec/bazzite-bluetooth-ds4-ds5-workaround %i Restart=on-failure RestartSec=5 -TimeoutSec=5s - -[Install] -WantedBy=multi-user.target diff --git a/system_files/desktop/shared/usr/lib/udev/rules.d/80-bazzite-ps-controller-sleep.rules b/system_files/desktop/shared/usr/lib/udev/rules.d/80-bazzite-ps-controller-sleep.rules new file mode 100644 index 0000000000..e59c1a1412 --- /dev/null +++ b/system_files/desktop/shared/usr/lib/udev/rules.d/80-bazzite-ps-controller-sleep.rules @@ -0,0 +1,3 @@ +ACTION=="add", \ +ATTRS{name}=="*Wireless Controller", \ +RUN=+"/usr/bin/bash /usr/bin/systemctl start bazzite-bluetooth-ds4-ds5-workaround@$attr{uniq}.service" \ No newline at end of file From a955399018a867a49eb3a35d1589fa31d20e0096 Mon Sep 17 00:00:00 2001 From: Zeglius <33781398+Zeglius@users.noreply.github.com> Date: Tue, 30 Jul 2024 21:32:52 +0200 Subject: [PATCH 13/29] refactor: rewrite bazzite-bluetooth-ds4-ds5-workaround to python Add device handling with device mac address as argument --- .../bazzite-bluetooth-ds4-ds5-workaround | 323 +++++++++--------- 1 file changed, 159 insertions(+), 164 deletions(-) diff --git a/system_files/desktop/shared/usr/libexec/bazzite-bluetooth-ds4-ds5-workaround b/system_files/desktop/shared/usr/libexec/bazzite-bluetooth-ds4-ds5-workaround index 33e7819c7e..a4159883ab 100755 --- a/system_files/desktop/shared/usr/libexec/bazzite-bluetooth-ds4-ds5-workaround +++ b/system_files/desktop/shared/usr/libexec/bazzite-bluetooth-ds4-ds5-workaround @@ -1,8 +1,9 @@ -#!/bin/bash +#!/usr/bin/python +""" # Script Name: bazzite-bluetooth-ds4-ds5-workaround # Author: https://github.com/thekk1 -# Version: 1.5 +# Version: 1.6 # # Related issues: # https://github.com/ublue-os/bazzite/issues/1289 @@ -17,169 +18,163 @@ # This script should be removed if there is a native solution under one of the mentioned issues. # # Usage: -# ./bazzite-bluetooth-ds4-ds5-workaround [-d] -# -d: Enable debug mode - -DEBUG=false -MONITOR_FILE="/tmp/monitored_devices.txt" -truncate -s 0 $MONITOR_FILE - -# Check for the debug flag -while getopts "d" opt; do - case ${opt} in - d ) DEBUG=true ;; - \? ) echo "Usage: $0 [-d]" ;; - esac -done - -# Function to find gamepad devices (PS4 and PS5) -find_gamepad_devices() { - local devices=() - local base_path="/sys/class/input" - - for entry in "$base_path"/event*; do - local device_path="$entry/device" - local uevent_path="$device_path/uevent" - - if [[ -f "$uevent_path" ]]; then - local devicename - devicename=$(grep "NAME" "$uevent_path" | cut -d'=' -f2 | tr -d '"') - if [[ "$devicename" == "Wireless Controller" || "$devicename" == "DualSense Wireless Controller" ]]; then - devices+=("$(basename "$entry")") - fi - fi - done - echo "${devices[@]}" +# ./bazzite-bluetooth-ds4-ds5-workaround + +""" +# See https://gist.github.com/noohgnas/7c896791d437e51122c59fe9576a1bcf for reference +from concurrent.futures import thread +import glob +import multiprocessing +import re +import struct +import subprocess +import sys + +from threading import Thread +from time import sleep + + +class KeyStatus: + def __init__(self) -> None: + self.home: bool = False + self.triangle: bool = False + self.other: set[int] = set() + + +GAMEPAD_KEYS = { + "HOME": [ + 316, # Dualshock + ], + "TRIANGLE": [ + 307, # Dualshock + ], } -# Function to get MAC address from uevent file -get_mac_address_from_uevent() { - local device="$1" - local uniq_path="/sys/class/input/$device/device/uevent" - - if [[ -f "$uniq_path" ]]; then - local mac_address - mac_address=$(grep "UNIQ" "$uniq_path" | cut -d'=' -f2 | tr -d '"') - echo "$mac_address" - else - echo "" - fi -} - -# Function to monitor the gamepad and disconnect Bluetooth connection -monitor_gamepad() { - local device_path="$1" - local bluetooth_mac_address="$2" - local process_name="monitor_gamepad_$bluetooth_mac_address" - - $DEBUG && echo "Starting monitoring on device: $device_path" - - # Check if process is already running - if pgrep -f "$process_name" > /dev/null; then - $DEBUG && echo "Process for $bluetooth_mac_address is already running." +EV_KEY = 1 + + +def trigger_callback(device_mac: str): + """Action to realize when HOME + TRIANGLE is held at the same time""" + # Get bluetooth adapters + p = subprocess.Popen( + ["/usr/bin/bluetoothctl", "list"], + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + text=True, + ) + p.wait() + adapt_strlines = p.stdout + if adapt_strlines is None: + print("ERROR: No adapters detected") return - fi - - # Define the command to disconnect all controllers - disconnect_cmd="for controller in \$(bluetoothctl list | awk '/Controller/ {print \$2}'); do echo -e \"select \$controller\ndisconnect $bluetooth_mac_address\n\" | bluetoothctl; done" - - # Run the monitoring process with a specific process name - (cat "$device_path" 2>&1 | xxd -p -c 24 | awk -v mac="$bluetooth_mac_address" -v pname="$process_name" -v cmd="$disconnect_cmd" -v debug="$DEBUG" ' - BEGIN { home_pressed=0; triangle_pressed=0 } - { - event_part=substr($0,33); - if(substr(event_part,1,4)=="0100") { - code=substr(event_part,5,4); - value=substr(event_part,9,2); - if(code=="3301" || code=="3c01") { - if(value=="01") { - if(code=="3301") home_pressed=1; - if(code=="3c01") triangle_pressed=1; - if(home_pressed && triangle_pressed) { - # Print a message before executing the disconnect command - if (debug == "true") { - print "Disconnect command issued for MAC address: " mac; - } - # Execute the disconnect command only once - system(cmd); - home_pressed=0; - triangle_pressed=0; - } - } else { - home_pressed=0; - triangle_pressed=0; - } - } - } - }' >&1) & echo $! > "/tmp/$process_name.pid" & disown - - $DEBUG && echo "Started monitoring process for $bluetooth_mac_address with process name $process_name." -} - -# Function to clean up processes -cleanup_processes() { - # List of currently monitored MAC addresses - local monitored_macs=$(cat "$MONITOR_FILE") - - # Iterate through all monitored MAC addresses - while IFS= read -r mac; do - process_name="monitor_gamepad_$mac" - pid_file="/tmp/${process_name}.pid" - - if [[ -z "$mac" ]]; then - continue - fi - - if [[ -f "$pid_file" ]]; then - pid=$(cat "$pid_file") - if ! ps -p "$pid" > /dev/null; then - $DEBUG && echo "Stopping process for $mac as it's no longer running." - pkill -f "$process_name" - rm -f "$pid_file" - # Remove the MAC address from the monitor file - sed -i "/$mac/d" "$MONITOR_FILE" - fi - else - $DEBUG && echo "No PID file found for $mac." - fi - done <<< "$monitored_macs" -} -# Main loop of the script -while true; do - # Find currently connected gamepad devices - gamepad_devices=$(find_gamepad_devices) - - # Get current MAC addresses from the monitor file - current_macs=$(cat "$MONITOR_FILE") - - if [[ -z "$gamepad_devices" ]]; then - $DEBUG && echo "No PS4 or PS5 controllers found." - else - $DEBUG && echo "Found devices: $gamepad_devices" - # Convert the list of devices into an array - IFS=' ' read -r -a devices_array <<< "$gamepad_devices" - - # Loop over the found devices - for device in "${devices_array[@]}"; do - device_path="/dev/input/$device" - mac_address=$(get_mac_address_from_uevent "$device") - - if [[ -n "$mac_address" ]]; then - # Check if this device is already being monitored - if ! grep -q "$mac_address" "$MONITOR_FILE"; then - echo "$mac_address" >> "$MONITOR_FILE" - $DEBUG && echo "Monitoring device: $device_path" - monitor_gamepad "$device_path" "$mac_address" - fi - else - $DEBUG && echo "No MAC address found for $device." - fi - done - fi - - # Clean up processes that are no longer needed - cleanup_processes - - sleep 5 # Wait before searching for new devices -done + for adap in adapt_strlines: + print(f"DEBUG: {adap}") + adap = adap.strip().split(" ", maxsplit=2)[1] + p2 = subprocess.Popen( + ["/usr/bin/bash", "-c", f"""echo -e "select {adap}\ndisconnect {device_mac}" | bluetoothctl """], + stdin=subprocess.PIPE, + stdout=subprocess.PIPE, + text=True, + ) + p2.wait() + + +def get_event_path(mac: str) -> str | None: + """Obtain the /dev/input/eventX path for a bluetooth + Returns: + str: path address + """ + res: str | None = None + mac = mac.lower() + proc = subprocess.Popen( + [ + "/usr/bin/udevadm", + "trigger", + "-c", + "add", + f"--attr-match=uniq={mac}", + "--dry-run", + "--verbose", + ], + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + text=True, + ) + proc.wait() + if proc.stdout is None: + return res + paths = proc.stdout.readlines() + for path in paths: + path = path.strip() + with open(f"{path}/name") as f: + contents = f.read().strip() + if re.match(r"^(?:Dualsense )?Wireless Controller$", contents) is not None: + ev_name = glob.glob(f"{path}/event*")[0].rstrip("/").split("/")[-1] + res = f"/dev/input/{ev_name}" + break + + return res + + +def main(argv: list[str]): + if len(argv[1:]) != 1: + print("ERROR: Missing argument", file=sys.stderr) + exit(1) + + device_mac = argv[1] + if device_mac is None or device_mac == "": + print("ERROR: Incorrect device bluetooth mac address", file=sys.stderr) + exit(1) + + global keys_status + keys_status = KeyStatus() + + gamepad_mac = get_event_path(device_mac) + if gamepad_mac is None: + print("ERROR: Incorrect device bluetooth mac address", file=sys.stderr) + exit(1) + + # long int, long int, unsigned short, unsigned short, unsigned int + FORMAT = "llHHI" + EVENT_SIZE = struct.calcsize(FORMAT) + + # open file in binary mode + in_file = open(gamepad_mac, "rb") + + event = in_file.read(EVENT_SIZE) + + while event: + (_tv_sec, _tv_usec, type, code, value) = struct.unpack(FORMAT, event) + + if type == EV_KEY: + if code in GAMEPAD_KEYS["HOME"]: + keys_status.home = value == 1 + elif code in GAMEPAD_KEYS["TRIANGLE"]: + keys_status.triangle = value == 1 + else: + ( + keys_status.other.add(code) + if value == 1 + else keys_status.other.remove(code) + ) + + # print( + # f"home: {keys_status.home}, triangle: {keys_status.triangle}, other: {keys_status.other}", + # ) + if ( + value == 1 + and keys_status.home + and keys_status.triangle + and len(keys_status.other) <= 0 + ): + #### Here we manage what happens when the HOME TRIANGLE is pressed + print("HOME + TRIANGLE detected") + trigger_callback(device_mac) + event = in_file.read(EVENT_SIZE) + + in_file.close() + + +if __name__ == "__main__": + main(sys.argv) From 8391e8310773a73fcc25826a0e93f2fa4b9c4c2e Mon Sep 17 00:00:00 2001 From: Zeglius <33781398+Zeglius@users.noreply.github.com> Date: Tue, 30 Jul 2024 21:41:52 +0200 Subject: [PATCH 14/29] chore: remove leftover service activation --- Containerfile | 1 - 1 file changed, 1 deletion(-) diff --git a/Containerfile b/Containerfile index b5ee5e0be3..7f72bb5d7c 100644 --- a/Containerfile +++ b/Containerfile @@ -684,7 +684,6 @@ RUN rm -f /etc/profile.d/toolbox.sh && \ systemctl enable bazzite-hardware-setup.service && \ systemctl enable tailscaled.service && \ systemctl enable dev-hugepages1G.mount && \ - systemctl --global enable bazzite-bluetooth-ds4-ds5-workaround.service && \ systemctl --global enable bazzite-user-setup.service && \ systemctl --global enable podman.socket && \ systemctl --global enable systemd-tmpfiles-setup.service && \ From 6db8b73a62282ad2a3e805f8008a9e8709548b0f Mon Sep 17 00:00:00 2001 From: Zeglius <33781398+Zeglius@users.noreply.github.com> Date: Thu, 1 Aug 2024 20:08:56 +0200 Subject: [PATCH 15/29] fix: fix broken udev rule --- .../usr/lib/udev/rules.d/80-bazzite-ps-controller-sleep.rules | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/system_files/desktop/shared/usr/lib/udev/rules.d/80-bazzite-ps-controller-sleep.rules b/system_files/desktop/shared/usr/lib/udev/rules.d/80-bazzite-ps-controller-sleep.rules index e59c1a1412..7ba7145f92 100644 --- a/system_files/desktop/shared/usr/lib/udev/rules.d/80-bazzite-ps-controller-sleep.rules +++ b/system_files/desktop/shared/usr/lib/udev/rules.d/80-bazzite-ps-controller-sleep.rules @@ -1,3 +1 @@ -ACTION=="add", \ -ATTRS{name}=="*Wireless Controller", \ -RUN=+"/usr/bin/bash /usr/bin/systemctl start bazzite-bluetooth-ds4-ds5-workaround@$attr{uniq}.service" \ No newline at end of file +ACTION=="add", DRIVERS=="playstation", ATTRS{name}=="*Wireless Controller", TAG+="systemd", ENV{SYSTEMD_WANTS}="bazzite-bluetooth-ds4-ds5-workaround@$attr{uniq}.service" \ No newline at end of file From f9e38db3f3f102764001aa711a45201fd7ac8de9 Mon Sep 17 00:00:00 2001 From: Zeglius <33781398+Zeglius@users.noreply.github.com> Date: Mon, 5 Aug 2024 01:43:00 +0200 Subject: [PATCH 16/29] fix: incompatible udev rule --- .../system/bazzite-bluetooth-ds4-ds5-workaround@.service | 2 +- .../usr/lib/udev/rules.d/80-bazzite-ps-controller-sleep.rules | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/system_files/desktop/shared/usr/lib/systemd/system/bazzite-bluetooth-ds4-ds5-workaround@.service b/system_files/desktop/shared/usr/lib/systemd/system/bazzite-bluetooth-ds4-ds5-workaround@.service index 50c762b79e..c80ab4203f 100644 --- a/system_files/desktop/shared/usr/lib/systemd/system/bazzite-bluetooth-ds4-ds5-workaround@.service +++ b/system_files/desktop/shared/usr/lib/systemd/system/bazzite-bluetooth-ds4-ds5-workaround@.service @@ -7,6 +7,6 @@ ConditionFileIsExecutable=/usr/libexec/bazzite-bluetooth-ds4-ds5-workaround [Service] User=root Type=simple -ExecStart=/usr/libexec/bazzite-bluetooth-ds4-ds5-workaround %i +ExecStart=/usr/libexec/bazzite-bluetooth-ds4-ds5-workaround %I Restart=on-failure RestartSec=5 diff --git a/system_files/desktop/shared/usr/lib/udev/rules.d/80-bazzite-ps-controller-sleep.rules b/system_files/desktop/shared/usr/lib/udev/rules.d/80-bazzite-ps-controller-sleep.rules index 7ba7145f92..e2e6c07fe8 100644 --- a/system_files/desktop/shared/usr/lib/udev/rules.d/80-bazzite-ps-controller-sleep.rules +++ b/system_files/desktop/shared/usr/lib/udev/rules.d/80-bazzite-ps-controller-sleep.rules @@ -1 +1 @@ -ACTION=="add", DRIVERS=="playstation", ATTRS{name}=="*Wireless Controller", TAG+="systemd", ENV{SYSTEMD_WANTS}="bazzite-bluetooth-ds4-ds5-workaround@$attr{uniq}.service" \ No newline at end of file +ACTION=="add", SUBSYSTEMS=="input", ATTRS{name}=="*Wireless Controller", RUN+="/usr/bin/systemctl start --no-block --runtime bazzite-bluetooth-ds4-ds5-workaround@$attr{uniq}.service" \ No newline at end of file From e51f39781bcce7b0f41420ebec0d344919472440 Mon Sep 17 00:00:00 2001 From: Zeglius <33781398+Zeglius@users.noreply.github.com> Date: Mon, 5 Aug 2024 12:21:22 +0200 Subject: [PATCH 17/29] fix: tweak exitcode This way, bazziye-bluetooth-ds4-ds5-workaround wont use exit code 1 whenever we dont receive MAC address of the controller --- .../shared/usr/libexec/bazzite-bluetooth-ds4-ds5-workaround | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/system_files/desktop/shared/usr/libexec/bazzite-bluetooth-ds4-ds5-workaround b/system_files/desktop/shared/usr/libexec/bazzite-bluetooth-ds4-ds5-workaround index a4159883ab..223b1b4881 100755 --- a/system_files/desktop/shared/usr/libexec/bazzite-bluetooth-ds4-ds5-workaround +++ b/system_files/desktop/shared/usr/libexec/bazzite-bluetooth-ds4-ds5-workaround @@ -124,8 +124,8 @@ def main(argv: list[str]): device_mac = argv[1] if device_mac is None or device_mac == "": - print("ERROR: Incorrect device bluetooth mac address", file=sys.stderr) - exit(1) + print("ERROR: Missing device bluetooth mac address", file=sys.stderr) + exit(0) global keys_status keys_status = KeyStatus() @@ -133,7 +133,7 @@ def main(argv: list[str]): gamepad_mac = get_event_path(device_mac) if gamepad_mac is None: print("ERROR: Incorrect device bluetooth mac address", file=sys.stderr) - exit(1) + exit(69) # systemd-analyze exit-status UNAVAILABLE # long int, long int, unsigned short, unsigned short, unsigned int FORMAT = "llHHI" From 2b8c496eab93de655c01780c555a6f3ed75446f7 Mon Sep 17 00:00:00 2001 From: Zeglius <33781398+Zeglius@users.noreply.github.com> Date: Mon, 5 Aug 2024 13:14:03 +0200 Subject: [PATCH 18/29] chore: Add CPUQuota to ds4/5 workaround --- .../systemd/system/bazzite-bluetooth-ds4-ds5-workaround@.service | 1 + 1 file changed, 1 insertion(+) diff --git a/system_files/desktop/shared/usr/lib/systemd/system/bazzite-bluetooth-ds4-ds5-workaround@.service b/system_files/desktop/shared/usr/lib/systemd/system/bazzite-bluetooth-ds4-ds5-workaround@.service index c80ab4203f..cb209e5fa0 100644 --- a/system_files/desktop/shared/usr/lib/systemd/system/bazzite-bluetooth-ds4-ds5-workaround@.service +++ b/system_files/desktop/shared/usr/lib/systemd/system/bazzite-bluetooth-ds4-ds5-workaround@.service @@ -7,6 +7,7 @@ ConditionFileIsExecutable=/usr/libexec/bazzite-bluetooth-ds4-ds5-workaround [Service] User=root Type=simple +CPUQuota=25% ExecStart=/usr/libexec/bazzite-bluetooth-ds4-ds5-workaround %I Restart=on-failure RestartSec=5 From 818a88266425f5f4daf70d6322ebe6fd6b53e3d5 Mon Sep 17 00:00:00 2001 From: Zeglius <33781398+Zeglius@users.noreply.github.com> Date: Mon, 5 Aug 2024 13:34:31 +0200 Subject: [PATCH 19/29] chore: add brief doc to ds4-ds5 workaround --- .../80-bazzite-ps-controller-sleep.rules | 4 ++++ ...zzite-bluetooth-ds4-ds5-workaround@.service | 18 ++++++++++++++++++ 2 files changed, 22 insertions(+) create mode 100644 system_files/desktop/shared/usr/etc/udev/rules.d/80-bazzite-ps-controller-sleep.rules diff --git a/system_files/desktop/shared/usr/etc/udev/rules.d/80-bazzite-ps-controller-sleep.rules b/system_files/desktop/shared/usr/etc/udev/rules.d/80-bazzite-ps-controller-sleep.rules new file mode 100644 index 0000000000..a10f5a0cba --- /dev/null +++ b/system_files/desktop/shared/usr/etc/udev/rules.d/80-bazzite-ps-controller-sleep.rules @@ -0,0 +1,4 @@ +# DO NOT TOUCH ME +# This file is here in order to disable /usr/lib/udev/rules.d/80-bazzite-ps-controller-sleep.rules +# Read /usr/lib/systemd/system/bazzite-bluetooth-ds4-ds5-workaround@.service +# Delete me if you want to enable workaround \ No newline at end of file diff --git a/system_files/desktop/shared/usr/lib/systemd/system/bazzite-bluetooth-ds4-ds5-workaround@.service b/system_files/desktop/shared/usr/lib/systemd/system/bazzite-bluetooth-ds4-ds5-workaround@.service index cb209e5fa0..aa31afd672 100644 --- a/system_files/desktop/shared/usr/lib/systemd/system/bazzite-bluetooth-ds4-ds5-workaround@.service +++ b/system_files/desktop/shared/usr/lib/systemd/system/bazzite-bluetooth-ds4-ds5-workaround@.service @@ -1,3 +1,21 @@ +# By Bazzite +# This workaround allows for DualShock/Dualsense controllers of disconnecting +# when pressing HOME + TRIANGLE +# +# Files composing workaround: +# +# - /usr/lib/udev/rules.d/80-bazzite-ps-controller-sleep.rules +# Activates the service with controller MAC as parameter. +# +# - /usr/lib/systemd/system/bazzite-bluetooth-ds4-ds5-workaround@.service +# Allows to start binary that handles keycode reading. +# +# - /usr/libexec/bazzite-bluetooth-ds4-ds5-workaround +# Reads keycodes and disconnects controllers when HOME + TRIANGLE is read. +# +# - /etc/udev/rules.d/80-bazzite-ps-controller-sleep.rules +# Empty file that acts as a deactivator of the workaround + [Unit] Description=Disconnect DS4 and DS5 controller on shortcut HOME + triangle After=bluetooth.target From 9366de23d92ee8c76b59749b1ce73432dd16aa73 Mon Sep 17 00:00:00 2001 From: Zeglius <33781398+Zeglius@users.noreply.github.com> Date: Mon, 5 Aug 2024 13:15:10 +0200 Subject: [PATCH 20/29] chore: add ujust enable-ds4-workaround --- .../usr/share/ublue-os/just/80-bazzite.just | 97 +++++++++++++++++++ 1 file changed, 97 insertions(+) diff --git a/system_files/desktop/shared/usr/share/ublue-os/just/80-bazzite.just b/system_files/desktop/shared/usr/share/ublue-os/just/80-bazzite.just index ef1568a5a3..fb55999c5e 100644 --- a/system_files/desktop/shared/usr/share/ublue-os/just/80-bazzite.just +++ b/system_files/desktop/shared/usr/share/ublue-os/just/80-bazzite.just @@ -363,3 +363,100 @@ bazzite-cli: benchmark: echo 'Running a 1 minute benchmark ...' cd /tmp && stress-ng --matrix 0 -t 1m --times + +# Enable/disable HOME + TRIANGLE controller shutdown option for DualShock/DualSense +enable-ds45-workaround ACTION="": + #!/usr/bin/bash + + set -eo pipefail + source /usr/lib/ujust/ujust.sh + + OPTION={{ ACTION }} + PLACEHOLDER=/etc/udev/rules.d/80-bazzite-ps-controller-sleep.rules + WORKAROUND_NAME="bazzite-bluetooth-ds4-ds5-workaround" + + function is_enabled() { + if [[ ! -e $PLACEHOLDER ]]; then + return 0 + fi + return 1 + } + + function enable_workaround() { + # Check if the placeholder rule exists and if does, delete it + if is_enabled ; then + echo "$WORKAROUND_NAME is already enabled" + exit 0 + fi + sudo rm -v "$PLACEHOLDER" + echo "$WORKAROUND_NAME was enabled" + } + + function disable_workaround() { + # Set placeholder to disable workaround + if ! is_enabled; then + echo "$WORKAROUND_NAME is already disabled" + return 0 + fi + sudo cp -v /usr/$PLACEHOLDER $PLACEHOLDER || { : | sudo tee $ $PLACEHOLDER; } + echo "$WORKAROUND_NAME was disabled" + } + + function show_help() { + echo "Usage: ujust enable-ds45-workaround