D15625: Sublime: Fix crash caused when all tool view items are small
René J.V. Bertin
noreply at phabricator.kde.org
Mon Sep 24 12:25:21 BST 2018
rjvbb requested changes to this revision.
rjvbb added a comment.
This revision now requires changes to proceed.
It works and can go in with just one minor change request.
I still need the fallback protection though. I added some additional debug output (see below) which shows what is really going on for me: maximumWidth is calculated to be 0. I haven't tried to figure out if that's an anomaly, but it explains why I'm getting only small items.
This happens only with my QtCurve style; if you want to bite in deeper I can share my settings (and fonts, if needed).
diff --git a/kdevplatform/sublime/ideallayout.cpp b/kdevplatform/sublime/ideallayout.cpp
index 8bc43479197dfb1b018b780c116034c3f1fc7e69..4157743641fc8024e1d5b8813ccac52b66e71a5c 100644
--- a/kdevplatform/sublime/ideallayout.cpp
+++ b/kdevplatform/sublime/ideallayout.cpp
@@ -22,6 +22,8 @@
#include "ideallayout.h"
+#include <debug.h>
+
#include <QStyle>
#include <QWidget>
@@ -202,25 +204,36 @@ int IdealButtonBarLayout::doVerticalLayout(const QRect &rect, bool updateGeometr
return x + currentLineWidth + r;
}
- const bool shrink = rect.height() < sizeHint().height();
+ bool shrink = rect.height() < sizeHint().height();
- const int maximumHeight = rect.height() / _items.size();
+ // space left per button after removing available space for buttonSpacing
+ const int maximumHeight = (rect.height() - buttonSpacing * (_items.size() - 1)) / _items.size();
int shrinkedHeight = -1;
if (shrink) {
int smallItemCount = 0;
- const int surplus = std::accumulate(_items.begin(), _items.end(), 0, [maximumHeight, &smallItemCount](int acc, QLayoutItem* item) {
+ int minHeight = _items.at(0)->sizeHint().height();
+ const int surplus = std::accumulate(_items.begin(), _items.end(), 0, [maximumHeight, &smallItemCount, &minHeight](int acc, QLayoutItem* item) {
const int itemHeight = item->sizeHint().height();
if (itemHeight <= maximumHeight) {
acc += maximumHeight - itemHeight;
++smallItemCount;
}
+ if (itemHeight < minHeight) {
+ minHeight = itemHeight;
+ }
return acc;
});
- Q_ASSERT(_items.size() != smallItemCount); // should be true since rect.width != sizeHint.width
- // evenly distribute surplus height over large items
- shrinkedHeight = maximumHeight + surplus / (_items.size() - smallItemCount);
+ // Sanity check to prevent against a divide-by-zero due to some latent miscalculations
+ if (_items.size() != smallItemCount) {
+ // evenly distribute surplus height over large items
+ shrinkedHeight = maximumHeight + surplus / (_items.size() - smallItemCount);
+ } else {
+ qCDebug(SUBLIME) << "Expected at least one large item, none found, possible erraneous shrink predicate or sizeHint";
+ qCDebug(SUBLIME) << "\tthreshold height=" << maximumHeight << "min width found:" << minHeight;
+ shrink = false;
+ }
}
for (QLayoutItem* item : _items) {
@@ -260,25 +273,36 @@ int IdealButtonBarLayout::doHorizontalLayout(const QRect &rect, bool updateGeome
return y + currentLineHeight + b;
}
- const bool shrink = rect.width() < sizeHint().width();
+ bool shrink = rect.width() < sizeHint().width();
- const int maximumWidth = rect.width() / _items.size();
+ // space left per button after removing available space for buttonSpacing
+ const int maximumWidth = (rect.width() - buttonSpacing * (_items.size() - 1)) / _items.size();
int shrinkedWidth = -1;
if (shrink) {
int smallItemCount = 0;
- const int surplus = std::accumulate(_items.begin(), _items.end(), 0, [maximumWidth, &smallItemCount](int acc, QLayoutItem* item) {
+ int minWidth = _items.at(0)->sizeHint().width();
+ const int surplus = std::accumulate(_items.begin(), _items.end(), 0, [maximumWidth, &smallItemCount, &minWidth](int acc, QLayoutItem* item) {
const int itemWidth = item->sizeHint().width();
if (itemWidth <= maximumWidth) {
acc += maximumWidth - itemWidth;
++smallItemCount;
}
+ if (itemWidth < minWidth) {
+ minWidth = itemWidth;
+ }
return acc;
});
- Q_ASSERT(_items.size() != smallItemCount); // should be true since rect.width != sizeHint.width
- // evenly distribute surplus width on the large items
- shrinkedWidth = maximumWidth + surplus / (_items.size() - smallItemCount);
+ // Sanity check to prevent against a divide-by-zero due to some latent miscalculations
+ if (_items.size() != smallItemCount) {
+ // evenly distribute surplus width on the large items
+ shrinkedWidth = maximumWidth + surplus / (_items.size() - smallItemCount);
+ } else {
+ qCDebug(SUBLIME) << "Expected at least one large item, none found, possible erraneous shrink predicate or sizeHint";
+ qCDebug(SUBLIME) << "\tthreshold width=" << maximumWidth << "min width found:" << minWidth;
+ shrink = false;
+ }
}
for (QLayoutItem* item : _items) {
INLINE COMMENTS
> ideallayout.cpp:293
> + } else {
> + qCWarning(SUBLIME) << "Expected at least one large item, none found, possible erraneous shrink predicate or sizeHint";
> + shrink = false;
Please make this a qCDebug; no need to bother the user with this information because it will be printed really lots of times if the situation arises.
REPOSITORY
R32 KDevelop
REVISION DETAIL
https://phabricator.kde.org/D15625
To: amhndu, #kdevelop, kossebau, rjvbb
Cc: kossebau, rjvbb, kdevelop-devel, glebaccon, antismap, iodelay, vbspam, geetamc, Pilzschaf, akshaydeo, surgenight, arrowd
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.kde.org/pipermail/kdevelop-devel/attachments/20180924/093ee81e/attachment.html>
More information about the KDevelop-devel
mailing list