summaryrefslogtreecommitdiffstats
path: root/src/widgets
diff options
context:
space:
mode:
authorFrederik Gladhorn <frederik.gladhorn@digia.com>2014-04-11 14:36:55 +0200
committerFrederik Gladhorn <frederik.gladhorn@digia.com>2014-04-11 14:36:55 +0200
commit98d3e40fb7c88b670a93e73dace2d0f05a5f903c (patch)
treeb1292124a86c219fb434db4ec28e8f805ff52287 /src/widgets
parenta74e4b85be83e2da47f4a1d8fcf0e78079335b80 (diff)
parentbab494e4d046f5617d19f5fec35eeff94377c51f (diff)
Merge remote-tracking branch 'origin/stable' into dev
Conflicts: mkspecs/qnx-armv7le-qcc/qplatformdefs.h src/printsupport/kernel/qcups.cpp src/widgets/styles/qstyle.h tests/auto/widgets/itemviews/qlistwidget/tst_qlistwidget.cpp Change-Id: Ia41e13051169a6d4a8a1267548e7d47b859bb267
Diffstat (limited to 'src/widgets')
-rw-r--r--src/widgets/accessible/widgets.pro1
-rw-r--r--src/widgets/kernel/qapplication_qpa.cpp14
-rw-r--r--src/widgets/kernel/qopenglwidget.cpp8
-rw-r--r--src/widgets/kernel/qwidget.cpp7
-rw-r--r--src/widgets/kernel/qwidget_qpa.cpp20
-rw-r--r--src/widgets/kernel/qwidgetwindow.cpp14
-rw-r--r--src/widgets/styles/qmacstyle_mac.mm63
-rw-r--r--src/widgets/styles/qstyle.cpp3
-rw-r--r--src/widgets/styles/qstyle.h1
-rw-r--r--src/widgets/widgets/qcombobox.cpp108
-rw-r--r--src/widgets/widgets/qcombobox_p.h4
-rw-r--r--src/widgets/widgets/qmainwindow.cpp6
-rw-r--r--src/widgets/widgets/qmainwindowlayout.cpp12
-rw-r--r--src/widgets/widgets/qmdisubwindow.cpp2
-rw-r--r--src/widgets/widgets/qtabbar.cpp71
-rw-r--r--src/widgets/widgets/qtabbar_p.h1
-rw-r--r--src/widgets/widgets/qtoolbar.cpp19
-rw-r--r--src/widgets/widgets/qtoolbararealayout.cpp38
-rw-r--r--src/widgets/widgets/qtoolbararealayout_p.h2
-rw-r--r--src/widgets/widgets/qtoolbarlayout.cpp4
-rw-r--r--src/widgets/widgets/qwidgettextcontrol.cpp28
-rw-r--r--src/widgets/widgets/qwidgettextcontrol_p.h1
-rw-r--r--src/widgets/widgets/qwidgettextcontrol_p_p.h1
23 files changed, 331 insertions, 97 deletions
diff --git a/src/widgets/accessible/widgets.pro b/src/widgets/accessible/widgets.pro
index aff60d9781..c6af6d3f71 100644
--- a/src/widgets/accessible/widgets.pro
+++ b/src/widgets/accessible/widgets.pro
@@ -1,6 +1,7 @@
TARGET = qtaccessiblewidgets
PLUGIN_TYPE = accessible
+PLUGIN_EXTENDS = widgets
PLUGIN_CLASS_NAME = AccessibleFactory
load(qt_plugin)
diff --git a/src/widgets/kernel/qapplication_qpa.cpp b/src/widgets/kernel/qapplication_qpa.cpp
index 1c40ca01be..ccd6c2b03c 100644
--- a/src/widgets/kernel/qapplication_qpa.cpp
+++ b/src/widgets/kernel/qapplication_qpa.cpp
@@ -93,7 +93,6 @@ bool qt_try_modal(QWidget *widget, QEvent::Type type)
return true;
bool block_event = false;
- bool paint_event = false;
switch (type) {
#if 0
@@ -113,7 +112,7 @@ bool qt_try_modal(QWidget *widget, QEvent::Type type)
break;
}
- if ((block_event || paint_event) && top->parentWidget() == 0)
+ if (block_event && top && top->parentWidget() == 0)
top->raise();
return !block_event;
@@ -126,8 +125,15 @@ bool QApplicationPrivate::modalState()
QWidget *qt_tlw_for_window(QWindow *wnd)
{
- while (wnd && !wnd->isTopLevel()) // QTBUG-32177, wnd might be a QQuickView embedded via window container.
- wnd = wnd->parent();
+ // QTBUG-32177, wnd might be a QQuickView embedded via window container.
+ while (wnd && !wnd->isTopLevel()) {
+ QWindow *parent = wnd->parent();
+ // Don't end up in windows not belonging to this application
+ if (parent && parent->type() != Qt::ForeignWindow)
+ wnd = wnd->parent();
+ else
+ break;
+ }
if (wnd)
foreach (QWidget *tlw, qApp->topLevelWidgets())
if (tlw->windowHandle() == wnd)
diff --git a/src/widgets/kernel/qopenglwidget.cpp b/src/widgets/kernel/qopenglwidget.cpp
index 66aacadb28..10be5aef16 100644
--- a/src/widgets/kernel/qopenglwidget.cpp
+++ b/src/widgets/kernel/qopenglwidget.cpp
@@ -60,7 +60,6 @@ public:
QOpenGLWidgetPrivate()
: fbo(0), uninitialized(true)
{
- setRenderToTexture();
}
GLuint textureId() const { return fbo ? fbo->texture() : 0; }
@@ -91,6 +90,8 @@ void QOpenGLWidgetPrivate::initialize()
QOpenGLWidget::QOpenGLWidget(QWidget *parent, Qt::WindowFlags f)
: QWidget(*(new QOpenGLWidgetPrivate), parent, f)
{
+ Q_D(QOpenGLWidget);
+ d->setRenderToTexture();
}
QOpenGLWidget::~QOpenGLWidget()
@@ -146,6 +147,9 @@ void QOpenGLWidget::paintGL()
void QOpenGLWidget::updateGL()
{
Q_D(QOpenGLWidget);
+ if (d->uninitialized)
+ return;
+
makeCurrent();
paintGL();
d->context.functions()->glFlush();
@@ -163,7 +167,7 @@ void QOpenGLWidget::resizeEvent(QResizeEvent *)
d->context.makeCurrent(d->surface());
delete d->fbo; // recreate when resized
- d->fbo = new QOpenGLFramebufferObject(size() * devicePixelRatio());
+ d->fbo = new QOpenGLFramebufferObject(size() * devicePixelRatio(), QOpenGLFramebufferObject::CombinedDepthStencil);
d->fbo->bind();
QOpenGLFunctions *funcs = d->context.functions();
funcs->glBindTexture(GL_TEXTURE_2D, d->fbo->texture());
diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp
index 569828c44d..926db7febf 100644
--- a/src/widgets/kernel/qwidget.cpp
+++ b/src/widgets/kernel/qwidget.cpp
@@ -79,6 +79,7 @@
#include "qfileinfo.h"
#include <QtGui/qinputmethod.h>
#include <QtGui/qopenglcontext.h>
+#include <QtGui/private/qopenglcontext_p.h>
#include <private/qgraphicseffect_p.h>
#include <qbackingstore.h>
@@ -2840,7 +2841,10 @@ void QWidget::showFullScreen()
setWindowState((windowState() & ~(Qt::WindowMinimized | Qt::WindowMaximized))
| Qt::WindowFullScreen);
setVisible(true);
+#if !defined Q_OS_QNX // On QNX this window will be activated anyway from libscreen
+ // activating it here before libscreen activates it causes problems
activateWindow();
+#endif
}
/*!
@@ -8359,6 +8363,8 @@ bool QWidget::event(QEvent *event)
d->extra->customDpiY = value;
d->updateFont(d->data.fnt);
}
+ if (windowHandle() && !qstrncmp(propName, "_q_platform_", 12))
+ windowHandle()->setProperty(propName, property(propName));
// fall through
}
#endif
@@ -11153,6 +11159,7 @@ QOpenGLContext *QWidgetPrivate::shareContext() const
QWidgetPrivate *that = const_cast<QWidgetPrivate *>(this);
if (!extra->topextra->shareContext) {
QOpenGLContext *ctx = new QOpenGLContext();
+ ctx->setShareContext(QOpenGLContextPrivate::globalShareContext());
ctx->setFormat(extra->topextra->window->format());
ctx->create();
that->extra->topextra->shareContext = ctx;
diff --git a/src/widgets/kernel/qwidget_qpa.cpp b/src/widgets/kernel/qwidget_qpa.cpp
index 85ae55b8ac..5ba0a90d3d 100644
--- a/src/widgets/kernel/qwidget_qpa.cpp
+++ b/src/widgets/kernel/qwidget_qpa.cpp
@@ -110,6 +110,11 @@ void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyO
win = topData()->window;
}
+ foreach (const QByteArray &propertyName, q->dynamicPropertyNames()) {
+ if (!qstrncmp(propertyName, "_q_platform_", 12))
+ win->setProperty(propertyName, q->property(propertyName));
+ }
+
win->setFlags(data.window_flags);
fixPosIncludesFrame();
if (q->testAttribute(Qt::WA_Moved)
@@ -834,13 +839,16 @@ int QWidget::metric(PaintDeviceMetric m) const
{
Q_D(const QWidget);
+ QWindow *topLevelWindow = 0;
QScreen *screen = 0;
if (QWidget *topLevel = window())
- if (QWindow *topLevelWindow = topLevel->windowHandle()) {
- QPlatformScreen *platformScreen = QPlatformScreen::platformScreenForWindow(topLevelWindow);
- if (platformScreen)
- screen = platformScreen->screen();
- }
+ topLevelWindow = topLevel->windowHandle();
+
+ if (topLevelWindow) {
+ QPlatformScreen *platformScreen = QPlatformScreen::platformScreenForWindow(topLevelWindow);
+ if (platformScreen)
+ screen = platformScreen->screen();
+ }
if (!screen && QGuiApplication::primaryScreen())
screen = QGuiApplication::primaryScreen();
@@ -877,7 +885,7 @@ int QWidget::metric(PaintDeviceMetric m) const
} else if (m == PdmPhysicalDpiY) {
return qRound(screen->physicalDotsPerInchY());
} else if (m == PdmDevicePixelRatio) {
- return screen->devicePixelRatio();
+ return topLevelWindow ? topLevelWindow->devicePixelRatio() : qApp->devicePixelRatio();
} else {
val = QPaintDevice::metric(m);// XXX
}
diff --git a/src/widgets/kernel/qwidgetwindow.cpp b/src/widgets/kernel/qwidgetwindow.cpp
index ef138267bb..0031d8e965 100644
--- a/src/widgets/kernel/qwidgetwindow.cpp
+++ b/src/widgets/kernel/qwidgetwindow.cpp
@@ -58,8 +58,7 @@ QT_BEGIN_NAMESPACE
Q_WIDGETS_EXPORT extern bool qt_tab_all_widgets();
QWidget *qt_button_down = 0; // widget got last button-down
-static QWidget *qt_tablet_target = 0;
-static QWidget *qt_tablet_target_window = 0;
+static QPointer<QWidget> qt_tablet_target = 0;
// popup control
QWidget *qt_popup_down = 0; // popup that contains the pressed widget
@@ -105,10 +104,6 @@ QWidgetWindow::QWidgetWindow(QWidget *widget)
QWidgetWindow::~QWidgetWindow()
{
- if (m_widget == qt_tablet_target_window) {
- qt_tablet_target = 0;
- qt_tablet_target_window = 0;
- }
}
#ifndef QT_NO_ACCESSIBILITY
@@ -486,7 +481,7 @@ void QWidgetWindow::handleMouseEvent(QMouseEvent *event)
if (!widget)
widget = m_widget;
- if (event->type() == QEvent::MouseButtonPress || event->type() == QEvent::MouseButtonDblClick)
+ if (event->type() == QEvent::MouseButtonPress)
qt_button_down = widget;
QWidget *receiver = QApplicationPrivate::pickMouseReceiver(m_widget, event->windowPos().toPoint(), &mapped, event->type(), event->buttons(),
@@ -791,7 +786,6 @@ void QWidgetWindow::handleTabletEvent(QTabletEvent *event)
widget = m_widget;
qt_tablet_target = widget;
- qt_tablet_target_window = m_widget;
}
if (qt_tablet_target) {
@@ -804,10 +798,8 @@ void QWidgetWindow::handleTabletEvent(QTabletEvent *event)
QGuiApplication::sendSpontaneousEvent(qt_tablet_target, &ev);
}
- if (event->type() == QEvent::TabletRelease) {
+ if (event->type() == QEvent::TabletRelease)
qt_tablet_target = 0;
- qt_tablet_target_window = 0;
- }
}
#endif // QT_NO_TABLETEVENT
diff --git a/src/widgets/styles/qmacstyle_mac.mm b/src/widgets/styles/qmacstyle_mac.mm
index 55e808e9ba..d35dd16f85 100644
--- a/src/widgets/styles/qmacstyle_mac.mm
+++ b/src/widgets/styles/qmacstyle_mac.mm
@@ -179,6 +179,19 @@ static bool isVerticalTabs(const QTabBar::Shape shape) {
|| shape == QTabBar::TriangularWest);
}
+static bool isInMacUnifiedToolbarArea(QWindow *window, int windowY)
+{
+ QPlatformNativeInterface *nativeInterface = QGuiApplication::platformNativeInterface();
+ QPlatformNativeInterface::NativeResourceForIntegrationFunction function =
+ nativeInterface->nativeResourceFunctionForIntegration("testContentBorderPosition");
+ if (!function)
+ return false; // Not Cocoa platform plugin.
+
+ typedef bool (*TestContentBorderPositionFunction)(QWindow *, int);
+ return (reinterpret_cast<TestContentBorderPositionFunction>(function))(window, windowY);
+}
+
+
void drawTabCloseButton(QPainter *p, bool hover, bool active, bool selected)
{
// draw background circle
@@ -239,7 +252,7 @@ QRect rotateTabPainter(QPainter *p, QTabBar::Shape shape, QRect tabRect)
return tabRect;
}
-void drawTabShape(QPainter *p, const QStyleOptionTabV3 *tabOpt)
+void drawTabShape(QPainter *p, const QStyleOptionTabV3 *tabOpt, bool isUnified)
{
QRect r = tabOpt->rect;
p->translate(tabOpt->rect.x(), tabOpt->rect.y());
@@ -256,7 +269,12 @@ void drawTabShape(QPainter *p, const QStyleOptionTabV3 *tabOpt)
QRect rect(1, 0, width - 2, height);
// fill body
- if (active) {
+ if (tabOpt->documentMode && isUnified) {
+ p->save();
+ p->setCompositionMode(QPainter::CompositionMode_Source);
+ p->fillRect(rect, QColor(Qt::transparent));
+ p->restore();
+ } else if (active) {
int d = (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_6) ? 16 : 0;
p->fillRect(rect, QColor(151 + d, 151 + d, 151 + d));
} else {
@@ -3721,7 +3739,7 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter
QStyleOptionComboBox comboCopy = *cb;
comboCopy.direction = Qt::LeftToRight;
if ((opt->state & QStyle::State_Small) && QSysInfo::macVersion() > QSysInfo::MV_10_6)
- comboCopy.rect.translate(0, w ? -1 : -2); // Supports Qt Quick Controls
+ comboCopy.rect.translate(0, w ? (QSysInfo::macVersion() > QSysInfo::MV_10_8 ? 0 : -1) : -2); // Supports Qt Quick Controls
else if (QSysInfo::macVersion() > QSysInfo::MV_10_8)
comboCopy.rect.translate(0, 1);
QCommonStyle::drawControl(CE_ComboBoxLabel, &comboCopy, p, w);
@@ -3733,8 +3751,14 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter
if (const QStyleOptionTabV3 *tabOptV3 = qstyleoption_cast<const QStyleOptionTabV3 *>(opt)) {
if (tabOptV3->documentMode) {
p->save();
- // QRect tabRect = tabOptV3->rect;
- drawTabShape(p, tabOptV3);
+ bool isUnified = false;
+ if (w) {
+ QRect tabRect = tabOptV3->rect;
+ QPoint windowTabStart = w->mapTo(w->window(), tabRect.topLeft());
+ isUnified = isInMacUnifiedToolbarArea(w->window()->windowHandle(), windowTabStart.y());
+ }
+
+ drawTabShape(p, tabOptV3, isUnified);
p->restore();
return;
}
@@ -4414,7 +4438,9 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter
QPen pen(strokeColor);
p->setPen(pen);
p->setBrush(fillColor);
- p->drawRect(opt->rect.adjusted(0, 0, -1, -1));
+ QRect adjusted = opt->rect.adjusted(1, 1, -1, -1);
+ if (adjusted.isValid())
+ p->drawRect(adjusted);
p->setPen(oldPen);
p->setBrush(oldBrush);
}
@@ -4440,15 +4466,22 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter
p->fillRect(opt->rect, Qt::transparent);
p->restore();
- // drow horizontal sepearator line at toolBar bottom.
- SInt32 margin;
- GetThemeMetric(kThemeMetricSeparatorSize, &margin);
- CGRect separatorRect = CGRectMake(opt->rect.left(), opt->rect.bottom(), opt->rect.width(), margin);
- HIThemeSeparatorDrawInfo separatorDrawInfo;
- separatorDrawInfo.version = 0;
- separatorDrawInfo.state = qt_macWindowMainWindow(mainWindow) ? kThemeStateActive : kThemeStateInactive;
- QMacCGContext cg(p);
- HIThemeDrawSeparator(&separatorRect, &separatorDrawInfo, cg, kHIThemeOrientationNormal);
+ // Drow a horizontal sepearator line at the toolBar bottom if the "unified" area ends here.
+ // There might be additional toolbars or other widgets such as tab bars in document
+ // mode below. Determine this by making a unified toolbar area test for the row below
+ // this toolbar.
+ QPoint windowToolbarEnd = w->mapTo(w->window(), opt->rect.bottomLeft());
+ bool isEndOfUnifiedArea = !isInMacUnifiedToolbarArea(w->window()->windowHandle(), windowToolbarEnd.y() + 1);
+ if (isEndOfUnifiedArea) {
+ SInt32 margin;
+ GetThemeMetric(kThemeMetricSeparatorSize, &margin);
+ CGRect separatorRect = CGRectMake(opt->rect.left(), opt->rect.bottom(), opt->rect.width(), margin);
+ HIThemeSeparatorDrawInfo separatorDrawInfo;
+ separatorDrawInfo.version = 0;
+ separatorDrawInfo.state = qt_macWindowMainWindow(mainWindow) ? kThemeStateActive : kThemeStateInactive;
+ QMacCGContext cg(p);
+ HIThemeDrawSeparator(&separatorRect, &separatorDrawInfo, cg, kHIThemeOrientationNormal);
+ }
break;
}
}
diff --git a/src/widgets/styles/qstyle.cpp b/src/widgets/styles/qstyle.cpp
index 37c0a41227..8774d71c0c 100644
--- a/src/widgets/styles/qstyle.cpp
+++ b/src/widgets/styles/qstyle.cpp
@@ -1750,6 +1750,9 @@ void QStyle::drawItemPixmap(QPainter *painter, const QRect &rect, int alignment,
\value SH_ComboBox_Popup Allows popups as a combobox drop-down
menu.
+ \omitvalue SH_ComboBox_UseNativePopup Whether we should use a native popup.
+ Only supported for non-editable combo boxes on Mac OS X so far.
+
\value SH_Workspace_FillSpaceOnMaximize The workspace should
maximize the client area.
diff --git a/src/widgets/styles/qstyle.h b/src/widgets/styles/qstyle.h
index 82c40a954c..ea012faf46 100644
--- a/src/widgets/styles/qstyle.h
+++ b/src/widgets/styles/qstyle.h
@@ -702,6 +702,7 @@ public:
SH_ToolTip_FallAsleepDelay,
SH_Widget_Animate,
SH_Splitter_OpaqueResize,
+ SH_ComboBox_UseNativePopup,
SH_LineEdit_PasswordMaskDelay,
// Add new style hint values here
diff --git a/src/widgets/widgets/qcombobox.cpp b/src/widgets/widgets/qcombobox.cpp
index e0f5ac1050..06258cb4a6 100644
--- a/src/widgets/widgets/qcombobox.cpp
+++ b/src/widgets/widgets/qcombobox.cpp
@@ -44,6 +44,7 @@
#ifndef QT_NO_COMBOBOX
#include <qstylepainter.h>
#include <qpa/qplatformtheme.h>
+#include <qpa/qplatformmenu.h>
#include <qlineedit.h>
#include <qapplication.h>
#include <qdesktopwidget.h>
@@ -205,7 +206,7 @@ void QComboBoxPrivate::updateArrow(QStyle::StateFlag state)
arrowState = state;
QStyleOptionComboBox opt;
q->initStyleOption(&opt);
- q->update(q->style()->subControlRect(QStyle::CC_ComboBox, &opt, QStyle::SC_ComboBoxArrow, q));
+ q->update(q->rect());
}
void QComboBoxPrivate::_q_modelReset()
@@ -2375,6 +2376,79 @@ QSize QComboBox::sizeHint() const
return d->recomputeSizeHint(d->sizeHint);
}
+#ifdef Q_OS_OSX
+/*!
+ * \internal
+ *
+ * Tries to show a native popup. Returns true if it could, false otherwise.
+ *
+ */
+bool QComboBoxPrivate::showNativePopup()
+{
+ Q_Q(QComboBox);
+
+ QPlatformTheme *theme = QGuiApplicationPrivate::instance()->platformTheme();
+ if (QPlatformMenu *menu = theme->createPlatformMenu()) {
+ int itemsCount = q->count();
+
+ struct IndexSetter {
+ int index;
+ QComboBox *cb;
+
+ void operator()(void) { cb->setCurrentIndex(index); }
+ };
+
+ QList<QPlatformMenuItem *> items;
+ items.reserve(itemsCount);
+ QPlatformMenuItem *currentItem = 0;
+ int currentIndex = q->currentIndex();
+
+ for (int i = 0; i < itemsCount; ++i) {
+ QPlatformMenuItem *item = theme->createPlatformMenuItem();
+ QModelIndex rowIndex = model->index(i, modelColumn, root);
+ QVariant textVariant = model->data(rowIndex, Qt::EditRole);
+ item->setText(textVariant.toString());
+ QVariant iconVariant = model->data(rowIndex, Qt::DecorationRole);
+ if (iconVariant.canConvert<QIcon>())
+ item->setIcon(iconVariant.value<QIcon>());
+ item->setCheckable(true);
+ item->setChecked(i == currentIndex);
+ if (!currentItem || i == currentIndex)
+ currentItem = item;
+
+ IndexSetter setter = { i, q };
+ QObject::connect(item, &QPlatformMenuItem::activated, setter);
+
+ menu->insertMenuItem(item, 0);
+ menu->syncMenuItem(item);
+ }
+
+ QWindow *tlw = q->window()->windowHandle();
+ menu->setFont(q->font());
+ menu->setMinimumWidth(q->rect().width());
+ QPoint offset = QPoint(0, 7);
+ if (q->testAttribute(Qt::WA_MacSmallSize))
+ offset = QPoint(-1, 7);
+ else if (q->testAttribute(Qt::WA_MacMiniSize))
+ offset = QPoint(-2, 6);
+ menu->showPopup(tlw, tlw->mapFromGlobal(q->mapToGlobal(offset)), currentItem);
+ menu->deleteLater();
+ Q_FOREACH (QPlatformMenuItem *item, items)
+ item->deleteLater();
+
+ // The Cocoa popup will swallow any mouse release event.
+ // We need to fake one here to un-press the button.
+ QMouseEvent mouseReleased(QEvent::MouseButtonRelease, q->pos(), Qt::LeftButton,
+ Qt::MouseButtons(Qt::LeftButton), Qt::KeyboardModifiers());
+ qApp->sendEvent(q, &mouseReleased);
+
+ return true;
+ }
+
+ return false;
+}
+#endif // Q_OS_OSX
+
/*!
Displays the list of items in the combobox. If the list is empty
then the no items will be shown.
@@ -2390,6 +2464,21 @@ void QComboBox::showPopup()
if (count() <= 0)
return;
+ QStyle * const style = this->style();
+ QStyleOptionComboBox opt;
+ initStyleOption(&opt);
+ const bool usePopup = style->styleHint(QStyle::SH_ComboBox_Popup, &opt, this);
+
+#ifdef Q_OS_OSX
+ if (usePopup
+ && (!d->container
+ || (view()->metaObject()->className() == QByteArray("QComboBoxListView")
+ && view()->itemDelegate()->metaObject()->className() == QByteArray("QComboMenuDelegate")))
+ && style->styleHint(QStyle::SH_ComboBox_UseNativePopup, &opt, this)
+ && d->showNativePopup())
+ return;
+#endif // Q_OS_OSX
+
#ifdef QT_KEYPAD_NAVIGATION
#ifndef QT_NO_COMPLETER
if (QApplication::keypadNavigationEnabled() && d->completer) {
@@ -2401,14 +2490,10 @@ void QComboBox::showPopup()
#endif
#endif
- QStyle * const style = this->style();
-
// set current item and select it
view()->selectionModel()->setCurrentIndex(d->currentIndex,
QItemSelectionModel::ClearAndSelect);
QComboBoxPrivateContainer* container = d->viewContainer();
- QStyleOptionComboBox opt;
- initStyleOption(&opt);
QRect listRect(style->subControlRect(QStyle::CC_ComboBox, &opt,
QStyle::SC_ComboBoxListBoxPopup, this));
QRect screen = d->popupGeometry(QApplication::desktop()->screenNumber(this));
@@ -2419,7 +2504,6 @@ void QComboBox::showPopup()
int aboveHeight = above.y() - screen.y();
bool boundToScreen = !window()->testAttribute(Qt::WA_DontShowOnScreen);
- const bool usePopup = style->styleHint(QStyle::SH_ComboBox_Popup, &opt, this);
{
int listHeight = 0;
int count = 0;
@@ -2750,6 +2834,18 @@ void QComboBox::changeEvent(QEvent *e)
d->updateLineEditGeometry();
d->setLayoutItemMargins(QStyle::SE_ComboBoxLayoutItem);
+ if (e->type() == QEvent::MacSizeChange){
+ QPlatformTheme::Font f = QPlatformTheme::SystemFont;
+ if (testAttribute(Qt::WA_MacSmallSize))
+ f = QPlatformTheme::SmallFont;
+ else if (testAttribute(Qt::WA_MacMiniSize))
+ f = QPlatformTheme::MiniFont;
+ if (const QFont *platformFont = QApplicationPrivate::platformTheme()->font(f)) {
+ QFont f = font();
+ f.setPointSizeF(platformFont->pointSizeF());
+ setFont(f);
+ }
+ }
// ### need to update scrollers etc. as well here
break;
case QEvent::EnabledChange:
diff --git a/src/widgets/widgets/qcombobox_p.h b/src/widgets/widgets/qcombobox_p.h
index 1ad2aa455a..dceffe8d35 100644
--- a/src/widgets/widgets/qcombobox_p.h
+++ b/src/widgets/widgets/qcombobox_p.h
@@ -377,6 +377,10 @@ public:
void modelChanged();
void updateViewContainerPaletteAndOpacity();
+#ifdef Q_OS_OSX
+ bool showNativePopup();
+#endif
+
QAbstractItemModel *model;
QLineEdit *lineEdit;
QComboBoxPrivateContainer *container;
diff --git a/src/widgets/widgets/qmainwindow.cpp b/src/widgets/widgets/qmainwindow.cpp
index 1d0268a244..90cfb1d7cb 100644
--- a/src/widgets/widgets/qmainwindow.cpp
+++ b/src/widgets/widgets/qmainwindow.cpp
@@ -1513,12 +1513,12 @@ void QMainWindow::setUnifiedTitleAndToolBarOnMac(bool set)
QPlatformNativeInterface *nativeInterface = QGuiApplication::platformNativeInterface();
QPlatformNativeInterface::NativeResourceForIntegrationFunction function =
- nativeInterface->nativeResourceFunctionForIntegration("enableContentBorderArea");
+ nativeInterface->nativeResourceFunctionForIntegration("setContentBorderEnabled");
if (!function)
return; // Not Cocoa platform plugin.
- typedef void (*EnableContentBorderAreaFunction)(QWindow *window, bool enable);
- (reinterpret_cast<EnableContentBorderAreaFunction>(function))(window()->windowHandle(), set);
+ typedef void (*SetContentBorderEnabledFunction)(QWindow *window, bool enable);
+ (reinterpret_cast<SetContentBorderEnabledFunction>(function))(window()->windowHandle(), set);
}
#endif
diff --git a/src/widgets/widgets/qmainwindowlayout.cpp b/src/widgets/widgets/qmainwindowlayout.cpp
index 92a1274d7c..c026b79103 100644
--- a/src/widgets/widgets/qmainwindowlayout.cpp
+++ b/src/widgets/widgets/qmainwindowlayout.cpp
@@ -508,8 +508,11 @@ QLayoutItem *QMainWindowLayoutState::item(const QList<int> &path)
int i = path.first();
#ifndef QT_NO_TOOLBAR
- if (i == 0)
- return toolBarAreaLayout.item(path.mid(1)).widgetItem;
+ if (i == 0) {
+ const QToolBarAreaLayoutItem *tbItem = toolBarAreaLayout.item(path.mid(1));
+ Q_ASSERT(tbItem);
+ return tbItem->widgetItem;
+ }
#endif
#ifndef QT_NO_DOCKWIDGET
@@ -1567,9 +1570,10 @@ bool QMainWindowLayout::plug(QLayoutItem *widgetItem)
QList<int> previousPath = layoutState.indexOf(widget);
- QLayoutItem *it = layoutState.plug(currentGapPos);
+ const QLayoutItem *it = layoutState.plug(currentGapPos);
+ if (!it)
+ return false;
Q_ASSERT(it == widgetItem);
- Q_UNUSED(it);
if (!previousPath.isEmpty())
layoutState.remove(previousPath);
diff --git a/src/widgets/widgets/qmdisubwindow.cpp b/src/widgets/widgets/qmdisubwindow.cpp
index 94674319bc..b1adb3f760 100644
--- a/src/widgets/widgets/qmdisubwindow.cpp
+++ b/src/widgets/widgets/qmdisubwindow.cpp
@@ -1761,11 +1761,13 @@ bool QMdiSubWindowPrivate::drawTitleBarWhenMaximized() const
return false;
#if defined(Q_OS_MAC) && !defined(QT_NO_STYLE_MAC) || defined(Q_OS_WINCE_WM)
+ Q_UNUSED(isChildOfQMdiSubWindow);
return true;
#else
if (q->style()->styleHint(QStyle::SH_Workspace_FillSpaceOnMaximize, 0, q))
return true;
#if defined(QT_NO_MENUBAR) || defined(QT_NO_MAINWINDOW)
+ Q_UNUSED(isChildOfQMdiSubWindow);
return true;
#else
QMainWindow *mainWindow = qobject_cast<QMainWindow *>(q->window());
diff --git a/src/widgets/widgets/qtabbar.cpp b/src/widgets/widgets/qtabbar.cpp
index b47d65f561..789ec2f6fd 100644
--- a/src/widgets/widgets/qtabbar.cpp
+++ b/src/widgets/widgets/qtabbar.cpp
@@ -56,6 +56,9 @@
#ifndef QT_NO_ACCESSIBILITY
#include "qaccessible.h"
#endif
+#ifdef Q_OS_OSX
+#include <qpa/qplatformnativeinterface.h>
+#endif
#include "qdebug.h"
#include "private/qtabbar_p.h"
@@ -80,35 +83,44 @@ inline static bool verticalTabs(QTabBar::Shape shape)
void QTabBarPrivate::updateMacBorderMetrics()
{
-#if defined(Q_WS_MAC)
- if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5) {
- Q_Q(QTabBar);
- ::HIContentBorderMetrics metrics;
-
- // TODO: get metrics to preserve the bottom value
- // TODO: test tab bar position
-
- OSWindowRef window = qt_mac_window_for(q);
-
- // push base line separator down to the client are so we can paint over it (Carbon)
- metrics.top = (documentMode && q->isVisible()) ? 1 : 0;
- metrics.bottom = 0;
- metrics.left = 0;
- metrics.right = 0;
- qt_mac_updateContentBorderMetricts(window, metrics);
- // In Cocoa we need to keep track of the drawRect method.
- // If documentMode is enabled we need to change it, unless
- // a toolbar is present.
- // Notice that all the information is kept in the window,
- // that's why we get the private widget for it instead of
- // the private widget for this widget.
- QWidgetPrivate *privateWidget = qt_widget_private(q->window());
- if(privateWidget)
- privateWidget->changeMethods = documentMode;
- // Since in Cocoa there is no simple way to remove the baseline, so we just ask the
- // top level to do the magic for us.
- privateWidget->syncUnifiedMode();
+#if defined(Q_OS_OSX)
+ Q_Q(QTabBar);
+ // Extend the unified title and toolbar area to cover the tab bar iff
+ // 1) the tab bar is in document mode
+ // 2) the tab bar is directly below an "unified" area.
+ // The extending itself is done in the Cocoa platform plugin and Mac style,
+ // this function registers geometry and visibility state for the tab bar.
+
+ // Calculate geometry
+ int upper, lower;
+ if (documentMode) {
+ QPoint windowPos = q->mapTo(q->window(), QPoint(0,0));
+ upper = windowPos.y();
+ int tabStripHeight = q->tabSizeHint(0).height();
+ int pixelTweak = -3;
+ lower = upper + tabStripHeight + pixelTweak;
+ } else {
+ upper = 0;
+ lower = 0;
}
+
+ QPlatformNativeInterface *nativeInterface = QGuiApplication::platformNativeInterface();
+ quintptr identifier = reinterpret_cast<quintptr>(q);
+
+ // Set geometry
+ QPlatformNativeInterface::NativeResourceForIntegrationFunction function =
+ nativeInterface->nativeResourceFunctionForIntegration("registerContentBorderArea");
+ if (!function)
+ return; // Not Cocoa platform plugin.
+ typedef void (*RegisterContentBorderAreaFunction)(QWindow *window, quintptr identifier, int upper, int lower);
+ (reinterpret_cast<RegisterContentBorderAreaFunction>(function))(q->window()->windowHandle(), identifier, upper, lower);
+
+ // Set visibility state
+ function = nativeInterface->nativeResourceFunctionForIntegration("setContentBorderAreaEnabled");
+ if (!function)
+ return;
+ typedef void (*SetContentBorderAreaEnabledFunction)(QWindow *window, quintptr identifier, bool enable);
+ (reinterpret_cast<SetContentBorderAreaEnabledFunction>(function))(q->window()->windowHandle(), identifier, q->isVisible());
#endif
}
@@ -1502,6 +1514,9 @@ bool QTabBar::event(QEvent *event)
|| (!d->rightB->isHidden() && d->rightB->geometry().contains(pos));
if (!isEventInCornerButtons)
emit tabBarDoubleClicked(tabAt(pos));
+ } else if (event->type() == QEvent::Move) {
+ d->updateMacBorderMetrics();
+ return QWidget::event(event);
}
return QWidget::event(event);
}
diff --git a/src/widgets/widgets/qtabbar_p.h b/src/widgets/widgets/qtabbar_p.h
index b7b6998ca3..3228308bc6 100644
--- a/src/widgets/widgets/qtabbar_p.h
+++ b/src/widgets/widgets/qtabbar_p.h
@@ -182,6 +182,7 @@ public:
void layoutWidgets(int start = 0);
void layoutTab(int index);
void updateMacBorderMetrics();
+ bool isTabInMacUnifiedToolbarArea() const;
void setupMovableTab();
void makeVisible(int index);
diff --git a/src/widgets/widgets/qtoolbar.cpp b/src/widgets/widgets/qtoolbar.cpp
index d20b7a380d..3fd615c3c7 100644
--- a/src/widgets/widgets/qtoolbar.cpp
+++ b/src/widgets/widgets/qtoolbar.cpp
@@ -83,6 +83,7 @@ void QToolBarPrivate::init()
q->setBackgroundRole(QPalette::Button);
q->setAttribute(Qt::WA_Hover);
q->setAttribute(Qt::WA_X11NetWmWindowTypeToolBar);
+ q->setProperty("_q_platform_MacUseNSWindow", QVariant(true));
QStyle *style = q->style();
int e = style->pixelMetric(QStyle::PM_ToolBarIconSize, 0, q);
@@ -1039,6 +1040,21 @@ static bool waitForPopup(QToolBar *tb, QWidget *popup)
return false;
}
+#ifdef Q_OS_OSX
+static void enableMacToolBar(QToolBar *toolbar, bool enable)
+{
+ QPlatformNativeInterface *nativeInterface = QApplication::platformNativeInterface();
+ QPlatformNativeInterface::NativeResourceForIntegrationFunction function =
+ nativeInterface->nativeResourceFunctionForIntegration("setContentBorderAreaEnabled");
+ if (!function)
+ return; // Not Cocoa platform plugin.
+
+ typedef void (*SetContentBorderAreaEnabledFunction)(QWindow *window, void *identifier, bool enabled);
+ (reinterpret_cast<SetContentBorderAreaEnabledFunction>(function))(toolbar->window()->windowHandle(), toolbar, enable);
+}
+#endif
+
+
/*! \reimp */
bool QToolBar::event(QEvent *event)
{
@@ -1061,6 +1077,9 @@ bool QToolBar::event(QEvent *event)
// fallthrough intended
case QEvent::Show:
d->toggleViewAction->setChecked(event->type() == QEvent::Show);
+#ifdef Q_OS_OSX
+ enableMacToolBar(this, event->type() == QEvent::Show);
+#endif
emit visibilityChanged(event->type() == QEvent::Show);
break;
case QEvent::ParentChange:
diff --git a/src/widgets/widgets/qtoolbararealayout.cpp b/src/widgets/widgets/qtoolbararealayout.cpp
index 5ec76569aa..4591c2ac5f 100644
--- a/src/widgets/widgets/qtoolbararealayout.cpp
+++ b/src/widgets/widgets/qtoolbararealayout.cpp
@@ -1107,16 +1107,19 @@ void QToolBarAreaLayout::clear()
rect = QRect();
}
-QToolBarAreaLayoutItem &QToolBarAreaLayout::item(const QList<int> &path)
+QToolBarAreaLayoutItem *QToolBarAreaLayout::item(const QList<int> &path)
{
Q_ASSERT(path.count() == 3);
- Q_ASSERT(path.at(0) >= 0 && path.at(0) < QInternal::DockCount);
+ if (path.at(0) < 0 || path.at(0) >= QInternal::DockCount)
+ return 0;
QToolBarAreaLayoutInfo &info = docks[path.at(0)];
- Q_ASSERT(path.at(1) >= 0 && path.at(1) < info.lines.count());
+ if (path.at(1) < 0 || path.at(1) >= info.lines.count())
+ return 0;
QToolBarAreaLayoutLine &line = info.lines[path.at(1)];
- Q_ASSERT(path.at(2) >= 0 && path.at(2) < line.toolBarItems.count());
- return line.toolBarItems[path.at(2)];
+ if (path.at(2) < 0 || path.at(2) >= line.toolBarItems.count())
+ return 0;
+ return &(line.toolBarItems[path.at(2)]);
}
QRect QToolBarAreaLayout::itemRect(const QList<int> &path) const
@@ -1132,23 +1135,28 @@ QRect QToolBarAreaLayout::itemRect(const QList<int> &path) const
QLayoutItem *QToolBarAreaLayout::plug(const QList<int> &path)
{
- QToolBarAreaLayoutItem &item = this->item(path);
- Q_ASSERT(item.gap);
- Q_ASSERT(item.widgetItem != 0);
- item.gap = false;
- return item.widgetItem;
+ QToolBarAreaLayoutItem *item = this->item(path);
+ if (!item) {
+ qWarning() << Q_FUNC_INFO << "No item at" << path;
+ return 0;
+ }
+ Q_ASSERT(item->gap);
+ Q_ASSERT(item->widgetItem != 0);
+ item->gap = false;
+ return item->widgetItem;
}
QLayoutItem *QToolBarAreaLayout::unplug(const QList<int> &path, QToolBarAreaLayout *other)
{
//other needs to be update as well
Q_ASSERT(path.count() == 3);
- QToolBarAreaLayoutItem &item = this->item(path);
+ QToolBarAreaLayoutItem *item = this->item(path);
+ Q_ASSERT(item);
//update the leading space here
QToolBarAreaLayoutInfo &info = docks[path.at(0)];
QToolBarAreaLayoutLine &line = info.lines[path.at(1)];
- if (item.size != pick(line.o, item.realSizeHint())) {
+ if (item->size != pick(line.o, item->realSizeHint())) {
//the item doesn't have its default size
//so we'll give this to the next item
int newExtraSpace = 0;
@@ -1185,9 +1193,9 @@ QLayoutItem *QToolBarAreaLayout::unplug(const QList<int> &path, QToolBarAreaLayo
}
}
- Q_ASSERT(!item.gap);
- item.gap = true;
- return item.widgetItem;
+ Q_ASSERT(!item->gap);
+ item->gap = true;
+ return item->widgetItem;
}
static QRect unpackRect(uint geom0, uint geom1, bool *floating)
diff --git a/src/widgets/widgets/qtoolbararealayout_p.h b/src/widgets/widgets/qtoolbararealayout_p.h
index ec7d1f26f1..6ba9768467 100644
--- a/src/widgets/widgets/qtoolbararealayout_p.h
+++ b/src/widgets/widgets/qtoolbararealayout_p.h
@@ -232,7 +232,7 @@ public:
void remove(const QList<int> &path);
void remove(QLayoutItem *item);
void clear();
- QToolBarAreaLayoutItem &item(const QList<int> &path);
+ QToolBarAreaLayoutItem *item(const QList<int> &path);
QRect itemRect(const QList<int> &path) const;
QLayoutItem *plug(const QList<int> &path);
QLayoutItem *unplug(const QList<int> &path, QToolBarAreaLayout *other);
diff --git a/src/widgets/widgets/qtoolbarlayout.cpp b/src/widgets/widgets/qtoolbarlayout.cpp
index 020d180778..efd33da7fc 100644
--- a/src/widgets/widgets/qtoolbarlayout.cpp
+++ b/src/widgets/widgets/qtoolbarlayout.cpp
@@ -369,9 +369,9 @@ void QToolBarLayout::updateMacBorderMetrics()
typedef void (*RegisterContentBorderAreaFunction)(QWindow *window, void *identifier, int upper, int lower);
if (mainWindow->toolBarArea(tb) == Qt::TopToolBarArea) {
- (reinterpret_cast<RegisterContentBorderAreaFunction>(function))(tb->window()->windowHandle(), this, upper.y(), lower.y());
+ (reinterpret_cast<RegisterContentBorderAreaFunction>(function))(tb->window()->windowHandle(), tb, upper.y(), lower.y());
} else {
- (reinterpret_cast<RegisterContentBorderAreaFunction>(function))(tb->window()->windowHandle(), this, 0, 0);
+ (reinterpret_cast<RegisterContentBorderAreaFunction>(function))(tb->window()->windowHandle(), tb, 0, 0);
}
#endif
}
diff --git a/src/widgets/widgets/qwidgettextcontrol.cpp b/src/widgets/widgets/qwidgettextcontrol.cpp
index 3740f3e698..9cc62fd10a 100644
--- a/src/widgets/widgets/qwidgettextcontrol.cpp
+++ b/src/widgets/widgets/qwidgettextcontrol.cpp
@@ -438,6 +438,7 @@ void QWidgetTextControlPrivate::setContent(Qt::TextFormat format, const QString
QObject::connect(doc, SIGNAL(contentsChanged()), q, SLOT(_q_updateCurrentCharFormatAndSelection()));
QObject::connect(doc, SIGNAL(cursorPositionChanged(QTextCursor)), q, SLOT(_q_emitCursorPosChanged(QTextCursor)));
+ QObject::connect(doc, SIGNAL(contentsChange(int,int,int)), q, SLOT(_q_contentsChanged(int,int,int)));
QObject::connect(doc, SIGNAL(documentLayoutChanged()), q, SLOT(_q_documentLayoutChanged()));
// convenience signal forwards
@@ -641,6 +642,33 @@ void QWidgetTextControlPrivate::_q_emitCursorPosChanged(const QTextCursor &someC
}
}
+void QWidgetTextControlPrivate::_q_contentsChanged(int from, int charsRemoved, int charsAdded)
+{
+ Q_Q(QWidgetTextControl);
+#ifndef QT_NO_ACCESSIBILITY
+ if (QAccessible::isActive()) {
+ QTextCursor tmp(doc);
+ tmp.setPosition(from);
+ tmp.setPosition(from + charsAdded, QTextCursor::KeepAnchor);
+ QString newText = tmp.selectedText();
+
+ // always report the right number of removed chars, but in lack of the real string use spaces
+ QString oldText = QString(charsRemoved, QLatin1Char(' '));
+
+ QAccessibleEvent *ev = 0;
+ if (charsRemoved == 0) {
+ ev = new QAccessibleTextInsertEvent(q->parent(), from, newText);
+ } else if (charsAdded == 0) {
+ ev = new QAccessibleTextRemoveEvent(q->parent(), from, oldText);
+ } else {
+ ev = new QAccessibleTextUpdateEvent(q->parent(), from, oldText, newText);
+ }
+ QAccessible::updateAccessibility(ev);
+ delete ev;
+ }
+#endif
+}
+
void QWidgetTextControlPrivate::_q_documentLayoutChanged()
{
Q_Q(QWidgetTextControl);
diff --git a/src/widgets/widgets/qwidgettextcontrol_p.h b/src/widgets/widgets/qwidgettextcontrol_p.h
index 0c76355ca1..867b55fe32 100644
--- a/src/widgets/widgets/qwidgettextcontrol_p.h
+++ b/src/widgets/widgets/qwidgettextcontrol_p.h
@@ -262,6 +262,7 @@ private:
Q_PRIVATE_SLOT(d_func(), void _q_copyLink())
Q_PRIVATE_SLOT(d_func(), void _q_updateBlock(const QTextBlock &))
Q_PRIVATE_SLOT(d_func(), void _q_documentLayoutChanged())
+ Q_PRIVATE_SLOT(d_func(), void _q_contentsChanged(int, int, int))
};
diff --git a/src/widgets/widgets/qwidgettextcontrol_p_p.h b/src/widgets/widgets/qwidgettextcontrol_p_p.h
index 727821015e..4d578c76f8 100644
--- a/src/widgets/widgets/qwidgettextcontrol_p_p.h
+++ b/src/widgets/widgets/qwidgettextcontrol_p_p.h
@@ -111,6 +111,7 @@ public:
#endif
void _q_emitCursorPosChanged(const QTextCursor &someCursor);
+ void _q_contentsChanged(int from, int charsRemoved, int charsAdded);
void setBlinkingCursorEnabled(bool enable);