summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorVolker Hilsheimer <volker.hilsheimer@qt.io>2020-01-22 13:51:01 +0100
committerVolker Hilsheimer <volker.hilsheimer@qt.io>2020-01-28 22:26:26 +0100
commit6e1d70ae12baae4610356ec7b69635ad75a97b4e (patch)
treefa84a818aabe41389544c2fa05ac2ca4b2ff6bb6 /src
parent94bc57213f9a8a74e9e7520de68d7bba7f42ea4c (diff)
QPushButton: only trigger button when click occurs within the bevel rect
On the mac, the push button's bevel doesn't cover the entire widget rectangle, but is smaller to leave space for focus frame, shadow, and in general to meet style guidelines. Without this change, a click anywhere inside the widget would activate the button. QAbstractButton::hitButton can be reimplemented to limit the area in which the button is triggered. However, getting the rectangle also requires an addition to QStyle, so that we can query QStyle::subElementRect for the actual area the button's bevel covers. As a side effect, tests that use QPushButton and assume that it responds to clicks at position 0,0 have to be fixed so that they don't fail on mac. Change-Id: I01b60a763bccf39090aee5b2369af300f922d226 Fixes: QTBUG-81452 Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/plugins/styles/mac/qmacstyle_mac.mm18
-rw-r--r--src/widgets/styles/qcommonstyle.cpp6
-rw-r--r--src/widgets/styles/qstyle.cpp2
-rw-r--r--src/widgets/styles/qstyle.h2
-rw-r--r--src/widgets/widgets/qpushbutton.cpp11
-rw-r--r--src/widgets/widgets/qpushbutton.h1
6 files changed, 37 insertions, 3 deletions
diff --git a/src/plugins/styles/mac/qmacstyle_mac.mm b/src/plugins/styles/mac/qmacstyle_mac.mm
index 37b658dd76..b34a304ec0 100644
--- a/src/plugins/styles/mac/qmacstyle_mac.mm
+++ b/src/plugins/styles/mac/qmacstyle_mac.mm
@@ -4613,6 +4613,7 @@ QRect QMacStyle::subElementRect(SubElement sr, const QStyleOption *opt,
case SE_ToolBoxTabContents:
rect = QCommonStyle::subElementRect(sr, opt, widget);
break;
+ case SE_PushButtonBevel:
case SE_PushButtonContents:
if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
// Comment from the old HITheme days:
@@ -4626,9 +4627,20 @@ QRect QMacStyle::subElementRect(SubElement sr, const QStyleOption *opt,
const auto ct = cocoaControlType(btn, widget);
const auto cs = d->effectiveAquaSizeConstrain(btn, widget);
const auto cw = QMacStylePrivate::CocoaControl(ct, cs);
- const auto frameRect = cw.adjustedControlFrame(btn->rect);
- const auto titleMargins = cw.titleMargins();
- rect = (frameRect - titleMargins).toRect();
+ auto frameRect = cw.adjustedControlFrame(btn->rect);
+ if (sr == SE_PushButtonContents) {
+ frameRect -= cw.titleMargins();
+ } else {
+ auto *pb = static_cast<NSButton *>(d->cocoaControl(cw));
+ if (cw.type != QMacStylePrivate::Button_SquareButton) {
+ frameRect = QRectF::fromCGRect([pb alignmentRectForFrame:pb.frame]);
+ if (cw.type == QMacStylePrivate::Button_PushButton)
+ frameRect -= pushButtonShadowMargins[cw.size];
+ else if (cw.type == QMacStylePrivate::Button_PullDown)
+ frameRect -= pullDownButtonShadowMargins[cw.size];
+ }
+ }
+ rect = frameRect.toRect();
}
break;
case SE_HeaderLabel: {
diff --git a/src/widgets/styles/qcommonstyle.cpp b/src/widgets/styles/qcommonstyle.cpp
index 1e5830d216..eb5399bd4a 100644
--- a/src/widgets/styles/qcommonstyle.cpp
+++ b/src/widgets/styles/qcommonstyle.cpp
@@ -2465,6 +2465,12 @@ QRect QCommonStyle::subElementRect(SubElement sr, const QStyleOption *opt,
r = visualRect(opt->direction, opt->rect, r);
}
break;
+ case SE_PushButtonBevel:
+ {
+ r = opt->rect;
+ r = visualRect(opt->direction, opt->rect, r);
+ }
+ break;
case SE_CheckBoxIndicator:
{
int h = proxy()->pixelMetric(PM_IndicatorHeight, opt, widget);
diff --git a/src/widgets/styles/qstyle.cpp b/src/widgets/styles/qstyle.cpp
index 72e40d657d..987465efae 100644
--- a/src/widgets/styles/qstyle.cpp
+++ b/src/widgets/styles/qstyle.cpp
@@ -1012,6 +1012,7 @@ void QStyle::drawItemPixmap(QPainter *painter, const QRect &rect, int alignment,
\value SE_PushButtonFocusRect Area for the focus rect (usually
larger than the contents rect).
\value SE_PushButtonLayoutItem Area that counts for the parent layout.
+ \value SE_PushButtonBevel Area used for the bevel of the button.
\value SE_CheckBoxIndicator Area for the state indicator (e.g., check mark).
\value SE_CheckBoxContents Area for the label (text or pixmap).
@@ -1120,6 +1121,7 @@ void QStyle::drawItemPixmap(QPainter *painter, const QRect &rect, int alignment,
\header \li Sub Element \li QStyleOption Subclass
\row \li \l SE_PushButtonContents \li \l QStyleOptionButton
\row \li \l SE_PushButtonFocusRect \li \l QStyleOptionButton
+ \row \li \l SE_PushButtonBevel \li \l QStyleOptionButton
\row \li \l SE_CheckBoxIndicator \li \l QStyleOptionButton
\row \li \l SE_CheckBoxContents \li \l QStyleOptionButton
\row \li \l SE_CheckBoxFocusRect \li \l QStyleOptionButton
diff --git a/src/widgets/styles/qstyle.h b/src/widgets/styles/qstyle.h
index ee234457f5..04628e6ef9 100644
--- a/src/widgets/styles/qstyle.h
+++ b/src/widgets/styles/qstyle.h
@@ -361,6 +361,8 @@ public:
SE_TabBarScrollRightButton,
SE_TabBarTearIndicatorRight,
+ SE_PushButtonBevel,
+
// do not add any values below/greater than this
SE_CustomBase = 0xf0000000
};
diff --git a/src/widgets/widgets/qpushbutton.cpp b/src/widgets/widgets/qpushbutton.cpp
index b0d3ba51f9..3d075bf92f 100644
--- a/src/widgets/widgets/qpushbutton.cpp
+++ b/src/widgets/widgets/qpushbutton.cpp
@@ -509,6 +509,17 @@ void QPushButton::focusOutEvent(QFocusEvent *e)
#endif
}
+/*!
+ \reimp
+*/
+bool QPushButton::hitButton(const QPoint &pos) const
+{
+ QStyleOptionButton option;
+ initStyleOption(&option);
+ const QRect bevel = style()->subElementRect(QStyle::SE_PushButtonBevel, &option, this);
+ return bevel.contains(pos);
+}
+
#if QT_CONFIG(menu)
/*!
Associates the popup menu \a menu with this push button. This
diff --git a/src/widgets/widgets/qpushbutton.h b/src/widgets/widgets/qpushbutton.h
index b02ba63d07..283dfe2c61 100644
--- a/src/widgets/widgets/qpushbutton.h
+++ b/src/widgets/widgets/qpushbutton.h
@@ -94,6 +94,7 @@ protected:
void focusInEvent(QFocusEvent *) override;
void focusOutEvent(QFocusEvent *) override;
void initStyleOption(QStyleOptionButton *option) const;
+ bool hitButton(const QPoint &pos) const override;
QPushButton(QPushButtonPrivate &dd, QWidget* parent = nullptr);
public: