Merge branch 'master' of git.kde.org:kde-workspace

icc-effect-5.14.5
Montel Laurent 2012-11-14 21:43:42 +01:00
commit 7fb7f2b5e1
12 changed files with 127 additions and 57 deletions

View File

@ -457,16 +457,24 @@ bool Workspace::activateNextClient(Client* c)
Client* get_focus = NULL;
if (options->isNextFocusPrefersMouse()) {
// precedence on keeping the current tabgroup active. to the user that's the same window
if (c && c->tabGroup()) {
if (c == c->tabGroup()->current())
c->tabGroup()->activateNext();
get_focus = c->tabGroup()->current();
if (get_focus == c) // single tab case - should not happen
get_focus = NULL;
}
if (!get_focus && options->isNextFocusPrefersMouse()) {
get_focus = clientUnderMouse(c ? c->screen() : activeScreen());
if (get_focus && (get_focus == c || get_focus->isDesktop())) {
// should rather not happen, but it cannot get the focus. rest of usability is tested above
get_focus = 0;
get_focus = NULL;
}
}
if (!get_focus) { // no suitable window under the mouse -> find sth. else
// first try to pass the focus to the (former) active clients leader
if (c && (get_focus = c->transientFor()) && isUsableFocusCandidate(get_focus, c, options->isSeparateScreenFocus())) {
raiseClient(get_focus); // also raise - we don't know where it came from

View File

@ -357,7 +357,7 @@ void Client::updateInputWindow()
{
QRegion region;
if (!noBorder() && dynamic_cast<KDecorationUnstable*>(decoration)) {
if (!noBorder()) {
// This function is implemented as a slot to avoid breaking binary
// compatibility
QMetaObject::invokeMethod(decoration, "region", Qt::DirectConnection,
@ -391,6 +391,8 @@ void Client::updateInputWindow()
input_window = XCreateWindow(display(), rootWindow(), bounds.x(), bounds.y(),
bounds.width(), bounds.height(), 0, 0,
InputOnly, 0, CWEventMask | CWOverrideRedirect, &attr);
if (mapping_state == Mapped)
XMapWindow(display(), inputId());
} else {
XMoveResizeWindow(display(), input_window, bounds.x(), bounds.y(),
bounds.width(), bounds.height());

View File

@ -24,6 +24,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <kwinglutils.h>
#ifdef KWIN_HAVE_XRENDER_COMPOSITING
#include <kwinxrenderutils.h>
#include <QPainter>
#endif
#include <KDE/KAction>
#include <KDE/KActionCollection>
#include <KDE/KConfigGroup>
@ -36,6 +41,10 @@ namespace KWin
KWIN_EFFECT(mouseclick, MouseClickEffect)
KWIN_EFFECT_SUPPORTED(mouseclick, MouseClickEffect::supported())
#ifdef KWIN_HAVE_XRENDER_COMPOSITING
static QPixmap s_XrBuffer;
#endif
MouseClickEffect::MouseClickEffect()
{
m_enabled = false;
@ -55,6 +64,10 @@ MouseClickEffect::MouseClickEffect()
MouseClickEffect::~MouseClickEffect()
{
#ifdef KWIN_HAVE_XRENDER_COMPOSITING
if (!s_XrBuffer.isNull())
XFreePixmap(display(), s_XrBuffer.handle());
#endif
effects->stopMousePolling();
foreach (const MouseEvent* click, m_clicks) {
delete click;
@ -68,7 +81,7 @@ MouseClickEffect::~MouseClickEffect()
bool MouseClickEffect::supported()
{
return effects->isOpenGLCompositing();
return true;
}
void MouseClickEffect::reconfigure(ReconfigureFlags)
@ -252,17 +265,22 @@ bool MouseClickEffect::isActive() const
void MouseClickEffect::drawCircle(const QColor& color, float cx, float cy, float r)
{
drawCircleGl(color, cx, cy, r);
if (effects->isOpenGLCompositing())
drawCircleGl(color, cx, cy, r);
if (effects->compositingType() == XRenderCompositing)
drawCircleXr(color, cx, cy, r);
}
void MouseClickEffect::paintScreenSetup(int mask, QRegion region, ScreenPaintData& data)
{
paintScreenSetupGl(mask, region, data);
if (effects->isOpenGLCompositing())
paintScreenSetupGl(mask, region, data);
}
void MouseClickEffect::paintScreenFinish(int mask, QRegion region, ScreenPaintData& data)
{
paintScreenFinishGl(mask, region, data);
if (effects->isOpenGLCompositing())
paintScreenFinishGl(mask, region, data);
}
void MouseClickEffect::drawCircleGl(const QColor& color, float cx, float cy, float r)
@ -294,6 +312,35 @@ void MouseClickEffect::drawCircleGl(const QColor& color, float cx, float cy, flo
vbo->render(GL_LINE_LOOP);
}
void MouseClickEffect::drawCircleXr(const QColor& color, float cx, float cy, float r)
{
#ifdef KWIN_HAVE_XRENDER_COMPOSITING
const int bufferSize = qRound(1.41421356*(2*m_ringMaxSize + m_lineWidth)) | 1;
if (bufferSize < 0) // should not happen, but we neither want to leak XPixmaps
return;
if (s_XrBuffer.size() != QSize(bufferSize, bufferSize)) {
if (!s_XrBuffer.isNull()) {
XFreePixmap(display(), s_XrBuffer.handle());
}
Pixmap xpix = XCreatePixmap(display(), rootWindow(), bufferSize, bufferSize, 32);
s_XrBuffer = QPixmap::fromX11Pixmap(xpix, QPixmap::ExplicitlyShared);
}
s_XrBuffer.fill(Qt::transparent);
QRect rct(s_XrBuffer.rect());
QPainter p(&s_XrBuffer);
p.setBrush(Qt::NoBrush);
p.setPen(QPen(color, m_lineWidth));
p.setRenderHint(QPainter::Antialiasing);
const int ir = qRound(r);
p.drawEllipse(rct.center(), ir, ir);
p.end();
rct.moveCenter(QPoint(qRound(cx), qRound(cy)));
XRenderComposite( display(), PictOpOver,
s_XrBuffer.x11PictureHandle(), 0, effects->xrenderBufferPicture(),
0, 0, 0, 0, rct.x(), rct.y(), rct.width(), rct.height() );
#endif
}
void MouseClickEffect::paintScreenSetupGl(int, QRegion, ScreenPaintData&)
{
if (ShaderManager::instance()->isValid()) {

View File

@ -160,6 +160,7 @@ private:
void repaint();
void drawCircleGl(const QColor& color, float cx, float cy, float r);
void drawCircleXr(const QColor& color, float cx, float cy, float r);
void paintScreenSetupGl(int mask, QRegion region, ScreenPaintData& data);
void paintScreenFinishGl(int mask, QRegion region, ScreenPaintData& data);

View File

@ -1180,16 +1180,17 @@ bool Client::buttonPressEvent(Window w, int button, int state, int x, int y, int
XAllowEvents(display(), ReplayPointer, CurrentTime); //xTime());
return true;
}
if (w == decorationId() || w == inputId()) {
if (w == inputId()) {
x = x_root - geometry().x() + padding_left;
y = y_root - geometry().y() + padding_top;
}
if (w == inputId()) {
x = x_root - geometry().x() + padding_left;
y = y_root - geometry().y() + padding_top;
// New API processes core events FIRST and only passes unused ones to the decoration
return processDecorationButtonPress(button, state, x, y, x_root, y_root, true);
}
if (w == decorationId()) {
if (dynamic_cast<KDecorationUnstable*>(decoration))
// New API processes core events FIRST and only passes unused ones to the decoration
return processDecorationButtonPress(button, state, x, y, x_root, y_root, true);
else
return false; // Don't eat old API decoration events
return false;
}
if (w == frameId())
processDecorationButtonPress(button, state, x, y, x_root, y_root);

View File

@ -2544,24 +2544,27 @@ bool Client::startMoveResize()
// when starting a move as the user can undo their action by moving the window back to
// the top of the screen. When the setting is disabled then doing so is confusing.
bool fakeMove = false;
if (maximizeMode() != MaximizeRestore && (maximizeMode() != MaximizeFull || options->moveResizeMaximizedWindows())) {
// allow moveResize, but unset maximization state in resize case
if (mode != PositionCenter) { // means "isResize()" but moveResizeMode = true is set below
if (maximizeMode() == MaximizeFull) { // partial is cond. reset in finishMoveResize
geom_restore = geometry(); // "restore" to current geometry
setMaximize(false, false);
}
} else if (quick_tile_mode != QuickTileNone) // no longer now - we move, resize is handled below
setQuickTileMode(QuickTileNone); // otherwise we mess every second tile, bug #303937
} else if ((maximizeMode() == MaximizeFull && options->electricBorderMaximize()) ||
(quick_tile_mode != QuickTileNone && isMovable() && mode == PositionCenter)) {
// Exit quick tile mode when the user attempts to move a tiled window, cannot use isMove() yet
const QRect before = geometry();
setQuickTileMode(QuickTileNone);
// Move the window so it's under the cursor
moveOffset = QPoint(double(moveOffset.x()) / double(before.width()) * double(geom_restore.width()),
double(moveOffset.y()) / double(before.height()) * double(geom_restore.height()));
fakeMove = true;
if (!isFullScreen()) { // xinerama move across screens -> window is FS, everything else is secondary and untouched
if (maximizeMode() != MaximizeRestore &&
(maximizeMode() != MaximizeFull || options->moveResizeMaximizedWindows())) {
// allow moveResize, but unset maximization state in resize case
if (mode != PositionCenter) { // means "isResize()" but moveResizeMode = true is set below
if (maximizeMode() == MaximizeFull) { // partial is cond. reset in finishMoveResize
geom_restore = geometry(); // "restore" to current geometry
setMaximize(false, false);
}
} else if (quick_tile_mode != QuickTileNone) // no longer now - we move, resize is handled below
setQuickTileMode(QuickTileNone); // otherwise we mess every second tile, bug #303937
} else if ((maximizeMode() == MaximizeFull && options->electricBorderMaximize()) ||
(quick_tile_mode != QuickTileNone && isMovable() && mode == PositionCenter)) {
// Exit quick tile mode when the user attempts to move a tiled window, cannot use isMove() yet
const QRect before = geometry();
setQuickTileMode(QuickTileNone);
// Move the window so it's under the cursor
moveOffset = QPoint(double(moveOffset.x()) / double(before.width()) * double(geom_restore.width()),
double(moveOffset.y()) / double(before.height()) * double(geom_restore.height()));
fakeMove = true;
}
}
if (quick_tile_mode != QuickTileNone && mode != PositionCenter) { // Cannot use isResize() yet

View File

@ -516,7 +516,7 @@ KDecoration::WindowOperation KDecorationUnstable::buttonToWindowOperation(Qt::Mo
return static_cast< KDecorationBridgeUnstable* >(bridge_)->buttonToWindowOperation(button);
}
QRegion KDecorationUnstable::region(KDecorationDefines::Region)
QRegion KDecoration::region(KDecorationDefines::Region)
{
return QRegion();
}

View File

@ -1011,6 +1011,15 @@ protected Q_SLOTS:
* @since 4.10
**/
void setAlphaEnabled(bool enabled);
/**
* This slot can be reimplemented to return the regions defined
* by KDecorationDefines::Region.
*
* The default implementation always returns an empty region.
*
* @since 4.8
*/
QRegion region(KDecorationDefines::Region r);
private:
KDecorationBridge* bridge_;
@ -1121,17 +1130,6 @@ public:
* a button press was for window tab dragging or for displaying the client menu.
*/
WindowOperation buttonToWindowOperation(Qt::MouseButtons button);
public Q_SLOTS:
/**
* This slot can be reimplemented to return the regions defined
* by KDecorationDefines::Region.
*
* The default implementation always returns an empty region.
*
* @since 4.8
*/
QRegion region(KDecorationDefines::Region r);
};
inline

View File

@ -29,7 +29,7 @@ AniData::AniData()
{
attribute = AnimationEffect::Opacity;
windowType = (NET::WindowTypeMask)0;
duration = time = meta = 0;
duration = time = meta = startTime = 0;
waitAtSource = false;
}
@ -37,7 +37,6 @@ AniData::AniData(AnimationEffect::Attribute a, int meta, int ms, const FPx2 &to,
QEasingCurve curve, int delay, const FPx2 &from, bool waitAtSource )
{
attribute = a;
startTime = QTime::currentTime().addMSecs(delay);
this->from = from;
this->to = to;
this->curve = curve;
@ -45,6 +44,7 @@ AniData::AniData(AnimationEffect::Attribute a, int meta, int ms, const FPx2 &to,
time = 0;
this->meta = meta;
this->waitAtSource = waitAtSource;
startTime = AnimationEffect::clock() + delay;
}
AniData::AniData(const AniData &other)
@ -54,11 +54,11 @@ AniData::AniData(const AniData &other)
to = other.to;
time = other.time;
duration = other.duration;
startTime = other.startTime;
curve = other.curve;
customCurve = other.customCurve;
windowType = other.windowType;
meta = other.meta;
startTime = other.startTime;
}
static FPx2 fpx2(const QString &s, AnimationEffect::Attribute a)

View File

@ -23,7 +23,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "kwinanimationeffect.h"
#include <QEasingCurve>
#include <QTime>
#include <netwm.h>
namespace KWin {
@ -47,7 +46,7 @@ public:
FPx2 from, to;
int time, duration;
uint meta;
QTime startTime;
qint64 startTime;
NET::WindowTypeMask windowType;
bool waitAtSource;
};

View File

@ -21,10 +21,13 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "kwinanimationeffect.h"
#include "anidata_p.h"
#include <QTime>
#include <QDateTime>
#include <QTimer>
namespace KWin {
QElapsedTimer AnimationEffect::s_clock;
struct AnimationEffectPrivate {
public:
AnimationEffectPrivate() { m_animated = m_damageDirty = false; }
@ -40,6 +43,8 @@ AnimationEffect::AnimationEffect() : d_ptr(new AnimationEffectPrivate())
{
Q_D(AnimationEffect);
d->m_animated = false;
if (!s_clock.isValid())
s_clock.start();
/* this is the same as the QTimer::singleShot(0, SLOT(init())) kludge
* defering the init and esp. the connection to the windowClosed slot */
QMetaObject::invokeMethod( this, "init", Qt::QueuedConnection );
@ -202,7 +207,7 @@ void AnimationEffect::prePaintScreen( ScreenPrePaintData& data, int time )
bool invalidateLayerRect = false;
QList<AniData>::iterator anim = entry->first.begin(), animEnd = entry->first.end();
while (anim != animEnd) {
if (QTime::currentTime() < anim->startTime) {
if (anim->startTime > clock()) {
if (!anim->waitAtSource) {
++anim;
continue;
@ -347,7 +352,7 @@ void AnimationEffect::prePaintWindow( EffectWindow* w, WindowPrePaintData& data,
if ( entry != d->m_animations.constEnd() ) {
bool isUsed = false;
for (QList<AniData>::const_iterator anim = entry->first.constBegin(); anim != entry->first.constEnd(); ++anim) {
if (QTime::currentTime() < anim->startTime && !anim->waitAtSource)
if (anim->startTime > clock() && !anim->waitAtSource)
continue;
isUsed = true;
@ -392,7 +397,7 @@ void AnimationEffect::paintWindow( EffectWindow* w, int mask, QRegion region, Wi
if ( entry != d->m_animations.constEnd() ) {
for ( QList<AniData>::const_iterator anim = entry->first.constBegin(); anim != entry->first.constEnd(); ++anim ) {
if (QTime::currentTime() < anim->startTime && !anim->waitAtSource)
if (anim->startTime > clock() && !anim->waitAtSource)
continue;
switch (anim->attribute) {
@ -511,14 +516,14 @@ void AnimationEffect::postPaintScreen()
float AnimationEffect::interpolated( const AniData &a, int i ) const
{
if (QTime::currentTime() < a.startTime)
if (a.startTime > clock())
return a.from[i];
return a.from[i] + a.curve.valueForProgress( ((float)a.time)/a.duration )*(a.to[i] - a.from[i]);
}
float AnimationEffect::progress( const AniData &a ) const
{
if (QTime::currentTime() < a.startTime)
if (a.startTime > clock())
return 0.0;
return a.curve.valueForProgress( ((float)a.time)/a.duration );
}
@ -630,7 +635,7 @@ void AnimationEffect::updateLayerRepaints()
QList<QRect> rects;
QRect *layerRect = const_cast<QRect*>(&(entry->second));
for (QList<AniData>::const_iterator anim = entry->first.constBegin(), animEnd = entry->first.constEnd(); anim != animEnd; ++anim) {
if (QTime::currentTime() < anim->startTime)
if (anim->startTime > clock())
continue;
switch (anim->attribute) {
case Opacity:

View File

@ -22,6 +22,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define ANIMATION_EFFECT_H
#include <QEasingCurve>
#include <QElapsedTimer>
#include <QtCore/qmath.h>
#include <kwineffects.h>
@ -139,6 +140,10 @@ public:
return qExp(progress);
}
static inline qint64 clock() {
return s_clock.elapsed();
}
protected:
/**
* The central function of this class - call it to create an animated transition of any supported attribute
@ -177,6 +182,7 @@ private Q_SLOTS:
void _windowDeleted( KWin::EffectWindow* w );
void _expandedGeometryChanged(KWin::EffectWindow *w, const QRect &old);
private:
static QElapsedTimer s_clock;
typedef QMap< EffectWindow*, QPair<QList<AniData>, QRect> > AniMap;
AnimationEffectPrivate * const d_ptr;
Q_DECLARE_PRIVATE(AnimationEffect)