View Issue Details

IDProjectCategoryView StatusLast Update
0036127LazarusLCLpublic2020-09-19 10:56
ReporterJoeny Ang Assigned ToJuha Manninen  
PrioritynormalSeverityminorReproducibilityalways
Status resolvedResolutionfixed 
Platformx86_64OSArch Linux 
Product Version2.0.4 
Summary0036127: [Patch] TForm's bounds and restored bounds are inconsistent
DescriptionThe attached patch tries to fix the following issues:

When form is designed with WindowState=wsMaximized:
1. Restored dimension is wrong (related to 0027894, 0022771, 0027375)
2. Width/Height in OnShow() and OnActivate() events are wrong (related to 0021119)
     Under Delphi 3:
          - OnCreate(): design time restored width/height
          - OnShow() and OnActivate(): maximized width/height

When form's WindowsState=not maximized
3. Restored bounds in OnResize() and OnChangeBounds() events are wrong or not updated (related to 0032631)

Note: Expanded on the idea of Yuichiro Takahashi from Issue 0008576 to use Application.QueueAsyncCall() to "queue" the procedure to update the restored values, to the main event loop, thus delaying it until the form is properly moved or resized. The first calls to OnShow() and OnActivate() are also moved to this procedure so that querying Width/Height during these events will return the correct values.

Tested on GTK2 and Win32.
TagsNo tags attached.
Fixed in Revisionr61997, r62113, r63218, r63577, r63842, r63888
LazTarget-
WidgetsetGTK 2, Win32/Win64
Attached Files

Relationships

related to 0027894 closedJuha Manninen Lazarus TForm RestoredWidth and RestoredHeight updated incorrectly if window maximized under Gtk2 
related to 0022771 resolvedJuha Manninen Lazarus When FormStyle = wsMaximized, after restore Widht/Height have wrong values 
related to 0027375 resolvedJuha Manninen Lazarus If a Form is started with wsMaximized (set in OI), it does not restore to designed Size 
related to 0021119 resolvedZeljan Rikalo Lazarus When a form is started as wsMaximized height and width report design time values 
related to 0032631 resolvedJuha Manninen Packages "restoredLeft, restoredTop, restoredWidth, restoredHeight" of TForm returned wrong value 
related to 0008576 closedJuha Manninen Lazarus After Mini/Maximizing window 'RestoredLeft/Top' values changes to "unreal" values 
related to 0037647 closedJuha Manninen Lazarus It does not raise an OnShow event if the form is maximized and ... - since rev 63577 (changed from 62892) 
related to 0036877 closedZeljan Rikalo Lazarus LCL: Regression TCustomForm.OnActivate 
related to 0037467 resolvedJuha Manninen Lazarus Form Resize Not Firing Correctly 
related to 0037732 resolvedJuha Manninen Lazarus Win32: bad window behavior after Restore from minimized state 
related to 0037688 new Lazarus Form Resize, Controls sizing very slow 

Activities

Joeny Ang

2019-10-02 09:55

reporter  

tform-wrong-bounds-and-restored-bounds.patch (9,834 bytes)   
--- lcl/forms.pp
+++ lcl/forms.pp
@@ -490,6 +490,8 @@
     FRestoredHeight: integer;
     FShowInTaskbar: TShowInTaskbar;
     FWindowState: TWindowState;
+    FMovedCtr: Integer;
+    FIsFirstOnShow, FIsFirstOnActivate: Boolean;
     function GetClientHandle: HWND;
     function GetEffectiveShowInTaskBar: TShowInTaskBar;
     function GetMonitor: TMonitor;
@@ -590,7 +592,6 @@
     procedure VisibleChanged; override;
     procedure WndProc(var TheMessage : TLMessage); override;
     function VisibleIsStored: boolean;
-    procedure DoSendBoundsToInterface; override;
     procedure DoAutoSize; override;
     procedure SetAutoSize(Value: Boolean); override;
     procedure SetAutoScroll(Value: Boolean); override;
@@ -649,7 +650,8 @@
     function CanFocus: Boolean; override;
     procedure SetFocus; override;
     function SetFocusedControl(Control: TWinControl): Boolean ; virtual;
-    procedure SetRestoredBounds(ALeft, ATop, AWidth, AHeight: integer);
+    procedure SetRestoredBounds(ALeft, ATop, AWidth, AHeight: integer; const
+                                ADefaultPosition: Boolean = False);
     procedure Show;
 
     function ShowModal: Integer; virtual;
--- lcl/include/customform.inc
+++ lcl/include/customform.inc
@@ -16,6 +16,8 @@
 
 const
   BorderStylesAllowAutoScroll = [bsSizeable, bsSizeToolWin];
+  ShowCommands: array[TWindowState] of Integer =
+    (SW_SHOWNORMAL, SW_MINIMIZE, SW_SHOWMAXIMIZED, SW_SHOWFULLSCREEN);
 
 { TCustomForm }
 
@@ -68,93 +70,10 @@
   Gets called after the construction of the object
  ------------------------------------------------------------------------------}
 procedure TCustomForm.AfterConstruction;
-var
-  NewWidth, NewHeight: Integer;
-  OldWindowState: TWindowState;
-
-  procedure ChangeFormDimensions(AIsBeforeOnCreate: Boolean);
-  begin
-    if (WindowState = wsMaximized) and (FormStyle <> fsMDIChild) then
-    begin
-      {$IFDEF DEBUG_SM_LCLMAXIMIZED}
-      DebugLn('TCustomForm.AfterConstruction: SM_CYCAPTION ',
-        dbgs(GetSystemMetrics(SM_CYCAPTION)),
-      ' SM_CYSIZEFRAME ',dbgs(GetSystemMetrics(SM_CYSIZEFRAME)),
-      ' SM_CXMAXIMIZED ',dbgs(GetSystemMetrics(SM_CXMAXIMIZED)),
-      ' SM_CYMAXIMIZED ',dbgs(GetSystemMetrics(SM_CYMAXIMIZED)),
-      ' SM_LCLMAXIMIZEDHEIGHT ',dbgs(GetSystemMetrics(SM_LCLMAXIMIZEDHEIGHT)),
-      ' SM_LCLMAXIMIZEDWIDTH ',dbgs(GetSystemMetrics(SM_LCLMAXIMIZEDWIDTH)),
-      ' AIsBeforeOnCreate ',dbgs(AIsBeforeOnCreate));
-      {$ENDIF}
-
-      if (BorderStyle <> bsNone) and (FormStyle <> fsSplash) then
-      begin
-        NewHeight := GetSystemMetrics(SM_LCLMAXIMIZEDHEIGHT);
-        NewWidth := GetSystemMetrics(SM_LCLMAXIMIZEDWIDTH);
-        // if some ws does not implement this then provide normal metrics.
-        if NewHeight <= 0 then
-          NewHeight := GetSystemMetrics(SM_CYMAXIMIZED);
-        if NewWidth <= 0 then
-          NewHeight := GetSystemMetrics(SM_CXMAXIMIZED);
-      end else
-      begin
-        NewHeight := GetSystemMetrics(SM_CYMAXIMIZED);
-        NewWidth := GetSystemMetrics(SM_CXMAXIMIZED);
-      end;
-
-      if Constraints.MaxWidth > 0 then
-        NewWidth := Min(Constraints.MaxWidth, NewWidth);
-      if Constraints.MaxHeight > 0 then
-        NewHeight := Min(Constraints.MaxHeight, NewHeight);
-
-      // for unknown reasons on some systems SM_*MAXIMIZED* system metrics
-      // (tested xubuntu,64bits) return 0 or negative values, in this case
-      // a maximized window is expected to have at least WorkArea width/height.
-      //
-      // Reproduced again under Debian Wheezy.
-      // mistery solved, it ocurrs under gtk2/64-bit, fixed at the place
-      // the checks doesn't hurt though
-      //
-      // see bug #21634
-      if NewWidth<=0 then
-        NewWidth := Screen.WorkAreaWidth;
-      if NewHeight<=0 then
-        NewHeight := Screen.WorkAreaHeight;
-
-      if NewWidth>0 then
-        Width := NewWidth;
-      if NewHeight>0 then
-        Height := NewHeight;
-    end;
-
-    if (WindowState = wsFullScreen) and (FormStyle <> fsMDIChild) then
-    begin
-      NewWidth := LCLIntf.GetSystemMetrics(SM_CXFULLSCREEN);
-      NewHeight := LCLIntf.GetSystemMetrics(SM_CYFULLSCREEN);
-      if Constraints.MaxWidth > 0 then
-        NewWidth := Min(Constraints.MaxWidth, NewWidth);
-      if Constraints.MaxHeight > 0 then
-        NewHeight := Min(Constraints.MaxHeight, NewHeight);
-      Width := NewWidth;
-      Height := NewHeight;
-    end;
-  end;
-begin
-  // issue #21119, prepare maximized or fullscreen form to accurate dimensions.
-  // we avoid flickering also in this case.
-  if not (csDesigning in ComponentState) then
-    ChangeFormDimensions(True);
-
-  OldWindowState := WindowState;
+begin
+  SetRestoredBounds(Left, Top, Width, Height, True);
+
   DoCreate;
-
-  // if we change WindowState in constructor and handle isn't allocated
-  // then change our dimensions to accurate one
-  if not (csDesigning in ComponentState) and not HandleAllocated and
-    (OldWindowState <> WindowState) and
-    not (OldWindowState in [wsMaximized, wsFullScreen]) and
-    (WindowState in [wsMaximized, wsFullScreen]) then
-      ChangeFormDimensions(False);
 
   EndFormUpdate; // the BeginFormUpdate is in CreateNew
   inherited AfterConstruction;
@@ -677,6 +596,9 @@
  ------------------------------------------------------------------------------}
 procedure TCustomForm.Activate;
 begin
+  if FIsFirstOnActivate and (WindowState = wsMaximized) then
+    Exit;
+  FIsFirstOnActivate := False;
   if Assigned(FOnActivate) then FOnActivate(Self);
 end;
 
@@ -732,28 +654,47 @@
   end;
 
   inherited WMSize(Message);
-
-  if (Message.SizeType and not SIZE_SourceIsInterface) = SIZE_RESTORED then
-  begin
-    FRestoredWidth := Width;
-    FRestoredHeight := Height;
-    //DebugLn('[TCustomForm.WMSize] saving restored bounds ',DbgSName(Self),' ',dbgs(FRestoredWidth),'x',dbgs(FRestoredHeight));
-  end;
+  Inc(FMovedCtr);
+  Application.QueueAsyncCall(@Moved, 1);  // 1 = resized
 end;
 
 procedure TCustomForm.WMMove(var Message: TLMMove);
 begin
   inherited WMMove(Message);
-  Application.QueueAsyncCall(@Moved, 0);
+  Inc(FMovedCtr);
+  Application.QueueAsyncCall(@Moved, 0);  // 0 = moved
 end;
 
 procedure TCustomForm.Moved(Data: PtrInt);
 begin
+  Dec(FMovedCtr);
+  if FMovedCtr > 0 then
+    Exit;
   if WindowState = wsNormal then
   begin
-    FRestoredLeft := Left;
-    FRestoredTop := Top;
-  end;
+    if Data = 0 then
+      begin
+        FRestoredLeft := Left;
+        FRestoredTop := Top;
+      end
+    else
+      begin
+        FRestoredWidth := Width;
+        FRestoredHeight := Height;
+        DoOnResize;
+      end;
+    DoOnChangeBounds;
+  end;
+  if FIsFirstOnShow then
+    begin
+      FIsFirstOnShow := False;
+      DoShow;
+    end;
+  if FIsFirstOnActivate then
+    begin
+      FIsFirstOnActivate := False;
+      Activate;
+    end;
 end;
 
 procedure TCustomForm.WMWindowPosChanged(var Message: TLMWindowPosChanged);
@@ -1016,6 +957,9 @@
  ------------------------------------------------------------------------------}
 procedure TCustomForm.DoShow;
 begin
+  if FIsFirstOnShow and (WindowState = wsMaximized) then
+    Exit;
+  FIsFirstOnShow := False;
   if Assigned(FOnShow) then FOnShow(Self);
 end;
 
@@ -1338,7 +1282,7 @@
           AForm := TCustomForm(Owner)
         else
           AForm := Application.MainForm;
-        if (Self <> AForm) then
+        if (Self <> AForm) and Assigned(AForm) then
         begin
           if FormStyle = fsMDIChild then
           begin
@@ -1487,18 +1431,6 @@
   Result := (Color <> {$ifdef UseCLDefault}clDefault{$else}clBtnFace{$endif});
 end;
 
-procedure TCustomForm.DoSendBoundsToInterface;
-begin
-  inherited DoSendBoundsToInterface;
-  if WindowState = wsNormal then
-  begin
-    FRestoredLeft := Left;
-    FRestoredTop := Top;
-    FRestoredWidth := Width;
-    FRestoredHeight := Height;
-  end;
-end;
-
 procedure TCustomForm.GetPreferredSize(var PreferredWidth,
   PreferredHeight: integer; Raw: boolean; WithThemeSpace: boolean);
 begin
@@ -1851,9 +1783,6 @@
        TCustomForm SetWindowState
 ------------------------------------------------------------------------------}
 procedure TCustomForm.SetWindowState(Value : TWindowState);
-const
-  ShowCommands: array[TWindowState] of Integer =
-    (SW_SHOWNORMAL, SW_MINIMIZE, SW_SHOWMAXIMIZED, SW_SHOWFULLSCREEN);
 begin
   if FWindowState <> Value then
   begin
@@ -1864,7 +1793,8 @@
   end;
 end;
 
-procedure TCustomForm.SetRestoredBounds(ALeft, ATop, AWidth, AHeight: integer);
+procedure TCustomForm.SetRestoredBounds(ALeft, ATop, AWidth, AHeight: integer;
+  const ADefaultPosition: Boolean);
 var
   prevWindowState: TWindowState;
 begin
@@ -1874,7 +1804,14 @@
   prevWindowState := WindowState;
   WindowState := wsNormal;
   SetBounds(ALeft, ATop, AWidth, AHeight);
+  // override
+  if ADefaultPosition then
+    MoveToDefaultPosition;
   WindowState := prevWindowState;
+  FRestoredLeft := Left;
+  FRestoredTop := Top;
+  FRestoredWidth := Width;
+  FRestoredHeight := Height;
 end;
 
 procedure TCustomForm.SetScaled(const AScaled: Boolean);
@@ -2047,6 +1984,9 @@
 ------------------------------------------------------------------------------}
 constructor TCustomForm.Create(AOwner: TComponent);
 begin
+  FMovedCtr := 0;
+  FIsFirstOnShow := True;
+  FIsFirstOnActivate := True;
   GlobalNameSpace.BeginWrite;
   try
     CreateNew(AOwner, 1); // this calls BeginFormUpdate, which is ended in AfterConstruction
@@ -2328,6 +2268,9 @@
       Width, MulDiv(Width, Monitor.PixelsPerInch, PixelsPerInch));
 
   Visible := True;
+  { wxMaximized secondary forms are not being shown maximized }
+  if (not (csDesigning in ComponentState)) and Showing then
+    ShowWindow(Handle, ShowCommands[WindowState]);
   BringToFront;
 end;
 

tform-restoredbounds.zip (133,630 bytes)

Joeny Ang

2019-10-03 03:52

reporter   ~0118263

Updated the patch (v2) with the following fixes:
- because the queued procedure is shared between WMMove and WMSize events, an event is sometimes missed because duplicate calls are discarded.
tform-wrong-bounds-and-restored-bounds-v2.patch (10,758 bytes)   
--- lcl/forms.pp
+++ lcl/forms.pp
@@ -490,6 +490,9 @@
     FRestoredHeight: integer;
     FShowInTaskbar: TShowInTaskbar;
     FWindowState: TWindowState;
+    FDelayedEventCtr: Integer;
+    FDelayedWMMove, FDelayedWMSize: Boolean;
+    FIsFirstOnShow, FIsFirstOnActivate: Boolean;
     function GetClientHandle: HWND;
     function GetEffectiveShowInTaskBar: TShowInTaskBar;
     function GetMonitor: TMonitor;
@@ -499,7 +502,7 @@
     procedure CloseModal;
     procedure FreeIconHandles;
     procedure IconChanged(Sender: TObject);
-    procedure Moved(Data: PtrInt);
+    procedure DelayedEvent(Data: PtrInt);
     procedure SetActive(AValue: Boolean);
     procedure SetActiveControl(AWinControl: TWinControl);
     procedure SetActiveDefaultControl(AControl: TControl);
@@ -590,7 +593,6 @@
     procedure VisibleChanged; override;
     procedure WndProc(var TheMessage : TLMessage); override;
     function VisibleIsStored: boolean;
-    procedure DoSendBoundsToInterface; override;
     procedure DoAutoSize; override;
     procedure SetAutoSize(Value: Boolean); override;
     procedure SetAutoScroll(Value: Boolean); override;
@@ -649,7 +651,8 @@
     function CanFocus: Boolean; override;
     procedure SetFocus; override;
     function SetFocusedControl(Control: TWinControl): Boolean ; virtual;
-    procedure SetRestoredBounds(ALeft, ATop, AWidth, AHeight: integer);
+    procedure SetRestoredBounds(ALeft, ATop, AWidth, AHeight: integer; const
+                                ADefaultPosition: Boolean = False);
     procedure Show;
 
     function ShowModal: Integer; virtual;
--- lcl/include/customform.inc
+++ lcl/include/customform.inc
@@ -16,6 +16,8 @@
 
 const
   BorderStylesAllowAutoScroll = [bsSizeable, bsSizeToolWin];
+  ShowCommands: array[TWindowState] of Integer =
+    (SW_SHOWNORMAL, SW_MINIMIZE, SW_SHOWMAXIMIZED, SW_SHOWFULLSCREEN);
 
 { TCustomForm }
 
@@ -68,93 +70,10 @@
   Gets called after the construction of the object
  ------------------------------------------------------------------------------}
 procedure TCustomForm.AfterConstruction;
-var
-  NewWidth, NewHeight: Integer;
-  OldWindowState: TWindowState;
-
-  procedure ChangeFormDimensions(AIsBeforeOnCreate: Boolean);
-  begin
-    if (WindowState = wsMaximized) and (FormStyle <> fsMDIChild) then
-    begin
-      {$IFDEF DEBUG_SM_LCLMAXIMIZED}
-      DebugLn('TCustomForm.AfterConstruction: SM_CYCAPTION ',
-        dbgs(GetSystemMetrics(SM_CYCAPTION)),
-      ' SM_CYSIZEFRAME ',dbgs(GetSystemMetrics(SM_CYSIZEFRAME)),
-      ' SM_CXMAXIMIZED ',dbgs(GetSystemMetrics(SM_CXMAXIMIZED)),
-      ' SM_CYMAXIMIZED ',dbgs(GetSystemMetrics(SM_CYMAXIMIZED)),
-      ' SM_LCLMAXIMIZEDHEIGHT ',dbgs(GetSystemMetrics(SM_LCLMAXIMIZEDHEIGHT)),
-      ' SM_LCLMAXIMIZEDWIDTH ',dbgs(GetSystemMetrics(SM_LCLMAXIMIZEDWIDTH)),
-      ' AIsBeforeOnCreate ',dbgs(AIsBeforeOnCreate));
-      {$ENDIF}
-
-      if (BorderStyle <> bsNone) and (FormStyle <> fsSplash) then
-      begin
-        NewHeight := GetSystemMetrics(SM_LCLMAXIMIZEDHEIGHT);
-        NewWidth := GetSystemMetrics(SM_LCLMAXIMIZEDWIDTH);
-        // if some ws does not implement this then provide normal metrics.
-        if NewHeight <= 0 then
-          NewHeight := GetSystemMetrics(SM_CYMAXIMIZED);
-        if NewWidth <= 0 then
-          NewHeight := GetSystemMetrics(SM_CXMAXIMIZED);
-      end else
-      begin
-        NewHeight := GetSystemMetrics(SM_CYMAXIMIZED);
-        NewWidth := GetSystemMetrics(SM_CXMAXIMIZED);
-      end;
-
-      if Constraints.MaxWidth > 0 then
-        NewWidth := Min(Constraints.MaxWidth, NewWidth);
-      if Constraints.MaxHeight > 0 then
-        NewHeight := Min(Constraints.MaxHeight, NewHeight);
-
-      // for unknown reasons on some systems SM_*MAXIMIZED* system metrics
-      // (tested xubuntu,64bits) return 0 or negative values, in this case
-      // a maximized window is expected to have at least WorkArea width/height.
-      //
-      // Reproduced again under Debian Wheezy.
-      // mistery solved, it ocurrs under gtk2/64-bit, fixed at the place
-      // the checks doesn't hurt though
-      //
-      // see bug #21634
-      if NewWidth<=0 then
-        NewWidth := Screen.WorkAreaWidth;
-      if NewHeight<=0 then
-        NewHeight := Screen.WorkAreaHeight;
-
-      if NewWidth>0 then
-        Width := NewWidth;
-      if NewHeight>0 then
-        Height := NewHeight;
-    end;
-
-    if (WindowState = wsFullScreen) and (FormStyle <> fsMDIChild) then
-    begin
-      NewWidth := LCLIntf.GetSystemMetrics(SM_CXFULLSCREEN);
-      NewHeight := LCLIntf.GetSystemMetrics(SM_CYFULLSCREEN);
-      if Constraints.MaxWidth > 0 then
-        NewWidth := Min(Constraints.MaxWidth, NewWidth);
-      if Constraints.MaxHeight > 0 then
-        NewHeight := Min(Constraints.MaxHeight, NewHeight);
-      Width := NewWidth;
-      Height := NewHeight;
-    end;
-  end;
-begin
-  // issue #21119, prepare maximized or fullscreen form to accurate dimensions.
-  // we avoid flickering also in this case.
-  if not (csDesigning in ComponentState) then
-    ChangeFormDimensions(True);
-
-  OldWindowState := WindowState;
+begin
+  SetRestoredBounds(Left, Top, Width, Height, True);
+
   DoCreate;
-
-  // if we change WindowState in constructor and handle isn't allocated
-  // then change our dimensions to accurate one
-  if not (csDesigning in ComponentState) and not HandleAllocated and
-    (OldWindowState <> WindowState) and
-    not (OldWindowState in [wsMaximized, wsFullScreen]) and
-    (WindowState in [wsMaximized, wsFullScreen]) then
-      ChangeFormDimensions(False);
 
   EndFormUpdate; // the BeginFormUpdate is in CreateNew
   inherited AfterConstruction;
@@ -677,6 +596,9 @@
  ------------------------------------------------------------------------------}
 procedure TCustomForm.Activate;
 begin
+  if FIsFirstOnActivate and (WindowState = wsMaximized) then
+    Exit;
+  FIsFirstOnActivate := False;
   if Assigned(FOnActivate) then FOnActivate(Self);
 end;
 
@@ -733,27 +655,55 @@
 
   inherited WMSize(Message);
 
-  if (Message.SizeType and not SIZE_SourceIsInterface) = SIZE_RESTORED then
-  begin
-    FRestoredWidth := Width;
-    FRestoredHeight := Height;
-    //DebugLn('[TCustomForm.WMSize] saving restored bounds ',DbgSName(Self),' ',dbgs(FRestoredWidth),'x',dbgs(FRestoredHeight));
-  end;
+  FDelayedWMSize := True;
+  Inc(FDelayedEventCtr);
+  Application.QueueAsyncCall(@DelayedEvent, 0);
 end;
 
 procedure TCustomForm.WMMove(var Message: TLMMove);
 begin
   inherited WMMove(Message);
-  Application.QueueAsyncCall(@Moved, 0);
-end;
-
-procedure TCustomForm.Moved(Data: PtrInt);
-begin
+
+  FDelayedWMMove := True;
+  Inc(FDelayedEventCtr);
+  Application.QueueAsyncCall(@DelayedEvent, 0);
+end;
+
+procedure TCustomForm.DelayedEvent(Data: PtrInt);
+begin
+  { discard duplicate calls, accept last call only }
+  Dec(FDelayedEventCtr);
+  if FDelayedEventCtr > 0 then
+    Exit;
+  { update restored bounds }
   if WindowState = wsNormal then
-  begin
-    FRestoredLeft := Left;
-    FRestoredTop := Top;
-  end;
+    begin
+      if FDelayedWMMove then
+        begin
+          FRestoredLeft := Left;
+          FRestoredTop := Top;
+        end;
+      if FDelayedWMSize then
+        begin
+          FRestoredWidth := Width;
+          FRestoredHeight := Height;
+          DoOnResize;     // delayed onResize()
+        end;
+      DoOnChangeBounds;     // delayed onChangeBounds()
+    end;
+  FDelayedWMMove := False;
+  FDelayedWMSize := False;
+  { call onShow() or onActivate() for the first time }
+  if FIsFirstOnShow then
+    begin
+      FIsFirstOnShow := False;
+      DoShow;
+    end;
+  if FIsFirstOnActivate then
+    begin
+      FIsFirstOnActivate := False;
+      Activate;
+    end;
 end;
 
 procedure TCustomForm.WMWindowPosChanged(var Message: TLMWindowPosChanged);
@@ -1016,6 +966,9 @@
  ------------------------------------------------------------------------------}
 procedure TCustomForm.DoShow;
 begin
+  if FIsFirstOnShow and (WindowState = wsMaximized) then
+    Exit;
+  FIsFirstOnShow := False;
   if Assigned(FOnShow) then FOnShow(Self);
 end;
 
@@ -1338,7 +1291,7 @@
           AForm := TCustomForm(Owner)
         else
           AForm := Application.MainForm;
-        if (Self <> AForm) then
+        if (Self <> AForm) and Assigned(AForm) then
         begin
           if FormStyle = fsMDIChild then
           begin
@@ -1487,18 +1440,6 @@
   Result := (Color <> {$ifdef UseCLDefault}clDefault{$else}clBtnFace{$endif});
 end;
 
-procedure TCustomForm.DoSendBoundsToInterface;
-begin
-  inherited DoSendBoundsToInterface;
-  if WindowState = wsNormal then
-  begin
-    FRestoredLeft := Left;
-    FRestoredTop := Top;
-    FRestoredWidth := Width;
-    FRestoredHeight := Height;
-  end;
-end;
-
 procedure TCustomForm.GetPreferredSize(var PreferredWidth,
   PreferredHeight: integer; Raw: boolean; WithThemeSpace: boolean);
 begin
@@ -1851,9 +1792,6 @@
        TCustomForm SetWindowState
 ------------------------------------------------------------------------------}
 procedure TCustomForm.SetWindowState(Value : TWindowState);
-const
-  ShowCommands: array[TWindowState] of Integer =
-    (SW_SHOWNORMAL, SW_MINIMIZE, SW_SHOWMAXIMIZED, SW_SHOWFULLSCREEN);
 begin
   if FWindowState <> Value then
   begin
@@ -1864,7 +1802,8 @@
   end;
 end;
 
-procedure TCustomForm.SetRestoredBounds(ALeft, ATop, AWidth, AHeight: integer);
+procedure TCustomForm.SetRestoredBounds(ALeft, ATop, AWidth, AHeight: integer;
+  const ADefaultPosition: Boolean);
 var
   prevWindowState: TWindowState;
 begin
@@ -1874,7 +1813,14 @@
   prevWindowState := WindowState;
   WindowState := wsNormal;
   SetBounds(ALeft, ATop, AWidth, AHeight);
+  // override
+  if ADefaultPosition then
+    MoveToDefaultPosition;
   WindowState := prevWindowState;
+  FRestoredLeft := Left;
+  FRestoredTop := Top;
+  FRestoredWidth := Width;
+  FRestoredHeight := Height;
 end;
 
 procedure TCustomForm.SetScaled(const AScaled: Boolean);
@@ -2047,6 +1993,11 @@
 ------------------------------------------------------------------------------}
 constructor TCustomForm.Create(AOwner: TComponent);
 begin
+  FDelayedEventCtr := 0;
+  FDelayedWMMove := False;
+  FDelayedWMSize := False;
+  FIsFirstOnShow := True;
+  FIsFirstOnActivate := True;
   GlobalNameSpace.BeginWrite;
   try
     CreateNew(AOwner, 1); // this calls BeginFormUpdate, which is ended in AfterConstruction
@@ -2328,6 +2279,9 @@
       Width, MulDiv(Width, Monitor.PixelsPerInch, PixelsPerInch));
 
   Visible := True;
+  { wxMaximized secondary forms are not being shown maximized }
+  if (not (csDesigning in ComponentState)) and Showing then
+    ShowWindow(Handle, ShowCommands[WindowState]);
   BringToFront;
 end;
 

Juha Manninen

2019-10-03 16:01

developer   ~0118278

Interesting! How many of the related issues this would fix?
I think this should be applied and tested in trunk.

Juha Manninen

2019-10-05 22:28

developer   ~0118358

I applied the patch in r61997 for everybody to test. Let's see if somebody finds bugs in it.

Joeny Ang

2019-10-07 08:00

reporter  

delayedevent-wait-for-wmsize-before-onshow-onactivate.patch (922 bytes)   
--- lcl/include/customform.inc
+++ lcl/include/customform.inc
@@ -691,19 +691,22 @@
         end;
       DoOnChangeBounds;     // delayed onChangeBounds()
     end;
+  { call onShow() or onActivate() for the first time, after first WMSize }
+  if FDelayedWMSize then
+    begin
+      if FIsFirstOnShow then
+        begin
+          FIsFirstOnShow := False;
+          DoShow;
+        end;
+      if FIsFirstOnActivate then
+        begin
+          FIsFirstOnActivate := False;
+          Activate;
+        end;
+    end;
   FDelayedWMMove := False;
   FDelayedWMSize := False;
-  { call onShow() or onActivate() for the first time }
-  if FIsFirstOnShow then
-    begin
-      FIsFirstOnShow := False;
-      DoShow;
-    end;
-  if FIsFirstOnActivate then
-    begin
-      FIsFirstOnActivate := False;
-      Activate;
-    end;
 end;
 
 procedure TCustomForm.WMWindowPosChanged(var Message: TLMWindowPosChanged);

Joeny Ang

2019-10-07 08:00

reporter   ~0118386

Another one :)

GTK2 only:
When a form is designed so as part of it is clipped off the screen, and WindowState=wsMaximized, width and height during onShow()/onActivate() is wrong.
Reason: After creation (?), the window manager automatically moves the form so that the whole form is visible. This will trigger WMMove() events, thus triggering the delayed onShow()/onActivate() even before the form is maxmimized.
Solution is to wait for the first WMSize() before triggering onShow()/onActivate().

Apply patch after the v2 patch.

Juha Manninen

2019-10-25 00:37

developer   ~0118793

I applied the new patch in r62113. Thanks. Please test everybody.

Juha Manninen

2020-03-16 19:29

developer   ~0121628

Resolving.
Thank you Joeny Ang for the patches.

Michl

2020-05-24 15:56

developer   ~0123037

Last edited: 2020-05-24 17:33

View 3 revisions

At least it breaks the usage of SpartaDockedFormEditor. After revision 61997 it isn't possible to change the bounds of a form anymore.

Too bad, just Windows seems to be affected. Just tried GTK2 and QT, both are working fine.

I'll try to look at it.

Michl

2020-05-25 15:17

developer   ~0123059

I fixed the problem with SpartaDockedFormEditor in revision 63218

Michl

2020-05-25 21:05

developer   ~0123062

Last edited: 2020-05-25 21:08

View 3 revisions

I have to reopen the issue. I could fix one problem with SpartaDockedFormEditor, but there is a other one, what can't be fixed there. If there are more than one form opened and resized, the frame got corrupted. Before I can search for the problem, one main problem has to be fixed:

After the revision 61997, OnChangeBounds of a form is called twice. See added project TestChangeBoundsEvent.zip. (tested on Windows 7)

Joeny Ang

2020-07-15 10:26

reporter   ~0124030

Last edited: 2020-07-15 10:27

View 2 revisions

Changes made by this patch:
  - fixed sequence of events (based on Delphi 3... create, show, activate, resize)
  - OnResize() and OnChangeBounds() are being called twice
      :: moved code queueing delayed events to overriden DoOnResize() and DoOnChangeBounds()
  - removed TCustomForm.WMMove()
  - added check for wsFullScreen in TCustomForm.Activate() and TCustomForm.DoShow()
  - renamed some variables
fix-duplicate-onresize-onchangebounds.patch (4,523 bytes)   
--- lcl/forms.pp
+++ lcl/forms.pp
@@ -491,7 +491,7 @@
     FShowInTaskbar: TShowInTaskbar;
     FWindowState: TWindowState;
     FDelayedEventCtr: Integer;
-    FDelayedWMMove, FDelayedWMSize: Boolean;
+    FDelayedOnChangeBounds, FDelayedOnResize: Boolean;
     FIsFirstOnShow, FIsFirstOnActivate: Boolean;
     function GetClientHandle: HWND;
     function GetEffectiveShowInTaskBar: TShowInTaskBar;
@@ -535,7 +535,6 @@
     procedure WMActivate(var Message : TLMActivate); message LM_ACTIVATE;
     procedure WMCloseQuery(var message: TLMessage); message LM_CLOSEQUERY;
     procedure WMHelp(var Message: TLMHelp); message LM_HELP;
-    procedure WMMove(var Message: TLMMove); message LM_MOVE;
     procedure WMShowWindow(var message: TLMShowWindow); message LM_SHOWWINDOW;
     procedure WMSize(var message: TLMSize); message LM_Size;
     procedure WMWindowPosChanged(var Message: TLMWindowPosChanged); message LM_WINDOWPOSCHANGED;
@@ -581,6 +580,8 @@
     procedure Resizing(State: TWindowState); override;
     procedure CalculatePreferredSize(var PreferredWidth,
            PreferredHeight: integer; WithThemeSpace: Boolean); override;
+    procedure DoOnResize; override;
+    procedure DoOnChangeBounds; override;
     procedure SetZOrder(Topmost: Boolean); override;
     procedure SetParent(NewParent: TWinControl); override;
     procedure MoveToDefaultPosition; virtual;
--- lcl/include/customform.inc
+++ lcl/include/customform.inc
@@ -604,7 +604,7 @@
  ------------------------------------------------------------------------------}
 procedure TCustomForm.Activate;
 begin
-  if FIsFirstOnActivate and (WindowState = wsMaximized) then
+  if FIsFirstOnActivate and (WindowState in [wsMaximized, wsFullScreen]) then
     Exit;
   FIsFirstOnActivate := False;
   if Assigned(FOnActivate) then FOnActivate(Self);
@@ -662,22 +662,23 @@
   end;
 
   inherited WMSize(Message);
-
+end;
+
+procedure TCustomForm.DoOnResize;
+begin
   if not (csDestroying in ComponentState) then
   begin
-    FDelayedWMSize := True;
+    FDelayedOnResize := True;
     Inc(FDelayedEventCtr);
     Application.QueueAsyncCall(@DelayedEvent, 0);
   end;
 end;
 
-procedure TCustomForm.WMMove(var Message: TLMMove);
-begin
-  inherited WMMove(Message);
-
+procedure TCustomForm.DoOnChangeBounds;
+begin
   if not (csDestroying in ComponentState) then
   begin
-    FDelayedWMMove := True;
+    FDelayedOnChangeBounds := True;
     Inc(FDelayedEventCtr);
     Application.QueueAsyncCall(@DelayedEvent, 0);
   end;
@@ -692,21 +693,20 @@
   { update restored bounds }
   if WindowState = wsNormal then
     begin
-      if FDelayedWMMove then
+      if FDelayedOnChangeBounds then
         begin
           FRestoredLeft := Left;
           FRestoredTop := Top;
         end;
-      if FDelayedWMSize then
+      if FDelayedOnResize then
         begin
           FRestoredWidth := Width;
           FRestoredHeight := Height;
-          DoOnResize;     // delayed onResize()
         end;
-      DoOnChangeBounds;     // delayed onChangeBounds()
-    end;
-  { call onShow() or onActivate() for the first time, after first WMSize }
-  if FDelayedWMSize then
+    end;
+  { call onShow() or onActivate() for the first time, after first OnResize()
+    and OnChangeBounds() }
+  if FDelayedOnResize and FDelayedOnChangeBounds then
     begin
       if FIsFirstOnShow then
         begin
@@ -720,8 +720,14 @@
             Activate;
         end;
     end;
-  FDelayedWMMove := False;
-  FDelayedWMSize := False;
+  { delayed onResize() }
+  if FDelayedOnResize then
+    inherited DoOnResize;
+  { delayed onChangeBounds() }
+  if FDelayedOnResize or FDelayedOnChangeBounds then
+    inherited DoOnChangeBounds;
+  FDelayedOnChangeBounds := False;
+  FDelayedOnResize := False;
 end;
 
 procedure TCustomForm.WMWindowPosChanged(var Message: TLMWindowPosChanged);
@@ -992,7 +998,7 @@
  ------------------------------------------------------------------------------}
 procedure TCustomForm.DoShow;
 begin
-  if FIsFirstOnShow and (WindowState = wsMaximized) then
+  if FIsFirstOnShow and (WindowState in [wsMaximized, wsFullScreen]) then
     Exit;
   FIsFirstOnShow := False;
   if Assigned(FOnShow) then FOnShow(Self);
@@ -2020,8 +2026,8 @@
 constructor TCustomForm.Create(AOwner: TComponent);
 begin
   FDelayedEventCtr := 0;
-  FDelayedWMMove := False;
-  FDelayedWMSize := False;
+  FDelayedOnChangeBounds := False;
+  FDelayedOnResize := False;
   FIsFirstOnShow := True;
   FIsFirstOnActivate := True;
   GlobalNameSpace.BeginWrite;

Juha Manninen

2020-07-17 01:01

developer   ~0124110

Thanks for the patch. I applied it in r63577.
Michl and others, please test.

Juha Manninen

2020-07-22 19:35

developer   ~0124233

No complaints. I guess this is fixed now. Resolving...

Juha Manninen

2020-08-26 11:12

developer   ~0125129

Last edited: 2020-08-26 11:13

View 2 revisions

r63577 caused a regression, see the related issue 0037467.
How to fix it?

BrunoK

2020-08-26 15:44

reporter   ~0125133

In my trunk I reverted to r62745.

Reason : Unit2.Form2 of example has Position = poMainFormCenter. I would expect that when restoring Form2 from initial wsMaximized to wsNomal the first time, it would place form2 at poMainFormCenter.
Afterwards, the new position of the modal form2 goes tracks the the last size/position.

Failing event FormResize beeing tracked is no good.

Also avoiding excessive messages in DelayedEvent seems reasonabéy neat in its currrent state.

Juha Manninen

2020-08-26 21:45

developer   ~0125143

How is r62745 related to this one? It says:
 "LCL: implement MDI for win32. Issue 36582, based on patch by Kostas Michalopoulos, attempt 2"

Paweł Dmitruk

2020-08-27 11:24

reporter   ~0125150

Juha: https://bugs.freepascal.org/view.php?id=37647

BrunoK

2020-08-27 11:54

reporter   ~0125151

Last edited: 2020-08-27 12:09

View 2 revisions

@Juha Manninen 2020-08-26 21:45

I picked up the lcl\forms.pp and lcl\include\customform.inc from r62745 and replaced the trunk r63577 version of these files in my installation.

At r62745 these two files seem to be OK . Issue 0037467 does not show with this version.

The logic of the various resizing events are a bit dispersed but still usable, I remember that in Delphi [ed. BDS 2007] BDS 2006 I had already difficulties figuring out how those things worked.

Here after a modified Unit2 from TestChangeBoundsEvent.zip that gives a bit more information about how the related sizing events works. Also if you change the Position = poMainFormCenter to Position = poDesigned, form2 will show at the designed position.

Joeny Ang

2020-08-28 03:17

reporter   ~0125163

Another patch :)
- if form is designed maximized or fullscreen, first restore will now honor Position property
- setting WindowState property will now trigger onWindowStateChange()
- win32: moving/resizing via mouse will now trigger onResize/onChangeBounds
  :: the async queue is not being processed while the mouse button is down
- gtk2: switching (via code) between wsFullscreen and other states now works properly

Tested:
  Widgetsets: Gtk2, Qt5, Win32 (WinXP)
  Window managers: Metacity, Mutter
tform-wrong-bounds-and-restored-bounds-part4.patch (5,701 bytes)   
--- lazarus/lcl/forms.pp.63838
+++ lazarus/lcl/forms.pp
@@ -492,7 +492,7 @@
     FWindowState: TWindowState;
     FDelayedEventCtr: Integer;
     FDelayedOnChangeBounds, FDelayedOnResize: Boolean;
-    FIsFirstOnShow, FIsFirstOnActivate: Boolean;
+    FIsFirstOnShow, FIsFirstOnActivate, FIsFirstRestore: Boolean;
     function GetClientHandle: HWND;
     function GetEffectiveShowInTaskBar: TShowInTaskBar;
     function GetMonitor: TMonitor;
--- lazarus/lcl/include/customform.inc.63838
+++ lazarus/lcl/include/customform.inc
@@ -692,42 +692,45 @@
     Exit;
   { update restored bounds }
   if WindowState = wsNormal then
-    begin
-      if FDelayedOnChangeBounds then
-        begin
-          FRestoredLeft := Left;
-          FRestoredTop := Top;
-        end;
-      if FDelayedOnResize then
-        begin
-          FRestoredWidth := Width;
-          FRestoredHeight := Height;
-        end;
-    end;
+  begin
+    if FDelayedOnChangeBounds then
+    begin
+      FRestoredLeft := Left;
+      FRestoredTop := Top;
+    end;
+    if FDelayedOnResize then
+    begin
+      FRestoredWidth := Width;
+      FRestoredHeight := Height;
+    end;
+  end;
   { call onShow() or onActivate() for the first time, after first OnResize()
     and OnChangeBounds() }
   if FDelayedOnResize and FDelayedOnChangeBounds then
-    begin
-      if FIsFirstOnShow then
-        begin
-          FIsFirstOnShow := False;
-          DoShow;
-        end;
-      if FIsFirstOnActivate then
-        begin
-          FIsFirstOnActivate := False;
-          if FActive then
-            Activate;
-        end;
-    end;
-  { delayed onResize() }
-  if FDelayedOnResize then
-    inherited DoOnResize;
-  { delayed onChangeBounds() }
-  if FDelayedOnResize or FDelayedOnChangeBounds then
-    inherited DoOnChangeBounds;
-  FDelayedOnChangeBounds := False;
-  FDelayedOnResize := False;
+  begin
+    if FIsFirstOnShow then
+    begin
+      FIsFirstOnShow := False;
+      DoShow;
+    end;
+    if FIsFirstOnActivate then
+    begin
+      FIsFirstOnActivate := False;
+      if FActive then
+        Activate;
+    end;
+  end;
+  if not (FIsFirstOnShow or FIsFirstOnActivate) then
+  begin
+    { delayed onResize() }
+    if FDelayedOnResize then
+      inherited DoOnResize;
+    { delayed onChangeBounds() }
+    if FDelayedOnResize or FDelayedOnChangeBounds then
+      inherited DoOnChangeBounds;
+    FDelayedOnChangeBounds := False;
+    FDelayedOnResize := False;
+  end;
 end;
 
 procedure TCustomForm.WMWindowPosChanged(var Message: TLMWindowPosChanged);
@@ -1001,6 +1004,7 @@
   if FIsFirstOnShow and (WindowState in [wsMaximized, wsFullScreen]) then
     Exit;
   FIsFirstOnShow := False;
+  FIsFirstRestore := WindowState in [wsMaximized, wsFullScreen];
   if Assigned(FOnShow) then FOnShow(Self);
 end;
 
@@ -1139,17 +1143,15 @@
   if Showing and not (csDesigning in ComponentState) then
   begin
     OldState := FWindowState;
-    FWindowState := State;
     if OldState <> State then
     begin
+      WindowState := State;
       if (State = wsMinimized) and (Application.MainForm = Self) and
          (WidgetSet.GetLCLCapability(lcNeedMininimizeAppWithMainForm) <> LCL_CAPABILITY_NO) then
         Application.Minimize;
       if (OldState = wsMinimized) and (Application.MainForm = Self) and
          (WidgetSet.GetLCLCapability(lcNeedMininimizeAppWithMainForm) <> LCL_CAPABILITY_NO) then
         Application.Restore;
-      if Assigned(OnWindowStateChange) then
-        OnWindowStateChange(Self);
     end;
   end;
 end;
@@ -1830,7 +1832,19 @@
     FWindowState := Value;
     //DebugLn(['TCustomForm.SetWindowState ',DbgSName(Self),' ',ord(FWindowState),' csDesigning=',csDesigning in ComponentState,' Showing=',Showing]);
     if (not (csDesigning in ComponentState)) and Showing then
+    begin
       ShowWindow(Handle, ShowCommands[Value]);
+      if not (FIsFirstOnShow or FIsFirstOnActivate) then
+      begin
+        if FIsFirstRestore then
+        begin
+          MoveToDefaultPosition;
+          FIsFirstRestore := False;
+        end;
+        if Assigned(OnWindowStateChange) then
+          OnWindowStateChange(Self);
+      end;
+    end;
   end;
 end;
 
@@ -2030,6 +2044,7 @@
   FDelayedOnResize := False;
   FIsFirstOnShow := True;
   FIsFirstOnActivate := True;
+  FIsFirstRestore := False;
   GlobalNameSpace.BeginWrite;
   try
     CreateNew(AOwner, 1); // this calls BeginFormUpdate, which is ended in AfterConstruction
--- lcl/interfaces/win32/win32callback.inc.63838
+++ lcl/interfaces/win32/win32callback.inc
@@ -15,6 +15,7 @@
 {$ENDIF}
 type
   TWinControlAccess = class(TWinControl);
+  TApplicationAccess = class(TApplication);
 {*************************************************************}
 {            callback routines                                }
 {*************************************************************}
@@ -2054,6 +2055,8 @@
       begin
         CheckSynchronize;
         TWin32Widgetset(Widgetset).CheckPipeEvents;
+        if Assigned(Application) then
+          TApplicationAccess(Application).ProcessAsyncCallQueue;
       end;
     WM_ENTERIDLE: Application.Idle(False);
     WM_ACTIVATE:  SetLMessageAndParams(LM_ACTIVATE);
--- lcl/interfaces/gtk2/gtk2callback.inc.63838
+++ lcl/interfaces/gtk2/gtk2callback.inc
@@ -1121,6 +1121,8 @@
           {$ENDIF}
           SizeMsg.SizeType := SIZE_MINIMIZED;
         end
+        else if (GDK_WINDOW_STATE_FULLSCREEN and state^.new_window_state)>0 then
+          SizeMsg.SizeType := SIZE_FULLSCREEN
         else if (GDK_WINDOW_STATE_MAXIMIZED and state^.new_window_state)>0 then
         begin
           // it can be both maximized + iconified and just loose iconified state

Joeny Ang

2020-08-28 11:16

reporter   ~0125170

Oooppss... updated the patch. :)
tform-wrong-bounds-and-restored-bounds-part4v2.patch (5,669 bytes)   
--- lcl/forms.pp.63838
+++ lcl/forms.pp
@@ -492,7 +492,7 @@
     FWindowState: TWindowState;
     FDelayedEventCtr: Integer;
     FDelayedOnChangeBounds, FDelayedOnResize: Boolean;
-    FIsFirstOnShow, FIsFirstOnActivate: Boolean;
+    FIsFirstOnShow, FIsFirstOnActivate, FIsFirstRestore: Boolean;
     function GetClientHandle: HWND;
     function GetEffectiveShowInTaskBar: TShowInTaskBar;
     function GetMonitor: TMonitor;
--- lcl/include/customform.inc.63838
+++ lcl/include/customform.inc
@@ -692,42 +692,45 @@
     Exit;
   { update restored bounds }
   if WindowState = wsNormal then
-    begin
-      if FDelayedOnChangeBounds then
-        begin
-          FRestoredLeft := Left;
-          FRestoredTop := Top;
-        end;
-      if FDelayedOnResize then
-        begin
-          FRestoredWidth := Width;
-          FRestoredHeight := Height;
-        end;
-    end;
+  begin
+    if FDelayedOnChangeBounds then
+    begin
+      FRestoredLeft := Left;
+      FRestoredTop := Top;
+    end;
+    if FDelayedOnResize then
+    begin
+      FRestoredWidth := Width;
+      FRestoredHeight := Height;
+    end;
+  end;
   { call onShow() or onActivate() for the first time, after first OnResize()
     and OnChangeBounds() }
   if FDelayedOnResize and FDelayedOnChangeBounds then
-    begin
-      if FIsFirstOnShow then
-        begin
-          FIsFirstOnShow := False;
-          DoShow;
-        end;
-      if FIsFirstOnActivate then
-        begin
-          FIsFirstOnActivate := False;
-          if FActive then
-            Activate;
-        end;
-    end;
-  { delayed onResize() }
-  if FDelayedOnResize then
-    inherited DoOnResize;
-  { delayed onChangeBounds() }
-  if FDelayedOnResize or FDelayedOnChangeBounds then
-    inherited DoOnChangeBounds;
-  FDelayedOnChangeBounds := False;
-  FDelayedOnResize := False;
+  begin
+    if FIsFirstOnShow then
+    begin
+      FIsFirstOnShow := False;
+      DoShow;
+    end;
+    if FIsFirstOnActivate then
+    begin
+      FIsFirstOnActivate := False;
+      if FActive then
+        Activate;
+    end;
+  end;
+  if not (FIsFirstOnShow or FIsFirstOnActivate) then
+  begin
+    { delayed onResize() }
+    if FDelayedOnResize then
+      inherited DoOnResize;
+    { delayed onChangeBounds() }
+    if FDelayedOnResize or FDelayedOnChangeBounds then
+      inherited DoOnChangeBounds;
+    FDelayedOnChangeBounds := False;
+    FDelayedOnResize := False;
+  end;
 end;
 
 procedure TCustomForm.WMWindowPosChanged(var Message: TLMWindowPosChanged);
@@ -1001,6 +1004,7 @@
   if FIsFirstOnShow and (WindowState in [wsMaximized, wsFullScreen]) then
     Exit;
   FIsFirstOnShow := False;
+  FIsFirstRestore := WindowState in [wsMaximized, wsFullScreen];
   if Assigned(FOnShow) then FOnShow(Self);
 end;
 
@@ -1139,17 +1143,15 @@
   if Showing and not (csDesigning in ComponentState) then
   begin
     OldState := FWindowState;
-    FWindowState := State;
     if OldState <> State then
     begin
+      WindowState := State;
       if (State = wsMinimized) and (Application.MainForm = Self) and
          (WidgetSet.GetLCLCapability(lcNeedMininimizeAppWithMainForm) <> LCL_CAPABILITY_NO) then
         Application.Minimize;
       if (OldState = wsMinimized) and (Application.MainForm = Self) and
          (WidgetSet.GetLCLCapability(lcNeedMininimizeAppWithMainForm) <> LCL_CAPABILITY_NO) then
         Application.Restore;
-      if Assigned(OnWindowStateChange) then
-        OnWindowStateChange(Self);
     end;
   end;
 end;
@@ -1830,7 +1832,19 @@
     FWindowState := Value;
     //DebugLn(['TCustomForm.SetWindowState ',DbgSName(Self),' ',ord(FWindowState),' csDesigning=',csDesigning in ComponentState,' Showing=',Showing]);
     if (not (csDesigning in ComponentState)) and Showing then
+    begin
       ShowWindow(Handle, ShowCommands[Value]);
+      if not (FIsFirstOnShow or FIsFirstOnActivate) then
+      begin
+        if FIsFirstRestore then
+        begin
+          MoveToDefaultPosition;
+          FIsFirstRestore := False;
+        end;
+        if Assigned(OnWindowStateChange) then
+          OnWindowStateChange(Self);
+      end;
+    end;
   end;
 end;
 
@@ -2030,6 +2044,7 @@
   FDelayedOnResize := False;
   FIsFirstOnShow := True;
   FIsFirstOnActivate := True;
+  FIsFirstRestore := False;
   GlobalNameSpace.BeginWrite;
   try
     CreateNew(AOwner, 1); // this calls BeginFormUpdate, which is ended in AfterConstruction
--- lcl/interfaces/win32/win32callback.inc.63838
+++ lcl/interfaces/win32/win32callback.inc
@@ -15,6 +15,7 @@
 {$ENDIF}
 type
   TWinControlAccess = class(TWinControl);
+  TApplicationAccess = class(TApplication);
 {*************************************************************}
 {            callback routines                                }
 {*************************************************************}
@@ -2054,6 +2055,8 @@
       begin
         CheckSynchronize;
         TWin32Widgetset(Widgetset).CheckPipeEvents;
+        if Assigned(Application) then
+          TApplicationAccess(Application).ProcessAsyncCallQueue;
       end;
     WM_ENTERIDLE: Application.Idle(False);
     WM_ACTIVATE:  SetLMessageAndParams(LM_ACTIVATE);
--- lcl/interfaces/gtk2/gtk2callback.inc.63838
+++ lcl/interfaces/gtk2/gtk2callback.inc
@@ -1121,6 +1121,8 @@
           {$ENDIF}
           SizeMsg.SizeType := SIZE_MINIMIZED;
         end
+        else if (GDK_WINDOW_STATE_FULLSCREEN and state^.new_window_state)>0 then
+          SizeMsg.SizeType := SIZE_FULLSCREEN
         else if (GDK_WINDOW_STATE_MAXIMIZED and state^.new_window_state)>0 then
         begin
           // it can be both maximized + iconified and just loose iconified state

Juha Manninen

2020-08-29 16:46

developer   ~0125202

Last edited: 2020-08-29 17:24

View 3 revisions

I applied the latest patch in r63842. Thanks.
Note: I split the unindent formatting part to another commit, r63843. Easier to figure out what happens.

@BrunoK, you mean r62745 did not change the behavior? It was just a random pick. Please write here only about revisions that are relevant for this issue. We already have many revisions and many reports to deal with. No need to complicate it more.
You can bisect guilty revisions. I recommend "git bisect" command for that.

BrunoK

2020-08-30 15:01

reporter   ~0125216

Juha Manninen 2020-08-29 16:46

I only meant : At r62745 these two files seem to be OK . Issue 0037467 does not show with this version. NOTHING MORE.

I will test with at r63842 and report how it looks.

jamie philbrook

2020-09-11 01:14

reporter   ~0125470

ITs strange because I just tested a variety of versions here, not the trunk and they all work correctly ?

So why all of this ? I too have Delphi 3 and they work exactly like D3 so like I said why ?

CudaText man_

2020-09-11 15:40

reporter   ~0125482

This patch broke the Restore action
https://bugs.freepascal.org/view.php?id=37732

Juha Manninen

2020-09-11 20:05

developer   ~0125488

r63842 caused a regression. I had to revert it.

BrunoK

2020-09-12 16:15

reporter   ~0125511

I reverted to
   \lcl\include\Forms.pp at r62745,
   \lcl\include\customform.inc at r62892.
Attached patch on 63882

Reason : r63882 makes 0037467 still broken : Form Resize Not Firing Correctly and its attached demos.

I have not critics about improving excessive messaging but think we should try, using Joeny Ang's ideas, to design a safer way to rework the code.
We should consider what is Widget set dependent and what is pure /lcl and /lcl/include stuff.

There has been recently quite a few issues in the bugtracker that I could not reproduce in Win10 2004 / 10.0.19041.508 (example > 0037706: [Regression] IDE extremely slow when adding a new control to a heavily populated form < ) so it is a bit difficult to understand what is going on.
revert_form_200912.patch (7,604 bytes)   
Index: lcl/forms.pp
===================================================================
--- lcl/forms.pp	(revision 63882)
+++ lcl/forms.pp	(working copy)
@@ -491,7 +491,7 @@
     FShowInTaskbar: TShowInTaskbar;
     FWindowState: TWindowState;
     FDelayedEventCtr: Integer;
-    FDelayedOnChangeBounds, FDelayedOnResize: Boolean;
+    FDelayedWMMove, FDelayedWMSize: Boolean;
     FIsFirstOnShow, FIsFirstOnActivate: Boolean;
     function GetClientHandle: HWND;
     function GetEffectiveShowInTaskBar: TShowInTaskBar;
@@ -535,6 +535,7 @@
     procedure WMActivate(var Message : TLMActivate); message LM_ACTIVATE;
     procedure WMCloseQuery(var message: TLMessage); message LM_CLOSEQUERY;
     procedure WMHelp(var Message: TLMHelp); message LM_HELP;
+    procedure WMMove(var Message: TLMMove); message LM_MOVE;
     procedure WMShowWindow(var message: TLMShowWindow); message LM_SHOWWINDOW;
     procedure WMSize(var message: TLMSize); message LM_Size;
     procedure WMWindowPosChanged(var Message: TLMWindowPosChanged); message LM_WINDOWPOSCHANGED;
@@ -580,8 +581,6 @@
     procedure Resizing(State: TWindowState); override;
     procedure CalculatePreferredSize(var PreferredWidth,
            PreferredHeight: integer; WithThemeSpace: Boolean); override;
-    procedure DoOnResize; override;
-    procedure DoOnChangeBounds; override;
     procedure SetZOrder(Topmost: Boolean); override;
     procedure SetParent(NewParent: TWinControl); override;
     procedure MoveToDefaultPosition; virtual;
@@ -1192,7 +1191,7 @@
     property Forms[Index: Integer]: TForm read GetForms;
     property DataModuleCount: Integer read GetDataModuleCount;
     property DataModules[Index: Integer]: TDataModule read GetDataModules;
-    
+
     property HintFont: TFont read GetHintFont write SetHintFont;
     property IconFont: TFont read GetIconFont write SetIconFont;
     property MenuFont: TFont read GetMenuFont write SetMenuFont;
Index: lcl/include/customform.inc
===================================================================
--- lcl/include/customform.inc	(revision 63882)
+++ lcl/include/customform.inc	(working copy)
@@ -240,7 +240,7 @@
     if Assigned(OldCancelControl) then
       OldCancelControl.UpdateRolesForForm;
     // notify new control
-    if Assigned(FCancelControl) then 
+    if Assigned(FCancelControl) then
     begin
       FreeNotification(FCancelControl);
       FCancelControl.UpdateRolesForForm;
@@ -604,7 +604,7 @@
  ------------------------------------------------------------------------------}
 procedure TCustomForm.Activate;
 begin
-  if FIsFirstOnActivate and (WindowState in [wsMaximized, wsFullScreen]) then
+  if FIsFirstOnActivate and (WindowState = wsMaximized) then
     Exit;
   FIsFirstOnActivate := False;
   if Assigned(FOnActivate) then FOnActivate(Self);
@@ -662,23 +662,22 @@
   end;
 
   inherited WMSize(Message);
-end;
 
-procedure TCustomForm.DoOnResize;
-begin
   if not (csDestroying in ComponentState) then
   begin
-    FDelayedOnResize := True;
+    FDelayedWMSize := True;
     Inc(FDelayedEventCtr);
     Application.QueueAsyncCall(@DelayedEvent, 0);
   end;
 end;
 
-procedure TCustomForm.DoOnChangeBounds;
+procedure TCustomForm.WMMove(var Message: TLMMove);
 begin
+  inherited WMMove(Message);
+
   if not (csDestroying in ComponentState) then
   begin
-    FDelayedOnChangeBounds := True;
+    FDelayedWMMove := True;
     Inc(FDelayedEventCtr);
     Application.QueueAsyncCall(@DelayedEvent, 0);
   end;
@@ -692,42 +691,37 @@
     Exit;
   { update restored bounds }
   if WindowState = wsNormal then
-  begin
-    if FDelayedOnChangeBounds then
     begin
-      FRestoredLeft := Left;
-      FRestoredTop := Top;
+      if FDelayedWMMove then
+        begin
+          FRestoredLeft := Left;
+          FRestoredTop := Top;
+        end;
+      if FDelayedWMSize then
+        begin
+          FRestoredWidth := Width;
+          FRestoredHeight := Height;
+          DoOnResize;     // delayed onResize()
+        end;
+      DoOnChangeBounds;     // delayed onChangeBounds()
     end;
-    if FDelayedOnResize then
+  { call onShow() or onActivate() for the first time, after first WMSize }
+  if FDelayedWMSize then
     begin
-      FRestoredWidth := Width;
-      FRestoredHeight := Height;
+      if FIsFirstOnShow then
+        begin
+          FIsFirstOnShow := False;
+          DoShow;
+        end;
+      if FIsFirstOnActivate then
+        begin
+          FIsFirstOnActivate := False;
+          if FActive then
+            Activate;
+        end;
     end;
-  end;
-  { call onShow() or onActivate() for the first time,
-    after first OnResize() and OnChangeBounds() }
-  if FDelayedOnResize or FDelayedOnChangeBounds then
-  begin
-    if FIsFirstOnShow then
-    begin
-      FIsFirstOnShow := False;
-      DoShow;
-    end;
-    if FIsFirstOnActivate then
-    begin
-      FIsFirstOnActivate := False;
-      if FActive then
-        Activate;
-    end;
-  end;
-  { delayed onResize() }
-  if FDelayedOnResize then
-    inherited DoOnResize;
-  { delayed onChangeBounds() }
-  if FDelayedOnResize or FDelayedOnChangeBounds then
-    inherited DoOnChangeBounds;
-  FDelayedOnChangeBounds := False;
-  FDelayedOnResize := False;
+  FDelayedWMMove := False;
+  FDelayedWMSize := False;
 end;
 
 procedure TCustomForm.WMWindowPosChanged(var Message: TLMWindowPosChanged);
@@ -998,7 +992,7 @@
  ------------------------------------------------------------------------------}
 procedure TCustomForm.DoShow;
 begin
-  if FIsFirstOnShow and (WindowState in [wsMaximized, wsFullScreen]) then
+  if FIsFirstOnShow and (WindowState = wsMaximized) then
     Exit;
   FIsFirstOnShow := False;
   if Assigned(FOnShow) then FOnShow(Self);
@@ -1625,7 +1619,7 @@
     end;
     Result := False;
   end;
-  
+
 begin
   // don't execute action while designing or when form is not visible
   if (csDesigning in ComponentState) or not Visible then
@@ -1634,9 +1628,9 @@
   // assume it gets handled somewhere
   Result := True;
   if Assigned(ActiveControl) and ActiveControl.ExecuteAction(ExeAction) then Exit;
-    
+
   if ExecuteAction(ExeAction) then Exit;
-    
+
   if DoExecuteActionInChildControls(Self, ExeAction) then Exit;
 
   // not handled anywhere, return false
@@ -1748,7 +1742,7 @@
     Value := nil;
 
   FMenu := Value;
-  if FMenu <> nil then 
+  if FMenu <> nil then
   begin
     FMenu.FreeNotification(Self);
     FMenu.Parent := Self;
@@ -1790,7 +1784,7 @@
   AdaptBorderIcons := not (csLoading in ComponentState) and
                       (BorderIcons = DefaultBorderIcons[FFormBorderStyle]);
   FFormBorderStyle := NewStyle;
-  
+
   if not (csDesigning in ComponentState) then
   begin
     // if Form had default border icons before change, it should keep the default
@@ -1939,7 +1933,7 @@
 begin
   if AValue = FAllowDropFiles then Exit;
   FAllowDropFiles := AValue;
-  
+
   if HandleAllocated and not (csDesigning in ComponentState) then
     TWSCustomFormClass(WidgetSetClass).SetAllowDropFiles(Self, AValue);
 end;
@@ -2026,8 +2020,8 @@
 constructor TCustomForm.Create(AOwner: TComponent);
 begin
   FDelayedEventCtr := 0;
-  FDelayedOnChangeBounds := False;
-  FDelayedOnResize := False;
+  FDelayedWMMove := False;
+  FDelayedWMSize := False;
   FIsFirstOnShow := True;
   FIsFirstOnActivate := True;
   GlobalNameSpace.BeginWrite;
@@ -2661,7 +2655,7 @@
 procedure TCustomForm.IntfHelp(AComponent: TComponent);
 begin
   if csDesigning in ComponentState then exit;
-  
+
   if AComponent is TControl then begin
     TControl(AComponent).ShowHelp;
   end else begin
revert_form_200912.patch (7,604 bytes)   

Juha Manninen

2020-09-13 12:12

developer   ~0125523

@BrunoK, did you test issue 0037732 with your patch?
I will look at it later.

BrunoK

2020-09-13 13:03

reporter   ~0125525

@Juha Manninen
> did you test issue 0037732 with your patch?

Tested 0037732 on Win 10 64 / PFC 3.0.4 i386/win32. Works for me.
My patch is a revert to a reasonable stable state so we can reassert what and where something should be done.

Note that 0037467 does show (in debug mode) some duplicates OnResize but the problem demo is maybe not optimally written.

Joeny Ang

2020-09-14 12:02

reporter   ~0125536

Hi all :)

Updated the last patch:
- Issue 0037732 was caused by the attempt to fix onWindowStateChange() not triggering when setting WindowState via code. This is now fixed.
- Fixed code to honor Position property on first restore when form was designed maximized.
- Tweaked DelayedEvent() for QT5 sometimes triggering onChangeBounds() twice on first show.

Patched against r63882
tform-wrong-bounds-and-restored-bounds-part4-fix.patch (5,616 bytes)   
--- lcl/forms.pp.63882
+++ lcl/forms.pp
@@ -493,6 +493,7 @@
     FDelayedEventCtr: Integer;
     FDelayedOnChangeBounds, FDelayedOnResize: Boolean;
     FIsFirstOnShow, FIsFirstOnActivate: Boolean;
+    FIsFirstRestore, FWindowStateChanged: Boolean;
     function GetClientHandle: HWND;
     function GetEffectiveShowInTaskBar: TShowInTaskBar;
     function GetMonitor: TMonitor;
--- lcl/include/customform.inc.63882
+++ lcl/include/customform.inc
@@ -706,7 +706,7 @@
   end;
   { call onShow() or onActivate() for the first time,
     after first OnResize() and OnChangeBounds() }
-  if FDelayedOnResize or FDelayedOnChangeBounds then
+  if FDelayedOnResize and FDelayedOnChangeBounds and FActive then
   begin
     if FIsFirstOnShow then
     begin
@@ -716,18 +716,20 @@
     if FIsFirstOnActivate then
     begin
       FIsFirstOnActivate := False;
-      if FActive then
-        Activate;
-    end;
-  end;
-  { delayed onResize() }
-  if FDelayedOnResize then
-    inherited DoOnResize;
-  { delayed onChangeBounds() }
-  if FDelayedOnResize or FDelayedOnChangeBounds then
-    inherited DoOnChangeBounds;
-  FDelayedOnChangeBounds := False;
-  FDelayedOnResize := False;
+      Activate;
+    end;
+  end;
+  if not (FIsFirstOnShow or FIsFirstOnActivate) then
+  begin
+    { delayed onResize() }
+    if FDelayedOnResize then
+      inherited DoOnResize;
+    { delayed onChangeBounds() }
+    if FDelayedOnResize or FDelayedOnChangeBounds then
+      inherited DoOnChangeBounds;
+    FDelayedOnChangeBounds := False;
+    FDelayedOnResize := False;
+  end;
 end;
 
 procedure TCustomForm.WMWindowPosChanged(var Message: TLMWindowPosChanged);
@@ -1001,6 +1003,7 @@
   if FIsFirstOnShow and (WindowState in [wsMaximized, wsFullScreen]) then
     Exit;
   FIsFirstOnShow := False;
+  FIsFirstRestore := WindowState in [wsMaximized, wsFullScreen];
   if Assigned(FOnShow) then FOnShow(Self);
 end;
 
@@ -1148,8 +1151,28 @@
       if (OldState = wsMinimized) and (Application.MainForm = Self) and
          (WidgetSet.GetLCLCapability(lcNeedMininimizeAppWithMainForm) <> LCL_CAPABILITY_NO) then
         Application.Restore;
-      if Assigned(OnWindowStateChange) then
-        OnWindowStateChange(Self);
+    end;
+
+    if (OldState <> State) or FWindowStateChanged then
+    begin
+      { honor Position property on first restore when form was designed maximized }
+      if not (FIsFirstOnShow or FIsFirstOnActivate) then
+      begin
+        if FIsFirstRestore and (State = wsNormal) then
+        begin
+          { Need to check width/height before calling MoveToDefaultPosition.
+            QT5 triggers Resizing() twice: one for position change, and
+            another for size change. This check should not affect other
+            widgetsets. }
+          if (Width <> RestoredWidth) or (Height <> RestoredHeight) then
+            Exit;
+          MoveToDefaultPosition;
+          FIsFirstRestore := False;
+        end;
+        if Assigned(OnWindowStateChange) then
+          OnWindowStateChange(Self);
+      end;
+      FWindowStateChanged := False;
     end;
   end;
 end;
@@ -1830,7 +1853,10 @@
     FWindowState := Value;
     //DebugLn(['TCustomForm.SetWindowState ',DbgSName(Self),' ',ord(FWindowState),' csDesigning=',csDesigning in ComponentState,' Showing=',Showing]);
     if (not (csDesigning in ComponentState)) and Showing then
+    begin
+      FWindowStateChanged := True;
       ShowWindow(Handle, ShowCommands[Value]);
+    end;
   end;
 end;
 
@@ -2030,6 +2056,8 @@
   FDelayedOnResize := False;
   FIsFirstOnShow := True;
   FIsFirstOnActivate := True;
+  FIsFirstRestore := False;
+  FWindowStateChanged := False;
   GlobalNameSpace.BeginWrite;
   try
     CreateNew(AOwner, 1); // this calls BeginFormUpdate, which is ended in AfterConstruction
--- lcl/interfaces/gtk2/gtk2callback.inc.63882
+++ lcl/interfaces/gtk2/gtk2callback.inc
@@ -1121,6 +1121,8 @@
           {$ENDIF}
           SizeMsg.SizeType := SIZE_MINIMIZED;
         end
+        else if (GDK_WINDOW_STATE_FULLSCREEN and state^.new_window_state)>0 then
+          SizeMsg.SizeType := SIZE_FULLSCREEN
         else if (GDK_WINDOW_STATE_MAXIMIZED and state^.new_window_state)>0 then
         begin
           // it can be both maximized + iconified and just loose iconified state
@@ -1133,7 +1135,8 @@
         // don't bother the LCL if nothing changed
         case SizeMsg.SizeType of
           SIZE_RESTORED: if TheForm.WindowState=wsNormal then exit;
-          SIZE_MINIMIZED: if TheForm.WindowState=wsMinimized then exit;
+          // Need to send LM_SIZE message to LCL if wsMinimized to trigger onWindowStateChange()
+          //SIZE_MINIMIZED: if TheForm.WindowState=wsMinimized then exit;
           SIZE_MAXIMIZED: if TheForm.WindowState=wsMaximized then exit;
           SIZE_FULLSCREEN: if TheForm.WindowState=wsFullScreen then exit;
         end;
--- lcl/interfaces/win32/win32callback.inc.63882
+++ lcl/interfaces/win32/win32callback.inc
@@ -15,6 +15,7 @@
 {$ENDIF}
 type
   TWinControlAccess = class(TWinControl);
+  TApplicationAccess = class(TApplication);
 {*************************************************************}
 {            callback routines                                }
 {*************************************************************}
@@ -2054,6 +2055,8 @@
       begin
         CheckSynchronize;
         TWin32Widgetset(Widgetset).CheckPipeEvents;
+        if Assigned(Application) then
+          TApplicationAccess(Application).ProcessAsyncCallQueue;
       end;
     WM_ENTERIDLE: Application.Idle(False);
     WM_ACTIVATE:  SetLMessageAndParams(LM_ACTIVATE);

Juha Manninen

2020-09-18 11:49

developer   ~0125609

Sorry for the delay. I had other stuff going on.
In r63888 I applied the latest patch from Joeny Ang with one important change.
In customform.inc the patch has :
+ if FDelayedOnResize and FDelayedOnChangeBounds and FActive then
which reverts my fix for issue 0037647 (after lots of debugging :) .
I changed it to :
+ if (FDelayedOnResize or FDelayedOnChangeBounds) and FActive then
Everybody please test and verify it works.
If it works then I would like to resolve this issue ASAP. It is getting long and difficult to follow with all the revisions involved. New related issues can have their own reports.

CudaText man_

2020-09-18 13:14

reporter   ~0125613

Thanks for the fix

josh

2020-09-18 21:49

reporter   ~0125631

Hi
Just tested Rev 63888.
it has fixed that the form.resize is being fired.

form.OnResize appears now not to be re-entrent, if you run the attached test with rev 63888, and compare against rev 63556, you will see some big differneces in the time my re-size take to complete.

The attached project; now keeps track of how many time the on-reize is called when it is allready in the re-size code.


rev 63556 (resizing the form via the corner tab, slowly upto full screen and back again)
Use processmessages re-entrant called 48 times, max time in code 94ms average time in resize code 20ms
use ProcessMessages and Begin/End Update Re-entrent 88, max 94 avg 13
Use Begin/Endupdate Re-entrant 0, Max 16, Avg 3.
use None Re-Entrant 0, Max 31, AVg 5

rev 63888
Use processmessages re-entrant called 0, max time in code 344ms average time in resize code 141ms
use ProcessMessages and Begin/End Update Re-entrent 0, max 234 avg 37
Use Begin/Endupdate Re-entrant 0, Max 62, Avg 12.
use None Re-Entrant 0, Max 281, Avg 38

I get similar figures when testing on WIn/32/64 and linux Mint. Not yet tried on MacOS yet

Can anyone else confirm similar impacts?

You may think that its a strange test; but a few of my applications use the resize event to calculate what is displayed on the screen and in what location; based on the size of active form etc. These forms do not use anchor docking because visual components can be moved, made visible etc based on screen size and user preferences. Also they keeps a track if it in a re-entrant state so that any cpu/gpu intensive scaling etc can be ignored; until its not in a re-entrent state; it might complicated; but it does keep the application extrememly responsive and smooth. THought I would explain the issue.
Also the current way it works is not very compatible with Delphi
Form_events_3.zip (102,037 bytes)

Juha Manninen

2020-09-18 23:21

developer   ~0125632

@josh, please open a new report for your speed issue. It can have this issue, 0037467 and maybe 0037706 as related issues.
Resolving this one.

josh

2020-09-18 23:35

reporter   ~0125634

@Juha Manninen
I will add this to my previous report. 0037688

I still make the issue of the form.onresize not be re-entrant? was this introduced in this report?

Issue History

Date Modified Username Field Change
2019-10-02 09:55 Joeny Ang New Issue
2019-10-02 09:55 Joeny Ang File Added: tform-wrong-bounds-and-restored-bounds.patch
2019-10-02 09:55 Joeny Ang File Added: tform-restoredbounds.zip
2019-10-03 03:52 Joeny Ang File Added: tform-wrong-bounds-and-restored-bounds-v2.patch
2019-10-03 03:52 Joeny Ang Note Added: 0118263
2019-10-03 14:33 Juha Manninen Relationship added related to 0027894
2019-10-03 14:33 Juha Manninen Relationship added related to 0022771
2019-10-03 14:33 Juha Manninen Relationship added related to 0027375
2019-10-03 14:34 Juha Manninen Relationship added related to 0021119
2019-10-03 14:42 Juha Manninen Relationship added related to 0032631
2019-10-03 14:44 Juha Manninen Relationship added related to 0008576
2019-10-03 14:45 Juha Manninen Description Updated View Revisions
2019-10-03 14:45 Juha Manninen LazTarget => -
2019-10-03 14:45 Juha Manninen Widgetset GTK 2, Win32/Win64 => GTK 2, Win32/Win64
2019-10-03 16:01 Juha Manninen Note Added: 0118278
2019-10-05 22:26 Juha Manninen Assigned To => Juha Manninen
2019-10-05 22:26 Juha Manninen Status new => assigned
2019-10-05 22:28 Juha Manninen Note Added: 0118358
2019-10-07 08:00 Joeny Ang File Added: delayedevent-wait-for-wmsize-before-onshow-onactivate.patch
2019-10-07 08:00 Joeny Ang Note Added: 0118386
2019-10-25 00:37 Juha Manninen Note Added: 0118793
2019-10-25 00:38 Juha Manninen Fixed in Revision => r61997, r62113
2019-10-25 00:38 Juha Manninen Widgetset GTK 2, Win32/Win64 => GTK 2, Win32/Win64
2020-03-16 19:29 Juha Manninen Status assigned => resolved
2020-03-16 19:29 Juha Manninen Resolution open => fixed
2020-03-16 19:29 Juha Manninen Widgetset GTK 2, Win32/Win64 => GTK 2, Win32/Win64
2020-03-16 19:29 Juha Manninen Note Added: 0121628
2020-04-05 18:44 Juha Manninen Relationship added related to 0036877
2020-05-24 15:56 Michl Note Added: 0123037
2020-05-24 15:59 Michl Note Edited: 0123037 View Revisions
2020-05-24 17:33 Michl Note Edited: 0123037 View Revisions
2020-05-25 15:16 Michl Fixed in Revision r61997, r62113 => r61997, r62113, r63218
2020-05-25 15:16 Michl Widgetset GTK 2, Win32/Win64 => GTK 2, Win32/Win64
2020-05-25 15:17 Michl Note Added: 0123059
2020-05-25 21:04 Michl Status resolved => assigned
2020-05-25 21:04 Michl Resolution fixed => reopened
2020-05-25 21:05 Michl Note Added: 0123062
2020-05-25 21:05 Michl File Added: TestChangeBoundsEvent.zip
2020-05-25 21:07 Michl Note Edited: 0123062 View Revisions
2020-05-25 21:08 Michl Note Edited: 0123062 View Revisions
2020-07-15 10:26 Joeny Ang Note Added: 0124030
2020-07-15 10:26 Joeny Ang File Added: fix-duplicate-onresize-onchangebounds.patch
2020-07-15 10:27 Joeny Ang Note Edited: 0124030 View Revisions
2020-07-17 01:01 Juha Manninen Note Added: 0124110
2020-07-17 01:02 Juha Manninen Fixed in Revision r61997, r62113, r63218 => r61997, r62113, r63218, r63577
2020-07-17 01:02 Juha Manninen Widgetset GTK 2, Win32/Win64 => GTK 2, Win32/Win64
2020-07-22 19:35 Juha Manninen Status assigned => resolved
2020-07-22 19:35 Juha Manninen Widgetset GTK 2, Win32/Win64 => GTK 2, Win32/Win64
2020-07-22 19:35 Juha Manninen Note Added: 0124233
2020-08-26 11:10 Juha Manninen Relationship added related to 0037467
2020-08-26 11:12 Juha Manninen Status resolved => assigned
2020-08-26 11:12 Juha Manninen Resolution reopened => open
2020-08-26 11:12 Juha Manninen Note Added: 0125129
2020-08-26 11:13 Juha Manninen Note Edited: 0125129 View Revisions
2020-08-26 15:44 BrunoK Note Added: 0125133
2020-08-26 21:45 Juha Manninen Note Added: 0125143
2020-08-27 11:24 Paweł Dmitruk Note Added: 0125150
2020-08-27 11:54 BrunoK Note Added: 0125151
2020-08-27 11:54 BrunoK File Added: tform-restoredbounds-unit2.zip
2020-08-27 12:09 BrunoK Note Edited: 0125151 View Revisions
2020-08-28 03:17 Joeny Ang Note Added: 0125163
2020-08-28 03:17 Joeny Ang File Added: tform-wrong-bounds-and-restored-bounds-part4.patch
2020-08-28 03:17 Joeny Ang File Added: tform-restoredbounds2-2020.08.28.zip
2020-08-28 11:16 Joeny Ang Note Added: 0125170
2020-08-28 11:16 Joeny Ang File Added: tform-wrong-bounds-and-restored-bounds-part4v2.patch
2020-08-29 15:46 Juha Manninen Relationship added related to 0037647
2020-08-29 16:46 Juha Manninen Note Added: 0125202
2020-08-29 16:47 Juha Manninen Fixed in Revision r61997, r62113, r63218, r63577 => r61997, r62113, r63218, r63577, r63842
2020-08-29 16:47 Juha Manninen Widgetset GTK 2, Win32/Win64 => GTK 2, Win32/Win64
2020-08-29 16:51 Juha Manninen Note Edited: 0125202 View Revisions
2020-08-29 17:24 Juha Manninen Note Edited: 0125202 View Revisions
2020-08-30 15:01 BrunoK Note Added: 0125216
2020-09-02 17:39 Juha Manninen Status assigned => resolved
2020-09-02 17:39 Juha Manninen Resolution open => fixed
2020-09-02 17:39 Juha Manninen Widgetset GTK 2, Win32/Win64 => GTK 2, Win32/Win64
2020-09-10 23:49 wp Relationship added related to 0037732
2020-09-11 01:14 jamie philbrook Note Added: 0125470
2020-09-11 15:40 CudaText man_ Note Added: 0125482
2020-09-11 20:05 Juha Manninen Status resolved => assigned
2020-09-11 20:05 Juha Manninen Resolution fixed => open
2020-09-11 20:05 Juha Manninen Note Added: 0125488
2020-09-12 16:15 BrunoK Note Added: 0125511
2020-09-12 16:15 BrunoK File Added: revert_form_200912.patch
2020-09-13 12:12 Juha Manninen Note Added: 0125523
2020-09-13 13:03 BrunoK Note Added: 0125525
2020-09-14 12:02 Joeny Ang Note Added: 0125536
2020-09-14 12:02 Joeny Ang File Added: tform-wrong-bounds-and-restored-bounds-part4-fix.patch
2020-09-18 11:49 Juha Manninen Note Added: 0125609
2020-09-18 11:50 Juha Manninen Status assigned => feedback
2020-09-18 13:14 CudaText man_ Note Added: 0125613
2020-09-18 21:49 josh Note Added: 0125631
2020-09-18 21:49 josh File Added: Form_events_3.zip
2020-09-18 23:21 Juha Manninen Status feedback => resolved
2020-09-18 23:21 Juha Manninen Resolution open => fixed
2020-09-18 23:21 Juha Manninen Fixed in Revision r61997, r62113, r63218, r63577, r63842 => r61997, r62113, r63218, r63577, r63842, r63888
2020-09-18 23:21 Juha Manninen Widgetset GTK 2, Win32/Win64 => GTK 2, Win32/Win64
2020-09-18 23:21 Juha Manninen Note Added: 0125632
2020-09-18 23:35 josh Note Added: 0125634
2020-09-19 10:56 Juha Manninen Relationship added related to 0037688