You could use for example:
myCanvas->Connect("ProcessedEvent(Int_t,Int_t,Int_t,TObject*)", "MyClass (or empty if it's a script/macro)",
this or nullptr, "CaptureEvent(Int_t,Int_t,Int_t,TObject*)");
and then you implement void MyClass::CaptureEvent or just void CaptureEvent in a macro.
see examples within the tutorials folder:
gui/exec3.C: c1->Connect("ProcessedEvent(Int_t,Int_t,Int_t,TObject*)", nullptr, nullptr,
gui/statusBar.C: myc->Connect("ProcessedEvent(Int_t,Int_t,Int_t,TObject*)","MyMainFrame",this,
gui/guitest.C: fFrame->Connect("ProcessedEvent(Event_t*)", "TileFrame", this,
gui/guitest.C: fEc1->GetCanvas()->Connect("ProcessedEvent(Int_t,Int_t,Int_t,TObject*)",
If you rather want to catch ctrl+C or signals like that, then use:
std::shared_ptr<TSignalHandler> interruptHandler = std::make_shared<TSignalHandler>(kSigInterrupt, kFALSE);
interruptHandler->Add();
and you can redirect things to prevent kill with things like:
gVirtualX->GrabKey(GetId(), gVirtualX->KeysymToKeycode(kKey_c),
kKeyControlMask, en); // capture CTRL+C
gVirtualX->GrabKey(GetId(), gVirtualX->KeysymToKeycode(kKey_c),
kKeyControlMask | kKeyMod2Mask,
en); // capture CTRL+C NumLock on