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