#!/usr/bin/env zsh exec >(systemd-cat -t default-application-launcher -p info) exec 2> >(systemd-cat -t default-application-launcher -p err) export PATH=$HOME/.pyenv/shims:$HOME/.local/bin:/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin export PYENV_HOME=$HOME/.pyenv export PYENV_VERSION=personal ws_data=$(sway_get_focused_workspace) current_workspace=$(echo $ws_data | jq -r '.index') program=$(echo $ws_data | jq -r '.exec') program_name=$(echo $ws_data | jq -r '.program_name') memory_profile=$(echo $ws_data | jq '.memory_profile' -c) run_with_systemd=$(echo $ws_data | jq '.systemd' -r) is_forking=$(echo $ws_data | jq '.forking' -r) void_output=$(echo $ws_data | jq '.void_output' -r) is_comms=$(echo $ws_data | jq '.comms' -r) IFS=$'\n' environ=($(echo $ws_data | jq '.environ | to_entries | map("\(.key)=\(.value|tostring)") | .[]' -r 2>/dev/null)) IFS=$'\n' args=($(echo $ws_data | jq '.args | .[]' -r 2>/dev/null)) systemd_run_args=() if [[ $memory_profile != "null" ]]; then max_memory=$(echo $memory_profile | jq -r '.max') high_memory=$(echo $memory_profile | jq -r '.high') systemd_run_args+=("--property=MemoryAccounting=yes" "--property=MemoryMax=${max_memory}" "--property=MemoryHigh=${high_memory}") fi pty=alacritty function error() { gxmessage -buttons "OK:0" -name "Program Launch Error" -title "Program Launch Error" "Error: This workspace is not assigned a default program" -borderless -wrap -center -sticky -default OK } if [[ $program == "" ]]; then echo "error: no program for workspace ${current_workspace} is defined (got ${program})" >&2 exec error fi slice=app-sway.slice if [[ $is_comms == 'true' ]]; then # This is to create a cgroup containing all our comms apps that can be suspended in one go # when the session goes idle, preventing the issue that happens where notifications go to a system # that's always on. slice=app-comms.slice fi echo "Launching application $program" if [[ $environ != "" ]]; then for env in $environ; do echo "setting environment $env" systemd_run_args+=("--setenv=$env") done fi if [[ $is_forking == "true" ]]; then systemd_run_args+=("--service-type=forking") fi if [[ $program == "console" ]] && [[ $pty == "alacritty" ]]; then # Create a new window if an instance is already running, otherwise start the service echo "Creating new alacritty window" alacritty msg --socket=$XDG_RUNTIME_DIR/alacritty create-window exit 0 elif [[ $program == "console" ]]; then program=$pty fi if [[ $void_output == "true" ]]; then # Run it under a scope for resource control, but don't capture stdout/stderr # This should only be used for programs that either produce no output, or # produce so much output that it would flood the journal and make it # difficult to use. exec >/dev/null exec 2>/dev/null exec systemd-run --user $=systemd_run_args --scope --unit="app-sway-$program_name-$RANDOM" --description="$program_name" --slice=$slice -- $=program fi if [[ $run_with_systemd == "false" ]]; then # Run it under systemd-cat to capture stdout/stderr to journal, but don't use systemd-run # so that we don't get resource control exec systemd-cat -t $program_name -p info -- $=program fi # Run programs using systemd-run to allow for resource control and capture of stdout/stderr # We're using a service instead of a scope because scopes don't capture output, and wrapping # the call in systemd-cat is more complicated than just using a service. echo exec systemd-run --user $=systemd_run_args --unit="app-sway-$program_name@$RANDOM" --description="$program_name" --slice=$slice -- $program $args exec systemd-run --user $=systemd_run_args --unit="app-sway-$program_name@$RANDOM" --description="$program_name" --slice=$slice -- $program $args