Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Cross-Platform-Entwicklung (https://www.delphipraxis.net/91-cross-platform-entwicklung/)
-   -   TTimer unzuverlässig auf neueren Iphones (https://www.delphipraxis.net/207273-ttimer-unzuverlaessig-auf-neueren-iphones.html)

AuronTLG 9. Mär 2021 10:11

TTimer unzuverlässig auf neueren Iphones
 
Hallo,

ich habe ein seltsames Problem mit Timern auf neueren Iphones bei einer einfachen manuellen Popup-Konstruktion:
Eine Listbox hat ein Mousedown-Ereignis, was einen 500ms-Timer startet, sowie ein MouseUp-Ereignis, was ihn stoppt.
Geht der Timer durch, so wird ein Kontextmenü sichtbar gemacht, kommt das MouseUp vorher, wird der Timer gestoppt und das Ganze als Klick gewertet.

Das Problem ist, dass auf neueren Iphones (11er und 12er Reihe) der Zeitabstand zwischen Drücken und Erscheinen des Kontextmenüs unregelmäßig ist.
Manchmal erscheint es exakt nach 0,5 Sekunden, manchmal erst nach 5 Sekunden.

Kurios ist folgendes: Logge ich MouseDown und das Ende der OnTimer-Methode, so zeigt das Log jedes einzelne Mal einen Zeitabstand von 500 + 10-20 ms zwischen den beiden Punkten, obwohl des Erscheinen des Kontextmenüs teilweise deutlich länger gedauert hat.
Setze ich im OnTimer an diesselbe Stelle wie den Logeintrag eine einfache optische Änderung, so wie etwa das Ändern des Textes einer Schaltfläche, so erfolgt diese zeitgleich mit dem Anzeigen des Kontextmenüs, während das Log wie gehabt die korrekte Zeit anzeigt.

Auf nem Iphone X oder älteren Geräten funktioniert das Ganze ziemlich zuverlässig.
Kompiliert auf Delphi 10.4.1 mit einer 14.3 SDK.

Ich würde mal vermuten, dass das entweder ein optisches Aktualisierungsproblem oder ein Thread-Problem ist.

Hat irgendwer hier auch vergleichbare Timer-Probleme? Ansonsten wäre für mich auch eine alternative Konstruktion eine Lösung, mit der ich den Timer ersetzen könnte, den ich als Komponente sowieso nicht sonderlich mag. Vielleicht einen anonymen Thread mit Wait oder sowas... Hat jemand sich jemand vielleicht schonmal damit auseinandergesetzt?

Der schöne Günther 9. Mär 2021 10:36

AW: TTimer unzuverlässig auf neueren Iphones
 
Du sagst doch dass das OnTimer-Event zuverlässig 500 ms ± 20 ms ausgelöst wird. Da kann man dem Timer doch keine Vorwürfe machen? Ich hätte es eher auf das FireMonkey-Kontextmenü selbst geschoben. Ich habe ewig nichts mehr für iOS gemacht, aber spontan hätte ich gesagt dass die Hardware egal ist und die iOS-Version zählt. Ist die iOS-Version tatsächlich gleich?

TiGü 9. Mär 2021 10:36

AW: TTimer unzuverlässig auf neueren Iphones
 
So in der Art?

Delphi-Quellcode:
unit Unit1;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.Menus, FMX.Layouts, FMX.ListBox;

type
  TForm1 = class(TForm)
    ListBox1: TListBox;
    PopupMenu1: TPopupMenu;
    MenuItem1: TMenuItem;
    MenuItem2: TMenuItem;
    MenuItem3: TMenuItem;
    procedure ListBox1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Single);
    procedure ListBox1MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Single);
  private
    FCanShowPopupMenu: Boolean;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.fmx}


procedure TForm1.ListBox1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Single);
var
  Thread: TThread;
  ThreadProc: TProc;
begin
  FCanShowPopupMenu := True;

  ThreadProc := procedure
    var
      ThreadProcedure: TThreadProcedure;
    begin
      Sleep(500);

      ThreadProcedure := procedure
        begin
          if TThread.Current.ThreadID = MainThreadID then
          begin
            if FCanShowPopupMenu then
            begin
              Self.PopupMenu1.Popup(Screen.MousePos.X, Screen.MousePos.Y);
            end;
          end;
        end;

      TThread.Queue(nil, ThreadProcedure);
    end;

  Thread := TThread.CreateAnonymousThread(ThreadProc);
  Thread.Start;
end;

procedure TForm1.ListBox1MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Single);
begin
  FCanShowPopupMenu := False;
end;

end.

AuronTLG 9. Mär 2021 11:12

AW: TTimer unzuverlässig auf neueren Iphones
 
Ich habe mal die Konstruktion mit dem anonymen Thread implementiert, und siehe da: Haargenau dasselbe Problem, absolut kein Unterschied.

Ich würde dann wohl mal vermuten, dass das ein Thread-Problem ist, bei dem die Aufrufe nicht genau nach 500 ms wieder in den Hauptthread eingliedert werden können. Beim anonymen Thread wird das das TThread.Queue sein, beim TTimer etwas äquivalentes.

Der schöne Günther 9. Mär 2021 11:34

AW: TTimer unzuverlässig auf neueren Iphones
 
Ist das nicht genau der Punkt dass ein Timer immer im Hauptthread läuft? Wenn der schon richtig geloggt wird dann ist das Problem doch die Oberfläche (Firemonkey) und nicht so etwas wie Thread-Synchronisation.

AuronTLG 9. Mär 2021 11:38

AW: TTimer unzuverlässig auf neueren Iphones
 
Jupp, spricht einiges dafür, wie ich gerade feststelle:

Ich habe nochmal ein wenig rumprobiert, da ich diese Konstruktion nicht nur an einer Stelle verwende.

An einer anderen Stelle funktioniert haargenau diesselbe Konstruktion zuverlässig. Unterschied ist die auslösende Komponente, über die MouseDown/Up läuft.

Bei der Problemstelle ist die verwendete Komponente eine TMSFMXTreeView.

AuronTLG 9. Mär 2021 13:19

AW: TTimer unzuverlässig auf neueren Iphones
 
Jo, ist die Komponente, bzw vergleichbare Komponenten.
Lege ich die Ereignisse 1 zu 1 auf einen stinknormalen Button funktioniert es zuverlässig.
Der Timer ist tatsächlich unschuldig...

TurboMagic 9. Mär 2021 19:05

AW: TTimer unzuverlässig auf neueren Iphones
 
Das ist wohl jetzt ein Fall für das TMX Forum...


Alle Zeitangaben in WEZ +1. Es ist jetzt 04:40 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz