OK, so here is one for you wxPerl whizzes out there. I really need to figure this out. I have a derived class which has the following override function for AutoSizeColumn(). There is also one for AutoSizeRow(), but I’m going to focus on this one as I believe this is where my issue is occurring. I have a program which shows a grid which updates every 10 seconds, which includes AutoSize’ing the grid. Over a period of time, (like say 1 hour), something is happening which includes a small memory leak, but something more profound with X11. When the program is quit, it will hang for a while, but only if SMART_AUTOSIZE is set to 2. If it is zero, or 1 it works fine, but when set to 2 it causes something to happen that is either a strict memory leak or some excess chattiness with the X11 server. If used with Exceed on OSX, it will cause it to lock up the server altogether, to the point it requires to be killed (-9).
The only thing I can see materially different here is that when SMART_AUTOSIZE is 2, then the current column label is split into words, and the maximum word width is determined, then WrapColLabelValue() is called which ultimately wraps the column label value to the width of the column. Any clues? I’m using WxWidgets 2.8.10 Here is the code: sub AutoSizeColumn { my $self = shift; my $col = shift; my $setAsMin = shift; return if $self->IsColHidden($col); return $self->SUPER::AutoSizeColumn($col,$setAsMin) unless $self->{SMART_AUTOSIZE}; my $cwc = defined $self->{COLUMN_WRAP}{$col}{MODE} ? $col : 'ALL'; if ($self->{COL_SIZE}{$col}) { Debug("fixed col size.. wrapping"); $self->SetColSize($col,$self->{COL_SIZE}{$col}); $self->WrapColumnValues($col) if $self->{COLUMN_WRAP}{$cwc}{MODE}; return; } my $nr = $self->GetNumberRows() - 1; my $clv = $self->SUPER::GetColLabelValue($col); my @hdr = $self->{SMART_AUTOSIZE} == 2 ? split(/\s+/,$clv) : ($clv); if ($hdr[-1] eq '/\\' or $hdr [-1] eq '\\/') { $hdr[-2] .= ' ' . $hdr[-1]; pop @hdr; } my $lfont = $self->GetLabelFont(); my $w = $self->{HIDE_COLUMN_LABEL} ? 0 : Max(map { ($self->GetTextExtent($_,$lfont))[0] } @hdr); Debug("$col. $clv: w=$w"); for my $r (0..$nr) { next if $self->IsRowHidden($r); my $v = $self->{COLUMN_WRAP}{$cwc}{MODE} ? ($self->{COLUMN_WRAP}{$cwc}{WIDTH} ? $self->WrapCellValue($r,$col) : $self->UnwrapCellValue($r,$col)) : $self->GetCellValue($r,$col); next unless $v; $w = Max($w,($self->GetTextExtent($v,$self->GetCellFont($r,$col)))[0]); Debug("v='$v' w=$w"); } if ($w) { $self->SetColSize($col,$w + GRID_SIZE_PAD); $self->WrapColLabelValue($col) if $self->{SMART_AUTOSIZE} == 2; } else { $self->SUPER::AutoSizeColumn($col,$setAsMin); } } # WrapColLabelValue( <col> ) # If the column has a fixed width, then wrap the Column label contents at space boundaries to fit. sub WrapColLabelValue { my $self = shift; my $col = shift; my $w = $self->GetColSize($col); my $val = units::unWrapString($self->SUPER::GetColLabelValue($col),1); return unless $val; my $font = $self->GetLabelFont(); my ($sx,$sy,$descent,$el) = new Wx::Window($self,-1)->GetTextExtent($val,$font); my $nw = int(length($val)/$sx*$w) - 2; my $sw = units::wrapString($val,'\s+',$nw,1); $sw =~ s/\n([\/\\]+)$/ $1/; $self->SUPER::SetColLabelValue($col,$sw); return 0; } # wrapString( <string>, <delimiter>, <width> [, <mode> ] ) # <string> string to be wrapped # <delimiter> regex expression for delimiter # <width> max width of the output in characters (string will be wrapped to not exceed this value) # <mode> If set, then space delimiters will be compressed (IE: ' ' --> ' '). # # Returns the wrapped string. sub wrapString { my $str = shift; my $d = shift; my $w = shift; my $mode = shift; return '' unless defined $str; my @tok = split /$d/,$str; my @del = $str =~ /($d)/g; my $nstr = ''; my $sw = 0; my $s = $mode ? '\s*' : ''; for my $t (@tok) { my $d = pop @del; $d = '' if not defined $d; $nstr =~ s/$s$/\n/,$sw=0 if $sw and ($sw + length($t.$d)) > $w; $nstr .= $t.$d; $sw += length($t.$d); } return $nstr; } # unWrapString( <string> [, <mode> ] ) # Unwrap the string. If <mode> is set, then add space # character in place of line feed sub unWrapString { my $str = shift; my $mode = shift; my $d = $mode ? ' ' : ''; $str =~ s/\n/$d/g; return $str; } --------------------------------- Jim Clark Senior Software Engineer, EES Apple, Inc 408-974-9906 (office) 408-781-1425 (cell) ** Converting pizza into code for over 20 years **