fixed focusing in gtklist

git-svn-id: trunk@8568 -
This commit is contained in:
mattias 2006-01-19 22:54:58 +00:00
parent 5571a611a1
commit fe9a9c9db9
3 changed files with 103 additions and 20 deletions

View File

@ -732,9 +732,16 @@ end;
------------------------------------------------------------------------------} ------------------------------------------------------------------------------}
procedure TGtkListStringList.Clear; procedure TGtkListStringList.Clear;
{$IFDEF DebugLCLComponents}
var i: integer;
{$ENDIF}
begin begin
BeginUpdate; BeginUpdate;
RemoveAllCallbacks; RemoveAllCallbacks;
{$IFDEF DebugLCLComponents}
for i:=0 to FCachedCount-1 do
DebugGtkWidgets.MarkDestroyed(FCachedItems[i]);
{$ENDIF}
Include(FStates,glsItemCacheNeedsUpdate); Include(FStates,glsItemCacheNeedsUpdate);
CheckForInvalidFocus; CheckForInvalidFocus;
gtk_list_clear_items(FGtkList, 0, Count); gtk_list_clear_items(FGtkList, 0, Count);

View File

@ -8284,6 +8284,7 @@ function TGtkWidgetSet.SetFocus(hWnd: HWND): HWND;
WinWidgetInfo: PWinWidgetInfo; WinWidgetInfo: PWinWidgetInfo;
ImplWidget: PGtkWidget; ImplWidget: PGtkWidget;
GList: PGlist; GList: PGlist;
LastFocusWidget: PGtkWidget;
begin begin
// Default to the widget, try to find other // Default to the widget, try to find other
Result := AWidget; Result := AWidget;
@ -8317,6 +8318,9 @@ function TGtkWidgetSet.SetFocus(hWnd: HWND): HWND;
// Try the last added selected // Try the last added selected
if not (selection_mode(PGtkList(ImplWidget)^) in [GTK_SELECTION_SINGLE, GTK_SELECTION_BROWSE]) if not (selection_mode(PGtkList(ImplWidget)^) in [GTK_SELECTION_SINGLE, GTK_SELECTION_BROWSE])
and (PGtkList(ImplWidget)^.last_focus_child <> nil) and (PGtkList(ImplWidget)^.last_focus_child <> nil)
then begin
LastFocusWidget:=PGtkList(ImplWidget)^.last_focus_child;
if g_list_find(PGtkList(ImplWidget)^.selection,LastFocusWidget)<>nil
then begin then begin
Result := PGtkList(ImplWidget)^.last_focus_child; Result := PGtkList(ImplWidget)^.last_focus_child;
{$IfDef VerboseFocus} {$IfDef VerboseFocus}
@ -8324,6 +8328,7 @@ function TGtkWidgetSet.SetFocus(hWnd: HWND): HWND;
{$EndIf} {$EndIf}
Exit; Exit;
end; end;
end;
// If there is a selection, try the first // If there is a selection, try the first
GList := PGtkList(ImplWidget)^.selection; GList := PGtkList(ImplWidget)^.selection;
@ -8442,6 +8447,7 @@ begin
{$IfDef VerboseFocus} {$IfDef VerboseFocus}
DebugLn(' H SETTING NewFocusWidget=',dbgs(NewFocusWidget),' ',DbgSName(GetNearestLCLObject(NewFocusWidget))); DebugLn(' H SETTING NewFocusWidget=',dbgs(NewFocusWidget),' ',DbgSName(GetNearestLCLObject(NewFocusWidget)));
{$EndIf} {$EndIf}
//DebugLn('TGtkWidgetSet.SetFocus TopLevel[',DebugGtkWidgets.GetInfo(TopLevel,false),'] NewFocusWidget=[',DebugGtkWidgets.GetInfo(NewFocusWidget,false),']');
gtk_window_set_focus(PGtkWindow(TopLevel),NewFocusWidget); gtk_window_set_focus(PGtkWindow(TopLevel),NewFocusWidget);
{$IfDef VerboseFocus} {$IfDef VerboseFocus}
DebugLn(' I NewTopLevel FocusWidget=',DbgS(PGtkWindow(TopLevel)^.Focus_Widget),' Success=',dbgs(PGtkWindow(TopLevel)^.Focus_Widget=NewFocusWidget)); DebugLn(' I NewTopLevel FocusWidget=',DbgS(PGtkWindow(TopLevel)^.Focus_Widget),' Success=',dbgs(PGtkWindow(TopLevel)^.Focus_Widget=NewFocusWidget));

View File

@ -58,6 +58,7 @@ type
end; end;
type type
TStackTracePointers = array of Pointer;
{ TDebugLCLItemInfo } { TDebugLCLItemInfo }
@ -66,9 +67,10 @@ type
Item: Pointer; Item: Pointer;
IsDestroyed: boolean; IsDestroyed: boolean;
Info: string; Info: string;
CreationStack: string; // stack trace at creationg CreationStack: TStackTracePointers; // stack trace at creationg
DestructionStack: string;// stack trace at destruction DestructionStack: TStackTracePointers;// stack trace at destruction
function AsString: string; function AsString(WithStackTraces: boolean): string;
destructor Destroy; override;
end; end;
{ TDebugLCLItems } { TDebugLCLItems }
@ -84,6 +86,7 @@ type
function IsDestroyed(p: Pointer): boolean; function IsDestroyed(p: Pointer): boolean;
function MarkCreated(p: Pointer; const InfoText: string): TDebugLCLItemInfo; function MarkCreated(p: Pointer; const InfoText: string): TDebugLCLItemInfo;
procedure MarkDestroyed(p: Pointer); procedure MarkDestroyed(p: Pointer);
function GetInfo(p: Pointer; WithStackTraces: boolean): string;
end; end;
TLineInfoCacheItem = record TLineInfoCacheItem = record
@ -160,6 +163,9 @@ procedure RaiseGDBException(const Msg: string);
procedure DumpExceptionBackTrace; procedure DumpExceptionBackTrace;
procedure DumpStack; procedure DumpStack;
function GetStackTrace(UseCache: boolean): string; function GetStackTrace(UseCache: boolean): string;
procedure GetStackTracePointers(var AStack: TStackTracePointers);
function StackTraceAsString(const AStack: TStackTracePointers;
UseCache: boolean): string;
function GetLineInfo(Addr: Pointer; UseCache: boolean): string; function GetLineInfo(Addr: Pointer; UseCache: boolean): string;
procedure DebugLn(const S: String; Args: array of const); procedure DebugLn(const S: String; Args: array of const);
@ -763,6 +769,50 @@ begin
end; end;
end; end;
procedure GetStackTracePointers(var AStack: TStackTracePointers);
var
Depth: Integer;
bp: Pointer;
oldbp: Pointer;
begin
// get stack depth
Depth:=0;
bp:=get_caller_frame(get_frame);
while bp<>nil do begin
inc(Depth);
oldbp:=bp;
bp:=get_caller_frame(bp);
if (bp<=oldbp) or (bp>(StackBottom + StackLength)) then
bp:=nil;
end;
SetLength(AStack,Depth);
if Depth>0 then begin
Depth:=0;
bp:=get_caller_frame(get_frame);
while bp<>nil do begin
AStack[Depth]:=get_caller_addr(bp);
inc(Depth);
oldbp:=bp;
bp:=get_caller_frame(bp);
if (bp<=oldbp) or (bp>(StackBottom + StackLength)) then
bp:=nil;
end;
end;
end;
function StackTraceAsString(const AStack: TStackTracePointers;
UseCache: boolean): string;
var
i: Integer;
CurAddress: String;
begin
Result:='';
for i:=0 to length(AStack)-1 do begin
CurAddress:=GetLineInfo(AStack[i],UseCache);
Result:=Result+CurAddress+LineEnding;
end;
end;
function GetLineInfo(Addr: Pointer; UseCache: boolean): string; function GetLineInfo(Addr: Pointer; UseCache: boolean): string;
var var
ANode: TAvgLvlTreeNode; ANode: TAvgLvlTreeNode;
@ -2550,7 +2600,7 @@ var
procedure RaiseDoubleDestroyed; procedure RaiseDoubleDestroyed;
begin begin
debugLn('TDebugLCLItems.MarkDestroyed Double destroyed:'); debugLn('TDebugLCLItems.MarkDestroyed Double destroyed:');
debugln(Info.AsString); debugln(Info.AsString(true));
debugln('Now:'); debugln('Now:');
DebugLn(GetStackTrace(true)); DebugLn(GetStackTrace(true));
RaiseGDBException('RaiseDoubleDestroyed'); RaiseGDBException('RaiseDoubleDestroyed');
@ -2563,7 +2613,18 @@ begin
if Info.IsDestroyed then if Info.IsDestroyed then
RaiseDoubleDestroyed; RaiseDoubleDestroyed;
Info.IsDestroyed:=true; Info.IsDestroyed:=true;
Info.DestructionStack:=GetStackTrace(true); GetStackTracePointers(Info.DestructionStack);
end;
function TDebugLCLItems.GetInfo(p: Pointer; WithStackTraces: boolean): string;
var
Info: TDebugLCLItemInfo;
begin
Info:=FindInfo(p,false);
if Info<>nil then
Result:=Info.AsString(WithStackTraces)
else
Result:='';
end; end;
function TDebugLCLItems.MarkCreated(p: Pointer; function TDebugLCLItems.MarkCreated(p: Pointer;
@ -2574,7 +2635,7 @@ var
procedure RaiseDoubleCreated; procedure RaiseDoubleCreated;
begin begin
debugLn('TDebugLCLItems.MarkCreated old:'); debugLn('TDebugLCLItems.MarkCreated old:');
debugln(Info.AsString); debugln(Info.AsString(true));
debugln(' New=',dbgs(p),' InfoText="',InfoText,'"'); debugln(' New=',dbgs(p),' InfoText="',InfoText,'"');
DebugLn(GetStackTrace(true)); DebugLn(GetStackTrace(true));
RaiseGDBException('RaiseDoubleCreated'); RaiseGDBException('RaiseDoubleCreated');
@ -2591,22 +2652,31 @@ begin
end; end;
Info.IsDestroyed:=false; Info.IsDestroyed:=false;
Info.Info:=InfoText; Info.Info:=InfoText;
Info.CreationStack:=GetStackTrace(true); GetStackTracePointers(Info.CreationStack);
Info.DestructionStack:=''; SetLength(Info.DestructionStack,0);
Result:=Info; Result:=Info;
end; end;
{ TDebugLCLItemInfo } { TDebugLCLItemInfo }
function TDebugLCLItemInfo.AsString: string; function TDebugLCLItemInfo.AsString(WithStackTraces: boolean): string;
begin begin
Result:='Item='+Dbgs(Item)+LineEnding Result:='Item='+Dbgs(Item)+LineEnding
+'Info="'+DbgStr(Info)+LineEnding +'Info="'+DbgStr(Info)+LineEnding;
+'Creation:'+LineEnding if WithStackTraces then
+CreationStack; Result:=Result+'Creation:'+LineEnding+StackTraceAsString(CreationStack,true);
if IsDestroyed then if IsDestroyed then begin
Result:=Result+'Destroyed:'+LineEnding Result:=Result+'Destroyed:'+LineEnding;
+DestructionStack if WithStackTraces then
Result:=Result+StackTraceAsString(DestructionStack,true);
end;
end;
destructor TDebugLCLItemInfo.Destroy;
begin
SetLength(CreationStack,0);
SetLength(DestructionStack,0);
inherited Destroy;
end; end;
initialization initialization