Cocoa: fix/upd that related to NSApp.windows, Merge branch 'cocoa/NSAPP.windows'

This commit is contained in:
rich2014 2023-09-29 17:51:41 +08:00
commit 7d2eb74931
4 changed files with 57 additions and 83 deletions

View File

@ -279,6 +279,8 @@ function CocoaPromptUser(const DialogCaption, DialogMessage: String;
EscapeResult: Longint;
sheetOfWindow: NSWindow = nil; modalSheet: Boolean = false): Longint;
function GetCocoaWindowAtPos(p: NSPoint): TCocoaWindow;
// The function tries to initialize the proper application class.
// The desired application class can be specified in info.plit
// by specifying NSPrincipalClass property.
@ -510,6 +512,34 @@ begin
end;
{$endif}
// ensure that gets the correct window at mouse pos
// 1. in Z-Order
// 2. on the active Space
// 3. in current App
// 4. is visible window
// 5. is not the misc window like Menu Bar
function GetCocoaWindowAtPos(p: NSPoint): TCocoaWindow;
var
windowNumber: NSInteger;
windowNumbers: NSArray;
window: NSWindow;
begin
Result := nil;
// ensure 1
windowNumber := NSWindow.windowNumberAtPoint_belowWindowWithWindowNumber(p,0);
windowNumbers := NSWindow.windowNumbersWithOptions(0);
// ensure 2, 3, 4
if not windowNumbers.containsObject(NSNumber.numberWithInt(windowNumber)) then
exit;
// ensure 5
window := NSApp.windowWithWindowNumber(windowNumber);
if Assigned(window) and window.isKindOfClass(TCocoaWindow) then
Result := TCocoaWindow(window);
end;
procedure ForwardMouseMove(app: NSApplication; theEvent: NSEvent);
var
w : NSWindow;
@ -517,8 +547,6 @@ var
ev : NSEvent;
p : NSPoint;
wfr : NSRect;
windowNumbers : NSArray;
windowNumber : NSNumber;
begin
kw := app.keyWindow;
p := theEvent.mouseLocation;
@ -538,44 +566,24 @@ begin
end;
end;
// mouse move was consumed by the focused window
if Assigned(kw) and NSPointInRect(p, kw.frame) then
w := GetCocoaWindowAtPos(p);
if (not Assigned(w)) or (w=kw) then
exit;
// windowNumbersWithOptions() shoulde be used here.
// because windowNumbersWithOptions() return windowsNumber of visible windows
// from front to back, and NSAPP.windows return all windows not ordered.
windowNumbers := NSWindow.windowNumbersWithOptions(0);
for windowNumber in windowNumbers do
begin
w := app.windowWithWindowNumber(windowNumber.integerValue);
if not Assigned(w) then
continue;
wfr := w.frame;
if not NSPointInRect( theEvent.mouseLocation, wfr) then
continue;
if not w.isKindOfClass(TCocoaWindow) then
break;
p := theEvent.mouseLocation;
p.x := p.x - w.frame.origin.x;
p.y := p.y - w.frame.origin.y;
ev := NSEvent.mouseEventWithType_location_modifierFlags_timestamp_windowNumber_context_eventNumber_clickCount_pressure(
theEvent.type_,
p,
theEvent.modifierFlags,
theEvent.timestamp,
w.windowNumber,
theEvent.context,
theEvent.eventNumber,
theEvent.clickCount,
theEvent.pressure
);
w.sendEvent(ev);
break;
end;
p.x := p.x - w.frame.origin.x;
p.y := p.y - w.frame.origin.y;
ev := NSEvent.mouseEventWithType_location_modifierFlags_timestamp_windowNumber_context_eventNumber_clickCount_pressure(
theEvent.type_,
p,
theEvent.modifierFlags,
theEvent.timestamp,
w.windowNumber,
theEvent.context,
theEvent.eventNumber,
theEvent.clickCount,
theEvent.pressure
);
w.sendEvent(ev);
end;
procedure TCocoaApplication.sendEvent(theEvent: NSEvent);

View File

@ -1554,11 +1554,8 @@ end;
function TCocoaWidgetSet.WindowFromPoint(Point: TPoint): HWND;
var
windows: NSArray;
win: integer;
window, windowbelowpoint: NSWindow;
window:NSWindow;
p:NSPoint;
winnr:NSInteger;
begin
Result := 0;
if not assigned(NSApp) then
@ -1566,19 +1563,9 @@ begin
p.x:=Point.X;
p.y:=NSScreenZeroHeight-Point.Y;
winnr:=NSWindow.windowNumberAtPoint_belowWindowWithWindowNumber(p,0);
windowbelowpoint:=NSWindow(NSApp.windowWithWindowNumber(winnr));
windows := NSApp.windows;
for win := 0 to windows.count - 1 do
begin
window:=windows.objectAtIndex(win);
if windowbelowpoint=window then
begin
Result:= HWND(window.contentView);
exit;
end;
end;
window := GetCocoaWindowAtPos(p);
if Assigned(window) then
Result:= HWND(window.contentView);
end;

View File

@ -793,7 +793,7 @@ begin
if Assigned(callback) then
callback.Activate;
performSelector_withObject_afterDelay( ObjCSelector('DoWindowDidBecomeKey'), nil, 0.1 );
performSelector_withObject_afterDelay( ObjCSelector('DoWindowDidBecomeKey'), nil, 0 );
end;
procedure TCocoaWindow.windowDidResignKey(notification: NSNotification);

View File

@ -949,12 +949,9 @@ end;
class procedure TCocoaWSPopupMenu.Popup(const APopupMenu: TPopupMenu; const X,
Y: Integer);
var
res : Boolean;
mnu : NSMenuItem;
view : NSView;
w : NSWindow;
px, py: Integer;
wi: NSUInteger;
begin
if Assigned(APopupMenu) and (APopupMenu.Handle<>0) then
begin
@ -971,30 +968,10 @@ begin
py := y;
view := nil;
w :=NSApp.keyWindow;
if not Assigned(w) and (NSApp.windows.count>0) then
begin
if not Assigned(w) then
// in macOS it's possible to "rightclick" without focusing a window
// so let's try to find the window
for wi := 0 to NSApp.windows.count-1 do
begin
w := NSWindow(NSApp.windows.objectAtIndex(wi));
if not w.isVisible then Continue;
view := w.contentView;
view.lclScreenToLocal(px, py);
if (px >= 0) and (py >= 0)
and (px<=Round(view.frame.size.width))
and (py<=Round(view.frame.size.height))
then
begin
px := X;
py := Y;
Break;
end;
w := nil;
px := X;
py := Y;
end;
end;
w := GetCocoaWindowAtPos( NSMakePoint(px, py) );
if Assigned(w) then
begin
@ -1007,8 +984,10 @@ begin
if not view.isFlipped then
py := Round(view.frame.size.height - py);
end;
end;
res := TCocoaMenu(APopupMenu.Handle).popUpMenuPositioningItem_atLocation_inView(
end
else
py := Round(NSScreenZeroHeight - py);
TCocoaMenu(APopupMenu.Handle).popUpMenuPositioningItem_atLocation_inView(
nil, NSMakePoint(px, py), view);
APopupMenu.Close; // notify LCL popup menu
end;