[Qt-interest] having Qt-based application notified on system standby/hibernate events

Crni Gorac cgorac at gmail.com
Wed Feb 23 22:39:05 CET 2011


2011/2/23 Konstantin Tokarev <annulen at yandex.ru>:
>
>
> 23.02.2011, 19:01, "Crni Gorac" <cgorac at gmail.com>:
>> On Wed, Feb 23, 2011 at 1:19 AM, Tony Rietwyk
>> <tony.rietwyk at rightsoft.com.au>; wrote:
>>
>>>  Hi Crni,
>>>
>>>  Have a look at QCoreApplication::winEventFilter and
>>>  QApplication::macEventFilter.  Log the messages received during system
>>>  shutdown and then analyze the log to see which messages to act on.
>>
>> Thanks for the suggestion.  Indeed, on Windows I was able to get
>> notifications through catching WM_POWERBROADCAST message in
>> winEventFilter() override.  On Mac, I think also I found how to
>> register for notifications in native code:
>>    http://developer.apple.com/library/mac/#qa/qa2004/qa1340.html
>> I'm using Cocoa-based Qt build, thus Listing 1 from the above link
>> applies.  So it seems rather simple in Objective C, and I know gcc
>> make it possible to use Objective C code alongside with C++ code.
>> However, I have no clue on how to actually register my QObject derived
>> class as "observer" (in Cocoa lingo) for these notifcations.  So - any
>> suggestions or pointers on how to connect Objective C notifications
>> and Qt event loop?
>
> Create Obj-C observer and call your Qt code from it
>
> --
> Regards,
> Konstantin
>

Thanks, I think I've managed to have it working (examining Qt source
helped a lot too, there is a similar thing in-there).  For anyone
interested, here is the code:

First, header file powernotifier.h:

// ---------------------------------------------------------------
#include <Cocoa/Cocoa.h>

#include <QObject>

@class CocoaPowerNotifier;

class PowerNotifier : public QObject
{
    Q_OBJECT

 public:
    static PowerNotifier* getInstance(void);

    ~PowerNotifier(void);

    void OnSystemSleep(void);
    void OnSystemWake(void);

 signals:
    void SystemSleep(void);
    void SystemWake(void);

 protected:
    PowerNotifier(QObject* parent = 0);

 private:
    CocoaPowerNotifier* m_CocoaPowerNotifier;
};

#endif
// ---------------------------------------------------------------

And then .cpp file (powernotifier.cpp):

// ---------------------------------------------------------------
#include "powernotifier.h"

static void OnSystemSleep(void)
{
    PowerNotifier::getInstance()->OnSystemSleep();
}

static void OnSystemWake(void)
{
    PowerNotifier::getInstance()->OnSystemWake();
}

@interface CocoaPowerNotifier : NSObject
@end

@implementation CocoaPowerNotifier
- (id)init
{
    self = [super init];

    if (self) {
        [[[NSWorkspace sharedWorkspace] notificationCenter]
addObserver: self  selector: @selector(receiveSleepNote:) name:
NSWorkspaceWillSleepNotification object: nil];
        [[[NSWorkspace sharedWorkspace] notificationCenter]
addObserver: self  selector: @selector(receiveWakeNote:) name:
NSWorkspaceDidWakeNotification object: nil];
    }
    return self;
}

- (void) receiveSleepNote: (NSNotification*) note
{
    OnSystemSleep();
}

- (void) receiveWakeNote: (NSNotification*) note
{
    OnSystemWake();
}
@end

PowerNotifier* PowerNotifier::getInstance(void)
{
    static PowerNotifier instance;
    return &instance;
}

PowerNotifier::~PowerNotifier(void)
{
    CFRelease(m_CocoaPowerNotifier);
}

void PowerNotifier::OnSystemSleep(void)
{
    emit SystemSleep();
}

void PowerNotifier::OnSystemWake(void)
{
    emit SystemWake();
}

PowerNotifier::PowerNotifier(QObject* parent)
    : QObject(parent)
{
    m_CocoaPowerNotifier =  [[CocoaPowerNotifier alloc] init];
    CFRetain(m_CocoaPowerNotifier);
    [m_CocoaPowerNotifier release];
}
// ---------------------------------------------------------------

Include these files in your project only on Mac, and then you could
connect to SystemSleep() and SystemWake() signals of
PowerNotifier::getInstance() singleton, and you should be good to go.

Any comments welcome.



More information about the Qt-interest-old mailing list