Dialog does not respect footer implicit width
Kirigami Dialog, being a QQC2 Templates Dialog, is expected to follow implicit size of its content, header and footer. Also, by extension being a QQC2 Popup, it would ensure that it does not grow too large that it does not fit into its parent window.
Default QQC2 style implementation specifies the following sizing expressions:
implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset,
contentWidth + leftPadding + rightPadding,
implicitHeaderWidth,
implicitFooterWidth)
implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset,
contentHeight + topPadding + bottomPadding
+ (implicitHeaderHeight > 0 ? implicitHeaderHeight + spacing : 0)
+ (implicitFooterHeight > 0 ? implicitFooterHeight + spacing : 0))
But Kirigami overrides with lots of its own magic, and no header/footer for implicitWidth:
// calculate dimensions
implicitWidth: contentItem.implicitWidth + leftPadding + rightPadding // maximum width enforced from our content (one source of truth) to avoid binding loops
implicitHeight: contentItem.implicitHeight + topPadding + bottomPadding
+ (implicitHeaderHeight > 0 ? implicitHeaderHeight + spacing : 0)
+ (implicitFooterHeight > 0 ? implicitFooterHeight + spacing : 0);
This doesn't quite work for dialogs with standard buttons, and the implicit width of DialogButtonBox is just disregarded. Adding to the mix a semi-broken implementation of DialogButtonBox in qqc2-desktop-style, which doesn't respect explicitly given width, we get this picture:
This is a screenshot of ChangeWalletPassword.qml from Users KCM, patched to use customFooterActions
instead of custom 1-column GridLayout. Also, as far as I can tell, there is no way to scroll it horizontally either, despite the fact that the buttons are supposed to land in a horizontal ListView.
So, if we patch Kirigami.Dialog to account for footer like this:
// calculate dimensions
- implicitWidth: contentItem.implicitWidth + leftPadding + rightPadding // maximum width enforced from our content (one source of truth) to avoid binding loops
+ implicitWidth: Math.max(
+ contentItem.implicitWidth + leftPadding + rightPadding, // maximum width enforced from our content (one source of truth) to avoid binding loops
+ implicitHeaderWidth,
+ implicitFooterWidth)
footer: T.Control {
id: footerToolBar
- property bool bufferMode: contentItem.implicitHeight === 0
- implicitHeight: bufferMode ? Kirigami.Units.smallSpacing : contentItem.implicitHeight
+ property bool bufferMode: implicitContentHeight === 0
+ implicitHeight: bufferMode ? Kirigami.Units.smallSpacing :
+ Math.max(implicitContentHeight + topPadding + bottomPadding,
+ implicitBackgroundHeight + topInset + bottomInset)
+ implicitWidth:
+ Math.max(implicitContentWidth + leftPadding + rightPadding,
+ implicitBackgroundWidth + leftInset + rightInset)
…then I get a perfectly sized dialog like this:
and AFAICT I don't get any new binding loops. Not sure what that comment about "one source of truth" was referring to.
On the other hand, I don't quite understand why upstream code uses explicit content height instead of implicit counterparts.