cocoa: update handling of isRunning flag in NSApplication, for the proper modal window passing focus back to the calling window. (partial rework of r62707 #64e40526df)

git-svn-id: trunk@63247 -
This commit is contained in:
dmitry 2020-05-29 04:46:01 +00:00
parent 001d9849ac
commit e5dd3bb2c6
2 changed files with 48 additions and 0 deletions

View File

@ -33,3 +33,29 @@
// the call stays there until, LCL application is terminated
{$define COCOALOOPHIJACK}
{$endif}
{$ifdef COCOALOOPOVERRIDE}
// The proper switching modal dialogs depends on NSApp.isRunning method
// The method returns true (on macOS 10.15 and later), only with "run" method
// called direclty.
// (there's an internal flag, that's defines the value of the property)
// Since LCL needs the direct control over the event loop (with Loopoverride)
// it canot call the inherited NSapp.run. (or the control is lossed to Cocoa)
//
// Instead, CocoaWS can set isRunning property to true, in TWO ways
// 1) (COCOAPPRUNNING_OVERRIDEPROPERTY)
// override isRunning method and return TRUE when wanted
// 2) (COCOAPPRUNNING_SETINTPROPERTY)
// using KeyValue APIs set the internal property
// Either method is not entirely good, but it makes modal switching work.
//
// The actual problem (of not having isRunning set to true), is the following:
// 1) Create a window.
// 2) Show a modal dialog.
// 3) Close the modal window
// 4) the focus stays in the closed and hidden modal window...
// with NSApp.isRunning, the focus goes back to the previously active window
{$define COCOAPPRUNNING_OVERRIDEPROPERTY}
{.$define COCOAPPRUNNING_SETINTPROPERTY}
{$endif}

View File

@ -86,6 +86,9 @@ type
modals : NSMutableDictionary;
inputclient : TCocoaInputClient;
inputctx : NSTextInputContext;
{$ifdef COCOAPPRUNNING_OVERRIDEPROPERTY}
Stopped : Boolean;
{$endif}
procedure dealloc; override;
{$ifdef COCOALOOPOVERRIDE}
@ -96,6 +99,10 @@ type
function runModalForWindow(theWindow: NSWindow): NSInteger; override;
procedure lclSyncCheck(arg: id); message 'lclSyncCheck:';
{$ifdef COCOAPPRUNNING_OVERRIDEPROPERTY}
function isRunning: Boolean; override;
procedure stop(sender: id); override;
{$endif}
end;
{ TModalSession }
@ -445,6 +452,9 @@ end;
{$ifdef COCOALOOPOVERRIDE}
procedure TCocoaApplication.run;
begin
{$ifdef COCOAPPRUNNING_SETINTPROPERTY}
setValue_forKey(NSNumber.numberWithBool(true), NSSTR('_running'));
{$endif}
aloop();
end;
{$endif}
@ -676,6 +686,18 @@ begin
{$endif}
end;
{$ifdef COCOAPPRUNNING_OVERRIDEPROPERTY}
function TCocoaApplication.isRunning: Boolean;
begin
Result:=not Stopped;
end;
procedure TCocoaApplication.stop(sender: id);
begin
Stopped := true;
inherited stop(sender);
end;
{$endif}
procedure InternalInit;
begin