ELayoutException - Wie debuggen ?

Für Fragen rund um die Ide und zum Debugger
Antworten
Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6198
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

ELayoutException - Wie debuggen ?

Beitrag von af0815 »

Hallo,
ich habe plötzlich ein Problem mit einem komplexen Layout. Dabei sind Frames in Frames in Frames in Frames.... verschachtelt. Das hat jahrelang funktioniert. Jetzt plötzlich hat die Applikation einen Fehler.
ELayoutException
ELayoutException
Screenshot 2021-11-18 095352.jpg (23.36 KiB) 1995 mal betrachtet
Ich habe das jetzt einkreisen können, es ist in einem Frame, das 2 Panels übereinander beinhaltet, das obere Panel1 enthält Navigationselemente aus Label, Edits, Button,... Dieses Panel hat oben, links und rechts Anchors die es am Frame festmachen.
Das untere Panel2 ist oben am Panel1 festgemacht, die restlichen Seiten am Frame. Auf diesen Frame befinden sich 2 Elemente, ein TabControl und ein WorkSheetgrid. Das WorkSheetGrid ist oben am TabControl festgemacht und die restlichen Seiten am Panel2.
TabControl1
TabControl1
Screenshot 2021-11-18 095254.jpg (28.02 KiB) 1995 mal betrachtet
Jetzt kommt etwas was ich nicht ganz verstehe:
Das TabControl1 ist oben und links am Panel2 festgemacht.

-> Das funktioniert soweit, nur wenn ich jetzt die rechte Seite an das Panel2 binde, so kommt die obige Fehlermeldung. Nehme ich den Anchor weg so geht es wieder.
TabControl1 rechts nicht angehaengt
TabControl1 rechts nicht angehaengt
Screenshot 2021-11-18 095229.jpg (31.44 KiB) 1995 mal betrachtet
Ich gehe davon aus, das es im TabSheet zu einer Situation kommt, das das Layout sich versucht in einer Loop zu aktualisieren, weil die Werte dürften in Schritten von 2 px ändern. Das ist plötzlich bei mir auf Win10 auf diversen Rechnern aufgetreten, die alle mitsamt die aktuellen Patches von M$ erhalten. Weil vor ca. 14 Tagen hat der Code ohne Probleme funktioniert. Daher habe ich auch ein Installationspaket gemacht und das hat Probleme gemacht. Und der Originalcode plötzlich auch. Ich würde auf einen Fix im Widgetset von Win10 tippen, der das in dieser speziellen Kombination auslöst.

Es dürfte kein großes Problem sein, nur ist die Frage, wie kann ich das in der LCL am besten debuggen. :?:

Oder sieht wer in dem Layout noch etwas was ich übersehen habe ?


------ Hinweise -----
Lazarus 2.1.0 r65130 FPC 3.2.2 i386-win32-win32/win64 - da habe ich das Problem nicht gesehen. Wenn ich das Projekt mit der Version rekompiliere dann gibt es keine Fehlermeldung.

Lazarus 2.3.0 rmain-2_3-342-gc44d729ba2 FPC 3.2.3 i386-win32-win32/win64 - da mit lief das Programm bis vor ca. 2 Wochen. Gestern wieder probiert -> Fehler

Lazarus 2.3.0 (rev main-2_3-674-gdda96a3864) FPC 3.2.2 i386-win32-win32/win64 gestern erstellt -> Fehler
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6198
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: ELayoutException - Wie debuggen ?

Beitrag von af0815 »

Das debuggen ist gar nicht so schwer. Einfach bei Lazarus "Tools->Configure Build Lazarus" aufrufen und dort bei Profile "Debug IDE" auswählen, ein clear rebuild und es geht schon los mit dem Debuggen.

Ich habe in der Lazarus\lcl\include\control.inc in Zeile 685 mal folgendes aktiviert

Code: Alles auswählen

  DebugLn(['TControl.ChangeBounds A ',DbgSName(Self),
    ' Old=',Left,',',Top,',',Width,',',Height,
    ' New=',ALeft,',',ATop,',',AWidth,',',AHeight,
    ' KeepBase=',KeepBase]);
Darauf hin wird die Loop laut Log (tmp.txt) ersichtlicher. Das Hauptframe ist XXXBasisFrameXXX, da sieht man wie das jeden Durchlauf um 2 Pixel breiter wird, bis die Überprüfung auf eine Schleife anspricht. Alle anderen Controls werden nachgeführt, eines nach dem anderen. Ist das fertig ist die breite des Frames geändert und der Sch.... beginnt von vorne.

Nehme ich beim TabControl1:TTabControl den rechten Anchor weg und setze den anders (per Programm) so wird das Layout einmal eingerichtet und ist dann stabil - daher keine Loop.

Das kann ich aber nur in der einen speziellen Konfiguration beobachten. Ich habe nur keine Idee warum das Frame bei jeden durchlauf um 2 Pixel breiter wird.
Dateianhänge
Temp.txt
Log der Loop
(850.34 KiB) 77-mal heruntergeladen
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Benutzeravatar
fliegermichl
Lazarusforum e. V.
Beiträge: 1430
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Lazarus Fixes FPC Stable
CPU-Target: 32/64Bit
Wohnort: Echzell

Re: ELayoutException - Wie debuggen ?

Beitrag von fliegermichl »

Ich hab das mal nachgebaut. Bei mir gibt es keine Fehlermeldungen.
Lazarus 2.3.0 r65479 FPC 3.3.1 x86_64-win64-win32/win64

Kannst du mal einen Codeschnipsel hochladen, der das provoziert?

wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: ELayoutException - Wie debuggen ?

Beitrag von wp_xyz »

So toll das Anchoring von Lazarus ist, so schwierig ist es, die Ursache zu finden, wenn es sich irgendwo verhakt hat. Da ist irgendwo noch ein Häkchen gesetzt, das nicht sein sollte, und schon funktioniert es nicht.

Mein Ausweg ist immer, einen Schritt zurückzugehen und das Anchoring wieder herauszunehmen, wo es geht. In deinem Fall - Panel1 links, oben und rechts am Frame verankert, Panel2 links/rechts/unten am Frame und oben an Panel1 verankert - kann man sich ganz einfach behelfen, in dem man so tut als wäre man bei Delphi: Panel1.Align := alTop, Panel2.Align := alClient (dazu alle Verankerungen von Panel1/Panel2 lösen).

Was ich in der Beschreibung nicht verstanden habe: "Das WorkSheetGrid ist oben am TabControl festgemacht und die restlichen Seiten am Panel2" - meiner Meinung nach sollte das Grid IM TabControl sein, nicht unter ihm.

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6198
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: ELayoutException - Wie debuggen ?

Beitrag von af0815 »

@fliegermichl
Ein Codeschnippsel zum testen gibt es nicht, sonst wäre das schon in einem Bugreport :-) AUsserdem handelt es sich immer um einen 32 Bit Lazarus.

@wp_xyz
Das TabControl dient zur Auswahl was gerade im WorkSheetGrid angezeigt wird. Vom TabControl werden nur die Pages-Reiter verwendet, die dynamisch erzeugt werden. Das WorkSheetGrid ist absichtlich darunter befestigt, damit sich die Höhe dynamisch anpassen kann, falls die Pages-Reiter mal zweireihig werden.

Ich habe die ganzen Anchors und Aligns mal herausgenommen und langsam nochmals NUR Anchors gesetzt. Das geht alles super, bis ich den letzten rechten Anchor setze. Was mir nur aufgefallen ist, das der Versatz genau der Standardrand vom TabControl ist. Laut Sourcen sind das 2 Pixel. Was auffällig ist, das das ganze im Frame abspielt, jede iteration der Schleife macht das Frame um genau 2 Punkte auf der rechten Seite größer. So als würde der Anchor erzwingen, das der Parent sich vergrößern muss.

Das mit dem Delphi Ansatz werde ich morgen mal probieren. Bei dem Layout sollte das kein Problem sein.

-----
Grundlegend ist das Arbeiten mit dynamischen Frames und den ganzen Anchor echt steil. Die Frames erzwingen eine absolute Trennung und wieder Verwendbarkeit im Code und mit den Anchors ist das Layout total dynamisch. Egal ob die dann unter Windows oder Linux läuft. Wenn man jetzt auch noch mit Vererbungen im Frame arbeitet, hat man einen Baukasten vor sich, der echt stark ist.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6198
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: ELayoutException - Wie debuggen ?

Beitrag von af0815 »

So, ich habe ein Beispiel zusamengebracht. Es ist recht tricky gewesen, da der Fehler nur im Verbund Frame in Frame auftritt.

Die Ursache habe ich auch eingrenzen können. In der \lazarus\lcl\include\tabcontrol.inc wird beim setzen der TabPosition tpTop auch die Breite mitgeändert. Es wird dort für die Breite die TabControl.ClientWidth genommen. Diese ist aber um die Breite des Randes korrigiert. Meiner Meinung nach müsste dort der Wert von FNoteBook.Width genommen werden, da das FNoteBook geändert werden soll und dabei die Breite ja gleich sein soll.
Das System sollte ja überall gleich sein.

Genaugenommen solllte das auch für tpLeft und tpRigth gelten. dort wird IMHO auch geändert.

Auffallen tut das ganze deswegen, weil das Layout mit dem Frames wesentlich 'weicher' (=dynamisch änderbar) ist.

Code: Alles auswählen

procedure TTabControlNoteBookStrings.TabControlBoundsChange;
var
  NewHeight: LongInt;
  NewWidth: LongInt;
begin
  inherited TabControlBoundsChange;

  FNoteBook.TabPosition:=TabControl.TabPosition;

  case TabControl.TabPosition of
  tpTop,tpBottom:
    begin
      NewHeight:=TabControl.TabHeight;
      if NewHeight<=0 then
        NewHeight:=FNoteBook.GetMinimumTabHeight;
      NewHeight:=Min(TabControl.ClientHeight,NewHeight);
      if TabControl.TabPosition=tpTop then
        FNoteBook.SetBounds(0,0,TabControl.ClientWidth,NewHeight) // <-- hier
      else
        FNoteBook.SetBounds(0,TabControl.ClientHeight-NewHeight,
                            TabControl.ClientWidth,NewHeight);                       // <-- hier
    end;
Was sagt ihr dazu ?!

Edit: Issue: https://gitlab.com/freepascal.org/lazar ... sues/39478
Dateianhänge
layoutproblem.zip
(108.04 KiB) 80-mal heruntergeladen
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: ELayoutException - Wie debuggen ?

Beitrag von wp_xyz »

Ja, wenn ich in den gekennzeichneten Zeilen das TabControl.ClientWidth durch FNotebook.Width ersetze, gibt es keinen Absturz mehr. Keine Ahnung, welche Seiteneffekte das hat...

Du solltest das auf jeden Fall im Bug-Tracker melden, ich glaube, es gibt ein paar Leute, die sich um das kümmern könnten. Nimm aber bitte die Abhängigkeit von fpspreadsheet aus dem Beispiel-Projekt, das hat nichts mit dem Problem zu tun, und schafft für einen, der fpspreadsheet nicht hat, nur eine unnötige Hürde, sich mit dem Problem zu befassen.

P.S.
Sehe gerade, du hast es ja schon gemeldet. Gut. Den Lösungsvorschlag würde ich auch dazuschreiben, oder am besten gleich als Patch-Datei einreichen.

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6198
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: ELayoutException - Wie debuggen ?

Beitrag von af0815 »

Abhängigkeit zu fpspreadsheet entfernt und auch einen Kommentar zu eventuellen Lösung gegeben, nur das muss sich ein Wissender ansehen, damit es nicht zu Regressionen kommt.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6198
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: ELayoutException - Wie debuggen ?

Beitrag von af0815 »

Neue Info Martin hat es sich angesehen. Das Problem ist, das das Frame in Frame in eine Scrollbox gebunden ist und die Scrollbox die untergeordneten Element als Gruppe fragt, wie hättet ihr es gerne. Und das TabControl sagt halt, bitte um 2 px größer. -> Loop und Boom.

Nur wer der Adressat für den Fix ist , verstehe ich nicht. Irgendwie bekomme ich mit meinem englisch Verständnis das nicht auf die Reihe.

https://gitlab.com/freepascal.org/lazar ... _745368981

Wenn es an mich geht - so verstehe ich den Fix nicht, denn der wäre ja nicht allgemeingültig. Der nächste der ein Frame in eine Scrollbox einbaut, steht ja dann genauso auch den Schlauch. Vor allen weis das Frame in Frame ja nicht, wo sein endgültiger Bestimmungsort ist.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

PascalDragon
Beiträge: 825
Registriert: Mi 3. Jun 2020, 07:18
OS, Lazarus, FPC: L 2.0.8, FPC Trunk, OS Win/Linux
CPU-Target: Aarch64 bis Z80 ;)
Wohnort: München

Re: ELayoutException - Wie debuggen ?

Beitrag von PascalDragon »

af0815 hat geschrieben:
Mo 29. Nov 2021, 08:54
Nur wer der Adressat für den Fix ist , verstehe ich nicht. Irgendwie bekomme ich mit meinem englisch Verständnis das nicht auf die Reihe.

https://gitlab.com/freepascal.org/lazar ... _745368981
Das ist 'ne allgemeine Beschreibung wie es zu fixen wäre, sie ist nicht direkt an dich gerichtet.
FPC Compiler Entwickler

Antworten