summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeremy Katz <jeremy.katz@nokia.com>2010-06-15 11:09:50 (GMT)
committerJeremy Katz <jeremy.katz@nokia.com>2010-06-15 11:09:50 (GMT)
commit47b8d9d08386e841580ddc920681b07b338cbdb6 (patch)
treef036dffa4bbfc1ea02e44dc191ec9d7b39be7d8f
parente5d607b3635d53c84dbb782f534d8cac9096dd14 (diff)
downloadQt-47b8d9d08386e841580ddc920681b07b338cbdb6.zip
Qt-47b8d9d08386e841580ddc920681b07b338cbdb6.tar.gz
Qt-47b8d9d08386e841580ddc920681b07b338cbdb6.tar.bz2
virtual desktop multiscreen support - VNC plugin
-rw-r--r--src/gui/kernel/qapplication_lite.cpp6
-rw-r--r--src/gui/kernel/qdesktopwidget_lite.cpp14
-rw-r--r--src/gui/kernel/qdesktopwidget_lite_p.h3
-rw-r--r--src/plugins/platforms/fb_base/fb_base.cpp79
-rw-r--r--src/plugins/platforms/fb_base/fb_base.h7
-rw-r--r--src/plugins/platforms/vnc/qvncintegration.cpp22
-rw-r--r--src/plugins/platforms/vnc/qvncintegration.h2
7 files changed, 100 insertions, 33 deletions
diff --git a/src/gui/kernel/qapplication_lite.cpp b/src/gui/kernel/qapplication_lite.cpp
index dd25cd4..bd72663 100644
--- a/src/gui/kernel/qapplication_lite.cpp
+++ b/src/gui/kernel/qapplication_lite.cpp
@@ -400,6 +400,12 @@ QWidget *QApplication::topLevelAt(const QPoint &pos)
QList<QPlatformScreen *>::const_iterator screen = screens.constBegin();
QList<QPlatformScreen *>::const_iterator end = screens.constEnd();
+ // The first screen in a virtual environment should know about all top levels
+ if (pi->isVirtualDesktop()) {
+ QWidget *w = (*screen)->topLevelAt(pos);
+ return w;
+ }
+
while (screen != end) {
if ((*screen)->geometry().contains(pos))
return (*screen)->topLevelAt(pos);
diff --git a/src/gui/kernel/qdesktopwidget_lite.cpp b/src/gui/kernel/qdesktopwidget_lite.cpp
index 3e37faf..52c1b17 100644
--- a/src/gui/kernel/qdesktopwidget_lite.cpp
+++ b/src/gui/kernel/qdesktopwidget_lite.cpp
@@ -71,9 +71,19 @@ void QDesktopWidgetPrivate::updateScreenList()
}
}
+ QRegion virtualGeometry;
+ bool doVirtualGeometry = QApplicationPrivate::platformIntegration()->isVirtualDesktop();
+
// update the geometry of each screen widget
for (int i = 0; i < screens.length(); i++) {
- screens.at(i)->setGeometry(screenList.at(i)->geometry());
+ QRect screenGeometry = screenList.at(i)->geometry();
+ screens.at(i)->setGeometry(screenGeometry);
+ if (doVirtualGeometry)
+ virtualGeometry += screenGeometry;
+ }
+
+ if (doVirtualGeometry) {
+ virtualScreen.setGeometry(virtualGeometry.boundingRect());
}
}
@@ -106,6 +116,8 @@ int QDesktopWidget::numScreens() const
QWidget *QDesktopWidget::screen(int screen)
{
Q_D(QDesktopWidget);
+ if (QApplicationPrivate::platformIntegration()->isVirtualDesktop())
+ return &d->virtualScreen;
if (screen < 0 || screen >= d->screens.length())
return d->screens.at(0);
return d->screens.at(screen);
diff --git a/src/gui/kernel/qdesktopwidget_lite_p.h b/src/gui/kernel/qdesktopwidget_lite_p.h
index c04e172..2f7ad52 100644
--- a/src/gui/kernel/qdesktopwidget_lite_p.h
+++ b/src/gui/kernel/qdesktopwidget_lite_p.h
@@ -59,7 +59,7 @@
class QDesktopScreenWidget : public QWidget {
Q_OBJECT
public:
- QDesktopScreenWidget(int screenNumber) { setWindowFlags(Qt::Desktop); setVisible(false); d_func()->screenNumber = screenNumber; }
+ QDesktopScreenWidget(int screenNumber = -1) { setWindowFlags(Qt::Desktop); setVisible(false); d_func()->screenNumber = screenNumber; }
};
class QDesktopWidgetPrivate : public QWidgetPrivate {
@@ -69,6 +69,7 @@ public:
void updateScreenList();
QList<QDesktopScreenWidget *> screens;
+ QDesktopScreenWidget virtualScreen;
};
#endif // QDESKTOPWIDGET_LITE_P_H
diff --git a/src/plugins/platforms/fb_base/fb_base.cpp b/src/plugins/platforms/fb_base/fb_base.cpp
index 5004a5a..be4a530 100644
--- a/src/plugins/platforms/fb_base/fb_base.cpp
+++ b/src/plugins/platforms/fb_base/fb_base.cpp
@@ -162,8 +162,9 @@ void QFbScreen::generateRects()
continue;
if (!windowStack[i]->widget()->testAttribute(Qt::WA_TranslucentBackground)) {
- remainingScreen -= windowStack[i]->localGeometry();
- QRegion windowRegion(windowStack[i]->localGeometry());
+ QRect localGeometry = windowStack.at(i)->geometry().translated(-screenOffset); // global to local translation
+ remainingScreen -= localGeometry;
+ QRegion windowRegion(localGeometry);
windowRegion -= remainingScreen;
foreach(QRect rect, windowRegion.rects()) {
cachedRects += QPair<QRect, int>(rect, i);
@@ -180,7 +181,7 @@ void QFbScreen::generateRects()
QRegion QFbScreen::doRedraw()
{
- QPoint screenOffset = mGeometry.topLeft(); // optimize me!
+ QPoint screenOffset = mGeometry.topLeft();
QRegion touchedRegion;
if (cursor && cursor->isDirty() && cursor->isOnScreen()) {
@@ -257,9 +258,7 @@ QRegion QFbScreen::doRedraw()
void QFbScreen::addWindow(QFbWindow *surface)
{
windowStack.prepend(surface);
- surface->mScreen = this;
- QPoint screenOffset = mGeometry.topLeft();
- surface->localGeometry() = surface->geometry().translated(-screenOffset); // global to local translation
+ surface->mScreens.append(this);
invalidateRectCache();
setDirty(surface->geometry());
}
@@ -267,13 +266,19 @@ void QFbScreen::addWindow(QFbWindow *surface)
void QFbScreen::removeWindow(QFbWindow * surface)
{
windowStack.removeOne(surface);
+ surface->mScreens.removeOne(this);
invalidateRectCache();
setDirty(surface->geometry());
}
void QFbWindow::raise()
{
- mScreen->raise(this);
+ QList<QFbScreen *>::const_iterator i = mScreens.constBegin();
+ QList<QFbScreen *>::const_iterator end = mScreens.constEnd();
+ while (i != end) {
+ (*i)->raise(this);
+ ++i;
+ }
}
void QFbScreen::raise(QPlatformWindow * surface)
@@ -289,7 +294,12 @@ void QFbScreen::raise(QPlatformWindow * surface)
void QFbWindow::lower()
{
- mScreen->lower(this);
+ QList<QFbScreen *>::const_iterator i = mScreens.constBegin();
+ QList<QFbScreen *>::const_iterator end = mScreens.constEnd();
+ while (i != end) {
+ (*i)->lower(this);
+ ++i;
+ }
}
void QFbScreen::lower(QPlatformWindow * surface)
@@ -315,9 +325,8 @@ QWidget * QFbScreen::topLevelAt(const QPoint & p) const
return 0;
}
-QFbWindow::QFbWindow(QFbScreen *screen, QWidget *window)
+QFbWindow::QFbWindow(QWidget *window)
:QPlatformWindow(window),
- mScreen(screen),
visibleFlag(false)
{
static QAtomicInt winIdGenerator(1);
@@ -327,7 +336,12 @@ QFbWindow::QFbWindow(QFbScreen *screen, QWidget *window)
QFbWindow::~QFbWindow()
{
- mScreen->removeWindow(this);
+ QList<QFbScreen *>::const_iterator i = mScreens.constBegin();
+ QList<QFbScreen *>::const_iterator end = mScreens.constEnd();
+ while (i != end) {
+ (*i)->removeWindow(this);
+ ++i;
+ }
}
@@ -361,18 +375,23 @@ void QFbWindowSurface::flush(QWidget *widget, const QRegion &region, const QPoin
void QFbWindow::repaint(const QRegion &region)
{
QRect currentGeometry = geometry();
- // If this is a move, redraw the previous location
- if (oldGeometry != currentGeometry) {
- mScreen->setDirty(oldGeometry);
- oldGeometry = currentGeometry;
- }
QRect dirtyClient = region.boundingRect();
QRect dirtyRegion(currentGeometry.left() + dirtyClient.left(),
currentGeometry.top() + dirtyClient.top(),
dirtyClient.width(),
dirtyClient.height());
- mScreen->setDirty(dirtyRegion);
+ QList<QFbScreen *>::const_iterator i = mScreens.constBegin();
+ QList<QFbScreen *>::const_iterator end = mScreens.constEnd();
+ while (i != end) {
+ // If this is a move, redraw the previous location
+ if (oldGeometry != currentGeometry) {
+ (*i)->setDirty(oldGeometry);
+ oldGeometry = currentGeometry;
+ }
+ (*i)->setDirty(dirtyRegion);
+ ++i;
+ }
}
void QFbWindowSurface::resize(const QSize &size)
@@ -389,13 +408,15 @@ void QFbWindow::setGeometry(const QRect &rect)
oldGeometry = geometry();
- mScreen->invalidateRectCache();
+ QList<QFbScreen *>::const_iterator i = mScreens.constBegin();
+ QList<QFbScreen *>::const_iterator end = mScreens.constEnd();
+ while (i != end) {
+ (*i)->invalidateRectCache();
+ ++i;
+ }
//### QWindowSystemInterface::handleGeometryChange(window(), rect);
QPlatformWindow::setGeometry(rect);
-
- QPoint screenOffset = mScreen->geometry().topLeft();
- mLocalGeometry = rect.translated(-screenOffset); // global to local translation
}
bool QFbWindowSurface::scroll(const QRegion &area, int dx, int dy)
@@ -416,14 +437,24 @@ void QFbWindowSurface::endPaint(const QRegion &region)
void QFbWindow::setVisible(bool visible)
{
visibleFlag = visible;
- mScreen->invalidateRectCache();
- mScreen->setDirty(geometry());
+ QList<QFbScreen *>::const_iterator i = mScreens.constBegin();
+ QList<QFbScreen *>::const_iterator end = mScreens.constEnd();
+ while (i != end) {
+ (*i)->invalidateRectCache();
+ (*i)->setDirty(geometry());
+ ++i;
+ }
}
Qt::WindowFlags QFbWindow::setWindowFlags(Qt::WindowFlags type)
{
flags = type;
- mScreen->invalidateRectCache();
+ QList<QFbScreen *>::const_iterator i = mScreens.constBegin();
+ QList<QFbScreen *>::const_iterator end = mScreens.constEnd();
+ while (i != end) {
+ (*i)->invalidateRectCache();
+ ++i;
+ }
return flags;
}
diff --git a/src/plugins/platforms/fb_base/fb_base.h b/src/plugins/platforms/fb_base/fb_base.h
index 124dde0..3b5075d 100644
--- a/src/plugins/platforms/fb_base/fb_base.h
+++ b/src/plugins/platforms/fb_base/fb_base.h
@@ -80,7 +80,7 @@ class QFbWindow : public QPlatformWindow
{
public:
- QFbWindow(QFbScreen *screen, QWidget *window);
+ QFbWindow(QWidget *window);
~QFbWindow();
@@ -99,17 +99,14 @@ public:
virtual void repaint(const QRegion&);
- virtual QRect localGeometry() { return mLocalGeometry; }
-
protected:
friend class QFbWindowSurface;
friend class QFbScreen;
QFbWindowSurface *surface;
- QFbScreen *mScreen;
+ QList<QFbScreen *> mScreens;
QRect oldGeometry;
bool visibleFlag;
Qt::WindowFlags flags;
- QRect mLocalGeometry; // local screen coordinates
WId windowId;
};
diff --git a/src/plugins/platforms/vnc/qvncintegration.cpp b/src/plugins/platforms/vnc/qvncintegration.cpp
index de6d81f..2ae34dc 100644
--- a/src/plugins/platforms/vnc/qvncintegration.cpp
+++ b/src/plugins/platforms/vnc/qvncintegration.cpp
@@ -95,6 +95,7 @@ static void usage()
}
QVNCIntegration::QVNCIntegration(const QStringList& paramList)
+ : virtualDesktop(false)
{
int sizeX = defaultWidth();
int sizeY = defaultHeight();
@@ -125,6 +126,9 @@ QVNCIntegration::QVNCIntegration(const QStringList& paramList)
screen->setDirty(screenRect);
++display;
}
+ else if (confString == QLatin1String("virtual")) {
+ virtualDesktop = true;
+ }
else {
qWarning() << "Unknown VNC option:" << confString;
showUsage = true;
@@ -167,13 +171,27 @@ QWindowSurface *QVNCIntegration::createWindowSurface(QWidget *widget, WId) const
QPlatformWindow *QVNCIntegration::createPlatformWindow(QWidget *widget, WId /*winId*/) const
{
- QFbWindow *w = new QFbWindow(mPrimaryScreen, widget);
- mPrimaryScreen->addWindow(w);
+ QFbWindow *w = new QFbWindow(widget);
+ if (virtualDesktop) {
+ QList<QPlatformScreen *>::const_iterator i = mScreens.constBegin();
+ QList<QPlatformScreen *>::const_iterator end = mScreens.constEnd();
+ QFbScreen *screen;
+ while (i != end) {
+ screen = static_cast<QFbScreen *>(*i);
+ screen->addWindow(w);
+ ++i;
+ }
+ }
+ else
+ mPrimaryScreen->addWindow(w);
return w;
}
void QVNCIntegration::moveToScreen(QWidget *window, int screen)
{
+ if (virtualDesktop) { // all windows exist on all screens in virtual desktop mode
+ return;
+ }
if (screen < 0 || screen > mScreens.size())
return;
QVNCScreen * newScreen = qobject_cast<QVNCScreen *>(mScreens.at(screen));
diff --git a/src/plugins/platforms/vnc/qvncintegration.h b/src/plugins/platforms/vnc/qvncintegration.h
index 3436e51..d49e051 100644
--- a/src/plugins/platforms/vnc/qvncintegration.h
+++ b/src/plugins/platforms/vnc/qvncintegration.h
@@ -86,11 +86,13 @@ public:
QList<QPlatformScreen *> screens() const { return mScreens; }
+ bool isVirtualDesktop() { return virtualDesktop; }
void moveToScreen(QWidget *window, int screen);
private:
QVNCScreen *mPrimaryScreen;
QList<QPlatformScreen *> mScreens;
+ bool virtualDesktop;
};