diff options
Diffstat (limited to 'src/plugins/styles')
-rw-r--r-- | src/plugins/styles/mac/qmacstyle_mac.mm | 89 | ||||
-rw-r--r-- | src/plugins/styles/windowsvista/qwindowsvistastyle.cpp | 28 | ||||
-rw-r--r-- | src/plugins/styles/windowsvista/qwindowsxpstyle.cpp | 16 |
3 files changed, 70 insertions, 63 deletions
diff --git a/src/plugins/styles/mac/qmacstyle_mac.mm b/src/plugins/styles/mac/qmacstyle_mac.mm index 45da5fbd84..dd7959f3cf 100644 --- a/src/plugins/styles/mac/qmacstyle_mac.mm +++ b/src/plugins/styles/mac/qmacstyle_mac.mm @@ -143,22 +143,12 @@ static QWindow *qt_getWindow(const QWidget *widget) return widget ? widget->window()->windowHandle() : 0; } -@interface QT_MANGLE_NAMESPACE(NotificationReceiver) : NSObject { -QMacStylePrivate *mPrivate; -} -- (id)initWithPrivate:(QMacStylePrivate *)priv; -- (void)scrollBarStyleDidChange:(NSNotification *)notification; +@interface QT_MANGLE_NAMESPACE(NotificationReceiver) : NSObject @end QT_NAMESPACE_ALIAS_OBJC_CLASS(NotificationReceiver); @implementation NotificationReceiver -- (id)initWithPrivate:(QMacStylePrivate *)priv -{ - self = [super init]; - mPrivate = priv; - return self; -} - (void)scrollBarStyleDidChange:(NSNotification *)notification { @@ -1880,20 +1870,46 @@ NSCell *QMacStylePrivate::cocoaCell(CocoaControl widget) const return cell; } -void QMacStylePrivate::drawNSViewInRect(NSView *view, const QRectF &qtRect, QPainter *p, +void QMacStylePrivate::drawNSViewInRect(NSView *view, const QRectF &rect, QPainter *p, __attribute__((noescape)) DrawRectBlock drawRectBlock) const { QMacCGContext ctx(p); setupNSGraphicsContext(ctx, YES); - const CGRect rect = qtRect.toCGRect(); + // FIXME: The rect that we get in is relative to the widget that we're drawing + // style on behalf of, and doesn't take into account the offset of that widget + // to the widget that owns the backingstore, which we are placing the native + // view into below. This means most of the views are placed in the upper left + // corner of backingStoreNSView, which does not map to where the actual widget + // is, and which may cause problems such as triggering a setNeedsDisplay of the + // backingStoreNSView for the wrong rect. We work around this by making the view + // layer-backed, which prevents triggering display of the backingStoreNSView, but + // but there may be other issues lurking here due to the wrong position. QTBUG-68023 + view.wantsLayer = YES; + + // FIXME: We are also setting the frame of the incoming view a lot at the call + // sites of this function, making it unclear who's actually responsible for + // maintaining the size and position of the view. In theory the call sites + // should ensure the _size_ of the view is correct, and then let this code + // take care of _positioning_ the view at the right place inside backingStoreNSView. + // For now we pass on the rect as is, to prevent any regressions until this + // can be investigated properly. + view.frame = rect.toCGRect(); [backingStoreNSView addSubview:view]; - view.frame = rect; + + // FIXME: Based on the code below, this method isn't drawing an NSView into + // a rect, it's drawing _part of the NSView_, defined by the incoming clip + // or dirty rect, into the current graphics context. We're doing some manual + // translations at the call sites that would indicate that this relationship + // is a bit fuzzy. + const CGRect dirtyRect = rect.toCGRect(); + if (drawRectBlock) - drawRectBlock(ctx, rect); + drawRectBlock(ctx, dirtyRect); else - [view drawRect:rect]; + [view drawRect:dirtyRect]; + [view removeFromSuperviewWithoutNeedingDisplay]; restoreNSGraphicsContext(ctx); @@ -1910,7 +1926,7 @@ QMacStyle::QMacStyle() Q_D(QMacStyle); QMacAutoReleasePool pool; - d->receiver = [[NotificationReceiver alloc] initWithPrivate:d]; + d->receiver = [[NotificationReceiver alloc] init]; [[NSNotificationCenter defaultCenter] addObserver:d->receiver selector:@selector(scrollBarStyleDidChange:) name:NSPreferredScrollerStyleDidChangeNotification @@ -2794,8 +2810,7 @@ void QMacStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPai { Q_D(const QMacStyle); QMacCGContext cg(p); - QWindow *window = w && w->window() ? w->window()->windowHandle() : - QStyleHelper::styleObjectWindow(opt->styleObject); + QWindow *window = w && w->window() ? w->window()->windowHandle() : nullptr; d->resolveCurrentNSView(window); switch (pe) { case PE_IndicatorArrowUp: @@ -3110,8 +3125,7 @@ void QMacStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPai tf.bezeled = YES; static_cast<NSTextFieldCell *>(tf.cell).bezelStyle = isRounded ? NSTextFieldRoundedBezel : NSTextFieldSquareBezel; tf.frame = opt->rect.toCGRect(); - d->drawNSViewInRect(tf, opt->rect, p, ^(CGContextRef ctx, const CGRect &rect) { - Q_UNUSED(ctx); + d->drawNSViewInRect(tf, opt->rect, p, ^(CGContextRef, const CGRect &rect) { [tf.cell drawWithFrame:rect inView:tf]; }); } else { @@ -3240,8 +3254,7 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter { Q_D(const QMacStyle); QMacCGContext cg(p); - QWindow *window = w && w->window() ? w->window()->windowHandle() : - QStyleHelper::styleObjectWindow(opt->styleObject); + QWindow *window = w && w->window() ? w->window()->windowHandle() : nullptr; d->resolveCurrentNSView(window); switch (ce) { case CE_HeaderSection: @@ -3442,7 +3455,7 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter pb.enabled = isEnabled; [pb highlight:isPressed]; pb.state = isHighlighted && !isPressed ? NSOnState : NSOffState; - d->drawNSViewInRect(pb, frameRect, p, ^(CGContextRef __unused ctx, const CGRect &r) { + d->drawNSViewInRect(pb, frameRect, p, ^(CGContextRef, const CGRect &r) { [pb.cell drawBezelWithFrame:r inView:pb.superview]; }); [pb highlight:NO]; @@ -4184,7 +4197,7 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter const auto cw = QMacStylePrivate::CocoaControl(ct, QStyleHelper::SizeLarge); auto *sv = static_cast<NSSplitView *>(d->cocoaControl(cw)); sv.frame = opt->rect.toCGRect(); - d->drawNSViewInRect(sv, opt->rect, p, ^(CGContextRef __unused ctx, const CGRect &rect) { + d->drawNSViewInRect(sv, opt->rect, p, ^(CGContextRef, const CGRect &rect) { [sv drawDividerInRect:rect]; }); } else { @@ -4815,8 +4828,7 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex { Q_D(const QMacStyle); QMacCGContext cg(p); - QWindow *window = widget && widget->window() ? widget->window()->windowHandle() : - QStyleHelper::styleObjectWindow(opt->styleObject); + QWindow *window = widget && widget->window() ? widget->window()->windowHandle() : nullptr; d->resolveCurrentNSView(window); switch (cc) { case CC_ScrollBar: @@ -5191,7 +5203,7 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex } pb.frame = frameRect.toCGRect(); [pb highlight:isPressed]; - d->drawNSViewInRect(pb, frameRect, p, ^(CGContextRef __unused ctx, const CGRect &r) { + d->drawNSViewInRect(pb, frameRect, p, ^(CGContextRef, const CGRect &r) { [pb.cell drawBezelWithFrame:r inView:pb.superview]; }); } else if (cw.type == QMacStylePrivate::ComboBox) { @@ -5207,7 +5219,7 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex // TODO Render to pixmap and darken the button manually } - d->drawNSViewInRect(cb, frameRect, p, ^(CGContextRef __unused ctx, const CGRect &r) { + d->drawNSViewInRect(cb, frameRect, p, ^(CGContextRef, const CGRect &r) { // FIXME This is usually drawn in the control's superview, but we wouldn't get inactive look in this case [cb.cell drawWithFrame:r inView:cb]; }); @@ -5279,13 +5291,10 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex Q_UNUSED(isHovered); // FIXME No public API for this const auto buttonRect = proxy()->subControlRect(CC_TitleBar, titlebar, sc, widget); - const auto drawBlock = ^ (CGContextRef ctx, const CGRect &rect) { - Q_UNUSED(ctx); - Q_UNUSED(rect); + d->drawNSViewInRect(wb, buttonRect, p, ^(CGContextRef, const CGRect &rect) { auto *wbCell = static_cast<NSButtonCell *>(wb.cell); [wbCell drawWithFrame:rect inView:wb]; - }; - d->drawNSViewInRect(wb, buttonRect, p, drawBlock); + }); } } @@ -5350,12 +5359,6 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex d->drawToolbarButtonArrow(tb, p); } if (tb->state & State_On) { - QWindow *window = 0; - if (widget && widget->window()) - window = widget->window()->windowHandle(); - else if (opt->styleObject) - window = opt->styleObject->property("_q_styleObjectWindow").value<QWindow *>(); - NSView *view = window ? (NSView *)window->winId() : nil; bool isKey = false; if (view) @@ -5394,8 +5397,8 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex pb.enabled = isEnabled; [pb highlight:isPressed]; pb.state = isHighlighted && !isPressed ? NSOnState : NSOffState; - const auto buttonRect = proxy()->subControlRect(cc, tb, SC_ToolButton, widget); - d->drawNSViewInRect(pb, buttonRect, p, ^(CGContextRef __unused ctx, const CGRect &rect) { + const auto buttonRect = proxy()->subControlRect(cc, tb, SC_ToolButton, widget); + d->drawNSViewInRect(pb, buttonRect, p, ^(CGContextRef, const CGRect &rect) { [pb.cell drawBezelWithFrame:rect inView:pb]; }); } @@ -5878,7 +5881,7 @@ QSize QMacStyle::sizeFromContents(ContentsType ct, const QStyleOption *opt, switch (ct) { #if QT_CONFIG(spinbox) case CT_SpinBox: - if (const QStyleOptionSpinBox *vopt = qstyleoption_cast<const QStyleOptionSpinBox *>(opt)) { + if (qstyleoption_cast<const QStyleOptionSpinBox *>(opt)) { const int buttonWidth = 20; // FIXME Use subControlRect() sz += QSize(buttonWidth, 0); } diff --git a/src/plugins/styles/windowsvista/qwindowsvistastyle.cpp b/src/plugins/styles/windowsvista/qwindowsvistastyle.cpp index 6add110249..bb110660a3 100644 --- a/src/plugins/styles/windowsvista/qwindowsvistastyle.cpp +++ b/src/plugins/styles/windowsvista/qwindowsvistastyle.cpp @@ -2171,12 +2171,12 @@ QRect QWindowsVistaStyle::subControlRect(ComplexControl control, const QStyleOpt if (const QStyleOptionTitleBar *tb = qstyleoption_cast<const QStyleOptionTitleBar *>(option)) { if (!buttonVisible(subControl, tb)) return rect; + const qreal factor = QWindowsStylePrivate::nativeMetricScaleFactor(widget); const bool isToolTitle = false; const int height = tb->rect.height(); const int width = tb->rect.width(); const int buttonWidth = - qRound(qreal(GetSystemMetrics(SM_CXSIZE)) * QWindowsStylePrivate::nativeMetricScaleFactor(widget) - - QStyleHelper::dpiScaled(4)); + qRound(qreal(GetSystemMetrics(SM_CXSIZE)) * factor - QStyleHelper::dpiScaled(4)); const int frameWidth = proxy()->pixelMetric(PM_MdiSubWindowFrameWidth, option, widget); const bool sysmenuHint = (tb->titleBarFlags & Qt::WindowSystemMenuHint) != 0; @@ -2190,31 +2190,31 @@ QRect QWindowsVistaStyle::subControlRect(ComplexControl control, const QStyleOpt rect = QRect(frameWidth, 0, width - (buttonWidth + frameWidth + 10), height); if (isToolTitle) { if (sysmenuHint) { - rect.adjust(0, 0, -buttonWidth - 3, 0); + rect.adjust(0, 0, int(-buttonWidth - 3 * factor), 0); } if (minimizeHint || maximizeHint) - rect.adjust(0, 0, -buttonWidth - 2, 0); + rect.adjust(0, 0, int(-buttonWidth - 2 * factor), 0); } else { if (sysmenuHint) { - const int leftOffset = height - 8; - rect.adjust(leftOffset, 0, 0, 4); + const int leftOffset = int(height - 8 * factor); + rect.adjust(leftOffset, 0, 0, int(4 * factor)); } if (minimizeHint) - rect.adjust(0, 0, -buttonWidth - 2, 0); + rect.adjust(0, 0, int(-buttonWidth - 2 * factor), 0); if (maximizeHint) - rect.adjust(0, 0, -buttonWidth - 2, 0); + rect.adjust(0, 0, int(-buttonWidth - 2 * factor), 0); if (contextHint) - rect.adjust(0, 0, -buttonWidth - 2, 0); + rect.adjust(0, 0, int(-buttonWidth - 2 * factor), 0); if (shadeHint) - rect.adjust(0, 0, -buttonWidth - 2, 0); + rect.adjust(0, 0, int(-buttonWidth - 2 * factor), 0); } - rect.translate(0, 2); + rect.translate(0, int(2 * factor)); rect = visualRect(option->direction, option->rect, rect); break; case SC_TitleBarSysMenu: { - const int controlTop = 6; - const int controlHeight = height - controlTop - 3; + const int controlTop = int(6 * factor); + const int controlHeight = int(height - controlTop - 3 * factor); int iconExtent = proxy()->pixelMetric(PM_SmallIconSize); QSize iconSize = tb->icon.actualSize(QSize(iconExtent, iconExtent)); if (tb->icon.isNull()) @@ -2222,7 +2222,7 @@ QRect QWindowsVistaStyle::subControlRect(ComplexControl control, const QStyleOpt int hPad = (controlHeight - iconSize.height())/2; int vPad = (controlHeight - iconSize.width())/2; rect = QRect(frameWidth + hPad, controlTop + vPad, iconSize.width(), iconSize.height()); - rect.translate(0, 3); + rect.translate(0, int(3 * factor)); rect = visualRect(option->direction, option->rect, rect); } break; diff --git a/src/plugins/styles/windowsvista/qwindowsxpstyle.cpp b/src/plugins/styles/windowsvista/qwindowsxpstyle.cpp index 36a8afb453..4b583e13d3 100644 --- a/src/plugins/styles/windowsvista/qwindowsxpstyle.cpp +++ b/src/plugins/styles/windowsvista/qwindowsxpstyle.cpp @@ -494,7 +494,8 @@ bool QWindowsXPStylePrivate::isTransparent(XPThemeData &themeData) QRegion QWindowsXPStylePrivate::region(XPThemeData &themeData) { HRGN hRgn = 0; - RECT rect = themeData.toRECT(themeData.rect); + const qreal factor = QWindowsStylePrivate::nativeMetricScaleFactor(themeData.widget); + RECT rect = themeData.toRECT(QRect(themeData.rect.topLeft() / factor, themeData.rect.size() / factor)); if (!SUCCEEDED(GetThemeBackgroundRegion(themeData.handle(), bufferHDC(), themeData.partId, themeData.stateId, &rect, &hRgn))) { return QRegion(); @@ -523,7 +524,7 @@ QRegion QWindowsXPStylePrivate::region(XPThemeData &themeData) RECT *r = reinterpret_cast<RECT*>(rd->Buffer); for (uint i = 0; i < rd->rdh.nCount; ++i) { QRect rect; - rect.setCoords(r->left, r->top, r->right - 1, r->bottom - 1); + rect.setCoords(int(r->left * factor), int(r->top * factor), int((r->right - 1) * factor), int((r->bottom - 1) * factor)); ++r; region |= rect; } @@ -1756,9 +1757,9 @@ case PE_Frame: else stateId = FS_INACTIVE; - int fwidth = frm->lineWidth + frm->midLineWidth; + int fwidth = int((frm->lineWidth + frm->midLineWidth) / QWindowsStylePrivate::nativeMetricScaleFactor(widget)); - XPThemeData theme(0, p, themeNumber, 0, stateId); + XPThemeData theme(widget, p, themeNumber, 0, stateId); if (!theme.isValid()) break; @@ -2949,6 +2950,7 @@ void QWindowsXPStyle::drawComplexControl(ComplexControl cc, const QStyleOptionCo { if (const QStyleOptionTitleBar *tb = qstyleoption_cast<const QStyleOptionTitleBar *>(option)) { + const qreal factor = QWindowsStylePrivate::nativeMetricScaleFactor(widget); bool isActive = tb->titleBarState & QStyle::State_Active; XPThemeData theme(widget, p, QWindowsXPStylePrivate::WindowTheme); if (sub & SC_TitleBarLabel) { @@ -2975,13 +2977,15 @@ void QWindowsXPStyle::drawComplexControl(ComplexControl cc, const QStyleOptionCo GetThemeColor(theme.handle(), WP_CAPTION, isActive ? CS_ACTIVE : CS_INACTIVE, TMT_TEXTSHADOWCOLOR, &textShadowRef); QColor textShadow = qRgb(GetRValue(textShadowRef), GetGValue(textShadowRef), GetBValue(textShadowRef)); p->setPen(textShadow); - p->drawText(ir.x() + 3, ir.y() + 2, ir.width() - 1, ir.height(), + p->drawText(int(ir.x() + 3 * factor), int(ir.y() + 2 * factor), + int(ir.width() - 1 * factor), ir.height(), Qt::AlignLeft | Qt::AlignVCenter | Qt::TextSingleLine, tb->text); } COLORREF captionText = GetSysColor(isActive ? COLOR_CAPTIONTEXT : COLOR_INACTIVECAPTIONTEXT); QColor textColor = qRgb(GetRValue(captionText), GetGValue(captionText), GetBValue(captionText)); p->setPen(textColor); - p->drawText(ir.x() + 2, ir.y() + 1, ir.width() - 2, ir.height(), + p->drawText(int(ir.x() + 2 * factor), int(ir.y() + 1 * factor), + int(ir.width() - 2 * factor), ir.height(), Qt::AlignLeft | Qt::AlignVCenter | Qt::TextSingleLine, tb->text); } if (sub & SC_TitleBarSysMenu && tb->titleBarFlags & Qt::WindowSystemMenuHint) { |