1
0
mirror of https://github.com/salvadordf/CEF4Delphi.git synced 2025-04-17 06:57:13 +02:00

CrAppProtocol for cocoa / Add Cocoa CloseChildHandle

This commit is contained in:
martin 2021-02-25 15:10:58 +01:00
parent 08d8c3076f
commit 121a43e824
8 changed files with 225 additions and 7 deletions

View File

@ -5,4 +5,9 @@ cd "$(dirname "$0")"
../../Lazarus_any_OS/AppHelper/create_mac_helper_apps.sh ../../../bin/ExternalPumpBrowser.app ../../Lazarus_any_OS/AppHelper/create_mac_helper_apps.sh ../../../bin/ExternalPumpBrowser.app
if [ "$(grep -i TCrCocoaApplication ../../../bin/ExternalPumpBrowser.app/Contents/Info.plist)" = "" ];
then
sed -i '' "1,4s/<dict>/<dict>\n <key>NSPrincipalClass<\/key>\n <string>TCrCocoaApplication<\/string>/" ../../../bin/ExternalPumpBrowser.app/Contents/Info.plist
fi
cd "$CDIR" cd "$CDIR"

View File

@ -43,7 +43,9 @@ unit uExternalPumpBrowser;
interface interface
uses uses
GlobalCefApplication, Classes, SysUtils, Messages, Forms, Controls, Graphics, GlobalCefApplication,
uCEFLazarusCocoa, // required for Cocoa
Classes, SysUtils, Messages, Forms, Controls, Graphics,
Dialogs, ExtCtrls, StdCtrls, LMessages, uCEFChromium, uCEFWindowParent, Dialogs, ExtCtrls, StdCtrls, LMessages, uCEFChromium, uCEFWindowParent,
uCEFConstants, uCEFTypes, uCEFInterfaces, uCEFChromiumEvents, uCEFConstants, uCEFTypes, uCEFInterfaces, uCEFChromiumEvents,
uCEFLinkedWindowParent, uCEFWorkScheduler; uCEFLinkedWindowParent, uCEFWorkScheduler;
@ -194,7 +196,9 @@ end;
procedure TForm1.Chromium1Close(Sender: TObject; const browser: ICefBrowser; var aAction: TCefCloseBrowserAction); procedure TForm1.Chromium1Close(Sender: TObject; const browser: ICefBrowser; var aAction: TCefCloseBrowserAction);
begin begin
aAction := cbaClose; // continue closing the browser
CEFLinkedWindowParent1.DestroyChildWindow;
aAction := cbaDelay;
end; end;
procedure TForm1.Chromium1BeforeClose(Sender: TObject; const browser: ICefBrowser); procedure TForm1.Chromium1BeforeClose(Sender: TObject; const browser: ICefBrowser);
@ -267,6 +271,7 @@ begin
end; end;
initialization initialization
AddCrDelegate;
if GlobalCEFApp = nil then begin if GlobalCEFApp = nil then begin
CreateGlobalCEFApp; CreateGlobalCEFApp;
if not GlobalCEFApp.StartMainProcess then begin if not GlobalCEFApp.StartMainProcess then begin

View File

@ -5,4 +5,9 @@ cd "$(dirname "$0")"
../AppHelper/create_mac_helper_apps.sh ../../../bin/ExternalPumpBrowser.app ../AppHelper/create_mac_helper_apps.sh ../../../bin/ExternalPumpBrowser.app
if [ "$(grep -i TCrCocoaApplication ../../../bin/ExternalPumpBrowser.app/Contents/Info.plist)" = "" ];
then
sed -i '' "1,4s/<dict>/<dict>\n <key>NSPrincipalClass<\/key>\n <string>TCrCocoaApplication<\/string>/" ../../../bin/ExternalPumpBrowser.app/Contents/Info.plist
fi
cd "$CDIR" cd "$CDIR"

View File

@ -43,7 +43,9 @@ unit uExternalPumpBrowser;
interface interface
uses uses
GlobalCefApplication, Classes, SysUtils, Messages, Forms, Controls, Graphics, GlobalCefApplication,
uCEFLazarusCocoa, // required for Cocoa
Classes, SysUtils, Messages, Forms, Controls, Graphics,
Dialogs, ExtCtrls, StdCtrls, LMessages, uCEFChromium, uCEFWindowParent, Dialogs, ExtCtrls, StdCtrls, LMessages, uCEFChromium, uCEFWindowParent,
uCEFConstants, uCEFTypes, uCEFInterfaces, uCEFChromiumEvents, uCEFConstants, uCEFTypes, uCEFInterfaces, uCEFChromiumEvents,
uCEFLinkedWindowParent, uCEFWorkScheduler; uCEFLinkedWindowParent, uCEFWorkScheduler;
@ -291,6 +293,9 @@ end;
{$ENDIF} {$ENDIF}
initialization initialization
{$IFDEF DARWIN} // $IFDEF MACOSX
AddCrDelegate;
{$ENDIF}
if GlobalCEFApp = nil then begin if GlobalCEFApp = nil then begin
CreateGlobalCEFApp; CreateGlobalCEFApp;
if not GlobalCEFApp.StartMainProcess then begin if not GlobalCEFApp.StartMainProcess then begin

View File

@ -22,7 +22,7 @@
<Description Value="CEF4Delphi is an open source project created by Salvador Díaz Fau to embed Chromium-based browsers in applications made with Delphi or Lazarus/FPC."/> <Description Value="CEF4Delphi is an open source project created by Salvador Díaz Fau to embed Chromium-based browsers in applications made with Delphi or Lazarus/FPC."/>
<License Value="MPL 1.1"/> <License Value="MPL 1.1"/>
<Version Major="88" Minor="2" Release="9"/> <Version Major="88" Minor="2" Release="9"/>
<Files Count="198"> <Files Count="199">
<Item1> <Item1>
<Filename Value="..\source\uCEFAccessibilityHandler.pas"/> <Filename Value="..\source\uCEFAccessibilityHandler.pas"/>
<UnitName Value="uCEFAccessibilityHandler"/> <UnitName Value="uCEFAccessibilityHandler"/>
@ -831,6 +831,10 @@
<Filename Value="..\source\uCEFLinkedWinControlBase.pas"/> <Filename Value="..\source\uCEFLinkedWinControlBase.pas"/>
<UnitName Value="uCEFLinkedWinControlBase"/> <UnitName Value="uCEFLinkedWinControlBase"/>
</Item198> </Item198>
<Item199>
<Filename Value="..\source\uceflazaruscocoa.pas"/>
<UnitName Value="uceflazaruscocoa"/>
</Item199>
</Files> </Files>
<RequiredPkgs Count="4"> <RequiredPkgs Count="4">
<Item1> <Item1>

View File

@ -65,7 +65,8 @@ uses
uCEFMediaSinkDeviceInfoCallback, uCEFJson, uCEFBitmapBitBuffer, uCEFMediaSinkDeviceInfoCallback, uCEFJson, uCEFBitmapBitBuffer,
uCEFPrintDialogCallback, uCEFPrintHandler, uCEFPrintJobCallback, uCEFPrintDialogCallback, uCEFPrintHandler, uCEFPrintJobCallback,
uCEFLinuxFunctions, uCEFLinuxTypes, uCEFLinuxConstants, uCEFLinuxFunctions, uCEFLinuxTypes, uCEFLinuxConstants,
uCEFWorkSchedulerQueueThread, uCEFLinkedWinControlBase, LazarusPackageIntf; uCEFWorkSchedulerQueueThread, uCEFLinkedWinControlBase, uCEFLazarusCocoa,
LazarusPackageIntf;
implementation implementation

View File

@ -37,15 +37,18 @@
unit uCEFWinControl; unit uCEFWinControl;
{$I cef.inc}
{$IFDEF FPC} {$IFDEF FPC}
{$MODE OBJFPC}{$H+} {$MODE OBJFPC}{$H+}
{$IFDEF MACOSX}
{$ModeSwitch objectivec1}
{$ENDIF}
{$ENDIF} {$ENDIF}
{$IFNDEF CPUX64}{$ALIGN ON}{$ENDIF} {$IFNDEF CPUX64}{$ALIGN ON}{$ENDIF}
{$MINENUMSIZE 4} {$MINENUMSIZE 4}
{$I cef.inc}
interface interface
uses uses
@ -57,6 +60,9 @@ uses
LCLProc, LCLType, LCLIntf, LResources, InterfaceBase, LCLProc, LCLType, LCLIntf, LResources, InterfaceBase,
{$ENDIF} {$ENDIF}
{$ENDIF} {$ENDIF}
{$IFDEF FPC}{$IFDEF MACOSX}
CocoaAll,
{$ENDIF}{$ENDIF}
uCEFTypes, uCEFInterfaces; uCEFTypes, uCEFInterfaces;
type type
@ -186,12 +192,25 @@ function TCEFWinControl.DestroyChildWindow : boolean;
var var
TempHWND : HWND; TempHWND : HWND;
{$ENDIF} {$ENDIF}
{$IFDEF FPC}{$IFDEF MACOSX}
var
ViewObj: NSObject;
{$ENDIF}{$ENDIF}
begin begin
{$IFDEF MSWINDOWS} {$IFDEF MSWINDOWS}
TempHWND := ChildWindowHandle; TempHWND := ChildWindowHandle;
Result := (TempHWND <> 0) and DestroyWindow(TempHWND); Result := (TempHWND <> 0) and DestroyWindow(TempHWND);
{$ELSE} {$ELSE}
Result := False; Result := False;
{$IFDEF FPC}{$IFDEF MACOSX}
ViewObj := NSObject(ChildWindowHandle);
if ViewObj <> nil then begin
if ViewObj.isKindOfClass_(nsview) then begin
NSView(ViewObj).removeFromSuperview;
Result := True;
end;
end;
{$ENDIF}{$ENDIF}
{$ENDIF} {$ENDIF}
end; end;

174
source/uceflazaruscocoa.pas Normal file
View File

@ -0,0 +1,174 @@
// ************************************************************************
// ***************************** 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.