Gentoo Forums
Gentoo Forums
Gentoo Forums
Quick Search: in
HOWTO: Deactivate xscreensaver while watching online videos
View unanswered posts
View posts from last 24 hours

 
Reply to topic    Gentoo Forums Forum Index Documentation, Tips & Tricks
View previous topic :: View next topic  
Author Message
VinzC
Watchman
Watchman


Joined: 17 Apr 2004
Posts: 5098
Location: Dark side of the mood

PostPosted: Sun Jun 26, 2016 9:33 pm    Post subject: HOWTO: Deactivate xscreensaver while watching online videos Reply with quote

Hi all. This is a sequel from a thread I posted a while ago. I came out with this script today and I have just tested it while watching videos on Youtube with Firefox. The script can be updated for use with any browser though.

See also Syl20 nice & simple implementation.

The background story

I love xscreensaver. But I just hate it when I have to tuck it off while I'm away from the keyboard, watching videos, for instance. On one hand the developers of mplayer have come with a nifty solution: heartbeat-cmd. Unfortunately you can't expect Mozilla to implement the same trick. So we have to do it ourselves, right?...

Prerequisite

As krinn rightfully hints, /proc/pid/io may not always be available. You have to make sure your kernel configuration includes the following:
Kernel config:
Enable extended accounting over taskstats (CONFIG_TASK_XACCT)
* Enable per-task storage I/O accounting (CONFIG_TASK_IO_ACCOUNTING=y)

Note that very same configuration is required if you use iotop.

How does it work

It's best (IMHO) to have the script run on as many distributions as possible instead of relying on extensions or modules, which are browser- or desktop-environment-dependent. Xorg comes with plenty of tools, which used appropriately can get us close to what we want.

Instead of deactivating xscreensaver from within Firefox, we want to a) detect what the active (i.e. currently focused) window is, b) check the process it belongs to, c) if it is busy downloading (a video, whatever...) While a) and b) are easy, c) is less straightforward. How can we detect a browser that pulls down a video from Youtube? Or any video? Check the URL? No, too cumbersome.

A browser that shows a video is supposed to cause disk activity. In general (and it's true with Youtube) videos aren't downloaded at once (unless they're very short) but slowly enough to not hog up the whole bandwidth. That's the most daring assumption I made. If you check the kernel I/O information for a given process ID you'll see a few hints as to what amount of data a process is pulling off or throwing at the storage. Check write_bytes in /proc/<PID>/io for short.

If the browser doesn't write to the disk for 30 seconds the script exits. Otherwise it sends the deactivate beacon to xscreensaver.

EDIT: Here's an updated version that I run on my laptop. The update accounts for the presence of a power manager, which may co-exist with a screen saver such as xscreensaver. In such cases deactivate screen saving is just not enough. The trick I used is to switch to presentation mode (an underused featured, speaking for myself) to temporarily disable energy saving while the screen is busy but no input is detected. Since complexity slightly increased, I also included a self-explained help section, you know, just in case ;-).

Running it from the command line is also improved, along with rudimentary diagnostics. I also introduced a way to support other DE than just Xfce. I didn't implement it though but I thought of dynamically loading DE modules (see xfce_ prefixes. It would require a dedicated command line argument but it should be not too difficult to add.

One last note: it might interfere with the presentation settings on your machine. I don't use it at all so I didn't think of a non-intrusive solution. Feel free to comment & suggest if you use that feature with your power manager application 8) .

Important note: I also changed the command line interface, which now requires a -P option for gathering the DISPLAY variable.

Here's the script.

/usr/local/bin/keep-active.sh:
#!/bin/sh
#
# This script tries to inhibit screen saving while there's a browser
# which is detected active, i.e. exhibiting disk activity for a given
# amount of time. The detection algorithm is triggered only when the
# browser window is on the foreground, i.e. the window with the focus.
#
# The script may be run from the command line or a cron job. The main
# goal is to compensate for the lack of features in browsers to block
# or suspend power savings while the screen is busy, say rendering
# videos, for example.
#
# Author: Vinz C. <vinzc@users.sf.net>

# Configuration variables. These affect how long a program remains idle
# i.e. without disk activity. Disk activity is checked as many times as
# MAX_COUNT (in seconds) for a total amount of LOOP_DELAY x MAX_COUNT .
#
MAX_COUNT=3      # Number of times no disk activity is detected
LOOP_DELAY=10      # Seconds to wait once activity is detected
VERBOSE=false

# [Supposedly] read-only variable
NAME=${0##*/}      # This script's name

# Process watch indicators
last_write_bytes=0   # Most recent bytes written to disk
count=0         # Iteration count

# Writes a message to the standard error or the system log
# on a non interactive shell
message()
{
   tty -s && echo "$*">&2 || logger -t $NAME "$*"
}

# Writes an error message to the standard error or the system log
# on a non interactive shell and exit with a return code if non zero
error()
{
   local ret=$1
   shift && message "$*"
   [ $ret -eq 0 ] || exit $ret
}

# Writes a message to the standard error or the system log
# on a non interactive shell but only in verbose mode
verbose()
{
   $VERBOSE && message "$*"
}

# Find the DISPLAY environment variable of a given process
find_display()
{
   local PID=$(pgrep -u $UID $1) || return $?
   eval $(grep -Eoa 'DISPLAY=[:09.]+' /proc/$PID/environ)
}

# Return non-zero if the given process window has he focus on DISPLAY
#
# Force xprop formatting to output eval assignment expressions, such
# as '_NET_ACTIVE_WINDOW' and '_NET_WM_PID' (eval doesn't accept spaces
# around the equal sign.)
pid_if_active()
{
   # Get active window ID
   local _NET_ACTIVE_WINDOW
   eval $(xprop -root -notype -f _NET_ACTIVE_WINDOW 32x '=$0\n' _NET_ACTIVE_WINDOW 2>/dev/null)
   [ -n "$_NET_ACTIVE_WINDOW" ] || return 1

        # Get its process ID, set PID if found
   local _NET_WM_PID
   eval $(xprop -id $_NET_ACTIVE_WINDOW -notype -f _NET_WM_PID 32c '=$0\n' _NET_WM_PID 2>/dev/null)
   [ -n "$_NET_WM_PID" ] || return 1

        # Is it the process which name was passed as an argument?
        grep -Eqs "$@" /proc/$_NET_WM_PID/cmdline && PID=$_NET_WM_PID
}

# Deactivate (temporarily) the screensaver for DISPLAY
keep_active()
{
   # Keep useless babling out...
   DISPLAY=$DISPLAY xscreensaver-command -deactivate >/dev/null
}

# Xfce-specific: enable/disable presentation mode
xfce_presentation_mode()
{
   $XFCES_POWER_MGR && [ -n "$1" ] && xfconf-query -c xfce4-power-manager \
      -p /xfce4-power-manager/presentation-mode -s $1
}

# Xfce-specific: deactivate screen saver and set presentation mode
# On Xfce presentation mode doesn't (seem to) prevent xsvreensaver
# from activating itself so both must be taken care of.
xfce_keep_active()
{
   keep_active
   xfce_presentation_mode true
}

usage()
{
   cat <<-EOF
   Usage: $NAME [-h][-P name][-d delay][-c count][-v][--debug] process

   Watch for disk activity of a process and temporarily disable power saving
   until no disk activity is detected. This script is intended for use when
   watching videos in a[ny] browser since none of them include features to
   disable power saving while the screen is busy and input is idle.

   process      Process (typically a browser name (not PID) to watch for.

   -P name      Fetch the DISPLAY environment variable from process name.
          If run from Xfce "name" will be xfce4-session. This is
          useful when running multiple DE or on a machine with more
          than one user account.
          The DISPLAY environment variable is deduced and passed to
          \`xprop´ and other applications that need it to work.

   -d delay   Delay (in seconds) to wait between loops once disk activity
          is detected.

   -c count   Loop no more than \`count´ if there's no disk activity.

   -v      Verbose mode (e.g. when run from the command line)

   --debug      Run the script with \`set -x´

   -h      This help screen.

   DESCRIPTION

   This script may be run as a cron job, in whch case -P is required for a
   valid DISPLAY variable to exist for monitoring X properties. It can also
   be run from the command line, in a terminal or from a TTY. In the latter
   case the argumen -P is also required and for the same reasons.

   The algorithm used in this script assumes every browser caches what it
   fetches from the interwebs, which should include video streams as well.
   So it might fail in very predictible circumstances and specific contexts.

   The script first detects if the process, which name is passed as an argument
   has its window in the foreground then monitors disk activity. Power saving
   is temporarily disabled and presentation mode enabled (if present) as soon
   as disk activity is detected. If no disk activity is detected then power
   saving is "restored" — i.e. set to default values because the script is
   stateless.

   USE CASES

   When run as a cron job the period should be less than the idle delay that
   triggers power (or screen) saving. For example, on a laptop where screen
   blanking occurs after 20 minues and xscreensaver is run after 10 minutes,
   the script might need to run every five minutes.
   EOF
}

# Parse command line arguments
while getopts "hP:vc:d:-:" opt; do
   case $opt in
   P)   find_display $OPTARG || error $? "No DISPLAY found for $OPTARG." ;;
   d)   LOOP_DELAY=$OPTARG ;;
   c)   MAX_COUNT=$OPTARG ;;
   v)   VERBOSE=true ;;
   h)   usage && exit 0 ;;
   -)   case "$OPTARG" in
      debug)   set -x ;;
      esac ;;
   ?)   usage && exit 1 ;;
   esac
done && shift $((OPTIND - 1)) || exit $?

# Don't run twice on the same process
pgrep -u $UID -f "$NAME" | grep -v $$ | xargs ps | grep -qE "$0\s+.*$1" && \
   message "Already watching ..." && \
   exit 0

# Abort if there's no detected DISPLAY
[ -n "$DISPLAY" ] || error $? "No display found."
export DISPLAY

pid_if_active $1 || exit 0
verbose "Watching $PID ..."


# Xfce-specific: Detect the presence of a (running) power manager
XFCE_POWER_MGR=false
pgrep -u $UID -f 'xfce4-power-manager' >/dev/null && XFCE_POWER_MGR=true
$XFCE_POWER_MGR && verbose "Using Xfce power manager"

# Set/reset presentation settings on exit (disabled by default
# except when disk activity is detected while the process has
# the focus)
$XFCE_POWER_MGR && trap "xfce_presentation_mode false" EXIT INT


while [ $count -lt $MAX_COUNT ]; do
   # Check active window process. If the window is not active,
   # power saving will be restored
   pid_if_active $1 || exit 0

   # Check how many bytes the process has written to disk.
   # The loop will track the process for as long as it detects
   # some disk activity...
   eval $(sed -rn '/^write_bytes/s/:\s+/=/p' /proc/$PID/io || echo write_bytes=0)
   if [ $last_write_bytes -ne $write_bytes ]; then
      if [ $last_write_bytes -ne 0 ]; then
         xfce_keep_active
         verbose "Detected $((write_bytes - last_write_bytes)) bytes written"
      fi
      last_write_bytes=$write_bytes
      count=0
   else
      (( count++ ))
      verbose "$NAME: No activity detected ($count)"
   fi
   sleep ${LOOP_DELAY}
done

# This forces a clean exit code if run from cron:
exit 0


EDIT: Bug fixed in the 10s loop; every time the script is executed might prevent the screensaver from running for good since last_write_bytes always starts from 0, which always differs from what's in /proc/$_NET_WM_PID/io on the first iteration.

I successfully ran it from a cron job for a couple of hours while watching videos on Youtube:

crontab -e:
*/5 * * * *     /usr/local/bin/keep-active.sh -P xfce4-session firefox

The script runs with bash. Making it run with dash shouldn't be too difficult. On my machine the screen saver delay is set to 10 minutes. So far it has been enough. The screen saver started as expected after I closed the video tab and left my machine idle for a little more than 10 minutes. Not sure one needs to close the video tab though.

One caveat is that the screen saver will also be deactivated if you leave your browser active while downloading something. Just switch to another window to fix that.

If you want to check, say, seamonkey and firefox, thanks to the grep clause:
crontab -e:
*/5 * * * *     /usr/local/bin/keep-active.sh -P xfce4-session 'seamonkey|firefox'

Hope this helps.
_________________
Gentoo addict: tomorrow I quit, I promise!... Just one more emerge...
1739!


Last edited by VinzC on Sun Dec 23, 2018 8:10 pm; edited 6 times in total
Back to top
View user's profile Send private message
krinn
Watchman
Watchman


Joined: 02 May 2003
Posts: 7470

PostPosted: Mon Jun 27, 2016 11:11 am    Post subject: Reply with quote

some notes:
Code:
 sleep 3 && xprop -root -notype -f _NET_ACTIVE_WINDOW 32x '=$0\n' _NET_ACTIVE_WINDOW
(sleep 3 so i have time to click on firefox windows)
_NET_ACTIVE_WINDOW=0x100008e
xprop -id 0x100008e -notype -f _NET_WM_PID 32c '=$0\n' _NET_WM_PID
_NET_WM_PID=5939

Code:
pidof firefox
5939

Code:
LANG=C ls /proc/5939/i*
ls: cannot access '/proc/5939/i*': No such file or directory


- are you sure /proc/pid/io is always there? for my firefox i have none. making the test for write_bytes not that reliable
- i fail to see the fullscreen check. my tests were made with firefox not fullscreen and they pass it well.

edit: in case it help, my "dirty" solve to that problem is: open vlc with a movie, hit pause: vlc disable screen saving (i have no screensaver to disable myself, except the monitors getting off)
Back to top
View user's profile Send private message
VinzC
Watchman
Watchman


Joined: 17 Apr 2004
Posts: 5098
Location: Dark side of the mood

PostPosted: Mon Jun 27, 2016 11:36 am    Post subject: Reply with quote

krinn wrote:
some notes:
...
- are you sure /proc/pid/io is always there? for my firefox i have none. making the test for write_bytes not that reliable
- i fail to see the fullscreen check. my tests were made with firefox not fullscreen and they pass it well.

Dumb me!... I wrote this HOWTO right before going to sleep. Indeed there's no check for _NET_WM_STATE_FULLSCREEN as I later acknowledged any focused web browser window that is using storage continuously must mean to deactivate the screen saver... So the check was there in a first draft of my script, now it's gone. So indeed if you are viewing videos, the screen saver should be deactivated regardless of the full screen state. I'll update my post accordingly.

As for your second point, I can tell it's also present on Manjaro, which runs my laptop. It's filed in your kernel config "Enable per-task storage I/O accounting" (CONFIG_TASK_IO_ACCOUNTING).

krinn wrote:
edit: in case it help, my "dirty" solve to that problem is: open vlc with a movie, hit pause: vlc disable screen saving (i have no screensaver to disable myself, except the monitors getting off)

I don't have VLC on my Gentoo machine and wanted as few dependencies as possible.
_________________
Gentoo addict: tomorrow I quit, I promise!... Just one more emerge...
1739!
Back to top
View user's profile Send private message
krinn
Watchman
Watchman


Joined: 02 May 2003
Posts: 7470

PostPosted: Mon Jun 27, 2016 3:00 pm    Post subject: Reply with quote

Code:
grep CONFIG_TASK /usr/src/linux/.config
CONFIG_TASKSTATS=y
CONFIG_TASK_DELAY_ACCT=y
# CONFIG_TASK_XACCT is not set
# CONFIG_TASKS_RCU is not set


Well at least good to note it need a kernel option, but from my kernel, it also mean some minimal kernel version. (i'm using 3.18.30)
Back to top
View user's profile Send private message
VinzC
Watchman
Watchman


Joined: 17 Apr 2004
Posts: 5098
Location: Dark side of the mood

PostPosted: Tue Jun 28, 2016 2:48 pm    Post subject: Reply with quote

krinn wrote:
Code:
grep CONFIG_TASK /usr/src/linux/.config
CONFIG_TASKSTATS=y
CONFIG_TASK_DELAY_ACCT=y
# CONFIG_TASK_XACCT is not set
# CONFIG_TASKS_RCU is not set


Well at least good to note it need a kernel option, but from my kernel, it also mean some minimal kernel version. (i'm using 3.18.30)

You need to enable CONFIG_TASK_XACCT to see CONFIG_TASK_IO_ACCOUNTING. Updating the thread :-) ... Done.
_________________
Gentoo addict: tomorrow I quit, I promise!... Just one more emerge...
1739!
Back to top
View user's profile Send private message
Syl20
l33t
l33t


Joined: 04 Aug 2005
Posts: 619
Location: France

PostPosted: Tue Jun 28, 2016 5:29 pm    Post subject: Reply with quote

I'm looking for a solution to this problem, more or less, for years... So I made some tests yesterday, but, unfortunately, Firefox is too much quiet : the "write_bytes" field isn't increased often enough to block the screensaver on my computer. :cry:
My config : amd64 stable, firefox 46, watching Youtube HTML5 videos, xscreensaver configured to blank the screen after five minutes of inactivity, and the script is cronned every two minutes (so there are two executions before the screensaver starting).

That said, this way is interesting, thank you. I'll try to dig a little more, to see if I can find something working on my systems.
Back to top
View user's profile Send private message
VinzC
Watchman
Watchman


Joined: 17 Apr 2004
Posts: 5098
Location: Dark side of the mood

PostPosted: Tue Jun 28, 2016 7:50 pm    Post subject: Reply with quote

Syl20 wrote:
I'm looking for a solution to this problem, more or less, for years... So I made some tests yesterday, but, unfortunately, Firefox is too much quiet : the "write_bytes" field isn't increased often enough to block the screensaver on my computer. :cry:
My config : amd64 stable, firefox 46, watching Youtube HTML5 videos, xscreensaver configured to blank the screen after five minutes of inactivity, and the script is cronned every two minutes (so there are two executions before the screensaver starting).

That said, this way is interesting, thank you. I'll try to dig a little more, to see if I can find something working on my systems.


There are a few ways from here. A couple of options I thought of
  • looking into the window title with xprop
  • monitoring firefox's network traffic — which would maybe require throttling with fast internet connections, in case the download process is too quick
  • find another field from /proc/<pid> to monitor
  • use the fullscreen property alone to deactivate xscreensaver
Maybe also the idle delay you gave xscreensaver is a little too short. I know some applications do restrain from writing to the disk for some period. Don't know if it's the case with firefox but you might want to increase xscreensaver idle delay up to 10 minutes like I did and, why not, increase the number of 10s loops in the script...
_________________
Gentoo addict: tomorrow I quit, I promise!... Just one more emerge...
1739!
Back to top
View user's profile Send private message
Syl20
l33t
l33t


Joined: 04 Aug 2005
Posts: 619
Location: France

PostPosted: Thu Jun 30, 2016 10:05 am    Post subject: Reply with quote

I should have some time to spend on this next weekend. Thank you for the tips.
Back to top
View user's profile Send private message
krinn
Watchman
Watchman


Joined: 02 May 2003
Posts: 7470

PostPosted: Thu Jun 30, 2016 3:29 pm    Post subject: Reply with quote

how about netstat -p | firefox
if you get an ESTABLISHED state, it is at work.
Back to top
View user's profile Send private message
frankenputer
n00b
n00b


Joined: 09 Mar 2016
Posts: 26

PostPosted: Thu Jun 30, 2016 3:44 pm    Post subject: Reply with quote

krinn wrote:
how about netstat -p | firefox
if you get an ESTABLISHED state, it is at work.


Code:
netstat -n | gawk '/^tcp/ {state=$NF} END {print state}'
netstat -n | gawk \
  '/^tcp/ {
    st[$NF]++;
  }
  END {
    for (k in st) {
      print k,"\t",st[k];
    }
  }'


Edit:

I think the more correct approach will be to check the CPU load and if it matches certain load to execute xset -dmps and xset s off

Code:
ps -eo pcpu,comm | gawk '{ if ($1 > 20) { print $1,$2 } }'
# 32.4 chrome
Back to top
View user's profile Send private message
VinzC
Watchman
Watchman


Joined: 17 Apr 2004
Posts: 5098
Location: Dark side of the mood

PostPosted: Fri Jul 01, 2016 8:47 pm    Post subject: Reply with quote

krinn wrote:
how about netstat -p | firefox
if you get an ESTABLISHED state, it is at work.

Might be worth trying 8) . I believe keep alive connections/scripts might defeat this test but definitely worth combining with other detection steps.

frankenputer wrote:
I think the more correct approach will be to check the CPU load and if it matches certain load to execute xset -dmps and xset s off

Code:
ps -eo pcpu,comm | gawk '{ if ($1 > 20) { print $1,$2 } }'
# 32.4 chrome

Hmmm... not sure. Web sites with heavy animations might defeat the detection on a "non-accelerated-graphics" (i.e. between old and very, very old) machine, for instance.
_________________
Gentoo addict: tomorrow I quit, I promise!... Just one more emerge...
1739!
Back to top
View user's profile Send private message
Syl20
l33t
l33t


Joined: 04 Aug 2005
Posts: 619
Location: France

PostPosted: Mon Jul 04, 2016 3:44 pm    Post subject: Reply with quote

Ok, I've a working script. I decided to deactivate the screensaver only when the browser window has both focused and fullscreen (not maximized) states. That does the job, according to my habits.

Code:
#!/bin/bash
# This script tries to inhibit the screen saver while Firefox (or any other
# browser) is full screen. It is intended to run as a cron job every
# minute or so, i.e. any period shorter than xscreensaver lock time.
#                                                                                                                           
# Note this script uses xprop formatting to output eval compatible assignment
# expressions, such as _NET_ACTIVE_WINDOW and _NET_WM_PID. IF we don't do
# that xprop output contains extraneous spaces that mess things up.
set -uef -o pipefail
                                                                                                                           
[ -z "$@" ] && exit 1
NAV="$1"        # Browser, as it appears in `ps` list

# First, is the browser running ?
PID=$(pgrep --delimiter " " --uid "$UID" "$NAV")
[ -z "$PID" ] && exit 0

# Second, am I focused on it ?
DISPLAYS=""                                                                                                                 
DISPLAY=""                                                                                                                 
for pid in $PID
do
        eval $(grep -Eoa 'DISPLAY=[:09.]+' "/proc/$pid/environ")
        [ -z "$DISPLAY" ] && continue
        DISPLAYS="$DISPLAYS $DISPLAY"
done                                                                                                                       
                                                                                                                           
for DISPLAY in $(echo $DISPLAYS | tr " " "\n" | sort -u)
do
        export DISPLAY

        # Get active window ID
        eval $(xprop -root -notype -f _NET_ACTIVE_WINDOW 32x '=$0\n' _NET_ACTIVE_WINDOW)
        [ -z "$_NET_ACTIVE_WINDOW" ] && exit 1
        # Get its process ID
        eval $(xprop -id "$_NET_ACTIVE_WINDOW" -notype -f _NET_WM_PID 32c '=$0\n' _NET_WM_PID)
        [ -z "$_NET_WM_PID" ] && exit 1
        # Check the process name
        grep -q "$NAV" "/proc/$_NET_WM_PID/cmdline" || continue

        # Third, is the browser window full-screen ?
        xprop -id "$_NET_ACTIVE_WINDOW" -notype "_NET_WM_STATE" | grep -q "_NET_WM_STATE_FULLSCREEN" || continue

        # Ok, all the requirements are met.
        xscreensaver-command -deactivate > /dev/null 2>&1
        xset dpms s reset > /dev/null 2>&1
        exit 0
done


Even if firefox is still mono-processus, I decided to make this script multi-processus compliant. But, most of the times, on a personal computer, there's only one display used at a given time. Rarely two. Splitting the windows properties detections into two different for loops limits the number of executed commands.

I had to add the "xset dpms s reset" command to deactivate all the screen blanking capabilities.

Thank you VinzC for the ideas, the base script, and the motivation to finish this long quest... :lol:
Back to top
View user's profile Send private message
VinzC
Watchman
Watchman


Joined: 17 Apr 2004
Posts: 5098
Location: Dark side of the mood

PostPosted: Thu Jul 07, 2016 5:42 pm    Post subject: Reply with quote

Syl20 wrote:
Thank you VinzC for the ideas, the base script, and the motivation to finish this long quest... :lol:

My pleasure. Glad you found a working solution 8) .
_________________
Gentoo addict: tomorrow I quit, I promise!... Just one more emerge...
1739!
Back to top
View user's profile Send private message
VinzC
Watchman
Watchman


Joined: 17 Apr 2004
Posts: 5098
Location: Dark side of the mood

PostPosted: Sun Dec 23, 2018 12:46 pm    Post subject: Reply with quote

I updated my script to work on laptops with a power management application such as xfce4-power-manager. I was annoyed my script didn't prevent the screen from blanking in some circumstances so I decided to improve it. Here's the results.

Peace, Merry Christmas and Happy New Year everyone.
_________________
Gentoo addict: tomorrow I quit, I promise!... Just one more emerge...
1739!
Back to top
View user's profile Send private message
Display posts from previous:   
Reply to topic    Gentoo Forums Forum Index Documentation, Tips & Tricks All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum