summaryrefslogtreecommitdiffstats
path: root/src/gui/kernel
diff options
context:
space:
mode:
authorQt Continuous Integration System <qt-info@nokia.com>2010-02-10 03:06:47 (GMT)
committerQt Continuous Integration System <qt-info@nokia.com>2010-02-10 03:06:47 (GMT)
commitf74029e286e97067ac39086955481bf979af69dc (patch)
treeba6b9706b47624cb4dcd51a3fb4236ce4dddd5b3 /src/gui/kernel
parent4a5e8e026bed24d451e2d36f490f42a17ed74b47 (diff)
parentec0f388dfb14712a144d534296b33df7e6a2df7f (diff)
downloadQt-f74029e286e97067ac39086955481bf979af69dc.zip
Qt-f74029e286e97067ac39086955481bf979af69dc.tar.gz
Qt-f74029e286e97067ac39086955481bf979af69dc.tar.bz2
Merge branch 'qt-master-from-4.6' of scm.dev.nokia.troll.no:qt/qt-integration into master-integration
* 'qt-master-from-4.6' of scm.dev.nokia.troll.no:qt/qt-integration: (104 commits) Documentation: clarified RVCT support for Symbian Update Symbian OS def files for 4.6.2 Remove the installer from the Qt sources. Don't remove all dependencies when patching the pkg. Fixes qabstractslider autotest Workaround for abld toolchain issue with s60main Add a recursive rule for running the auto-tests. Do not run the tests automatically during install. Enabling runfast mode when vfpv2 used. Fixing a test case to be runnable on Symbian device. [CRASH] audioinput and audiooutput examples crash when no devices are Fixed casual crash in initializeDb (Symbian) Fixes scrolling horizontally with a mouse wheel over sliders. don't use QKeySequence::mnemonic() after all Fixed qt_x11_wait_for_window_manager Revert change 34f1758 on non-Synbian platforms Fixed QGifHandler::loopCount(). Doc: Clarified ownership of custom buttons added to a QDialogButtonBox. Updated WebKit from /home/shausman/src/webkit/trunk to qtwebkit/qtwebkit-4.6 ( da5d96a26e80162027bc95ce7e5725fe4b277ff7 ) don't use stylesheet for just making labels bold ...
Diffstat (limited to 'src/gui/kernel')
-rw-r--r--src/gui/kernel/qaction.cpp4
-rw-r--r--src/gui/kernel/qapplication_s60.cpp20
-rw-r--r--src/gui/kernel/qcocoapanel_mac.mm3
-rw-r--r--src/gui/kernel/qcocoasharedwindowmethods_mac_p.h24
-rw-r--r--src/gui/kernel/qcocoaview_mac.mm9
-rw-r--r--src/gui/kernel/qcocoawindow_mac_p.h3
-rw-r--r--src/gui/kernel/qdesktopwidget_s60.cpp18
-rw-r--r--src/gui/kernel/qsoftkeymanager_s60.cpp86
-rw-r--r--src/gui/kernel/qsoftkeymanager_s60_p.h4
-rw-r--r--src/gui/kernel/qt_cocoa_helpers_mac.mm2
-rw-r--r--src/gui/kernel/qwidget.cpp29
-rw-r--r--src/gui/kernel/qwidget_mac.mm19
-rw-r--r--src/gui/kernel/qwidget_s60.cpp112
-rw-r--r--src/gui/kernel/qwidget_x11.cpp77
14 files changed, 248 insertions, 162 deletions
diff --git a/src/gui/kernel/qaction.cpp b/src/gui/kernel/qaction.cpp
index 4b7d949..8ddd051 100644
--- a/src/gui/kernel/qaction.cpp
+++ b/src/gui/kernel/qaction.cpp
@@ -715,6 +715,10 @@ QActionGroup *QAction::actionGroup() const
it is displayed to the left of the menu text. There is no default
icon.
+ On Symbian the icons which are passed to softkeys, i.e. to actions with
+ softkey role, need to have pixmap alpha channel correctly set otherwise
+ drawing artifacts will appear when softkey is pressed down.
+
If a null icon (QIcon::isNull() is passed into this function,
the icon of the action is cleared.
*/
diff --git a/src/gui/kernel/qapplication_s60.cpp b/src/gui/kernel/qapplication_s60.cpp
index 20b8030..87de602 100644
--- a/src/gui/kernel/qapplication_s60.cpp
+++ b/src/gui/kernel/qapplication_s60.cpp
@@ -924,8 +924,8 @@ void QSymbianControl::PositionChanged()
cr.moveTopLeft(newPos);
qwidget->data->crect = cr;
QTLWExtra *top = qwidget->d_func()->maybeTopData();
- if (top)
- top->normalGeometry = cr;
+ if (top && (qwidget->windowState() & (~Qt::WindowActive)) == Qt::WindowNoState)
+ top->normalGeometry.moveTopLeft(newPos);
if (qwidget->isVisible()) {
QMoveEvent e(newPos, oldPos);
qt_sendSpontaneousEvent(qwidget, &e);
@@ -960,15 +960,14 @@ 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, hide status pane and button container
- // otherwise show them.
+ // If widget is fullscreen/minimized, hide status pane and button container otherwise show them.
CEikStatusPane* statusPane = S60->statusPane();
CEikButtonGroupContainer* buttonGroup = S60->buttonGroupContainer();
- bool isFullscreen = qwidget->windowState() & Qt::WindowFullScreen;
- if (statusPane && (bool)statusPane->IsVisible() == isFullscreen)
- statusPane->MakeVisible(!isFullscreen);
- if (buttonGroup && (bool)buttonGroup->IsVisible() == isFullscreen)
- buttonGroup->MakeVisible(!isFullscreen);
+ TBool visible = !(qwidget->windowState() & (Qt::WindowFullScreen | Qt::WindowMinimized));
+ if (statusPane)
+ statusPane->MakeVisible(visible);
+ if (buttonGroup)
+ buttonGroup->MakeVisible(visible);
#endif
} else if (QApplication::activeWindow() == qwidget->window()) {
if (CCoeEnv::Static()->AppUi()->IsDisplayingMenuOrDialog()) {
@@ -1647,6 +1646,9 @@ int QApplicationPrivate::symbianProcessWsEvent(const QSymbianEvent *symbianEvent
if (visChangedEvent->iFlags & TWsVisibilityChangedEvent::ENotVisible) {
delete w->d_func()->topData()->backingStore;
w->d_func()->topData()->backingStore = 0;
+ // In order to ensure that any resources used by the window surface
+ // are immediately freed, we flush the WSERV command buffer.
+ S60->wsSession().Flush();
} else if ((visChangedEvent->iFlags & TWsVisibilityChangedEvent::EPartiallyVisible)
&& !w->d_func()->maybeBackingStore()) {
w->d_func()->topData()->backingStore = new QWidgetBackingStore(w);
diff --git a/src/gui/kernel/qcocoapanel_mac.mm b/src/gui/kernel/qcocoapanel_mac.mm
index 3012093..0b48efd 100644
--- a/src/gui/kernel/qcocoapanel_mac.mm
+++ b/src/gui/kernel/qcocoapanel_mac.mm
@@ -47,6 +47,9 @@
#import <private/qcocoaview_mac_p.h>
#import <private/qcocoawindowcustomthemeframe_mac_p.h>
#import <private/qcocoaapplication_mac_p.h>
+#include <private/qapplication_p.h>
+#include <private/qbackingstore_p.h>
+
#include <QtGui/QWidget>
diff --git a/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h b/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h
index d8bbcd4..a1d2c61 100644
--- a/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h
+++ b/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h
@@ -51,6 +51,9 @@
NSPanel, while QCocoaWindow needs to inherit NSWindow rather than NSPanel).
****************************************************************************/
+// WARNING: Don't include any header files from within this file. Put them
+// directly into qcocoawindow_mac_p.h and qcocoapanel_mac_p.h
+
QT_BEGIN_NAMESPACE
extern Qt::MouseButton cocoaButton2QtButton(NSInteger buttonNum); // qcocoaview.mm
extern QPointer<QWidget> qt_button_down; //qapplication_mac.cpp
@@ -205,7 +208,7 @@ QT_END_NAMESPACE
qt_button_down = widget;
handled = qt_mac_handleMouseEvent(view, event, QEvent::MouseButtonPress, mouseButton);
// Don't call super here. This prevents us from getting the mouseUp event,
- // which we need to send even if the mouseDown event was not accepted.
+ // which we need to send even if the mouseDown event was not accepted.
// (this is standard Qt behavior.)
break;
case NSRightMouseDown:
@@ -303,9 +306,9 @@ QT_END_NAMESPACE
{
// The user dragged something into the window. Send a draggingEntered message
// to the QWidget under the mouse. As the drag moves over the window, and over
- // different widgets, we will handle enter and leave events from within
+ // different widgets, we will handle enter and leave events from within
// draggingUpdated below. The reason why we handle this ourselves rather than
- // subscribing for drag events directly in QCocoaView is that calling
+ // subscribing for drag events directly in QCocoaView is that calling
// registerForDraggedTypes on the views will severly degrade initialization time
// for an application that uses a lot of drag subscribing widgets.
@@ -369,3 +372,18 @@ QT_END_NAMESPACE
return dropResult;
}
+- (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];
+}
diff --git a/src/gui/kernel/qcocoaview_mac.mm b/src/gui/kernel/qcocoaview_mac.mm
index 8c5d166..70c78c8 100644
--- a/src/gui/kernel/qcocoaview_mac.mm
+++ b/src/gui/kernel/qcocoaview_mac.mm
@@ -474,10 +474,11 @@ extern "C" {
- (void)drawRect:(NSRect)aRect
{
if (QApplicationPrivate::graphicsSystem() != 0) {
- if (QWidgetBackingStore *bs = qwidgetprivate->maybeBackingStore())
- bs->markDirty(qwidget->rect(), qwidget);
- qwidgetprivate->syncBackingStore(qwidget->rect());
- return;
+ if (QWidgetBackingStore *bs = qwidgetprivate->maybeBackingStore()) {
+ // Drawing is handled on the window level
+ // See qcocoasharedwindowmethods_mac_p.
+ return;
+ }
}
CGContextRef cg = (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort];
qwidgetprivate->hd = cg;
diff --git a/src/gui/kernel/qcocoawindow_mac_p.h b/src/gui/kernel/qcocoawindow_mac_p.h
index 403a1a5..21f82df 100644
--- a/src/gui/kernel/qcocoawindow_mac_p.h
+++ b/src/gui/kernel/qcocoawindow_mac_p.h
@@ -53,6 +53,9 @@
#ifdef QT_MAC_USE_COCOA
#include "qmacdefines_mac.h"
#import <Cocoa/Cocoa.h>
+#include <private/qapplication_p.h>
+#include <private/qbackingstore_p.h>
+
enum { QtMacCustomizeWindow = 1 << 21 }; // This will one day be run over by
diff --git a/src/gui/kernel/qdesktopwidget_s60.cpp b/src/gui/kernel/qdesktopwidget_s60.cpp
index 77745ea..84e3c5d 100644
--- a/src/gui/kernel/qdesktopwidget_s60.cpp
+++ b/src/gui/kernel/qdesktopwidget_s60.cpp
@@ -88,24 +88,20 @@ QDesktopWidgetPrivate::~QDesktopWidgetPrivate()
void QDesktopWidgetPrivate::init(QDesktopWidget *that)
{
- int screenCount=0;
+// int screenCount=0;
- if (HAL::Get(0, HALData::EDisplayNumberOfScreens, screenCount) == KErrNone)
- QDesktopWidgetPrivate::screenCount = screenCount;
- else
- QDesktopWidgetPrivate::screenCount = 0;
+ // ### TODO: Implement proper multi-display support
+ QDesktopWidgetPrivate::screenCount = 1;
+// if (HAL::Get(0, HALData::EDisplayNumberOfScreens, screenCount) == KErrNone)
+// QDesktopWidgetPrivate::screenCount = screenCount;
+// else
+// QDesktopWidgetPrivate::screenCount = 0;
rects = new QVector<QRect>();
workrects = new QVector<QRect>();
rects->resize(QDesktopWidgetPrivate::screenCount);
workrects->resize(QDesktopWidgetPrivate::screenCount);
-
- // ### TODO: Implement proper multi-display support
- rects->resize(1);
- rects->replace(0, that->rect());
- workrects->resize(1);
- workrects->replace(0, that->rect());
}
void QDesktopWidgetPrivate::cleanup()
diff --git a/src/gui/kernel/qsoftkeymanager_s60.cpp b/src/gui/kernel/qsoftkeymanager_s60.cpp
index 67ed8b0..af84a8f 100644
--- a/src/gui/kernel/qsoftkeymanager_s60.cpp
+++ b/src/gui/kernel/qsoftkeymanager_s60.cpp
@@ -49,7 +49,7 @@
#include "private/qsoftkeymanager_p.h"
#include "private/qsoftkeymanager_s60_p.h"
#include "private/qobject_p.h"
-//#include <eiksoftkeyimage.h>
+#include <eiksoftkeyimage.h>
#include <eikcmbut.h>
#ifndef QT_NO_SOFTKEYMANAGER
@@ -64,6 +64,8 @@ QSoftKeyManagerPrivateS60::QSoftKeyManagerPrivateS60()
{
cachedCbaIconSize[0] = QSize(0,0);
cachedCbaIconSize[1] = QSize(0,0);
+ cachedCbaIconSize[2] = QSize(0,0);
+ cachedCbaIconSize[3] = QSize(0,0);
skipNextUpdate = false;
}
@@ -149,6 +151,39 @@ void QSoftKeyManagerPrivateS60::setNativeSoftkey(CEikButtonGroupContainer &cba,
QT_TRAP_THROWING(cba.SetCommandL(position, command, text));
}
+QPoint QSoftKeyManagerPrivateS60::softkeyIconPosition(int position, QSize sourceSize, QSize targetSize)
+{
+ QPoint iconPosition(0,0);
+ switch( AknLayoutUtils::CbaLocation() )
+ {
+ case AknLayoutUtils::EAknCbaLocationBottom:
+ // RSK must be moved to right, LSK in on correct position by default
+ if (position == RSK_POSITION)
+ iconPosition.setX(targetSize.width() - sourceSize.width());
+ break;
+ case AknLayoutUtils::EAknCbaLocationRight:
+ case AknLayoutUtils::EAknCbaLocationLeft:
+ // Already in correct position
+ default:
+ break;
+ }
+
+ // Align horizontally to center
+ iconPosition.setY((targetSize.height() - sourceSize.height()) >> 1);
+ return iconPosition;
+}
+
+QPixmap QSoftKeyManagerPrivateS60::prepareSoftkeyPixmap(QPixmap src, int position, QSize targetSize)
+{
+ QPixmap target(targetSize);
+ target.fill(Qt::transparent);
+ QPainter p;
+ p.begin(&target);
+ p.drawPixmap(softkeyIconPosition(position, src.size(), targetSize), src);
+ p.end();
+ return target;
+}
+
bool QSoftKeyManagerPrivateS60::isOrientationLandscape()
{
// Hard to believe that there is no public API in S60 to
@@ -158,15 +193,11 @@ bool QSoftKeyManagerPrivateS60::isOrientationLandscape()
QSize QSoftKeyManagerPrivateS60::cbaIconSize(CEikButtonGroupContainer *cba, int position)
{
- Q_UNUSED(cba);
- Q_UNUSED(position);
- // Will be implemented when EikSoftkeyImage usage license wise is OK
-/*
- const int index = isOrientationLandscape() ? 0 : 1;
+ int index = position;
+ index += isOrientationLandscape() ? 0 : 1;
if(cachedCbaIconSize[index].isNull()) {
// Only way I figured out to get CBA icon size without RnD SDK, was
- // Only way I figured out to get CBA icon size without RnD SDK, was
// to set some dummy icon to CBA first and then ask CBA button CCoeControl::Size()
// The returned value is cached to avoid unnecessary icon setting every time.
const bool left = (position == LSK_POSITION);
@@ -178,38 +209,46 @@ QSize QSoftKeyManagerPrivateS60::cbaIconSize(CEikButtonGroupContainer *cba, int
setNativeSoftkey(*cba, position, command, KNullDesC());
cachedCbaIconSize[index] = qt_TSize2QSize(cba->ControlOrNull(command)->Size());
EikSoftkeyImage::SetLabel(cba, left);
+
+ if(cachedCbaIconSize[index] == QSize(138,72)) {
+ // Hack for S60 5.0 (5800) landscape orientation, which return wrong icon size
+ cachedCbaIconSize[index] = QSize(60,60);
+ }
}
}
return cachedCbaIconSize[index];
-*/
- return QSize();
}
bool QSoftKeyManagerPrivateS60::setSoftkeyImage(CEikButtonGroupContainer *cba,
QAction &action, int position)
{
bool ret = false;
- Q_UNUSED(cba);
- Q_UNUSED(action);
- Q_UNUSED(position);
- // Will be implemented when EikSoftkeyImage usage license wise is OK
- /*
const bool left = (position == LSK_POSITION);
if(position == LSK_POSITION || position == RSK_POSITION) {
QIcon icon = action.icon();
if (!icon.isNull()) {
- QPixmap pm = icon.pixmap(cbaIconSize(cba, position));
- pm = pm.scaled(cbaIconSize(cba, position));
- QBitmap mask = pm.mask();
- if (mask.isNull()) {
- mask = QBitmap(pm.size());
- mask.fill(Qt::color1);
+ // Get size of CBA icon area based on button position and orientation
+ QSize requiredIconSize = cbaIconSize(cba, position);
+ // Get pixmap out of icon based on preferred size, the aspect ratio is kept
+ QPixmap pmWihtAspectRatio = icon.pixmap(requiredIconSize);
+ // Native softkeys require that pixmap size is exactly the same as requiredIconSize
+ // prepareSoftkeyPixmap creates a new pixmap with requiredIconSize and blits the 'pmWihtAspectRatio'
+ // to correct location of it
+ QPixmap softkeyPixmap = prepareSoftkeyPixmap(pmWihtAspectRatio, position, requiredIconSize);
+
+ QPixmap softkeyAlpha = softkeyPixmap.alphaChannel();
+ // Alpha channel in 5.1 and older devices need to be inverted
+ // TODO: Switch to use toSymbianCFbsBitmap with invert when available
+ if(QSysInfo::s60Version() <= QSysInfo::SV_S60_5_1) {
+ QImage alphaImage = softkeyAlpha.toImage();
+ alphaImage.invertPixels();
+ softkeyAlpha = QPixmap::fromImage(alphaImage);
}
- CFbsBitmap* nBitmap = pm.toSymbianCFbsBitmap();
- CFbsBitmap* nMask = mask.toSymbianCFbsBitmap();
+ CFbsBitmap* nBitmap = softkeyPixmap.toSymbianCFbsBitmap();
+ CFbsBitmap* nMask = softkeyAlpha.toSymbianCFbsBitmap();
CEikImage* myimage = new (ELeave) CEikImage;
myimage->SetPicture( nBitmap, nMask ); // nBitmap and nMask ownership transfered
@@ -221,7 +260,6 @@ bool QSoftKeyManagerPrivateS60::setSoftkeyImage(CEikButtonGroupContainer *cba,
EikSoftkeyImage::SetLabel(cba, left);
}
}
- */
return ret;
}
@@ -272,6 +310,7 @@ bool QSoftKeyManagerPrivateS60::setRightSoftkey(CEikButtonGroupContainer &cba)
if (windowType != Qt::Dialog && windowType != Qt::Popup) {
QString text(QSoftKeyManager::tr("Exit"));
TPtrC nativeText = qt_QString2TPtrC(text);
+ EikSoftkeyImage::SetLabel(&cba, false);
setNativeSoftkey(cba, RSK_POSITION, EAknSoftkeyExit, nativeText);
return true;
}
@@ -303,7 +342,6 @@ void QSoftKeyManagerPrivateS60::setSoftkeys(CEikButtonGroupContainer &cba)
void QSoftKeyManagerPrivateS60::updateSoftKeys_sys()
{
- //bool status = CCoeEnv::Static()->AppUi()->IsDisplayingMenuOrDialog();
if (skipCbaUpdate())
return;
diff --git a/src/gui/kernel/qsoftkeymanager_s60_p.h b/src/gui/kernel/qsoftkeymanager_s60_p.h
index 46e3596..f8bd6d9 100644
--- a/src/gui/kernel/qsoftkeymanager_s60_p.h
+++ b/src/gui/kernel/qsoftkeymanager_s60_p.h
@@ -84,6 +84,8 @@ private:
QAction *highestPrioritySoftkey(QAction::SoftKeyRole role);
static bool actionPriorityMoreThan(const QAction* item1, const QAction* item2);
void setNativeSoftkey(CEikButtonGroupContainer &cba, TInt position, TInt command, const TDesC& text);
+ QPoint softkeyIconPosition(int position, QSize sourceSize, QSize targetSize);
+ QPixmap prepareSoftkeyPixmap(QPixmap src, int position, QSize targetSize);
bool isOrientationLandscape();
QSize cbaIconSize(CEikButtonGroupContainer *cba, int position);
bool setSoftkeyImage(CEikButtonGroupContainer *cba, QAction &action, int position);
@@ -95,7 +97,7 @@ private:
private:
QHash<int, QAction*> realSoftKeyActions;
- QSize cachedCbaIconSize[2];
+ QSize cachedCbaIconSize[4];
bool skipNextUpdate;
};
diff --git a/src/gui/kernel/qt_cocoa_helpers_mac.mm b/src/gui/kernel/qt_cocoa_helpers_mac.mm
index 377e5a0..4e51cf4 100644
--- a/src/gui/kernel/qt_cocoa_helpers_mac.mm
+++ b/src/gui/kernel/qt_cocoa_helpers_mac.mm
@@ -1162,7 +1162,7 @@ CGContextRef qt_mac_graphicsContextFor(QWidget *widget)
CGrafPtr port = GetWindowPort(qt_mac_window_for(widget));
QDBeginCGContext(port, &context);
#else
- CGContextRef context = (CGContextRef)[[NSGraphicsContext graphicsContextWithWindow:qt_mac_window_for(widget)] graphicsPort];
+ CGContextRef context = reinterpret_cast<CGContextRef>([[qt_mac_window_for(widget) graphicsContext] graphicsPort]);
#endif
return context;
}
diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp
index 884447d..2e951b6 100644
--- a/src/gui/kernel/qwidget.cpp
+++ b/src/gui/kernel/qwidget.cpp
@@ -1439,6 +1439,18 @@ QWidget::~QWidget()
}
#endif
+#ifdef Q_OS_SYMBIAN
+ if (d->extra && d->extra->topextra && d->extra->topextra->backingStore) {
+ // Okay, we are about to destroy the top-level window that owns
+ // the backing store. Make sure we delete the backing store right away
+ // before the window handle is invalid. This is important because
+ // the backing store will delete its window surface, which may or may
+ // not have a reference to this widget that will be used later to
+ // notify the window it no longer has a surface.
+ delete d->extra->topextra->backingStore;
+ d->extra->topextra->backingStore = 0;
+ }
+#endif
if (QWidgetBackingStore *bs = d->maybeBackingStore()) {
bs->removeDirtyWidget(this);
if (testAttribute(Qt::WA_StaticContents))
@@ -1660,7 +1672,13 @@ void QWidgetPrivate::syncBackingStore()
repaint_sys(dirty);
dirty = QRegion();
} else if (QWidgetBackingStore *bs = maybeBackingStore()) {
+#ifdef QT_MAC_USE_COCOA
+ Q_UNUSED(bs);
+ void qt_mac_set_needs_display(QWidget *, QRegion);
+ qt_mac_set_needs_display(q_func(), QRegion());
+#else
bs->sync();
+#endif
}
}
@@ -1668,8 +1686,15 @@ void QWidgetPrivate::syncBackingStore(const QRegion &region)
{
if (paintOnScreen())
repaint_sys(region);
- else if (QWidgetBackingStore *bs = maybeBackingStore())
+ else if (QWidgetBackingStore *bs = maybeBackingStore()) {
+#ifdef QT_MAC_USE_COCOA
+ Q_UNUSED(bs);
+ void qt_mac_set_needs_display(QWidget *, QRegion);
+ qt_mac_set_needs_display(q_func(), region);
+#else
bs->sync(q_func(), region);
+#endif
+ }
}
void QWidgetPrivate::setUpdatesEnabled_helper(bool enable)
@@ -6422,6 +6447,8 @@ void QWidget::setTabOrder(QWidget* first, QWidget *second)
first = fp;
}
+ if (fp == second)
+ return;
if (QWidget *sp = second->focusProxy())
second = sp;
diff --git a/src/gui/kernel/qwidget_mac.mm b/src/gui/kernel/qwidget_mac.mm
index 878b776..a5633d3 100644
--- a/src/gui/kernel/qwidget_mac.mm
+++ b/src/gui/kernel/qwidget_mac.mm
@@ -565,6 +565,25 @@ inline static void qt_mac_set_window_group_to_popup(OSWindowRef window)
}
#endif
+#ifdef QT_MAC_USE_COCOA
+void qt_mac_set_needs_display(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
+
inline static bool updateRedirectedToGraphicsProxyWidget(QWidget *widget, const QRect &rect)
{
if (!widget)
diff --git a/src/gui/kernel/qwidget_s60.cpp b/src/gui/kernel/qwidget_s60.cpp
index 00f2213..a844430 100644
--- a/src/gui/kernel/qwidget_s60.cpp
+++ b/src/gui/kernel/qwidget_s60.cpp
@@ -1046,96 +1046,48 @@ void QWidget::setWindowState(Qt::WindowStates newstate)
return;
if (isWindow()) {
-#ifdef Q_WS_S60
- // Change window decoration visibility if switching to or from fullsccreen
- // In addition decoration visibility is changed when the initial has been
- // WindowNoState.
- // 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 unnecessarty redraws
- if ((oldstate & Qt::WindowFullScreen) != (newstate & Qt::WindowFullScreen) ||
- oldstate == Qt::WindowNoState) {
- CEikStatusPane* statusPane = S60->statusPane();
- CEikButtonGroupContainer* buttonGroup = S60->buttonGroupContainer();
- if (newstate & Qt::WindowFullScreen) {
- if (statusPane)
- statusPane->MakeVisible(false);
- if (buttonGroup)
- buttonGroup->MakeVisible(false);
- } else {
- if (statusPane)
- statusPane->MakeVisible(true);
- if (buttonGroup)
- buttonGroup->MakeVisible(true);
- }
+ QSymbianControl *window = static_cast<QSymbianControl *>(effectiveWinId());
+ if (window && newstate & Qt::WindowMinimized) {
+ window->setFocusSafely(false);
+ window->MakeVisible(false);
+ } else if (window && oldstate & Qt::WindowMinimized) {
+ window->setFocusSafely(true);
+ window->MakeVisible(true);
}
+
+#ifdef Q_WS_S60
+ // Hide window decoration when switching to fullsccreen / 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 unnecessarty redraws
+ CEikStatusPane* statusPane = S60->statusPane();
+ CEikButtonGroupContainer* buttonGroup = S60->buttonGroupContainer();
+ TBool visible = !(newstate & (Qt::WindowFullScreen | Qt::WindowMinimized));
+ if (statusPane)
+ statusPane->MakeVisible(visible);
+ if (buttonGroup)
+ buttonGroup->MakeVisible(visible);
#endif // Q_WS_S60
createWinId();
Q_ASSERT(testAttribute(Qt::WA_WState_Created));
- QTLWExtra *top = d->topData();
-
// Ensure the initial size is valid, since we store it as normalGeometry below.
if (!testAttribute(Qt::WA_Resized) && !isVisible())
adjustSize();
- if ((oldstate & Qt::WindowMaximized) != (newstate & Qt::WindowMaximized)) {
- if ((newstate & Qt::WindowMaximized)) {
- const QRect normalGeometry = geometry();
+ QTLWExtra *top = d->topData();
+ const QRect normalGeometry = (top->normalGeometry.width() < 0) ? geometry() : top->normalGeometry;
- const QRect r = top->normalGeometry;
- setGeometry(qApp->desktop()->availableGeometry(this));
- top->normalGeometry = r;
+ if (newstate & Qt::WindowFullScreen)
+ setGeometry(qApp->desktop()->screenGeometry(this));
+ else if (newstate & Qt::WindowMaximized)
+ setGeometry(qApp->desktop()->availableGeometry(this));
+ else
+ setGeometry(normalGeometry);
- if (top->normalGeometry.width() < 0)
- top->normalGeometry = normalGeometry;
- } else {
- // restore original geometry
- setGeometry(top->normalGeometry);
- }
- }
- if ((oldstate & Qt::WindowFullScreen) != (newstate & Qt::WindowFullScreen)) {
- if (newstate & Qt::WindowFullScreen) {
- const QRect normalGeometry = geometry();
- const QRect r = top->normalGeometry;
- setGeometry(qApp->desktop()->screenGeometry(this));
-
- top->normalGeometry = r;
- if (top->normalGeometry.width() < 0)
- top->normalGeometry = normalGeometry;
- } else {
- if (newstate & Qt::WindowMaximized) {
- const QRect r = top->normalGeometry;
- setGeometry(qApp->desktop()->availableGeometry(this));
- top->normalGeometry = r;
- } else {
- setGeometry(top->normalGeometry);
- }
- }
- }
- if ((oldstate & Qt::WindowMinimized) != (newstate & Qt::WindowMinimized)) {
- if (newstate & Qt::WindowMinimized) {
- if (isVisible()) {
- QSymbianControl *id = static_cast<QSymbianControl *>(effectiveWinId());
- if (id->IsFocused()) // Avoid unnecessary calls to FocusChanged()
- id->setFocusSafely(false);
- id->MakeVisible(false);
- }
- } else {
- if (isVisible()) {
- QSymbianControl *id = static_cast<QSymbianControl *>(effectiveWinId());
- id->MakeVisible(true);
- if (!id->IsFocused()) // Avoid unnecessary calls to FocusChanged()
- id->setFocusSafely(true);
- }
- const QRect normalGeometry = geometry();
- const QRect r = top->normalGeometry;
- top->normalGeometry = r;
- if (top->normalGeometry.width() < 0)
- top->normalGeometry = normalGeometry;
- }
- }
+ //restore normal geometry
+ top->normalGeometry = normalGeometry;
}
data->window_state = newstate;
@@ -1195,6 +1147,10 @@ void QWidget::destroy(bool destroyWindow, bool destroySubWindows)
if (destroyWindow) {
delete id;
+ // At this point the backing store should already be destroyed
+ // so we flush the command buffer to ensure that the freeing of
+ // those resources and deleting the window can happen "atomically"
+ S60->wsSession().Flush();
}
}
diff --git a/src/gui/kernel/qwidget_x11.cpp b/src/gui/kernel/qwidget_x11.cpp
index 4684bc1..10fb009 100644
--- a/src/gui/kernel/qwidget_x11.cpp
+++ b/src/gui/kernel/qwidget_x11.cpp
@@ -346,11 +346,6 @@ Q_GUI_EXPORT void qt_x11_enforce_cursor(QWidget * w)
qt_x11_enforce_cursor(w, false);
}
-static Bool checkForConfigureAndExpose(Display *, XEvent *e, XPointer)
-{
- return e->type == ConfigureNotify || e->type == Expose;
-}
-
Q_GUI_EXPORT void qt_x11_wait_for_window_manager(QWidget* w)
{
if (!w || (!w->isWindow() && !w->internalWinId()))
@@ -363,38 +358,60 @@ Q_GUI_EXPORT void qt_x11_wait_for_window_manager(QWidget* w)
if (!w->testAttribute(Qt::WA_WState_Created))
return;
- if (!(w->windowFlags() & Qt::X11BypassWindowManagerHint)) {
- // if the window is not override-redirect, then the window manager
- // will reparent us to the frame decoration window.
- while (!XCheckTypedWindowEvent(X11->display, w->effectiveWinId(), ReparentNotify, &ev)) {
- if (t.elapsed() > maximumWaitTime)
- return;
- qApp->syncX(); // non-busy wait
- }
- }
+ WId winid = w->internalWinId();
- while (!XCheckTypedWindowEvent(X11->display, w->effectiveWinId(), MapNotify, &ev)) {
- if (t.elapsed() > maximumWaitTime)
- return;
- qApp->syncX(); // non-busy wait
- }
+ // first deliver events that are already in the local queue
+ QApplication::sendPostedEvents();
- qApp->x11ProcessEvent(&ev);
+ // the normal sequence is:
+ // ... ConfigureNotify ... ReparentNotify ... MapNotify ... Expose
+ // with X11BypassWindowManagerHint:
+ // ConfigureNotify ... MapNotify ... Expose
- // ok, seems like the window manager successfully reparented us, we'll wait
- // for the first paint event to arrive, while handling ConfigureNotify in
- // the arrival order
- while(1)
- {
- if (XCheckIfEvent(X11->display, &ev, checkForConfigureAndExpose, 0)) {
+ enum State {
+ Initial, Reparented, Mapped
+ } state = Initial;
+
+ do {
+ if (XEventsQueued(X11->display, QueuedAlready)) {
+ XNextEvent(X11->display, &ev);
qApp->x11ProcessEvent(&ev);
- if (ev.type == Expose)
- return;
+
+ if (w->windowFlags() & Qt::X11BypassWindowManagerHint) {
+ switch (state) {
+ case Initial:
+ case Reparented:
+ if (ev.type == MapNotify && ev.xany.window == winid)
+ state = Mapped;
+ break;
+ case Mapped:
+ if (ev.type == Expose && ev.xany.window == winid)
+ return;
+ break;
+ }
+ } else {
+ switch (state) {
+ case Initial:
+ if (ev.type == ReparentNotify && ev.xany.window == winid)
+ state = Reparented;
+ break;
+ case Reparented:
+ if (ev.type == MapNotify && ev.xany.window == winid)
+ state = Mapped;
+ break;
+ case Mapped:
+ if (ev.type == Expose && ev.xany.window == winid)
+ return;
+ break;
+ }
+ }
+ } else {
+ if (!XEventsQueued(X11->display, QueuedAfterFlush))
+ qApp->syncX(); // non-busy wait
}
if (t.elapsed() > maximumWaitTime)
return;
- qApp->syncX(); // non-busy wait
- }
+ } while(1);
}
void qt_change_net_wm_state(const QWidget* w, bool set, Atom one, Atom two = 0)