Merge "Merge remote-tracking branch 'origin/release' into stable" into refs/staging/stable

This commit is contained in:
Frederik Gladhorn 2013-11-22 16:47:35 +01:00 committed by The Qt Project
commit 225526410b
22 changed files with 1124 additions and 1269 deletions

2030
configure vendored

File diff suppressed because it is too large Load Diff

View File

@ -285,13 +285,13 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t)
t << odir << ".deps/%.d: " << pwd << "/%.cpp\n\t";
if(project->isActiveConfig("echo_depend_creation"))
t << "@echo Creating depend for $<\n\t";
t << mkdir_p_asstring("$(@D)") << "\n\t"
t << mkdir_p_asstring("$(@D)", false) << "\n\t"
<< "@$(CXX) " << cmd << " $< | sed \"s,^\\($(*F).o\\):," << odir << "\\1:,g\" >$@\n\n";
t << odir << ".deps/%.d: " << pwd << "/%.c\n\t";
if(project->isActiveConfig("echo_depend_creation"))
t << "@echo Creating depend for $<\n\t";
t << mkdir_p_asstring("$(@D)") << "\n\t"
t << mkdir_p_asstring("$(@D)", false) << "\n\t"
<< "@$(CC) " << cmd << " $< | sed \"s,^\\($(*F).o\\):," << odir << "\\1:,g\" >$@\n\n";
static const char * const src[] = { "SOURCES", "GENERATED_SOURCES", 0 };
@ -804,7 +804,7 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t)
project->first("OBJECTS_DIR")) + ddir,
Option::output_dir, Option::output_dir));
t << "dist: \n\t"
<< mkdir_p_asstring(ddir_c) << "\n\t"
<< mkdir_p_asstring(ddir_c, false) << "\n\t"
<< "$(COPY_FILE) --parents $(SOURCES) $(DIST) " << ddir_c << Option::dir_sep << " && ";
if(!project->isEmpty("QMAKE_EXTRA_COMPILERS")) {
const ProStringList &quc = project->values("QMAKE_EXTRA_COMPILERS");

View File

@ -63,64 +63,45 @@ void QAndroidPlatformMessageDialogHelper::exec()
static QString standardButtonText(int sbutton)
{
QString buttonText = 0;
switch (sbutton) {
case QMessageDialogOptions::Ok:
buttonText = QObject::tr("OK");
break;
return QAndroidPlatformMessageDialogHelper::tr("OK");
case QMessageDialogOptions::Save:
buttonText = QObject::tr("Save");
break;
return QAndroidPlatformMessageDialogHelper::tr("Save");
case QMessageDialogOptions::Open:
buttonText = QObject::tr("Open");
break;
return QAndroidPlatformMessageDialogHelper::tr("Open");
case QMessageDialogOptions::Cancel:
buttonText = QObject::tr("Cancel");
break;
return QAndroidPlatformMessageDialogHelper::tr("Cancel");
case QMessageDialogOptions::Close:
buttonText = QObject::tr("Close");
break;
return QAndroidPlatformMessageDialogHelper::tr("Close");
case QMessageDialogOptions::Apply:
buttonText = QObject::tr("Apply");
break;
return QAndroidPlatformMessageDialogHelper::tr("Apply");
case QMessageDialogOptions::Reset:
buttonText = QObject::tr("Reset");
break;
return QAndroidPlatformMessageDialogHelper::tr("Reset");
case QMessageDialogOptions::Help:
buttonText = QObject::tr("Help");
break;
return QAndroidPlatformMessageDialogHelper::tr("Help");
case QMessageDialogOptions::Discard:
buttonText = QObject::tr("Discard");
break;
return QAndroidPlatformMessageDialogHelper::tr("Discard");
case QMessageDialogOptions::Yes:
buttonText = QObject::tr("Yes");
break;
return QAndroidPlatformMessageDialogHelper::tr("Yes");
case QMessageDialogOptions::YesToAll:
buttonText = QObject::tr("Yes to All");
break;
return QAndroidPlatformMessageDialogHelper::tr("Yes to All");
case QMessageDialogOptions::No:
buttonText = QObject::tr("No");
break;
return QAndroidPlatformMessageDialogHelper::tr("No");
case QMessageDialogOptions::NoToAll:
buttonText = QObject::tr("No to All");
break;
return QAndroidPlatformMessageDialogHelper::tr("No to All");
case QMessageDialogOptions::SaveAll:
buttonText = QObject::tr("Save All");
break;
return QAndroidPlatformMessageDialogHelper::tr("Save All");
case QMessageDialogOptions::Abort:
buttonText = QObject::tr("Abort");
break;
return QAndroidPlatformMessageDialogHelper::tr("Abort");
case QMessageDialogOptions::Retry:
buttonText = QObject::tr("Retry");
break;
return QAndroidPlatformMessageDialogHelper::tr("Retry");
case QMessageDialogOptions::Ignore:
buttonText = QObject::tr("Ignore");
break;
return QAndroidPlatformMessageDialogHelper::tr("Ignore");
case QMessageDialogOptions::RestoreDefaults:
buttonText = QObject::tr("Restore Defaults");
break;
return QAndroidPlatformMessageDialogHelper::tr("Restore Defaults");
} // switch
return buttonText;
return QString();
}
bool QAndroidPlatformMessageDialogHelper::show(Qt::WindowFlags windowFlags

View File

@ -47,6 +47,5 @@
@interface QIOSApplicationDelegate : UIResponder <UIApplicationDelegate>
@property (strong, nonatomic) UIWindow *window;
@property (strong, nonatomic) QIOSViewController *qiosViewController;
@end

View File

@ -49,7 +49,6 @@
@implementation QIOSApplicationDelegate
@synthesize window;
@synthesize qiosViewController;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
@ -57,8 +56,7 @@
Q_UNUSED(launchOptions);
self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
self.qiosViewController = [[[QIOSViewController alloc] init] autorelease];
self.window.rootViewController = self.qiosViewController;
self.window.rootViewController = [[[QIOSViewController alloc] init] autorelease];
self.window.hidden = NO;
@ -67,7 +65,6 @@
- (void)dealloc
{
[qiosViewController release];
[window release];
[super dealloc];
}

View File

@ -52,7 +52,6 @@ QT_BEGIN_NAMESPACE
class QPlatformScreen;
bool isQtApplication();
QIOSViewController *qiosViewController();
CGRect toCGRect(const QRect &rect);
QRect fromCGRect(const CGRect &rect);

View File

@ -58,17 +58,6 @@ bool isQtApplication()
return isQt;
}
QIOSViewController *qiosViewController()
{
// If Qt controls the application, we have created a root view controller were we place top-level
// QWindows. Note that in a mixed native application, our view controller might later be removed or
// added as a child of another controller. To protect against that, we keep an explicit pointer to the
// view controller in cases where this is the controller we need to access.
static QIOSViewController *c = isQtApplication() ?
static_cast<QIOSApplicationDelegate *>([UIApplication sharedApplication].delegate).qiosViewController : nil;
return c;
}
CGRect toCGRect(const QRect &rect)
{
return CGRectMake(rect.x(), rect.y(), rect.width(), rect.height());

View File

@ -72,13 +72,14 @@ public:
UIScreen *uiScreen() const;
void setPrimaryOrientation(Qt::ScreenOrientation orientation);
void updateProperties();
private:
UIScreen *m_uiScreen;
QRect m_geometry;
QRect m_availableGeometry;
int m_depth;
uint m_unscaledDpi;
QSizeF m_physicalSize;
QIOSOrientationListener *m_orientationListener;
};

View File

@ -132,25 +132,14 @@ QIOSScreen::QIOSScreen(unsigned int screenIndex)
m_depth = 24;
}
int unscaledDpi = 163; // Regular iPhone DPI
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad
&& !deviceIdentifier.contains(QRegularExpression("^iPad2,[567]$")) /* excluding iPad Mini */) {
unscaledDpi = 132;
};
CGRect bounds = [m_uiScreen bounds];
m_geometry = QRect(bounds.origin.x, bounds.origin.y, bounds.size.width, bounds.size.height);
CGRect frame = m_uiScreen.applicationFrame;
m_availableGeometry = QRect(frame.origin.x, frame.origin.y, frame.size.width, frame.size.height);
const qreal millimetersPerInch = 25.4;
m_physicalSize = QSizeF(m_geometry.size()) / unscaledDpi * millimetersPerInch;
if (isQtApplication()) {
// When in a non-mixed environment, let QScreen follow the current interface orientation:
setPrimaryOrientation(toQtScreenOrientation(UIDeviceOrientation(qiosViewController().interfaceOrientation)));
m_unscaledDpi = 132;
} else {
m_unscaledDpi = 163; // Regular iPhone DPI
}
updateProperties();
}
QIOSScreen::~QIOSScreen()
@ -158,6 +147,44 @@ QIOSScreen::~QIOSScreen()
[m_orientationListener release];
}
void QIOSScreen::updateProperties()
{
UIWindow *uiWindow = 0;
for (uiWindow in [[UIApplication sharedApplication] windows]) {
if (uiWindow.screen == m_uiScreen)
break;
}
bool inPortrait = UIInterfaceOrientationIsPortrait(uiWindow.rootViewController.interfaceOrientation);
QRect geometry = inPortrait ? fromCGRect(m_uiScreen.bounds)
: QRect(m_uiScreen.bounds.origin.x, m_uiScreen.bounds.origin.y,
m_uiScreen.bounds.size.height, m_uiScreen.bounds.size.width);
if (geometry != m_geometry) {
m_geometry = geometry;
const qreal millimetersPerInch = 25.4;
m_physicalSize = QSizeF(m_geometry.size()) / m_unscaledDpi * millimetersPerInch;
QWindowSystemInterface::handleScreenGeometryChange(screen(), m_geometry);
}
QRect availableGeometry = geometry;
CGSize applicationFrameSize = m_uiScreen.applicationFrame.size;
int statusBarHeight = geometry.height() - (inPortrait ? applicationFrameSize.height : applicationFrameSize.width);
availableGeometry.adjust(0, statusBarHeight, 0, 0);
if (availableGeometry != m_availableGeometry) {
m_availableGeometry = availableGeometry;
QWindowSystemInterface::handleScreenAvailableGeometryChange(screen(), m_availableGeometry);
}
if (screen())
resizeMaximizedWindows();
}
QRect QIOSScreen::geometry() const
{
return m_geometry;
@ -195,7 +222,9 @@ qreal QIOSScreen::devicePixelRatio() const
Qt::ScreenOrientation QIOSScreen::nativeOrientation() const
{
return Qt::PortraitOrientation;
// A UIScreen stays in the native orientation, regardless of rotation
return m_uiScreen.bounds.size.width >= m_uiScreen.bounds.size.height ?
Qt::LandscapeOrientation : Qt::PortraitOrientation;
}
Qt::ScreenOrientation QIOSScreen::orientation() const
@ -213,28 +242,6 @@ void QIOSScreen::setOrientationUpdateMask(Qt::ScreenOrientations mask)
}
}
void QIOSScreen::setPrimaryOrientation(Qt::ScreenOrientation orientation)
{
// Note that UIScreen never changes orientation, but QScreen should. To work around
// this, we let QIOSViewController call us whenever interface orientation changes, and
// use that as primary orientation. After all, the viewcontrollers geometry is what we
// place QWindows on top of. A problem with this approach is that QIOSViewController is
// not in use in a mixed environment, which results in no change to primary orientation.
// We see that as acceptable since Qt should most likely not interfere with orientation
// for that case anyway.
bool portrait = screen()->isPortrait(orientation);
if (portrait && m_geometry.width() < m_geometry.height())
return;
// Switching portrait/landscape means swapping width/height (and adjusting x/y):
m_geometry = QRect(0, 0, m_geometry.height(), m_geometry.width());
m_physicalSize = QSizeF(m_physicalSize.height(), m_physicalSize.width());
m_availableGeometry = fromPortraitToPrimary(fromCGRect(m_uiScreen.applicationFrame), this);
QWindowSystemInterface::handleScreenGeometryChange(screen(), m_geometry);
QWindowSystemInterface::handleScreenAvailableGeometryChange(screen(), m_availableGeometry);
}
UIScreen *QIOSScreen::uiScreen() const
{
return m_uiScreen;

View File

@ -62,19 +62,16 @@
return UIInterfaceOrientationMaskAll;
}
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation duration:(NSTimeInterval)duration
{
Q_UNUSED(duration);
Q_UNUSED(interfaceOrientation);
if (!QCoreApplication::instance())
return; // FIXME: Store orientation for later (?)
Qt::ScreenOrientation orientation = toQtScreenOrientation(UIDeviceOrientation(toInterfaceOrientation));
if (orientation == -1)
return;
QIOSScreen *qiosScreen = static_cast<QIOSScreen *>(QGuiApplication::primaryScreen()->handle());
qiosScreen->setPrimaryOrientation(orientation);
qiosScreen->updateProperties();
}
@end

View File

@ -52,6 +52,7 @@ class QIOSWindow;
@interface UIView (QIOS)
@property(readonly) QWindow *qwindow;
@property(readonly) UIViewController *viewController;
@end
QT_BEGIN_NAMESPACE

View File

@ -105,7 +105,7 @@
CAEAGLLayer *eaglLayer = static_cast<CAEAGLLayer *>(self.layer);
eaglLayer.opaque = TRUE;
eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:YES], kEAGLDrawablePropertyRetainedBacking,
[NSNumber numberWithBool:NO], kEAGLDrawablePropertyRetainedBacking,
kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat, nil];
// Set up text input
@ -168,7 +168,7 @@
QRect geometry = fromCGRect(self.frame);
m_qioswindow->QPlatformWindow::setGeometry(geometry);
QWindowSystemInterface::handleGeometryChange(m_qioswindow->window(), geometry);
QWindowSystemInterface::handleExposeEvent(m_qioswindow->window(), geometry);
QWindowSystemInterface::handleExposeEvent(m_qioswindow->window(), QRect(QPoint(), geometry.size()));
// If we have a new size here we need to resize the FBO's corresponding buffers,
// but we defer that to when the application calls makeCurrent.
@ -348,6 +348,16 @@
return nil;
}
- (UIViewController *)viewController
{
id responder = self;
while ((responder = [responder nextResponder])) {
if ([responder isKindOfClass:UIViewController.class])
return responder;
}
return nil;
}
@end
QT_BEGIN_NAMESPACE
@ -404,7 +414,7 @@ void QIOSWindow::setVisible(bool visible)
requestActivateWindow();
} else {
// Activate top-most visible QWindow:
NSArray *subviews = qiosViewController().view.subviews;
NSArray *subviews = m_view.viewController.view.subviews;
for (int i = int(subviews.count) - 1; i >= 0; --i) {
UIView *view = [subviews objectAtIndex:i];
if (!view.hidden) {
@ -438,19 +448,26 @@ void QIOSWindow::setWindowState(Qt::WindowState state)
// Perhaps setting QWindow to maximized should also mean that we'll show
// the statusbar, and vice versa for fullscreen?
if (state != Qt::WindowNoState)
m_normalGeometry = geometry();
switch (state) {
case Qt::WindowMaximized:
case Qt::WindowFullScreen: {
// Since UIScreen does not take orientation into account when
// reporting geometry, we need to look at the top view instead:
CGSize fullscreenSize = m_view.window.rootViewController.view.bounds.size;
m_view.frame = CGRectMake(0, 0, fullscreenSize.width, fullscreenSize.height);
m_view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
break; }
default:
m_view.frame = toCGRect(m_normalGeometry);
m_view.autoresizingMask = UIViewAutoresizingNone;
case Qt::WindowNoState:
setGeometry(m_normalGeometry);
break;
case Qt::WindowMaximized:
setGeometry(screen()->availableGeometry());
break;
case Qt::WindowFullScreen:
setGeometry(screen()->geometry());
break;
case Qt::WindowMinimized:
setGeometry(QRect());
break;
case Qt::WindowActive:
Q_UNREACHABLE();
default:
Q_UNREACHABLE();
}
}
@ -460,7 +477,12 @@ void QIOSWindow::setParent(const QPlatformWindow *parentWindow)
UIView *parentView = reinterpret_cast<UIView *>(parentWindow->winId());
[parentView addSubview:m_view];
} else if (isQtApplication()) {
[qiosViewController().view addSubview:m_view];
for (UIWindow *uiWindow in [[UIApplication sharedApplication] windows]) {
if (uiWindow.screen == static_cast<QIOSScreen *>(screen())->uiScreen()) {
[uiWindow.rootViewController.view addSubview:m_view];
break;
}
}
}
}
@ -469,12 +491,14 @@ void QIOSWindow::requestActivateWindow()
// Note that several windows can be active at the same time if they exist in the same
// hierarchy (transient children). But only one window can be QGuiApplication::focusWindow().
// Dispite the name, 'requestActivateWindow' means raise and transfer focus to the window:
if (!window()->isTopLevel() || blockedByModal())
if (blockedByModal())
return;
[m_view.window makeKeyWindow];
raise();
if (window()->isTopLevel())
raise();
QPlatformInputContext *context = QGuiApplicationPrivate::platformIntegration()->inputContext();
static_cast<QIOSInputContext *>(context)->focusViewChanged(m_view);
QWindowSystemInterface::handleWindowActivated(window());

View File

@ -53,6 +53,7 @@
#include <qpa/qplatformintegration.h>
#include "QtGui/private/qwindow_p.h"
#include "QtGui/private/qguiapplication_p.h"
#include <private/qwindowcontainer_p.h>
#include <qpa/qplatformcursor.h>
#include <QtGui/QGuiApplication>
@ -267,8 +268,11 @@ void QWidgetPrivate::setParent_sys(QWidget *newparent, Qt::WindowFlags f)
bool explicitlyHidden = q->testAttribute(Qt::WA_WState_Hidden) && q->testAttribute(Qt::WA_WState_ExplicitShowHide);
// Reparenting toplevel to child
if (wasCreated && !(f & Qt::Window) && (oldFlags & Qt::Window) && !q->testAttribute(Qt::WA_NativeWindow))
if (wasCreated && !(f & Qt::Window) && (oldFlags & Qt::Window) && !q->testAttribute(Qt::WA_NativeWindow)) {
if (extra && extra->hasWindowContainer)
QWindowContainer::toplevelAboutToBeDestroyed(q);
q->destroy();
}
adjustFlags(f, q);
data.window_flags = f;
@ -506,9 +510,9 @@ void QWidgetPrivate::show_sys()
QWindow *window = q->windowHandle();
q->setAttribute(Qt::WA_Mapped);
if (q->testAttribute(Qt::WA_DontShowOnScreen)) {
invalidateBuffer(q->rect());
q->setAttribute(Qt::WA_Mapped);
if (q->isWindow() && q->windowModality() != Qt::NonModal && window) {
// add our window to the modal window list
QGuiApplicationPrivate::showModalWindow(window);

View File

@ -715,6 +715,10 @@ void QWidgetWindow::handleWindowStateChangedEvent(QWindowStateChangeEvent *event
break;
}
// Note that widgetState == m_widget->data->window_state when triggered by QWidget::setWindowState().
if (!(widgetState & Qt::WindowMinimized))
m_widget->setAttribute(Qt::WA_Mapped);
// Sent event if the state changed (that is, it is not triggered by
// QWidget::setWindowState(), which also sends an event to the widget).
if (widgetState != int(m_widget->data->window_state)) {

View File

@ -305,15 +305,28 @@ static void qwindowcontainer_traverse(QWidget *parent, qwindowcontainer_traverse
}
}
void QWindowContainer::toplevelAboutToBeDestroyed(QWidget *parent)
{
if (QWindowContainerPrivate *d = QWindowContainerPrivate::get(parent)) {
d->window->setParent(&d->fakeParent);
}
qwindowcontainer_traverse(parent, toplevelAboutToBeDestroyed);
}
void QWindowContainer::parentWasChanged(QWidget *parent)
{
if (QWindowContainerPrivate *d = QWindowContainerPrivate::get(parent)) {
if (d->window->parent()) {
d->updateUsesNativeWidgets();
d->markParentChain();
d->window->setParent(d->usesNativeWidgets
? parent->windowHandle()
: parent->window()->windowHandle());
QWidget *toplevel = d->usesNativeWidgets ? parent : parent->window();
if (!toplevel->windowHandle()) {
QWidgetPrivate *tld = static_cast<QWidgetPrivate *>(QWidgetPrivate::get(toplevel));
tld->createTLExtra();
tld->createTLSysExtra();
Q_ASSERT(toplevel->windowHandle());
}
d->window->setParent(toplevel->windowHandle());
d->updateGeometry();
}
}

View File

@ -57,6 +57,7 @@ public:
explicit QWindowContainer(QWindow *embeddedWindow, QWidget *parent = 0, Qt::WindowFlags f = 0);
~QWindowContainer();
static void toplevelAboutToBeDestroyed(QWidget *parent);
static void parentWasChanged(QWidget *parent);
static void parentWasMoved(QWidget *parent);
static void parentWasRaised(QWidget *parent);

View File

@ -1834,6 +1834,14 @@ QSize QMenu::sizeHint() const
void QMenu::popup(const QPoint &p, QAction *atAction)
{
Q_D(QMenu);
#ifdef Q_OS_ANDROID
if (!d->platformMenu.isNull() && !testAttribute(Qt::WA_SetStyle)) {
d->platformMenu->showPopup(window()->windowHandle(), p, 0);
return;
}
#endif
if (d->scroll) { // reset scroll state from last popup
if (d->scroll->scrollOffset)
d->itemsDirty = 1; // sizeHint will be incorrect if there is previous scroll

View File

@ -177,7 +177,7 @@ void tst_QWindow::resizeEventAfterResize()
Window window;
window.setGeometry(geometry);
window.show();
window.showNormal();
QTRY_COMPARE(window.received(QEvent::Resize), 1);
@ -843,7 +843,10 @@ void tst_QWindow::activateAndClose()
{
for (int i = 0; i < 10; ++i) {
QWindow window;
window.show();
// qWaitForWindowActive will block for the duration of
// of the timeout if the window is at 0,0
window.setGeometry(QGuiApplication::primaryScreen()->availableGeometry().adjusted(1, 1, -1, -1));
window.showNormal();
window.requestActivate();
QVERIFY(QTest::qWaitForWindowActive(&window));
QCOMPARE(qGuiApp->focusWindow(), &window);

View File

@ -7192,6 +7192,10 @@ void tst_QWidget::hideOpaqueChildWhileHidden()
#if !defined(Q_OS_WINCE)
void tst_QWidget::updateWhileMinimized()
{
#ifdef Q_OS_UNIX
if (qgetenv("XDG_CURRENT_DESKTOP").contains("Unity"))
QSKIP("This test fails on Unity."); // Minimized windows are not unmapped for some reason.
#endif // Q_OS_UNIX
UpdateWidget widget;
// Filter out activation change and focus events to avoid update() calls in QWidget.
widget.updateOnActivationChangeAndFocusIn = false;

View File

@ -91,6 +91,8 @@ private slots:
void tst_showWithoutActivating();
void tst_paintEventOnSecondShow();
void obscuredNativeMapped();
#ifndef QT_NO_DRAGANDDROP
void tst_dnd();
#endif
@ -368,6 +370,32 @@ void tst_QWidget_window::tst_paintEventOnSecondShow()
QTRY_VERIFY(w.paintEventReceived);
}
// QTBUG-33520, a toplevel fully obscured by native children should still receive Qt::WA_Mapped
void tst_QWidget_window::obscuredNativeMapped()
{
enum { size = 200 };
QWidget topLevel;
topLevel.setWindowFlags(Qt::FramelessWindowHint);
QWidget *child = new QWidget(&topLevel);
child->resize(size, size);
topLevel.resize(size, size);
topLevel.move(QGuiApplication::primaryScreen()->availableGeometry().center() - QPoint(size /2 , size / 2));
child->winId();
topLevel.show();
QTRY_VERIFY(topLevel.testAttribute(Qt::WA_Mapped));
#if defined(Q_OS_MAC)
QSKIP("This test fails on Mac."); // Minimized windows are not unmapped for some reason.
#elif defined(Q_OS_UNIX)
if (qgetenv("XDG_CURRENT_DESKTOP").contains("Unity"))
QSKIP("This test fails on Unity."); // Minimized windows are not unmapped for some reason.
#endif // Q_OS_UNIX
topLevel.setWindowState(Qt::WindowMinimized);
QTRY_VERIFY(!topLevel.testAttribute(Qt::WA_Mapped));
topLevel.setWindowState(Qt::WindowNoState);
QTRY_VERIFY(topLevel.testAttribute(Qt::WA_Mapped));
}
#ifndef QT_NO_DRAGANDDROP
/* DnD test for QWidgetWindow (handleDrag*Event() functions).

View File

@ -46,6 +46,8 @@
#include <qwindow.h>
#include <qwidget.h>
#include <qdockwidget.h>
#include <qmainwindow.h>
class Window : public QWindow
@ -80,6 +82,7 @@ private slots:
void testUnparenting();
void testActivation();
void testAncestorChange();
void testDockWidget();
};
@ -278,6 +281,7 @@ void tst_QWindowContainer::testAncestorChange()
newRoot->setGeometry(100, 100, 200, 200);
newRoot->show();
QVERIFY(QTest::qWaitForWindowExposed(newRoot));
QCOMPARE(newRoot->windowHandle(), window->parent());
// newRoot
// + right
// + container
@ -285,6 +289,31 @@ void tst_QWindowContainer::testAncestorChange()
QCOMPARE(window->geometry(), QRect(100, 0, 100, 100));
}
void tst_QWindowContainer::testDockWidget()
{
QMainWindow mainWindow;
mainWindow.resize(200, 200);
QDockWidget *dock = new QDockWidget();
QWindow *window = new QWindow();
QWidget *container = QWidget::createWindowContainer(window);
dock->setWidget(container);
mainWindow.addDockWidget(Qt::RightDockWidgetArea, dock);
mainWindow.show();
QVERIFY(QTest::qWaitForWindowExposed(&mainWindow));
QVERIFY(window->parent() == mainWindow.window()->windowHandle());
QTest::qWait(1000);
dock->setFloating(true);
QTRY_VERIFY(window->parent() != mainWindow.window()->windowHandle());
QTest::qWait(1000);
dock->setFloating(false);
QTRY_VERIFY(window->parent() == mainWindow.window()->windowHandle());
}
QTEST_MAIN(tst_QWindowContainer)
#include "tst_qwindowcontainer.moc"

View File

@ -384,7 +384,7 @@ void Configure::parseCmdLine()
configCmdLine.clear();
reloadCmdLine();
} else {
dictionary[ "HELP" ] = "yes";
dictionary[ "DONE" ] = "error";
}
i = 0;
}
@ -1304,7 +1304,7 @@ void Configure::parseCmdLine()
}
else {
dictionary[ "HELP" ] = "yes";
dictionary[ "DONE" ] = "error";
cout << "Unknown option " << configCmdLine.at(i) << endl;
break;
}
@ -1324,7 +1324,7 @@ void Configure::parseCmdLine()
if (dictionary["QMAKESPEC"].toLower() == "features"
|| !mkspecs.contains(dictionary["QMAKESPEC"], Qt::CaseInsensitive)) {
dictionary[ "HELP" ] = "yes";
dictionary[ "DONE" ] = "error";
if (dictionary ["QMAKESPEC_FROM"] == "commandline") {
cout << "Invalid option \"" << dictionary["QMAKESPEC"] << "\" for -platform." << endl;
} else if (dictionary ["QMAKESPEC_FROM"] == "env") {
@ -1362,10 +1362,10 @@ void Configure::parseCmdLine()
const QStringList family = devices.filter(dictionary["XQMAKESPEC"], Qt::CaseInsensitive);
if (family.isEmpty()) {
dictionary["HELP"] = "yes";
dictionary[ "DONE" ] = "error";
cout << "Error: No device matching '" << dictionary["XQMAKESPEC"] << "'." << endl;
} else if (family.size() > 1) {
dictionary["HELP"] = "yes";
dictionary[ "DONE" ] = "error";
cout << "Error: Multiple matches for device '" << dictionary["XQMAKESPEC"] << "'. Candidates are:" << endl;
@ -1380,7 +1380,7 @@ void Configure::parseCmdLine()
// Ensure that -spec (XQMAKESPEC) exists in the mkspecs folder as well
if (dictionary.contains("XQMAKESPEC") &&
!mkspecs.contains(dictionary["XQMAKESPEC"], Qt::CaseInsensitive)) {
dictionary["HELP"] = "yes";
dictionary[ "DONE" ] = "error";
cout << "Invalid option \"" << dictionary["XQMAKESPEC"] << "\" for -xplatform." << endl;
}
}
@ -1432,7 +1432,8 @@ void Configure::parseCmdLine()
for (QStringList::Iterator it = disabledModules.begin(); it != disabledModules.end(); ++it)
qtConfig.removeAll(*it);
if ((dictionary[ "REDO" ] != "yes") && (dictionary[ "HELP" ] != "yes"))
if ((dictionary[ "REDO" ] != "yes") && (dictionary[ "HELP" ] != "yes")
&& (dictionary[ "DONE" ] != "error"))
saveCmdLine();
}
@ -1461,7 +1462,7 @@ void Configure::validateArgs()
if (!QFileInfo::exists(cfgpath)) {
cfgpath = QFileInfo(dictionary["QCONFIG"]).absoluteFilePath();
if (!QFileInfo::exists(cfgpath)) {
dictionary[ "HELP" ] = "yes";
dictionary[ "DONE" ] = "error";
cout << "No such configuration \"" << qPrintable(dictionary["QCONFIG"]) << "\"" << endl ;
return;
}
@ -2825,7 +2826,6 @@ void Configure::generateOutputVars()
cout << "Configure could not detect your compiler. QMAKESPEC must either" << endl
<< "be defined as an environment variable, or specified as an" << endl
<< "argument with -platform" << endl;
dictionary[ "HELP" ] = "yes";
QStringList winPlatforms;
QDir mkspecsDir(sourcePath + "/mkspecs");