#!/bin/bash # Copyright (C) Daniel Napora 2021-24 # https://maboxlinux.org #: deskmngr - save all programs (windows) running on current desktop in session file. #: With windows positions and state (decorated or not) #: Usage: #: -l|listsessions - list saved sessions #: -s|save - save session from current desktop #: -r|restore sesionfile desktop_ID - restore session from sessionfile on desktop #: # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . SESSIONDIR="$HOME/.config/deskmngr/" CONFIG_FILE="$SESSIONDIR/deskmngr.conf" mkdir -p $SESSIONDIR # If config file not exist create one with defaults if [ ! -f $CONFIG_FILE ]; then cat < ${CONFIG_FILE} waitsec=1 EOF fi source <(grep = $CONFIG_FILE) waittime=${waitsec:-1} case "$LANG" in pl*) TITLE="Nie ma nic do zapisania" TEXT="\nWygląda na to że nie ma otwartych okien na bieżącym pulpicie.\nUruchom jakieś programy i spróbuj ponownie.\n" SAVE_AS="Zapisz sesję jako:" SESSNAME="Nazwa sesji" ;; *) TITLE="Nothing to save" TEXT="\nLooks like there are no windows to save on current desktop.\n Run some programs and try again.\n" SAVE_AS="Save session as:" SESSNAME="Session name" ;; esac savesession() { curdesk=$(wmctrl -d | grep "*" | awk '{print $1}') if [ $(wmctrl -l -p -G | awk -v c=$curdesk '$2 == c {print $2}' | wc -l) == "0" ];then notify-send -i dialog-warning "$TITLE" "$TEXT";exit 1;fi if [ -n "$1" ]; then filename="$1" else filename=$(yad --center --width=300 --title "$SAVE_AS" --entry --entry-label="$SESSNAME" --entry-text="$SESSNAME") || exit 1 fi windows=() wmctrl -l -p -G | { while IFS= read -r line do read -r ID DESK PID x_offset y_offset width height rest< <(echo $line) if [[ "$DESK" != "-1" ]]; then if [[ "$DESK" == "$curdesk" ]]; then cmdline=$(ps -fp $PID -o command=) if [[ $cmdline != *quake-term* ]]; then xwininfo -id "$ID" -wm | grep -q Undecorated && D="u" || D="d" ## frameY=$(xwininfo -id "$ID" -stats | grep "Relative upper-left Y:" | cut -d: -f2) frameX=$(xwininfo -id "$ID" -stats | grep "Relative upper-left X:" | cut -d: -f2) windows+=("$D $width $height $((x_offset-frameX)) $((y_offset-2*frameY)) $cmdline") fi fi fi done if [ ${#windows[@]} -eq 0 ]; then notify-send -i dialog-warning "$TITLE" "$TEXT" else printf "%s\n" "${windows[@]}" > "$SESSIONDIR/${filename// /_}.desk" # Serch replace if command -v sd 1>/dev/null; then sd -s "/usr/lib/chromium/chromium" "chromium --new-window" "$SESSIONDIR/${filename// /_}.desk" sd -s "/usr/lib/firefox/firefox" "firefox --new-window" "$SESSIONDIR/${filename// /_}.desk" sd -s "/usr/bin/python3 /usr/bin/terminator" "terminator" "$SESSIONDIR/${filename// /_}.desk" sd -s "/usr/bin/python /usr/bin/terminator" "terminator" "$SESSIONDIR/${filename// /_}.desk" sd -s "geany" "geany -i" "$SESSIONDIR/${filename// /_}.desk" sd -s "cherrytree" "cherrytree --new-window" "$SESSIONDIR/${filename// /_}.desk" sd -s "pcmanfm -d" "pcmanfm -n" "$SESSIONDIR/${filename// /_}.desk" sd -s "Thunar --daemon" "thunar" "$SESSIONDIR/${filename// /_}.desk" else sed -i '/usr/lib/chromium/chromium,chromium --new-window,' "$SESSIONDIR/${filename// /_}.desk" sed -i '/usr/lib/firefox/firefox,firefox --new-window,' "$SESSIONDIR/${filename// /_}.desk" sed -i '/usr/bin/python3 /usr/bin/terminator,terminator,' "$SESSIONDIR/${filename// /_}.desk" sed -i '/usr/bin/python /usr/bin/terminator,terminator,' "$SESSIONDIR/${filename// /_}.desk" sed -i 'geany,geany -i,' "$SESSIONDIR/${filename// /_}.desk" sed -i 'cherrytree,cherrytree --new-window,' "$SESSIONDIR/${filename// /_}.desk" sed -i 'pcmanfm -d,pcmanfm -n,' "$SESSIONDIR/${filename// /_}.desk" sed -i 'Thunar --daemon,thunar,' "$SESSIONDIR/${filename// /_}.desk" fi if command -v geany 1>/dev/null; then geany "$SESSIONDIR/${filename// /_}.desk" fi fi } } restoresession() { sessfile="$1" DESK="$2" echo "$sessfile" cat "$SESSIONDIR/$sessfile" | { while IFS= read -r line do read -r D width height x y cmdline< <(echo $line) wmctrl -s ${DESK} ${cmdline} > /dev/null 2>&1 & # We need to wait for window to appear sleep ${waittime} wmctrl -r :ACTIVE: -b remove,maximized_vert,maximized_horz if [[ "$D" = "u" ]]; then xdotool key super+b; fi wmctrl -r :ACTIVE: -e 0,${x},${y},${width},${height} done } } overwrite() { echo "Not implemented" } listsessions() { ls -1 ${SESSIONDIR}| grep .desk } usage() { grep "^#:" $0 | while read DOC; do printf '%s\n' "${DOC###:}"; done exit } case "$1" in -s|save) savesession "$2";; -r|restore) restoresession "$2" "$3";; -o|overwrite) overwrite "$2" ;; -l|list) listsessions ;; -h|--help) usage;; *) usage;; esac exit 0