(de)activate screensaver while playing video

Write tutorials for Linux Mint here
More tutorials on https://github.com/orgs/linuxmint/discu ... /tutorials and (archive) on https://community.linuxmint.com/tutorial
Forum rules
Don't add support questions to tutorials; start your own topic in the appropriate sub-forum instead. Before you post read forum rules
rezitengaM

(de)activate screensaver while playing video

Post by rezitengaM »

Hello everybody,

this is a short manual how to fix the behaviour of the screensaver in Linux Mint 11 (or any other distro using Gnome 2.x as a Desktop manager)

What is the problem? The screensaver in plain Linux Mint 11 is not deactivated when you play a movie with 'vlc' or a flash movie in Firefox. That is a little annoying because the screensaver will blank your screen while you are watching the movie. Of course you could just switch the screensaver off but then the screen and computer stays awake even if you fall asleep...;-) This is not what you want.

There is a way how to handle this stuff nicely but not all applications make use of this possibility. Fortunately the default movie player Totem does it right. It inhibits the screensaver when you start playing something (movie, audio) and it uninhibits the screensaver when it is finished playing your media. But there are a great number of players / processes that do not make use of the possibilities of the gnome-screensaver (yet).

This is where my little script comes in. It is not very sophisticated and it does not make use of the official way to handle (un)inhibiting the screensaver via the Dbus but for me it works great at the moment and perhaps someone is happy with it. I will test it some more days and perhaps after that I will rewrite it so that it uses the official way of doing things.

What the script does is the following. It checks whether some predefined processes eat up too much CPU and decides whether this should (un)inhibit the screensaver. The processes can be defined in the script itself in the following section:

Code: Select all

# define process names (from 'top' output) and their CPU usage thresholds
my %processes = (
	'firefox'            => '50',
	'plugin-container'   => '15',
	'vlc'                => '8',
);
What you see here is that the screensaver will be inhibited when firefox eats up 50% (or more) of the CPU (which most certainly means that I am watching a movie in HTML5). It also inhibits the screensaver if the plugin-container uses more than 15% of the CPU which most certainly means I am playing a flash video and so on.

Of course, this is based on assumptions and it will not be the same for every system but I found that I can make a 100% matching profile for my own computer which is great. The screensaver does exactly what it should do. Keep quiet when I am watching a movie and kick in afterwards. That's great!! :D

There is another problem. If one undefinded process is making heavy use of the processor, the defined processes could stay below their thresholds because looking at the percentages the processes seem not very busy even if you are watching video. That's why I added the possibility to inhibit the screensaver when the total load of the system gets "very high" as well. You can adjust this in the following part of the script:

Code: Select all

# define total load that wil inhibit the screensaver
my $maxLoad = 0.6;
You can and should edit those parts of the script to match your needs. Additionally, if you want to inhibit the screensaver while a lengthy operation is going on on your system, just add a line to the processlist with the appropriate CPU usage. In fact it is quite easy to get the script right with some Linux experience.

You can get the whole script below.

Play around and get the parameters right for your needs. (Yes, this could be a hard part for Newbies, just ask if you do not know what to do)

After that add it to the startup items of your Gnome desktop.

And then you will never have to wiggle the mouse again to keep watching your Flash movie in Firefox.

Have fun and take care! ;-)

Magnetizer
-----

Here is the whole script (tried to add it as an attachment but to no prevail):

Code: Select all

#!/usr/bin/perl -W

# ====================================================================
#
# screensaver_inhibitor -- 	script to (un)inhibit the screensaver due
# 							to the CPU usages of several predefined
# 							processes and the total system load.
#
# Usage: screensaver_inhibitor
#
# Author: <magnetizer@live.com>
#
# written on 10/08/2011
#
# Copyright: Magnetizer, october 2011
#
# ====================================================================

# ====================================================================
# Configuration
# ====================================================================

# --------------------------------------------------------------------
# General settings
# --------------------------------------------------------------------

# define process names (from 'top' output) and their CPU usage thresholds
my %processes = (
	'firefox' 			=> '50',
	'plugin-container' 	=> '15',
	'vlc'	 			=> '8',
);

# define total load that wil inhibit the screensaver
my $maxLoad				=  0.6;

# --------------------------------------------------------------------
# Required perl modules
# --------------------------------------------------------------------

use strict;

# --------------------------------------------------------------------
# Subroutine to get the current date
# --------------------------------------------------------------------

sub getDate() {

	# determine the current date
	my @dateTimeData = localtime(time);

	# format the date to be used as a MySQL datetime field
	my $date  = $dateTimeData[5] + 1900;
	$date    .= '-';
	$date    .= sprintf("%02d", $dateTimeData[4] + 1);
	$date    .= '-';
	$date    .= sprintf("%02d", $dateTimeData[3]);

	# return date
	return $date;
}

# --------------------------------------------------------------------
# Subroutine to get the current time 
# --------------------------------------------------------------------

sub getTime() {

	# determine the current time 
	my @dateTimeData = localtime(time);

	# format the date to be used as a MySQL datetime field
	my $time  = sprintf("%02d", $dateTimeData[2]);
	$time    .= ':';
	$time    .= sprintf("%02d", $dateTimeData[1]);
	$time    .= ':';
	$time    .= sprintf("%02d", $dateTimeData[0]);

	# return time
	return $time;
}

# ====================================================================
# Main loop
# ====================================================================

my $process 	        = undef;
my $processShort        = undef; 
my $threshold           = undef;
my $topOutput           = undef;
my $top                 = undef;
my $CPU                 = undef;
my @topValues           = undef;
my $inhibit             = undef;
my $processName         = undef;
my $reason              = undef;
my $last_inhibit_status = 0;

while (1 == 1) {

	$inhibit     = 0;
	$reason      = undef;
	$processName = undef;

	# get 'top' twice (the first time the output of 'top' is often distorted by 'top' itself)
	#$topOutput   = `top -b -n1`;
	$topOutput   = `top -b -n1`;

	# check the definded processes
	while (($process, $threshold) = each(%processes)) {

		# 'top' only outputs the first 16 characters of the process name
		$processShort = substr($process, 0, 15);

		# initialize varibles
		$top          = undef;
		$CPU          = undef;
		@topValues    = undef;

		# search for process name in 'top' output
		if ($topOutput =~ /\n(.*?$processShort.*?)\n/i) {

			# get the result
			$top = $1;
			chomp($top);

			# get the CPU usage from the result
			@topValues = split(' ', $top);
			$CPU = $topValues[8];

			if (defined($CPU) && ($CPU >= $threshold)) {
				print getDate() . " " .getTime() . " -- process above threshhold : " . $processShort . " -- usage : " . $CPU . " (threshold : " . $threshold . ")\n";
				$processName = $process;
				$reason	     = 'busy';
				$inhibit     = 1;
			}
		}
	}

	# also check the total load
	if ($topOutput =~ /load average:\s*(.*?),/i) {

		$CPU = $1;
		if (defined($CPU) && ($CPU >= $maxLoad)) {
			print getDate() . " " . getTime() . " -- system load above threshold -- load : " . $CPU . " (threshold : " . $maxLoad . ")\n";
			$processName = 'system-load';
			$reason		 = 'too-high';
			$inhibit	 = 1;
		}
	}

	# do the appropriate action depending on whether the 'inhibit' flag is set ...
	if ($inhibit == 1) {
		if ($last_inhibit_status == 0) {
			print getDate() . " " . getTime() . " action: inhibiting screensaver\n";
			system("killall gnome-screensaver-command");
			system("/usr/bin/gnome-screensaver-command -i -n $processName -r $reason &");
		} else {
			print getDate() . " " . getTime() . " action: nothing, screensaver still inhibited\n";
		}
		$last_inhibit_status = 1;
	}

	# or not ...
	if ($inhibit == 0) {
		if ($last_inhibit_status == 1) {
			print getDate() . " " . getTime() . " action: uninhibiting screensaver\n";
			system("killall gnome-screensaver-command");
			system("killall gnome-screensaver");
			system("gnome-screensaver-command -q");
		} else {
			print getDate() . " " . getTime() . " action: nothing, screensaver still unihibited\n";
		}
		$last_inhibit_status = 0;
	}

	# sleep a while before running again
	sleep(10);
}

# ====================================================================
# End of script
# ====================================================================

exit 0;
Last edited by rezitengaM on Mon Sep 24, 2012 5:51 am, edited 1 time in total.
Mauro

Re: (de)activate screensaver while playing video

Post by Mauro »

That's cool, but instead of an script I use gnome-power-manager.
http://www.gnome.org/projects/gnome-power-manager/

You can find it in as an applet for the panels.
rezitengaM

Re: (de)activate screensaver while playing video

Post by rezitengaM »

Mauro wrote:That's cool, but instead of an script I use gnome-power-manager.
http://www.gnome.org/projects/gnome-power-manager/

You can find it in as an applet for the panels.

Thanks Mauro, I'm aware of the gnome-power-manager, but that's a different thing.

What the script does is detecting whether you are watching a (Flash) video.

It will then automatically deactivate the screensaver and powermanagement so that the video will not be interrupted.

Correct me if I'm wrong but I don't think the gnome-power-manager does that, does it?
rezitengaM

Re: (de)activate screensaver while playing video

Post by rezitengaM »

Hello everybody,

Here is an updated version of the script I wrote.

It got much simpler by making use of the 'dbus-send' command and it's a lot nicer because it doesn't kill processes just to start them again, which was kind of quick and dirty.

There are still some improvements I could make:

1) Making use of Net::DBus instead of a system call via 'dbus-send'. The script could then be run by 'cron' instead of being a continous process with a 'sleeptime' after each iteration. That would be nicer but I think it is not really necessary.
2) I could use the 'Inhibit' / 'Uninhibit' methods instead of 'SimulateUserActivity'. I think this is what they are for. But then this would mean that the script gets more complicated again, so why bother? ;-)
3) Find a way to be sure that flash is playing a movie. Right now, I use the CPU usage of the flash plugin to make that decision but this could give false positives / negatives. The problem is, not all flash videos use the same amount of the CPU, it depends on the site you are on. In principle this could mean that the script does not work correctly on some sites.

But anyway, I use the script for several days now and it works nicely for me.

Here is the updated version:

Code: Select all

#!/usr/bin/perl -W

# ====================================================================
#
# screensaver_prevention --	script to prevent the screensaver due
# 							to the CPU usages of several predefined
# 							processes and the total system load.
#
# Usage: screensaver_prevention
#
# Author: <magnetizer@live.com>
#
# written on 10/08/2011
#
# Copyright: Magnetizer, october 2011
#
# ====================================================================

# ====================================================================
# Configuration
# ====================================================================

# --------------------------------------------------------------------
# General settings
# --------------------------------------------------------------------

# define process names (from 'top' output) and their CPU usage thresholds
my %processes = (
	'firefox' 			=> '70',
	'plugin-container' 	=> '70',
	'vlc' 				=> '8',
);

# define total load that wil inhibit the screensaver
my $maxLoad				=  0.8;

# --------------------------------------------------------------------
# Required perl modules
# --------------------------------------------------------------------

use strict;

# ====================================================================
# Main loop
# ====================================================================

my ($process, $threshold, $processShort, $topOutput, $top, $CPU, @topValues, $prevent);

while (1==1) {

	# get the top output
	$topOutput   = `top -b -n1`;

	# check the definded processes
	while (($process, $threshold) = each(%processes)) {

		# 'top' only outputs the first 16 characters of the process name
		$processShort = substr($process, 0, 15);

		# search for process name in 'top' output
		if ($topOutput =~ /\n(.*?$processShort.*?)\n/i) {

			# get the result
			$top = $1;
			chomp($top);

			# get the CPU usage from the result
			@topValues = split(' ', $top);
			$CPU = $topValues[8];
			$prevent = (defined($CPU) && ($CPU >= $threshold)) ? 1 : 0;
		}
	}

	# also check the total load if prevent 
	if ($topOutput =~ /load average:\s*(.*?),/i) {
		$CPU = $1;
		$prevent = (defined($CPU) && ($CPU >= $maxLoad)) ? 1 : $prevent;
	}

	# simulate user activity if 'inhibit' flag is set ...
	if ($prevent == 1) {
		system("dbus-send --session --type=method_call --dest=org.gnome.ScreenSaver --reply-timeout=20000 /org/gnome/ScreenSaver org.gnome.ScreenSaver.SimulateUserActivity");
	}

	sleep(30);
}

# ====================================================================
# End of script
# ====================================================================

exit 0;
Have fun and take care.

Greetings, Magnetizer
Last edited by rezitengaM on Mon Sep 24, 2012 5:54 am, edited 2 times in total.
Just-Linux

Re: (de)activate screensaver while playing video

Post by Just-Linux »

Thanks a lot for the script .
rezitengaM

Re: (de)activate screensaver while playing video

Post by rezitengaM »

You are absolutely welcome..;-)

I hope the script will be useful, it is for me.

I am also looking into ways to diffenrentiate between deactivating the screensaver or deactivating the sleep mode. This could be useful when performing a lengthy operation such as backups or calculations. In that case the screensave may show up and lock the screen but the computer is not supposed to go into the sleepmode.

But nevermind, I hope the script is of any help to you.

Cheers!
rezitengaM

Re: (de)activate screensaver while playing video

Post by rezitengaM »

Hello everybody,

here is another update of the script that automatically disables / enables the screensaver according to userdefined conditions (CPU usage of processes). The script now only checks for the processes of the current user. That means that if someone else is logged in the screensaver will not be inhibited.

I have also created a little app for the notification area. It does the same thing but you can also click on it to disable / enable the screensaver manually. I use this all the time now and it works great. I have written this app for Ubuntu but as Mint also uses Gnome 3 en GTK, I suppose it should also work with Linux Mint.

If someone wants to try it, let me know in this thread and I will post it.

Have fun with Linux!

Magnetizer

Code: Select all

#!/usr/bin/perl -W

# ====================================================================
#
# screensaver_prevention -- script to prevent screensaver activation 
#                           by looking at the CPU usage of several
#                           predefined processes and the total system
#                           load.
#
# Usage: screensaver_prevention
#
# Author: <magnetizer@live.com>
#
# written on 04/30/2012
#
# Copyright: Magnetizer, april 2012
#
# ====================================================================

# ====================================================================
# Configuration
# ====================================================================

# --------------------------------------------------------------------
# General settings
# --------------------------------------------------------------------

# define process names (from 'top' output) and their CPU usage thresholds
my %processes = (
    'plugin-container'  => '20',
    'deja-dup'          => '10',
);

# define total load that will inhibit the screensaver
my $maxLoad             =  10; 

# --------------------------------------------------------------------
# Required perl modules
# --------------------------------------------------------------------

use strict;

# ====================================================================
# Main loop
# ====================================================================

my ($user, $process, $threshold, $processShort, $topOutput, $top, $CPU, @topValues, $prevent);

# get the username
my $whoami = `whoami`;
chomp($whoami);

while (1==1) {

    # get the top output
    $topOutput = `top -b -n1`;
    chomp($topOutput);
    $topOutput =~ s/\r//g;

    # reset the prevent status
    $prevent = 0;

    # check the definded processes
    while (($process, $threshold) = each(%processes)) {

        # do nothing if the prevent status is already on
        next if $prevent == 1;

        # 'top' only outputs the first 16 characters of the process name
        $processShort = substr($process, 0, 15);

        # split top output in seperate lines
        my @lines = split(/\n/, $topOutput);

        # search each line
        foreach my $line (@lines) {

            # do nothing if the prevent status is already on
            next if $prevent == 1;

            # only use the process specific lines
            next unless $line =~ m/^\s*[0-9]+/;

            # cleanup line
            $line =~ s/\n//g;
            $line =~ s/\r//g;
            $line =~ s/\s+/;/g;
            $line =~ s/^;//;
            $line =~ s/;$//;

            # delete the optional <defunct> statement in the 'top' output
            $line =~ s/;<.*$//;
            
            # split line
            @topValues = split(/;/, $line);
            $user      = $topValues[1];
            $process   = $topValues[-1];
            $CPU       = $topValues[-4];

            # check the user name
            next unless ($user eq $whoami);

            # check the process name
            next unless ($process eq $processShort);

            # otherwise check for the threshold
            $prevent = ($CPU >= $threshold) ? 1 : 0;

        }
    }

    # also check the total load
    if ($topOutput =~ /load average:\s*(.*?),/i) {
        $CPU = $1;
        $prevent = (defined($CPU) && ($CPU >= $maxLoad)) ? 1 : $prevent;
    }
    
    # simulate user activity if 'prevent' flag is set
    system("dbus-send --session --type=method_call --dest=org.gnome.ScreenSaver --reply-timeout=20000 /org/gnome/ScreenSaver org.gnome.ScreenSaver.SimulateUserActivity") if ($prevent == 1);

    sleep(60);
}

# ====================================================================
# End of script
# ====================================================================

exit 0;
staubi

Re: (de)activate screensaver while playing video

Post by staubi »

Hi, thanks for Your fix to this annoying bug...

But unfortunately I get the following error when trying to start the latest version...

Code: Select all

Argument "0,0" isn't numeric in numeric ge (>=) at ./disablescreensaveronvideo line 107.
Can You tell me what I have to do?

Greetings, staubi
rezitengaM

Re: (de)activate screensaver while playing video

Post by rezitengaM »

Hi Staubi,

thanks, I am glad if the script is useful for others as well.

it looks like you have entered "0,0" somewhere as a threshold for a process. The right notation would be "0.0" or even "0". That should solve the error message but it is not very useful to enter a threshold of "0%" for a process. This would mean that your screensaver will be inhibited all the time, which is the same as turning it off completely.

Can you copy paste your process definition from the script?

The default is:

# define process names (from 'top' output) and their CPU usage thresholds
my %processes = (
'plugin-container' => '20',
'deja-dup' => '10',
);

# define total load that will inhibit the screensaver
my $maxLoad = 10;

---------

I am finishing a new version of an even nicer program to deal with the same problem. It will give you a little inidicator in the panel showing whether your screensaver is switched off or on. You can use it in the same automatic way as this script, but you can also click on it to switch the screensaver off manually.

I will post it here, if I have ironed out the last bug.

Kind regards,
rezitengaM (as Magnetizer was already in use...;-))
CmdLnNOOB

Re: (de)activate screensaver while playing video

Post by CmdLnNOOB »

Hey guys this script looks like exactly what I require......I am a noob and I'm sorry for asking but I have tried to look up the answer to no avail so thought I would ask the experts..... :)

Where do I place this script? in the gnome-desktop config? or place it as a seperate file? a step by step proccess would really help me out.....

I am using xscreensaver right now with glslideshow but will switch to gnome-screensaver if I can get this script to run :)

My kids are watching netflix and constanty having to get up and jiggle the mouse....my wife says at least they are moving and not just sitting there... lol

DISTRIB_ID=LinuxMint
DISTRIB_RELEASE=14
DISTRIB_CODENAME=nadia
DISTRIB_DESCRIPTION="Linux Mint 14 Nadia"
NAME="Ubuntu"
VERSION="12.10, Quantal Quetzal"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu quantal (12.10)"
VERSION_ID="12.10"
rezitengaM

Re: (de)activate screensaver while playing video

Post by rezitengaM »

Hi CmdLnNOOB,

I wrote this script for Linux Mint 11. It did a fine job, but things have changed in the meantime. I will post a greatly improved script within the next days which I am developing for Linux Mint 14. I will gladly explain how to use it. No worry, it is quite easy...;-)

Greetz,

rezitengaM (as Magnetizer was already in use).
rezitengaM

Re: (de)activate screensaver while playing video

Post by rezitengaM »

Hello everybody,

here is the newest screensaver inhibitor script. You can use it to automatically inhibit your screensaver when some important process is running. For instance, you can automatically disable the screensaver while watching video in your browser or while you are backing up files or some other lengthy process.

The script gives you a little app in the taskbar showing if the screensaver is disabled by the script or not. You can also use this icon to manually disable the screensaver or to pause the program.

I hope you will have fun with it.

If you have any questions, just ask.

Kind regards,

rezitengaM (as Magnetizer was already in use)
CmdLnNOOB

Re: (de)activate screensaver while playing video

Post by CmdLnNOOB »

Thank you very much for the great app its working perfectly :)
rezitengaM

Re: (de)activate screensaver while playing video

Post by rezitengaM »

Hi CmdLnNOOB,

you are welcome.

There is one annoying bug left which I have not solved so far.

The app deactivates the screensaver nicely while watching a (Flash) video, afterwards it activates the screensaver again. If there is no user interaction at all, something strange happens. The screensaver starts after a while but then the screen comes back to life and stays on even though the screensaver is not blocked by the script. One jiggle with the mouse and everything works fine again.

This is rather strange and till now I have no idea where to look for the bug. As a workaround I tried to simulate some user activity to reset everything to normal but that does not do the trick. If you watch a movie and afterwards use your computer again, you will not encounter this bug. It only happens if there is no user activity at all.

If anybody has an idea, I would be glad to hear about it.

Greetz,

rezitengaM
rezitengaM

Re: (de)activate screensaver while playing video

Post by rezitengaM »

Hello everybody,

here is the newest version of this script. I fixed the strange screensaver behaviour by making use of "xdotool" to simulate some user activitiy (wiggling the mouse).

This means, in order to use this version of the script you first have to install 'xdotool'. No sweat, this can be done easily.

You can use the "Software Manager" to search for "xdotool" and install it.

Alternatively you can use the "Terminal" and type:

sudo apt-get install xdotool

Both ways will install "xdotool" on your machine. After that you can use this script to make your screensaver behave nicely.

I hope you will have fun with it.

Greets, zetitengaM (as Magnetizer was already in use).
rezitengaM

Re: (de)activate screensaver while playing video

Post by rezitengaM »

Hello everybody,

here is the newest version of this script. I fixed a minor bug. The icon will now update immediately if the app is changed from any status to "automatic".

I also added "vlc" to the list of predefined processes as there is an annoying bug in vlc: Vlc does correctly inhibit the screensaver but it does not reenable it after after the video is finished or when the video is paused. This means the screensaver will not kick in after you have watched the movie.

I fixed this behaviour by:

1) adding "vlc" to the script with a threshold of 10% CPU usage
2) changing the "advanced preferences" in vlc:
* Start vlc
* Click on Tools --> Preferences --> Show settings All
* Uncheck "Inhibit the power management daemon during playback"

Now vlc will not disable the screensaver at all, but that's ok as the screensaver inhibitor applet will take care of this.

I hope you will have fun with it.

Greets, zetitengaM (as Magnetizer was already in use).
dawbomb

Re: (de)activate screensaver while playing video

Post by dawbomb »

Brilliant! Now Ubuntu and Linux mint are complete! I still can't believe this sort of logic wasn't included by default :?

One line that may be useful to some people:

Code: Select all

predefined_processes['xbmc.bin']            = 10
Edit:
Changed CPU usage from 20 to 10
Last edited by dawbomb on Mon Apr 29, 2013 3:03 am, edited 1 time in total.
DrHu

Re: (de)activate screensaver while playing video

Post by DrHu »

I don't knwo, usually when I am using the computer (running a session), I don't want any screensaver interruptions at all..

http://www.webupd8.org/2012/05/2-ways-t ... sable.html
--various tricks/scripts to get around screen saver issues: I think it is so much simpler to just turn off screen saver while at work..
So, I might may that step one: disable screen saver on the available settings menus screensavers selection(s)
DrHu

Re: (de)activate screensaver while playing video

Post by DrHu »

I don't knwo, usually when I am using the computer (running a session), I don't want any screensaver interruptions at all..

http://www.webupd8.org/2012/05/2-ways-t ... sable.html
--various tricks/scripts to get around screen saver issues: I think it is so much simpler to just turn off screen saver while at work..
So, I might may that step one: disable screen saver on the available settings menus screensavers selection(s)
rezitengaM

Re: (de)activate screensaver while playing video

Post by rezitengaM »

dawbomb wrote:Brilliant! Now Ubuntu and Linux mint are complete! I still can't believe this sort of logic wasn't included by default :?

One line that may be useful to some people:

Code: Select all

predefined_processes['xbmc.bin']            = 10
Edit:
Changed CPU usage from 20 to 10

Thanks, nice to hear that the script is useful for others aswell. I think the reason why it is no default behaviour is because it is not really a "ready out of the box" solution. It still needs some fiddling but then it works great.
Post Reply

Return to “Tutorials”