Cocoa: Fix #40581 #40535 , Merge branch 'cocoa/message'

keep LM_SETFOCUS/LM_KILLFOCUS/LM_DESTROY consistent with Win32
This commit is contained in:
rich2014 2024-01-19 22:26:20 +08:00
commit 7b75e8ba5d
4 changed files with 38 additions and 5 deletions

View File

@ -170,6 +170,9 @@ type
procedure DoSetMainMenu(AMenu: NSMenu; ALCLMenu: TMenu); procedure DoSetMainMenu(AMenu: NSMenu; ALCLMenu: TMenu);
public public
KeyWindow: NSWindow;
KillingFocus: Boolean;
// modal session // modal session
Modals : TList; Modals : TList;
ModalCounter: Integer; // the cheapest way to determine if modal window was called ModalCounter: Integer; // the cheapest way to determine if modal window was called

View File

@ -2148,8 +2148,15 @@ var
lclobj : TObject; lclobj : TObject;
begin begin
Result := 0; Result := 0;
if KillingFocus then
Exit;
win := NSApp.keyWindow; win := NSApp.keyWindow;
if not Assigned(win) then Exit; if not Assigned(win) then
win := CocoaWidgetSet.KeyWindow;
if not Assigned(win) then
Exit;
// assuming that that the content view of Window // assuming that that the content view of Window
// is the focused handle and return it, by default // is the focused handle and return it, by default
Result := HWND(win.contentView); Result := HWND(win.contentView);

View File

@ -1376,7 +1376,12 @@ end;
procedure TLCLCommonCallback.ResignFirstResponder; procedure TLCLCommonCallback.ResignFirstResponder;
begin begin
if not Assigned(Target) then Exit; if not Assigned(Target) then Exit;
LCLSendKillFocusMsg(Target); CocoaWidgetSet.KillingFocus:= true;
try
LCLSendKillFocusMsg(Target);
finally
CocoaWidgetSet.KillingFocus:= false;
end;
end; end;
procedure TLCLCommonCallback.DidBecomeKeyNotification; procedure TLCLCommonCallback.DidBecomeKeyNotification;
@ -1621,6 +1626,12 @@ begin
CocoaWidgetSet.ReleaseCapture; CocoaWidgetSet.ReleaseCapture;
obj := NSObject(AWinControl.Handle); obj := NSObject(AWinControl.Handle);
Callback := obj.lclGetCallback;
if AWinControl.Focused and Assigned(Callback) then
Callback.ResignFirstResponder; // dont' call LCLSendKillFocusMsg
LCLSendDestroyMsg( AWinControl );
if obj.isKindOfClass_(NSView) then if obj.isKindOfClass_(NSView) then
begin begin
// no need to "retain" prior to "removeFromSuperview" // no need to "retain" prior to "removeFromSuperview"
@ -1633,7 +1644,6 @@ begin
NSWindow(obj).close; NSWindow(obj).close;
// destroy the callback // destroy the callback
Callback := obj.lclGetCallback;
if Assigned(Callback) then if Assigned(Callback) then
begin begin
if Callback.HasCaret then DestroyCaret(nil); if Callback.HasCaret then DestroyCaret(nil);

View File

@ -348,7 +348,10 @@ procedure TLCLWindowCallback.Activate;
var var
ACustForm: TCustomForm; ACustForm: TCustomForm;
isDesign: Boolean; isDesign: Boolean;
focusedCb: ICommonCallback;
begin begin
CocoaWidgetSet.KeyWindow:= window;
if not IsActivating then if not IsActivating then
begin begin
IsActivating:=True; IsActivating:=True;
@ -379,7 +382,9 @@ begin
end; end;
LCLSendActivateMsg(Target, WA_ACTIVE, false); LCLSendActivateMsg(Target, WA_ACTIVE, false);
LCLSendSetFocusMsg(Target); focusedCb := window.firstResponder.lclGetCallback;
if Assigned(focusedCb) then
focusedCb.BecomeFirstResponder;
// The only way to update Forms.ActiveCustomForm for the main form // The only way to update Forms.ActiveCustomForm for the main form
// is calling TCustomForm.SetFocusedControl, see bug 31056 // is calling TCustomForm.SetFocusedControl, see bug 31056
ACustForm.SetFocusedControl(ACustForm.ActiveControl); ACustForm.SetFocusedControl(ACustForm.ActiveControl);
@ -392,9 +397,17 @@ begin
end; end;
procedure TLCLWindowCallback.Deactivate; procedure TLCLWindowCallback.Deactivate;
var
focusedCb: ICommonCallback;
begin begin
CocoaWidgetSet.KeyWindow:= nil;
focusedCb:= window.firstResponder.lclGetCallback;
if Assigned(focusedCb) then begin
if not (csDestroying in TComponent(focusedCb.GetTarget).ComponentState) then
focusedCb.ResignFirstResponder;
end;
LCLSendActivateMsg(Target, WA_INACTIVE, false); LCLSendActivateMsg(Target, WA_INACTIVE, false);
LCLSendKillFocusMsg(Target);
end; end;
procedure TLCLWindowCallback.CloseQuery(var CanClose: Boolean); procedure TLCLWindowCallback.CloseQuery(var CanClose: Boolean);