Merge branch 'master' of git.kde.org:kde-workspace
commit
7fb7f2b5e1
|
@ -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
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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()) {
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
15
events.cpp
15
events.cpp
|
@ -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);
|
||||
|
|
39
geometry.cpp
39
geometry.cpp
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue