-
-
Save stephan-t/561d0e473dddb270be3da6a8ca994306 to your computer and use it in GitHub Desktop.
#!/bin/bash | |
# Fixes texture corruption in VS Code terminal after resuming from suspend. | |
# | |
# Place script in /lib/systemd/system-sleep/ so it can run after resuming. | |
# | |
# Dependencies: jq | |
case "$1" in | |
post) | |
# Check if VS Code is running | |
if [ -z "$(pgrep -x code)" ]; then | |
exit 0 | |
fi | |
user=$(cut -d " " -f 1 <<< $(users)) | |
settings_file="/home/$user/.config/Code/User/settings.json" | |
# Check if settings file is a symlink | |
if [ -L "$settings_file" ]; then | |
settings_link=$settings_file | |
settings_file=$(readlink $settings_file) | |
fi | |
# Create backup of settings | |
backup_file="/home/$user/.config/Code/User/settings.json.bak" | |
if [ ! -e "$backup_file" ]; then | |
cp $settings_file $backup_file | |
fi | |
# Before overwriting, ensure settings file is not truncated from errors | |
tmp_file='/tmp/settings.json' | |
overwrite() { | |
local tmp_file_lines=$(wc -l $tmp_file | cut -d " " -f 1) | |
if [ "$tmp_file_lines" -le 1 ]; then | |
rm $tmp_file | |
exit 1 | |
else | |
chown $user:$user $tmp_file | |
mv $tmp_file $settings_file | |
if [ ! -z ${settings_link+x} ]; then | |
touch -h $settings_link | |
fi | |
fi | |
} | |
# Wait for screen unlock | |
tail -f /var/log/auth.log -n 1 | sed '/unlocked login keyring/ q;/Power key pressed/ q' | |
# Get current zoom level | |
zoom_level=$(jq '.["window.zoomLevel"]' $settings_file) | |
# Add missing key if required | |
if [ "$zoom_level" = "null" ]; then | |
jq '. + { "window.zoomLevel": 0 }' $settings_file > $tmp_file | |
overwrite | |
fi | |
# Change zoom level | |
let zoom_level++ | |
jq '.["window.zoomLevel"] = $zoom' --argjson zoom $zoom_level \ | |
$settings_file > $tmp_file | |
overwrite | |
sleep 0.5 | |
let zoom_level-- | |
jq '.["window.zoomLevel"] = $zoom' --argjson zoom $zoom_level \ | |
$settings_file > $tmp_file | |
overwrite | |
;; | |
esac |
Couldn't you just check for zoom then
sed -i
? That would also allow this to work with dotfiles. As it stands ofsettings.json
is a symlink, this kills the link.See: https://gist.github.com/Fmstrat/7de01996206537b9dbc8f673b2c5ced2
Hi @Fmstrat, thanks for your suggestion and contribution.
I initially thought about using sed
but found that it is advised against for parsing complex structured data such as JSON or XML since there are a lot of chances for it to go wrong, especially if the data is malformed. It is usually recommended to use dedicated parsing tools such as jq
to ensure reliability.
Reference: https://askubuntu.com/questions/863865/regex-with-sed-command-to-parse-json-text
That makes sense. In that case, I would recommend outputting into the file directly, such as with > settings.json
as to handle any symlinks/dotfiles (vs moving over it).
Also, it looks like you could simplify your wait on unlock with this: https://gist.github.com/Fmstrat/7de01996206537b9dbc8f673b2c5ced2#file-vscode-texture-fix-sh-L21
Lastly, how do you get the $(users)
variable? The script fails for me because that variable doesn't exist (Ubuntu 20.04, logged into a domain). Did it work for you out of the box? Maybe it's a domain thing.
Thanks @Fmstrat. I simplified the "wait on unlock" with your code.
The reason why I don't direct jq
's output to settings.json
is because if there is any error in jq
's input or filter string then it will output an empty file, which is why the script first outputs to a temporary file and verifies it in the overwrite
function before overwriting settings.json
. However, I have now modified the code to check for symlinks and handle it appropriately.
I used the built-in users
command (Ubuntu 20.04) to get the list of currently logged in users, which then uses the first username in the list as a variable for the rest of the script. It works out of the box for me. Unfortunately, I am not familiar with domain logins in Ubuntu so I wouldn't know how to modify the code to work with that. I only used the users
command so that others using the script wouldn't have to modify anything to get it to work but you can always hard code your username into the user
variable. You can also try the who
command to see if it lists your domain username. Using whoami
command won't work because the script will execute as root
on resume.
@stephan-t I've noticed one other thing that I've corrected in my version of the script. Users who assign their power button to pm-hibernate
never have to "re-login", and thus nothing shows up in the Auth log. So the tail
command just runs forever. The fix is this line in my version if it helps: https://gist.github.com/Fmstrat/7de01996206537b9dbc8f673b2c5ced2#file-vscode-texture-fix-sh-L20
Good catch @Fmstrat, thank you. I've updated my script to include that as well.
Couldn't you just check for zoom then
sed -i
? That would also allow this to work with dotfiles. As it stands ofsettings.json
is a symlink, this kills the link.See: https://gist.github.com/Fmstrat/7de01996206537b9dbc8f673b2c5ced2