cocoa: reduce the amount of focus (responders) related code. Process the focus handling in NSWindow only (rather than each control individually). Update tab switch notification to report tab change prior to focus switch

git-svn-id: trunk@59039 -
This commit is contained in:
dmitry 2018-09-17 01:33:50 +00:00
parent f2ecffd6b1
commit b3b559273c
8 changed files with 62 additions and 294 deletions

View File

@ -69,8 +69,6 @@ type
procedure dealloc; override; procedure dealloc; override;
function initWithFrame(frameRect: NSRect): id; override; function initWithFrame(frameRect: NSRect): id; override;
function acceptsFirstResponder: Boolean; override; function acceptsFirstResponder: Boolean; override;
function becomeFirstResponder: Boolean; override;
function resignFirstResponder: Boolean; override;
procedure drawRect(dirtyRect: NSRect); override; procedure drawRect(dirtyRect: NSRect); override;
function lclGetCallback: ICommonCallback; override; function lclGetCallback: ICommonCallback; override;
procedure lclClearCallback; override; procedure lclClearCallback; override;
@ -236,20 +234,6 @@ begin
Result := True; Result := True;
end; end;
function TCocoaButton.becomeFirstResponder: Boolean;
begin
Result := inherited becomeFirstResponder;
if Assigned(callback) then
callback.BecomeFirstResponder;
end;
function TCocoaButton.resignFirstResponder: Boolean;
begin
Result := inherited resignFirstResponder;
if Assigned(callback) then
callback.ResignFirstResponder;
end;
procedure TCocoaButton.drawRect(dirtyRect: NSRect); procedure TCocoaButton.drawRect(dirtyRect: NSRect);
var ctx: NSGraphicsContext; var ctx: NSGraphicsContext;
begin begin

View File

@ -30,8 +30,6 @@ type
procedure mouseMoved(event: NSEvent); override; procedure mouseMoved(event: NSEvent); override;
function acceptsFirstResponder: Boolean; override; function acceptsFirstResponder: Boolean; override;
function becomeFirstResponder: Boolean; override;
function resignFirstResponder: Boolean; override;
procedure setFrame(aframe: NSRect); override; procedure setFrame(aframe: NSRect); override;
end; end;
@ -73,20 +71,6 @@ begin
Result := True; Result := True;
end; end;
function TCocoaDatePicker.becomeFirstResponder: Boolean;
begin
Result := inherited becomeFirstResponder;
if Assigned(callback) then
callback.BecomeFirstResponder;
end;
function TCocoaDatePicker.resignFirstResponder: Boolean;
begin
Result := inherited resignFirstResponder;
if Assigned(callback) then
callback.ResignFirstResponder;
end;
function TCocoaDatePicker.lclGetCallback: ICommonCallback; function TCocoaDatePicker.lclGetCallback: ICommonCallback;
begin begin
Result := callback; Result := callback;

View File

@ -186,8 +186,6 @@ type
auxMouseByParent: Boolean; auxMouseByParent: Boolean;
procedure dealloc; override; procedure dealloc; override;
function acceptsFirstResponder: Boolean; override; function acceptsFirstResponder: Boolean; override;
function becomeFirstResponder: Boolean; override;
function resignFirstResponder: Boolean; override;
procedure drawRect(dirtyRect: NSRect); override; procedure drawRect(dirtyRect: NSRect); override;
function lclGetCallback: ICommonCallback; override; function lclGetCallback: ICommonCallback; override;
procedure lclClearCallback; override; procedure lclClearCallback; override;
@ -254,8 +252,6 @@ type
public public
callback: ICommonCallback; callback: ICommonCallback;
function acceptsFirstResponder: Boolean; override; function acceptsFirstResponder: Boolean; override;
function becomeFirstResponder: Boolean; override;
function resignFirstResponder: Boolean; override;
function lclGetCallback: ICommonCallback; override; function lclGetCallback: ICommonCallback; override;
procedure lclClearCallback; override; procedure lclClearCallback; override;
procedure resetCursorRects; override; procedure resetCursorRects; override;
@ -275,8 +271,6 @@ type
TCocoaProgressIndicator = objcclass(NSProgressIndicator) TCocoaProgressIndicator = objcclass(NSProgressIndicator)
callback: ICommonCallback; callback: ICommonCallback;
function acceptsFirstResponder: Boolean; override; function acceptsFirstResponder: Boolean; override;
function becomeFirstResponder: Boolean; override;
function resignFirstResponder: Boolean; override;
function lclGetCallback: ICommonCallback; override; function lclGetCallback: ICommonCallback; override;
procedure lclClearCallback; override; procedure lclClearCallback; override;
procedure resetCursorRects; override; procedure resetCursorRects; override;
@ -318,8 +312,6 @@ type
procedure drawRect(dirtyRect: NSRect); override; procedure drawRect(dirtyRect: NSRect); override;
function acceptsFirstResponder: Boolean; override; function acceptsFirstResponder: Boolean; override;
function becomeFirstResponder: Boolean; override;
function resignFirstResponder: Boolean; override;
function lclGetCallback: ICommonCallback; override; function lclGetCallback: ICommonCallback; override;
procedure lclClearCallback; override; procedure lclClearCallback; override;
procedure resetCursorRects; override; procedure resetCursorRects; override;
@ -368,10 +360,19 @@ var
// todo: this should be a threadvar // todo: this should be a threadvar
TrackedControl : NSObject = nil; TrackedControl : NSObject = nil;
function isCallbackForSameObject(cb1, cb2: ICommonCallback): Boolean;
implementation implementation
uses CocoaInt; uses CocoaInt;
function isCallbackForSameObject(cb1, cb2: ICommonCallback): Boolean;
begin
Result := Assigned(cb1) and Assigned(cb2);
if Result then
Result := (cb1 = cb2) or (cb1.GetTarget = cb2.GetTarget);
end;
{$I mackeycodes.inc} {$I mackeycodes.inc}
procedure SetViewDefaults(AView: NSView); procedure SetViewDefaults(AView: NSView);
@ -453,20 +454,6 @@ begin
Result := True; Result := True;
end; end;
function TCocoaGroupBox.becomeFirstResponder: Boolean;
begin
Result := inherited becomeFirstResponder;
if Assigned(callback) then
callback.BecomeFirstResponder;
end;
function TCocoaGroupBox.resignFirstResponder: Boolean;
begin
Result := inherited resignFirstResponder;
if Assigned(callback) then
callback.ResignFirstResponder;
end;
function TCocoaGroupBox.lclGetCallback: ICommonCallback; function TCocoaGroupBox.lclGetCallback: ICommonCallback;
begin begin
Result := callback; Result := callback;
@ -523,20 +510,6 @@ begin
Result := True; Result := True;
end; end;
function TCocoaCustomControl.becomeFirstResponder: Boolean;
begin
Result := inherited becomeFirstResponder;
if Assigned(callback) then
callback.BecomeFirstResponder;
end;
function TCocoaCustomControl.resignFirstResponder: Boolean;
begin
Result := inherited resignFirstResponder;
if Assigned(callback) then
callback.ResignFirstResponder;
end;
function TCocoaCustomControl.acceptsFirstMouse(event: NSEvent): Boolean; function TCocoaCustomControl.acceptsFirstMouse(event: NSEvent): Boolean;
begin begin
// By default, a mouse-down event in a window that isnt the key window // By default, a mouse-down event in a window that isnt the key window
@ -1178,18 +1151,6 @@ begin
Result:=True; Result:=True;
end; end;
function TCocoaProgressIndicator.becomeFirstResponder: Boolean;
begin
Result := inherited becomeFirstResponder;
callback.BecomeFirstResponder;
end;
function TCocoaProgressIndicator.resignFirstResponder: Boolean;
begin
Result := inherited resignFirstResponder;
callback.ResignFirstResponder;
end;
function TCocoaProgressIndicator.lclGetCallback: ICommonCallback; function TCocoaProgressIndicator.lclGetCallback: ICommonCallback;
begin begin
Result:=callback; Result:=callback;
@ -1361,18 +1322,6 @@ begin
Result := True; Result := True;
end; end;
function TCocoaSlider.becomeFirstResponder: Boolean;
begin
Result := inherited becomeFirstResponder;
callback.BecomeFirstResponder;
end;
function TCocoaSlider.resignFirstResponder: Boolean;
begin
Result := inherited resignFirstResponder;
callback.ResignFirstResponder;
end;
function TCocoaSlider.lclGetCallback: ICommonCallback; function TCocoaSlider.lclGetCallback: ICommonCallback;
begin begin
Result:=callback; Result:=callback;

View File

@ -44,8 +44,6 @@ type
procedure dealloc; override; procedure dealloc; override;
procedure setFrame(aframe: NSRect); override; procedure setFrame(aframe: NSRect); override;
function acceptsFirstResponder: Boolean; override; function acceptsFirstResponder: Boolean; override;
function becomeFirstResponder: Boolean; override;
function resignFirstResponder: Boolean; override;
function lclGetCallback: ICommonCallback; override; function lclGetCallback: ICommonCallback; override;
procedure lclClearCallback; override; procedure lclClearCallback; override;
procedure resetCursorRects; override; procedure resetCursorRects; override;
@ -114,8 +112,6 @@ type
procedure actionScrolling(sender: NSObject); message 'actionScrolling:'; procedure actionScrolling(sender: NSObject); message 'actionScrolling:';
function IsHorizontal: Boolean; message 'IsHorizontal'; function IsHorizontal: Boolean; message 'IsHorizontal';
function acceptsFirstResponder: Boolean; override; function acceptsFirstResponder: Boolean; override;
function becomeFirstResponder: Boolean; override;
function resignFirstResponder: Boolean; override;
function lclGetCallback: ICommonCallback; override; function lclGetCallback: ICommonCallback; override;
procedure lclClearCallback; override; procedure lclClearCallback; override;
procedure resetCursorRects; override; procedure resetCursorRects; override;
@ -746,20 +742,6 @@ begin
Result := True; Result := True;
end; end;
function TCocoaScrollView.becomeFirstResponder: Boolean;
begin
Result := inherited becomeFirstResponder;
if Assigned(callback) then
callback.BecomeFirstResponder;
end;
function TCocoaScrollView.resignFirstResponder: Boolean;
begin
Result := inherited resignFirstResponder;
if Assigned(callback) then
callback.ResignFirstResponder;
end;
function TCocoaScrollView.lclGetCallback: ICommonCallback; function TCocoaScrollView.lclGetCallback: ICommonCallback;
begin begin
Result := callback; Result := callback;
@ -946,20 +928,6 @@ begin
Result := True; Result := True;
end; end;
function TCocoaScrollBar.becomeFirstResponder: Boolean;
begin
Result := inherited becomeFirstResponder;
if Assigned(callback) then
callback.BecomeFirstResponder;
end;
function TCocoaScrollBar.resignFirstResponder: Boolean;
begin
Result := inherited resignFirstResponder;
if Assigned(callback) then
callback.ResignFirstResponder;
end;
function TCocoaScrollBar.lclGetCallback: ICommonCallback; function TCocoaScrollBar.lclGetCallback: ICommonCallback;
begin begin
Result := callback; Result := callback;

View File

@ -479,22 +479,27 @@ procedure TCocoaTabControl.tabView_willSelectTabViewItem(tabView: NSTabView;
tabViewItem: NSTabViewItem); tabViewItem: NSTabViewItem);
begin begin
if Assigned(callback) then if Assigned(callback) then
begin
callback.willSelectTabViewItem( IndexOfTab( self, tabViewItem) ); callback.willSelectTabViewItem( IndexOfTab( self, tabViewItem) );
// This must be called, prior to notification about focus (firstResponder) change
// Focus changing goes as following:
// First page becomes visible
// Then focus is switching to the control of the page
// In Cocoa world, first "willSelect" runs, then "firstResponder" changes, then "didSelect" is fired
callback.didSelectTabViewItem( IndexOfTab( self, tabViewItem) );
end;
end; end;
procedure TCocoaTabControl.tabView_didSelectTabViewItem(tabView: NSTabView; procedure TCocoaTabControl.tabView_didSelectTabViewItem(tabView: NSTabView;
tabViewItem: NSTabViewItem); tabViewItem: NSTabViewItem);
//var
//i: Integer;
//lTabView, lCurSubview: NSView;
//lLCLControl: TWinControl;
//lBounds: TRect;
//lCurCallback: ICommonCallback;
begin begin
if Assigned(callback) then //it's called together with "willSelect"
begin
callback.didSelectTabViewItem( IndexOfTab( self, tabViewItem) ); //if Assigned(callback) then
end; //begin
//callback.didSelectTabViewItem( IndexOfTab( self, tabViewItem) );
//end;
// The recent clean up, drove the workaround below unnecessary // The recent clean up, drove the workaround below unnecessary
// (at least the problem is not observed) // (at least the problem is not observed)

View File

@ -77,8 +77,6 @@ type
smallimages : NSMutableDictionary; smallimages : NSMutableDictionary;
function acceptsFirstResponder: Boolean; override; function acceptsFirstResponder: Boolean; override;
function becomeFirstResponder: Boolean; override;
function resignFirstResponder: Boolean; override;
function lclGetCallback: ICommonCallback; override; function lclGetCallback: ICommonCallback; override;
procedure lclClearCallback; override; procedure lclClearCallback; override;
@ -420,18 +418,6 @@ begin
Result := True; Result := True;
end; end;
function TCocoaTableListView.becomeFirstResponder: Boolean;
begin
Result := inherited becomeFirstResponder;
callback.BecomeFirstResponder;
end;
function TCocoaTableListView.resignFirstResponder: Boolean;
begin
Result := inherited resignFirstResponder;
callback.ResignFirstResponder;
end;
function TCocoaTableListView.lclGetCallback: ICommonCallback; function TCocoaTableListView.lclGetCallback: ICommonCallback;
begin begin
Result := callback; Result := callback;

View File

@ -59,9 +59,6 @@ type
TCocoaTextField = objcclass(NSTextField) TCocoaTextField = objcclass(NSTextField)
callback: ICommonCallback; callback: ICommonCallback;
function acceptsFirstResponder: Boolean; override; function acceptsFirstResponder: Boolean; override;
function becomeFirstResponder: Boolean; override;
function RealResignFirstResponder: Boolean; message 'RealResignFirstResponder';
function resignFirstResponder: Boolean; override;
function lclGetCallback: ICommonCallback; override; function lclGetCallback: ICommonCallback; override;
procedure lclClearCallback; override; procedure lclClearCallback; override;
procedure resetCursorRects; override; procedure resetCursorRects; override;
@ -86,9 +83,6 @@ type
public public
callback: ICommonCallback; callback: ICommonCallback;
function acceptsFirstResponder: Boolean; override; function acceptsFirstResponder: Boolean; override;
function becomeFirstResponder: Boolean; override;
function RealResignFirstResponder: Boolean; message 'RealResignFirstResponder';
function resignFirstResponder: Boolean; override;
procedure resetCursorRects; override; procedure resetCursorRects; override;
// key // key
//procedure keyDown(event: NSEvent); override; -> keyDown doesn't work in NSTextField //procedure keyDown(event: NSEvent); override; -> keyDown doesn't work in NSTextField
@ -115,8 +109,6 @@ type
supressTextChangeEvent: Integer; // if above zero, then don't send text change event supressTextChangeEvent: Integer; // if above zero, then don't send text change event
function acceptsFirstResponder: Boolean; override; function acceptsFirstResponder: Boolean; override;
function becomeFirstResponder: Boolean; override;
function resignFirstResponder: Boolean; override;
function lclGetCallback: ICommonCallback; override; function lclGetCallback: ICommonCallback; override;
procedure lclClearCallback; override; procedure lclClearCallback; override;
procedure resetCursorRects; override; procedure resetCursorRects; override;
@ -150,7 +142,7 @@ type
TCocoaFieldEditor = objcclass(NSTextView) TCocoaFieldEditor = objcclass(NSTextView)
public public
function resignFirstResponder: Boolean; override; function lclGetCallback: ICommonCallback; override;
// keyboard // keyboard
procedure keyDown(event: NSEvent); override; procedure keyDown(event: NSEvent); override;
// mouse // mouse
@ -228,8 +220,6 @@ type
list: TCocoaComboBoxList; list: TCocoaComboBoxList;
resultNS: NSString; //use to return values to combo resultNS: NSString; //use to return values to combo
function acceptsFirstResponder: Boolean; override; function acceptsFirstResponder: Boolean; override;
function becomeFirstResponder: Boolean; override;
function resignFirstResponder: Boolean; override;
procedure textDidChange(notification: NSNotification); override; procedure textDidChange(notification: NSNotification); override;
procedure textDidEndEditing(notification: NSNotification); override; procedure textDidEndEditing(notification: NSNotification); override;
// NSComboBoxDataSourceProtocol // NSComboBoxDataSourceProtocol
@ -287,8 +277,6 @@ type
isOwnerDrawn: Boolean; isOwnerDrawn: Boolean;
isOwnerMeasure: Boolean; isOwnerMeasure: Boolean;
function acceptsFirstResponder: Boolean; override; function acceptsFirstResponder: Boolean; override;
function becomeFirstResponder: Boolean; override;
function resignFirstResponder: Boolean; override;
procedure dealloc; override; procedure dealloc; override;
function lclGetCallback: ICommonCallback; override; function lclGetCallback: ICommonCallback; override;
procedure lclClearCallback; override; procedure lclClearCallback; override;
@ -327,8 +315,6 @@ type
procedure StepperChanged(sender: NSObject); message 'StepperChanged:'; procedure StepperChanged(sender: NSObject); message 'StepperChanged:';
// lcl // lcl
function acceptsFirstResponder: Boolean; override; function acceptsFirstResponder: Boolean; override;
function becomeFirstResponder: Boolean; override;
function resignFirstResponder: Boolean; override;
function lclGetCallback: ICommonCallback; override; function lclGetCallback: ICommonCallback; override;
procedure lclClearCallback; override; procedure lclClearCallback; override;
// NSViewFix // NSViewFix
@ -352,9 +338,6 @@ type
procedure controlTextDidChange(obj: NSNotification); override; procedure controlTextDidChange(obj: NSNotification); override;
// lcl // lcl
function acceptsFirstResponder: Boolean; override; function acceptsFirstResponder: Boolean; override;
function becomeFirstResponder: Boolean; override;
function RealResignFirstResponder: Boolean; message 'RealResignFirstResponder';
function resignFirstResponder: Boolean; override;
function lclGetCallback: ICommonCallback; override; function lclGetCallback: ICommonCallback; override;
procedure lclClearCallback; override; procedure lclClearCallback; override;
procedure resetCursorRects; override; procedure resetCursorRects; override;
@ -493,24 +476,10 @@ begin
Result := NSView(v); Result := NSView(v);
end; end;
function TCocoaFieldEditor.resignFirstResponder: Boolean; function TCocoaFieldEditor.lclGetCallback: ICommonCallback;
var
v : NSObject;
begin begin
v := GetEditBox(Self); if Assigned(delegate) then Result := NSObject(delegate).lclGetCallback
//DebugLn('[TCocoaFieldEditor.resignFirstResponder]'); else Result := nil;
if (v <> nil) then
begin
if v.isKindOfClass_(TCocoaTextField) then
begin
TCocoaTextField(v).RealResignFirstResponder();
end
else if v.isKindOfClass_(TCocoaSecureTextField) then
begin
TCocoaSecureTextField(v).RealResignFirstResponder();
end;
end;
Result := inherited resignFirstResponder;
end; end;
procedure TCocoaFieldEditor.keyDown(event: NSEvent); procedure TCocoaFieldEditor.keyDown(event: NSEvent);
@ -655,30 +624,6 @@ begin
Result := True; Result := True;
end; end;
function TCocoaTextField.becomeFirstResponder: Boolean;
begin
Result := inherited becomeFirstResponder;
callback.BecomeFirstResponder;
end;
function TCocoaTextField.RealResignFirstResponder: Boolean;
begin
callback.ResignFirstResponder;
Result := True;
end;
// Do not propagate this event to the LCL,
// because Cocoa NSTextField loses focus as soon as it receives it
// and the shared editor gets focus instead.
// see NSWindow.fieldEditor:forObject:
// See http://www.cocoabuilder.com/archive/cocoa/103607-resignfirstresponder-called-immediately.html
// See http://stackoverflow.com/questions/3192905/nstextfield-not-noticing-lost-focus-when-pressing-tab
function TCocoaTextField.resignFirstResponder: Boolean;
begin
//DebugLn('[TCocoaTextField.resignFirstResponder]');
Result := inherited resignFirstResponder;
end;
function TCocoaTextField.lclGetCallback: ICommonCallback; function TCocoaTextField.lclGetCallback: ICommonCallback;
begin begin
Result := callback; Result := callback;
@ -821,18 +766,6 @@ begin
Result := True; Result := True;
end; end;
function TCocoaTextView.becomeFirstResponder: Boolean;
begin
Result := inherited becomeFirstResponder;
callback.BecomeFirstResponder;
end;
function TCocoaTextView.resignFirstResponder: Boolean;
begin
Result := inherited resignFirstResponder;
callback.ResignFirstResponder;
end;
function TCocoaTextView.lclGetCallback: ICommonCallback; function TCocoaTextView.lclGetCallback: ICommonCallback;
begin begin
Result := callback; Result := callback;
@ -943,24 +876,6 @@ begin
Result := True; Result := True;
end; end;
function TCocoaSecureTextField.becomeFirstResponder: Boolean;
begin
Result := inherited becomeFirstResponder;
callback.BecomeFirstResponder;
end;
function TCocoaSecureTextField.RealResignFirstResponder: Boolean;
begin
callback.ResignFirstResponder;
Result := True;
end;
function TCocoaSecureTextField.resignFirstResponder: Boolean;
begin
//DebugLn('[TCocoaTextField.resignFirstResponder]');
Result := inherited resignFirstResponder;
end;
procedure TCocoaSecureTextField.resetCursorRects; procedure TCocoaSecureTextField.resetCursorRects;
begin begin
if not callback.resetCursorRects then if not callback.resetCursorRects then
@ -1144,18 +1059,6 @@ begin
Result := True; Result := True;
end; end;
function TCocoaComboBox.becomeFirstResponder: Boolean;
begin
Result := inherited becomeFirstResponder;
callback.BecomeFirstResponder;
end;
function TCocoaComboBox.resignFirstResponder: Boolean;
begin
Result := inherited resignFirstResponder;
callback.ResignFirstResponder;
end;
procedure TCocoaComboBox.textDidChange(notification: NSNotification); procedure TCocoaComboBox.textDidChange(notification: NSNotification);
var var
TheEvent: NSEvent; TheEvent: NSEvent;
@ -1352,18 +1255,6 @@ begin
Result := True; Result := True;
end; end;
function TCocoaReadOnlyComboBox.becomeFirstResponder: Boolean;
begin
Result := inherited becomeFirstResponder;
callback.BecomeFirstResponder;
end;
function TCocoaReadOnlyComboBox.resignFirstResponder: Boolean;
begin
Result := inherited resignFirstResponder;
callback.ResignFirstResponder;
end;
procedure TCocoaReadOnlyComboBox.dealloc; procedure TCocoaReadOnlyComboBox.dealloc;
begin begin
if Assigned(list) then if Assigned(list) then
@ -1649,20 +1540,6 @@ begin
Result := True; Result := True;
end; end;
function TCocoaSpinEdit.becomeFirstResponder: Boolean;
begin
Result := Edit.becomeFirstResponder;
if Assigned(callback) then
callback.BecomeFirstResponder;
end;
function TCocoaSpinEdit.resignFirstResponder: Boolean;
begin
Result := inherited resignFirstResponder;
if Assigned(callback) then
callback.ResignFirstResponder;
end;
function TCocoaSpinEdit.lclGetCallback: ICommonCallback; function TCocoaSpinEdit.lclGetCallback: ICommonCallback;
begin begin
Result := callback; Result := callback;
@ -1822,25 +1699,6 @@ begin
Result := True; Result := True;
end; end;
function TCocoaSpinEdit.becomeFirstResponder: Boolean;
begin
Result := inherited becomeFirstResponder;
callback.BecomeFirstResponder;
end;
function TCocoaSpinEdit.RealResignFirstResponder: Boolean;
begin
callback.ResignFirstResponder;
Result := True;
end;
// See TCocoaTextField.resignFirstResponder as to why this is done here
function TCocoaSpinEdit.resignFirstResponder: Boolean;
begin
//DebugLn('[TCocoaTextField.resignFirstResponder]');
Result := inherited resignFirstResponder;
end;
function TCocoaSpinEdit.lclGetCallback: ICommonCallback; function TCocoaSpinEdit.lclGetCallback: ICommonCallback;
begin begin
Result := callback; Result := callback;

View File

@ -121,6 +121,10 @@ type
isInFullScreen: Boolean; isInFullScreen: Boolean;
orderOutAfterFS : Boolean; orderOutAfterFS : Boolean;
fsview: TCocoaWindowContent; fsview: TCocoaWindowContent;
responderSwitch: Integer;
respInitCb : ICommonCallback;
function windowShouldClose(sender : id): LongBool; message 'windowShouldClose:'; function windowShouldClose(sender : id): LongBool; message 'windowShouldClose:';
procedure windowWillClose(notification: NSNotification); message 'windowWillClose:'; procedure windowWillClose(notification: NSNotification); message 'windowWillClose:';
function windowWillReturnFieldEditor_toObject(sender: NSWindow; client: id): id; message 'windowWillReturnFieldEditor:toObject:'; function windowWillReturnFieldEditor_toObject(sender: NSWindow; client: id): id; message 'windowWillReturnFieldEditor:toObject:';
@ -160,6 +164,8 @@ type
// NSDraggingDestinationCategory // NSDraggingDestinationCategory
function draggingEntered(sender: NSDraggingInfoProtocol): NSDragOperation; override; function draggingEntered(sender: NSDraggingInfoProtocol): NSDragOperation; override;
function performDragOperation(sender: NSDraggingInfoProtocol): Boolean; override; function performDragOperation(sender: NSDraggingInfoProtocol): Boolean; override;
// windows
function makeFirstResponder(r: NSResponder): Boolean; override;
// menu support // menu support
procedure lclItemSelected(sender: id); message 'lclItemSelected:'; procedure lclItemSelected(sender: id); message 'lclItemSelected:';
@ -204,6 +210,7 @@ type
procedure didAddSubview(aview: NSView); override; procedure didAddSubview(aview: NSView); override;
end; end;
implementation implementation
{ TCocoaDesignOverlay } { TCocoaDesignOverlay }
@ -917,6 +924,33 @@ begin
Result := True; Result := True;
end; end;
function TCocoaWindow.makeFirstResponder(r: NSResponder): Boolean;
var
cbnew: ICommonCallback;
begin
if (responderSwitch = 0) then
respInitCb := firstResponder.lclGetCallback;
// makeFirstResponder calls can be recursive!
// the resulting NSResponder can be the same object (i.e. fieldEditor)
// yet, the callback should be the different anyway
inc(responderSwitch);
Result:=inherited makeFirstResponder(r);
dec(responderSwitch);
if (responderSwitch = 0) then
begin
cbnew := firstResponder.lclGetCallback;
if not isCallbackForSameObject(respInitCb, cbnew) then
begin
if Assigned(respInitCb) then respInitCb.ResignFirstResponder;
if Assigned(cbnew) then cbnew.BecomeFirstResponder;
end;
end;
end;
procedure TCocoaWindow.lclItemSelected(sender: id); procedure TCocoaWindow.lclItemSelected(sender: id);
begin begin