mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-04-22 11:19:26 +02:00
Cocoa: TCocoaWidgetSet.MonitorFromPoint() implemented
This commit is contained in:
parent
6121304a85
commit
275776771b
@ -42,6 +42,10 @@ 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 IndexToHMonitor(i: NSUInteger): HMonitor;
|
||||
function HMonitorToIndex(h: HMonitor): NSUInteger;
|
||||
function getScreenFromHMonitor(h: HMonitor): NSScreen;
|
||||
|
||||
function NSPrimaryScreen: NSScreen;
|
||||
function NSPrimaryScreenFrame: NSRect;
|
||||
function NSGlobalScreenFrame: NSRect;
|
||||
@ -755,6 +759,36 @@ begin
|
||||
ns.size.height:=lcl.Bottom-lcl.Top;
|
||||
end;
|
||||
|
||||
// According to the documentation of NSScreen.screen It's recommended
|
||||
// not to cache NSScreen objects stored in the array. As those might change.
|
||||
// However, according to the same documentation, the objects can change
|
||||
// only with a notificatio sent out. BUT while using a macincloud (remote desktop)
|
||||
// services, it was identified that NSScreen object CAN change without any notification.
|
||||
// So, instead of passing NSScreen as HMonitor, only INDEX+1 in NSScreen.screen
|
||||
// is used.
|
||||
function IndexToHMonitor(i: NSUInteger): HMonitor;
|
||||
begin
|
||||
if i = NSIntegerMax then Result := 0
|
||||
else Result := i + 1;
|
||||
end;
|
||||
|
||||
function HMonitorToIndex(h: HMonitor): NSUInteger;
|
||||
begin
|
||||
if h = 0 then Result := NSIntegerMax
|
||||
else Result := NSUInteger(h)-1;
|
||||
end;
|
||||
|
||||
function getScreenFromHMonitor(h: HMonitor): NSScreen;
|
||||
var
|
||||
index: NSUInteger;
|
||||
begin
|
||||
Result:= nil;
|
||||
index:= HMonitorToIndex( h );
|
||||
if index>=NSScreen.screens.count then
|
||||
Exit;
|
||||
Result:= NSScreen( NSScreen.screens.objectAtIndex(index) );
|
||||
end;
|
||||
|
||||
// primary display
|
||||
function NSPrimaryScreen: NSScreen;
|
||||
begin
|
||||
|
@ -740,25 +740,6 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
// According to the documentation of NSScreen.screen It's recommended
|
||||
// not to cache NSScreen objects stored in the array. As those might change.
|
||||
// However, according to the same documentation, the objects can change
|
||||
// only with a notificatio sent out. BUT while using a macincloud (remote desktop)
|
||||
// services, it was identified that NSScreen object CAN change without any notification.
|
||||
// So, instead of passing NSScreen as HMonitor, only INDEX+1 in NSScreen.screen
|
||||
// is used.
|
||||
function IndexToHMonitor(i: NSUInteger): HMonitor;
|
||||
begin
|
||||
if i = NSIntegerMax then Result := 0
|
||||
else Result := i + 1;
|
||||
end;
|
||||
|
||||
function HMonitorToIndex(h: HMonitor): NSUInteger;
|
||||
begin
|
||||
if h = 0 then Result := NSIntegerMax
|
||||
else Result := NSUInteger(h)-1;
|
||||
end;
|
||||
|
||||
function TCocoaWidgetSet.EnumDisplayMonitors(hdc: HDC; lprcClip: PRect;
|
||||
lpfnEnum: MonitorEnumProc; dwData: LPARAM): LongBool;
|
||||
var
|
||||
@ -1174,21 +1155,19 @@ function TCocoaWidgetSet.GetMonitorInfo(hMonitor: HMONITOR; lpmi: PMonitorInfo):
|
||||
var
|
||||
globalScreenHeight: CGFloat;
|
||||
ScreenID: NSScreen;
|
||||
idx : NSUInteger;
|
||||
begin
|
||||
Result := (lpmi <> nil) and (lpmi^.cbSize >= SizeOf(TMonitorInfo));
|
||||
if not Result then Exit;
|
||||
idx := HMonitorToIndex(hMonitor);
|
||||
Result := (idx < NSScreen.screens.count);
|
||||
ScreenID := getScreenFromHMonitor( hMonitor );
|
||||
Result := Assigned(ScreenID);
|
||||
if not Result then Exit;
|
||||
|
||||
globalScreenHeight := NSGlobalScreenHeight;
|
||||
ScreenID := NSScreen(NSScreen.screens.objectAtIndex(idx));
|
||||
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
|
||||
if HMonitorToIndex(hMonitor) = 0 then
|
||||
lpmi^.dwFlags := MONITORINFOF_PRIMARY
|
||||
else
|
||||
lpmi^.dwFlags := 0;
|
||||
@ -1893,6 +1872,29 @@ begin
|
||||
Result := CocoaRegionTypeToWin32Map[TCocoaRegion(RGN).GetType];
|
||||
end;
|
||||
|
||||
function TCocoaWidgetSet.MonitorFromPoint(ptScreenCoords: TPoint; dwFlags: DWord): HMONITOR;
|
||||
var
|
||||
point: NSPoint;
|
||||
screen: NSScreen;
|
||||
i: Integer;
|
||||
begin
|
||||
Result:= 0;
|
||||
point:= LCLToNSPoint( ptScreenCoords, NSGlobalScreenHeight );
|
||||
if point.y>=1 then // NSPointInRect is (upper,left) inside
|
||||
point.y:= point.y-1; // (lower,right) outside
|
||||
|
||||
for i := 0 to NSScreen.screens.count - 1 do begin
|
||||
screen:= NSScreen( NSScreen.screens.objectAtIndex(i) );
|
||||
if NSPointInRect(point, screen.frame) then begin
|
||||
Result:= IndexToHMonitor( i );
|
||||
Exit;
|
||||
end;
|
||||
end;
|
||||
|
||||
if dwFlags<>MONITOR_DEFAULTTONULL then
|
||||
Result:= IndexToHMonitor( 0 );
|
||||
end;
|
||||
|
||||
function TCocoaWidgetSet.MoveToEx(DC: HDC; X, Y: Integer; OldPoint: PPoint): Boolean;
|
||||
var
|
||||
ctx: TCocoaContext;
|
||||
|
@ -140,6 +140,8 @@ function LPtoDP(DC: HDC; var Points; Count: Integer): BOOL; override;
|
||||
|
||||
function OffsetRgn(RGN: HRGN; nXOffset, nYOffset: Integer): Integer; override;
|
||||
|
||||
function MonitorFromPoint(ptScreenCoords: TPoint; dwFlags: DWord): HMONITOR; override;
|
||||
|
||||
{function MessageBox(hWnd: HWND; lpText, lpCaption: PChar; uType: Cardinal): integer; override;}
|
||||
function MoveToEx(DC: HDC; X, Y: Integer; OldPoint: PPoint): Boolean; override;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user