Icono del sitio Shakaran

Aprende a cerrar/guardar/restaurar la sesion Gnome por terminal y haz que guarde tus aplicaciones


Este articulo no hablara de como apagar o reiniciar tu ordenador por terminal (algo bastante comentado en google). Sino de algo quizás más útil como es cerrar la sesión de Gnome en la que un usuario se encuentre logueado.

El artículo tiene algunas explicaciones para desarrolladores y curiosos, si esto no te interesara, dirígete hacia la parte central de “Guardar y restaurar sesiones de gnome-session“, donde se explican los comandos imprescindibles.

Esto es útil, para entornos de desarrollo o testing, en los que por ejemplo puedes quedarte sin gnome-panel o fallarte el nuevo interfaz unity o puedes perder widgets con los que cerrar la sesión (pero no quieres apagar el ordenador o reiniciarlo, ni tampoco cerrar todas las X perdiendo tus aplicaciones abiertas o disposición de ventanas).

A partir de la versión 2.24 de Gnome se hizo una total reescritura del manejador de sesiones que permite guardar y restaurar sesiones.

Disclaimer: Aunque por ahora una de las principales habilidades de gnome-session sean Guardar y Restaurar tu sesión en Gnome, ten en mente que el guardado y restaurado en algunas aplicaciones no es completamente funcional, por ejemplo en Firefox, Thunderbird o OpenOffice que ignoraran completamente al administrador de sesiones.

¿Como funciona?

Realmente no es muy complicado, gnome-session implementa un mecanismo de autoinicio que determina que aplicaciones serán lanzadas para una determinada sesión. Para ello, simplemente necesita un archivo .desktop que define la aplicación y sus parámetros.

Puedes ejecutar:

$ gnome-session-properties

Para invocar al applet que lista todas las aplicaciones que serán lanzadas en tu sesión.

Los archivos .desktop son ubicados por defecto en el directorio /usr/share/gnome/autostart y para usuarios específicos se ubican sobre el directorio ~/.config/autostart.

Guardar y restaurar sesiones de gnome-session

La utilidad que permite guardar y restaurar sesiones es gnome-session-save, que dependiendo de sus parámetros realizaremos una u otra acción.

Para cerrar la sesión:

$ gnome-session-save --logout

Puede ser, que las aplicaciones que no respondan o ocupadas, si quieres inhibir el estado de la sesión y forzar el cerrado:

$ gnome-session-save --force-logout

También puedes forzar a que aparezca el dialogo estándar de cerrar sesión, con la opción también de cambiar usuario

$ gnome-session-save --logout-dialog

O el diálogo estándar de apagar, reiniciar y suspender:

$ gnome-session-save --shutdown-dialog

Si añades la opción --gui los posibles errores no se mostrarían en la terminal y se mostrarían la GUI en cajas de diálogo.

Existe otras opciones obsoletas (deprecated) como --kill que actúa igual que --logout-dialog y otra llamada --silent que si es usada con --kill actúa igual que --logout

Inconvenientes

1) Puede y es muy probable que con gnome-shell en el nuevo Gnome 3.0 no funcione o disponga de otro manejador de sesiones.

2) Otro inconveniente que parece haber (desconozco si prosigue en las nuevas versiones de Gnome) es que todas las aplicaciones aparecen en el mismo espacio de trabajo (workspace), es decir, el primero y para la geometría de las ventanas, implicaría tener algún script de preconfiguración establecida para el ancho/alto y posición X/Y, pero esto es solucionado en el siguiente apartado.

Script para generar guardado/restaurado de ficheros de autostart

Gracias a Matt Keenan, Ingeniero de Sun (ahora Oracle) y desarrollador de GNOME Desktop, podemos utilizar dos script que hizo en su día llamados save-session y restore-session.

Restore-session

#!/bin/bash
# name :  restore-session
# author : Matt Keenan (matt.keenan@sun.com)
# Date : Oct 2008
#
# restore-session is a quick means of restoring your apps locations
# and geometry. It can be used in conjunction with Gnome 2.24 gnome-sessiojn
# autostart feature, as the save session feature for gnome-session in Gnome
# 2.24 does not exist.
#
# It uses wnckprop to position and resize known application windows as
# specified and identified in $HOME/.config/restore-session.conf
#
# The format of restore-session.conf is :
#
#
#
# It has been written to work with both metacity and compiz, with metacity
# wnckprop --set-workspace is used, but as with compiz there is only one
# workspace and 4 viewports, the moving to another viewport  is achieved
# by increasing the X CoOrdinate by screen widths.

# Saved Session Data file
SAVED_SESSION=$HOME/.config/restore-session.conf

# Check if Compiz or metacity running, hacky would be nice to have
# something better
wnckprop --window=`wnckprop --list | head -1 | awk 'BEGIN {FS=": ";}{print $1;}'` | grep compiz > /dev/null
if [ $? -eq 0 ]; then
    compiz=1
else
    compiz=0
fi

# Get Screen width (only needed when using compiz)
if [ $compiz -eq 1 ]; then
    screen_width=`xdpyinfo | grep "  dimensions:" | awk ' {    \
        dimstr=substr($0, 18, 10);      \
        if (index(dimstr, "x") == 5) {  \
            print substr(dimstr, 1, 4); \
        } else {                        \
            print substr(dimstr, 1, 3); \
        }                               \
    }'`
fi

# Get List of current windows
wnckprop --list > /tmp/$$.wnckprop 2>&1

lineno=0
while read LINE
do
    if [ $lineno -eq 0 ]; then
        # Skip first line, just column headers
        let lineno=$lineno+1
    else
        win_title=`echo $LINE | awk '{print $1}'`
        win_workspace=`echo $LINE | awk '{print $2}'`
        win_x=`echo $LINE | awk '{print $3}'`
        win_y=`echo $LINE | awk '{print $4}'`
        win_width=`echo $LINE | awk '{print $5}'`
        win_height=`echo $LINE | awk '{print $6}'`

        win_id=`grep $win_title /tmp/$$.wnckprop | head -1 | awk 'BEGIN {FS=": ";}{print $1;}'`

        echo "$win_title $win_workspace $win_x $win_y $win_width $win_height"

        if [ "$win_id" != "" ]; then

            if [ $win_x -gt -1 ]; then
                x_opt="--set-x=$win_x"
            else
                x_opt="--set-x=$win_x"
            fi

            if [ $win_y -gt -1 ]; then
                y_opt="--set-y=$win_y"
            else
                y_opt="--set-y=$win_y"
            fi

            if [ $win_width -gt 0 ]; then
                width_opt="--set-width=$win_width"
            else
                width_opt=""
            fi

            if [ $win_height -gt 0 ]; then
                height_opt="--set-height=$win_height"
            else
                height_opt=""
            fi

            if [ $compiz -eq 1 ]; then
                # if x > current screen width then just use it. As it and
                # ignore workspace column otherwise use workspace column
                # to calculate new x coord to position in correct viewport
                if [ $win_x -gt $screen_width ]; then
                    x_opt="--set-x=$win_x"
                else
                    let new_x=$screen_width*$win_workspace
                    let new_x=$new_x+$win_x
                    x_opt="--set-x=$new_x"
                fi

                # echo "$win_title:$win_workspace : wnckprop --window=$win_id $x_opt $y_opt $width_opt $height_opt"
                wnckprop --window=$win_id $x_opt $y_opt $width_opt $height_opt
            else
                # echo "$win_title:$win_workspace : wnckprop --window=$win_id --set-workspace=$win_workspace $x_opt $y_opt $width_opt $height_opt"
                wnckprop --window=$win_id --set-workspace=$win_workspace $x_opt $y_opt $width_opt $height_opt
            fi
        else
            echo "$win_title:$win_workspace - Failed to get win_id"
        fi
    fi
done < $SAVED_SESSION

rm /tmp/$$.wnckprop

Este script lee la configuración guardada en ~/.config/restore-session.conf. Este archivo contine una lista de aplicaciones identificadas con su ubicación de coordenadas e información de tamaño. Cada linea tiene campos separados por un tabulador (carácter \t) con el siguiente formato:

NAME	WORKSPACE	X	Y	WIDTH	HEIGHT

Por ejemplo:

#NAME	WORKSPACE	X	Y	WIDTH	HEIGHT
Bugster 0	38	15	565	416
XChat	1	6	523	1376	492
GnomeTerminal1	0	397	266	593	719
GnomeTerminal2	0	1001	266	593	719
GnomeTerminal3	1	30	30	726	719
Thunderbird	1	18	3	1639	873
Mail 1	648	367	437	186
Firefox 0	667	92 650 141

La primera línea de cabecera con las columnas para legibilidad es ignorada.

La columna NAME (nombre) es una palabra simple con la identificación de la aplicación específica. En este ejemplo hay varios terminales, un chat, Thunderbirt, Firefox, localizados en diferentes espacios de trabajo (ten en mente que los espacios de trabajo se numeran desde 0).

Este script usa la utilidad wnckprop que para solaris y en paquetes de gnome-sun venia integrado, pero que para Ubuntu, debe instalarse ya que no se encuentra por defecto instalada luego debes instalar el paquete:

$ sudo apt-get install libwnck-dev

Por tanto, ahora solo necesitamos expandir el ejemplo superior. Ahora tendremos varios archivos .desktop en el directorio autostart, por ejemplo uno de un terminal podría ser:

[Desktop Entry]
Type=Application
Name=Terminal 1
Exec=gnome-terminal --title="GnomeTerminal1"
Icon=utilities-terminal
Comment=Run a command line shell

Observa como se especifica el título del terminal con el comando de CLI –title en gnome-terminal. Así, la próxima vez que se loguee la sesión, los terminales serán ejecutados.

Puedes preguntarte, que de esta forma no se restauran los tamaños de ventana y ubicaciones, pero tenemos varias formas de realizar esto.

La primera, que no es muy fiable, es establecer otro .desktop que llame a restore-session el mismo, pero no garantiza el orden de lanzado de las aplicaciones por el método de autostart y restore-session, podría ejecutarse ante que otras aplicaciones y fallaría al no poder establecer las propiedades de la ventana.

El segundo método, es situar un lanzador en tu panel, que ejecute este script, que aunque no es ideal, es un método simple para establecer las propiedades una vez que accedas.

Otra opción, es que si eres el desarrollador de la aplicación (por ejemplo, tengo pensamiento de incorporar un sistema así en Tivion en un futuro), es que leas la información al inicializar tu aplicación del fichero de restore-session.conf, de esta manera, garantizas situar tu aplicación donde el usuario la dejo al salir.

Save-session

#!/bin/bash
# name :  save-session
# author : Matt Keenan (matt.keenan@sun.com)
# Date : Oct 2008
#
# save-session is used in conjunction with restore-session, it is used to
# generate $HOME/.config/restore-session.conf file, which should be viewed
# and edited after generation to confirm accuracy.
#
# It uses wnckprop to determine workspace and geometry information.
#
# The format of restore-session.conf is :
#
#
#
# NOTE : If running compiz window manager, workspace location of windows
# is determined based on the X Co-ordinate. To ensure this is correct
# Ths script must be run from the first Viewport(worksace).
# For metacity this does not matter, as wnckprop will report the correct
# workspace.

function panel_or_nautilus() {
    wnckprop --window=$win_id | grep "Bottom Expanded Edge Panel" > /dev/null
    if [ $? -eq 0 ]; then
        echo "1"
    else
        wnckprop --window=$win_id | grep "x-nautilus-desktop" > /dev/null
        if [ $? -eq 0 ]; then
            echo "1"
        else
            echo "0"
        fi
    fi
}

# Saved Session Data file
SAVED_SESSION=$HOME/.config/restore-session.conf

if [ -s $SAVED_SESSION ]; then
    echo "Backing up previous $SAVED_SESSION file to $SAVED_SESSION.old.`date '+%d-%m-%y--%H:%M:%S'`"
    mv $SAVED_SESSION $SAVED_SESSION.old.`date '+%d-%m-%y--%H:%M:%S'`
fi

echo "#NAME	WORKSPACE	X	Y	WIDTH	HEIGHT" >> $SAVED_SESSION

# Check if Compiz or metacity running, hacky would be nice to have
# something better
wnckprop --window=`wnckprop --list | head -1 | awk 'BEGIN {FS=": ";}{print $1;}'` | grep compiz > /dev/null
if [ $? -eq 0 ]; then
    compiz=1
else
    compiz=0
fi

# Get Screen width (only needed when using compiz)
if [ $compiz -eq 1 ]; then
    screen_width=`xdpyinfo | grep "  dimensions:" | awk ' {    \
        dimstr=substr($0, 18, 10);      \
        if (index(dimstr, "x") == 5) {  \
            print substr(dimstr, 1, 4); \
        } else {                        \
            print substr(dimstr, 1, 3); \
        }                               \
    }'`
fi

# Get List of current windows
wnckprop --list > /tmp/$$.wnckprop 2>&1

while read LINE
do
    win_id=`echo $LINE | awk 'BEGIN {FS=": ";}{print $1;}'`

    echo "$LINE";

    if [ "$win_id" != "" ]; then

        # Skip panel and nautilus
        skip=`panel_or_nautilus`
        if [ $skip -eq 0 ]; then
            win_title=`wnckprop --window=$win_id | grep ^Name | awk '{ \
                title=$2; for (i=3; i<=NF; i++) title=title " " $i; print title;}'`             win_x=`wnckprop --window=$win_id | grep Geometry | awk '{print substr($6, 1, length($6)-1);}'`             win_y=`wnckprop --window=$win_id | grep Geometry | awk '{print substr($7, 1, length($7)-1);}'`             win_width=`wnckprop --window=$win_id | grep Geometry | awk '{print substr($8, 1, length($8)-1);}'`             win_height=`wnckprop --window=$win_id | grep Geometry | awk '{print $9;}'`             if [ $compiz -eq 1 ]; then                 # Workspace is determined based on X Co-ordinate / screen-width                 if [ $win_x -lt $screen_width ]; then                     win_workspace=0                 elif [ $win_x -lt 0 ]; then                     win_workspace=0                 else                     let win_workspace=$win_x/$screen_width                     if [ $win_workspace > 0 ]; then
                        let new_x=$screen_width*$win_workspace
                        let win_x=$win_x-$new_x
                    fi
                fi
            else
                win_workspace=`wnckprop --window=$win_id | grep Workspace | awk '{print $3;}'`
            fi

            # echo "$win_title	$win_workspace	$win_x	$win_y	$win_width	$win_height"
            echo "$win_title	$win_workspace	$win_x	$win_y	$win_width	$win_height" >> $SAVED_SESSION
        fi
    fi

done < /tmp/$$.wnckprop

echo "$SAVED_SESSION Generated"

rm /tmp/$$.wnckprop

Este segundo script, simplemente consigue el nombre, tamaño y propiedades de ubicación de la ventana de aplicación para todas las aplicaciones existentes en los distintos espacios de trabajo, generando el archivo ~/.config/restore-session.conf

El script podría mejorarse, ya que requiere edición manual para editar los nombres correctos, pero es un buen comienzo como script.

Fuentes

Artículo de Matt Keenan

Apartir del 21 de abril, el enlace estará en Oracle


Salir de la versión móvil