Made tst_QWidget::updateWhileMinimized() pass.

This requires adding a couple of window system interface events, namely
Map, Unmap, and Expose. When a widget is minimized on X11 it is
unmapped, and thus update requests should not be delivered. Instead the
event will delivered when the widget is mapped, which causes an Expose
event to be sent. The Unmap and Expose event thus need to be handled in
QWidgetWindow, and Map is also added for the purpose of API symmetry
(and for future needs).
bb10
Samuel Rødal 2011-06-06 15:54:11 +02:00
parent 481067453f
commit 078e4ef6c7
13 changed files with 154 additions and 3 deletions

View File

@ -291,6 +291,11 @@ public:
ScrollPrepare = 204,
Scroll = 205,
Map = 206,
Unmap = 207,
Expose = 208,
// 512 reserved for Qt Jambi's MetaCall event
// 513 reserved for Qt Jambi's DeleteOnMainThread event

View File

@ -167,6 +167,18 @@ public:
QScrollEvent::ScrollState state;
};
class QExposeEvent : public QEvent
{
public:
inline QExposeEvent(const QRegion &rgn)
: QEvent(Expose)
, region(rgn)
{
}
QRegion region;
};
QT_END_NAMESPACE
#endif // QEVENT_P_H

View File

@ -455,6 +455,15 @@ void QGuiApplicationPrivate::processWindowSystemEvent(QWindowSystemInterfacePriv
QGuiApplicationPrivate::reportAvailableGeometryChange(
static_cast<QWindowSystemInterfacePrivate::ScreenAvailableGeometryEvent *>(e));
break;
case QWindowSystemInterfacePrivate::Map:
QGuiApplicationPrivate::processMapEvent(static_cast<QWindowSystemInterfacePrivate::MapEvent *>(e));
break;
case QWindowSystemInterfacePrivate::Unmap:
QGuiApplicationPrivate::processUnmapEvent(static_cast<QWindowSystemInterfacePrivate::UnmapEvent *>(e));
break;
case QWindowSystemInterfacePrivate::Expose:
QGuiApplicationPrivate::processExposeEvent(static_cast<QWindowSystemInterfacePrivate::ExposeEvent *>(e));
break;
default:
qWarning() << "Unknown user input event type:" << e->type;
break;
@ -659,6 +668,24 @@ void QGuiApplicationPrivate::reportAvailableGeometryChange(
return;
}
void QGuiApplicationPrivate::processMapEvent(QWindowSystemInterfacePrivate::MapEvent *e)
{
QEvent event(QEvent::Map);
QCoreApplication::sendSpontaneousEvent(e->mapped.data(), &event);
}
void QGuiApplicationPrivate::processUnmapEvent(QWindowSystemInterfacePrivate::UnmapEvent *e)
{
QEvent event(QEvent::Unmap);
QCoreApplication::sendSpontaneousEvent(e->unmapped.data(), &event);
}
void QGuiApplicationPrivate::processExposeEvent(QWindowSystemInterfacePrivate::ExposeEvent *e)
{
QExposeEvent event(e->region);
QCoreApplication::sendSpontaneousEvent(e->exposed.data(), &event);
}
#ifndef QT_NO_CLIPBOARD
QClipboard * QGuiApplication::clipboard()
{

View File

@ -119,6 +119,11 @@ public:
static void reportGeometryChange(QWindowSystemInterfacePrivate::ScreenGeometryEvent *e);
static void reportAvailableGeometryChange(QWindowSystemInterfacePrivate::ScreenAvailableGeometryEvent *e);
static void processMapEvent(QWindowSystemInterfacePrivate::MapEvent *e);
static void processUnmapEvent(QWindowSystemInterfacePrivate::UnmapEvent *e);
static void processExposeEvent(QWindowSystemInterfacePrivate::ExposeEvent *e);
static inline Qt::Alignment visualAlignment(Qt::LayoutDirection direction, Qt::Alignment alignment)
{
if (!(alignment & Qt::AlignHorizontal_Mask))

View File

@ -49,6 +49,8 @@
#include "qwindow_p.h"
#include "qguiapplication_p.h"
#include <private/qevent_p.h>
#include <QtCore/QDebug>
QT_BEGIN_NAMESPACE
@ -486,6 +488,7 @@ void QWindow::hideEvent(QHideEvent *)
bool QWindow::event(QEvent *event)
{
Q_D(QWindow);
switch (event->type()) {
case QEvent::MouseMove:
mouseMoveEvent(static_cast<QMouseEvent*>(event));
@ -525,6 +528,11 @@ bool QWindow::event(QEvent *event)
destroy();
break;
case QEvent::Expose:
if (d->surface)
d->surface->flush(this, static_cast<QExposeEvent *>(event)->region, QPoint());
break;
default:
return QObject::event(event);
}

View File

@ -252,4 +252,22 @@ void QWindowSystemInterface::handleScreenCountChange(int count)
QWindowSystemInterfacePrivate::queueWindowSystemEvent(e);
}
void QWindowSystemInterface::handleMapEvent(QWindow *tlw)
{
QWindowSystemInterfacePrivate::MapEvent *e = new QWindowSystemInterfacePrivate::MapEvent(tlw);
QWindowSystemInterfacePrivate::queueWindowSystemEvent(e);
}
void QWindowSystemInterface::handleUnmapEvent(QWindow *tlw)
{
QWindowSystemInterfacePrivate::UnmapEvent *e = new QWindowSystemInterfacePrivate::UnmapEvent(tlw);
QWindowSystemInterfacePrivate::queueWindowSystemEvent(e);
}
void QWindowSystemInterface::handleExposeEvent(QWindow *tlw, const QRegion &region)
{
QWindowSystemInterfacePrivate::ExposeEvent *e = new QWindowSystemInterfacePrivate::ExposeEvent(tlw, region);
QWindowSystemInterfacePrivate::queueWindowSystemEvent(e);
}
QT_END_NAMESPACE

View File

@ -96,6 +96,11 @@ public:
static void handleLeaveEvent(QWindow *w);
static void handleWindowActivated(QWindow *w);
static void handleMapEvent(QWindow *w);
static void handleUnmapEvent(QWindow *w);
static void handleExposeEvent(QWindow *w, const QRegion &region);
// Changes to the screen
static void handleScreenGeometryChange(int screenIndex);
static void handleScreenAvailableGeometryChange(int screenIndex);

View File

@ -61,7 +61,10 @@ public:
Touch,
ScreenGeometry,
ScreenAvailableGeometry,
ScreenCountChange
ScreenCountChange,
Map,
Unmap,
Expose
};
class WindowSystemEvent {
@ -192,6 +195,31 @@ public:
int index;
};
class MapEvent : public WindowSystemEvent {
public:
MapEvent(QWindow *mapped)
: WindowSystemEvent(Map), mapped(mapped)
{ }
QWeakPointer<QWindow> mapped;
};
class UnmapEvent : public WindowSystemEvent {
public:
UnmapEvent(QWindow *unmapped)
: WindowSystemEvent(Unmap), unmapped(unmapped)
{ }
QWeakPointer<QWindow> unmapped;
};
class ExposeEvent : public WindowSystemEvent {
public:
ExposeEvent(QWindow *exposed, const QRegion &region)
: WindowSystemEvent(Expose), exposed(exposed), region(region)
{ }
QWeakPointer<QWindow> exposed;
QRegion region;
};
static QList<WindowSystemEvent *> windowSystemEventQueue;
static QMutex queueMutex;

View File

@ -445,6 +445,8 @@ void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event)
HANDLE_PLATFORM_WINDOW_EVENT(xcb_configure_notify_event_t, event, handleConfigureNotifyEvent);
case XCB_MAP_NOTIFY:
HANDLE_PLATFORM_WINDOW_EVENT(xcb_map_notify_event_t, event, handleMapNotifyEvent);
case XCB_UNMAP_NOTIFY:
HANDLE_PLATFORM_WINDOW_EVENT(xcb_unmap_notify_event_t, event, handleUnmapNotifyEvent);
case XCB_CLIENT_MESSAGE:
HANDLE_PLATFORM_WINDOW_EVENT(xcb_client_message_event_t, window, handleClientMessageEvent);
case XCB_ENTER_NOTIFY:

View File

@ -927,7 +927,7 @@ void QXcbWindow::handleExposeEvent(const xcb_expose_event_t *event)
if (surface) {
QRect rect(event->x, event->y, event->width, event->height);
surface->flush(window(), rect, QPoint());
QWindowSystemInterface::handleExposeEvent(window(), rect);
}
}
@ -981,8 +981,18 @@ void QXcbWindow::handleConfigureNotifyEvent(const xcb_configure_notify_event_t *
void QXcbWindow::handleMapNotifyEvent(const xcb_map_notify_event_t *event)
{
if (event->window == m_window)
if (event->window == m_window) {
m_mapped = true;
QWindowSystemInterface::handleMapEvent(window());
}
}
void QXcbWindow::handleUnmapNotifyEvent(const xcb_unmap_notify_event_t *event)
{
if (event->window == m_window) {
m_mapped = false;
QWindowSystemInterface::handleUnmapEvent(window());
}
}
static Qt::MouseButtons translateMouseButtons(int s)

View File

@ -87,6 +87,7 @@ public:
void handleClientMessageEvent(const xcb_client_message_event_t *event);
void handleConfigureNotifyEvent(const xcb_configure_notify_event_t *event);
void handleMapNotifyEvent(const xcb_map_notify_event_t *event);
void handleUnmapNotifyEvent(const xcb_unmap_notify_event_t *event);
void handleButtonPressEvent(const xcb_button_press_event_t *event);
void handleButtonReleaseEvent(const xcb_button_release_event_t *event);
void handleMotionNotifyEvent(const xcb_motion_notify_event_t *event);

View File

@ -100,6 +100,19 @@ bool QWidgetWindow::event(QEvent *event)
case QEvent::DragMove:
case QEvent::Drop:
handleDragEvent(event);
break;
case QEvent::Map:
m_widget->setAttribute(Qt::WA_Mapped);
return true;
case QEvent::Unmap:
m_widget->setAttribute(Qt::WA_Mapped, false);
return true;
case QEvent::Expose:
handleExposeEvent(static_cast<QExposeEvent *>(event));
return true;
default:
break;
@ -261,8 +274,19 @@ void QWidgetWindow::handleMoveEvent(QMoveEvent *event)
void QWidgetWindow::handleResizeEvent(QResizeEvent *event)
{
QSize oldSize = m_widget->data->crect.size();
m_widget->data->crect = geometry();
QGuiApplication::sendSpontaneousEvent(m_widget, event);
if (m_widget->d_func()->paintOnScreen()) {
QRegion updateRegion(geometry());
if (m_widget->testAttribute(Qt::WA_StaticContents))
updateRegion -= QRect(0, 0, oldSize.width(), oldSize.height());
m_widget->d_func()->syncBackingStore(updateRegion);
} else {
m_widget->d_func()->syncBackingStore();
}
}
void QWidgetWindow::handleCloseEvent(QCloseEvent *)
@ -345,5 +369,9 @@ void QWidgetWindow::handleDragEvent(QEvent *event)
}
}
void QWidgetWindow::handleExposeEvent(QExposeEvent *event)
{
m_widget->d_func()->syncBackingStore(event->region);
}
QT_END_NAMESPACE

View File

@ -45,6 +45,7 @@
#include <QtGui/qwindow.h>
#include <QtCore/private/qobject_p.h>
#include <QtGui/private/qevent_p.h>
QT_BEGIN_HEADER
@ -74,6 +75,7 @@ protected:
void handleResizeEvent(QResizeEvent *);
void handleWheelEvent(QWheelEvent *);
void handleDragEvent(QEvent *);
void handleExposeEvent(QExposeEvent *);
private:
QWidget *m_widget;