'manually' saving/restoring KDE sessions

This is a script to manually save/restore KDE sessions, as this feature seems either not to be implemented or not to be working (?). It could also be that nobody knows how to achieve this from within KDE. But it wasn’t a big deal to write a quick and dirty script to fill that gap and help this user (see thread linked below) or anyone in this situation. Also notice that one could do that differently (by rewriting each key/value pair with kwriteconfig)… but I was just to lazy.

KDE: How to save more than 1 session and choose one on login?

Code:


#! /bin/bash
#: Title       : ksession
#: Date Created: Sun Aug 26 17:55:55 PDT 2012 
#: Last Edit   : Sun Aug 26 23:02:18 PDT 2012
#: Author      : Agnelo de la Crotche (please_try_again)
#: Version     : 1.0
#: Description : save/restore 'named' KDE sessions
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#

ksmserver=~/.kde4/share/config/ksmserverrc
declare -a sessions
ver=1.0
prg=$(basename $0)


# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# functions
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

# use the popup library if found
which popup &>/dev/null && source $(which popup)

# use popup functions if available
function Error { 
	declare -F | grep -q 'error$' || msg Error $* 
	error "$*" || msg Error $* 
}

function Warn  { declare -F | grep -q 'warn$' && warn  "$*" || msg Warning $* ;}

function Choose { declare -F | grep -q 'choose$' || Error "function choose not available. Please install the popup library" ;}

# otherwise use this function:
function msg {
	Error=1 ; Warning=2 
	T=$1 ; shift
	cat << EOFMSG
$(tput setaf ${!T})
$T: $* 
$(tput sgr0)
EOFMSG
	[ "$T" == "Error" ] && exit
}

function syntax {

cat << EOFHELP
	
$prg $ver - Agnelo de la Crotche - 2012

usage:
	$prg option [session]

options:
	-c --clear            : clear all sessions
	-s --save <name>      : save current session as "name"
	-r --restore [<name>] : restore session "name" at next login
	-p --previous         : restore previous session
	-e --empty            : start with an empty session
	-h --help             : display this help
EOFHELP
exit
}

function sessionsClearConfirm {
	declare -F | grep -q 'ask$' && D=yes 
	case $DIALOG in
		ZENITY|KDIALOG|DIALOG) D=${D:+yes} ;;
		*) unset D ;;
	esac
	if [ "$D" ] ; then
		ask "Do you want to clear all saved sessions?"
	else
		declare -l yesno
		while [ "$yesno" != "y" -a "$yesno" != "n" ] ; do
			read -p "$(tput setaf 3)Do you want to clear all saved sessions? (y|n) $(tput sgr0)$(tput bold)" -N 1 yesno
			echo
			[ "$yesno" == "n" ] && return 1
			[ "$yesno" == "y" ] && return 0
			printf "%sPlease answer with n or y.%s
" "$(tput setaf 1)" "$(tput sgr0)"
		done
	fi	
}

function sessionsClear {
	if ( sessionsClearConfirm ) ; then
		rm ~/.kde4/share/config/ksmserverrc
		rm -r ~/.kde4/share/config/session/*
	fi
	exit
}


function sessionSave {
	kwriteconfig --file ksmserverrc --group General  --key loginMode --type string "restoreSavedSession"
	qdbus org.kde.ksmserver /KSMServer saveCurrentSessionAs "$1"
	exit
}

function sessionDefault {
	case $1 in
		restorePreviousLogout|default) kwriteconfig --file ksmserverrc --group General  --key loginMode --type string "$1" ;;
		*) Error "Script internal error: Invalid value"
	esac
	exit
}

function sessionRestore {
	sessions=($(qdbus org.kde.ksmserver /KSMServer sessionList | sed '/default/d;/saved by user/d'))
	[ ${#sessions[li]} -eq 0 ] && Error "No session saved"
[/li]	if [ "$1" ] ; then
		SESSION=$1
	else
		if ( declare -F | grep -q ' choose$'); then
			SESSION=$(choose radio $(echo ${sessions[li]} | tr " " ",")) 
[/li]		else
			i=0
			while [ $i -le 0 -o $i -gt ${#sessions[li]} ] ; do
[/li]				echo ${sessions[li]}	| tr " " "[/li]" | awk '{ printf "%s) %s
", NR, $1 }; END { printf "Select a session (1-%s): ", NR}'
				read i ; i=$(($i*1)) ; SESSION=${sessions[$(($i-1))]} 
			done
		fi
	fi
	SESSION=${SESSION% *}
	echo ${sessions[li]} | tr " " "[/li]" | grep -q "^$SESSION$" || Error "Session not found"
	cp $ksmserver{,.old}
	sed '/^\[LegacySession: saved by user\]/,/^ *$/d;/^\[Session: saved by user\]/,/^ *$/d' $ksmserver.old > $ksmserver
	[ $(tail -1 $ksmserver | wc -w) -gt 0 ] || echo >> $ksmserver	
	sed -n "/^\[LegacySession: $SESSION/,/^ *$/p" $ksmserver.old | sed "s|\(LegacySession: \)$SESSION|\1saved by user|" >> $ksmserver
	sed -n "/^\[Session: $SESSION/,/^ *$/p" $ksmserver.old | sed "s|\(Session: \)$SESSION|\1saved by user|" >> $ksmserver
	kwriteconfig --file ksmserverrc --group General  --key loginMode --type string "restoreSavedSession"
	exit
}

# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

[ $# -eq 0 ] && syntax

args=`getopt -q -u -o hcpes:r:: -l help,clear,previous,empty,save:,restore:: -- "$@"`
set -- $args

for i; do
	case "$i" in
	-h|--help)   syntax ;;
	-c|--clear)  sessionsClear ;;
	-s|--save)   shift ; sessionSave $1 ;;
	-r|--restore) shift ; shift ; sessionRestore $1 ;;
	-p|--previous)  sessionDefault restorePreviousLogout ;;
	-e|--empty)     sessionDefault default ;;
	*) Error "invalid argument" ;;
	esac
done

To use this script you need to copy the popup library to some directory in your path (if you happened to install vmscripts from my repo, you will already have popup in /usr/bin): dialog boxes in bash scripts. It should also work without … but I didn’t have time to test it.

Usage:

[ul]
[li]have a look at the syntax first:
[/li]

$ ksession --help
ksession 1.0 - Agnelo de la Crotche - 2012

usage:
        ksession option [session]

options:
        -c --clear            : clear all sessions
        -s --save <name>      : save current session as "name"
        -r --restore [<name>] : restore session "name" at next login
        -p --previous         : restore previous session
        -e --empty            : start with an empty session
        -h --help             : display this help


[li]Start by clearing all sessions (and make sure you know what ‘clear’ means: you won’t obviously be able to restore them.)
[/li]

$ ksession --clear

[li]Open all program windows you want to save in “session1” Let us call it so. You can use the name you want but please, don’t use blanks in the name!
[/li][li]save this session with this command:
[/li]

$ ksession --save session1

[li]Now close some of these programs (or not) and open some other you want to save in “session2”. Then save this session with:
[/li]

$ ksession --save session2

[li]Repeat this operation for any additional session if needed.
[/li][li]You won’t be able to select the saved session at login … well it would be do-able by wrting a wrapper for startkde, but that would bring us too far. But you can choose the next session just before login out. Better than nothing (?). So before login out, select the session you want to be started at next login with:
[/li]

$ ksession --restore session1

or simply, without argument:

$ ksession --restore

and select the session you want in the list (remember to install “popup” to enjoy kde dialogs).
[li]Log out/re-log in and you should be in session1
[/li][/ul]

I tried with 2 sessions and it works … but don’t do anything else! (don’t try to save/restore sessions or change session settings in KDE).
If you want to log in in an emplty sessions next time, use:

ksession --empty

or if you just want to reopen the last session, use:

ksession --previous

Hope it helps.

It might have bugs, but you have the code. So feel free to fix itI do not intend to maintain such a script - as I rarely use KDE anyway.

Excellent script. Thanks for posting it.

This really needs to be integrated into the KDE Activity system including the option of session selection at start up.

Unfortunately, I would not know where to begin.

BTW: It works fine with or witthout the popup script.

On 05/28/2013 10:36 AM, andypotter wrote:
> This really needs to be integrated into the KDE Activity system

you are welcome to log your good idea into openFATE, here
https://features.opensuse.org/

there it can compete for developer interest against all the other
good ideas around!! (here it is just a comment unlikely for any
developer to notice–they seldom come here, and almost never come
looking for new ideas/work to do.)


dd