cocoa: resolve windows-level wrong use. A drawback - lost SystemOnTop setting, now behave similar to OnTop. (similar to Windows). #34939

git-svn-id: trunk@61162 -
This commit is contained in:
dmitry 2019-05-05 20:42:10 +00:00
parent 398156e28e
commit 9e4ab0beb5
2 changed files with 73 additions and 45 deletions

View File

@ -212,21 +212,15 @@ const
NSAppKitVersionNumber10_14 = 1641.10;
const
//kCGBaseWindowLevelKey = 0;
//kCGMinimumWindowLevelKey = 1;
//kCGDesktopWindowLevelKey = 2;
//kCGBackstopMenuLevelKey = 3;
NSNormalWindowLevel = 4;
NSFloatingWindowLevel = 5;
NSSubmenuWindowLevel = 6;
NSTornOffMenuWindowLevel = 6;
//kCGDockWindowLevelKey = 7; deprecated
NSMainMenuWindowLevel = 8;
NSStatusWindowLevel = 9;
NSModalPanelWindowLevel = 10;
NSPopUpMenuWindowLevel = 11;
NSScreenSaverWindowLevel = 12;
function NSNormalWindowLevel: NSInteger; inline;
function NSFloatingWindowLevel: NSInteger; inline;
function NSSubmenuWindowLevel: NSInteger; inline;
function NSTornOffMenuWindowLevel: NSInteger; inline;
function NSMainMenuWindowLevel: NSInteger; inline;
function NSStatusWindowLevel: NSInteger; inline;
function NSModalPanelWindowLevel: NSInteger; inline;
function NSPopUpMenuWindowLevel: NSInteger; inline;
function NSScreenSaverWindowLevel: NSInteger; inline;
//kCGScreenSaverWindowLevelKey = 13;
//kCGMaximumWindowLevelKey = 14;
//kCGOverlayWindowLevelKey = 15;
@ -273,5 +267,50 @@ const
implementation
function NSNormalWindowLevel: NSInteger;
begin
Result:=CGWindowLevelForKey(kCGNormalWindowLevelKey);
end;
function NSFloatingWindowLevel: NSInteger;
begin
Result:=CGWindowLevelForKey(kCGFloatingWindowLevelKey);
end;
function NSSubmenuWindowLevel: NSInteger;
begin
Result:=CGWindowLevelForKey(kCGTornOffMenuWindowLevelKey);
end;
function NSTornOffMenuWindowLevel: NSInteger;
begin
Result:=CGWindowLevelForKey(kCGTornOffMenuWindowLevelKey);
end;
function NSMainMenuWindowLevel: NSInteger;
begin
Result:=CGWindowLevelForKey(kCGMainMenuWindowLevelKey);
end;
function NSStatusWindowLevel: NSInteger;
begin
Result:=CGWindowLevelForKey(kCGStatusWindowLevelKey);
end;
function NSModalPanelWindowLevel: NSInteger;
begin
Result:=CGWindowLevelForKey(kCGModalPanelWindowLevelKey);
end;
function NSPopUpMenuWindowLevel: NSInteger;
begin
Result:=CGWindowLevelForKey(kCGPopUpMenuWindowLevelKey);
end;
function NSScreenSaverWindowLevel: NSInteger;
begin
Result:=CGWindowLevelForKey(kCGScreenSaverWindowLevelKey);
end;
end.

View File

@ -182,16 +182,17 @@ uses
CocoaInt;
const
// The documentation says we should use NSNormalWindowLevel=4 for normal forms,
// but in practice this causes the issue http://bugs.freepascal.org/view.php?id=28473
// The only value that works is zero =(
FormStyleToWindowLevel: array[TFormStyle] of NSInteger = (
{ fsNormal } 0,
{ fsMDIChild } 0,
{ fsMDIForm } 0,
{ fsStayOnTop } 9, // NSStatusWindowLevel
{ fsSplash } 9, // NSStatusWindowLevel
{ fsSystemStayOnTop } 10 // NSModalPanelWindowLevel
// The documentation is using constants like "NSNormalWindowLevel=4" for normal forms,
// however, these are macros of a function call to CGWindowLevelKey()
// where "Key" values of kCGNormalWindowLevelKey=4.
FormStyleToWindowLevelKey: array[TFormStyle] of NSInteger = (
{ fsNormal } kCGNormalWindowLevelKey,
{ fsMDIChild } kCGNormalWindowLevelKey,
{ fsMDIForm } kCGNormalWindowLevelKey,
{ fsStayOnTop } kCGFloatingWindowLevelKey,
{ fsSplash } kCGFloatingWindowLevelKey,
{ fsSystemStayOnTop } kCGFloatingWindowLevelKey // NSModalPanelWindowLevel
);
// Window levels make the form always stay on top, so if it is supposed to
// stay on top of the app only, then a workaround is to hide it while the app
@ -200,8 +201,8 @@ const
{ fsNormal } False,
{ fsMDIChild } False,
{ fsMDIForm } False,
{ fsStayOnTop } True,
{ fsSplash } True,
{ fsStayOnTop } false,
{ fsSplash } false,
{ fsSystemStayOnTop } False
);
@ -219,24 +220,12 @@ procedure WindowSetFormStyle(win: NSWindow; AFormStyle: TFormStyle);
var
lvl : NSInteger;
begin
if not (AFormStyle in [fsNormal, fsMDIChild, fsMDIForm]) then
begin
lvl := FormStyleToWindowLevel[AFormStyle];
{$ifdef BOOLFIX}
win.setHidesOnDeactivate_(Ord(FormStyleToHideOnDeactivate[AFormStyle]));
{$else}
win.setHidesOnDeactivate(FormStyleToHideOnDeactivate[AFormStyle]);
{$endif}
end
else
begin
lvl := 0;
{$ifdef BOOLFIX}
win.setHidesOnDeactivate_(Ord(false));
{$else}
win.setHidesOnDeactivate(false);
{$endif}
end;
lvl := CGWindowLevelForKey(FormStyleToWindowLevelKey[AFormStyle]);
{$ifdef BOOLFIX}
win.setHidesOnDeactivate_(Ord(FormStyleToHideOnDeactivate[AFormStyle]));
{$else}
win.setHidesOnDeactivate(FormStyleToHideOnDeactivate[AFormStyle]);
{$endif}
win.setLevel(lvl);
if win.isKindOfClass(TCocoaWindow) then
TCocoaWindow(win).keepWinLevel := lvl;