Merge branch 'KDE/4.11'

Conflicts:
	kwin/eglonxbackend.cpp
	kwin/glxbackend.cpp
This commit is contained in:
Thomas Lübking 2013-09-25 23:21:36 +02:00
commit 3594550b14
9 changed files with 117 additions and 29 deletions

View file

@ -2404,7 +2404,7 @@ QRect Client::decorationRect() const
}
}
KDecorationDefines::Position Client::titlebarPosition()
KDecorationDefines::Position Client::titlebarPosition() const
{
Position titlePos = PositionCenter; // PositionTop is returned by the default implementation
// this will hint errors in the metaobject usage ;-)

View file

@ -599,7 +599,7 @@ public:
bool decorationHasAlpha() const;
Position titlebarPosition();
Position titlebarPosition() const;
enum CoordinateMode {
DecorationRelative, // Relative to the top left corner of the decoration

View file

@ -269,7 +269,6 @@ void Compositor::slotCompositingOptionsInitialized()
}
// render at least once
compositeTimer.stop();
performCompositing();
}
@ -533,7 +532,6 @@ void Compositor::addRepaintFull()
void Compositor::timerEvent(QTimerEvent *te)
{
if (te->timerId() == compositeTimer.timerId()) {
compositeTimer.stop();
performCompositing();
} else
QObject::timerEvent(te);
@ -581,10 +579,12 @@ void Compositor::performCompositing()
if (repaints_region.isEmpty() && !windowRepaintsPending()) {
m_scene->idle();
m_timeSinceLastVBlank = fpsInterval - (options->vBlankTime() + 1); // means "start now"
// Note: It would seem here we should undo suspended unredirect, but when scenes need
// it for some reason, e.g. transformations or translucency, the next pass that does not
// need this anymore and paints normally will also reset the suspended unredirect.
// Otherwise the window would not be painted normally anyway.
compositeTimer.stop();
return;
}
@ -602,6 +602,8 @@ void Compositor::performCompositing()
m_timeSinceLastVBlank = m_scene->paint(repaints, windows);
compositeTimer.stop(); // stop here to ensure *we* cause the next repaint schedule - not some effect through m_scene->paint()
// Trigger at least one more pass even if there would be nothing to paint, so that scene->idle()
// is called the next time. If there would be nothing pending, it will not restart the timer and
// scheduleRepaint() would restart it again somewhen later, called from functions that
@ -661,10 +663,29 @@ void Compositor::setCompositeTimer()
waitTime = nanoToMilli(padding - options->vBlankTime());
}
}
else // w/o vsync we just jump to the next demanded tick
// the "1" will ensure we don't block out the eventloop - the system's just not faster
// "0" would be sufficient, but the compositor isn't the WMs only task
waitTime = (m_timeSinceLastVBlank > fpsInterval) ? 1 : nanoToMilli(fpsInterval - m_timeSinceLastVBlank);
else { // w/o blocking vsync we just jump to the next demanded tick
if (fpsInterval > m_timeSinceLastVBlank) {
waitTime = nanoToMilli(fpsInterval - m_timeSinceLastVBlank);
if (!waitTime) {
waitTime = 1; // will ensure we don't block out the eventloop - the system's just not faster ...
}
}/* else if (m_scene->syncsToVBlank() && m_timeSinceLastVBlank - fpsInterval < (vBlankInterval<<1)) {
// NOTICE - "for later" ------------------------------------------------------------------
// It can happen that we push two frames within one refresh cycle.
// Swapping will then block even with triple buffering when the GPU does not discard but
// queues frames
// now here's the mean part: if we take that as "OMG, we're late - next frame ASAP",
// there'll immediately be 2 frames in the pipe, swapping will block, we think we're
// late ... ewww
// so instead we pad to the clock again and add 2ms safety to ensure the pipe is really
// free
// NOTICE: obviously m_timeSinceLastVBlank can be too big because we're too slow as well
// So if this code was enabled, we'd needlessly half the framerate once more (15 instead of 30)
waitTime = nanoToMilli(vBlankInterval - (m_timeSinceLastVBlank - fpsInterval)%vBlankInterval) + 2;
}*/ else {
waitTime = 1; // ... "0" would be sufficient, but the compositor isn't the WMs only task
}
}
compositeTimer.start(qMin(waitTime, 250u), this); // force 4fps minimum
}

View file

@ -26,6 +26,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <kwinglplatform.h>
// Qt
#include <QDebug>
// system
#include <unistd.h>
namespace KWin
{
@ -320,6 +322,14 @@ SceneOpenGL::TexturePrivate *EglOnXBackend::createBackendTexture(SceneOpenGL::Te
void EglOnXBackend::prepareRenderingFrame()
{
if (gs_tripleBufferNeedsDetection) {
// the composite timer floors the repaint frequency. This can pollute our triple buffering
// detection because the glXSwapBuffers call for the new frame has to wait until the pending
// one scanned out.
// So we compensate for that by waiting an extra milisecond to give the driver the chance to
// fllush the buffer queue
usleep(1000);
}
present();
startRenderTimer();
eglWaitNative(EGL_CORE_NATIVE_ENGINE);

View file

@ -395,8 +395,9 @@ QPoint Workspace::adjustClientPosition(Client* c, QPoint pos, bool unrestricted,
if (options->windowSnapZone() || !borderSnapZone.isNull() || options->centerSnapZone()) {
const bool sOWO = options->isSnapOnlyWhenOverlapping();
const int screen = screens()->number(pos + c->rect().center());
if (maxRect.isNull())
maxRect = clientArea(MovementArea, pos + c->rect().center(), c->desktop());
maxRect = clientArea(MovementArea, screen, c->desktop());
const int xmin = maxRect.left();
const int xmax = maxRect.right() + 1; //desk size
const int ymin = maxRect.top();
@ -419,21 +420,25 @@ QPoint Workspace::adjustClientPosition(Client* c, QPoint pos, bool unrestricted,
const int snapX = borderSnapZone.width() * snapAdjust; //snap trigger
const int snapY = borderSnapZone.height() * snapAdjust;
if (snapX || snapY) {
QRect geo = c->geometry();
const QPoint cp = c->clientPos();
const QSize cs = c->geometry().size() - c->clientSize();
const QSize cs = geo.size() - c->clientSize();
int padding[4] = { cp.x(), cs.width() - cp.x(), cp.y(), cs.height() - cp.y() };
// snap to titlebar
// snap to titlebar / snap to window borders on inner screen edges
Position titlePos = c->titlebarPosition();
if (titlePos == PositionLeft || (c->maximizeMode() & MaximizeHorizontal))
if (padding[0] && (titlePos == PositionLeft || (c->maximizeMode() & MaximizeHorizontal) ||
screens()->intersecting(geo.translated(maxRect.x() - (padding[0] + geo.x()), 0)) > 1))
padding[0] = 0;
if (titlePos == PositionRight || (c->maximizeMode() & MaximizeHorizontal))
if (padding[1] && (titlePos == PositionRight || (c->maximizeMode() & MaximizeHorizontal) ||
screens()->intersecting(geo.translated(maxRect.right() + padding[1] - geo.right(), 0)) > 1))
padding[1] = 0;
if (titlePos == PositionTop || (c->maximizeMode() & MaximizeVertical))
if (padding[2] && (titlePos == PositionTop || (c->maximizeMode() & MaximizeVertical) ||
screens()->intersecting(geo.translated(0, maxRect.y() - (padding[2] + geo.y()))) > 1))
padding[2] = 0;
if (titlePos == PositionBottom || (c->maximizeMode() & MaximizeVertical))
if (padding[3] && (titlePos == PositionBottom || (c->maximizeMode() & MaximizeVertical) ||
screens()->intersecting(geo.translated(0, maxRect.bottom() + padding[3] - geo.bottom())) > 1))
padding[3] = 0;
if ((sOWO ? (cx < xmin) : true) && (qAbs(xmin - cx) < snapX)) {
deltaX = xmin - cx;
nx = xmin - padding[0];
@ -842,19 +847,19 @@ void Client::keepInArea(QRect area, bool partial)
if (area.width() < width() || area.height() < height())
resizeWithChecks(qMin(area.width(), width()), qMin(area.height(), height()));
}
int tx = x(), ty = y();
if (geometry().right() > area.right() && width() <= area.width())
move(area.right() - width() + 1, y());
tx = area.right() - width() + 1;
if (geometry().bottom() > area.bottom() && height() <= area.height())
move(x(), area.bottom() - height() + 1);
ty = area.bottom() - height() + 1;
if (!area.contains(geometry().topLeft())) {
int tx = x();
int ty = y();
if (tx < area.x())
tx = area.x();
if (ty < area.y())
ty = area.y();
move(tx, ty);
}
if (tx != x() || ty != y())
move(tx, ty);
}
/*!
@ -1480,16 +1485,16 @@ void Client::getWmNormalHints()
// update to match restrictions
QSize new_size = adjustedSize();
if (new_size != size() && !isFullScreen()) {
QRect orig_geometry = geometry();
QRect origClientGeometry(pos() + clientPos(), clientSize());
resizeWithChecks(new_size);
if ((!isSpecialWindow() || isToolbar()) && !isFullScreen()) {
// try to keep the window in its xinerama screen if possible,
// if that fails at least keep it visible somewhere
QRect area = workspace()->clientArea(MovementArea, this);
if (area.contains(orig_geometry))
if (area.contains(origClientGeometry))
keepInArea(area);
area = workspace()->clientArea(WorkArea, this);
if (area.contains(orig_geometry))
if (area.contains(origClientGeometry))
keepInArea(area);
}
}
@ -1671,7 +1676,7 @@ void Client::configureRequest(int value_mask, int rx, int ry, int rw, int rh, in
if (newScreen != rules()->checkScreen(newScreen))
return; // not allowed by rule
QRect orig_geometry = geometry();
QRect origClientGeometry(pos() + clientPos(), clientSize());
GeometryUpdatesBlocker blocker(this);
move(new_pos);
plainResize(ns);
@ -1679,7 +1684,7 @@ void Client::configureRequest(int value_mask, int rx, int ry, int rw, int rh, in
updateFullScreenHack(QRect(new_pos, QSize(nw, nh)));
QRect area = workspace()->clientArea(WorkArea, this);
if (!from_tool && (!isSpecialWindow() || isToolbar()) && !isFullScreen()
&& area.contains(orig_geometry))
&& area.contains(origClientGeometry))
keepInArea(area);
// this is part of the kicker-xinerama-hack... it should be
@ -1701,7 +1706,7 @@ void Client::configureRequest(int value_mask, int rx, int ry, int rw, int rh, in
QSize ns = sizeForClientSize(QSize(nw, nh));
if (ns != size()) { // don't restore if some app sets its own size again
QRect orig_geometry = geometry();
QRect origClientGeometry(pos() + clientPos(), clientSize());
GeometryUpdatesBlocker blocker(this);
int save_gravity = xSizeHint.win_gravity;
xSizeHint.win_gravity = gravity;
@ -1712,10 +1717,10 @@ void Client::configureRequest(int value_mask, int rx, int ry, int rw, int rh, in
// try to keep the window in its xinerama screen if possible,
// if that fails at least keep it visible somewhere
QRect area = workspace()->clientArea(MovementArea, this);
if (area.contains(orig_geometry))
if (area.contains(origClientGeometry))
keepInArea(area);
area = workspace()->clientArea(WorkArea, this);
if (area.contains(orig_geometry))
if (area.contains(origClientGeometry))
keepInArea(area);
}
}

View file

@ -34,6 +34,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <kwinglplatform.h>
// Qt
#include <QDebug>
// system
#include <unistd.h>
namespace KWin
{
@ -492,6 +494,14 @@ SceneOpenGL::TexturePrivate *GlxBackend::createBackendTexture(SceneOpenGL::Textu
void GlxBackend::prepareRenderingFrame()
{
if (gs_tripleBufferNeedsDetection) {
// the composite timer floors the repaint frequency. This can pollute our triple buffering
// detection because the glXSwapBuffers call for the new frame has to wait until the pending
// one scanned out.
// So we compensate for that by waiting an extra milisecond to give the driver the chance to
// fllush the buffer queue
usleep(1000);
}
present();
startRenderTimer();
glXWaitX();

View file

@ -33,6 +33,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "client.h"
#include "options.h"
#include "rules.h"
#include "screens.h"
#endif
namespace KWin
@ -836,6 +837,13 @@ int Workspace::packPositionLeft(const Client* cl, int oldx, bool left_edge) cons
if (oldx <= newx) // try another Xinerama screen
newx = clientArea(MaximizeArea,
QPoint(cl->geometry().left() - 1, cl->geometry().center().y()), cl->desktop()).left();
if (cl->titlebarPosition() != KDecorationDefines::PositionLeft) {
QRect geo = cl->geometry();
int rgt = newx - cl->clientPos().x();
geo.moveRight(rgt);
if (screens()->intersecting(geo) < 2)
newx = rgt;
}
if (oldx <= newx)
return oldx;
for (ClientList::ConstIterator it = clients.constBegin(), end = clients.constEnd(); it != end; ++it) {
@ -856,6 +864,13 @@ int Workspace::packPositionRight(const Client* cl, int oldx, bool right_edge) co
if (oldx >= newx) // try another Xinerama screen
newx = clientArea(MaximizeArea,
QPoint(cl->geometry().right() + 1, cl->geometry().center().y()), cl->desktop()).right();
if (cl->titlebarPosition() != KDecorationDefines::PositionRight) {
QRect geo = cl->geometry();
int rgt = newx + cl->width() - (cl->clientSize().width() + cl->clientPos().x());
geo.moveRight(rgt);
if (screens()->intersecting(geo) < 2)
newx = rgt;
}
if (oldx >= newx)
return oldx;
for (ClientList::ConstIterator it = clients.constBegin(), end = clients.constEnd(); it != end; ++it) {
@ -876,6 +891,13 @@ int Workspace::packPositionUp(const Client* cl, int oldy, bool top_edge) const
if (oldy <= newy) // try another Xinerama screen
newy = clientArea(MaximizeArea,
QPoint(cl->geometry().center().x(), cl->geometry().top() - 1), cl->desktop()).top();
if (cl->titlebarPosition() != KDecorationDefines::PositionTop) {
QRect geo = cl->geometry();
int top = newy - cl->clientPos().y();
geo.moveTop(top);
if (screens()->intersecting(geo) < 2)
newy = top;
}
if (oldy <= newy)
return oldy;
for (ClientList::ConstIterator it = clients.constBegin(), end = clients.constEnd(); it != end; ++it) {
@ -896,6 +918,13 @@ int Workspace::packPositionDown(const Client* cl, int oldy, bool bottom_edge) co
if (oldy >= newy) // try another Xinerama screen
newy = clientArea(MaximizeArea,
QPoint(cl->geometry().center().x(), cl->geometry().bottom() + 1), cl->desktop()).bottom();
if (cl->titlebarPosition() != KDecorationDefines::PositionBottom) {
QRect geo = cl->geometry();
int btm = newy + cl->height() - (cl->clientSize().height() + cl->clientPos().y());
geo.moveBottom(btm);
if (screens()->intersecting(geo) < 2)
newy = btm;
}
if (oldy >= newy)
return oldy;
for (ClientList::ConstIterator it = clients.constBegin(), end = clients.constEnd(); it != end; ++it) {

View file

@ -117,6 +117,17 @@ int Screens::current() const
return m_current;
}
int Screens::intersecting(const QRect &r) const
{
int cnt = 0;
for (int i = 0; i < count(); ++i) {
if (geometry(i).intersects(r)) {
++cnt;
}
}
return cnt;
}
DesktopWidgetScreens::DesktopWidgetScreens(QObject *parent)
: Screens(parent)
, m_desktop(QApplication::desktop())

View file

@ -68,6 +68,8 @@ public:
inline bool isChanging() { return m_changedTimer->isActive(); }
int intersecting(const QRect &r) const;
public Q_SLOTS:
void reconfigure();