summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam Endrodi <ext-adam.endrodi@nokia.com>2010-12-09 18:12:22 +0200
committerAdam Endrodi <ext-adam.endrodi@nokia.com>2010-12-15 15:59:55 +0200
commit7afd24073bff77bd2b536626d202d809ed3858ba (patch)
treee2ac880ce73485352feb0105057d85cf641e73bd
parentfecd9daf0e6d9e6c5d41d68da891b8734dedde7f (diff)
handle all kind of decoration geometries correctly
Currently we drop decoration rectangles semi-randomly and get the coordinates wrong if mdecorator is rotated, making test14 fail. * decorators/mdecorator/mdecoratorwindow.cpp: -- MDecoratorWindow::itemRectToScreenRect(): gone for good, use QTransform instead -- set_shape(): merge into MDecoratorWindow::setInputRegion() -- MDecoratorWindow::setInputRegion(): do the coordinate-mapping correctly in all cases and don't drop any rectangles
-rw-r--r--decorators/mdecorator/mdecoratorwindow.cpp126
1 files changed, 50 insertions, 76 deletions
diff --git a/decorators/mdecorator/mdecoratorwindow.cpp b/decorators/mdecorator/mdecoratorwindow.cpp
index 4e20aff..29025df 100644
--- a/decorators/mdecorator/mdecoratorwindow.cpp
+++ b/decorators/mdecorator/mdecoratorwindow.cpp
@@ -282,98 +282,72 @@ void MDecoratorWindow::screenRotated(const M::Orientation &orientation)
d->setAvailableGeometry(availableClientRect());
}
-// NOTE: this works with fullscreen-width rects only
-QRect MDecoratorWindow::itemRectToScreenRect(const QRect& r)
-{
- QRect rect;
- Display *dpy = QX11Info::display();
- int xres = ScreenOfDisplay(dpy, DefaultScreen(dpy))->width;
- int yres = ScreenOfDisplay(dpy, DefaultScreen(dpy))->height;
- switch (sceneManager()->orientationAngle()) {
- case 0:
- rect = r;
- break;
- case 90:
- rect = QRect(xres - r.height(), 0, r.height(), r.width());
- break;
- case 270:
- rect = QRect(0, 0, r.height(), r.width());
- break;
- case 180:
- rect = QRect(0, yres - r.height(), r.width(), r.height());
- break;
- default:
- break;
- }
- return rect;
-}
-
-static void set_shape(Window win, XRectangle *r, int n)
-{
- static XRectangle *prev_rects = 0;
- static int prev_n = 0;
- if (prev_n != n ||
- (prev_rects && memcmp(prev_rects, r, sizeof(XRectangle[n])))) {
- Display *dpy = QX11Info::display();
- XserverRegion shapeRegion = XFixesCreateRegion(dpy, r, n);
- XShapeCombineRectangles(dpy, win, ShapeBounding, 0, 0, r, n,
- ShapeSet, Unsorted);
- XFixesSetWindowShapeRegion(dpy, win, ShapeInput, 0, 0, shapeRegion);
- XFixesDestroyRegion(dpy, shapeRegion);
- } else
- return;
- if (prev_rects && prev_n != n) {
- delete[] prev_rects;
- prev_rects = new XRectangle[n];
- }
- prev_n = n;
- if (prev_rects)
- memcpy(prev_rects, r, sizeof(XRectangle[n]));
-}
-
void MDecoratorWindow::setInputRegion()
{
+ static QRegion prev_region;
QRegion region;
- const QRect fs(QApplication::desktop()->screenGeometry());
+ const QRegion fs(QApplication::desktop()->screenGeometry());
+
+ // region := decoration region
if (messageBox) {
- XRectangle rect;
+ // Occupy all space.
region = fs;
- rect.x = fs.x();
- rect.y = fs.y();
- rect.width = fs.width();
- rect.height = fs.height();
- availableRect = QRect(0, 0, 0, 0);
- set_shape(winId(), &rect, 1);
} else {
- region += statusBar->geometry().toRect();
+ // Decoration includes the status bar, and possibly other elements.
+ region = statusBar->geometry().toRect();
if (!only_statusbar) {
region += navigationBar->geometry().toRect();
region += homeButtonPanel->geometry().toRect();
region += escapeButtonPanel->geometry().toRect();
}
+ // The coordinates we receive from libmeegotouch are rotated
+ // by @angle. Map @retion back to screen coordinates.
+ int angle = sceneManager()->orientationAngle();
+ if (angle != 0) {
+ QTransform trans;
+ const QRect fs(QApplication::desktop()->screenGeometry());
+
+ trans.rotate(angle);
+ if (angle == 270)
+ trans.translate(-fs.height(), 0);
+ else if (angle == 180)
+ trans.translate(-fs.width(), -fs.height());
+ else if (angle == 90)
+ trans.translate(0, -fs.width());
+ region = trans.map(region);
+ }
+ }
+
+ // Set our input and bounding shape to @region if changed.
+ if (prev_region != region) {
+ prev_region = region;
+
+ // Convert @region to @xrects.
const QVector<QRect> rects = region.rects();
- QRegion screen_region;
- XRectangle *xrects = new XRectangle[rects.count()];
- int count = 0;
- for (int i = 0; i < rects.count(); ++i) {
- QRect r = itemRectToScreenRect(rects[i]);
- if (r.x() || (r.width() != fs.width() && r.width() != fs.height()))
- // only fullscreen-width components supported
- continue;
- screen_region += r;
- xrects[count].x = r.x();
- xrects[count].y = r.y();
- xrects[count].width = r.width();
- xrects[count].height = r.height();
- ++count;
+ int nxrects = rects.count();
+ XRectangle *xrects = new XRectangle[nxrects];
+ for (int i = 0; i < nxrects; ++i) {
+ xrects[i].x = rects[i].x();
+ xrects[i].y = rects[i].y();
+ xrects[i].width = rects[i].width();
+ xrects[i].height = rects[i].height();
}
- set_shape(winId(), xrects, count);
- delete[] xrects;
- // NOTE: assumes that the available region is a single rectangle
- availableRect = QRegion(QRegion(fs) - screen_region).boundingRect();
+ Display *dpy = QX11Info::display();
+ XserverRegion shapeRegion = XFixesCreateRegion(dpy, xrects, nxrects);
+ XFixesSetWindowShapeRegion(dpy, winId(), ShapeInput,
+ 0, 0, shapeRegion);
+ XFixesSetWindowShapeRegion(dpy, winId(), ShapeBounding,
+ 0, 0, shapeRegion);
+
+ XFixesDestroyRegion(dpy, shapeRegion);
+ delete[] xrects;
}
+
+ // The rectangle available for the application is the largest square
+ // on the screen not covered by decoration completely.
+ availableRect = (fs - region).boundingRect();
}
void MDecoratorWindow::setSceneSize()