mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-21 05:01:50 +02:00
Cocoa: memory leak fixes by David Jenkins, issue #40116
This commit is contained in:
parent
1b9d3d4cbf
commit
01d60e2dfd
@ -67,6 +67,7 @@ type
|
||||
fvscroll : NSScroller;
|
||||
public
|
||||
callback: ICommonCallback;
|
||||
procedure dealloc; override;
|
||||
function lclGetCallback: ICommonCallback; override;
|
||||
procedure lclClearCallback; override;
|
||||
function lclContentView: NSView; override;
|
||||
@ -328,6 +329,13 @@ end;
|
||||
|
||||
{ TCocoaManualScrollView }
|
||||
|
||||
procedure TCocoaManualScrollView.dealloc;
|
||||
begin
|
||||
if Assigned(fhscroll) then fhscroll.release;
|
||||
if Assigned(fvscroll) then fvscroll.release;
|
||||
inherited dealloc;
|
||||
end;
|
||||
|
||||
function TCocoaManualScrollView.lclGetCallback: ICommonCallback;
|
||||
begin
|
||||
Result := callback;
|
||||
|
@ -64,6 +64,7 @@ type
|
||||
lclEnabled: Boolean;
|
||||
// cocoa
|
||||
class function alloc: id; override;
|
||||
procedure dealloc; override;
|
||||
procedure setFrame(aframe: NSRect); override;
|
||||
// lcl
|
||||
function lclIsEnabled: Boolean; override;
|
||||
@ -421,6 +422,15 @@ begin
|
||||
TCocoaTabControl(Result).fulltabs := NSMutableArray(NSMutableArray.alloc).init;
|
||||
end;
|
||||
|
||||
procedure TCocoaTabControl.dealloc;
|
||||
begin
|
||||
if Assigned(fulltabs) then begin
|
||||
fulltabs.release;
|
||||
fulltabs := nil;
|
||||
end;
|
||||
inherited dealloc;
|
||||
end;
|
||||
|
||||
procedure TCocoaTabControl.setFrame(aframe: NSRect);
|
||||
begin
|
||||
inherited setFrame(aframe);
|
||||
|
@ -501,6 +501,7 @@ end;
|
||||
procedure TCocoaTableListView.dealloc;
|
||||
begin
|
||||
//if Assigned(Items) then FreeAndNil(Items);
|
||||
if Assigned(beforeSel) then beforeSel.release;
|
||||
if Assigned(smallimages) then smallimages.release; // all contents is released automatically
|
||||
inherited dealloc;
|
||||
end;
|
||||
@ -790,8 +791,8 @@ var
|
||||
dstl : NSUInteger;
|
||||
data : TCompareData;
|
||||
begin
|
||||
rm := NSMutableIndexSet.alloc.init;
|
||||
ad := NSMutableIndexSet.alloc.init;
|
||||
rm := NSMutableIndexSet.alloc.init.autorelease;
|
||||
ad := NSMutableIndexSet.alloc.init.autorelease;
|
||||
removed := rm;
|
||||
added := ad;
|
||||
|
||||
|
@ -517,6 +517,7 @@ begin
|
||||
menuItem.addTrackingArea(track);
|
||||
track.release;
|
||||
mn.setView(menuItem);
|
||||
menuItem.release;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
@ -557,6 +557,7 @@ begin
|
||||
NSNotificationCenter(NSNotificationCenter.defaultCenter).removeObserver(callback);
|
||||
callback.release;
|
||||
if (HdrCell<>nil) then hdrCell.Release;
|
||||
if (BtnCell<>nil) then BtnCell.Release;
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
|
@ -1196,6 +1196,7 @@ begin
|
||||
cmp.setMinute(m);
|
||||
cmp.setSecond(s);
|
||||
Result := NSCalendar.currentCalendar.dateFromComponents(cmp);
|
||||
cmp.release;
|
||||
end;
|
||||
|
||||
function NSDateToDateTime(const aDateTime: NSDate): TDateTime;
|
||||
|
@ -518,6 +518,7 @@ end;
|
||||
|
||||
procedure TCocoaWindowContent.dealloc;
|
||||
begin
|
||||
if Assigned(_stringValue) then _stringValue.release;
|
||||
inherited dealloc;
|
||||
end;
|
||||
|
||||
|
@ -223,7 +223,7 @@ begin
|
||||
list.callback := TLCLCheckboxListCallback.CreateWithView(list, AWinControl);
|
||||
list.lclSetFirstColumCheckboxes(true);
|
||||
//list.list := TCocoaStringList.Create(list);
|
||||
list.addTableColumn(NSTableColumn.alloc.init);
|
||||
list.addTableColumn(NSTableColumn.alloc.init.autorelease);
|
||||
list.setHeaderView(nil);
|
||||
list.setDataSource(list);
|
||||
list.setDelegate(list);
|
||||
@ -235,7 +235,6 @@ begin
|
||||
scroll := EmbedInScrollView(list);
|
||||
if not Assigned(scroll) then
|
||||
begin
|
||||
list.dealloc;
|
||||
Result := 0;
|
||||
Exit;
|
||||
end;
|
||||
|
@ -352,6 +352,7 @@ begin
|
||||
lNSText := NSStringUtf8(lText);
|
||||
|
||||
pasteboard.setString_forType(lNSText, lCurFormat.CocoaFormat);
|
||||
lNsText.release;
|
||||
end;
|
||||
ccdtCocoaStandard, ccdtNonStandard:
|
||||
begin
|
||||
|
@ -1013,7 +1013,7 @@ begin
|
||||
lTableLV := AllocCocoaTableListView.initWithFrame(ns);
|
||||
if lTableLV = nil then
|
||||
begin
|
||||
lCocoaLV.dealloc;
|
||||
lCocoaLV.release;
|
||||
Result := 0;
|
||||
exit;
|
||||
end;
|
||||
@ -1042,6 +1042,7 @@ begin
|
||||
// Windows compatibility. on Windows there's no extra space between columns
|
||||
sz.width := 0;
|
||||
lTableLV.setIntercellSpacing(sz);;
|
||||
lTableLV.release;
|
||||
{$IFDEF COCOA_DEBUG_LISTVIEW}
|
||||
WriteLn(Format('[TCocoaWSCustomListView.CreateHandle] headerView=%d', [PtrInt(lTableLV.headerView)]));
|
||||
{$ENDIF}
|
||||
@ -1117,6 +1118,7 @@ begin
|
||||
lNSColumn.headerCell.setStringValue(lTitle);
|
||||
lNSColumn.setResizingMask(NSTableColumnUserResizingMask);
|
||||
lTableLV.addTableColumn(lNSColumn);
|
||||
lNSColumn.release;
|
||||
lTitle.release;
|
||||
end;
|
||||
|
||||
@ -1643,7 +1645,7 @@ begin
|
||||
lvpShowColumnHeaders:
|
||||
if (AIsSet <> Assigned(lTableLV.headerView)) then
|
||||
begin
|
||||
if AIsSet then lTableLv.setHeaderView ( NSTableHeaderView.alloc.init )
|
||||
if AIsSet then lTableLv.setHeaderView ( NSTableHeaderView.alloc.init.autorelease )
|
||||
else lTableLv.setHeaderView(nil);
|
||||
end;
|
||||
{ lvpShowWorkAreas,
|
||||
@ -1898,6 +1900,8 @@ begin
|
||||
img := NSImage(NSImage.alloc).initWithSize( rep.size );
|
||||
img.addRepresentation(rep);
|
||||
Result := img;
|
||||
rep.release;
|
||||
|
||||
finally
|
||||
bmp.Free;
|
||||
end;
|
||||
|
@ -72,6 +72,7 @@ begin
|
||||
|
||||
c := NSCalendar.alloc.initWithCalendarIdentifier(NSString.string_);
|
||||
Result.setCalendar(c);
|
||||
c.release;
|
||||
|
||||
TCocoaDatePicker(Result).callback:= TLCLCommonCallback.Create(Result, ATarget);
|
||||
|
||||
|
@ -143,6 +143,8 @@ type
|
||||
Filters: TStringList; // filled by updateFilterList()
|
||||
NSFilters: NSMutableArray;
|
||||
lastSelectedItemIndex: Integer; // -1 means invalid or none selected
|
||||
class function alloc: id; override;
|
||||
procedure dealloc; override;
|
||||
procedure updateFilterList(); message 'updateFilterList';
|
||||
function setDialogFilter(ASelectedFilterIndex: Integer): Integer; message 'setDialogFilter:';
|
||||
procedure comboboxAction(sender: id); message 'comboboxAction:';
|
||||
@ -565,7 +567,7 @@ begin
|
||||
accessoryView.addSubview(okButton.autorelease);
|
||||
accessoryView.addSubview(cancelButton.autorelease);
|
||||
|
||||
colorPanel.setDelegate(colorDelegate);
|
||||
colorPanel.setDelegate(colorDelegate.autorelease);
|
||||
colorPanel.setAccessoryView(accessoryView.autorelease);
|
||||
colorPanel.setShowsAlpha(False);
|
||||
colorPanel.setDefaultButtonCell(okButton.cell);
|
||||
@ -740,7 +742,7 @@ begin
|
||||
accessoryView.addSubview(okButton.autorelease);
|
||||
accessoryView.addSubview(cancelButton.autorelease);
|
||||
|
||||
fontPanel.setDelegate(FontDelegate);
|
||||
fontPanel.setDelegate(FontDelegate.autorelease);
|
||||
fontPanel.setAccessoryView(accessoryView.autorelease);
|
||||
fontPanel.setDefaultButtonCell(okButton.cell);
|
||||
|
||||
@ -891,6 +893,18 @@ end;
|
||||
|
||||
{ TCocoaFilterComboBox }
|
||||
|
||||
class function TCocoaFilterComboBox.alloc: id;
|
||||
begin
|
||||
Result := inherited alloc;
|
||||
TCocoaFilterComboBox(Result).NSFilters := NSMutableArray.alloc.init;
|
||||
end;
|
||||
|
||||
procedure TCocoaFilterComboBox.dealloc;
|
||||
begin
|
||||
NSFilters.release;
|
||||
inherited dealloc;
|
||||
end;
|
||||
|
||||
class procedure TCocoaFilterComboBox.DoParseFilters(AFileDialog: TFileDialog; AOutput: TStringList);
|
||||
var
|
||||
lFilterParser, lExtParser: TParseStringList;
|
||||
@ -1032,6 +1046,7 @@ var
|
||||
uti : CFStringRef;
|
||||
ext : string;
|
||||
j : integer;
|
||||
UTIFilters: NSMutableArray;
|
||||
begin
|
||||
if (Filters = nil) or (Filters.Count=0) then
|
||||
begin
|
||||
@ -1044,14 +1059,14 @@ begin
|
||||
ASelectedFilterIndex := 0;
|
||||
Result := ASelectedFilterIndex;
|
||||
lCurFilter := TStringList(Filters.Objects[ASelectedFilterIndex]);
|
||||
NSFilters := NSMutableArray.alloc.init;
|
||||
UTIFilters := NSMutableArray.alloc.init;
|
||||
for i:=0 to lCurFilter.Count-1 do
|
||||
begin
|
||||
ext := lCurFilter[i];
|
||||
if (ext='') then Continue;
|
||||
if (ext='*.*') or (ext = '*') then begin
|
||||
//uti:=CFSTR('public.content');
|
||||
NSFilters.removeAllObjects;
|
||||
UTIFilters.removeAllObjects;
|
||||
break;
|
||||
end else begin
|
||||
// using the last part of the extension, as Cocoa doesn't suppot
|
||||
@ -1066,28 +1081,21 @@ begin
|
||||
CFStringRef(NSString.stringWithUTF8String(PChar(ext))), CFSTR('public.data'));
|
||||
end;
|
||||
if Assigned(uti) then
|
||||
NSFilters.addObject(id(uti));
|
||||
UTIFilters.addObject(id(uti));
|
||||
end;
|
||||
|
||||
if (NSFilters.count = 0) then
|
||||
if (UTIFilters.count = 0) then
|
||||
begin
|
||||
// select any file
|
||||
NSFilters.addObject(id(CFSTR('public.content')));
|
||||
NSFilters.addObject(id(CFSTR('public.data')));
|
||||
UTIFilters.addObject(id(CFSTR('public.content')));
|
||||
UTIFilters.addObject(id(CFSTR('public.data')));
|
||||
end;
|
||||
DialogHandle.setAllowedFileTypes(NSFilters);
|
||||
NSFilters.autorelease;
|
||||
DialogHandle.setAllowedFileTypes(UTIFilters);
|
||||
UTIFilters.release;
|
||||
exit;
|
||||
end;
|
||||
|
||||
if NSFilters = nil then
|
||||
begin
|
||||
NSFilters := NSMutableArray.alloc.init;
|
||||
end
|
||||
else
|
||||
begin
|
||||
NSFilters.removeAllObjects();
|
||||
end;
|
||||
NSFilters.removeAllObjects();
|
||||
|
||||
if (Filters.Count > 0) and (ASelectedFilterIndex >= 0) and
|
||||
(ASelectedFilterIndex < Filters.Count) then
|
||||
|
@ -307,6 +307,7 @@ begin
|
||||
TCocoaPanel(win).callback := cb;
|
||||
|
||||
win.setContentView(cnt);
|
||||
doc.release;
|
||||
|
||||
Result := TLCLIntfHandle(cnt);
|
||||
end;
|
||||
@ -832,7 +833,9 @@ begin
|
||||
|
||||
cnt.addSubview_positioned_relativeTo(ds, NSWindowAbove, nil);
|
||||
doc.overlay := ds;
|
||||
ds.release;
|
||||
end;
|
||||
doc.release;
|
||||
|
||||
Result := TLCLIntfHandle(cnt);
|
||||
end;
|
||||
|
@ -65,6 +65,7 @@ type
|
||||
attachedAppleMenu: Boolean;
|
||||
isKeyEq: Boolean;
|
||||
public
|
||||
procedure dealloc; override;
|
||||
procedure lclItemSelected(sender: id); message 'lclItemSelected:';
|
||||
procedure createAppleMenu(); message 'createAppleMenu';
|
||||
procedure overrideAppleMenu(AItem: TCocoaMenuItem); message 'overrideAppleMenu:';
|
||||
@ -299,6 +300,17 @@ end;
|
||||
|
||||
{ TCocoaMenu }
|
||||
|
||||
procedure TCocoaMenu.dealloc;
|
||||
begin
|
||||
if appleMenu <> nil then begin
|
||||
if indexOfItem(appleMenu) >= 0 then
|
||||
removeItem(appleMenu);
|
||||
appleMenu.release;
|
||||
appleMenu := nil;
|
||||
end;
|
||||
inherited dealloc;
|
||||
end;
|
||||
|
||||
procedure TCocoaMenu.lclItemSelected(sender:id);
|
||||
begin
|
||||
|
||||
@ -319,6 +331,7 @@ begin
|
||||
// add the submenu
|
||||
lNSSubmenu := NSMenu.alloc.initWithTitle(NSString.string_);
|
||||
appleMenu.setSubmenu(lNSSubmenu);
|
||||
lNSSubmenu.release;
|
||||
|
||||
appleMenu.attachAppleMenuItems();
|
||||
end;
|
||||
@ -419,6 +432,7 @@ end;
|
||||
procedure TCocoaMenuItem.attachAppleMenuItems();
|
||||
var
|
||||
item : NSMenuItem;
|
||||
itemSubMenu: NSMenu;
|
||||
begin
|
||||
if attachedAppleMenuItems then Exit;
|
||||
if not hasSubmenu() then Exit;
|
||||
@ -431,8 +445,11 @@ begin
|
||||
item.setTarget(nil);
|
||||
item.setAction(nil);
|
||||
submenu.insertItem_atIndex(item, submenu.itemArray.count);
|
||||
item.setSubmenu(NSMenu.alloc.initWithTitle( ControlTitleToNSStr(rsMacOSMenuServices)));
|
||||
itemSubMenu := NSMenu.alloc.initWithTitle( ControlTitleToNSStr(rsMacOSMenuServices));
|
||||
item.setSubmenu(itemSubMenu);
|
||||
itemSubMenu.release;
|
||||
NSApplication(NSApp).setServicesMenu(item.submenu);
|
||||
item.release;
|
||||
|
||||
// Separator
|
||||
submenu.insertItem_atIndex(NSMenuItem.separatorItem, submenu.itemArray.count);
|
||||
@ -440,14 +457,17 @@ begin
|
||||
// Hide App Meta-H
|
||||
item := LCLMenuItemInit( TCocoaMenuItem_HideApp.alloc, Format(rsMacOSMenuHide, [Application.Title]), VK_H, [ssMeta]);
|
||||
submenu.insertItem_atIndex(item, submenu.itemArray.count);
|
||||
item.release;
|
||||
|
||||
// Hide Others Meta-Alt-H
|
||||
item := LCLMenuItemInit( TCocoaMenuItem_HideOthers.alloc, rsMacOSMenuHideOthers, VK_H, [ssMeta, ssAlt]);
|
||||
submenu.insertItem_atIndex(item, submenu.itemArray.count);
|
||||
item.release;
|
||||
|
||||
// Show All
|
||||
item := LCLMenuItemInit( TCocoaMenuItem_ShowAllApp.alloc, rsMacOSMenuShowAll);
|
||||
submenu.insertItem_atIndex(item, submenu.itemArray.count);
|
||||
item.release;
|
||||
|
||||
// Separator
|
||||
submenu.insertItem_atIndex(NSMenuItem.separatorItem, submenu.itemArray.count);
|
||||
@ -455,6 +475,7 @@ begin
|
||||
// Quit Meta-Q
|
||||
item := LCLMenuItemInit( TCocoaMenuItem_Quit.alloc, Format(rsMacOSMenuQuit, [Application.Title]), VK_Q, [ssMeta]);
|
||||
submenu.insertItem_atIndex(item, submenu.itemArray.count);
|
||||
item.release;
|
||||
|
||||
attachedAppleMenuItems := True;
|
||||
end;
|
||||
@ -627,6 +648,7 @@ begin
|
||||
Parent := AllocCocoaMenu(AMenuItem.Parent.Caption);
|
||||
Parent.setDelegate(TCocoaMenuItem(ParObj));
|
||||
NSMenuItem(ParObj).setSubmenu(Parent);
|
||||
Parent.release;
|
||||
|
||||
// no longer respond to clicks. LCL might still need to get an event
|
||||
// yet the menu should not close
|
||||
@ -639,23 +661,22 @@ begin
|
||||
else
|
||||
Exit;
|
||||
|
||||
item := nil;
|
||||
idx := AMenuItem.MenuVisibleIndex;
|
||||
if idx < 0 then idx := Parent.numberOfItems;
|
||||
|
||||
MenuObj := NSObject(AMenuItem.Handle);
|
||||
if MenuObj.isKindOfClass(NSMenuItem) then
|
||||
item := NSMenuItem(MenuObj)
|
||||
if MenuObj.isKindOfClass(NSMenuItem) then begin
|
||||
item := NSMenuItem(MenuObj);
|
||||
Parent.insertItem_atIndex(NSMenuItem(item), idx)
|
||||
end
|
||||
else if MenuObj.isKindOfClass(NSMenu) then
|
||||
begin
|
||||
Menu := NSMenu(MenuObj);
|
||||
item := NSMenuItem(NSMenuItem.alloc).initWithTitle_action_keyEquivalent(
|
||||
ControlTitleToNSStr(AMenuItem.Caption), nil, NSString.string_ );
|
||||
item.setSubmenu( Menu );
|
||||
end;
|
||||
|
||||
if Assigned(item) then
|
||||
begin
|
||||
idx := AMenuItem.MenuVisibleIndex;
|
||||
if idx < 0 then idx := Parent.numberOfItems;
|
||||
Parent.insertItem_atIndex(NSMenuItem(item), idx)
|
||||
Parent.insertItem_atIndex(NSMenuItem(item), idx);
|
||||
item.release;
|
||||
end;
|
||||
end;
|
||||
|
||||
@ -702,6 +723,7 @@ begin
|
||||
ANSMenu := AllocCocoaMenu(AMenuItem.Caption);
|
||||
ANSMenu.setDelegate(TCocoaMenuItem(item));
|
||||
item.setSubmenu(ANSMenu);
|
||||
ANSMenu.release;
|
||||
end;
|
||||
|
||||
TCocoaMenuItem(item).menuItemCallback:=TLCLMenuItemCallback.Create(item, AMenuItem);
|
||||
@ -762,6 +784,8 @@ begin
|
||||
if nsitem.isSeparatorItem and Assigned(nsitem.menu) then
|
||||
nsitem.menu.removeItem(nsitem);
|
||||
// separator items are not "alloced", thus should not be released
|
||||
end else if item.isKindOfClass_(TCocoaMenu) then begin
|
||||
item.release;
|
||||
end;
|
||||
|
||||
end;
|
||||
|
@ -1565,6 +1565,7 @@ begin
|
||||
TextViewSetAllignment(txt, TCustomMemo(AWinControl).Alignment);
|
||||
txt.wantReturns := TCustomMemo(AWinControl).WantReturns;
|
||||
txt.callback.SetTabSuppress(not TCustomMemo(AWinControl).WantTabs);
|
||||
txt.release;
|
||||
Result := TLCLIntfHandle(scr);
|
||||
end;
|
||||
|
||||
@ -2224,7 +2225,7 @@ begin
|
||||
end;
|
||||
cb := TLCLListBoxCallback.CreateWithView(list, AWinControl);
|
||||
list.callback := cb;
|
||||
list.addTableColumn(NSTableColumn.alloc.init);
|
||||
list.addTableColumn(NSTableColumn.alloc.init.autorelease);
|
||||
list.setHeaderView(nil);
|
||||
list.setDataSource(list);
|
||||
list.setDelegate(list);
|
||||
@ -2244,7 +2245,6 @@ begin
|
||||
scroll := EmbedInScrollView(list);
|
||||
if not Assigned(scroll) then
|
||||
begin
|
||||
list.dealloc;
|
||||
Result := 0;
|
||||
Exit;
|
||||
end;
|
||||
|
Loading…
Reference in New Issue
Block a user