mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-18 07:59:28 +02:00
fixed focusing in gtklist
git-svn-id: trunk@8568 -
This commit is contained in:
parent
5571a611a1
commit
fe9a9c9db9
@ -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);
|
||||||
|
@ -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));
|
||||||
|
100
lcl/lclproc.pas
100
lcl/lclproc.pas
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user