mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-04-08 09:38:12 +02:00
Cocoa: support moving the mouse to HintWindow for operation in the IDE, Merge branch 'cocoa/mousemove'
there was a bug in the IDE before. HintWindow was hidden before the mouse was moved into HintWindow.
This commit is contained in:
parent
aa458fc479
commit
7157791611
@ -405,6 +405,9 @@ function THintWindowManager.ShowHint(ScreenPos: TPoint; TheHint: string;
|
||||
if NewHeight <= 0 then
|
||||
NewHeight := 200;
|
||||
|
||||
{$IFDEF LCLCOCOA}
|
||||
dec(ScreenPos.Y);
|
||||
{$ENDIF}
|
||||
HintRenderWindow.HintRectAdjust := Rect(0, 0, NewWidth, NewHeight);
|
||||
if MouseOffset then
|
||||
HintRenderWindow.OffsetHintRect(ScreenPos)
|
||||
|
@ -257,7 +257,7 @@ function CocoaPromptUser(const DialogCaption, DialogMessage: String;
|
||||
EscapeResult: Longint;
|
||||
sheetOfWindow: NSWindow = nil; modalSheet: Boolean = false): Longint;
|
||||
|
||||
function GetCocoaWindowAtPos(p: NSPoint): TCocoaWindow;
|
||||
function GetCocoaWindowAtPos(p: NSPoint): NSWindow;
|
||||
|
||||
// The function tries to initialize the proper application class.
|
||||
// The desired application class can be specified in info.plit
|
||||
@ -520,7 +520,7 @@ end;
|
||||
// 3. in current App
|
||||
// 4. is visible window
|
||||
// 5. is not the misc window like Menu Bar
|
||||
function GetCocoaWindowAtPos(p: NSPoint): TCocoaWindow;
|
||||
function GetCocoaWindowAtPos(p: NSPoint): NSWindow;
|
||||
var
|
||||
windowNumber: NSInteger;
|
||||
windowNumbers: NSArray;
|
||||
@ -538,14 +538,13 @@ begin
|
||||
|
||||
// ensure 5
|
||||
window := NSApp.windowWithWindowNumber(windowNumber);
|
||||
if Assigned(window) and window.isKindOfClass(TCocoaWindow) then
|
||||
Result := TCocoaWindow(window);
|
||||
if Assigned(window) and (window.isKindOfClass(TCocoaWindow) or window.isKindOfClass(TCocoaPanel)) then
|
||||
Result := window;
|
||||
end;
|
||||
|
||||
procedure ForwardMouseMove(app: NSApplication; theEvent: NSEvent);
|
||||
var
|
||||
w : NSWindow;
|
||||
kw : NSWindow;
|
||||
ev : NSEvent;
|
||||
p : NSPoint;
|
||||
wfr : NSRect;
|
||||
@ -553,13 +552,13 @@ begin
|
||||
if not app.isActive then
|
||||
exit;
|
||||
|
||||
kw := app.keyWindow;
|
||||
p := theEvent.mouseLocation;
|
||||
w := GetCocoaWindowAtPos(p);;
|
||||
|
||||
if Assigned(kw) then
|
||||
if Assigned(w) then
|
||||
begin
|
||||
wfr := kw.contentRectForFrameRect(kw.frame);
|
||||
// if mouse outside of ClientFrame of keyWindow,
|
||||
wfr := w.contentRectForFrameRect(w.frame);
|
||||
// if mouse outside of ClientFrame of Window,
|
||||
// Cursor should be forced to default.
|
||||
// see also: https://gitlab.com/freepascal.org/lazarus/lazarus/-/issues/40515
|
||||
if not NSPointInRect(p, wfr) then
|
||||
@ -571,9 +570,8 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
w := GetCocoaWindowAtPos(p);
|
||||
if (not Assigned(w)) or (w=kw) then
|
||||
exit;
|
||||
if (not Assigned(w)) or (not Assigned(theEvent.window)) or (w=theEvent.window) then
|
||||
Exit;
|
||||
|
||||
p.x := p.x - w.frame.origin.x;
|
||||
p.y := p.y - w.frame.origin.y;
|
||||
|
@ -42,6 +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 GetScreenPointFromEvent(const event: NSEvent): NSPoint;
|
||||
|
||||
function ScreenPointFromLCLToNS(const lclPoint: TPoint): NSPoint;
|
||||
function ScreenPointFromNSToLCL(const cocoaPoint: NSPoint): TPoint;
|
||||
function ScreenRectFromLCLToNS(const lclRect: TRect): NSRect;
|
||||
@ -752,6 +754,19 @@ begin
|
||||
ns.size.height:=lcl.Bottom-lcl.Top;
|
||||
end;
|
||||
|
||||
function GetScreenPointFromEvent(const event: NSEvent): NSPoint;
|
||||
var
|
||||
rect: NSRect;
|
||||
begin
|
||||
Result:= event.locationInWindow;
|
||||
if not Assigned(event.window) then
|
||||
Exit;
|
||||
rect.origin:= Result;
|
||||
rect.size:= NSZeroSize;
|
||||
rect:= event.window.convertRectToScreen( rect );
|
||||
Result:= rect.origin;
|
||||
end;
|
||||
|
||||
function ScreenPointFromLCLToNS(const lclPoint: TPoint): NSPoint;
|
||||
begin
|
||||
Result.x:= lclPoint.x;
|
||||
|
@ -91,10 +91,7 @@ type
|
||||
procedure windowDidMove(notification: NSNotification); message 'windowDidMove:';
|
||||
public
|
||||
callback: IWindowCallback;
|
||||
function acceptsFirstResponder: LCLObjCBoolean; override;
|
||||
function canBecomeKeyWindow: LCLObjCBoolean; override;
|
||||
function becomeFirstResponder: LCLObjCBoolean; override;
|
||||
function resignFirstResponder: LCLObjCBoolean; override;
|
||||
function lclGetCallback: ICommonCallback; override;
|
||||
procedure lclClearCallback; override;
|
||||
// mouse
|
||||
@ -579,28 +576,9 @@ begin
|
||||
callback.Move;
|
||||
end;
|
||||
|
||||
function TCocoaPanel.acceptsFirstResponder: LCLObjCBoolean;
|
||||
begin
|
||||
Result := True;
|
||||
end;
|
||||
|
||||
function TCocoaPanel.canBecomeKeyWindow: LCLObjCBoolean;
|
||||
begin
|
||||
Result := Assigned(callback) and callback.CanActivate;
|
||||
end;
|
||||
|
||||
function TCocoaPanel.becomeFirstResponder: LCLObjCBoolean;
|
||||
begin
|
||||
Result := inherited becomeFirstResponder;
|
||||
// if Assigned(callback) then
|
||||
// callback.BecomeFirstResponder;
|
||||
end;
|
||||
|
||||
function TCocoaPanel.resignFirstResponder: LCLObjCBoolean;
|
||||
begin
|
||||
Result := inherited resignFirstResponder;
|
||||
// if Assigned(callback) then
|
||||
// callback.ResignFirstResponder;
|
||||
Result := false;
|
||||
end;
|
||||
|
||||
function TCocoaPanel.lclGetCallback: ICommonCallback;
|
||||
|
@ -1109,14 +1109,13 @@ var
|
||||
MouseTargetLookup: Boolean;
|
||||
srchPt: TPoint;
|
||||
begin
|
||||
Result:= true;
|
||||
|
||||
if not NSApp.isActive then
|
||||
exit;
|
||||
|
||||
if Assigned(Owner) and not NSObjectIsLCLEnabled(Owner) then
|
||||
begin
|
||||
Result := True; // Cocoa should not handle the message.
|
||||
Exit; // LCL should get the notification either.
|
||||
end;
|
||||
exit; // LCL should get the notification either.
|
||||
|
||||
// If LCL control is provided and it's in designing state.
|
||||
// The default resolution: Notify LCL about event, but don't let Cocoa
|
||||
@ -1144,6 +1143,9 @@ begin
|
||||
end
|
||||
else
|
||||
begin
|
||||
if Event.window<>GetCocoaWindowAtPos(GetScreenPointFromEvent(Event)) then
|
||||
exit( true );
|
||||
|
||||
rect:=Target.BoundsRect;
|
||||
OffsetRect(rect, -rect.Left, -rect.Top);
|
||||
if (event.type_ = NSMouseMoved) and (not Types.PtInRect(rect, bndPt)) then
|
||||
@ -1203,8 +1205,9 @@ begin
|
||||
//debugln('MouseMove x='+dbgs(MousePos.X)+' y='+dbgs(MousePos.Y)+' Target='+Target.Name);
|
||||
|
||||
NotifyApplicationUserInput(Target, Msg.Msg);
|
||||
Result := DeliverMessage(Msg) <> 0;
|
||||
if BlockCocoaMouseMove then Result := true;
|
||||
// LCL/LM_MOUSEMOVE always return false, so we should discard return value
|
||||
DeliverMessage(Msg);
|
||||
Result:= true;
|
||||
|
||||
// if Screen.Cursor set, LCL won't call TCocoaWSWinControl.SetCursor().
|
||||
// we need to set the cursor ourselves
|
||||
@ -1805,14 +1808,14 @@ begin
|
||||
if Screen.Cursor<>crDefault
|
||||
then exit;
|
||||
|
||||
// control cursor only should be set when mouse in the keyWindow.
|
||||
// control cursor only should be set when mouse in the keyWindow or hintWindow.
|
||||
// for the MacOS system automatic restore cursor feature(also an issue),
|
||||
// it is more appropriate to set the default cursor when the mouse is out
|
||||
// of the keyWindow, which has been set in TLCLCommonCallback.MouseMove().
|
||||
// the keyWindow here refers to the Client Frame, excluding TitleBar.
|
||||
// see also: https://gitlab.com/freepascal.org/lazarus/lazarus/-/issues/40515
|
||||
topParent:= AWinControl.GetTopParent;
|
||||
if topParent is TCustomForm then
|
||||
if (topParent is TCustomForm) and not (topParent is THintWindow) then
|
||||
begin
|
||||
if NSView(TCustomForm(topParent).handle).window <> NSApp.keyWindow then
|
||||
exit;
|
||||
|
Loading…
Reference in New Issue
Block a user