mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-06-02 09:52:45 +02:00
cocoa: additional control over cocoa window levels
git-svn-id: trunk@59185 -
This commit is contained in:
parent
e355e20721
commit
a4503bccc0
@ -177,6 +177,7 @@ type
|
||||
procedure SetMainMenu(const AMenu: HMENU; const ALCLMenu: TMenu);
|
||||
function StartModal(awin: NSWindow; hasMenu: Boolean): Boolean;
|
||||
procedure EndModal(awin: NSWindow);
|
||||
function isModalSession: Boolean;
|
||||
|
||||
{todo:}
|
||||
function DCGetPixel(CanvasHandle: HDC; X, Y: integer): TGraphicsColor; override;
|
||||
@ -580,11 +581,19 @@ end;
|
||||
function TCocoaWidgetSet.StartModal(awin: NSWindow; hasMenu: Boolean): Boolean;
|
||||
var
|
||||
sess : NSModalSession;
|
||||
lvl : NSInteger;
|
||||
begin
|
||||
Result := false;
|
||||
if not Assigned(awin) then Exit;
|
||||
|
||||
lvl := awin.level;
|
||||
|
||||
sess := NSApplication(NSApp).beginModalSessionForWindow(awin);
|
||||
if not Assigned(sess) then Exit;
|
||||
|
||||
// beginModalSession "configures" the modality and potentially is changing window level
|
||||
awin.setLevel(lvl);
|
||||
|
||||
if not Assigned(Modals) then Modals := TList.Create;
|
||||
|
||||
// If a modal menu has it's menu, then SetMainMenu has already been called
|
||||
@ -619,6 +628,10 @@ begin
|
||||
Modals.Delete(Modals.Count-1);
|
||||
end;
|
||||
|
||||
function TCocoaWidgetSet.isModalSession: Boolean;
|
||||
begin
|
||||
Result := Assigned(Modals) and (Modals.Count > 0);
|
||||
end;
|
||||
|
||||
initialization
|
||||
// {$I Cocoaimages.lrs}
|
||||
|
@ -138,6 +138,7 @@ type
|
||||
procedure windowDidExitFullScreen(notification: NSNotification); message 'windowDidExitFullScreen:';
|
||||
public
|
||||
callback: IWindowCallback;
|
||||
keepWinLevel : NSInteger;
|
||||
//LCLForm: TCustomForm;
|
||||
procedure dealloc; override;
|
||||
function acceptsFirstResponder: Boolean; override;
|
||||
@ -758,6 +759,18 @@ end;
|
||||
|
||||
procedure TCocoaWindow.windowDidBecomeKey(notification: NSNotification);
|
||||
begin
|
||||
// forcing to keep the level as all other LCL windows
|
||||
// Modal windows tend to "restore" their elevated level
|
||||
// And that doesn't work for modal windows that are "Showing" other windows
|
||||
|
||||
// Another approach is to set elevated levels for windows, shown during modal session
|
||||
// That requires to revoke the elevated level from windows on closing a window session
|
||||
// This might be the way to go, if FormStyle (such as fsStayOnTop) would come
|
||||
// in conflict with modality
|
||||
if level <> keepWinLevel then begin
|
||||
setLevel(keepWinLevel);
|
||||
end;
|
||||
|
||||
if Assigned(callback) then
|
||||
callback.Activate;
|
||||
end;
|
||||
|
@ -170,6 +170,7 @@ type
|
||||
|
||||
procedure ArrangeTabOrder(const AWinControl: TWinControl);
|
||||
function HWNDToForm(AFormHandle: HWND): TCustomForm;
|
||||
procedure WindowSetFormStyle(win: NSWindow; AFormStyle: TFormStyle);
|
||||
|
||||
implementation
|
||||
|
||||
@ -210,6 +211,25 @@ begin
|
||||
Result := AForm.BorderStyle;
|
||||
end;
|
||||
|
||||
procedure WindowSetFormStyle(win: NSWindow; AFormStyle: TFormStyle);
|
||||
var
|
||||
lvl : NSInteger;
|
||||
begin
|
||||
if not (AFormStyle in [fsNormal, fsMDIChild, fsMDIForm]) then
|
||||
begin
|
||||
lvl := FormStyleToWindowLevel[AFormStyle];
|
||||
win.setHidesOnDeactivate(FormStyleToHideOnDeactivate[AFormStyle]);
|
||||
end
|
||||
else
|
||||
begin
|
||||
lvl := 0;
|
||||
win.setHidesOnDeactivate(false);
|
||||
end;
|
||||
win.setLevel(lvl);
|
||||
if win.isKindOfClass(TCocoaWindow) then
|
||||
TCocoaWindow(win).keepWinLevel := lvl;
|
||||
end;
|
||||
|
||||
{ TCocoaWSHintWindow }
|
||||
|
||||
class function TCocoaWSHintWindow.CreateHandle(const AWinControl: TWinControl;
|
||||
@ -323,6 +343,9 @@ begin
|
||||
ACustForm.SetFocusedControl(ACustForm.ActiveControl);
|
||||
|
||||
IsActivating:=False;
|
||||
|
||||
if CocoaWidgetSet.isModalSession then
|
||||
NSView(ACustForm.Handle).window.orderFront(nil);
|
||||
end;
|
||||
end;
|
||||
|
||||
@ -580,12 +603,8 @@ begin
|
||||
UpdateWindowIcons(win, GetDesigningBorderStyle(Form), Form.BorderIcons);
|
||||
// For safety, it is better to not apply any setLevel & similar if the form is just a standard style
|
||||
// see issue http://bugs.freepascal.org/view.php?id=28473
|
||||
if not (Form.FormStyle in [fsNormal, fsMDIChild, fsMDIForm])
|
||||
and not (csDesigning in AWinControl.ComponentState) then
|
||||
begin
|
||||
win.setLevel(FormStyleToWindowLevel[Form.FormStyle]);
|
||||
win.setHidesOnDeactivate(FormStyleToHideOnDeactivate[Form.FormStyle]);
|
||||
end;
|
||||
if not (csDesigning in AWinControl.ComponentState) then
|
||||
WindowSetFormStyle(win, Form.FormStyle);
|
||||
win.enableCursorRects;
|
||||
|
||||
TCocoaWindow(win).callback := cb;
|
||||
@ -831,11 +850,7 @@ begin
|
||||
if AForm.HandleAllocated and not (csDesigning in AForm.ComponentState) then
|
||||
begin
|
||||
win := TCocoaWindowContent(AForm.Handle).lclOwnWindow;
|
||||
if Assigned(win) then
|
||||
begin
|
||||
win.setLevel(FormStyleToWindowLevel[AFormStyle]);
|
||||
win.setHidesOnDeactivate(FormStyleToHideOnDeactivate[AFormStyle]);
|
||||
end;
|
||||
WindowSetFormStyle(win, AFormStyle);
|
||||
end;
|
||||
end;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user