diff options
author | Guoqing Zhang <guoqing.zhang@nokia.com> | 2011-04-05 07:49:59 (GMT) |
---|---|---|
committer | Guoqing Zhang <guoqing.zhang@nokia.com> | 2011-04-05 07:49:59 (GMT) |
commit | 81921596f6083eedb926c214c3e6324ba4b40cab (patch) | |
tree | 089f0bbd39c46afbae5e47f8ac990977024bc91c /src/gui/kernel | |
parent | ebe4edf58728f4dc5cf633ba6fb92dea721b2bdc (diff) | |
parent | c3e903409b96fede96cb4a7b95ba308663c88879 (diff) | |
download | Qt-81921596f6083eedb926c214c3e6324ba4b40cab.zip Qt-81921596f6083eedb926c214c3e6324ba4b40cab.tar.gz Qt-81921596f6083eedb926c214c3e6324ba4b40cab.tar.bz2 |
Merge remote branch 'qt-master/master'
Diffstat (limited to 'src/gui/kernel')
29 files changed, 651 insertions, 90 deletions
diff --git a/src/gui/kernel/kernel.pri b/src/gui/kernel/kernel.pri index 0ff3d88..32fa3d3 100644 --- a/src/gui/kernel/kernel.pri +++ b/src/gui/kernel/kernel.pri @@ -223,7 +223,8 @@ qpa { kernel/qdesktopwidget_qpa_p.h \ kernel/qplatformeventloopintegration_qpa.h \ kernel/qplatformcursor_qpa.h \ - kernel/qplatformclipboard_qpa.h + kernel/qplatformclipboard_qpa.h \ + kernel/qplatformnativeinterface_qpa.h SOURCES += \ kernel/qapplication_qpa.cpp \ @@ -246,7 +247,8 @@ qpa { kernel/qplatformeventloopintegration_qpa.cpp \ kernel/qplatformglcontext_qpa.cpp \ kernel/qplatformcursor_qpa.cpp \ - kernel/qplatformclipboard_qpa.cpp + kernel/qplatformclipboard_qpa.cpp \ + kernel/qplatformnativeinterface_qpa.cpp contains(QT_CONFIG, glib) { SOURCES += \ diff --git a/src/gui/kernel/qapplication_qpa.cpp b/src/gui/kernel/qapplication_qpa.cpp index cd76adf..cb5439c 100644 --- a/src/gui/kernel/qapplication_qpa.cpp +++ b/src/gui/kernel/qapplication_qpa.cpp @@ -51,6 +51,7 @@ #endif #include "private/qwidget_p.h" +#include "private/qevent_p.h" #include "qgenericpluginfactory_qpa.h" #include "qplatformintegrationfactory_qpa_p.h" @@ -816,8 +817,14 @@ void QApplicationPrivate::processKeyEvent(QWindowSystemInterfacePrivate::KeyEven if (app_do_modal && !qt_try_modal(focusW, e->keyType)) return; - QKeyEvent ev(e->keyType, e->key, e->modifiers, e->unicode, e->repeat, e->repeatCount); - QApplication::sendSpontaneousEvent(focusW, &ev); + if (e->nativeScanCode || e->nativeVirtualKey || e->nativeModifiers) { + QKeyEventEx ev(e->keyType, e->key, e->modifiers, e->unicode, e->repeat, e->repeatCount, + e->nativeScanCode, e->nativeVirtualKey, e->nativeModifiers); + QApplication::sendSpontaneousEvent(focusW, &ev); + } else { + QKeyEvent ev(e->keyType, e->key, e->modifiers, e->unicode, e->repeat, e->repeatCount); + QApplication::sendSpontaneousEvent(focusW, &ev); + } } void QApplicationPrivate::processEnterEvent(QWindowSystemInterfacePrivate::EnterEvent *e) diff --git a/src/gui/kernel/qapplication_s60.cpp b/src/gui/kernel/qapplication_s60.cpp index 3ce597b..769b136 100644 --- a/src/gui/kernel/qapplication_s60.cpp +++ b/src/gui/kernel/qapplication_s60.cpp @@ -1132,7 +1132,8 @@ void QSymbianControl::Draw(const TRect& controlRect) const // Do nothing break; case QWExtra::Blit: - if (qwidget->d_func()->isOpaque) + case QWExtra::BlitWriteAlpha: + if (qwidget->d_func()->isOpaque || nativePaintMode == QWExtra::BlitWriteAlpha) gc.SetDrawMode(CGraphicsContext::EDrawModeWriteAlpha); gc.BitBlt(controlRect.iTl, bitmap, backingStoreRect); break; @@ -1270,15 +1271,36 @@ void QSymbianControl::FocusChanged(TDrawNow /* aDrawNow */) qwidget->d_func()->setWindowIcon_sys(true); qwidget->d_func()->setWindowTitle_sys(qwidget->windowTitle()); #ifdef Q_WS_S60 - // If widget is fullscreen/minimized, hide status pane and button container otherwise show them. - QWidget *const window = qwidget->window(); - if (!window->parentWidget()) { // Only top level native windows have control over cba/status pane - const bool decorationsVisible = !(window->windowState() & (Qt::WindowFullScreen | Qt::WindowMinimized)); - const bool statusPaneVisibility = decorationsVisible; - const bool isFullscreen = window->windowState() & Qt::WindowFullScreen; - const bool cbaVisibilityHint = window->windowFlags() & Qt::WindowSoftkeysVisibleHint; - const bool buttonGroupVisibility = (decorationsVisible || (isFullscreen && cbaVisibilityHint)); - S60->setStatusPaneAndButtonGroupVisibility(statusPaneVisibility, buttonGroupVisibility); + if (qwidget->isWindow()) { + QWidget *const window = qwidget->window(); + QWidget *parentWindow = window->parentWidget(); + if (parentWindow) { + while (parentWindow->parentWidget()) + parentWindow = parentWindow->parentWidget(); + } else { + parentWindow = window; + } + + const bool parentDecorationsVisible = !(parentWindow->windowState() & (Qt::WindowFullScreen | Qt::WindowMinimized)); + const bool parentIsFullscreen = parentWindow->windowState() & Qt::WindowFullScreen; + const bool parentCbaVisibilityHint = parentWindow->windowFlags() & Qt::WindowSoftkeysVisibleHint; + bool buttonGroupVisibility = (parentDecorationsVisible || (parentIsFullscreen && parentCbaVisibilityHint)); + + // For non-toplevel normal and maximized windows, show cba if window has softkey + // actions even if topmost parent is not showing cba. Do the same for fullscreen + // windows that request it. + if (!buttonGroupVisibility + && window->parentWidget() + && !(window->windowState() & Qt::WindowMinimized) + && ((window->windowFlags() & Qt::WindowSoftkeysVisibleHint) || !(window->windowState() & Qt::WindowFullScreen))) { + for (int i = 0; i < window->actions().size(); ++i) { + if (window->actions().at(i)->softKeyRole() != QAction::NoSoftKey) { + buttonGroupVisibility = true; + break; + } + } + } + S60->setStatusPaneAndButtonGroupVisibility(parentDecorationsVisible, buttonGroupVisibility); } #endif } else if (QApplication::activeWindow() == qwidget->window()) { @@ -1454,6 +1476,35 @@ bool QSymbianControl::isControlActive() return IsActivated() ? true : false; } +void QSymbianControl::ensureFixNativeOrientation() +{ +#if defined(Q_SYMBIAN_SUPPORTS_FIXNATIVEORIENTATION) + // Call FixNativeOrientation() for fullscreen QDeclarativeViews that + // have a locked orientation matching the native orientation of the device. + // This avoids unnecessary window rotation on wserv level. + if (!qwidget->isWindow() || qwidget->windowType() == Qt::Desktop + || !qwidget->inherits("QDeclarativeView") + || S60->screenNumberForWidget(qwidget) > 0) + return; + const bool isFullScreen = qwidget->windowState().testFlag(Qt::WindowFullScreen); + const bool isFixed = qwidget->d_func()->fixNativeOrientationCalled; + const bool matchesNative = qwidget->testAttribute( + S60->nativeOrientationIsPortrait ? Qt::WA_LockPortraitOrientation + : Qt::WA_LockLandscapeOrientation); + if (isFullScreen && matchesNative) { + if (!isFixed) { + Window().FixNativeOrientation(); + qwidget->d_func()->fixNativeOrientationCalled = true; + } + } else if (isFixed) { + qwidget->d_func()->fixNativeOrientationCalled = false; + qwidget->hide(); + qwidget->d_func()->create_sys(0, false, true); + qwidget->show(); + } +#endif +} + /*! \typedef QApplication::QS60MainApplicationFactory \since 4.6 diff --git a/src/gui/kernel/qapplication_x11.cpp b/src/gui/kernel/qapplication_x11.cpp index 589b12e..31f70c7 100644 --- a/src/gui/kernel/qapplication_x11.cpp +++ b/src/gui/kernel/qapplication_x11.cpp @@ -1587,6 +1587,9 @@ static void getXDefault(const char *group, const char *key, int *val) int v = strtol(str, &end, 0); if (str != end) *val = v; + // otherwise use fontconfig to convert the string to integer + else + FcNameConstant((FcChar8 *) str, val); } } @@ -2237,6 +2240,7 @@ void qt_init(QApplicationPrivate *priv, int, } getXDefault("Xft", FC_ANTIALIAS, &X11->fc_antialias); #ifdef FC_HINT_STYLE + X11->fc_hint_style = -1; getXDefault("Xft", FC_HINT_STYLE, &X11->fc_hint_style); #endif #if 0 diff --git a/src/gui/kernel/qclipboard_win.cpp b/src/gui/kernel/qclipboard_win.cpp index 52b9663..ea41165 100644 --- a/src/gui/kernel/qclipboard_win.cpp +++ b/src/gui/kernel/qclipboard_win.cpp @@ -52,6 +52,7 @@ #include "qt_windows.h" #include "qdnd_p.h" #include <private/qwidget_p.h> +#include <private/qsystemlibrary_p.h> QT_BEGIN_NAMESPACE @@ -70,6 +71,9 @@ void QtCeFlushClipboard(); #endif +typedef BOOL (WINAPI *PtrIsHungAppWindow)(HWND); + +static PtrIsHungAppWindow ptrIsHungAppWindow = 0; class QClipboardWatcher : public QInternalMimeData { public: @@ -327,9 +331,16 @@ bool QClipboard::event(QEvent *e) d->releaseIData(); propagate = true; } - if (propagate && d->nextClipboardViewer) { - SendMessage(d->nextClipboardViewer, m->message, m->wParam, m->lParam); + if (ptrIsHungAppWindow == 0) { + QSystemLibrary library(QLatin1String("User32")); + ptrIsHungAppWindow = (PtrIsHungAppWindow)library.resolve("IsHungAppWindow"); + } + if (ptrIsHungAppWindow && ptrIsHungAppWindow(d->nextClipboardViewer)) { + qWarning("%s: Cowardly refusing to send clipboard message to hung application...", Q_FUNC_INFO); + } else { + SendMessage(d->nextClipboardViewer, m->message, m->wParam, m->lParam); + } } return true; diff --git a/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h b/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h index c4b74c6..7d41f3d 100644 --- a/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h +++ b/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h @@ -533,22 +533,6 @@ QT_END_NAMESPACE return de.isAccepted(); } -- (void)displayIfNeeded -{ - - QWidget *qwidget = [[QT_MANGLE_NAMESPACE(QCocoaWindowDelegate) sharedDelegate] qt_qwidgetForWindow:self]; - if (qwidget == 0) { - [super displayIfNeeded]; - return; - } - - if (QApplicationPrivate::graphicsSystem() != 0) { - if (QWidgetBackingStore *bs = qt_widget_private(qwidget)->maybeBackingStore()) - bs->sync(qwidget, qwidget->rect()); - } - [super displayIfNeeded]; -} - // This is a hack and it should be removed once we find the real cause for // the painting problems. // We have a static variable that signals if we have been called before or not. diff --git a/src/gui/kernel/qcocoaview_mac.mm b/src/gui/kernel/qcocoaview_mac.mm index 5e8b37e..b5e5d18 100644 --- a/src/gui/kernel/qcocoaview_mac.mm +++ b/src/gui/kernel/qcocoaview_mac.mm @@ -51,6 +51,8 @@ #include <private/qmacinputcontext_p.h> #include <private/qevent_p.h> #include <private/qbackingstore_p.h> +#include <private/qwindowsurface_raster_p.h> +#include <private/qunifiedtoolbarsurface_mac_p.h> #include <qscrollarea.h> #include <qhash.h> @@ -246,8 +248,82 @@ static int qCocoaViewCount = 0; { if (!qwidget) return; - if (QApplicationPrivate::graphicsSystem() != 0 && !qwidgetprivate->isInUnifiedToolbar) { - // INVARIANT: We use a different graphics system. + + // Getting context. + CGContextRef context = (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort]; + qt_mac_retain_graphics_context(context); + + // We use a different graphics system. + // + // Widgets that are set to paint on screen, specifically QGLWidget, + // requires the native engine to execute in order to be drawn. + if (QApplicationPrivate::graphicsSystem() != 0 && !qwidget->testAttribute(Qt::WA_PaintOnScreen)) { + + // Raster engine. + if (QApplicationPrivate::graphics_system_name == QLatin1String("raster")) { + + if (!qwidgetprivate->isInUnifiedToolbar) { + + // Qt handles the painting occuring inside the window. + // Cocoa also keeps track of all widgets as NSView and therefore might + // ask for a repainting of a widget even if Qt is already taking care of it. + // + // The only valid reason for Cocoa to call drawRect: is for window manipulation + // (ie. resize, ...). + // + // Qt will then forward the update to the children. + if (!qwidget->isWindow()) { + qt_mac_release_graphics_context(context); + return; + } + + QRasterWindowSurface *winSurface = dynamic_cast<QRasterWindowSurface *>(qwidget->windowSurface()); + if (!winSurface || !winSurface->needsFlush) { + qt_mac_release_graphics_context(context); + return; + } + + // Clip to region. + const QVector<QRect> &rects = winSurface->regionToFlush.rects(); + for (int i = 0; i < rects.size(); ++i) { + const QRect &rect = rects.at(i); + CGContextAddRect(context, CGRectMake(rect.x(), rect.y(), rect.width(), rect.height())); + } + CGContextClip(context); + + QRect r = winSurface->regionToFlush.boundingRect(); + const CGRect area = CGRectMake(r.x(), r.y(), r.width(), r.height()); + + qt_mac_draw_image(context, winSurface->imageContext(), area, area); + + winSurface->needsFlush = false; + winSurface->regionToFlush = QRegion(); + + } else { + + QUnifiedToolbarSurface *unifiedSurface = qwidgetprivate->unifiedSurface; + if (!unifiedSurface) { + qt_mac_release_graphics_context(context); + return; + } + + int areaX = qwidgetprivate->toolbar_offset.x(); + int areaY = qwidgetprivate->toolbar_offset.y(); + int areaWidth = qwidget->geometry().width(); + int areaHeight = qwidget->geometry().height(); + const CGRect area = CGRectMake(areaX, areaY, areaWidth, areaHeight); + const CGRect drawingArea = CGRectMake(0, 0, areaWidth, areaHeight); + + qt_mac_draw_image(context, unifiedSurface->imageContext(), area, drawingArea); + + qwidgetprivate->flushRequested = false; + + } + + CGContextFlush(context); + qt_mac_release_graphics_context(context); + return; + } // Qt handles the painting occuring inside the window. // Cocoa also keeps track of all widgets as NSView and therefore might @@ -261,27 +337,10 @@ static int qCocoaViewCount = 0; qwidget->update(qwidget->rect()); qwidgetprivate->syncBackingStore(qwidget->rect()); } - - // Since we don't want to use the native engine, we must exit, however - // widgets that are set to paint on screen, spesifically QGLWidget, - // requires the following code to execute in order to be drawn. - if (!qwidget->testAttribute(Qt::WA_PaintOnScreen)) - return; - } - - CGContextRef cg = (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort]; - CGContextRetain(cg); - qwidgetprivate->hd = cg; - - // We steal the CGContext for flushing in the unified toolbar with the raster engine. - if (QApplicationPrivate::graphicsSystem() != 0 && qwidgetprivate->isInUnifiedToolbar && qwidgetprivate->unifiedSurface) { - qwidgetprivate->cgContext = cg; - qwidgetprivate->hasOwnContext = true; - qwidgetprivate->unifiedSurface->flush(qwidget, qwidgetprivate->ut_rg, qwidgetprivate->ut_pt); - return; } - CGContextSaveGState(cg); + // Native engine. + qwidgetprivate->hd = context; if (qwidget->isVisible() && qwidget->updatesEnabled()) { //process the actual paint event. if (qwidget->testAttribute(Qt::WA_WState_InPaintEvent)) @@ -316,18 +375,18 @@ static int qCocoaViewCount = 0; engine->setSystemClip(qrgn); if (qwidgetprivate->extra && qwidgetprivate->extra->hasMask) { CGRect widgetRect = CGRectMake(0, 0, qwidget->width(), qwidget->height()); - CGContextTranslateCTM (cg, 0, widgetRect.size.height); - CGContextScaleCTM(cg, 1, -1); + CGContextTranslateCTM (context, 0, widgetRect.size.height); + CGContextScaleCTM(context, 1, -1); if (qwidget->isWindow()) - CGContextClearRect(cg, widgetRect); - CGContextClipToMask(cg, widgetRect, qwidgetprivate->extra->imageMask); - CGContextScaleCTM(cg, 1, -1); - CGContextTranslateCTM (cg, 0, -widgetRect.size.height); + CGContextClearRect(context, widgetRect); + CGContextClipToMask(context, widgetRect, qwidgetprivate->extra->imageMask); + CGContextScaleCTM(context, 1, -1); + CGContextTranslateCTM (context, 0, -widgetRect.size.height); } if (qwidget->isWindow() && !qwidgetprivate->isOpaque && !qwidget->testAttribute(Qt::WA_MacBrushedMetal)) { - CGContextClearRect(cg, NSRectToCGRect(aRect)); + CGContextClearRect(context, NSRectToCGRect(aRect)); } qwidget->setAttribute(Qt::WA_WState_InPaintEvent, false); @@ -358,8 +417,7 @@ static int qCocoaViewCount = 0; " widget outside of the PaintEvent"); } qwidgetprivate->hd = 0; - CGContextRestoreGState(cg); - CGContextRelease(cg); + qt_mac_release_graphics_context(context); } - (BOOL)acceptsFirstMouse:(NSEvent *)theEvent diff --git a/src/gui/kernel/qcocoawindowdelegate_mac.mm b/src/gui/kernel/qcocoawindowdelegate_mac.mm index b8be627..1faf068 100644 --- a/src/gui/kernel/qcocoawindowdelegate_mac.mm +++ b/src/gui/kernel/qcocoawindowdelegate_mac.mm @@ -48,6 +48,9 @@ #include <qlayout.h> #include <qcoreapplication.h> #include <qmenubar.h> +#include <QMainWindow> +#include <QToolBar> +#include <private/qmainwindowlayout_p.h> QT_BEGIN_NAMESPACE extern QWidgetData *qt_qwidget_data(QWidget *); // qwidget.cpp @@ -215,6 +218,24 @@ static void cleanupCocoaWindowDelegate() QWidgetPrivate::qt_mac_update_sizer(qwidget); [self syncSizeForWidget:qwidget toSize:newSize fromSize:oldSize]; } + + // We force the repaint to be synchronized with the resize of the window. + // Otherwise, the resize looks sluggish because we paint one event loop later. + if ([[window contentView] inLiveResize]) { + qwidget->repaint(); + + // We need to repaint the toolbar as well. + QMainWindow* mWindow = qobject_cast<QMainWindow*>(qwidget->window()); + if (mWindow) { + QMainWindowLayout *mLayout = qobject_cast<QMainWindowLayout*>(mWindow->layout()); + QList<QToolBar *> toolbarList = mLayout->qtoolbarsInUnifiedToolbarList; + + for (int i = 0; i < toolbarList.size(); ++i) { + QToolBar* toolbar = toolbarList.at(i); + toolbar->repaint(); + } + } + } } - (void)windowDidMove:(NSNotification *)notification diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp index 698c94b..277a5e8 100644 --- a/src/gui/kernel/qevent.cpp +++ b/src/gui/kernel/qevent.cpp @@ -43,6 +43,7 @@ #include "qcursor.h" #include "qapplication.h" #include "private/qapplication_p.h" +#include "private/qevent_p.h" #include "private/qkeysequence_p.h" #include "qwidget.h" #include "qgraphicsview.h" diff --git a/src/gui/kernel/qeventdispatcher_qpa.cpp b/src/gui/kernel/qeventdispatcher_qpa.cpp index 7701612..de53618 100644 --- a/src/gui/kernel/qeventdispatcher_qpa.cpp +++ b/src/gui/kernel/qeventdispatcher_qpa.cpp @@ -172,7 +172,6 @@ public: { if (qApp && (qApp->thread() == QThread::currentThread())) { m_isEventLoopIntegrationRunning = true; - QCoreApplication::processEvents(QEventLoop::WaitForMoreEvents); eventLoopIntegration->startEventLoop(); } } diff --git a/src/gui/kernel/qplatformclipboard_qpa.cpp b/src/gui/kernel/qplatformclipboard_qpa.cpp index e169f08..957a4df 100644 --- a/src/gui/kernel/qplatformclipboard_qpa.cpp +++ b/src/gui/kernel/qplatformclipboard_qpa.cpp @@ -40,6 +40,8 @@ ****************************************************************************/ #include "qplatformclipboard_qpa.h" +#ifndef QT_NO_CLIPBOARD + QT_BEGIN_NAMESPACE class QClipboardData @@ -99,3 +101,5 @@ bool QPlatformClipboard::supportsMode(QClipboard::Mode mode) const } QT_END_NAMESPACE + +#endif //QT_NO_CLIPBOARD diff --git a/src/gui/kernel/qplatformclipboard_qpa.h b/src/gui/kernel/qplatformclipboard_qpa.h index 78cd444..3381c06 100644 --- a/src/gui/kernel/qplatformclipboard_qpa.h +++ b/src/gui/kernel/qplatformclipboard_qpa.h @@ -44,6 +44,8 @@ #include <qplatformdefs.h> +#ifndef QT_NO_CLIPBOARD + #include <QtGui/QClipboard> QT_BEGIN_HEADER @@ -66,5 +68,6 @@ QT_END_NAMESPACE QT_END_HEADER +#endif // QT_NO_CLIPBOARD #endif //QPLATFORMCLIPBOARD_QPA_H diff --git a/src/gui/kernel/qplatformintegration_qpa.cpp b/src/gui/kernel/qplatformintegration_qpa.cpp index 7fb7fbd..c45a953 100644 --- a/src/gui/kernel/qplatformintegration_qpa.cpp +++ b/src/gui/kernel/qplatformintegration_qpa.cpp @@ -102,6 +102,9 @@ QPlatformFontDatabase *QPlatformIntegration::fontDatabase() const \sa QPlatformClipboard */ + +#ifndef QT_NO_CLIPBOARD + QPlatformClipboard *QPlatformIntegration::clipboard() const { static QPlatformClipboard *clipboard = 0; @@ -111,6 +114,13 @@ QPlatformClipboard *QPlatformIntegration::clipboard() const return clipboard; } +#endif + +QPlatformNativeInterface * QPlatformIntegration::nativeInterface() const +{ + return 0; +} + /*! \class QPlatformIntegration \since 4.8 @@ -211,4 +221,14 @@ QPlatformClipboard *QPlatformIntegration::clipboard() const QRect(x,y,width,height). */ + +bool QPlatformIntegration::hasCapability(Capability cap) const +{ + return false; +} + + + + + QT_END_NAMESPACE diff --git a/src/gui/kernel/qplatformintegration_qpa.h b/src/gui/kernel/qplatformintegration_qpa.h index e40cb48..0aacefa 100644 --- a/src/gui/kernel/qplatformintegration_qpa.h +++ b/src/gui/kernel/qplatformintegration_qpa.h @@ -60,12 +60,19 @@ class QWidget; class QPlatformEventLoopIntegration; class QPlatformFontDatabase; class QPlatformClipboard; +class QPlatformNativeInterface; class Q_GUI_EXPORT QPlatformIntegration { public: + enum Capability { + ThreadedPixmaps = 1, + }; + virtual ~QPlatformIntegration() { } + virtual bool hasCapability(Capability cap) const; + // GraphicsSystem functions virtual QPixmapData *createPixmapData(QPixmapData::PixelType type) const = 0; virtual QPlatformWindow *createPlatformWindow(QWidget *widget, WId winId = 0) const = 0; @@ -79,7 +86,9 @@ public: //Deeper window system integrations virtual QPlatformFontDatabase *fontDatabase() const; +#ifndef QT_NO_CLIPBOARD virtual QPlatformClipboard *clipboard() const; +#endif // Experimental in mainthread eventloop integration // This should only be used if it is only possible to do window system event processing in @@ -89,7 +98,8 @@ public: //jl:XXX should it be hasGLContext and do we need it at all? virtual bool hasOpenGL() const; - +// Access native handles. The window handle is already available from Wid; + virtual QPlatformNativeInterface *nativeInterface() const; }; QT_END_NAMESPACE diff --git a/src/gui/kernel/qplatformnativeinterface_qpa.cpp b/src/gui/kernel/qplatformnativeinterface_qpa.cpp new file mode 100644 index 0000000..ace4a7b --- /dev/null +++ b/src/gui/kernel/qplatformnativeinterface_qpa.cpp @@ -0,0 +1,53 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qplatformnativeinterface_qpa.h" + +QT_BEGIN_NAMESPACE + +void *QPlatformNativeInterface::nativeResourceForWidget(const QByteArray &resource, QWidget *widget) +{ + Q_UNUSED(resource); + Q_UNUSED(widget); + return 0; +} + +QT_END_NAMESPACE diff --git a/src/gui/kernel/qplatformnativeinterface_qpa.h b/src/gui/kernel/qplatformnativeinterface_qpa.h new file mode 100644 index 0000000..5ea2c13 --- /dev/null +++ b/src/gui/kernel/qplatformnativeinterface_qpa.h @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QPLATFORMNATIVEINTERFACE_QPA_H +#define QPLATFORMNATIVEINTERFACE_QPA_H + +#include <QtGui/qwindowdefs.h> + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Gui) + +class QWidget; + +class Q_GUI_EXPORT QPlatformNativeInterface +{ +public: + virtual void *nativeResourceForWidget(const QByteArray &resource, QWidget *widget); +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QPLATFORMNATIVEINTERFACE_QPA_H diff --git a/src/gui/kernel/qsoftkeymanager.cpp b/src/gui/kernel/qsoftkeymanager.cpp index 1b26933..204efe9 100644 --- a/src/gui/kernel/qsoftkeymanager.cpp +++ b/src/gui/kernel/qsoftkeymanager.cpp @@ -50,6 +50,10 @@ #include "private/qsoftkeymanager_s60_p.h" #endif +#ifdef SYMBIAN_VERSION_SYMBIAN3 +#include "private/qt_s60_p.h" +#endif + #ifndef QT_NO_SOFTKEYMANAGER QT_BEGIN_NAMESPACE @@ -101,6 +105,30 @@ QSoftKeyManager::QSoftKeyManager() : QAction *QSoftKeyManager::createAction(StandardSoftKey standardKey, QWidget *actionWidget) { QAction *action = new QAction(standardSoftKeyText(standardKey), actionWidget); +#ifdef SYMBIAN_VERSION_SYMBIAN3 + int key = 0; + switch (standardKey) { + case OkSoftKey: + key = EAknSoftkeyOk; + break; + case SelectSoftKey: + key = EAknSoftkeySelect; + break; + case DoneSoftKey: + key = EAknSoftkeyDone; + break; + case MenuSoftKey: + key = EAknSoftkeyOptions; + break; + case CancelSoftKey: + key = EAknSoftkeyCancel; + break; + default: + break; + }; + if (key != 0) + QSoftKeyManager::instance()->d_func()->softKeyCommandActions.insert(action, key); +#endif QAction::SoftKeyRole softKeyRole = QAction::NoSoftKey; switch (standardKey) { case MenuSoftKey: // FALL-THROUGH @@ -143,6 +171,9 @@ void QSoftKeyManager::cleanupHash(QObject *obj) Q_D(QSoftKeyManager); QAction *action = qobject_cast<QAction*>(obj); d->keyedActions.remove(action); +#ifdef SYMBIAN_VERSION_SYMBIAN3 + d->softKeyCommandActions.remove(action); +#endif } void QSoftKeyManager::sendKeyEvent() diff --git a/src/gui/kernel/qsoftkeymanager_common_p.h b/src/gui/kernel/qsoftkeymanager_common_p.h index 27d8ee9..02ae697 100644 --- a/src/gui/kernel/qsoftkeymanager_common_p.h +++ b/src/gui/kernel/qsoftkeymanager_common_p.h @@ -72,6 +72,9 @@ protected: QMultiHash<int, QAction*> requestedSoftKeyActions; QWidget *initialSoftKeySource; bool pendingUpdate; +#ifdef SYMBIAN_VERSION_SYMBIAN3 + QHash<QAction*, int> softKeyCommandActions; +#endif }; QT_END_NAMESPACE diff --git a/src/gui/kernel/qsoftkeymanager_s60.cpp b/src/gui/kernel/qsoftkeymanager_s60.cpp index 3496297..79ed91a 100644 --- a/src/gui/kernel/qsoftkeymanager_s60.cpp +++ b/src/gui/kernel/qsoftkeymanager_s60.cpp @@ -113,12 +113,20 @@ void QSoftKeyManagerPrivateS60::ensureCbaVisibilityAndResponsiviness(CEikButtonG void QSoftKeyManagerPrivateS60::clearSoftkeys(CEikButtonGroupContainer &cba) { +#ifdef SYMBIAN_VERSION_SYMBIAN3 + QT_TRAP_THROWING( + //EAknSoftkeyEmpty is used, because using -1 adds softkeys without actions on Symbian3 + cba.SetCommandL(0, EAknSoftkeyEmpty, KNullDesC); + cba.SetCommandL(2, EAknSoftkeyEmpty, KNullDesC); + ); +#else QT_TRAP_THROWING( //Using -1 instead of EAknSoftkeyEmpty to avoid flickering. cba.SetCommandL(0, -1, KNullDesC); // TODO: Should we clear also middle SK? cba.SetCommandL(2, -1, KNullDesC); ); +#endif realSoftKeyActions.clear(); } @@ -290,6 +298,10 @@ bool QSoftKeyManagerPrivateS60::setSoftkey(CEikButtonGroupContainer &cba, QString text = softkeyText(*action); TPtrC nativeText = qt_QString2TPtrC(text); int command = S60_COMMAND_START + position; +#ifdef SYMBIAN_VERSION_SYMBIAN3 + if (softKeyCommandActions.contains(action)) + command = softKeyCommandActions.value(action); +#endif setNativeSoftkey(cba, position, command, nativeText); const bool dimmed = !action->isEnabled() && !QSoftKeyManager::isForceEnabledInSofkeys(action); cba.DimCommand(command, dimmed); diff --git a/src/gui/kernel/qt_cocoa_helpers_mac.mm b/src/gui/kernel/qt_cocoa_helpers_mac.mm index f4a1ea5..32123ee 100644 --- a/src/gui/kernel/qt_cocoa_helpers_mac.mm +++ b/src/gui/kernel/qt_cocoa_helpers_mac.mm @@ -1794,7 +1794,29 @@ void qt_mac_display(QWidget *widget) { NSView *theNSView = qt_mac_nativeview_for(widget); [theNSView display]; - return; +} + +void qt_mac_setNeedsDisplay(QWidget *widget) +{ + NSView *theNSView = qt_mac_nativeview_for(widget); + [theNSView setNeedsDisplay:YES]; +} + +void qt_mac_setNeedsDisplayInRect(QWidget *widget, QRegion region) +{ + NSView *theNSView = qt_mac_nativeview_for(widget); + if (region.isEmpty()) { + [theNSView setNeedsDisplay:YES]; + return; + } + + QVector<QRect> rects = region.rects(); + for (int i = 0; i < rects.count(); ++i) { + const QRect &rect = rects.at(i); + NSRect nsrect = NSMakeRect(rect.x(), rect.y(), rect.width(), rect.height()); + [theNSView setNeedsDisplayInRect:nsrect]; + } + } #endif // QT_MAC_USE_COCOA diff --git a/src/gui/kernel/qt_cocoa_helpers_mac_p.h b/src/gui/kernel/qt_cocoa_helpers_mac_p.h index 334d9e8..a49753a 100644 --- a/src/gui/kernel/qt_cocoa_helpers_mac_p.h +++ b/src/gui/kernel/qt_cocoa_helpers_mac_p.h @@ -301,7 +301,39 @@ public: void qt_mac_post_retranslateAppMenu(); +#ifdef QT_MAC_USE_COCOA void qt_mac_display(QWidget *widget); +void qt_mac_setNeedsDisplay(QWidget *widget); +void qt_mac_setNeedsDisplayInRect(QWidget *widget, QRegion region); +#endif // QT_MAC_USE_COCOA + + +// Utility functions to ease the use of Core Graphics contexts. + +inline void qt_mac_retain_graphics_context(CGContextRef context) +{ + CGContextRetain(context); + CGContextSaveGState(context); +} + +inline void qt_mac_release_graphics_context(CGContextRef context) +{ + CGContextRestoreGState(context); + CGContextRelease(context); +} + +inline void qt_mac_draw_image(CGContextRef context, CGContextRef imageContext, CGRect area, CGRect drawingArea) +{ + CGImageRef image = CGBitmapContextCreateImage(imageContext); + CGImageRef subImage = CGImageCreateWithImageInRect(image, area); + + CGContextTranslateCTM (context, 0, drawingArea.origin.y + CGRectGetMaxY(drawingArea)); + CGContextScaleCTM(context, 1, -1); + CGContextDrawImage(context, drawingArea, subImage); + + CGImageRelease(subImage); + CGImageRelease(image); +} QT_END_NAMESPACE diff --git a/src/gui/kernel/qt_s60_p.h b/src/gui/kernel/qt_s60_p.h index 3bb27c3..102c0ca 100644 --- a/src/gui/kernel/qt_s60_p.h +++ b/src/gui/kernel/qt_s60_p.h @@ -189,6 +189,8 @@ public: int screenHeightInPixelsForScreen[qt_symbian_max_screens]; int screenWidthInTwipsForScreen[qt_symbian_max_screens]; int screenHeightInTwipsForScreen[qt_symbian_max_screens]; + + bool nativeOrientationIsPortrait; }; Q_AUTOTEST_EXPORT QS60Data* qGlobalS60Data(); @@ -233,6 +235,8 @@ public: bool isControlActive(); + void ensureFixNativeOrientation(); + #ifdef Q_WS_S60 void FadeBehindPopup(bool fade){ popupFader.FadeBehindPopup( this, this, fade); } void HandleStatusPaneSizeChange(); @@ -327,9 +331,11 @@ inline QS60Data::QS60Data() inline void QS60Data::updateScreenSize() { + CWsScreenDevice *dev = S60->screenDevice(); + int screenModeCount = dev->NumScreenModes(); + int mode = dev->CurrentScreenMode(); TPixelsTwipsAndRotation params; - int mode = S60->screenDevice()->CurrentScreenMode(); - S60->screenDevice()->GetScreenModeSizeAndRotation(mode, params); + dev->GetScreenModeSizeAndRotation(mode, params); S60->screenWidthInPixels = params.iPixelSize.iWidth; S60->screenHeightInPixels = params.iPixelSize.iHeight; S60->screenWidthInTwips = params.iTwipsSize.iWidth; @@ -352,6 +358,21 @@ inline void QS60Data::updateScreenSize() S60->screenWidthInTwipsForScreen[i] = params.iTwipsSize.iWidth; S60->screenHeightInTwipsForScreen[i] = params.iTwipsSize.iHeight; } + + // Look for a screen mode with rotation 0 + // in order to decide what the native orientation is. + int nativeScreenWidthInPixels = 0; + int nativeScreenHeightInPixels = 0; + for (mode = 0; mode < screenModeCount; ++mode) { + TPixelsAndRotation sizeAndRotation; + dev->GetScreenModeSizeAndRotation(mode, sizeAndRotation); + if (sizeAndRotation.iRotation == CFbsBitGc::EGraphicsOrientationNormal) { + nativeScreenWidthInPixels = sizeAndRotation.iPixelSize.iWidth; + nativeScreenHeightInPixels = sizeAndRotation.iPixelSize.iHeight; + break; + } + } + S60->nativeOrientationIsPortrait = nativeScreenWidthInPixels <= nativeScreenHeightInPixels; } inline RWsSession& QS60Data::wsSession() diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index adb5fe1..3cc3e65 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -312,6 +312,7 @@ QWidgetPrivate::QWidgetPrivate(int version) , qd_hd(0) #elif defined(Q_OS_SYMBIAN) , symbianScreenNumber(0) + , fixNativeOrientationCalled(false) #endif { if (!qApp) { @@ -328,9 +329,10 @@ QWidgetPrivate::QWidgetPrivate(int version) drawRectOriginalAdded = false; originalDrawMethod = true; changeMethods = false; - hasOwnContext = false; isInUnifiedToolbar = false; unifiedSurface = 0; + toolbar_ancestor = 0; + flushRequested = false; touchEventsEnabled = false; #endif // QT_MAC_USE_COCOA #ifdef QWIDGET_EXTRA_DEBUG @@ -366,9 +368,12 @@ QWindowSurface *QWidgetPrivate::createDefaultWindowSurface() Q_Q(QWidget); QWindowSurface *surface; +#ifndef QT_NO_PROPERTIES if (q->property("_q_DummyWindowSurface").toBool()) { surface = new QDummyWindowSurface(q); - } else { + } else +#endif + { if (QApplicationPrivate::graphicsSystem()) surface = QApplicationPrivate::graphicsSystem()->createWindowSurface(q); else @@ -1385,6 +1390,16 @@ void QWidgetPrivate::init(QWidget *parentWidget, Qt::WindowFlags f) QApplication::postEvent(q, new QEvent(QEvent::PolishRequest)); extraPaintEngine = 0; + +#ifdef QT_MAC_USE_COCOA + // If we add a child to the unified toolbar, we have to redirect the painting. + if (parentWidget && parentWidget->d_func() && parentWidget->d_func()->isInUnifiedToolbar) { + if (parentWidget->d_func()->unifiedSurface) { + QWidget *toolbar = parentWidget->d_func()->toolbar_ancestor; + parentWidget->d_func()->unifiedSurface->recursiveRedirect(toolbar, toolbar, toolbar->d_func()->toolbar_offset); + } + } +#endif // QT_MAC_USE_COCOA } @@ -2099,6 +2114,11 @@ void QWidgetPrivate::subtractOpaqueSiblings(QRegion &sourceRegion, bool *hasDirt if (disableSubtractOpaqueSiblings || q->isWindow()) return; +#ifdef QT_MAC_USE_COCOA + if (q->d_func()->isInUnifiedToolbar) + return; +#endif // QT_MAC_USE_COCOA + QRect clipBoundingRect; bool dirtyClipBoundingRect = true; @@ -10391,6 +10411,12 @@ void QWidget::repaint(const QRect &rect) return; if (hasBackingStoreSupport()) { +#ifdef QT_MAC_USE_COCOA + if (qt_widget_private(this)->isInUnifiedToolbar) { + qt_widget_private(this)->unifiedSurface->renderToolbar(this, true); + return; + } +#endif // QT_MAC_USE_COCOA QTLWExtra *tlwExtra = window()->d_func()->maybeTopData(); if (tlwExtra && !tlwExtra->inTopLevelResize && tlwExtra->backingStore) { tlwExtra->inRepaint = true; @@ -10420,6 +10446,12 @@ void QWidget::repaint(const QRegion &rgn) return; if (hasBackingStoreSupport()) { +#ifdef QT_MAC_USE_COCOA + if (qt_widget_private(this)->isInUnifiedToolbar) { + qt_widget_private(this)->unifiedSurface->renderToolbar(this, true); + return; + } +#endif // QT_MAC_USE_COCOA QTLWExtra *tlwExtra = window()->d_func()->maybeTopData(); if (tlwExtra && !tlwExtra->inTopLevelResize && tlwExtra->backingStore) { tlwExtra->inRepaint = true; @@ -10477,6 +10509,12 @@ void QWidget::update(const QRect &rect) } if (hasBackingStoreSupport()) { +#ifdef QT_MAC_USE_COCOA + if (qt_widget_private(this)->isInUnifiedToolbar) { + qt_widget_private(this)->unifiedSurface->renderToolbar(this, true); + return; + } +#endif // QT_MAC_USE_COCOA QTLWExtra *tlwExtra = window()->d_func()->maybeTopData(); if (tlwExtra && !tlwExtra->inTopLevelResize && tlwExtra->backingStore) tlwExtra->backingStore->markDirty(rect, this); @@ -10501,6 +10539,12 @@ void QWidget::update(const QRegion &rgn) } if (hasBackingStoreSupport()) { +#ifdef QT_MAC_USE_COCOA + if (qt_widget_private(this)->isInUnifiedToolbar) { + qt_widget_private(this)->unifiedSurface->renderToolbar(this, true); + return; + } +#endif // QT_MAC_USE_COCOA QTLWExtra *tlwExtra = window()->d_func()->maybeTopData(); if (tlwExtra && !tlwExtra->inTopLevelResize && tlwExtra->backingStore) tlwExtra->backingStore->markDirty(rgn, this); @@ -10927,6 +10971,9 @@ void QWidget::setAttribute(Qt::WidgetAttribute attribute, bool on) } QT_TRAP_THROWING(appUi->SetOrientationL(s60orientation)); S60->orientationSet = true; + QSymbianControl *window = static_cast<QSymbianControl *>(internalWinId()); + if (window) + window->ensureFixNativeOrientation(); #endif break; } diff --git a/src/gui/kernel/qwidget_mac.mm b/src/gui/kernel/qwidget_mac.mm index 14a90ef..34918e4 100644 --- a/src/gui/kernel/qwidget_mac.mm +++ b/src/gui/kernel/qwidget_mac.mm @@ -2476,6 +2476,8 @@ void QWidgetPrivate::createWindow_sys() void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyOldWindow) { Q_Q(QWidget); + QMacCocoaAutoReleasePool pool; + OSViewRef destroyid = 0; #ifndef QT_MAC_USE_COCOA window_event = 0; @@ -4423,6 +4425,8 @@ void QWidgetPrivate::adjustWithinMaxAndMinSize(int &w, int &h) void QWidgetPrivate::applyMaxAndMinSizeOnWindow() { Q_Q(QWidget); + QMacCocoaAutoReleasePool pool; + const float max_f(20000); #ifndef QT_MAC_USE_COCOA #define SF(x) ((x > max_f) ? max_f : x) diff --git a/src/gui/kernel/qwidget_p.h b/src/gui/kernel/qwidget_p.h index dd9bb49..919f8bc 100644 --- a/src/gui/kernel/qwidget_p.h +++ b/src/gui/kernel/qwidget_p.h @@ -113,6 +113,8 @@ class QWidgetItemV2; class QStyle; +class QUnifiedToolbarSurface; + class Q_AUTOTEST_EXPORT QWidgetBackingStoreTracker { @@ -322,6 +324,11 @@ struct QWExtra { */ ZeroFill, + /** + * Blit backing store, propagating alpha channel into the framebuffer. + */ + BlitWriteAlpha, + Default = Blit }; @@ -856,15 +863,15 @@ public: bool originalDrawMethod; // Do we need to change the methods? bool changeMethods; - bool hasOwnContext; - CGContextRef cgContext; - QRegion ut_rg; - QPoint ut_pt; + + // Unified toolbar variables bool isInUnifiedToolbar; - QWindowSurface *unifiedSurface; + QUnifiedToolbarSurface *unifiedSurface; QPoint toolbar_offset; + QWidget *toolbar_ancestor; + bool flushRequested; bool touchEventsEnabled; -#endif +#endif // QT_MAC_USE_COCOA void determineWindowClass(); void transferChildren(); bool qt_mac_dnd_event(uint, DragRef); @@ -901,6 +908,7 @@ public: static QWidget *mouseGrabber; static QWidget *keyboardGrabber; int symbianScreenNumber; // only valid for desktop widget and top-levels + bool fixNativeOrientationCalled; void s60UpdateIsOpaque(); void reparentChildren(); void registerTouchWindow(); diff --git a/src/gui/kernel/qwidget_s60.cpp b/src/gui/kernel/qwidget_s60.cpp index 16f28c7..c74c7eb 100644 --- a/src/gui/kernel/qwidget_s60.cpp +++ b/src/gui/kernel/qwidget_s60.cpp @@ -278,6 +278,8 @@ void QWidgetPrivate::setGeometry_sys(int x, int y, int w, int h, bool isMove) q->internalWinId()->SetRect(TRect(TPoint(x, y), TSize(w, h))); topData()->normalGeometry = data.crect; } + QSymbianControl *window = static_cast<QSymbianControl *>(q->internalWinId()); + window->ensureFixNativeOrientation(); } else { data.crect.setRect(x, y, w, h); @@ -809,9 +811,14 @@ void QWidgetPrivate::s60UpdateIsOpaque() { Q_Q(QWidget); - if (!q->testAttribute(Qt::WA_WState_Created) || !q->testAttribute(Qt::WA_TranslucentBackground)) + if (!q->testAttribute(Qt::WA_WState_Created)) return; + const bool writeAlpha = extraData()->nativePaintMode == QWExtra::BlitWriteAlpha; + if (!q->testAttribute(Qt::WA_TranslucentBackground) && !writeAlpha) + return; + const bool requireAlphaChannel = !isOpaque || writeAlpha; + createTLExtra(); RWindow *const window = static_cast<RWindow *>(q->effectiveWinId()->DrawableWindow()); @@ -823,12 +830,11 @@ void QWidgetPrivate::s60UpdateIsOpaque() return; } #endif - if (!isOpaque) { + if (requireAlphaChannel) { const TDisplayMode displayMode = static_cast<TDisplayMode>(window->SetRequiredDisplayMode(EColor16MA)); if (window->SetTransparencyAlphaChannel() == KErrNone) { window->SetBackgroundColor(TRgb(255, 255, 255, 0)); extra->topextra->nativeWindowTransparencyEnabled = 1; - if (extra->topextra->backingStore.data() && ( QApplicationPrivate::graphics_system_name == QLatin1String("openvg") || QApplicationPrivate::graphics_system_name == QLatin1String("opengl"))) { @@ -1204,17 +1210,41 @@ void QWidget::setWindowState(Qt::WindowStates newstate) } #ifdef Q_WS_S60 - bool decorationsVisible(false); - if (!parentWidget()) { // Only top level native windows have control over cba/status pane - // Hide window decoration when switching to fullscreen / minimized otherwise show decoration. - // The window decoration visibility has to be changed before doing actual window state - // change since in that order the availableGeometry will return directly the right size and - // we will avoid unnecessary redraws - decorationsVisible = !(newstate & (Qt::WindowFullScreen | Qt::WindowMinimized)); - const bool statusPaneVisibility = decorationsVisible; - const bool buttonGroupVisibility = (decorationsVisible || (isFullscreen && cbaRequested)); - S60->setStatusPaneAndButtonGroupVisibility(statusPaneVisibility, buttonGroupVisibility); + // Hide window decoration when switching to fullscreen / minimized otherwise show decoration. + // The window decoration visibility has to be changed before doing actual window state + // change since in that order the availableGeometry will return directly the right size and + // we will avoid unnecessary redraws + Qt::WindowStates comparisonState = newstate; + QWidget *parentWindow = parentWidget(); + if (parentWindow) { + while (parentWindow->parentWidget()) + parentWindow = parentWindow->parentWidget(); + comparisonState = parentWindow->windowState(); + } else { + parentWindow = this; + } + + const bool decorationsVisible = !(comparisonState & (Qt::WindowFullScreen | Qt::WindowMinimized)); + const bool parentIsFullscreen = comparisonState & Qt::WindowFullScreen; + const bool parentCbaVisibilityHint = parentWindow->windowFlags() & Qt::WindowSoftkeysVisibleHint; + bool buttonGroupVisibility = (decorationsVisible || (parentIsFullscreen && parentCbaVisibilityHint)); + + // For non-toplevel normal and maximized windows, show cba if window has softkey + // actions even if topmost parent is not showing cba. Do the same for fullscreen + // windows that request it. + if (!buttonGroupVisibility + && parentWidget() + && !(newstate & Qt::WindowMinimized) + && ((windowFlags() & Qt::WindowSoftkeysVisibleHint) || !(newstate & Qt::WindowFullScreen))) { + for (int i = 0; i < actions().size(); ++i) { + if (actions().at(i)->softKeyRole() != QAction::NoSoftKey) { + buttonGroupVisibility = true; + break; + } + } } + S60->setStatusPaneAndButtonGroupVisibility(decorationsVisible, buttonGroupVisibility); + #endif // Q_WS_S60 // Ensure the initial size is valid, since we store it as normalGeometry below. @@ -1273,6 +1303,12 @@ void QWidget::setWindowState(Qt::WindowStates newstate) if (newstate & Qt::WindowActive) activateWindow(); + if (isWindow()) { + // Now that the new state is set, fix the display memory layout, if needed. + QSymbianControl *window = static_cast<QSymbianControl *>(effectiveWinId()); + window->ensureFixNativeOrientation(); + } + QWindowStateChangeEvent e(oldstate); QApplication::sendEvent(this, &e); } @@ -1419,7 +1455,8 @@ void QWidget::activateWindow() if (tlw->isVisible()) { window()->createWinId(); QSymbianControl *id = static_cast<QSymbianControl *>(tlw->internalWinId()); - id->setFocusSafely(true); + if (!id->IsFocused()) + id->setFocusSafely(true); } } diff --git a/src/gui/kernel/qwindowsysteminterface_qpa.cpp b/src/gui/kernel/qwindowsysteminterface_qpa.cpp index c53eedb..740bb82 100644 --- a/src/gui/kernel/qwindowsysteminterface_qpa.cpp +++ b/src/gui/kernel/qwindowsysteminterface_qpa.cpp @@ -150,6 +150,36 @@ void QWindowSystemInterface::handleKeyEvent(QWidget *tlw, ulong timestamp, QEven QWindowSystemInterfacePrivate::queueWindowSystemEvent(e); } +void QWindowSystemInterface::handleExtendedKeyEvent(QWidget *w, QEvent::Type type, int key, Qt::KeyboardModifiers modifiers, + quint32 nativeScanCode, quint32 nativeVirtualKey, + quint32 nativeModifiers, + const QString& text, bool autorep, + ushort count) +{ + unsigned long time = QWindowSystemInterfacePrivate::eventTime.elapsed(); + handleExtendedKeyEvent(w, time, type, key, modifiers, nativeScanCode, nativeVirtualKey, nativeModifiers, + text, autorep, count); +} + +void QWindowSystemInterface::handleExtendedKeyEvent(QWidget *tlw, ulong timestamp, QEvent::Type type, int key, + Qt::KeyboardModifiers modifiers, + quint32 nativeScanCode, quint32 nativeVirtualKey, + quint32 nativeModifiers, + const QString& text, bool autorep, + ushort count) +{ + if (tlw) { + QWidgetData *data = qt_qwidget_data(tlw); + if (data->in_destructor) + tlw = 0; + } + + QWindowSystemInterfacePrivate::KeyEvent * e = + new QWindowSystemInterfacePrivate::KeyEvent(tlw, timestamp, type, key, modifiers, + nativeScanCode, nativeVirtualKey, nativeModifiers, text, autorep, count); + QWindowSystemInterfacePrivate::queueWindowSystemEvent(e); +} + void QWindowSystemInterface::handleWheelEvent(QWidget *w, const QPoint & local, const QPoint & global, int d, Qt::Orientation o) { unsigned long time = QWindowSystemInterfacePrivate::eventTime.elapsed(); handleWheelEvent(w, time, local, global, d, o); diff --git a/src/gui/kernel/qwindowsysteminterface_qpa.h b/src/gui/kernel/qwindowsysteminterface_qpa.h index 9dce7ea..a882fc1 100644 --- a/src/gui/kernel/qwindowsysteminterface_qpa.h +++ b/src/gui/kernel/qwindowsysteminterface_qpa.h @@ -64,6 +64,17 @@ public: static void handleKeyEvent(QWidget *w, QEvent::Type t, int k, Qt::KeyboardModifiers mods, const QString & text = QString(), bool autorep = false, ushort count = 1); static void handleKeyEvent(QWidget *w, ulong timestamp, QEvent::Type t, int k, Qt::KeyboardModifiers mods, const QString & text = QString(), bool autorep = false, ushort count = 1); + static void handleExtendedKeyEvent(QWidget *w, QEvent::Type type, int key, Qt::KeyboardModifiers modifiers, + quint32 nativeScanCode, quint32 nativeVirtualKey, + quint32 nativeModifiers, + const QString& text = QString(), bool autorep = false, + ushort count = 1); + static void handleExtendedKeyEvent(QWidget *w, ulong timestamp, QEvent::Type type, int key, Qt::KeyboardModifiers modifiers, + quint32 nativeScanCode, quint32 nativeVirtualKey, + quint32 nativeModifiers, + const QString& text = QString(), bool autorep = false, + ushort count = 1); + static void handleWheelEvent(QWidget *w, const QPoint & local, const QPoint & global, int d, Qt::Orientation o); static void handleWheelEvent(QWidget *w, ulong timestamp, const QPoint & local, const QPoint & global, int d, Qt::Orientation o); diff --git a/src/gui/kernel/qwindowsysteminterface_qpa_p.h b/src/gui/kernel/qwindowsysteminterface_qpa_p.h index 3491a1a..6be86ad 100644 --- a/src/gui/kernel/qwindowsysteminterface_qpa_p.h +++ b/src/gui/kernel/qwindowsysteminterface_qpa_p.h @@ -142,13 +142,23 @@ public: public: KeyEvent(QWidget *w, ulong time, QEvent::Type t, int k, Qt::KeyboardModifiers mods, const QString & text = QString(), bool autorep = false, ushort count = 1) :UserEvent(w, time, Key), key(k), unicode(text), repeat(autorep), - repeatCount(count), modifiers(mods), keyType(t) { } + repeatCount(count), modifiers(mods), keyType(t), + nativeScanCode(0), nativeVirtualKey(0), nativeModifiers(0) { } + KeyEvent(QWidget *w, ulong time, QEvent::Type t, int k, Qt::KeyboardModifiers mods, + quint32 nativeSC, quint32 nativeVK, quint32 nativeMods, + const QString & text = QString(), bool autorep = false, ushort count = 1) + :UserEvent(w, time, Key), key(k), unicode(text), repeat(autorep), + repeatCount(count), modifiers(mods), keyType(t), + nativeScanCode(nativeSC), nativeVirtualKey(nativeVK), nativeModifiers(nativeMods) { } int key; QString unicode; bool repeat; ushort repeatCount; Qt::KeyboardModifiers modifiers; QEvent::Type keyType; + quint32 nativeScanCode; + quint32 nativeVirtualKey; + quint32 nativeModifiers; }; class TouchEvent : public UserEvent { |