From 80d14feaba113280db095916dfd72c814732d008 Mon Sep 17 00:00:00 2001 From: dmitry Date: Tue, 4 Sep 2018 03:15:27 +0000 Subject: [PATCH] cocoa: forcing keep of the object on MouseMove call from the tracking event git-svn-id: trunk@58849 - --- lcl/interfaces/cocoa/cocoaint.pas | 4 +- lcl/interfaces/cocoa/cocoaprivate.pp | 2 +- lcl/interfaces/cocoa/cocoawscommon.pas | 113 +++++++++++++------------ 3 files changed, 62 insertions(+), 57 deletions(-) diff --git a/lcl/interfaces/cocoa/cocoaint.pas b/lcl/interfaces/cocoa/cocoaint.pas index a71f8b8a57..049f42f20c 100644 --- a/lcl/interfaces/cocoa/cocoaint.pas +++ b/lcl/interfaces/cocoa/cocoaint.pas @@ -389,7 +389,9 @@ begin and isMouseMoveEvent(Result.type_) then begin cb := TrackedControl.lclGetCallback; - if Assigned(cb) then cb.MouseMove(Result); + if Assigned(cb) then + // making sure that the only the same control is called + cb.MouseMove(Result, true); end; end; diff --git a/lcl/interfaces/cocoa/cocoaprivate.pp b/lcl/interfaces/cocoa/cocoaprivate.pp index e417bdef68..a1e30c69b7 100644 --- a/lcl/interfaces/cocoa/cocoaprivate.pp +++ b/lcl/interfaces/cocoa/cocoaprivate.pp @@ -49,7 +49,7 @@ type // mouse events function MouseUpDownEvent(Event: NSEvent; AForceAsMouseUp: Boolean = False; AOverrideBlock: Boolean = False): Boolean; procedure MouseClick; - function MouseMove(Event: NSEvent): Boolean; + function MouseMove(Event: NSEvent; AForceObject: Boolean = False): Boolean; function KeyEvent(Event: NSEvent; AForceAsKeyDown: Boolean = False): Boolean; procedure KeyEvPrepare(Event: NSEvent; AForceAsKeyDown: Boolean = False); diff --git a/lcl/interfaces/cocoa/cocoawscommon.pas b/lcl/interfaces/cocoa/cocoawscommon.pas index ad5d9ac8a2..c61577be97 100644 --- a/lcl/interfaces/cocoa/cocoawscommon.pas +++ b/lcl/interfaces/cocoa/cocoawscommon.pas @@ -73,7 +73,7 @@ type procedure KeyEvAfter; procedure MouseClick; virtual; - function MouseMove(Event: NSEvent): Boolean; virtual; + function MouseMove(Event: NSEvent; AForceObject: Boolean): Boolean; virtual; function scrollWheel(Event: NSEvent): Boolean; virtual; procedure frameDidChange(sender: id); virtual; procedure boundsDidChange(sender: id); virtual; @@ -1231,7 +1231,7 @@ begin end; end; -function TLCLCommonCallback.MouseMove(Event: NSEvent): Boolean; +function TLCLCommonCallback.MouseMove(Event: NSEvent; AForceObject: Boolean): Boolean; var Msg: TLMMouseMove; MousePos: NSPoint; @@ -1258,64 +1258,67 @@ begin MousePos := Event.locationInWindow; OffsetMousePos(MousePos, bndPt, clPt); - rect:=Owner.lclClientFrame; - targetControl:=nil; + if not AForceObject then + begin + rect:=Owner.lclClientFrame; + targetControl:=nil; - callback := GetCaptureControlCallback(); - if callback <> nil then - begin - FIsEventRouting:=true; - Result := callback.MouseMove(Event); - FIsEventRouting:=false; - exit; - end - else - begin - rect:=Target.BoundsRect; - OffsetRect(rect, -rect.Left, -rect.Top); - if (event.type_ = NSMouseMoved) and (not Types.PtInRect(rect, bndPt)) then + callback := GetCaptureControlCallback(); + if callback <> nil then begin - // do not send negative coordinates (unless dragging mouse) - Exit; + FIsEventRouting:=true; + Result := callback.MouseMove(Event); + FIsEventRouting:=false; + exit; + end + else + begin + rect:=Target.BoundsRect; + OffsetRect(rect, -rect.Left, -rect.Top); + if (event.type_ = NSMouseMoved) and (not Types.PtInRect(rect, bndPt)) then + begin + // do not send negative coordinates (unless dragging mouse) + Exit; + end; + + if assigned(Target.Parent) and not Types.PtInRect(rect, bndPt) then + targetControl:=Target.Parent // outside myself then route to parent + else + for i:=Target.ControlCount-1 downto 0 do // otherwise check, if over child and route to child + if Target.Controls[i] is TWinControl then + begin + childControl:=TWinControl(Target.Controls[i]); + rect:=childControl.BoundsRect; + if Types.PtInRect(rect, clPt) and childControl.Visible and childControl.Enabled then + begin + targetControl:=childControl; + break; + end; + end; end; - if assigned(Target.Parent) and not Types.PtInRect(rect, bndPt) then - targetControl:=Target.Parent // outside myself then route to parent - else - for i:=Target.ControlCount-1 downto 0 do // otherwise check, if over child and route to child - if Target.Controls[i] is TWinControl then - begin - childControl:=TWinControl(Target.Controls[i]); - rect:=childControl.BoundsRect; - if Types.PtInRect(rect, clPt) and childControl.Visible and childControl.Enabled then - begin - targetControl:=childControl; - break; - end; - end; - end; + if assigned(targetControl) and not FIsEventRouting then + begin + if not targetControl.HandleAllocated then Exit; // Fixes crash due to events being sent after ReleaseHandle + FIsEventRouting:=true; + //debugln(Target.name+' -> '+targetControl.Name+'- is parent:'+dbgs(targetControl=Target.Parent)+' Point: '+dbgs(br)+' Rect'+dbgs(rect)); + obj := GetNSObjectView(NSObject(targetControl.Handle)); + if obj = nil then Exit; + callback := obj.lclGetCallback; + if callback = nil then Exit; // Avoids crashes + result := callback.MouseMove(Event); + FIsEventRouting := false; + exit; + end; - if assigned(targetControl) and not FIsEventRouting then - begin - if not targetControl.HandleAllocated then Exit; // Fixes crash due to events being sent after ReleaseHandle - FIsEventRouting:=true; - //debugln(Target.name+' -> '+targetControl.Name+'- is parent:'+dbgs(targetControl=Target.Parent)+' Point: '+dbgs(br)+' Rect'+dbgs(rect)); - obj := GetNSObjectView(NSObject(targetControl.Handle)); - if obj = nil then Exit; - callback := obj.lclGetCallback; - if callback = nil then Exit; // Avoids crashes - result := callback.MouseMove(Event); - FIsEventRouting := false; - exit; - end; - - if (Event.type_ = NSMouseMoved) and Owner.lclIsMouseInAuxArea(Event) then - begin - // mouse is over auxillary area that's "blind" to mouse moves - // even though the mouse cursos is within the control bounds. - // (i.e. scrollbars) - Result := false; - Exit; + if (Event.type_ = NSMouseMoved) and Owner.lclIsMouseInAuxArea(Event) then + begin + // mouse is over auxillary area that's "blind" to mouse moves + // even though the mouse cursos is within the control bounds. + // (i.e. scrollbars) + Result := false; + Exit; + end; end; // debugln('Send to: '+Target.name+' Point: '+dbgs(mp));