summaryrefslogtreecommitdiffstats
path: root/src/widgets
diff options
context:
space:
mode:
Diffstat (limited to 'src/widgets')
-rw-r--r--src/widgets/Qt5WidgetsConfigExtras.cmake.in2
-rw-r--r--src/widgets/dialogs/qfiledialog.cpp77
-rw-r--r--src/widgets/graphicsview/qgraphicsproxywidget.cpp4
-rw-r--r--src/widgets/graphicsview/qgraphicsview.cpp2
-rw-r--r--src/widgets/itemviews/qlistwidget.cpp2
-rw-r--r--src/widgets/itemviews/qtreeview.cpp13
-rw-r--r--src/widgets/kernel/qapplication.cpp2
-rw-r--r--src/widgets/kernel/qapplication_qpa.cpp13
-rw-r--r--src/widgets/kernel/qopenglwidget.cpp2
-rw-r--r--src/widgets/kernel/qtooltip.cpp4
-rw-r--r--src/widgets/kernel/qwidget.cpp2
-rw-r--r--src/widgets/kernel/qwidgetwindow.cpp10
-rw-r--r--src/widgets/kernel/qwindowcontainer.cpp11
-rw-r--r--src/widgets/styles/qgtkstyle_p.cpp2
-rw-r--r--src/widgets/styles/qmacstyle_mac.mm34
-rw-r--r--src/widgets/widgets/qfontcombobox.cpp7
-rw-r--r--src/widgets/widgets/qmacnativewidget_mac.mm1
-rw-r--r--src/widgets/widgets/qmdiarea.cpp3
-rw-r--r--src/widgets/widgets/qmdisubwindow.cpp7
-rw-r--r--src/widgets/widgets/qmenu.cpp42
-rw-r--r--src/widgets/widgets/qmenu.h1
-rw-r--r--src/widgets/widgets/qmenu_mac.mm19
-rw-r--r--src/widgets/widgets/qmenu_p.h4
-rw-r--r--src/widgets/widgets/qmenubar.cpp7
24 files changed, 195 insertions, 76 deletions
diff --git a/src/widgets/Qt5WidgetsConfigExtras.cmake.in b/src/widgets/Qt5WidgetsConfigExtras.cmake.in
index e5650ff362..99d87e2e46 100644
--- a/src/widgets/Qt5WidgetsConfigExtras.cmake.in
+++ b/src/widgets/Qt5WidgetsConfigExtras.cmake.in
@@ -14,4 +14,6 @@ if (NOT TARGET Qt5::uic)
)
endif()
+include(\"${CMAKE_CURRENT_LIST_DIR}/Qt5Widgets_AccessibleFactory.cmake\" OPTIONAL)
+
set(Qt5Widgets_UIC_EXECUTABLE Qt5::uic)
diff --git a/src/widgets/dialogs/qfiledialog.cpp b/src/widgets/dialogs/qfiledialog.cpp
index 80e8d152ff..6349bdc301 100644
--- a/src/widgets/dialogs/qfiledialog.cpp
+++ b/src/widgets/dialogs/qfiledialog.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtWidgets module of the Qt Toolkit.
@@ -71,6 +71,7 @@ extern bool qt_priv_ptr_valid;
#endif
#if defined(Q_OS_UNIX)
#include <pwd.h>
+#include <unistd.h> // for pathconf() on OS X
#elif defined(Q_OS_WIN)
# include <QtCore/qt_windows.h>
#endif
@@ -1018,6 +1019,44 @@ QUrl QFileDialog::directoryUrl() const
return QUrl::fromLocalFile(directory().absolutePath());
}
+// FIXME Qt 5.4: Use upcoming QVolumeInfo class to determine this information?
+static inline bool isCaseSensitiveFileSystem(const QString &path)
+{
+ Q_UNUSED(path)
+#if defined(Q_OS_WIN)
+ // Return case insensitive unconditionally, even if someone has a case sensitive
+ // file system mounted, wrongly capitalized drive letters will cause mismatches.
+ return false;
+#elif defined(Q_OS_OSX)
+ return pathconf(QFile::encodeName(path).constData(), _PC_CASE_SENSITIVE);
+#else
+ return true;
+#endif
+}
+
+// Determine the file name to be set on the line edit from the path
+// passed to selectFile() in mode QFileDialog::AcceptSave.
+static inline QString fileFromPath(const QString &rootPath, QString path)
+{
+ if (!QFileInfo(path).isAbsolute())
+ return path;
+ if (path.startsWith(rootPath, isCaseSensitiveFileSystem(rootPath) ? Qt::CaseSensitive : Qt::CaseInsensitive))
+ path.remove(0, rootPath.size());
+
+ if (path.isEmpty())
+ return path;
+
+ if (path.at(0) == QDir::separator()
+#ifdef Q_OS_WIN
+ //On Windows both cases can happen
+ || path.at(0) == QLatin1Char('/')
+#endif
+ ) {
+ path.remove(0, 1);
+ }
+ return path;
+}
+
/*!
Selects the given \a filename in the file dialog.
@@ -1049,28 +1088,9 @@ void QFileDialog::selectFile(const QString &filename)
}
QModelIndex index = d->model->index(filename);
- QString file;
- if (!index.isValid()) {
- // save as dialog where we want to input a default value
- QString text = filename;
- if (QFileInfo(filename).isAbsolute()) {
- QString current = d->rootPath();
- text.remove(current);
- if (text.at(0) == QDir::separator()
-#ifdef Q_OS_WIN
- //On Windows both cases can happen
- || text.at(0) == QLatin1Char('/')
-#endif
- )
- text = text.remove(0,1);
- }
- file = text;
- } else {
- file = index.data().toString();
- }
d->qFileDialogUi->listView->selectionModel()->clear();
if (!isVisible() || !d->lineEdit()->hasFocus())
- d->lineEdit()->setText(file);
+ d->lineEdit()->setText(index.isValid() ? index.data().toString() : fileFromPath(d->rootPath(), filename));
}
/*!
@@ -1255,7 +1275,7 @@ QStringList QFileDialog::selectedFiles() const
QStringList files;
foreach (const QUrl &file, d->userSelectedFiles())
files.append(file.toLocalFile());
- if (files.isEmpty()) {
+ if (files.isEmpty() && d->usingWidgets()) {
const FileMode fm = fileMode();
if (fm != ExistingFile && fm != ExistingFiles)
files.append(d->rootIndex().data(QFileSystemModel::FilePathRole).toString());
@@ -1600,7 +1620,7 @@ QFileDialog::ViewMode QFileDialog::viewMode() const
{
Q_D(const QFileDialog);
if (!d->usingWidgets())
- return QFileDialog::List;
+ return static_cast<QFileDialog::ViewMode>(d->options->viewMode());
return (d->qFileDialogUi->stackedWidget->currentWidget() == d->qFileDialogUi->listView->parent() ? QFileDialog::List : QFileDialog::Detail);
}
@@ -2108,6 +2128,11 @@ QString QFileDialog::getOpenFileName(QWidget *parent,
return QString();
}
+static inline QUrl dialogResultToUrl(const QString &file)
+{
+ return file.isEmpty() ? QUrl() : QUrl::fromLocalFile(file);
+}
+
/*!
This is a convenience static function that returns an existing file
selected by the user. If the user presses Cancel, it returns an
@@ -2146,7 +2171,7 @@ QUrl QFileDialog::getOpenFileUrl(QWidget *parent,
Q_UNUSED(supportedSchemes);
// Falls back to local file
- return QUrl::fromLocalFile(getOpenFileName(parent, caption, dir.toLocalFile(), filter, selectedFilter, options));
+ return dialogResultToUrl(getOpenFileName(parent, caption, dir.toLocalFile(), filter, selectedFilter, options));
}
/*!
@@ -2404,7 +2429,7 @@ QUrl QFileDialog::getSaveFileUrl(QWidget *parent,
Q_UNUSED(supportedSchemes);
// Falls back to local file
- return QUrl::fromLocalFile(getSaveFileName(parent, caption, dir.toLocalFile(), filter, selectedFilter, options));
+ return dialogResultToUrl(getSaveFileName(parent, caption, dir.toLocalFile(), filter, selectedFilter, options));
}
/*!
@@ -2512,7 +2537,7 @@ QUrl QFileDialog::getExistingDirectoryUrl(QWidget *parent,
Q_UNUSED(supportedSchemes);
// Falls back to local file
- return QUrl::fromLocalFile(getExistingDirectory(parent, caption, dir.toLocalFile(), options));
+ return dialogResultToUrl(getExistingDirectory(parent, caption, dir.toLocalFile(), options));
}
inline static QString _qt_get_directory(const QString &path)
diff --git a/src/widgets/graphicsview/qgraphicsproxywidget.cpp b/src/widgets/graphicsview/qgraphicsproxywidget.cpp
index 68944817f6..f5db85b698 100644
--- a/src/widgets/graphicsview/qgraphicsproxywidget.cpp
+++ b/src/widgets/graphicsview/qgraphicsproxywidget.cpp
@@ -379,6 +379,10 @@ QWidget *QGraphicsProxyWidgetPrivate::findFocusChild(QWidget *child, bool next)
void QGraphicsProxyWidgetPrivate::_q_removeWidgetSlot()
{
Q_Q(QGraphicsProxyWidget);
+ if (!widget.isNull()) {
+ if (QWExtra *extra = widget->d_func()->extra)
+ extra->proxyWidget = 0;
+ }
widget = 0;
delete q;
}
diff --git a/src/widgets/graphicsview/qgraphicsview.cpp b/src/widgets/graphicsview/qgraphicsview.cpp
index 86648c4f26..5bcf52b6a3 100644
--- a/src/widgets/graphicsview/qgraphicsview.cpp
+++ b/src/widgets/graphicsview/qgraphicsview.cpp
@@ -1655,7 +1655,7 @@ void QGraphicsView::invalidateScene(const QRectF &rect, QGraphicsScene::SceneLay
/*!
\property QGraphicsView::interactive
- \brief whether the view allowed scene interaction.
+ \brief whether the view allows scene interaction.
If enabled, this view is set to allow scene interaction. Otherwise, this
view will not allow interaction, and any mouse or key events are ignored
diff --git a/src/widgets/itemviews/qlistwidget.cpp b/src/widgets/itemviews/qlistwidget.cpp
index 5040192f31..1f954d67dd 100644
--- a/src/widgets/itemviews/qlistwidget.cpp
+++ b/src/widgets/itemviews/qlistwidget.cpp
@@ -1631,7 +1631,7 @@ QWidget *QListWidget::itemWidget(QListWidgetItem *item) const
/*!
\since 4.1
- Sets the \a widget to be displayed in the give \a item.
+ Sets the \a widget to be displayed in the given \a item.
This function should only be used to display static content in the place of
a list widget item. If you want to display custom dynamic content or
diff --git a/src/widgets/itemviews/qtreeview.cpp b/src/widgets/itemviews/qtreeview.cpp
index 781dd345bd..3f952ff768 100644
--- a/src/widgets/itemviews/qtreeview.cpp
+++ b/src/widgets/itemviews/qtreeview.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtWidgets module of the Qt Toolkit.
@@ -1421,15 +1421,8 @@ void QTreeViewPrivate::adjustViewOptionsForIndex(QStyleOptionViewItem *option, c
const int right = (spanning ? header->visualIndex(0) : header->count() - 1 );
calcLogicalIndices(&logicalIndices, &viewItemPosList, left, right);
- int columnIndex = 0;
- for (int visualIndex = 0; visualIndex < current.column(); ++visualIndex) {
- int logicalIndex = header->logicalIndex(visualIndex);
- if (!header->isSectionHidden(logicalIndex)) {
- ++columnIndex;
- }
- }
-
- option->viewItemPosition = viewItemPosList.at(columnIndex);
+ const int visualIndex = logicalIndices.indexOf(current.column());
+ option->viewItemPosition = viewItemPosList.at(visualIndex);
}
diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp
index d90e2f5163..b4c4ffe7c7 100644
--- a/src/widgets/kernel/qapplication.cpp
+++ b/src/widgets/kernel/qapplication.cpp
@@ -368,6 +368,7 @@ QApplicationPrivate::~QApplicationPrivate()
void qt_init(QApplicationPrivate *priv, int type
);
+void qt_init_tooltip_palette();
void qt_cleanup();
QStyle *QApplicationPrivate::app_style = 0; // default application style
@@ -4025,6 +4026,7 @@ void QApplicationPrivate::notifyThemeChanged()
QGuiApplicationPrivate::notifyThemeChanged();
clearSystemPalette();
initSystemPalette();
+ qt_init_tooltip_palette();
}
#ifndef QT_NO_DRAGANDDROP
diff --git a/src/widgets/kernel/qapplication_qpa.cpp b/src/widgets/kernel/qapplication_qpa.cpp
index c68bcc773f..5893c52e1b 100644
--- a/src/widgets/kernel/qapplication_qpa.cpp
+++ b/src/widgets/kernel/qapplication_qpa.cpp
@@ -442,6 +442,14 @@ void QApplication::alert(QWidget *widget, int duration)
}
}
+void qt_init_tooltip_palette()
+{
+#ifndef QT_NO_TOOLTIP
+ if (const QPalette *toolTipPalette = QGuiApplicationPrivate::platformTheme()->palette(QPlatformTheme::ToolTipPalette))
+ QToolTip::setPalette(*toolTipPalette);
+#endif
+}
+
void qt_init(QApplicationPrivate *priv, int type)
{
Q_UNUSED(priv);
@@ -449,10 +457,7 @@ void qt_init(QApplicationPrivate *priv, int type)
QColormap::initialize();
-#ifndef QT_NO_TOOLTIP
- if (const QPalette *toolTipPalette = QGuiApplicationPrivate::platformTheme()->palette(QPlatformTheme::ToolTipPalette))
- QToolTip::setPalette(*toolTipPalette);
-#endif
+ qt_init_tooltip_palette();
QApplicationPrivate::initializeWidgetFontHash();
}
diff --git a/src/widgets/kernel/qopenglwidget.cpp b/src/widgets/kernel/qopenglwidget.cpp
index 10be5aef16..cbefb8a6bf 100644
--- a/src/widgets/kernel/qopenglwidget.cpp
+++ b/src/widgets/kernel/qopenglwidget.cpp
@@ -147,7 +147,7 @@ void QOpenGLWidget::paintGL()
void QOpenGLWidget::updateGL()
{
Q_D(QOpenGLWidget);
- if (d->uninitialized)
+ if (d->uninitialized || !d->surface())
return;
makeCurrent();
diff --git a/src/widgets/kernel/qtooltip.cpp b/src/widgets/kernel/qtooltip.cpp
index 5aea55e196..2b43fd7f6d 100644
--- a/src/widgets/kernel/qtooltip.cpp
+++ b/src/widgets/kernel/qtooltip.cpp
@@ -512,9 +512,9 @@ void QToolTip::showText(const QPoint &pos, const QString &text, QWidget *w, cons
else if (QApplication::isEffectEnabled(Qt::UI_AnimateTooltip))
qScrollEffect(QTipLabel::instance);
else
- QTipLabel::instance->show();
+ QTipLabel::instance->showNormal();
#else
- QTipLabel::instance->show();
+ QTipLabel::instance->showNormal();
#endif
}
}
diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp
index f79eaf197d..65e435fbdc 100644
--- a/src/widgets/kernel/qwidget.cpp
+++ b/src/widgets/kernel/qwidget.cpp
@@ -6002,10 +6002,8 @@ void QWidget::setFocus(Qt::FocusReason reason)
if (!(testAttribute(Qt::WA_WState_Created) && window()->windowType() != Qt::Popup && internalWinId()))
//setFocusWidget will already post a focus event for us (that the AT client receives) on Windows
# endif
-# ifdef Q_OS_UNIX
// menus update the focus manually and this would create bogus events
if (!(f->inherits("QMenuBar") || f->inherits("QMenu") || f->inherits("QMenuItem")))
-# endif
{
QAccessibleEvent event(f, QAccessible::Focus);
QAccessible::updateAccessibility(&event);
diff --git a/src/widgets/kernel/qwidgetwindow.cpp b/src/widgets/kernel/qwidgetwindow.cpp
index 0031d8e965..fc328e7af0 100644
--- a/src/widgets/kernel/qwidgetwindow.cpp
+++ b/src/widgets/kernel/qwidgetwindow.cpp
@@ -440,11 +440,13 @@ void QWidgetWindow::handleMouseEvent(QMouseEvent *event)
if (!win)
win = w->nativeParentWidget()->windowHandle();
if (win && win->geometry().contains(event->globalPos())) {
+ // Use postEvent() to ensure the local QEventLoop terminates when called from QMenu::exec()
const QPoint localPos = win->mapFromGlobal(event->globalPos());
- QMouseEvent e(QEvent::MouseButtonPress, localPos, localPos, event->globalPos(), event->button(), event->buttons(), event->modifiers());
- QGuiApplicationPrivate::setMouseEventSource(&e, QGuiApplicationPrivate::mouseEventSource(event));
- e.setTimestamp(event->timestamp());
- QApplication::sendSpontaneousEvent(win, &e);
+ QMouseEvent *e = new QMouseEvent(QEvent::MouseButtonPress, localPos, localPos, event->globalPos(), event->button(), event->buttons(), event->modifiers());
+ e->spont = 1;
+ QGuiApplicationPrivate::setMouseEventSource(e, QGuiApplicationPrivate::mouseEventSource(event));
+ e->setTimestamp(event->timestamp());
+ QCoreApplication::postEvent(win, e);
}
}
}
diff --git a/src/widgets/kernel/qwindowcontainer.cpp b/src/widgets/kernel/qwindowcontainer.cpp
index 4618e1c91d..1770e60c2e 100644
--- a/src/widgets/kernel/qwindowcontainer.cpp
+++ b/src/widgets/kernel/qwindowcontainer.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtWidgets module of the Qt Toolkit.
@@ -72,7 +72,14 @@ public:
void updateGeometry() {
Q_Q(QWindowContainer);
- if (usesNativeWidgets)
+ if (q->geometry().bottom() <= 0 || q->geometry().right() <= 0)
+ /* Qt (e.g. QSplitter) sometimes prefer to hide a widget by *not* calling
+ setVisible(false). This is often done by setting its coordinates to a sufficiently
+ negative value so that its clipped outside the parent. Since a QWindow is not clipped
+ to widgets in general, it needs to be dealt with as a special case.
+ */
+ window->setGeometry(q->geometry());
+ else if (usesNativeWidgets)
window->setGeometry(q->rect());
else
window->setGeometry(QRect(q->mapTo(q->window(), QPoint()), q->size()));
diff --git a/src/widgets/styles/qgtkstyle_p.cpp b/src/widgets/styles/qgtkstyle_p.cpp
index 2bd978bcb8..2c64225c70 100644
--- a/src/widgets/styles/qgtkstyle_p.cpp
+++ b/src/widgets/styles/qgtkstyle_p.cpp
@@ -855,7 +855,7 @@ QFont QGtkStylePrivate::getThemeFont()
QIcon QGtkStylePrivate::getFilesystemIcon(const QFileInfo &info)
{
QIcon icon;
- if (gnome_vfs_init && gnome_icon_lookup_sync) {
+ if (isThemeAvailable() && gnome_vfs_init && gnome_icon_lookup_sync) {
gnome_vfs_init();
GtkIconTheme *theme = gtk_icon_theme_get_default();
QByteArray fileurl = QUrl::fromLocalFile(info.absoluteFilePath()).toEncoded();
diff --git a/src/widgets/styles/qmacstyle_mac.mm b/src/widgets/styles/qmacstyle_mac.mm
index d35dd16f85..e165b8aa68 100644
--- a/src/widgets/styles/qmacstyle_mac.mm
+++ b/src/widgets/styles/qmacstyle_mac.mm
@@ -1345,12 +1345,30 @@ void QMacStylePrivate::initComboboxBdi(const QStyleOptionComboBox *combo, HIThem
// an extra check here before using the mini and small buttons.
int h = combo->rect.size().height();
if (combo->editable){
- if (h < 21)
- bdi->kind = kThemeComboBoxMini;
- else if (h < 26)
- bdi->kind = kThemeComboBoxSmall;
- else
- bdi->kind = kThemeComboBox;
+ if (qobject_cast<const QDateTimeEdit *>(widget)) {
+ // Except when, you know, we get a QDateTimeEdit with calendarPopup
+ // enabled. And then things get weird, basically because it's a
+ // transvestite spinbox with editable combobox tendencies. Meaning
+ // that it wants to look a combobox, except that it isn't one, so it
+ // doesn't get all those extra free margins around. (Don't know whose
+ // idea those margins were, but now it looks like we're stuck with
+ // them forever). So anyway, the height threshold should be smaller
+ // in this case, or the style gets confused when it needs to render
+ // or return any subcontrol size of the poor thing.
+ if (h < 9)
+ bdi->kind = kThemeComboBoxMini;
+ else if (h < 22)
+ bdi->kind = kThemeComboBoxSmall;
+ else
+ bdi->kind = kThemeComboBox;
+ } else {
+ if (h < 21)
+ bdi->kind = kThemeComboBoxMini;
+ else if (h < 26)
+ bdi->kind = kThemeComboBoxSmall;
+ else
+ bdi->kind = kThemeComboBox;
+ }
} else {
// Even if we specify that we want the kThemePopupButton, Carbon
// will use the kThemePopupButtonSmall if the size matches. So we
@@ -1678,7 +1696,7 @@ QMacStylePrivate::QMacStylePrivate()
if (ptrHIShapeGetBounds == 0) {
QLibrary library(QLatin1String("/System/Library/Frameworks/Carbon.framework/Carbon"));
library.setLoadHints(QLibrary::ExportExternalSymbolsHint);
- ptrHIShapeGetBounds = reinterpret_cast<PtrHIShapeGetBounds>(library.resolve("HIShapeGetBounds"));
+ ptrHIShapeGetBounds = reinterpret_cast<PtrHIShapeGetBounds>(library.resolve("HIShapeGetBounds"));
}
}
@@ -5301,7 +5319,7 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex
if (const QStyleOptionComboBox *combo = qstyleoption_cast<const QStyleOptionComboBox *>(opt)){
HIThemeButtonDrawInfo bdi;
d->initComboboxBdi(combo, &bdi, widget, d->getDrawState(opt->state));
- if (!tds == kThemeStateInactive)
+ if (tds != kThemeStateInactive)
QMacStylePrivate::drawCombobox(qt_hirectForQRect(combo->rect), bdi, p);
else
d->drawColorlessButton(qt_hirectForQRect(combo->rect), &bdi, p, opt);
diff --git a/src/widgets/widgets/qfontcombobox.cpp b/src/widgets/widgets/qfontcombobox.cpp
index 2bbf3730db..40ca73904c 100644
--- a/src/widgets/widgets/qfontcombobox.cpp
+++ b/src/widgets/widgets/qfontcombobox.cpp
@@ -50,6 +50,7 @@
#include <qevent.h>
#include <qapplication.h>
#include <private/qcombobox_p.h>
+#include <QDesktopWidget>
#include <qdebug.h>
QT_BEGIN_NAMESPACE
@@ -546,8 +547,10 @@ bool QFontComboBox::event(QEvent *e)
{
if (e->type() == QEvent::Resize) {
QListView *lview = qobject_cast<QListView*>(view());
- if (lview)
- lview->window()->setFixedWidth(width() * 5 / 3);
+ if (lview) {
+ setFixedWidth(qMin(width() * 5 / 3,
+ QApplication::desktop()->availableGeometry(lview).width()));
+ }
}
return QComboBox::event(e);
}
diff --git a/src/widgets/widgets/qmacnativewidget_mac.mm b/src/widgets/widgets/qmacnativewidget_mac.mm
index 66a1ed7ce7..d3f3515b04 100644
--- a/src/widgets/widgets/qmacnativewidget_mac.mm
+++ b/src/widgets/widgets/qmacnativewidget_mac.mm
@@ -128,6 +128,7 @@ QMacNativeWidget::QMacNativeWidget(NSView *parentView)
setAttribute(Qt::WA_SetPalette, false);
setAttribute(Qt::WA_LayoutUsesWidgetRect);
setAttribute(Qt::WA_TranslucentBackground);
+ setAttribute(Qt::WA_NoSystemBackground, false);
}
/*!
diff --git a/src/widgets/widgets/qmdiarea.cpp b/src/widgets/widgets/qmdiarea.cpp
index 600d9b536f..17f73b2809 100644
--- a/src/widgets/widgets/qmdiarea.cpp
+++ b/src/widgets/widgets/qmdiarea.cpp
@@ -2591,6 +2591,9 @@ bool QMdiArea::eventFilter(QObject *object, QEvent *event)
return QAbstractScrollArea::eventFilter(object, event);
}
+ if (subWindow->mdiArea() != this)
+ return QAbstractScrollArea::eventFilter(object, event);
+
// QMdiSubWindow events:
switch (event->type()) {
case QEvent::Move:
diff --git a/src/widgets/widgets/qmdisubwindow.cpp b/src/widgets/widgets/qmdisubwindow.cpp
index b1adb3f760..9104074122 100644
--- a/src/widgets/widgets/qmdisubwindow.cpp
+++ b/src/widgets/widgets/qmdisubwindow.cpp
@@ -1676,15 +1676,18 @@ void QMdiSubWindowPrivate::ensureWindowState(Qt::WindowState state)
switch (state) {
case Qt::WindowMinimized:
windowStates &= ~Qt::WindowMaximized;
+ windowStates &= ~Qt::WindowFullScreen;
windowStates &= ~Qt::WindowNoState;
break;
case Qt::WindowMaximized:
windowStates &= ~Qt::WindowMinimized;
+ windowStates &= ~Qt::WindowFullScreen;
windowStates &= ~Qt::WindowNoState;
break;
case Qt::WindowNoState:
windowStates &= ~Qt::WindowMinimized;
windowStates &= ~Qt::WindowMaximized;
+ windowStates &= ~Qt::WindowFullScreen;
break;
default:
break;
@@ -2732,7 +2735,7 @@ bool QMdiSubWindow::eventFilter(QObject *object, QEvent *event)
showMinimized();
else if (!(oldState & Qt::WindowMaximized) && (newState & Qt::WindowMaximized))
showMaximized();
- else if (!(newState & (Qt::WindowMaximized | Qt::WindowMinimized)))
+ else if (!(newState & (Qt::WindowMaximized | Qt::WindowMinimized | Qt::WindowFullScreen)))
showNormal();
break;
}
@@ -3005,7 +3008,7 @@ void QMdiSubWindow::changeEvent(QEvent *changeEvent)
d->setMinimizeMode();
else if (!(oldState & Qt::WindowMaximized) && (newState & Qt::WindowMaximized))
d->setMaximizeMode();
- else if (!(newState & (Qt::WindowMaximized | Qt::WindowMinimized)))
+ else if (!(newState & (Qt::WindowMaximized | Qt::WindowMinimized | Qt::WindowFullScreen)))
d->setNormalMode();
if (d->isActive)
diff --git a/src/widgets/widgets/qmenu.cpp b/src/widgets/widgets/qmenu.cpp
index eb93e461c0..7e48badea5 100644
--- a/src/widgets/widgets/qmenu.cpp
+++ b/src/widgets/widgets/qmenu.cpp
@@ -50,6 +50,9 @@
#include "qlayout.h"
#include "qpainter.h"
#include <qpa/qplatformtheme.h>
+#ifdef Q_OS_OSX
+#include "qmacnativewidget_mac.h"
+#endif
#include "qapplication.h"
#include "qdesktopwidget.h"
#ifndef QT_NO_ACCESSIBILITY
@@ -163,7 +166,7 @@ void QMenuPrivate::setPlatformMenu(QPlatformMenu *menu)
platformMenu = menu;
if (!platformMenu.isNull()) {
- QObject::connect(platformMenu, SIGNAL(aboutToShow()), q, SIGNAL(aboutToShow()));
+ QObject::connect(platformMenu, SIGNAL(aboutToShow()), q, SLOT(_q_platformMenuAboutToShow()));
QObject::connect(platformMenu, SIGNAL(aboutToHide()), q, SIGNAL(aboutToHide()));
}
}
@@ -1091,9 +1094,6 @@ void QMenuPrivate::activateAction(QAction *action, QAction::ActionEvent action_e
QAccessibleEvent focusEvent(q, QAccessible::Focus);
focusEvent.setChild(actionIndex);
QAccessible::updateAccessibility(&focusEvent);
- QAccessibleEvent selectionEvent(q, QAccessible::Selection);
- focusEvent.setChild(actionIndex);
- QAccessible::updateAccessibility(&selectionEvent);
}
#endif
action->showStatusText(topCausedWidget());
@@ -1107,6 +1107,8 @@ void QMenuPrivate::_q_actionTriggered()
Q_Q(QMenu);
if (QAction *action = qobject_cast<QAction *>(q->sender())) {
QPointer<QAction> actionGuard = action;
+ if (platformMenu && widgetItems.value(action))
+ platformMenu->dismiss();
emit q->triggered(action);
if (!activationRecursionGuard && actionGuard) {
//in case the action has not been activated by the mouse
@@ -1137,6 +1139,24 @@ void QMenuPrivate::_q_actionHovered()
}
}
+void QMenuPrivate::_q_platformMenuAboutToShow()
+{
+ Q_Q(QMenu);
+
+#ifdef Q_OS_OSX
+ if (platformMenu)
+ Q_FOREACH (QAction *action, q->actions())
+ if (QWidget *widget = widgetItems.value(const_cast<QAction *>(action)))
+ if (widget->parent() == q) {
+ QPlatformMenuItem *menuItem = platformMenu->menuItemForTag(reinterpret_cast<quintptr>(action));
+ moveWidgetToPlatformItem(widget, menuItem);
+ platformMenu->syncMenuItem(menuItem);
+ }
+#endif
+
+ emit q->aboutToShow();
+}
+
bool QMenuPrivate::hasMouseMoved(const QPoint &globalPos)
{
//determines if the mouse has moved (ie its initial position has
@@ -2157,6 +2177,7 @@ QAction *QMenu::exec()
QAction *QMenu::exec(const QPoint &p, QAction *action)
{
Q_D(QMenu);
+ ensurePolished();
createWinId();
QEventLoop eventLoop;
d->eventLoop = &eventLoop;
@@ -2999,8 +3020,19 @@ void QMenu::actionEvent(QActionEvent *e)
if (e->action() == d->currentAction)
d->currentAction = 0;
if (QWidgetAction *wa = qobject_cast<QWidgetAction *>(e->action())) {
- if (QWidget *widget = d->widgetItems.value(wa))
+ if (QWidget *widget = d->widgetItems.value(wa)) {
+#ifdef Q_OS_OSX
+ QWidget *p = widget->parentWidget();
+ if (p != this && qobject_cast<QMacNativeWidget *>(p)) {
+ // This widget was reparented into a native Mac view
+ // (see QMenuPrivate::moveWidgetToPlatformItem).
+ // Reset the parent and delete the native widget.
+ widget->setParent(this);
+ p->deleteLater();
+ }
+#endif
wa->releaseWidget(widget);
+ }
}
d->widgetItems.remove(e->action());
}
diff --git a/src/widgets/widgets/qmenu.h b/src/widgets/widgets/qmenu.h
index 8a8eaf3bae..fef7903278 100644
--- a/src/widgets/widgets/qmenu.h
+++ b/src/widgets/widgets/qmenu.h
@@ -195,6 +195,7 @@ private:
Q_PRIVATE_SLOT(d_func(), void _q_actionTriggered())
Q_PRIVATE_SLOT(d_func(), void _q_actionHovered())
Q_PRIVATE_SLOT(d_func(), void _q_overrideMenuActionDestroyed())
+ Q_PRIVATE_SLOT(d_func(), void _q_platformMenuAboutToShow())
protected:
QMenu(QMenuPrivate &dd, QWidget* parent = 0);
diff --git a/src/widgets/widgets/qmenu_mac.mm b/src/widgets/widgets/qmenu_mac.mm
index 41c4481b74..5e304d058b 100644
--- a/src/widgets/widgets/qmenu_mac.mm
+++ b/src/widgets/widgets/qmenu_mac.mm
@@ -44,6 +44,8 @@
#include "qmenu.h"
#include "qmenubar.h"
+#include "qmenubar_p.h"
+#include "qmacnativewidget_mac.h"
#include <QtCore/QDebug>
#include <QtGui/QGuiApplication>
@@ -115,6 +117,23 @@ void QMenu::setAsDockMenu()
\sa QMenu:setAsDockMenu()
*/
+void QMenuPrivate::moveWidgetToPlatformItem(QWidget *widget, QPlatformMenuItem* item)
+{
+ QMacNativeWidget *container = new QMacNativeWidget;
+ QObject::connect(platformMenu, SIGNAL(destroyed()), container, SLOT(deleteLater()));
+ container->resize(widget->sizeHint());
+ widget->setParent(container);
+
+ NSView *containerView = container->nativeView();
+ QWindow *containerWindow = container->windowHandle();
+ Qt::WindowFlags wf = containerWindow->flags();
+ containerWindow->setFlags(wf | Qt::SubWindow);
+ [(NSView *)widget->winId() setAutoresizingMask:NSViewWidthSizable];
+
+ item->setNativeContents((WId)containerView);
+ container->show();
+}
+
#endif //QT_NO_MENU
#ifndef QT_NO_MENUBAR
diff --git a/src/widgets/widgets/qmenu_p.h b/src/widgets/widgets/qmenu_p.h
index 9d9851af64..71bf33e1ce 100644
--- a/src/widgets/widgets/qmenu_p.h
+++ b/src/widgets/widgets/qmenu_p.h
@@ -110,6 +110,9 @@ public:
void init();
void setPlatformMenu(QPlatformMenu *menu);
void syncPlatformMenu();
+#ifdef Q_OS_OSX
+ void moveWidgetToPlatformItem(QWidget *w, QPlatformMenuItem* item);
+#endif
static QMenuPrivate *get(QMenu *m) { return m->d_func(); }
int scrollerHeight() const;
@@ -223,6 +226,7 @@ public:
void _q_actionTriggered();
void _q_actionHovered();
+ void _q_platformMenuAboutToShow();
bool hasMouseMoved(const QPoint &globalPos);
diff --git a/src/widgets/widgets/qmenubar.cpp b/src/widgets/widgets/qmenubar.cpp
index 03ab490823..f523ac2777 100644
--- a/src/widgets/widgets/qmenubar.cpp
+++ b/src/widgets/widgets/qmenubar.cpp
@@ -384,7 +384,7 @@ void QMenuBarPrivate::setCurrentAction(QAction *action, bool popup, bool activat
QAction *previousAction = currentAction;
#endif
currentAction = action;
- if (action) {
+ if (action && action->isEnabled()) {
activateAction(action, QAction::Hover);
if(popup)
popupAction(action, activateFirst);
@@ -531,9 +531,6 @@ void QMenuBarPrivate::_q_actionHovered()
QAccessibleEvent focusEvent(q, QAccessible::Focus);
focusEvent.setChild(actionIndex);
QAccessible::updateAccessibility(&focusEvent);
- QAccessibleEvent selectionEvent(q, QAccessible::Selection);
- selectionEvent.setChild(actionIndex);
- QAccessible::updateAccessibility(&selectionEvent);
}
#endif //QT_NO_ACCESSIBILITY
}
@@ -1041,7 +1038,7 @@ void QMenuBar::mousePressEvent(QMouseEvent *e)
d->mouseDown = true;
QAction *action = d->actionAt(e->pos());
- if (!action || !d->isVisible(action)) {
+ if (!action || !d->isVisible(action) || !action->isEnabled()) {
d->setCurrentAction(0);
#ifndef QT_NO_WHATSTHIS
if (QWhatsThis::inWhatsThisMode())