SEARCH

Enter your search query in the box above ^, or use the forum search tool.

You are not logged in.

#1 2011-05-03 12:01:08

Tunafish
#! Die Hard
From: the Netherlands
Registered: 2010-03-07
Posts: 1,204

Looking for a more friendly shutdown...

When i shutdown Ubuntu or (long ago) Windows, it would ask me to save unsaved documents. Is it possible to get this behavior in #! as well?

Thanks,
Tuna


sed 's/stress/relaxation/g'
Privacy & Security on #!

Offline

Be excellent to each other!

#2 2011-05-04 05:45:12

johnraff
nullglob
From: Nagoya, Japan
Registered: 2009-01-07
Posts: 4,148
Website

Re: Looking for a more friendly shutdown...

Easy. Make yourself a "shutdown.sh" script. Put in it whatever command you were previously using to shut down, and change your menu & keyboard to point to it. Then precede the shutdown command in the script with a line to call, for example, zenity, to confirm. eg:

zenity --question --title='Shutdown?' --text='Please save any documents before continuing. Press "Yes" when ready, or "No" to cancel shutdown.' || exit 

John
--------------------
( a boring Japan blog , Japan Links, idle twitterings  and GitStuff )
#! forum moderator    BunsenLabs

Offline

#3 2011-05-04 09:42:43

Tunafish
#! Die Hard
From: the Netherlands
Registered: 2010-03-07
Posts: 1,204

Re: Looking for a more friendly shutdown...

@Johnraff:
Thanks, but not completely what i'm looking for.

In Ubuntu and windows, the machine will only ask this question, if there are unsaved documents, not always. So what i need is a script to kill all running applications in a friendly way (asking to save documents first if necessary) and when finished do a shutdown.

Edit: I searched theses forums and you've solved this one before... smile
http://crunchbanglinux.org/forums/topic … llwindows/
In post 17 you even suggest to add the script to your "shutdown" script.
Do you have the best version from the "CloseAllWindows" script for me?

Thanks,
Tuna

Last edited by Tunafish (2011-05-04 09:57:09)


sed 's/stress/relaxation/g'
Privacy & Security on #!

Offline

#4 2011-05-04 10:11:14

Tunafish
#! Die Hard
From: the Netherlands
Registered: 2010-03-07
Posts: 1,204

Re: Looking for a more friendly shutdown...

I did this:

#!/bin/bash
ob_windows_list=(`wmctrl -l | awk '{print $4}'`)

for i in ${ob_windows_list[@]}
do
    wmctrl -c  $i
done
 
gdm-control --shutdown
openbox --exit

This will ask to save documents if necessary, but it doesn't wait for me to do so. How do i solve this?

Even better would be to close the last window, wait till it's done, than close the next, etc.

Last edited by Tunafish (2011-05-04 11:13:37)


sed 's/stress/relaxation/g'
Privacy & Security on #!

Offline

#5 2011-05-05 04:36:04

johnraff
nullglob
From: Nagoya, Japan
Registered: 2009-01-07
Posts: 4,148
Website

Re: Looking for a more friendly shutdown...

I never got round to adding that to my shutdown script, but it seems to be getting near what you want.

Tunafish wrote:

I did this:

#!/bin/bash
ob_windows_list=(`wmctrl -l | awk '{print $4}'`)

for i in ${ob_windows_list[@]}
do
    wmctrl -c  $i
done
 
gdm-control --shutdown
openbox --exit

This will ask to save documents if necessary,

How?

...but it doesn't wait for me to do so. How do i solve this?

So you need some way of knowing if an app has unsaved data or not? Not sure about that.

Even better would be to close the last window, wait till it's done, than close the next, etc.

The 'do... done' loop waits till each command has completed before doing the next. Do you mean you'd like to close the windows in reverse order, doing the newest first?

edit: I was wrong there - the wmctrl command seems to send out the signal then move straight on to the next window, without waiting for each one to close. However, I was forgetting that a lot of apps have their own built-in checks and will ask you if you want to save before closing. I just tried that wmctrl code with a couple of leafpad windows with unsaved data and they both put up a popup to confirm the closure. So that bit might be OK.

But that still leaves the problem of how to give you time to deal with the popups before going into the system shutdown bit, which will just close everything, saved or not.

Last edited by johnraff (2011-05-05 04:54:24)


John
--------------------
( a boring Japan blog , Japan Links, idle twitterings  and GitStuff )
#! forum moderator    BunsenLabs

Offline

#6 2011-05-05 08:27:01

Tunafish
#! Die Hard
From: the Netherlands
Registered: 2010-03-07
Posts: 1,204

Re: Looking for a more friendly shutdown...

So... now i have this:

#!/bin/bash
#~/bin/safeshutdown
# depens on wmctrl

ob_windows_list=(`wmctrl -l | awk '{print $4}'`)

openwindows=$(wmctrl -l | grep -v " N/A " | wc -l)
while [ $openwindows -gt 0 ]
do
    for i in ${ob_windows_list[@]}
    do
        wmctrl -c $i
    done
    openwindows=$(wmctrl -l | grep -v " N/A " | wc -l)
done

gdm-control --shutdown
openbox --exit

Terrible script to test as it closes all your windows all the time sad 
(of course i left out the shutdown part during testing...)

But i still welcome better ideas than mine. How is shutdown done in Ubuntu or Debian Mint? That might be interesting...

Last edited by Tunafish (2011-05-05 15:41:20)


sed 's/stress/relaxation/g'
Privacy & Security on #!

Offline

#7 2011-05-06 05:38:15

johnraff
nullglob
From: Nagoya, Japan
Registered: 2009-01-07
Posts: 4,148
Website

Re: Looking for a more friendly shutdown...

wmctrl -lp | awk '{print $5 " " $3}'

gives you the pid of each window after its name. Don't know if that would be any use...


John
--------------------
( a boring Japan blog , Japan Links, idle twitterings  and GitStuff )
#! forum moderator    BunsenLabs

Offline

#8 2011-06-10 05:59:42

johnraff
nullglob
From: Nagoya, Japan
Registered: 2009-01-07
Posts: 4,148
Website

Re: Looking for a more friendly shutdown...

Hi tuna smile
I've been planning to add this to my shutdown for a while now, but just yesterday I wanted to shut my laptop down quickly (a customer walked into Raffles roll ) and remembered how useful it would be.

Do you mind if I throw in a couple of suggestions? (...er, I am anyway...)

1) It might make things a bit cleaner to miss out "system" type windows from the closedown list. They'll get closed anyway, and there's no data to save. I mean things like conky, tint2 or ADeskBar. It's easy enough to get awk to skip those items like this:

ob_windows_list=(`wmctrl -l | awk '!/Conky|tint2|ADeskBar/{print $4}'`)

The stuff between the two / is a regular expression, and the ! says "not" so any lines that match that expression are not printed. Maybe it's neater to make an IGNORE variable first, with all the windows you don't want to mess with (run wmctrl -l to see how they're named) then add it to the awk line, like this:

IGNORE='Conky|tint2|ADeskBar|Desktop'
ob_windows_list=($(wmctrl -l | awk '!/'$IGNORE'/{print $4}'))

(The Desktop item is xfdesktop, which I'm using with openbox.) Of course now we'll have to change the openwindows variable too. awk can substitute for grep:

openwindows=$(wmctrl -l | awk '!/'$IGNORE'/' | wc -l)

2) Running your script in a terminal I see that it's coing through that loop closing windows over and over again as long as there's one still open. Probably no harm done, but it might be keeping the processor busy when it could be doing something else? Perhaps add a 'sleep 0.5' inside the loop to slow it down? I'm trying to think of a way to avoid having that while loop altogether, and might post something next week...

3) wmctrl -R "$i" will bring the window up to your current desktop and give it focus. Might be handy if you want to respond to a popup but when I just tried it in the script of course the loop went round and round so all the windows came up one after another roll

Anyway, this is a nice idea Tuna smile


John
--------------------
( a boring Japan blog , Japan Links, idle twitterings  and GitStuff )
#! forum moderator    BunsenLabs

Offline

#9 2011-06-10 07:48:07

Tunafish
#! Die Hard
From: the Netherlands
Registered: 2010-03-07
Posts: 1,204

Re: Looking for a more friendly shutdown...

johnraff wrote:

Do you mind if I throw in a couple of suggestions? (...er, I am anyway...)

Great! I was hoping someone would jump on this train (well.... it's more like a old locomotive or something), so we can improve this.

johnraff wrote:

It's easy enough to get awk to skip those items like this:

ob_windows_list=(`wmctrl -l | awk '!/Conky|tint2|ADeskBar/{print $4}'`)

I'll try this and implement it. There have to be changes to the openwindows counter as well.

johnraff wrote:

2) Running your script in a terminal I see that it's coing through that loop closing windows over and over again as long as there's one still open. Probably no harm done, but it might be keeping the processor busy when it could be doing something else? Perhaps add a 'sleep 0.5' inside the loop to slow it down? I'm trying to think of a way to avoid having that while loop altogether, and might post something next week...

What i tried to do was something like:
for i in ${ob_windows_list[@]}
    do
        'close window'
        if 'window is closed' then go to the next window in the list
    done

I just couldn't find a way to check if the window was really closed. I could check if a program is still in the list, but that might be a different instance. So you should get the exact program id, try to close that one (not just gedit for example), check if that instance still exists and than continue.

That way the exceptions list in 1) isn't necessary anymore. Tint2 will be close, and that's it.

johnraff wrote:

3) wmctrl -R "$i" will bring the window up to your current desktop and give it focus. Might be handy if you want to respond to a popup but when I just tried it in the script of course the loop went round and round so all the windows came up one after another roll

Might work with the one by one closing i suggested at 2)

Hope you/we can improve this thing. 
I hoped someone knows the way ubuntu (or any other distro, maybe Mint Debian) solves this.

Tuna


sed 's/stress/relaxation/g'
Privacy & Security on #!

Offline

#10 2011-06-10 13:09:45

slapfish
#! Die Hard
From: Athens, Greece
Registered: 2009-10-22
Posts: 601

Re: Looking for a more friendly shutdown...

I was playing around with the script and the best code I came up with is this:

ob_windows_list=$(wmctrl -l | awk '!/Conky|tint2|ADeskBar/{print $4}')
openwindowsnumber=$(wmctrl -l | awk '!/Conky|tint2|ADeskBar/' | wc -l)
openwindowsnumbertest=$(wmctrl -l | awk '!/Conky|tint2|ADeskBar/' | wc -l)

while [ $openwindowsnumber -gt 0 ]; 
do
    for i in ${ob_windows_list[@]}
    do
        wmctrl -R $i
        wmctrl -c $i
        openwindowsnumbertest=$(wmctrl -l | awk '!/Conky|tint2|ADeskBar/' | wc -l)
        
        until [ $openwindowsnumbertest -lt $openwindowsnumber ]; do
                openwindowsnumbertest=$(wmctrl -l | awk '!/Conky|tint2|ADeskBar/' | wc -l)
        done
        
    done
    openwindowsnumber=$(wmctrl -l | awk '!/Conky|tint2|ADeskBar/' | wc -l)
done

This way the windows are closing one by one and if saving or verification is needed the script waits. The problem is that if you choose to cancel the closing, the script should be trappted in an infinite loop. However on my tests it appears to be finishing. I'm guessing it counts the confirmation window as +1 window that tries to close and when you actually cancel the action and close the +1 window the loop test gets true and the script does finish.

I now have (or someone else) to find a workaround for the canceling thing...

Offline

#11 2011-06-10 13:16:17

slapfish
#! Die Hard
From: Athens, Greece
Registered: 2009-10-22
Posts: 601

Re: Looking for a more friendly shutdown...

I'm getting closer, but since I have almost no experience with scripting and programing, I'm getting a little bit confused on what it's going on. Anyway, I added one line and the script will ask one more time for any canceled closing action. But if you again chose to cancel  the closing then it stops. Here is the script:

ob_windows_list=$(wmctrl -l | awk '!/Conky|tint2|ADeskBar/{print $4}')
openwindowsnumber=$(wmctrl -l | awk '!/Conky|tint2|ADeskBar/' | wc -l)
openwindowsnumbertest=$(wmctrl -l | awk '!/Conky|tint2|ADeskBar/' | wc -l)

while [ $openwindowsnumber -gt 0 ]; 
do
    for i in ${ob_windows_list[@]}
    do
        wmctrl -R $i
        wmctrl -c $i
        openwindowsnumbertest=$(wmctrl -l | awk '!/Conky|tint2|ADeskBar/' | wc -l)
        until [ $openwindowsnumbertest -lt $openwindowsnumber ]; do
            openwindowsnumbertest=$(wmctrl -l | awk '!/Conky|tint2|ADeskBar/' | wc -l)
        done
    done
    ob_windows_list=$(wmctrl -l | awk '!/Conky|tint2|ADeskBar/{print $4}')
    openwindowsnumber=$(wmctrl -l | awk '!/Conky|tint2|ADeskBar/' | wc -l)
done

EDIT: I was wrong about the loop. It actually gets trapped in an infinite loop if you keep canceling the closing and It might also not waiting for one to get canceled. I'll have to look into it a little more (or much more).

Last edited by slapfish (2011-06-10 13:24:26)

Offline

#12 2011-06-10 17:51:51

johnraff
nullglob
From: Nagoya, Japan
Registered: 2009-01-07
Posts: 4,148
Website

Re: Looking for a more friendly shutdown...

This seems much harder than it should be, somehow. This last day I've been trying to find some simple test for whether a particular window is open or not, but without real success.

Ideas so far:

* Use the window id number instead of title, because it's unique:

ob_windows_list=($(wmctrl -l | awk '!/'$IGNORE'/{print $1}'))

then to close the window:

wmctrl -i -c "$i"

Unfortunately this returns "0" even if the window id doesn't exist, so it's no good as an open-or-not test.

* Use the full title ($4, $5...), not just the first word ($4):

ob_windows_list=($(wmctrl -l | awk '!/'$IGNORE'/{$1=$2=$3="";sub("   ","");print}'))

If the title doesn't match any open window then 'wmctrl -c "$i"' will return "1" which gives us some feedback.

* If we have the pid, we can run:

kill -0 $pid

to test if the process exists.

 wmctrl -lp | awk '!/'$IGNORE'/{print$3}'

will print out the pid numbers, but there doesn't seem to be any way to close a window with wmctrl by its pid. 'kill -HUP $pid' just shuts it down without any confirming popups, unless there's a different signal that would work. (I've tried HUP, INT, and TERM.) Maybe we could make a bunch of arrays holding both the pid numbers and window ids or titles, and run through them in turn, using the id to close the window and the pid to test if it's closed?

tunafish wrote:

What i tried to do was something like:
for i in ${ob_windows_list[@]}
    do
        'close window'
        if 'window is closed' then go to the next window in the list
    done

I just couldn't find a way to check if the window was really closed.

This is the core of the problem I suppose. neutral


John
--------------------
( a boring Japan blog , Japan Links, idle twitterings  and GitStuff )
#! forum moderator    BunsenLabs

Offline

#13 2011-06-10 18:20:46

johnraff
nullglob
From: Nagoya, Japan
Registered: 2009-01-07
Posts: 4,148
Website

Re: Looking for a more friendly shutdown...

It's past 3am and I must get to bed, but is this getting any closer?

#!/bin/bash
# close_all_windows
# depends on wmctrl

IGNORE='Conky|tint2|ADeskBar|Desktop'
ob_windows_list=($(wmctrl -lp | awk '!/'$IGNORE'/{print $1 "|" $3}')) # get ids and pids, separated by pipe symbol
for i in "${ob_windows_list[@]}"
do
    wmctrl -i -R ${i%|*}
    echo "closing ${i%|*}"
    wmctrl -i -c ${i%|*}
    while kill -0 ${i#*|} >/dev/null 2>&1
    do
        echo "waiting for ${i#*|}"
        sleep 0.5
    done
done

exit

The "echo" bits are just for debugging.


John
--------------------
( a boring Japan blog , Japan Links, idle twitterings  and GitStuff )
#! forum moderator    BunsenLabs

Offline

#14 2011-06-11 17:23:00

johnraff
nullglob
From: Nagoya, Japan
Registered: 2009-01-07
Posts: 4,148
Website

Re: Looking for a more friendly shutdown...

Had a rethink about using the window's pid to test if it's still open or not - there are a couple of problems:
1) Some windows don't let wmctrl know their pid - conky and tint2 in particular - and the pid shows as "0". OK if they're being ignored anyway, but if a window with pid = 0 is closed the script will hang in an endless loop waiting for 'kill -0 0' to return 1 which it never does.
2) Sometimes windows share the same pid, eg if you're using urxvtd then all the urxvtc terminal windows have the same pid, so again the script will hang after closing the first one because the pid doesn't go away.

So how about staying with the window IDs and checking the output of 'wmctrl -l' with grep instead? If you already know the window's ID number is $i then

wmctrl -l | grep "$i" >/dev/null 2>&1

will return 0 if the window is open and 1 if it's closed. It's slower than using kill with the pid, but maybe it doesn't really matter.

That gives us a close_all_windows script something like this:

#!/bin/bash
# close_all_windows
# depends on wmctrl

IGNORE='Conky|tint2|ADeskBar|Desktop' # leave these windows alone

ob_windows_list=($(wmctrl -l | awk '!/'$IGNORE'/{print $1}')) # get ids
for i in "${ob_windows_list[@]}"
do
    wmctrl -i -R $i
    wmctrl -i -c $i
    while wmctrl -l | grep "$i" >/dev/null 2>&1
    do
        sleep 0.5
    done
done

exit

This seems to be working nicely for me now, and I've added a call to this script from my shutdown script. I think it's worth keeping it as a separate script in the modular unix tradition, because there might be other times when you want to tidy everything away - like before doing a backup for example. cool


John
--------------------
( a boring Japan blog , Japan Links, idle twitterings  and GitStuff )
#! forum moderator    BunsenLabs

Offline

#15 2011-06-12 10:43:36

Tunafish
#! Die Hard
From: the Netherlands
Registered: 2010-03-07
Posts: 1,204

Re: Looking for a more friendly shutdown...

johnraff wrote:

Had a rethink about using the window's pid to test if it's still open or not - there are a couple of problems:
1) Some windows don't let wmctrl know their pid - conky and tint2 in particular - and the pid shows as "0". OK if they're being ignored anyway, but if a window with pid = 0 is closed the script will hang in an endless loop waiting for 'kill -0 0' to return 1 which it never does.
2) Sometimes windows share the same pid, eg if you're using urxvtd then all the urxvtc terminal windows have the same pid, so again the script will hang after closing the first one because the pid doesn't go away.

So how about staying with the window IDs and checking the output of 'wmctrl -l' with grep instead? If you already know the window's ID number is $i then

wmctrl -l | grep "$i" >/dev/null 2>&1

will return 0 if the window is open and 1 if it's closed. It's slower than using kill with the pid, but maybe it doesn't really matter.

That gives us a close_all_windows script something like this:

#!/bin/bash
# close_all_windows
# depends on wmctrl

IGNORE='Conky|tint2|ADeskBar|Desktop' # leave these windows alone

ob_windows_list=($(wmctrl -l | awk '!/'$IGNORE'/{print $1}')) # get ids
for i in "${ob_windows_list[@]}"
do
    wmctrl -i -R $i
    wmctrl -i -c $i
    while wmctrl -l | grep "$i" >/dev/null 2>&1
    do
        sleep 0.5
    done
done

exit

This seems to be working nicely for me now, and I've added a call to this script from my shutdown script. I think it's worth keeping it as a separate script in the modular unix tradition, because there might be other times when you want to tidy everything away - like before doing a backup for example. cool

I'm testing it now.
A problem i noticed: when you're editing tint2rc with gedit, it will be ignored as well, and gets closed anyway.


sed 's/stress/relaxation/g'
Privacy & Security on #!

Offline

#16 2011-06-13 10:43:23

slapfish
#! Die Hard
From: Athens, Greece
Registered: 2009-10-22
Posts: 601

Re: Looking for a more friendly shutdown...

@Johnraff Excellent and beautiful code! If it's not too much trouble, can you explain me what is  " while wmctrl -l | grep "$i" >/dev/null 2>&1 " doing, please (the >/dev/null 2>&1 part)? I know that waiting 0.5sec isn't much but wouldn't an "echo $i" be more appropriate? If I have understand that correctly you can't leave the do/done empty, like " while [something] do "nothing" done ". Finally why ignore "Desktop"? which window are you trying to ignore?

I have also written a small safegdm-control script which I updated with your code. I'm posting it at the end. It's not anything special, just a case-option for shutdown/reboot/logout.

@Tunafish The first time I get to play with your code I have noticed that there was a problem with conky/adeskbar and I was killing them at the start of the script. For tint2 the  |grep -v " N/A " is enough, so with this embedded in the code gedit tint2rc will no more be ignored.

My version of the script for shutdown/reboot/logout:

#!/bin/bash
# safegdm-control for Shutdown/reboot/logout
# depens on wmctrl

case $1 in
   --shutdown) (gdm-control --shutdown) ;;
   --reboot) (gdm-control --reboot) ;;
   --logout) ;;
   *) (echo "Usage: safegdm-control { --shutdown | --reboot | --logout }")
        exit;;
esac

IGNORE='Conky|ADeskBar|Desktop' # leave these windows alone

ob_windows_list=($(wmctrl -l |  grep -v " N/A " | awk '!/'$IGNORE'/{print $1}')) # get ids
for i in "${ob_windows_list[@]}"
do
    wmctrl -i -R $i
    wmctrl -i -c $i
    while wmctrl -l | grep "$i" >/dev/null 2>&1
    do
        echo $i
    done
done

openbox --exit 

Offline

#17 2011-06-13 17:44:54

johnraff
nullglob
From: Nagoya, Japan
Registered: 2009-01-07
Posts: 4,148
Website

Re: Looking for a more friendly shutdown...

Tunafish wrote:

A problem i noticed: when you're editing tint2rc with gedit, it will be ignored as well, and gets closed anyway.

That's the sort of thing that comes  up I guess. Presumably the same thing would happen if you were editing conkyrc too, except that conky's title is "Conky" (uppercase C). That "N/A" thing in 'wmctrl -l' only seems to occur with tint2 so I suppose you could use that as a substitute for "tint2" in $IGNORE, alternatively modify the regular expression to only match 'tint2' as a whole word, so tint2rc wouldn't match.

slapfish wrote:

can you explain me what is  " while wmctrl -l | grep "$i" >/dev/null 2>&1 " doing, please (the >/dev/null 2>&1 part)?

The >/dev/null bit throws away the output of grep into the "bitbucket". We only want the return value 0 or 1 to tell us if grep found $i in 'wmctrl -l' or not. The 2>&1 part sends STDERR (file descriptor 2, error messages) to /dev/null along with STDOUT (f.d. 1) which is what gets redirected by default.

slapfish wrote:

I know that waiting 0.5sec isn't much but wouldn't an "echo $i" be more appropriate?

You can set the sleep to whatever you want. If it's long you will have to wait longer to find out if the window is closed, so the script will take a bit longer to run. If it's short the loop will go round and round, using processor power unnecessarily while waiting for the user to click a response in the app's popup window. I don't see what "echo $i" would do, except for debugging. Normally it would just be sent to ~/.xsession-errors, filling it up with repeated lines of $i.

slapfish wrote:

Finally why ignore "Desktop"? which window are you trying to ignore?

I'm using xfdesktop (to draw desktop icons with  openbox) and that's how it appears in 'wmctrl -l'. If you're not using it you don't need "Desktop" in $IGNORE. You should run 'wmctrl -l', have a look at what windows you'd like to be left open and make your own version of $IGNORE. (btw if you add "N/A" to $IGNORE then you don't need to remove it with grep.)

-----------------------------------------------------------

I've been wondering about that "waiting" loop actually. If the user chooses to cancel the closing of gedit, for example, in the popup that it puts up, then what would we like the script to do?
1) Go on waiting and running round that loop every 0.5 sec. until gedit is eventually closed, then continuing with the window-closing?
2) Do a timeout and if there are still open windows after eg 5 min. then use zenity to ask the user whether to abandon the closedown or not?
3) Do a timeout and just force windows to close (eg by getting the pid and using kill)?
4) Something else?

Any ideas? Right now I'm thinking maybe #2.


John
--------------------
( a boring Japan blog , Japan Links, idle twitterings  and GitStuff )
#! forum moderator    BunsenLabs

Offline

#18 2011-06-13 20:23:09

slapfish
#! Die Hard
From: Athens, Greece
Registered: 2009-10-22
Posts: 601

Re: Looking for a more friendly shutdown...

johnraff wrote:

That "N/A" thing in 'wmctrl -l' only seems to occur with tint2 so I suppose you could use that as a substitute for "tint2" in $IGNORE, alternatively modify the regular expression to only match 'tint2' as a whole word, so tint2rc wouldn't match.

I think I understood what those numbers are, and why tint2 has N/A. I guess it is on the man page but I'm too lazy to check. So, any window located in the 1st desktop gets "0", any on 2nd desktop gets "1" and so on; any window that is set to be visible on all desktops gets "-1" and (this is a guess) any panel gets no number, hence the N/A for tint2. I was wondering how safe would be to ignore all windows with -1. I never set any application to be visible on all desktops but I don't think that this is the case for everyone, so I have some serious doubts about that. I added N/A in $IGNORE but it didn't worked so I use the grep way from Tunafish's script. How can we set only 'tint2' and not tint2rc?

johnraff wrote:

We only want the return value 0 or 1 to tell us if grep found $i in 'wmctrl -l' or not. The 2>&1 part sends STDERR (file descriptor 2, error messages) to /dev/null along with STDOUT (f.d. 1) which is what gets redirected by default.

I'm not sure I get this but if I'm not tiring you please verify this: When $i is on the list the output is discarded and while loop continues, but if it's not then the STDERR of grep (??) is redirected to STDOUT and the while loop stops, right?? 

johnraff wrote:

If it's short the loop will go round and round, using processor power unnecessarily while waiting for the user to click a response in the app's popup window. I don't see what "echo $i" would do...

I see...I was using the "echo $i" as an alternative to "wait 0" (can this be used?). I'm changing it to 0.5 so I can save some power. thanks.

johnraff wrote:

I've been wondering about that "waiting" loop actually. If the user chooses to cancel the closing of gedit, for example, in the popup that it puts up, then what would we like the script to do?

2) Do a timeout and if there are still open windows after eg 5 min. then use zenity to ask the user whether to abandon the closedown or not?

Any ideas? Right now I'm thinking maybe #2.

I also think #2 is more appropriate, but I would set the timeout to 1min or 2mins at the most. Also, i think that the list of opened windows should be re-read in case another window have been opened during the timeout.

Offline

#19 2011-06-13 21:07:26

Tunafish
#! Die Hard
From: the Netherlands
Registered: 2010-03-07
Posts: 1,204

Re: Looking for a more friendly shutdown...

slapfish wrote:

I also think #2 is more appropriate, but I would set the timeout to 1min or 2mins at the most. Also, i think that the list of opened windows should be re-read in case another window have been opened during the timeout.

OH NO! That's going to complicate things even more. Maybe sent a message to the user... "Your computer is shutting down, please don't open any new windows! Get your hands off the keyboard and leave your mouse alone!"

I'm still waiting for someone who can bring us the shutdown script from Mint Debian... Clem? Omns? Corenominal?   

No wait... this is more fun.... smile

If only i had some more time these days to test this script...


sed 's/stress/relaxation/g'
Privacy & Security on #!

Offline

#20 2011-06-14 18:22:32

johnraff
nullglob
From: Nagoya, Japan
Registered: 2009-01-07
Posts: 4,148
Website

Re: Looking for a more friendly shutdown...

slapfish wrote:
johnraff wrote:

That "N/A" thing in 'wmctrl -l' only seems to occur with tint2 so I suppose you could use that as a substitute for "tint2" in $IGNORE, alternatively modify the regular expression to only match 'tint2' as a whole word, so tint2rc wouldn't match.

I think I understood what those numbers are, and why tint2 has N/A. ... So, any window located in the 1st desktop gets "0", any on 2nd desktop gets "1" and so on; any window that is set to be visible on all desktops gets "-1" and (this is a guess) any panel gets no number, hence the N/A for tint2.

I don't think that's right. The column showing the desktop number (0, 1, ... -1) is different from the column showing the computer hostname, which is where the "N/A" appears for tint2.  I've just found that Dillo also shows "N/A" there too, so it's not because tint2 is a panel, but, I guess, because tint2 (and Dillo) are unable to report that information for some reason.

I was wondering how safe would be to ignore all windows with -1. I never set any application to be visible on all desktops but I don't think that this is the case for everyone, so I have some serious doubts about that.

Ignoring windows with "-1" is an idea, yes.

I added N/A in $IGNORE but it didn't worked

Sorry, I forgot the "/" needed escaping, because it's used to mark the beginning and end of the regular expression. 'N\/A' should work.

How can we set only 'tint2' and not tint2rc?

It can be done by tightening up the regular expression in the variable IGNORE. The symbol $ marks the end of the string, so 'tint2$' only matches if 'tint2' comes right at the end, with nothing following, so 'tint2rc' wouldn't match. This kind of condition is probably OK for those others like Conky and ADeskBar too, except that Conky is followed by '(hostname)'. We can allow for that by saying that the word must either come at the end of the string, or else be followed by a space (or tab). That can be done with the sequence: '($|[ \t])', so 'tint2($|[ \t])' matches if tint2 is the last word in the string, or followed by a space or tab. Likewise for 'Conky($|[ \t])'. Finally, all those words are preceded by a space, so we can include that in our regex too, to make sure we don't pick up something like 'othertint2', ie: ' tint2($|[ \t])'. So we can treat all the apps the same:

IGNORE=' Conky($|[ \t])| tint2($|[ \t])| ADeskBar($|[ \t])| Desktop($|[ \t])'

Amazingly this seems to work. (Took a little sweat though.) I only learnt regular expressions last year or so, but would recommend checking them out - they can be used in all sorts of places. cool

johnraff wrote:

We only want the return value 0 or 1 to tell us if grep found $i in 'wmctrl -l' or not. The 2>&1 part sends STDERR (file descriptor 2, error messages) to /dev/null along with STDOUT (f.d. 1) which is what gets redirected by default.

I'm not sure I get this but if I'm not tiring you please verify this: When $i is on the list the output is discarded and while loop continues, but if it's not then the STDERR of grep (??) is redirected to STDOUT and the while loop stops, right??

That's not it, it's only the return value of the grep command that we're interested in. STDOUT and STDERR are both thrown away to /dev/null. (You can get the same result using 'grep -q' instead, but it's less portable.) Grep returns 0 if a match is found, 1 if not found. Every command in bash returns a value of 0 (true) or non-zero (false) as well as whatever it might have sent to STDOUT. This return value is read by things like while and if. Have a look at 'help while'  and 'help if'. smile

i think that the list of opened windows should be re-read in case another window have been opened during the timeout.

Not sure about this - I tend to agree with tunafish that it might be making things too complicated.

Anyway, here's the revised close_all_windows script:

#!/bin/bash
# close_all_windows
# depends on wmctrl

IGNORE=' Conky($|[ \t])| tint2($|[ \t])| ADeskBar($|[ \t])| Desktop($|[ \t])' # regular expression to check against window strings from wmctrl -l
ob_windows_list=($(wmctrl -l | awk '!/'"$IGNORE"'/{print $1}')) # get ids
for i in "${ob_windows_list[@]}"
do
    wmctrl -i -R $i
    wmctrl -i -c $i
    while wmctrl -l | grep "$i" >/dev/null 2>&1
    do
        sleep 0.5
    done
done

exit

edit: Sorry, I missed out the line where ob_window_list is defined, for some reason. roll Must give up posting in the early morning.
btw Note that $IGNORE needs to be in double quotes because it contains spaces.

Last edited by johnraff (2011-06-15 04:31:51)


John
--------------------
( a boring Japan blog , Japan Links, idle twitterings  and GitStuff )
#! forum moderator    BunsenLabs

Offline

#21 2011-07-07 04:25:13

anonymous
The Mystery Member
Registered: 2008-11-29
Posts: 9,419

Re: Looking for a more friendly shutdown...

Tunafish wrote:

I'm still waiting for someone who can bring us the shutdown script from Mint Debian... Clem? Omns? Corenominal?

I was curious about this though its just the shutdown dialog built-in to Gnome:

gnome-session-save --shutdown-dialog

Offline

#22 2011-07-08 11:06:08

Dev
Member
Registered: 2011-07-08
Posts: 27

Re: Looking for a more friendly shutdown...

Have you noticed that most applications, regardless whether they're for Windows or Linux tend to add an asterisk before or after the name of the application or the open document (whichever is shown in the titlebar).

Cases:
gedit (After opened document's name)
Blender (Before application name i.e.*Blender (path_to_document))

You could use this to determine whether the application has unsaved data or not.

Offline

#23 2011-07-08 11:14:36

Tunafish
#! Die Hard
From: the Netherlands
Registered: 2010-03-07
Posts: 1,204

Re: Looking for a more friendly shutdown...

Dev wrote:

Have you noticed that most applications, regardless whether they're for Windows or Linux tend to add an asterisk before or after the name of the application or the open document (whichever is shown in the titlebar).

Cases:
gedit (After opened document's name)
Blender (Before application name i.e.*Blender (path_to_document))

You could use this to determine whether the application has unsaved data or not.

My first thought was "why didn't I/we think about this?", but then i noticed libreoffice doesn't use the asterisk.


sed 's/stress/relaxation/g'
Privacy & Security on #!

Offline

#24 2011-07-08 11:42:36

Dev
Member
Registered: 2011-07-08
Posts: 27

Re: Looking for a more friendly shutdown...

Tunafish wrote:
Dev wrote:

Have you noticed that most applications, regardless whether they're for Windows or Linux tend to add an asterisk before or after the name of the application or the open document (whichever is shown in the titlebar).

Cases:
gedit (After opened document's name)
Blender (Before application name i.e.*Blender (path_to_document))

You could use this to determine whether the application has unsaved data or not.

My first thought was "why didn't I/we think about this?", but then i noticed libreoffice doesn't use the asterisk.

I don't have that installed, though AbiWord does use the asterisk, I'm not sure about OpenOffice.

Offline

Be excellent to each other!

#25 2011-07-09 05:06:31

johnraff
nullglob
From: Nagoya, Japan
Registered: 2009-01-07
Posts: 4,148
Website

Re: Looking for a more friendly shutdown...

...but won't all the apps that are smart enough to display that asterisk already be putting up a "save data?" box when wmctrl tells them to close?


John
--------------------
( a boring Japan blog , Japan Links, idle twitterings  and GitStuff )
#! forum moderator    BunsenLabs

Offline

Board footer

Powered by FluxBB

Copyright © 2012 CrunchBang Linux.
Proudly powered by Debian. Hosted by Linode.
Debian is a registered trademark of Software in the Public Interest, Inc.
Server: acrobat

Debian Logo