diff --git a/lcl/interfaces/qt/qtint.pp b/lcl/interfaces/qt/qtint.pp index d761d012c8..177add6819 100644 --- a/lcl/interfaces/qt/qtint.pp +++ b/lcl/interfaces/qt/qtint.pp @@ -260,6 +260,8 @@ const // needed by itemviews (TQtListWidget, TQtTreeWidget) LCLQt_ItemViewAfterMouseRelease = QEventType(Ord(QEventUser) + $1008); + // used by TQtTabWidget + LCLQt_DelayLayoutRequest = QEventType(Ord(QEventUser) + $1009); var QtWidgetSet: TQtWidgetSet; diff --git a/lcl/interfaces/qt/qtpagecontrol.inc b/lcl/interfaces/qt/qtpagecontrol.inc index 35c763fccd..bb70e07441 100644 --- a/lcl/interfaces/qt/qtpagecontrol.inc +++ b/lcl/interfaces/qt/qtpagecontrol.inc @@ -137,7 +137,55 @@ begin QtTabWidget.AttachEvents; Result := TLCLIntfHandle(QtTabWidget); end; +end; +class function TQtWSCustomTabControl.GetDefaultClientRect( + const AWinControl: TWinControl; const aLeft, aTop, aWidth, aHeight: integer; + var aClientRect: TRect): boolean; +var + dx, dy: integer; + ATabWidget: TQtTabWidget; +begin + Result := False; + if AWinControl.HandleAllocated then + begin + if TQtWidget(AWinControl.Handle).ChildOfComplexWidget <> ccwTTabControl then + begin + ATabWidget := TQtTabWidget(AWinControl.Handle); + if ATabWidget.testAttribute(QtWA_PendingResizeEvent) then + begin + // we must recalculate aclientrect since we have pending resize event + // and clientrect won't be accurate.issue #21805 + Result := True; + dx := GetPixelMetric(QStylePM_DefaultFrameWidth, nil, nil); + + if ATabWidget.getTabPosition in [QTabWidgetNorth, QTabWidgetSouth] then + begin + if ATabWidget.TabBar.getVisible then + dy := ATabWidget.TabBar.getHeight + else + dy := 0; + aClientRect := Rect(0, 0, + Max(0, aWidth - (dx * 2)), + Max(0, aHeight - dx - dy)); + end else + begin + if ATabWidget.TabBar.getVisible then + dy := ATabWidget.TabBar.getWidth + else + dy := 0; + aClientRect := Rect(0,0, + Max(0, aWidth - dx - dy), + Max(0, aHeight - (dx * 2))); + end; + end; + end; + end else + begin + dx := GetPixelMetric(QStylePM_TabBarBaseHeight, nil, nil); + aClientRect := Rect(0,0, Max(0, aWidth - (dx * 2)), Max(0, aHeight - (dx * 2))); + Result := True; + end; end; class procedure TQtWSCustomTabControl.AddPage(const ATabControl: TCustomTabControl; diff --git a/lcl/interfaces/qt/qtwidgets.pas b/lcl/interfaces/qt/qtwidgets.pas index 3e3601c132..9e95a9958e 100644 --- a/lcl/interfaces/qt/qtwidgets.pas +++ b/lcl/interfaces/qt/qtwidgets.pas @@ -8723,12 +8723,13 @@ end; function TQtTabWidget.EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; -{$IFDEF QT_ENABLE_LCL_PAINT_TABS} var +{$IFDEF QT_ENABLE_LCL_PAINT_TABS} R: TRect; TabGeom: TRect; Pt: TPoint; {$ENDIF} + ALCLEvent: QLCLMessageEventH; begin Result := False; @@ -8743,13 +8744,11 @@ begin ' LCLObject=', dbgsName(LCLObject), ' Event=', EventTypeToStr(Event),' inUpdate=',inUpdate); {$endif} - case QEvent_type(Event) of - QEventResize: - if LCLObject.ClientRectNeedsInterfaceUpdate then - LCLObject.InvalidateClientRectCache(False); - // layoutRequest from stacked widget is very important ! - QEventLayoutRequest: LCLObject.DoAdjustClientRectChange(False); - end; + { + we don't use QEventResize and QEventLayoutRequest of StackedWidget anymore. + see commited revision for issue #21805. + We are leaving this part for debugging purposes. + } exit; end; @@ -8771,6 +8770,25 @@ begin QEvent_ignore(Event); end; {$ENDIF} + LCLQt_DelayLayoutRequest: + begin + if LCLObject.ClientRectNeedsInterfaceUpdate then + begin + {$IFDEF VerboseQtEvents} + DebugLn('<*><*> TQtTabWidget calling DoAdjustClientRectChange() from LCLQt_DelayLayoutRequest ...'); + {$ENDIF} + LCLObject.DoAdjustClientRectChange(True); + end; + Result := True; + end; + QEventLayoutRequest: + begin + //behaviour is changed because of issue #21805. + //we send delayed event so LCL can read clientRect at the right time. + ALCLEvent := QLCLMessageEvent_create(LCLQt_DelayLayoutRequest, 0, + 0, 0, 0); + QCoreApplication_postEvent(Sender, ALCLEvent); + end; QEventKeyPress, QEventKeyRelease: QEvent_ignore(Event); QEventWheel: @@ -8829,7 +8847,7 @@ end; function TQtTabWidget.getClientBounds: TRect; begin - QWidget_contentsRect(StackWidget, @Result) + QWidget_contentsRect(StackWidget, @Result); end; function TQtTabWidget.getCurrentIndex: Integer; @@ -15285,10 +15303,21 @@ end; function TQtPage.EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; begin - if (QEvent_type(Event) = QEventResize) and - LCLObject.Parent.ClientRectNeedsInterfaceUpdate then - LCLObject.Parent.InvalidateClientRectCache(False); - Result:=inherited EventFilter(Sender, Event); + if (QEvent_type(Event) = QEventResize) then + begin + //behaviour is changed because of issue #21805. + if LCLObject.ClientRectNeedsInterfaceUpdate then + begin + {$IFDEF VerboseQtEvents} + DebugLn('<*><*> TQtPage resize event invalidating clientrect cache !!!'); + {$ENDIF} + LCLObject.InvalidateClientRectCache(False); + + if FChildOfComplexWidget = ccwTabWidget then + exit(False); + end; + end; + Result := inherited EventFilter(Sender, Event); end; function TQtPage.getIcon: QIconH; diff --git a/lcl/interfaces/qt/qtwscomctrls.pp b/lcl/interfaces/qt/qtwscomctrls.pp index 44c5929005..affe3cae0e 100644 --- a/lcl/interfaces/qt/qtwscomctrls.pp +++ b/lcl/interfaces/qt/qtwscomctrls.pp @@ -57,7 +57,9 @@ type published class function CreateHandle(const AWinControl: TWinControl; const AParams: TCreateParams): TLCLIntfHandle; override; - + class function GetDefaultClientRect(const AWinControl: TWinControl; + const {%H-}aLeft, {%H-}aTop, aWidth, aHeight: integer; var aClientRect: TRect + ): boolean; override; class procedure AddPage(const ATabControl: TCustomTabControl; const AChild: TCustomPage; const AIndex: integer); override; class procedure MovePage(const ATabControl: TCustomTabControl; @@ -262,7 +264,7 @@ type implementation -uses qtint; +uses qtint, math; {$include qtpagecontrol.inc}