mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-04-23 01:39:31 +02:00
Cocoa: Multi Displays fully supported, Merge branch 'cocoa/MultiDisplay'
This commit is contained in:
parent
13c1f3497b
commit
d93c85c98d
@ -1,7 +1,7 @@
|
||||
unit CocoaUtils;
|
||||
|
||||
{$mode objfpc}{$H+}
|
||||
{$modeswitch objectivec1}
|
||||
{$modeswitch objectivec2}
|
||||
|
||||
interface
|
||||
|
||||
@ -42,7 +42,8 @@ function NSRectToRect(const NS: NSRect): TRect;
|
||||
procedure NSToLCLRect(const ns: NSRect; ParentHeight: Single; out lcl: TRect);
|
||||
procedure LCLToNSRect(const lcl: TRect; ParentHeight: Single; out ns: NSRect);
|
||||
|
||||
function NSScreenZeroHeight: CGFloat;
|
||||
function NSPrimaryScreenHeight: CGFloat;
|
||||
function NSGlobalScreenHeight: CGFloat;
|
||||
|
||||
function CreateParamsToNSRect(const params: TCreateParams): NSRect;
|
||||
|
||||
@ -751,11 +752,25 @@ begin
|
||||
ns.size.height:=lcl.Bottom-lcl.Top;
|
||||
end;
|
||||
|
||||
function NSScreenZeroHeight: CGFloat;
|
||||
// the height of primary display
|
||||
function NSPrimaryScreenHeight: CGFloat;
|
||||
begin
|
||||
Result := NSScreen(NSScreen.screens.objectAtIndex(0)).frame.size.height;
|
||||
end;
|
||||
|
||||
// the height of global full virtual display
|
||||
function NSGlobalScreenHeight: CGFloat;
|
||||
var
|
||||
globalFrame: NSRect;
|
||||
screen: NSScreen;
|
||||
begin
|
||||
globalFrame:= NSZeroRect;
|
||||
for screen in NSScreen.screens do begin
|
||||
globalFrame:= NSUnionRect( globalFrame, screen.frame );
|
||||
end;
|
||||
Result:= globalFrame.size.height;
|
||||
end;
|
||||
|
||||
function CreateParamsToNSRect(const params: TCreateParams): NSRect;
|
||||
begin
|
||||
with params do Result:=GetNSRect(X,Y,Width,Height);
|
||||
|
@ -1066,7 +1066,7 @@ begin
|
||||
SPI_GETWORKAREA:
|
||||
begin
|
||||
NSToLCLRect(NSScreen(NSScreen.screens.objectAtIndex(0)).visibleFrame
|
||||
, NSScreenZeroHeight
|
||||
, NSPrimaryScreenHeight
|
||||
, TRect(pvParam^));
|
||||
end;
|
||||
else
|
||||
@ -1164,7 +1164,7 @@ begin
|
||||
begin
|
||||
lpPoint.x := Round(x);
|
||||
// cocoa returns cursor with inverted y coordinate
|
||||
lpPoint.y := Round(NSScreenZeroHeight-y);
|
||||
lpPoint.y := Round(NSGlobalScreenHeight-y);
|
||||
end;
|
||||
//debugln('GetCursorPos='+DbgS(lpPoint));
|
||||
Result := True;
|
||||
@ -1172,7 +1172,7 @@ end;
|
||||
|
||||
function TCocoaWidgetSet.GetMonitorInfo(hMonitor: HMONITOR; lpmi: PMonitorInfo): Boolean;
|
||||
var
|
||||
Scr0Height: CGFloat;
|
||||
globalScreenHeight: CGFloat;
|
||||
ScreenID: NSScreen;
|
||||
idx : NSUInteger;
|
||||
begin
|
||||
@ -1182,10 +1182,10 @@ begin
|
||||
Result := (idx < NSScreen.screens.count);
|
||||
if not Result then Exit;
|
||||
|
||||
Scr0Height := NSScreenZeroHeight;
|
||||
globalScreenHeight := NSGlobalScreenHeight;
|
||||
ScreenID := NSScreen(NSScreen.screens.objectAtIndex(idx));
|
||||
NSToLCLRect(ScreenID.frame, Scr0Height, lpmi^.rcMonitor);
|
||||
NSToLCLRect(ScreenID.visibleFrame, Scr0Height, lpmi^.rcWork);
|
||||
NSToLCLRect(ScreenID.frame, globalScreenHeight, lpmi^.rcMonitor);
|
||||
NSToLCLRect(ScreenID.visibleFrame, globalScreenHeight, lpmi^.rcWork);
|
||||
// according to the documentation the primary (0,0 coord screen)
|
||||
// is always and index 0
|
||||
if idx = 0 then
|
||||
@ -1495,7 +1495,7 @@ begin
|
||||
Exit;
|
||||
|
||||
p.x:=Point.X;
|
||||
p.y:=NSScreenZeroHeight-Point.Y;
|
||||
p.y:=NSGlobalScreenHeight-Point.Y;
|
||||
window := GetCocoaWindowAtPos(p);
|
||||
if Assigned(window) then
|
||||
Result:= HWND(window.contentView);
|
||||
|
@ -480,7 +480,7 @@ begin
|
||||
begin
|
||||
//Window bounds should return "client rect" in screen coordinates
|
||||
if Assigned(window.screen) then
|
||||
NSToLCLRect(window.frame, NSScreenZeroHeight, wfrm)
|
||||
NSToLCLRect(window.frame, NSGlobalScreenHeight, wfrm)
|
||||
else
|
||||
wfrm := NSRectToRect(frame);
|
||||
Types.OffsetRect(Result, -Result.Left+wfrm.Left, -Result.Top+wfrm.Top);
|
||||
@ -1278,7 +1278,7 @@ begin
|
||||
begin
|
||||
f:=frame;
|
||||
Left := Round(f.origin.x);
|
||||
Top := Round(NSScreenZeroHeight - f.size.height - f.origin.y);
|
||||
Top := Round(NSGlobalScreenHeight - f.size.height - f.origin.y);
|
||||
//debugln('Top:'+dbgs(Top));
|
||||
end;
|
||||
end;
|
||||
@ -1291,7 +1291,7 @@ begin
|
||||
begin
|
||||
f := frame;
|
||||
inc(X, Round(f.origin.x));
|
||||
inc(Y, Round(NSScreenZeroHeight - f.size.height - f.origin.y));
|
||||
inc(Y, Round(NSGlobalScreenHeight - f.size.height - f.origin.y));
|
||||
end;
|
||||
end;
|
||||
|
||||
@ -1303,7 +1303,7 @@ begin
|
||||
begin
|
||||
f := frame;
|
||||
dec(X, Round(f.origin.x));
|
||||
dec(Y, Round(screen.frame.size.height - f.size.height - f.origin.y));
|
||||
dec(Y, Round(NSGlobalScreenHeight - f.size.height - f.origin.y));
|
||||
end;
|
||||
end;
|
||||
|
||||
@ -1314,7 +1314,7 @@ begin
|
||||
else
|
||||
begin
|
||||
if Assigned(screen) then
|
||||
NSToLCLRect(frame, NSScreenZeroHeight, Result)
|
||||
NSToLCLRect(frame, NSGlobalScreenHeight, Result)
|
||||
else
|
||||
Result := NSRectToRect(frame);
|
||||
end;
|
||||
@ -1333,29 +1333,12 @@ begin
|
||||
Point.y := contentView.bounds.size.height - Point.y;
|
||||
end;
|
||||
|
||||
procedure NSScreenGetRect(sc: NSScreen; mainScreenHeight: double; out r: TRect);
|
||||
var
|
||||
fr : NSRect;
|
||||
begin
|
||||
fr := sc.frame;
|
||||
r := Bounds(
|
||||
Round(fr.origin.x),
|
||||
Round(fr.origin.y - fr.size.height + mainScreenHeight),
|
||||
Round(fr.size.width), Round(fr.size.height)
|
||||
);
|
||||
end;
|
||||
|
||||
procedure NSScreenGetRect(sc: NSScreen; out r: TRect);
|
||||
begin
|
||||
NSScreenGetRect(sc, NSScreen.mainScreen.frame.size.height, r);
|
||||
end;
|
||||
|
||||
procedure LCLWindowExtension.lclSetFrame(const r: TRect);
|
||||
var
|
||||
ns : NSRect;
|
||||
h : integer;
|
||||
begin
|
||||
LCLToNSRect(r, NSScreenZeroHeight, ns);
|
||||
LCLToNSRect(r, NSGlobalScreenHeight, ns);
|
||||
|
||||
// add topbar height
|
||||
h:=lclGetTopBarHeight;
|
||||
|
@ -963,24 +963,25 @@ begin
|
||||
// in macOS it's possible to "rightclick" without focusing a window
|
||||
// so let's try to find the window
|
||||
if not Assigned(w) then
|
||||
w := GetCocoaWindowAtPos( NSMakePoint(px, py) );
|
||||
w := GetCocoaWindowAtPos( NSMakePoint(px, Round(NSGlobalScreenHeight) - py) );
|
||||
|
||||
if Assigned(w) then
|
||||
begin
|
||||
view := w.contentView;
|
||||
if Assigned(view) then
|
||||
begin
|
||||
menuY := round(w.screen.frame.size.height - w.screen.visibleFrame.origin.y - menu.size.height) - 1;
|
||||
// LCL Screen coordinate
|
||||
menuY := Round(NSGlobalScreenHeight - w.screen.visibleFrame.origin.y - menu.size.height) - 1;
|
||||
py := min(py, menuY);
|
||||
view.lclScreenToLocal(px, py);
|
||||
// have to flip again, because popUpMenuPositioningItem expects point
|
||||
// to be in View coordinates and it does respect Flipped flag
|
||||
if not view.isFlipped then
|
||||
py := Round(view.frame.size.height - py);
|
||||
py := Round(view.frame.size.height) - py;
|
||||
end;
|
||||
end
|
||||
else
|
||||
py := Round(NSScreenZeroHeight - py);
|
||||
py := Round(NSGlobalScreenHeight) - py;
|
||||
|
||||
menu.popUpMenuPositioningItem_atLocation_inView(nil, NSMakePoint(px, py), view);
|
||||
APopupMenu.Close; // notify LCL popup menu
|
||||
|
Loading…
Reference in New Issue
Block a user