[SOLVED] QDialog in fullscreen - disable OS screensaver?



  • Hi,

    I would like to know if it's possible to disable the OS screensaver from a QMainWindow or QDialog. If not, would it be possible to "hack" it and emulate mouse movement or keyboard press at interval time x so the screensaver doesn't show. It is important not to have a screensaver, since the user is away from the computer when using this application.

    Thank you

    Code sample :

    @ WorkoutDialog w(tableModel->getWorkoutAtRow(sourceIndex), this);
    w.setModal(true);
    w.showFullScreen();

        if (w.exec() == QDialog::Accepted) {
            //        qDebug() << "workout done!";
        }
        else {
            //        qDebug() << "workout cancel!";
        }@


  • If this is for Windows, I've read somewhere that you can use the SendInput() API, you set up a timer say twice a minute and do something similar to this:
    @ INPUT Mouse;

    Mouse.type = INPUT_MOUSE;
    Mouse.mi.dwFlags = MOUSEEVENTF_MOVE;
    ::SendInput(1,&Mouse,sizeof(INPUT));@
    

    This should emulate a mouse movement with zero delta x and zero delta y, should be enough to make the screensaver not start.

    Haven't tried, but I found "this thread on Stackoverflow":http://stackoverflow.com/questions/463813/programmatically-prevent-windows-screensaver-from-starting
    , somewhere in the middle there is code for this, in VB.NET though :-(



  • I'll check if I can find a cross-platform solution (Mac/Win), if not this will do the job, thanks a lot!



  • I found this :
    http://developer.nokia.com/community/wiki/Inhibiting_the_device_screen_saver_using_Qt

    But I can't include "QSystemScreenSaver", maybe it's no longer part of Qt? Using 5.2.1


  • Lifetime Qt Champion

    Hi,

    It was part of QtMobility and AFAICS, it's not been ported (yet ?) to Qt 5



  • On Windows:
    "SetThreadExecutionState":http://msdn.microsoft.com/en-us/library/aa373208(VS.85).aspx

    @
    #include <Windows.h>
    void DisableScreenSaver()
    {
    SetThreadExecutionState(EXECUTION_STATE.ES_DISPLAY_REQUIRED | EXECUTION_STATE.ES_CONTINUOUS);
    }
    void EnableScreenSaver()
    {
    SetThreadExecutionState(EXECUTION_STATE.ES_CONTINUOUS);
    }

    @



  • Yeah I tried that but alas, if you look at "the docs":http://msdn.microsoft.com/en-us/library/aa373208.aspx, at the bottom (just before examples):
    "...
    This function does not stop the screen saver from executing. " :-(



  • Ok, tested on Windows XP:

    DisableScreenSaver.c
    @
    #include <Windows.h>
    #pragma comment(lib, "user32.lib")

    int main()
    {
    SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, FALSE , NULL, SPIF_SENDWININICHANGE);
    return 0;
    }

    @



  • Finally trying to achieve this function after many user requested it.

    I'm thinking of a easy cross-platform way to do it (Windows and Mac OS X)

    What I'm thinking:

    • start a QTimer that fire each 1 minute
    • [Slot] emulate a key press on the keyboard or a small mouse movement (keyboard or mouse is not used in this part of the software so shouldn't matter)

    I'll see if I can achieve it (not sure how to emulate key or mouse movement in Qt) and post result!

    Thanks Qt!



  • Finally trying to achieve this function after many user requested it.

    I'm thinking of a easy cross-platform way to do it (Windows and Mac OS X)

    What I'm thinking:

    • start a QTimer that fire each 1 minute
    • [Slot] emulate a key press on the keyboard or a small mouse movement (keyboard or mouse is not used in this part of the software so shouldn't matter)

    I'll see if I can achieve it (not sure how to emulate key or mouse movement in Qt) and post result!

    Thanks Qt!



  • I tried this one on my QDialog. But still not working (screensaver activates)
    Maybe QDialog doesn't handle KeyPress event? investigating..

    @void WorkoutDialog::desactivateScreensaver() {

    qDebug() << "OK DESACTIVATE SCREENSAVER!";
    
    QKeyEvent *event = new QKeyEvent(QEvent::KeyPress, Qt::Key_Enter, Qt::NoModifier);
    QCoreApplication::postEvent(this, event);
    
    QKeyEvent *event1 = new QKeyEvent(QEvent::KeyRelease, Qt::Key_Enter, Qt::NoModifier);
    QCoreApplication::postEvent(this, event1);
    

    }@



  • I tried this one on my QDialog. But still not working (screensaver activates)
    Maybe QDialog doesn't handle KeyPress event? investigating..

    @void WorkoutDialog::desactivateScreensaver() {

    qDebug() << "OK DESACTIVATE SCREENSAVER!";
    
    QKeyEvent *event = new QKeyEvent(QEvent::KeyPress, Qt::Key_Enter, Qt::NoModifier);
    QCoreApplication::postEvent(this, event);
    
    QKeyEvent *event1 = new QKeyEvent(QEvent::KeyRelease, Qt::Key_Enter, Qt::NoModifier);
    QCoreApplication::postEvent(this, event1);
    

    }@



  • Weird because I see my eventFilter being called, but the action never takes place on the UI (key pressed, mouseMove, ..)

    @bool WorkoutDialog::eventFilter(QObject *watched, QEvent *event) {

    Q_UNUSED(watched);
    
    //    qDebug() << "EventFilter " << watched << "Event:" << event;
    
    /// Disable enter pressed on dialog (bug cause it to minimize)
    if(event->type() == QEvent::KeyPress) {
        QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
        if(keyEvent->key() == Qt::Key_Enter || keyEvent->key() == Qt::Key_Return )
            return true; // mark the event as handled
    }
    
    
    if(event->type() == QEvent::WindowStateChange)
    {
        if(windowState().testFlag(Qt::WindowMaximized) == true) {
            qDebug() << "Going call showFullSceen here";
            this->showFullScreenWin();
            return true;
        }
    }
    return false;
    

    }@



  • Weird because I see my eventFilter being called, but the action never takes place on the UI (key pressed, mouseMove, ..)

    @bool WorkoutDialog::eventFilter(QObject *watched, QEvent *event) {

    Q_UNUSED(watched);
    
    //    qDebug() << "EventFilter " << watched << "Event:" << event;
    
    /// Disable enter pressed on dialog (bug cause it to minimize)
    if(event->type() == QEvent::KeyPress) {
        QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
        if(keyEvent->key() == Qt::Key_Enter || keyEvent->key() == Qt::Key_Return )
            return true; // mark the event as handled
    }
    
    
    if(event->type() == QEvent::WindowStateChange)
    {
        if(windowState().testFlag(Qt::WindowMaximized) == true) {
            qDebug() << "Going call showFullSceen here";
            this->showFullScreenWin();
            return true;
        }
    }
    return false;
    

    }@



  • [quote author="MarianMMX" date="1397293908"]Ok, tested on Windows XP:

    DisableScreenSaver.c
    @
    #include <Windows.h>
    #pragma comment(lib, "user32.lib")

    int main()
    {
    SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, FALSE , NULL, SPIF_SENDWININICHANGE);
    return 0;
    }

    @
    [/quote]

    Tested and works on windows 7 too. thanks
    Update: not really what I wanted, it still disable the ScreenSaver after you leave the app.. don't want to mess with personal settings..

    I gave up trying to emulate a key press, will use this code instead.
    Trying to find an equivalent for Mac OS X now



  • [quote author="MarianMMX" date="1397293908"]Ok, tested on Windows XP:

    DisableScreenSaver.c
    @
    #include <Windows.h>
    #pragma comment(lib, "user32.lib")

    int main()
    {
    SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, FALSE , NULL, SPIF_SENDWININICHANGE);
    return 0;
    }

    @
    [/quote]

    Tested and works on windows 7 too. thanks
    Update: not really what I wanted, it still disable the ScreenSaver after you leave the app.. don't want to mess with personal settings..

    I gave up trying to emulate a key press, will use this code instead.
    Trying to find an equivalent for Mac OS X now



  • I read you can call Objective-C from Qt

    I want "to use this method":http://stackoverflow.com/questions/5596319/how-to-programmatically-prevent-a-mac-from-going-to-sleep/5596946#5596946

    I made a header file named "MacUtil.h" and a "MacUtil.mm" that will call the Objective-C code. Will see if I can get it to work and post result



  • I read you can call Objective-C from Qt

    I want "to use this method":http://stackoverflow.com/questions/5596319/how-to-programmatically-prevent-a-mac-from-going-to-sleep/5596946#5596946

    I made a header file named "MacUtil.h" and a "MacUtil.mm" that will call the Objective-C code. Will see if I can get it to work and post result



  • On the way, will edit this post with solution
    MacUtil.h

    @class MacUtil
    {

    public:
    MacUtil();
    ~MacUtil();

    void disableScreensaver();
    void releaseScreensaverLock();
    

    private:
    IOPMAssertionID assertionID;

    };

    #endif // MACUTIL_H@

    MacUtil.mm
    @//http://stackoverflow.com/questions/5596319/how-to-programmatically-prevent-a-mac-from-going-to-sleep/5596946#5596946
    void MacUtil::disableScreensaver() {

    CFStringRef* reasonForActivity= CFSTR("MaximumTrainer FullScreen Workout");
    IOReturn success = IOPMAssertionCreateWithName(kIOPMAssertionTypeNoDisplaySleep,
                                        kIOPMAssertionLevelOn, reasonForActivity, &assertionID);
    if (success == kIOReturnSuccess)
    {
        //return sucess? todo..
    }
    

    }

    void MacUtil::releaseScreensaverLock() {

    IOPMAssertionRelease(assertionID);
    

    }
    @



  • On the way, will edit this post with solution
    MacUtil.h

    @class MacUtil
    {

    public:
    MacUtil();
    ~MacUtil();

    void disableScreensaver();
    void releaseScreensaverLock();
    

    private:
    IOPMAssertionID assertionID;

    };

    #endif // MACUTIL_H@

    MacUtil.mm
    @//http://stackoverflow.com/questions/5596319/how-to-programmatically-prevent-a-mac-from-going-to-sleep/5596946#5596946
    void MacUtil::disableScreensaver() {

    CFStringRef* reasonForActivity= CFSTR("MaximumTrainer FullScreen Workout");
    IOReturn success = IOPMAssertionCreateWithName(kIOPMAssertionTypeNoDisplaySleep,
                                        kIOPMAssertionLevelOn, reasonForActivity, &assertionID);
    if (success == kIOReturnSuccess)
    {
        //return sucess? todo..
    }
    

    }

    void MacUtil::releaseScreensaverLock() {

    IOPMAssertionRelease(assertionID);
    

    }
    @



  • Anyone good with Objective-C?

    I'm getting theses error tryings to compile the new class (mm file) I just added:

    duplicate symbol __ZN8MacUtilsC2Ev in:
    MacUtils.o
    macutils.o
    duplicate symbol __ZN8MacUtilsC1Ev in:
    MacUtils.o
    macutils.o

    Seems like a conflict with
    @#import <IOKit/pwr_mgt/IOPMLib.h> in MacUtil.mm@
    and my .pro has already theses:
    @ LIBS += -framework IOKit
    LIBS += -framework CoreFoundation@



  • Anyone good with Objective-C?

    I'm getting theses error tryings to compile the new class (mm file) I just added:

    duplicate symbol __ZN8MacUtilsC2Ev in:
    MacUtils.o
    macutils.o
    duplicate symbol __ZN8MacUtilsC1Ev in:
    MacUtils.o
    macutils.o

    Seems like a conflict with
    @#import <IOKit/pwr_mgt/IOPMLib.h> in MacUtil.mm@
    and my .pro has already theses:
    @ LIBS += -framework IOKit
    LIBS += -framework CoreFoundation@



  • Solved, I had 2 times the OBJECTIVE_SOURCES directive in my pro file pointing to the same .mm file.
    Will have to go learn Objective-C now, sigh.. :)



  • Solved, I had 2 times the OBJECTIVE_SOURCES directive in my pro file pointing to the same .mm file.
    Will have to go learn Objective-C now, sigh.. :)



  • Working for both Windows and OS X!

    On dialog open (constructor):
    @// Disable ScreenSaver
    #ifdef Q_OS_MAC
    macUtil.disableScreensaver();
    #else
    SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, FALSE , NULL, SPIF_SENDWININICHANGE);
    #endif@

    On dialog close (destructor):
    @#ifdef Q_OS_MAC
    macUtil.releaseScreensaverLock();
    #else
    SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, TRUE , NULL, SPIF_SENDWININICHANGE);
    #endif@

    Tested and work for Windows, if you have no screensaver, it will not put one with the the destructor, all possible cases seems to work



  • Working for both Windows and OS X!

    On dialog open (constructor):
    @// Disable ScreenSaver
    #ifdef Q_OS_MAC
    macUtil.disableScreensaver();
    #else
    SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, FALSE , NULL, SPIF_SENDWININICHANGE);
    #endif@

    On dialog close (destructor):
    @#ifdef Q_OS_MAC
    macUtil.releaseScreensaverLock();
    #else
    SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, TRUE , NULL, SPIF_SENDWININICHANGE);
    #endif@

    Tested and work for Windows, if you have no screensaver, it will not put one with the the destructor, all possible cases seems to work


  • Lifetime Qt Champion

    You should rather use a elif defined(Q_OS_WIN) since it's completely platform specific


  • Lifetime Qt Champion

    You should rather use a elif defined(Q_OS_WIN) since it's completely platform specific



  • @maximus said:

    Working for both Windows and OS X!

    On dialog open (constructor):
    @// Disable ScreenSaver
    #ifdef Q_OS_MAC
    macUtil.disableScreensaver();
    #else
    SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, FALSE , NULL, SPIF_SENDWININICHANGE);
    #endif@

    On dialog close (destructor):
    @#ifdef Q_OS_MAC
    macUtil.releaseScreensaverLock();
    #else
    SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, TRUE , NULL, SPIF_SENDWININICHANGE);
    #endif@

    Tested and work for Windows, if you have no screensaver, it will not put one with the the destructor, all possible cases seems to work

    Can you share your source or at least the relevant part? I've been using the same code for my app to disable/re-enable on Windows, but now need to do the same for Mac clients. Thanks.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.