• Uncategorized

About c++ : How-to-disable-screensaverpower-managementscreen-blanking-when-a-GTK-program-is-running

Question Detail

The question

Is there a method to prevent an X session from starting the screensaver, going into power save mode, or performing a screen blank from code?

What I’m working with

Language: C/C++
GUI framework: GTK3
Hardware: Raspberry Pi 3B
Software: Raspbian 10 – Buster

My program needs to run on screen for long periods (up to 12 hours) with the GUI running without user interaction. The GUI acts as a status monitor for systems in field (if the screen goes black, something went wrong).

What I know

GTK3 can determine if the screensaver is active

GTK3 has a boolean property to report if the screensaver of the system is active (see here), but no other references are made in the documentation.

Raspbian uses screen blanking

Raspbian does not come installed with xscreensaver or other package to control the screen off time. Instead, it relies mostly on X to “blank screen”. This can be managed with the xset command as a superuser. The canonical way to do this is reported in the hardware-specific Stack Exchange (here).

End-users cannot be trusted

In my case, the program will be used by folks who are barely computer literate. The result must be user-friendly and not expect the user to ever touch a terminal, let alone to make permanent changes to the startup config of X. While one option would be to distribute the program as a customized Raspbian disk image, I would like to explore other options.

I need to see an example

While there were some places to start using this question, implementing them is problematic. When I attempt to use the following MWE with and without the commented line, nothing happens. I cannot simulate the screen blanking function.

#include <X11/extensions/scrnsaver.h>

int main() {
    // XScreenSaverSuspend;
    XForceScreenSaver;
    usleep(1000000);
    return 0;
}

Question Answer

You have to pass parameters to the function:

void XScreenSaverSuspend(Display *dpy, Bool suspend);
#include <X11/extensions/scrnsaver.h>

int main() {
    XScreenSaverSuspend (display, True);
    usleep(1000000);
    return 0;
}

But I don’t think you have time to see the result with this program and when program ends the screensaver goes back to its previous state.

For your GTK framework, you can obtain the Display use:

Display *
gdk_x11_display_get_xdisplay (GdkDisplay *display);

Docs here.

For X:

/* use the information from the environment variable DISPLAY 
   to create the X connection:
*/  
Display * dis = XOpenDisplay((char *)0); // or ":0.0"

A hacky, OS-specific solution:

Raspbian does not appear to require super user elevation to modify the xset. Adding the line to the code:

system("xset -dpms");
system("xset s off");

is sufficient to turn off the power management settings and the screensaver.

This is obviously sloppy, and it potentially leaves the OS in an undesirable state if the program breaks before these have a chance to be reset to default values. More elegant answers are encouraged.

You may also like...

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.