willSleep and didWake Notifications

Mac OSX specific forum
infratec
Always Here
Always Here
Posts: 7618
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

willSleep and didWake Notifications

Post by infratec »

Again I need some help for Cocoa stuff.

I need to detect if the mac goes to sleep or does wake up.
I found:

Code: Select all

func applicationDidFinishLaunching(_ aNotification: Notification) {
    NSWorkspace.shared.notificationCenter.addObserver(self, selector: #selector(sleepListener(_:)),
                                                      name: NSWorkspace.willSleepNotification, object: nil)
    NSWorkspace.shared.notificationCenter.addObserver(self, selector: #selector(sleepListener(_:)),
                                                      name: NSWorkspace.didWakeNotification, object: nil)
}


@objc private func sleepListener(_ aNotification: Notification) {
    print("listening to sleep")


    if aNotification.name == NSWorkspace.willSleepNotification {
        print("Going to sleep")
    } else if aNotification.name == NSWorkspace.didWakeNotification {
        print("Woke up")
    } else {
        print("Some other event other than the first two")
    }
}
How can I port this to PB?

I tried something like this:

Code: Select all

Procedure Notification_SleepListenerCB(notification)
  Protected notificationName = CocoaMessage(0, CocoaMessage(0, notification, "name"), "UTF8String")
  Debug PeekS(notificationName, -1, #PB_UTF8)
  
  Debug "Will sleep"
EndProcedure



app = CocoaMessage(0,0,"NSApplication sharedApplication")
Debug app

appDelegate = CocoaMessage(0, app, "delegate")
Debug appDelegate

delegateClass = object_getClass_(appDelegate)
Debug delegateClass

selector = sel_registerName_("willSleepNotification:")
Debug selector

notificationCenter = CocoaMessage(0, 0, "NSNotificationCenter defaultCenter")

class_addMethod_(delegateClass, selector, @Notification_SleepListenerCB, "v@:@")

CocoaMessage(0, notificationCenter, "addObserver:", appDelegate, "selector:", selector, "name:$", @"willSleepNotification", "object:", #nil)


i = 10
Repeat
  Delay(1000)
  Debug FormatDate("%yyyy.%mm.%dd %hh:%ii:%ss", Date())
  i - 1
Until i = 0

Debug CocoaMessage(0, notificationCenter, "removeObserver:", appDelegate, "name:$", @"willSleepNotification", "object:", #nil)
But no success.
I also don't now the structure of aNotification to detect the different notifications.
Ok I can also use 2 different callbacks, so this will not be my biggest problem.
Last edited by infratec on Fri May 05, 2023 10:50 am, edited 1 time in total.
infratec
Always Here
Always Here
Posts: 7618
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: willSleep and didWake Notifications

Post by infratec »

Ok found how to get more info about the notification:

Code: Select all

Protected notificationName = CocoaMessage(0, CocoaMessage(0, notification, "name"), "UTF8String")
Debug PeekS(notificationName, -1, #PB_UTF8)
infratec
Always Here
Always Here
Posts: 7618
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: willSleep and didWake Notifications

Post by infratec »

Still not working.

Can someone provide a working example for

NSWorkspaceWillSleepNotification

?
infratec
Always Here
Always Here
Posts: 7618
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: willSleep and didWake Notifications

Post by infratec »

An other example:

Code: Select all

- (void) receiveSleepNote: (NSNotification*) note
{
    NSLog(@"receiveSleepNote: %@", [note name]);
}


- (void) receiveWakeNote: (NSNotification*) note
{
    NSLog(@"receiveWakeNote: %@", [note name]);
}


- (void) fileNotifications
{
    //These notifications are filed on NSWorkspace's notification center, not the default
    // notification center. You will not receive sleep/wake notifications if you file
    //with the default notification center.

    [[[NSWorkspace sharedWorkspace] notificationCenter] addObserver: self
            selector: @selector(receiveSleepNote:)
            name: NSWorkspaceWillSleepNotification object: NULL];

    [[[NSWorkspace sharedWorkspace] notificationCenter] addObserver: self
            selector: @selector(receiveWakeNote:)
            name: NSWorkspaceDidWakeNotification object: NULL];
}
infratec
Always Here
Always Here
Posts: 7618
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: willSleep and didWake Notifications

Post by infratec »

Ok, found something which I was able to modify.

But ugly:

Code: Select all

ProcedureC WillSleep_CB(obj, sel, notification)
  Debug "Sleep Event " + Date()
EndProcedure

Procedure AddWillSleepCallback()
  
  Protected.i class, sel
  
  class = objc_allocateClassPair_(objc_getClass_("NSObject"), "WillSleepNotificationClass", 0)
  sel = sel_registerName_("WillSleepNotification:")
  class_addMethod_(class, sel, @WillSleep_CB(), "v@:@")
  objc_registerClassPair_(class)
  
  CocoaMessage(0, CocoaMessage(0, CocoaMessage(0, 0, "NSWorkspace sharedWorkspace"), "notificationCenter"), 
               "addObserver:", CocoaMessage(0, class, "new"), "selector:", sel, "name:$", 
               @"NSWorkspaceWillSleepNotification", "object:", #nil)
EndProcedure



ProcedureC DidWake_CB(obj, sel, notification)
  Debug "DidWake Event " + Date()
EndProcedure

Procedure AddDidWakeCallback()
  
  Protected.i class, sel
  
  class = objc_allocateClassPair_(objc_getClass_("NSObject"), "DidWakeNotificationClass", 0)
  sel = sel_registerName_("DidWakeNotification:")
  class_addMethod_(class, sel, @DidWake_CB(), "v@:@")
  objc_registerClassPair_(class)
  
  CocoaMessage(0, CocoaMessage(0, CocoaMessage(0, 0, "NSWorkspace sharedWorkspace"), "notificationCenter"), 
               "addObserver:", CocoaMessage(0, class, "new"), "selector:", sel, "name:$", 
               @"NSWorkspaceDidWakeNotification", "object:", #nil)
EndProcedure



AddWillSleepCallback()
AddDidWakeCallback()


OpenWindow(0, 0, 0, 320, 84, "WillSleep DidWake", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)

Repeat
  Event = WaitWindowEvent()
Until Event = #PB_Event_CloseWindow
infratec
Always Here
Always Here
Posts: 7618
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: willSleep and didWake Notifications

Post by infratec »

Better:

Code: Select all

Procedure AddCallbacks()
  
  Protected.i class, Workspace, NotificationCenter, Instance, selSleep, selWake
  
  
  class = objc_allocateClassPair_(objc_getClass_("NSObject"), "WillSleepDidWakeNotificationClass", 0)
  
  selSleep = sel_registerName_("WillSleepNotification:")
  class_addMethod_(class, selSleep, @WillSleep_CB(), "v@:@")
  
  selWake = sel_registerName_("DidWakeNotification:")
  class_addMethod_(class, selWake, @DidWake_CB(), "v@:@")
  
  objc_registerClassPair_(class)
  
  Workspace = CocoaMessage(0, 0, "NSWorkspace sharedWorkspace")
  NotificationCenter = CocoaMessage(0, Workspace, "notificationCenter")
  Instance = CocoaMessage(0, class, "new")
  
  CocoaMessage(#Null, NotificationCenter, "addObserver:", Instance, "selector:", selSleep, "name:$", @"NSWorkspaceWillSleepNotification", "object:", #nil)
  CocoaMessage(#Null, NotificationCenter, "addObserver:", Instance, "selector:", selWake, "name:$", @"NSWorkspaceDidWakeNotification", "object:", #nil)
  
EndProcedure
User avatar
jacdelad
Addict
Addict
Posts: 2010
Joined: Wed Feb 03, 2021 12:46 pm
Location: Riesa

Re: willSleep and didWake Notifications

Post by jacdelad »

Greatest monologue ever! :lol:
Good morning, that's a nice tnetennba!

PureBasic 6.21/Windows 11 x64/Ryzen 7900X/32GB RAM/3TB SSD
Synology DS1821+/DX517, 130.9TB+50.8TB+2TB SSD
User avatar
mk-soft
Always Here
Always Here
Posts: 6245
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: willSleep and didWake Notifications

Post by mk-soft »

Very nice ;)
I had already looked at it yesterday and started. But you were quicker to find the solution.

Code: Select all

;-TOP

; Base    : infractec
; Update  : mk-soft
; Link    : https://www.purebasic.fr/english/viewtopic.php?t=81565

Enumeration CustomEvent #PB_Event_FirstCustomValue
  #MyEvent_WillSleepNotification
  #MyEvent_DidWakeNotification
EndEnumeration

; ----

ProcedureC Notification_WillSleepCB(obj, sel, notification)
  PostEvent(#MyEvent_WillSleepNotification, 0, 0)
EndProcedure

ProcedureC Notification_DidWakeCB(obj, sel, notification)
  PostEvent(#MyEvent_DidWakeNotification, 0, 0)
EndProcedure

; ----

Procedure AddWorkspaceObserver()
  
  Protected.i class, Workspace, NotificationCenter, Instance, selSleep, selWake
  
  
  class = objc_allocateClassPair_(objc_getClass_("NSObject"), "MyWorkspaceNotificationClass", 0)
  
  selSleep = sel_registerName_("WillSleepNotification:")
  class_addMethod_(class, selSleep, @Notification_WillSleepCB(), "v@:@")
  
  selWake = sel_registerName_("DidWakeNotification:")
  class_addMethod_(class, selWake, @Notification_DidWakeCB(), "v@:@")
  
  objc_registerClassPair_(class)
  Instance = class_createInstance_(class, 0)
  
  Workspace = CocoaMessage(0, 0, "NSWorkspace sharedWorkspace")
  NotificationCenter = CocoaMessage(0, Workspace, "notificationCenter")
  
  CocoaMessage(#Null, NotificationCenter, "addObserver:", Instance, "selector:", selSleep, "name:$", @"NSWorkspaceWillSleepNotification", "object:", #nil)
  CocoaMessage(#Null, NotificationCenter, "addObserver:", Instance, "selector:", selWake, "name:$", @"NSWorkspaceDidWakeNotification", "object:", #nil)
  
  ProcedureReturn Instance
EndProcedure

Procedure RemoveWorkspaceObserver(Instance)
  Protected.i Workspace, NotificationCenter
  Workspace = CocoaMessage(0, 0, "NSWorkspace sharedWorkspace")
  NotificationCenter = CocoaMessage(0, Workspace, "notificationCenter")
  CocoaMessage(0, NotificationCenter, "removeObserver:", Instance, "name:$", @"NSWorkspaceWillSleepNotification", "object:", #nil)
  CocoaMessage(0, NotificationCenter, "removeObserver:", Instance, "name:$", @"NSWorkspaceDidWakeNotification", "object:", #nil)
EndProcedure

; ----

Procedure AddInfo(Text.s)
  Protected dx, dy
  dx = WindowWidth(0)
  dy = WindowHeight(0)
  AddGadgetItem(0, -1, FormatDate("%HH:%MM:%SS - ", Date()) + Text)
EndProcedure

Procedure UpdateWindow()
  Protected dx, dy
  dx = WindowWidth(0)
  dy = WindowHeight(0) - StatusBarHeight(0) - MenuHeight()
  ; Resize Gadgets
  ResizeGadget(0, 0, 0, dx, dy)
EndProcedure

; ----

Global WorkspaceInstance

Procedure Main()
  Protected dx, dy
  
  #WinStyle = #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_MaximizeGadget | #PB_Window_MinimizeGadget
  
  If OpenWindow(0, #PB_Ignore, #PB_Ignore, 600, 400, "Window", #WinStyle)
    ; MenuBar
    CreateMenu(0, WindowID(0))
    MenuTitle("File")
    
    ; StatusBar
    CreateStatusBar(0, WindowID(0))
    AddStatusBarField(#PB_Ignore)
    
    ; Gadgets
    dx = WindowWidth(0)
    dy = WindowHeight(0) - StatusBarHeight(0) - MenuHeight()
    ListViewGadget(0, 0, 0, dx, dy)
    
    ; Bind Events
    BindEvent(#PB_Event_SizeWindow, @UpdateWindow(), 0)
    
    WorkspaceInstance = AddWorkspaceObserver()
    
    ; Main Loop
    Repeat
      Select WaitWindowEvent()
        Case #PB_Event_CloseWindow
          Select EventWindow()
            Case 0
              Break
          EndSelect
          
        Case #PB_Event_Menu
          Select EventMenu()
            
          EndSelect
          
        Case #PB_Event_Gadget
          Select EventGadget()
              
          EndSelect
                    
        Case #MyEvent_WillSleepNotification
          AddInfo("WillSleepNotification")
          
        Case #MyEvent_DidWakeNotification
          AddInfo("DidWakeNotification")
        
      EndSelect
    ForEver
    
    RemoveWorkspaceObserver(WorkspaceInstance)
    
  EndIf
  
EndProcedure : Main() : End
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
Post Reply