qtresize_refactor.diff (19,168 bytes)
Index: lcl/interfaces/qt/qtwidgets.pas
===================================================================
--- lcl/interfaces/qt/qtwidgets.pas (revision 44962)
+++ lcl/interfaces/qt/qtwidgets.pas (working copy)
@@ -2168,8 +2168,7 @@
Params: None
Returns: Boolean
Checks if our control can call LCLObject.DoAdjustClientRect from SlotResize.
- eg. TQtCustomControl does not call it since DoAdjustClientRect is called
- from TQtViewport.EventFilter.This avoids deadlocks with autosizing.
+ This avoids deadlocks with autosizing.
------------------------------------------------------------------------------}
function TQtWidget.CanAdjustClientRectOnResize: Boolean;
begin
@@ -2375,6 +2374,8 @@
QtEdit: IQtEdit;
R: TRect;
Pt: TQtPoint;
+ ANewSize: TSize;
+ AResizeEvent: QResizeEventH;
begin
BeginEventProcessing;
Result := False;
@@ -2390,6 +2391,24 @@
if LCLObject <> nil then
begin
case QEvent_type(Event) of
+ LCLQt_DelayResizeEvent:
+ begin
+ ANewSize.cx := Lo(QLCLMessageEvent_getWParam(QLCLMessageEventH(Event)));
+ ANewSize.cy := Hi(QLCLMessageEvent_getWParam(QLCLMessageEventH(Event)));
+ AResizeEvent := QResizeEvent_create(@ANewSize, @ANewSize);
+ try
+ {$IF DEFINED(VerboseSizeIntf) OR DEFINED(VerboseQtResize)}
+ DebugLn('>LCLQt_DelayResizeEvent: ',dbgsName(LCLObject),' casp=',dbgs(caspComputingBounds in LCLObject.AutoSizePhases));
+ {$ENDIF}
+ SlotResize(AResizeEvent);
+ {$IF DEFINED(VerboseSizeIntf) OR DEFINED(VerboseQtResize)}
+ DebugLn('<LCLQt_DelayResizeEvent: ',dbgsName(LCLObject),' casp=',dbgs(caspComputingBounds in LCLObject.AutoSizePhases));
+ {$ENDIF}
+ finally
+ QResizeEvent_destroy(AResizeEvent);
+ end;
+ Result := True;
+ end;
QEventFontChange:
begin
//explanation for this event usage: issue #19695
@@ -2510,7 +2529,17 @@
end;
QEventMove: SlotMove(Event);
QEventResize: SlotResize(Event);
- QEventContentsRectChange: LCLObject.DoAdjustClientRectChange(False);
+ QEventContentsRectChange:
+ begin
+ if LCLObject.ClientRectNeedsInterfaceUpdate then
+ begin
+ {$IF DEFINED(VerboseSizeIntf) OR DEFINED(VerboseQtResize)}
+ DebugLn('WARNING: QEventContentsRectChange adjusting rect for ',dbgsName(LCLObject),' PHASE ? ',dbgs(caspComputingBounds in LCLObject.AutoSizePhases),' inUpdate=',dbgs(inUpdate),' Time: ',dbgs(GetTickCount));
+ {$ENDIF}
+ if not (caspComputingBounds in LCLObject.AutoSizePhases) then
+ LCLObject.DoAdjustClientRectChange(True);
+ end;
+ end;
QEventPaint:
begin
if canPaintBackground and (LCLObject.Color <> clDefault) then
@@ -3983,6 +4012,16 @@
var
Msg: TLMSize;
NewSize: TSize;
+ R: TRect;
+
+ procedure DelayResizeEvent;
+ var
+ ALCLResizeEvent: QLCLMessageEventH;
+ begin
+ ALCLResizeEvent := QLCLMessageEvent_create(LCLQt_DelayResizeEvent, 0, MakeWParam(Word(NewSize.cx), Word(NewSize.cy)), 0, 0);
+ QCoreApplication_postEvent(Widget, ALCLResizeEvent);
+ end;
+
begin
{$ifdef VerboseQt}
WriteLn('TQtWidget.SlotResize');
@@ -4012,9 +4051,20 @@
exit;
if CanAdjustClientRectOnResize and
- ((NewSize.cx <> LCLObject.Width) or (NewSize.cy <> LCLObject.Height) or
- LCLObject.ClientRectNeedsInterfaceUpdate) then
- LCLObject.DoAdjustClientRectChange;
+ LCLObject.ClientRectNeedsInterfaceUpdate then
+ begin
+ // postpone resize event if we are computingbounds otherwise
+ // we can run into infinite size loop.
+ if (caspComputingBounds in LCLObject.AutoSizePhases) then
+ begin
+ {$IF DEFINED(VerboseSizeIntf) OR DEFINED(VerboseQtResize)}
+ DebugLn('WARNING: *TQtWidget.SlotResize caspComputingBounds=true* ! ',dbgsname(LCLObject),' inUpdate=',dbgs(inUpdate),' Time: ',dbgs(GetTickCount));
+ {$ENDIF}
+ DelayResizeEvent;
+ exit;
+ end else
+ LCLObject.DoAdjustClientRectChange;
+ end;
FillChar(Msg, SizeOf(Msg), #0);
@@ -6093,7 +6143,7 @@
function TQtWindowArea.CanAdjustClientRectOnResize: Boolean;
begin
- Result := False;
+ Result := True;
end;
procedure TQtWindowArea.DetachEvents;
@@ -6143,6 +6193,8 @@
function TQtWindowArea.ScrollViewEventFilter(Sender: QObjectH; Event: QEventH
): Boolean; cdecl;
var
+ ASize: TSize;
+ AResizeEvent: QResizeEventH;
HaveVertBar, HaveHorzBar: Boolean;
ScrollBar: QScrollBarH;
begin
@@ -6158,24 +6210,17 @@
case QEvent_type(Event) of
QEventResize:
begin
- // immediate update clientRect !
if FOwner <> nil then
begin
- HaveVertBar := Assigned(FVScrollbar);
- HaveHorzBar := Assigned(FHScrollbar);
- if (caspComputingBounds in LCLObject.AutoSizePhases) then
- begin
- {$IF DEFINED(VerboseQt) OR DEFINED(VerboseQtCustomControlResizeDeadlock)}
- writeln('*** INTERCEPTED RESIZE DEADLOCK *** ',LCLObject.ClassName,
- ':',LCLObject.Name);
- {$ENDIF}
- {$IFDEF QTSCROLLABLEFORMS}
- // do not invalidate clientRectCache if we are embedded (eg. docked)
- if not Assigned(LCLObject.Parent) then
- LCLObject.InvalidateClientRectCache(True);
- {$ENDIF}
- end else
- LCLObject.DoAdjustClientRectChange(HaveVertBar or HaveHorzBar);
+ {TQtMainWindow does not send resize event if ScrollArea is assigned,
+ it is done here when viewport geometry is finally updated by Qt.}
+ ASize := FOwner.getSize;
+ AResizeEvent := QResizeEvent_create(@ASize, @ASize);
+ try
+ SlotResize(AResizeEvent);
+ finally
+ QEvent_destroy(AResizeEvent);
+ end;
end else
LCLObject.DoAdjustClientRectChange;
end;
@@ -6213,10 +6258,15 @@
QEventLayoutRequest:
begin
- with TQtMainWindow(FOwner) do
+ if FOwner <> nil then
begin
- if Self.LCLObject.ClientRectNeedsInterfaceUpdate then
- Self.LCLObject.DoAdjustClientRectChange(True);
+ if LCLObject.ClientRectNeedsInterfaceUpdate then
+ begin
+ {$IF DEFINED(VerboseSizeIntf) OR DEFINED(VerboseQtResize)}
+ DebugLn('TQtWindowArea.Viewport: ',dbgsName(LCLObject),' QEventLayoutRequest calling DoAdjustClientRectChange CASP=',dbgs(caspComputingBounds in LCLObject.AutoSizePhases),' ***** !!!! ');
+ {$ENDIF}
+ Self.LCLObject.DoAdjustClientRectChange(True);
+ end;
end;
end;
end;
@@ -6777,9 +6827,16 @@
if (Result) and (QEvent_type(Event) = QEventDrop) then
Result := slotDropFiles(Sender, Event);
end;
+ QEventResize:
+ begin
+ {$IFDEF QTSCROLLABLEFORMS}
+ if not Assigned(ScrollArea) then
+ {$ENDIF}
+ Result := inherited EventFilter(Sender, Event);
+ end;
QEventPaint:
begin
- {do not send paint event to LCL if we are pure TCustomForm,
+ {do not send paint or resize event to LCL if we are pure TCustomForm,
CWEvent or ScrollArea.EventFilter will process it.
So call SlotPaint only if we are eg TQtHintWindow.}
if (FCentralWidget = nil) or (FCentralWidget = Widget) then
@@ -7052,15 +7109,13 @@
begin
{first must get contents rect - all except main menu}
QWidget_contentsRect(FCentralWidget, @R);
-
{TODO: find better way to find out which controls are top,left,right & bottom aligned ...}
for i := 0 to LCLObject.ComponentCount - 1 do
begin
-
{find statusbars}
if LCLObject.Components[i] is TStatusBar then
begin
- R2 := TWinControl(LCLObject.Components[i]).ClientRect;
+ R2 := TWinControl(LCLObject.Components[i]).BoundsRect;
case TWinControl(LCLObject.Components[i]).Align of
alLeft: R.Left := R.Left + (R2.Right - R2.Left);
alTop: R.Top := R.Top + (R2.Bottom - R2.Top);
@@ -7072,7 +7127,7 @@
{find toolbars}
if LCLObject.Components[i] is TToolBar then
begin
- R2 := TWinControl(LCLObject.Components[i]).ClientRect;
+ R2 := TWinControl(LCLObject.Components[i]).BoundsRect;
case TWinControl(LCLObject.Components[i]).Align of
alLeft: R.Left := R.Left + (R2.Right - R2.Left);
alTop: R.Top := R.Top + (R2.Bottom - R2.Top);
@@ -7082,11 +7137,9 @@
end;
end; {components loop}
-
QWidget_setGeometry(MDIAreaHandle.Widget, @R);
end;
{mdi area part end}
-
end;
end;
end;
@@ -7724,17 +7777,6 @@
{$ifdef VerboseQt}
writeln('TQtAbstractSlider.rangeChanged() to min=',minimum,' max=',maximum);
{$endif}
- {$IFDEF QTSCROLLABLEFORMS}
- if (FOwner <> nil) and Assigned(FOwner.LCLObject) and
- (FOwner is TQtWindowArea) and
- not (caspComputingBounds in FOwner.LCLObject.AutoSizePhases) then
- LCLObject.InvalidateClientRectCache(True)
- else
- {$ENDIF}
- if (FOwner <> nil) and Assigned(FOwner.LCLObject) and
- (FOwner.FChildOfComplexWidget = ccwScrollingWinControl) and
- not (caspComputingBounds in FOwner.LCLObject.AutoSizePhases) then
- LCLObject.InvalidateClientRectCache(True);
end;
{------------------------------------------------------------------------------
@@ -7953,13 +7995,10 @@
if not InUpdate or (getVisible and ((p1=getMin) or b)) then
begin
- if b and (FChildOfComplexWidget = ccwAbstractScrollArea) then
- begin
- LCLObject.DoAdjustClientRectChange;
- if not InUpdate and getVisible then
+ if b and (FChildOfComplexWidget = ccwAbstractScrollArea) and
+ not InUpdate and getVisible then
QAbstractSlider_triggerAction(QAbstractSliderH(Widget),
QAbstractSliderSliderToMaximum);
- end;
end;
end;
@@ -8212,8 +8251,18 @@
end;
end;
end;
- QEventHide:
+ QEventHide, QEventShow:
begin
+ {$IFDEF VerboseQtResize}
+ if (FOwner <> nil) then
+ begin
+ if (QEvent_type(Event) = QEventShow) then
+ DebugLn('>>>>>>>>>>>>>>>>> TQtScrollbar QEventShow orientation=',dbgs(getOrientation))
+ else
+ DebugLn('>>>>>>>>>>>>>>>>> TQtScrollbar QEventHide orientation=',dbgs(getOrientation));
+ end;
+ {$ENDIF}
+
{$IFDEF QTSCROLLABLEFORMS}
if Assigned(FOwner) and (FOwner is TQtWindowArea) then
begin
@@ -8227,11 +8276,40 @@
if Assigned(FOwner) and (FOwner is TQtCustomControl) then
begin
if Assigned(TQtCustomControl(FOwner).FViewPortWidget) then
+ begin
case getOrientation of
QtVertical: TQtCustomControl(FOwner).FViewPortWidget.FScrollY := 0;
QtHorizontal: TQtCustomControl(FOwner).FViewPortWidget.FScrollX := 0;
end;
+ // this can fail with infinite loop like in gtk2 in case of ide main bar resizing
+ // don't know what to do since ClientRectNeedsInterfaceUpdate and caspComputing is enabled
+ if LCLObject.ClientRectNeedsInterfaceUpdate then
+ begin
+ {$IFDEF VerboseQtResize}
+ if QEvent_Type(Event) = QEventShow then
+ writeln('TQtScrollBar.EventFilter(SHOW) for bar ',getOrientation,' cliRect ',LCLObject.ClientRectNeedsInterfaceUpdate,' caps ',caspComputingBounds in LCLObject.AutoSizePhases,
+ ' QtWaVisible ',testAttribute(QtWA_WState_Visible),' QtWAHidden ',testAttribute(QtWA_WState_Hidden),
+ ' QtWaExpl ',testAttribute(QtWA_WState_ExplicitShowHide),' VtoP=',getVisibleTo(getParent))
+ else
+ writeln('TQtScrollBar.EventFilter(HIDE) for bar ',getOrientation,' cliRect ',LCLObject.ClientRectNeedsInterfaceUpdate,' caps ',caspComputingBounds in LCLObject.AutoSizePhases,
+ ' QtWaVisible ',testAttribute(QtWA_WState_Visible),' QtWAHidden ',testAttribute(QtWA_WState_Hidden),
+ ' QtWaExpl ',testAttribute(QtWA_WState_ExplicitShowHide),' VtoP=',getVisibleTo(getParent));
+ {$ENDIF}
+ LCLObject.DoAdjustClientRectChange(not (caspComputingBounds in LCLObject.AutoSizePhases));
+ Result := caspComputingBounds in LCLObject.AutoSizePhases;
+
+ end;
+ end;
end;
+ {$IFDEF VerboseQtResize}
+ if (FOwner <> nil) then
+ begin
+ if (QEvent_type(Event) = QEventShow) then
+ DebugLn('<<<<<<<<<<<<<<<<< TQtScrollbar QEventShow orientation=',dbgs(getOrientation))
+ else
+ DebugLn('<<<<<<<<<<<<<<<<< TQtScrollbar QEventHide orientation=',dbgs(getOrientation));
+ end;
+ {$ENDIF}
if FOwnWidget then
Result := inherited EventFilter(Sender, Event);
end;
@@ -9501,6 +9579,8 @@
Pt: TPoint;
{$ENDIF}
ALCLEvent: QLCLMessageEventH;
+ ASize: TSize;
+ AResizeEvent: QResizeEventH;
begin
Result := False;
@@ -9516,15 +9596,24 @@
' Event=', EventTypeToStr(Event),' inUpdate=',inUpdate);
{$endif}
{
- we don't use QEventResize and QEventLayoutRequest of StackedWidget anymore.
- see commited revision for issue #21805.
- We are leaving this part for debugging purposes.
+ main resize event should come from FStackWidget, not from QTabWidget,
+ after FStackWidget is resized by Qt to it's final size.
+ QTabWidget don't send QResizeEvent to LCL.
}
+ ASize := getSize;
+ AResizeEvent := QResizeEvent_create(@ASize, @ASize);
+ try
+ SlotResize(AResizeEvent);
+ finally
+ QEvent_destroy(AResizeEvent);
+ end;
+
exit;
end;
BeginEventProcessing;
case QEvent_type(Event) of
+ QEventResize: ; // stackwidget does that, look above
{$IFDEF QT_ENABLE_LCL_PAINT_TABS}
QEventPaint:
begin
@@ -9545,7 +9634,7 @@
begin
if LCLObject.ClientRectNeedsInterfaceUpdate then
begin
- {$IFDEF VerboseQtEvents}
+ {$IF DEFINED(VerboseQtEvents) OR DEFINED(VerboseQtResize)}
DebugLn('<*><*> TQtTabWidget calling DoAdjustClientRectChange() from LCLQt_DelayLayoutRequest ...');
{$ENDIF}
LCLObject.DoAdjustClientRectChange(True);
@@ -14834,12 +14923,12 @@
ACtl := TQtMainWindow(Window).LCLObject;
if Assigned(ACtl) and not (csDestroying in ACtl.ComponentState) then
begin
- {$IFDEF VerboseQtEvents}
+ {$IF DEFINED(VerboseQtEvents) OR DEFINED(VerboseQtResize)}
DebugLn('TQtMenuBar.EventFilter: before DoAdjustClientRecChange=',
dbgs(ACtl.ClientRect));
{$ENDIF}
ACtl.DoAdjustClientRectChange(True);
- {$IFDEF VerboseQtEvents}
+ {$IF DEFINED(VerboseQtEvents) OR DEFINED(VerboseQtResize)}
DebugLn('TQtMenuBar.EventFilter: after DoAdjustClientRecChange=',
dbgs(ACtl.ClientRect));
{$ENDIF}
@@ -15338,9 +15427,9 @@
function TQtViewPort.EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
var
- HaveVertBar: Boolean;
- HaveHorzBar: Boolean;
ScrollBar: QScrollBarH;
+ ASize: TSize;
+ AResizeEvent: QResizeEventH;
begin
Result := False;
{$IF DEFINED(VerboseQt) OR DEFINED(VerboseQtEvents)}
@@ -15357,17 +15446,22 @@
// immediate update clientRect !
if FOwner <> nil then
begin
- HaveVertBar := Assigned(TQtCustomControl(FOwner).FVScrollbar);
- HaveHorzBar := Assigned(TQtCustomControl(FOwner).FHScrollbar);
- if (caspComputingBounds in LCLObject.AutoSizePhases) then
- {$IF DEFINED(VerboseQt) OR DEFINED(VerboseQtCustomControlResizeDeadlock)}
- writeln('*** INTERCEPTED RESIZE DEADLOCK *** ',LCLObject.ClassName,
- ':',LCLObject.Name)
- {$ENDIF}
- else
- LCLObject.DoAdjustClientRectChange(HaveVertBar or HaveHorzBar);
+ {TQtCustomControl does not send resize event, it is done here
+ when viewport geometry is finally updated by Qt.}
+ ASize := FOwner.getSize;
+ AResizeEvent := QResizeEvent_create(@ASize, @ASize);
+ try
+ SlotResize(AResizeEvent);
+ finally
+ QEvent_destroy(AResizeEvent);
+ end;
end else
+ begin
+ {$IF DEFINED(VerboseQtEvents) OR DEFINED(VerboseQtResize)}
+ DebugLn('TQtViewport: QEventResize wrong call....possible ERROR');
+ {$ENDIF}
LCLObject.DoAdjustClientRectChange;
+ end;
end;
QEventWheel:
if not getEnabled then
@@ -15403,11 +15497,16 @@
QEventLayoutRequest:
begin
- with TQtCustomControl(FOwner) do
+ if FOwner <> nil then
begin
- if (ChildOfComplexWidget = ccwScrollingWinControl) and
- Self.LCLObject.ClientRectNeedsInterfaceUpdate then
- Self.LCLObject.DoAdjustClientRectChange(True);
+ if LCLObject.ClientRectNeedsInterfaceUpdate then
+ begin
+ {$IF DEFINED(VerboseQtEvents) OR DEFINED(VerboseQtResize) OR DEFINED(VerboseSizeIntf)}
+ if caspComputingBounds in LCLObject.AutoSizePhases then
+ DebugLn('TQtViewport of ',dbgsName(LCLObject),' QEventLayoutRequest calling DoAdjustClientRectChange. CASP=TRUE *** !!!!');
+ {$ENDIF}
+ LCLObject.DoAdjustClientRectChange(True);
+ end;
end;
end;
else
@@ -15800,6 +15899,7 @@
if (QEvent_type(Event) in [
QEventPaint,
+ QEventResize, // TQtViewport.EventFilter sends resize !
QEventMouseButtonPress,
QEventMouseButtonRelease,
QEventMouseButtonDblClick,
@@ -15894,7 +15994,7 @@
function TQtCustomControl.CanAdjustClientRectOnResize: Boolean;
begin
// DoAdjustClientRectChange(); is called from TQtViewport resize event !
- Result := False;
+ Result := True;
end;
{------------------------------------------------------------------------------
@@ -16587,7 +16687,7 @@
//behaviour is changed because of issue #21805.
if LCLObject.ClientRectNeedsInterfaceUpdate then
begin
- {$IFDEF VerboseQtEvents}
+ {$IF DEFINED(VerboseSizeIntf) OR DEFINED(VerboseQtResize)}
DebugLn('<*><*> TQtPage resize event invalidating clientrect cache !!!');
{$ENDIF}
LCLObject.InvalidateClientRectCache(False);
Index: lcl/interfaces/qt/qtint.pp
===================================================================
--- lcl/interfaces/qt/qtint.pp (revision 44962)
+++ lcl/interfaces/qt/qtint.pp (working copy)
@@ -274,6 +274,8 @@
LCLQt_ItemViewAfterMouseRelease = QEventType(Ord(QEventUser) + $1008);
// used by TQtTabWidget
LCLQt_DelayLayoutRequest = QEventType(Ord(QEventUser) + $1009);
+ // delayed resize event if wincontrol is computing bounds
+ LCLQt_DelayResizeEvent = QEventType(Ord(QEventUser) + $1010);
QtTextSingleLine = $0100;