2021-02-25 15:10:58 +01:00
|
|
|
// ************************************************************************
|
|
|
|
// ***************************** 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
|
|
|
|
//
|
2023-01-07 15:53:04 +01:00
|
|
|
// Copyright © 2023 Salvador Diaz Fau. All rights reserved.
|
2021-02-25 15:10:58 +01:00
|
|
|
//
|
|
|
|
// 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}
|
2021-03-20 05:25:18 +01:00
|
|
|
Classes, SysUtils, ctypes;
|
2021-02-25 15:10:58 +01:00
|
|
|
|
|
|
|
{$IFDEF DARWIN} // $IFDEF MACOSX
|
|
|
|
type
|
|
|
|
CrAppProtocol = objcprotocol
|
2021-03-01 23:59:58 +01:00
|
|
|
function isHandlingSendEvent: LCLObjCBoolean; message 'isHandlingSendEvent';
|
2021-02-25 15:10:58 +01:00
|
|
|
end;
|
|
|
|
|
|
|
|
CrAppControlProtocol = objcprotocol(CrAppProtocol)
|
2021-03-01 23:59:58 +01:00
|
|
|
procedure setHandlingSendEvent(handlingSendEvent: LCLObjCBoolean); message 'setHandlingSendEvent:';
|
2021-02-25 15:10:58 +01:00
|
|
|
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;
|
|
|
|
|
2021-03-20 05:25:18 +01:00
|
|
|
var LastMacOsKeyDownCode: cushort;
|
2021-02-25 15:10:58 +01:00
|
|
|
{$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);
|
2021-03-20 05:25:18 +01:00
|
|
|
if (theEvent.type_ = NSKeyDown)
|
|
|
|
then begin
|
|
|
|
LastMacOsKeyDownCode := theEvent.keyCode;
|
|
|
|
end;
|
2021-02-25 15:10:58 +01:00
|
|
|
inherited;
|
2021-03-20 05:25:18 +01:00
|
|
|
LastMacOsKeyDownCode:=0;
|
2021-02-25 15:10:58 +01:00
|
|
|
setHandlingSendEvent(CurrentHandling);
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TCrCocoaApplication.terminate(sender: id);
|
|
|
|
var
|
|
|
|
AppDelegate: TChromeAppDelegateIntercept;
|
|
|
|
begin
|
|
|
|
AppDelegate:=TChromeAppDelegateIntercept(NSApp.delegate);
|
|
|
|
AppDelegate.tryToTerminateApplication(CocoaWidgetSet.NSApp);
|
|
|
|
end;
|
|
|
|
|
|
|
|
{$ENDIF}
|
|
|
|
|
|
|
|
end.
|
|
|
|
|