mirror of
https://github.com/wxWidgets/wxWidgets.git
synced 2026-08-17 17:02:51 +08:00
Add wxCocoaPowerModule and CocoaPowerEventsObserver
Add support for wxPowerEvent generation under macOS. Register observers with notifications center, with callbacks for NSWorkspaceWillSleepNotification and NSWorkspaceDidWakeNotification notifications. These callbacks inform the top level window to handle POWER SUSPENDED and/or RESUME. For consistency with wxGTK/Linux, only generate these events once wxPowerResource::Acquire() has been called. Signed-off-by: Tijs Van Buggenhout <tijs.van.buggenhout@axsguard.com> Closes #25778.
This commit is contained in:
committed by
Vadim Zeitlin
parent
ace3d4d936
commit
5a3a7f5f48
+1
-1
@@ -40,7 +40,7 @@ enum wxBatteryState
|
||||
// compiling in the code for handling them which is never going to be invoked
|
||||
// under the other platforms, we define wxHAS_POWER_EVENTS symbol if this event
|
||||
// is available, it should be used to guard all code using wxPowerEvent
|
||||
#if defined(__WINDOWS__) || defined(__WXGTK__)
|
||||
#if defined(__WINDOWS__) || defined(__WXGTK__) || defined(__WXOSX_COCOA__)
|
||||
|
||||
#define wxHAS_POWER_EVENTS
|
||||
|
||||
|
||||
@@ -67,9 +67,9 @@ enum wxPowerBlockKind
|
||||
system is suspended, hibernated, plugged into or unplugged from the wall socket
|
||||
and so on. wxPowerEvents are emitted by wxWindows.
|
||||
|
||||
Notice that currently these events are generated only under MSW and Linux
|
||||
and that under Linux you @e must use wxPowerResource::Acquire() to receive
|
||||
them, e.g. typically an application interested in these events should
|
||||
Notice that currently these events are generated only under MSW, Linux and
|
||||
MacOS (cocoa). Under Linux and MacOS you @e must use wxPowerResource::Acquire()
|
||||
to receive them, e.g. typically an application interested in these events should
|
||||
initialize wxPowerResourceBlocker for ::wxPOWER_RESOURCE_SYSTEM resource
|
||||
using ::wxPOWER_DELAY block kind when initializing either the application
|
||||
itself or its main window. E.g. for an application that wants to handle
|
||||
|
||||
+96
-4
@@ -13,6 +13,11 @@
|
||||
|
||||
#include "wx/wxprec.h"
|
||||
|
||||
#ifndef WX_PRECOMP
|
||||
#include "wx/module.h"
|
||||
#include "wx/window.h"
|
||||
#endif
|
||||
|
||||
#include "wx/power.h"
|
||||
#include "wx/atomic.h"
|
||||
#include "wx/osx/private.h"
|
||||
@@ -20,11 +25,89 @@
|
||||
|
||||
#include <IOKit/pwr_mgt/IOPMLib.h>
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
static wxAtomicInt g_powerResourceSystemRefCount = 0;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// wxCocoaPowerModule
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
@interface wxCocoaPowerEventsObserver : NSObject
|
||||
@end
|
||||
|
||||
@implementation wxCocoaPowerEventsObserver
|
||||
|
||||
- (id)init {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
NSNotificationCenter *center = [[NSWorkspace sharedWorkspace] notificationCenter];
|
||||
|
||||
// Register for "will sleep" notification
|
||||
[center addObserver:self
|
||||
selector:@selector(handleWillSleep:)
|
||||
name:NSWorkspaceWillSleepNotification
|
||||
object:nil];
|
||||
|
||||
// Register for "did wake" notification
|
||||
[center addObserver:self
|
||||
selector:@selector(handleDidWake:)
|
||||
name:NSWorkspaceDidWakeNotification
|
||||
object:nil];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
[[[NSWorkspace sharedWorkspace] notificationCenter] removeObserver:self];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (void)handleWillSleep:(NSNotification *)notification {
|
||||
wxPowerEvent event(wxEVT_POWER_SUSPENDED);
|
||||
|
||||
for ( auto tlw : wxTopLevelWindows )
|
||||
tlw->HandleWindowEvent(event);
|
||||
}
|
||||
|
||||
- (void)handleDidWake:(NSNotification *)notification {
|
||||
wxPowerEvent event(wxEVT_POWER_RESUME);
|
||||
|
||||
for ( auto tlw : wxTopLevelWindows )
|
||||
tlw->HandleWindowEvent(event);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
namespace {
|
||||
// the global power events observer
|
||||
static wxCFRef<wxCocoaPowerEventsObserver*> g_powerEventsObserver;
|
||||
|
||||
// add power observers on init and remove on exit
|
||||
class wxCocoaPowerModule : public wxModule
|
||||
{
|
||||
public:
|
||||
bool OnInit() override { return true; }
|
||||
void OnExit() override
|
||||
{
|
||||
// There should be no other threads by now, so no locking is needed.
|
||||
if ( g_powerResourceSystemRefCount )
|
||||
{
|
||||
g_powerEventsObserver.reset();
|
||||
|
||||
g_powerResourceSystemRefCount = 0;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
wxDECLARE_NO_COPY_CLASS(wxCocoaPowerModule);
|
||||
};
|
||||
}; // anonymous namespace
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// wxPowerResource
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
static wxAtomicInt g_powerResourceSystemRefCount = 0;
|
||||
static NSObject* g_processInfoActivity = nil;
|
||||
|
||||
bool UpdatePowerResourceUsage(wxPowerResourceKind kind, const wxString& reason)
|
||||
@@ -58,9 +141,9 @@ bool UpdatePowerResourceUsage(wxPowerResourceKind kind, const wxString& reason)
|
||||
[[NSProcessInfo processInfo]
|
||||
endActivity:(id)g_processInfoActivity];
|
||||
g_processInfoActivity = nil;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
g_powerEventsObserver.reset();
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -73,7 +156,16 @@ wxPowerResource::Acquire(wxPowerResourceKind kind,
|
||||
{
|
||||
if ( blockKind == wxPOWER_DELAY )
|
||||
{
|
||||
// We don't support this mode under macOS because it's not needed there.
|
||||
if ( kind == wxPOWER_RESOURCE_SYSTEM )
|
||||
{
|
||||
wxAtomicInc(g_powerResourceSystemRefCount);
|
||||
|
||||
if ( g_powerEventsObserver.get() == nullptr )
|
||||
{
|
||||
g_powerEventsObserver = [[wxCocoaPowerEventsObserver alloc] init];
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user