CEF4Delphi/source/uceflazaruscocoa.pas

175 lines
4.3 KiB
ObjectPascal

// ************************************************************************
// ***************************** CEF4Delphi *******************************
// ************************************************************************
//
// CEF4Delphi is based on DCEF3 which uses CEF to embed a chromium-based
// browser in Delphi applications.
//
// The original license of DCEF3 still applies to CEF4Delphi.
//
// For more information about CEF4Delphi visit :
// https://www.briskbard.com/index.php?lang=en&pageid=cef
//
// Copyright © 2021 Salvador Diaz Fau. All rights reserved.
//
// Unit Author: Jonas Maebe
//
unit uCEFLazarusCocoa;
{$mode objfpc}{$H+}
{$I cef.inc}
{$IFDEF DARWIN} // $IFDEF MACOSX
{$ModeSwitch objectivec2}
{$ENDIF}
interface
uses
{$IFDEF DARWIN} // $IFDEF MACOSX
CocoaAll, CocoaInt, Cocoa_Extra,
{$ENDIF}
Classes, SysUtils;
{$IFDEF DARWIN} // $IFDEF MACOSX
type
CrAppProtocol = objcprotocol
function isHandlingSendEvent: objcbool; message 'isHandlingSendEvent';
end;
CrAppControlProtocol = objcprotocol(CrAppProtocol)
procedure setHandlingSendEvent(handlingSendEvent: objcbool); message 'setHandlingSendEvent:';
end;
TCrCocoaApplication = objcclass(TCocoaApplication, CrAppControlProtocol)
public
function isHandlingSendEvent: LCLObjCBoolean;
procedure setHandlingSendEvent(handlingSendEvent: LCLObjCBoolean);
procedure sendEvent(theEvent: NSEvent); override;
procedure terminate(sender: id); override;
private
fHandlingSendEvent: LCLObjCBoolean;
end;
procedure AddCrDelegate;
{$ENDIF}
implementation
{$IFDEF DARWIN} // $IFDEF MACOSX
uses
Forms;
type
TChromeAppDelegateIntercept = objcclass(NSProxy)
procedure tryToTerminateApplication(app: NSApplication); message 'tryToTerminateApplication:';
function initWithDelegate(delegate: id): id; message 'initWithDelegate:';
procedure dealloc; override;
function respondsToSelector(aSelector: SEL): LCLObjCBoolean; override;
procedure forwardInvocation (invocation: NSInvocation); override;
function methodSignatureForSelector (sel_: SEL): NSMethodSignature; override;
private
fLCLDelegate: id;
end;
procedure TChromeAppDelegateIntercept.tryToTerminateApplication(app: NSApplication);
begin
Application.MainForm.Close;
end;
function TChromeAppDelegateIntercept.initWithDelegate(delegate: id): id;
begin
fLCLDelegate:=delegate;
fLCLDelegate.retain;
result:=self;
end;
procedure TChromeAppDelegateIntercept.dealloc;
begin
fLCLDelegate.release;
fLCLDelegate:=nil;
inherited dealloc;
end;
function TChromeAppDelegateIntercept.respondsToSelector(aSelector: SEL): LCLObjCBoolean;
begin
if aSelector = objcselector('tryToTerminateApplication:') then
result:=true
else if assigned(fLCLDelegate) then
result:=fLCLDelegate.respondsToSelector(aSelector)
else
result:=false;
end;
procedure TChromeAppDelegateIntercept.forwardInvocation(invocation: NSInvocation);
begin
{ this only gets called in case we can't handle the invocation }
if assigned(fLCLDelegate) then
begin
invocation.setTarget(fLCLDelegate);
invocation.invoke;
end;
end;
function TChromeAppDelegateIntercept.methodSignatureForSelector(sel_: SEL): NSMethodSignature;
begin
{ if the original delegate can handle it, send it there. Otherwise we try to handle it }
if assigned(fLCLDelegate) then
result:=fLCLDelegate.methodSignatureForSelector(sel_);
if not assigned(result) then
result:=inherited;
end;
procedure AddCrDelegate;
var
delegate: id;
begin
delegate := TChromeAppDelegateIntercept.alloc.initWithDelegate(NSApp.delegate);
NSApp.setDelegate(delegate);
end;
function TCrCocoaApplication.isHandlingSendEvent: LCLObjCBoolean;
begin
result:=fHandlingSendEvent;
end;
procedure TCrCocoaApplication.setHandlingSendEvent(handlingSendEvent: LCLObjCBoolean);
begin
fHandlingSendEvent:=handlingSendEvent;
end;
procedure TCrCocoaApplication.sendEvent(theEvent: NSEvent);
var
CurrentHandling: LCLObjCBoolean;
begin
CurrentHandling:=isHandlingSendEvent;
setHandlingSendEvent(true);
inherited;
setHandlingSendEvent(CurrentHandling);
end;
procedure TCrCocoaApplication.terminate(sender: id);
var
AppDelegate: TChromeAppDelegateIntercept;
begin
AppDelegate:=TChromeAppDelegateIntercept(NSApp.delegate);
AppDelegate.tryToTerminateApplication(CocoaWidgetSet.NSApp);
end;
{$ENDIF}
end.