mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-06-17 20:08:34 +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);
|
procedure SetMainMenu(const AMenu: HMENU; const ALCLMenu: TMenu);
|
||||||
function StartModal(awin: NSWindow; hasMenu: Boolean): Boolean;
|
function StartModal(awin: NSWindow; hasMenu: Boolean): Boolean;
|
||||||
procedure EndModal(awin: NSWindow);
|
procedure EndModal(awin: NSWindow);
|
||||||
|
function isModalSession: Boolean;
|
||||||
|
|
||||||
{todo:}
|
{todo:}
|
||||||
function DCGetPixel(CanvasHandle: HDC; X, Y: integer): TGraphicsColor; override;
|
function DCGetPixel(CanvasHandle: HDC; X, Y: integer): TGraphicsColor; override;
|
||||||
@ -580,11 +581,19 @@ end;
|
|||||||
function TCocoaWidgetSet.StartModal(awin: NSWindow; hasMenu: Boolean): Boolean;
|
function TCocoaWidgetSet.StartModal(awin: NSWindow; hasMenu: Boolean): Boolean;
|
||||||
var
|
var
|
||||||
sess : NSModalSession;
|
sess : NSModalSession;
|
||||||
|
lvl : NSInteger;
|
||||||
begin
|
begin
|
||||||
Result := false;
|
Result := false;
|
||||||
if not Assigned(awin) then Exit;
|
if not Assigned(awin) then Exit;
|
||||||
|
|
||||||
|
lvl := awin.level;
|
||||||
|
|
||||||
sess := NSApplication(NSApp).beginModalSessionForWindow(awin);
|
sess := NSApplication(NSApp).beginModalSessionForWindow(awin);
|
||||||
if not Assigned(sess) then Exit;
|
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 not Assigned(Modals) then Modals := TList.Create;
|
||||||
|
|
||||||
// If a modal menu has it's menu, then SetMainMenu has already been called
|
// If a modal menu has it's menu, then SetMainMenu has already been called
|
||||||
@ -619,6 +628,10 @@ begin
|
|||||||
Modals.Delete(Modals.Count-1);
|
Modals.Delete(Modals.Count-1);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TCocoaWidgetSet.isModalSession: Boolean;
|
||||||
|
begin
|
||||||
|
Result := Assigned(Modals) and (Modals.Count > 0);
|
||||||
|
end;
|
||||||
|
|
||||||
initialization
|
initialization
|
||||||
// {$I Cocoaimages.lrs}
|
// {$I Cocoaimages.lrs}
|
||||||
|
@ -138,6 +138,7 @@ type
|
|||||||
procedure windowDidExitFullScreen(notification: NSNotification); message 'windowDidExitFullScreen:';
|
procedure windowDidExitFullScreen(notification: NSNotification); message 'windowDidExitFullScreen:';
|
||||||
public
|
public
|
||||||
callback: IWindowCallback;
|
callback: IWindowCallback;
|
||||||
|
keepWinLevel : NSInteger;
|
||||||
//LCLForm: TCustomForm;
|
//LCLForm: TCustomForm;
|
||||||
procedure dealloc; override;
|
procedure dealloc; override;
|
||||||
function acceptsFirstResponder: Boolean; override;
|
function acceptsFirstResponder: Boolean; override;
|
||||||
@ -758,6 +759,18 @@ end;
|
|||||||
|
|
||||||
procedure TCocoaWindow.windowDidBecomeKey(notification: NSNotification);
|
procedure TCocoaWindow.windowDidBecomeKey(notification: NSNotification);
|
||||||
begin
|
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
|
if Assigned(callback) then
|
||||||
callback.Activate;
|
callback.Activate;
|
||||||
end;
|
end;
|
||||||
|
@ -170,6 +170,7 @@ type
|
|||||||
|
|
||||||
procedure ArrangeTabOrder(const AWinControl: TWinControl);
|
procedure ArrangeTabOrder(const AWinControl: TWinControl);
|
||||||
function HWNDToForm(AFormHandle: HWND): TCustomForm;
|
function HWNDToForm(AFormHandle: HWND): TCustomForm;
|
||||||
|
procedure WindowSetFormStyle(win: NSWindow; AFormStyle: TFormStyle);
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
@ -210,6 +211,25 @@ begin
|
|||||||
Result := AForm.BorderStyle;
|
Result := AForm.BorderStyle;
|
||||||
end;
|
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 }
|
{ TCocoaWSHintWindow }
|
||||||
|
|
||||||
class function TCocoaWSHintWindow.CreateHandle(const AWinControl: TWinControl;
|
class function TCocoaWSHintWindow.CreateHandle(const AWinControl: TWinControl;
|
||||||
@ -323,6 +343,9 @@ begin
|
|||||||
ACustForm.SetFocusedControl(ACustForm.ActiveControl);
|
ACustForm.SetFocusedControl(ACustForm.ActiveControl);
|
||||||
|
|
||||||
IsActivating:=False;
|
IsActivating:=False;
|
||||||
|
|
||||||
|
if CocoaWidgetSet.isModalSession then
|
||||||
|
NSView(ACustForm.Handle).window.orderFront(nil);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -580,12 +603,8 @@ begin
|
|||||||
UpdateWindowIcons(win, GetDesigningBorderStyle(Form), Form.BorderIcons);
|
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
|
// 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
|
// see issue http://bugs.freepascal.org/view.php?id=28473
|
||||||
if not (Form.FormStyle in [fsNormal, fsMDIChild, fsMDIForm])
|
if not (csDesigning in AWinControl.ComponentState) then
|
||||||
and not (csDesigning in AWinControl.ComponentState) then
|
WindowSetFormStyle(win, Form.FormStyle);
|
||||||
begin
|
|
||||||
win.setLevel(FormStyleToWindowLevel[Form.FormStyle]);
|
|
||||||
win.setHidesOnDeactivate(FormStyleToHideOnDeactivate[Form.FormStyle]);
|
|
||||||
end;
|
|
||||||
win.enableCursorRects;
|
win.enableCursorRects;
|
||||||
|
|
||||||
TCocoaWindow(win).callback := cb;
|
TCocoaWindow(win).callback := cb;
|
||||||
@ -831,11 +850,7 @@ begin
|
|||||||
if AForm.HandleAllocated and not (csDesigning in AForm.ComponentState) then
|
if AForm.HandleAllocated and not (csDesigning in AForm.ComponentState) then
|
||||||
begin
|
begin
|
||||||
win := TCocoaWindowContent(AForm.Handle).lclOwnWindow;
|
win := TCocoaWindowContent(AForm.Handle).lclOwnWindow;
|
||||||
if Assigned(win) then
|
WindowSetFormStyle(win, AFormStyle);
|
||||||
begin
|
|
||||||
win.setLevel(FormStyleToWindowLevel[AFormStyle]);
|
|
||||||
win.setHidesOnDeactivate(FormStyleToHideOnDeactivate[AFormStyle]);
|
|
||||||
end;
|
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user