diff --git a/effects/wobblywindows/wobblywindows.cpp b/effects/wobblywindows/wobblywindows.cpp index 6dcaeecf9..aa0d6e83e 100644 --- a/effects/wobblywindows/wobblywindows.cpp +++ b/effects/wobblywindows/wobblywindows.cpp @@ -1,1227 +1,1090 @@ /***************************************************************** KWin - the KDE window manager This file is part of the KDE project. Copyright (C) 2008 Cédric Borgese You can Freely distribute this program under the GNU General Public License. See the file "COPYING" for the exact licensing terms. ******************************************************************/ #include "wobblywindows.h" #include "wobblywindowsconfig.h" #include //#define COMPUTE_STATS // if you enable it and run kwin in a terminal from the session it manages, // be sure to redirect the output of kwin in a file or // you'll propably get deadlocks. //#define VERBOSE_MODE #if defined COMPUTE_STATS && !defined VERBOSE_MODE # ifdef __GNUC__ # warning "You enable COMPUTE_STATS without VERBOSE_MODE, computed stats will not be printed." # endif #endif namespace KWin { struct ParameterSet { qreal stiffness; qreal drag; qreal move_factor; qreal xTesselation; qreal yTesselation; qreal minVelocity; qreal maxVelocity; qreal stopVelocity; qreal minAcceleration; qreal maxAcceleration; qreal stopAcceleration; - - bool moveEffectEnabled; - bool openEffectEnabled; - bool closeEffectEnabled; }; static const ParameterSet set_0 = { 0.15, 0.80, 0.10, 20.0, 20.0, 0.0, 1000.0, 0.5, 0.0, 1000.0, 0.5, - true, - false, - false }; static const ParameterSet set_1 = { 0.10, 0.85, 0.10, 20.0, 20.0, 0.0, 1000.0, 0.5, 0.0, 1000.0, 0.5, - true, - false, - false }; static const ParameterSet set_2 = { 0.06, 0.90, 0.10, 20.0, 20.0, 0.0, 1000.0, 0.5, 0.0, 1000.0, 0.5, - true, - false, - false }; static const ParameterSet set_3 = { 0.03, 0.92, 0.20, 20.0, 20.0, 0.0, 1000.0, 0.5, 0.0, 1000.0, 0.5, - true, - false, - false }; static const ParameterSet set_4 = { 0.01, 0.97, 0.25, 20.0, 20.0, 0.0, 1000.0, 0.5, 0.0, 1000.0, 0.5, - true, - false, - false }; static const ParameterSet pset[5] = { set_0, set_1, set_2, set_3, set_4 }; WobblyWindowsEffect::WobblyWindowsEffect() { initConfig(); reconfigure(ReconfigureAll); - connect(effects, &EffectsHandler::windowAdded, this, &WobblyWindowsEffect::slotWindowAdded); - connect(effects, &EffectsHandler::windowClosed, this, &WobblyWindowsEffect::slotWindowClosed); connect(effects, &EffectsHandler::windowStartUserMovedResized, this, &WobblyWindowsEffect::slotWindowStartUserMovedResized); connect(effects, &EffectsHandler::windowStepUserMovedResized, this, &WobblyWindowsEffect::slotWindowStepUserMovedResized); connect(effects, &EffectsHandler::windowFinishUserMovedResized, this, &WobblyWindowsEffect::slotWindowFinishUserMovedResized); connect(effects, &EffectsHandler::windowMaximizedStateChanged, this, &WobblyWindowsEffect::slotWindowMaximizeStateChanged); - connect(effects, &EffectsHandler::windowDataChanged, this, &WobblyWindowsEffect::cancelWindowGrab); } WobblyWindowsEffect::~WobblyWindowsEffect() { if (!windows.empty()) { // we should be empty at this point... // emit a warning and clean the list. qCDebug(KWINEFFECTS) << "Windows list not empty. Left items : " << windows.count(); QHash< const EffectWindow*, WindowWobblyInfos >::iterator i; for (i = windows.begin(); i != windows.end(); ++i) { freeWobblyInfo(i.value()); } } } void WobblyWindowsEffect::reconfigure(ReconfigureFlags) { WobblyWindowsConfig::self()->read(); QString settingsMode = WobblyWindowsConfig::settings(); if (settingsMode != QStringLiteral("Custom")) { unsigned int wobblynessLevel = WobblyWindowsConfig::wobblynessLevel(); if (wobblynessLevel > 4) { qCDebug(KWINEFFECTS) << "Wrong value for \"WobblynessLevel\" : " << wobblynessLevel; wobblynessLevel = 4; } setParameterSet(pset[wobblynessLevel]); if (WobblyWindowsConfig::advancedMode()) { m_stiffness = WobblyWindowsConfig::stiffness() / 100.0; m_drag = WobblyWindowsConfig::drag() / 100.0; m_move_factor = WobblyWindowsConfig::moveFactor() / 100.0; } } else { // Custom method, read all values from config file. m_stiffness = WobblyWindowsConfig::stiffness() / 100.0; m_drag = WobblyWindowsConfig::drag() / 100.0; m_move_factor = WobblyWindowsConfig::moveFactor() / 100.0; m_xTesselation = WobblyWindowsConfig::xTesselation(); m_yTesselation = WobblyWindowsConfig::yTesselation(); m_minVelocity = WobblyWindowsConfig::minVelocity(); m_maxVelocity = WobblyWindowsConfig::maxVelocity(); m_stopVelocity = WobblyWindowsConfig::stopVelocity(); m_minAcceleration = WobblyWindowsConfig::minAcceleration(); m_maxAcceleration = WobblyWindowsConfig::maxAcceleration(); m_stopAcceleration = WobblyWindowsConfig::stopAcceleration(); - - m_moveEffectEnabled = WobblyWindowsConfig::moveEffect(); - m_openEffectEnabled = WobblyWindowsConfig::openEffect(); - // disable close effect by default for now as it doesn't do what I want. - m_closeEffectEnabled = WobblyWindowsConfig::closeEffect(); } m_moveWobble = WobblyWindowsConfig::moveWobble(); m_resizeWobble = WobblyWindowsConfig::resizeWobble(); #if defined VERBOSE_MODE qCDebug(KWINEFFECTS) << "Parameters :\n" << - "move : " << m_moveEffectEnabled << ", open : " << m_openEffectEnabled << ", close : " << m_closeEffectEnabled << "\n" "grid(" << m_stiffness << ", " << m_drag << ", " << m_move_factor << ")\n" << "velocity(" << m_minVelocity << ", " << m_maxVelocity << ", " << m_stopVelocity << ")\n" << "acceleration(" << m_minAcceleration << ", " << m_maxAcceleration << ", " << m_stopAcceleration << ")\n" << "tesselation(" << m_xTesselation << ", " << m_yTesselation << ")"; #endif } bool WobblyWindowsEffect::supported() { return effects->isOpenGLCompositing() && effects->animationsSupported(); } void WobblyWindowsEffect::setParameterSet(const ParameterSet& pset) { m_stiffness = pset.stiffness; m_drag = pset.drag; m_move_factor = pset.move_factor; m_xTesselation = pset.xTesselation; m_yTesselation = pset.yTesselation; m_minVelocity = pset.minVelocity; m_maxVelocity = pset.maxVelocity; m_stopVelocity = pset.stopVelocity; m_minAcceleration = pset.minAcceleration; m_maxAcceleration = pset.maxAcceleration; m_stopAcceleration = pset.stopAcceleration; - - m_moveEffectEnabled = pset.moveEffectEnabled; - m_openEffectEnabled = pset.openEffectEnabled; - m_closeEffectEnabled = pset.closeEffectEnabled; } void WobblyWindowsEffect::setVelocityThreshold(qreal m_minVelocity) { this->m_minVelocity = m_minVelocity; } void WobblyWindowsEffect::setMoveFactor(qreal factor) { m_move_factor = factor; } void WobblyWindowsEffect::setStiffness(qreal stiffness) { m_stiffness = stiffness; } void WobblyWindowsEffect::setDrag(qreal drag) { m_drag = drag; } void WobblyWindowsEffect::prePaintScreen(ScreenPrePaintData& data, int time) { // We need to mark the screen windows as transformed. Otherwise the whole // screen won't be repainted, resulting in artefacts. // Could we just set a subset of the screen to be repainted ? if (windows.count() != 0) { m_updateRegion = QRegion(); } effects->prePaintScreen(data, time); } const qreal maxTime = 10.0; void WobblyWindowsEffect::prePaintWindow(EffectWindow* w, WindowPrePaintData& data, int time) { if (windows.contains(w)) { data.setTransformed(); data.quads = data.quads.makeRegularGrid(m_xTesselation, m_yTesselation); bool stop = false; qreal updateTime = time; while (!stop && (updateTime > maxTime)) { #if defined VERBOSE_MODE qCDebug(KWINEFFECTS) << "loop time " << updateTime << " / " << time; #endif stop = !updateWindowWobblyDatas(w, maxTime); updateTime -= maxTime; } if (!stop && updateTime > 0) { updateWindowWobblyDatas(w, updateTime); } } effects->prePaintWindow(w, data, time); } void WobblyWindowsEffect::paintWindow(EffectWindow* w, int mask, QRegion region, WindowPaintData& data) { if (!(mask & PAINT_SCREEN_TRANSFORMED) && windows.contains(w)) { WindowWobblyInfos& wwi = windows[w]; int tx = w->geometry().x(); int ty = w->geometry().y(); double left = 0.0; double top = 0.0; double right = w->width(); double bottom = w->height(); for (int i = 0; i < data.quads.count(); ++i) { for (int j = 0; j < 4; ++j) { WindowVertex& v = data.quads[i][j]; Pair oldPos = {tx + v.x(), ty + v.y()}; Pair newPos = computeBezierPoint(wwi, oldPos); v.move(newPos.x - tx, newPos.y - ty); } left = qMin(left, data.quads[i].left()); top = qMin(top, data.quads[i].top()); right = qMax(right, data.quads[i].right()); bottom = qMax(bottom, data.quads[i].bottom()); } QRectF dirtyRect( left * data.xScale() + w->x() + data.xTranslation(), top * data.yScale() + w->y() + data.yTranslation(), (right - left + 1.0) * data.xScale(), (bottom - top + 1.0) * data.yScale()); // Expand the dirty region by 1px to fix potential round/floor issues. dirtyRect.adjust(-1.0, -1.0, 1.0, 1.0); m_updateRegion = m_updateRegion.united(dirtyRect.toRect()); } // Call the next effect. effects->paintWindow(w, mask, region, data); } void WobblyWindowsEffect::postPaintScreen() { if (!windows.isEmpty()) { effects->addRepaint(m_updateRegion); } // Call the next effect. effects->postPaintScreen(); } void WobblyWindowsEffect::slotWindowStartUserMovedResized(EffectWindow *w) { - if (!m_moveEffectEnabled || w->isSpecialWindow()) + if (w->isSpecialWindow()) { return; + } if ((w->isUserMove() && m_moveWobble) || (w->isUserResize() && m_resizeWobble)) { startMovedResized(w); } } void WobblyWindowsEffect::slotWindowStepUserMovedResized(EffectWindow *w, const QRect &geometry) { Q_UNUSED(geometry) if (windows.contains(w)) { WindowWobblyInfos& wwi = windows[w]; QRect rect = w->geometry(); if (rect.y() != wwi.resize_original_rect.y()) wwi.can_wobble_top = true; if (rect.x() != wwi.resize_original_rect.x()) wwi.can_wobble_left = true; if (rect.right() != wwi.resize_original_rect.right()) wwi.can_wobble_right = true; if (rect.bottom() != wwi.resize_original_rect.bottom()) wwi.can_wobble_bottom = true; } } void WobblyWindowsEffect::slotWindowFinishUserMovedResized(EffectWindow *w) { if (windows.contains(w)) { WindowWobblyInfos& wwi = windows[w]; wwi.status = Free; QRect rect = w->geometry(); if (rect.y() != wwi.resize_original_rect.y()) wwi.can_wobble_top = true; if (rect.x() != wwi.resize_original_rect.x()) wwi.can_wobble_left = true; if (rect.right() != wwi.resize_original_rect.right()) wwi.can_wobble_right = true; if (rect.bottom() != wwi.resize_original_rect.bottom()) wwi.can_wobble_bottom = true; } } void WobblyWindowsEffect::slotWindowMaximizeStateChanged(EffectWindow *w, bool horizontal, bool vertical) { Q_UNUSED(horizontal) Q_UNUSED(vertical) - if (w->isUserMove() || !m_moveEffectEnabled || w->isSpecialWindow()) + if (w->isUserMove() || w->isSpecialWindow()) { return; + } if (m_moveWobble && m_resizeWobble) { stepMovedResized(w); } if (windows.contains(w)) { WindowWobblyInfos& wwi = windows[w]; QRect rect = w->geometry(); if (rect.y() != wwi.resize_original_rect.y()) wwi.can_wobble_top = true; if (rect.x() != wwi.resize_original_rect.x()) wwi.can_wobble_left = true; if (rect.right() != wwi.resize_original_rect.right()) wwi.can_wobble_right = true; if (rect.bottom() != wwi.resize_original_rect.bottom()) wwi.can_wobble_bottom = true; } } void WobblyWindowsEffect::startMovedResized(EffectWindow* w) { if (!windows.contains(w)) { WindowWobblyInfos new_wwi; initWobblyInfo(new_wwi, w->geometry()); windows[w] = new_wwi; } WindowWobblyInfos& wwi = windows[w]; wwi.status = Moving; const QRectF& rect = w->geometry(); qreal x_increment = rect.width() / (wwi.width - 1.0); qreal y_increment = rect.height() / (wwi.height - 1.0); Pair picked = {static_cast(cursorPos().x()), static_cast(cursorPos().y())}; int indx = (picked.x - rect.x()) / x_increment + 0.5; int indy = (picked.y - rect.y()) / y_increment + 0.5; int pickedPointIndex = indy * wwi.width + indx; if (pickedPointIndex < 0) { qCDebug(KWINEFFECTS) << "Picked index == " << pickedPointIndex << " with (" << cursorPos().x() << "," << cursorPos().y() << ")"; pickedPointIndex = 0; } else if (static_cast(pickedPointIndex) > wwi.count - 1) { qCDebug(KWINEFFECTS) << "Picked index == " << pickedPointIndex << " with (" << cursorPos().x() << "," << cursorPos().y() << ")"; pickedPointIndex = wwi.count - 1; } #if defined VERBOSE_MODE qCDebug(KWINEFFECTS) << "Original Picked point -- x : " << picked.x << " - y : " << picked.y; #endif wwi.constraint[pickedPointIndex] = true; if (w->isUserResize()) { // on a resize, do not allow any edges to wobble until it has been moved from // its original location wwi.can_wobble_top = wwi.can_wobble_left = wwi.can_wobble_right = wwi.can_wobble_bottom = false; wwi.resize_original_rect = w->geometry(); } else { wwi.can_wobble_top = wwi.can_wobble_left = wwi.can_wobble_right = wwi.can_wobble_bottom = true; } } void WobblyWindowsEffect::stepMovedResized(EffectWindow* w) { QRect new_geometry = w->geometry(); if (!windows.contains(w)) { WindowWobblyInfos new_wwi; initWobblyInfo(new_wwi, new_geometry); windows[w] = new_wwi; } WindowWobblyInfos& wwi = windows[w]; wwi.status = Free; QRect maximized_area = effects->clientArea(MaximizeArea, w); bool throb_direction_out = (new_geometry.top() == maximized_area.top() && new_geometry.bottom() == maximized_area.bottom()) || (new_geometry.left() == maximized_area.left() && new_geometry.right() == maximized_area.right()); qreal magnitude = throb_direction_out ? 10 : -30; // a small throb out when maximized, a larger throb inwards when restored for (unsigned int j = 0; j < wwi.height; ++j) { for (unsigned int i = 0; i < wwi.width; ++i) { Pair v = { magnitude*(i / qreal(wwi.width - 1) - 0.5), magnitude*(j / qreal(wwi.height - 1) - 0.5) }; wwi.velocity[j*wwi.width+i] = v; } } // constrain the middle of the window, so that any asymetry wont cause it to drift off-center for (unsigned int j = 1; j < wwi.height - 1; ++j) { for (unsigned int i = 1; i < wwi.width - 1; ++i) { wwi.constraint[j*wwi.width+i] = true; } } } -void WobblyWindowsEffect::slotWindowAdded(EffectWindow* w) -{ - if (m_openEffectEnabled && w->data(WindowAddedGrabRole).value() == nullptr) { - if (windows.contains(w)) { - // could this happen ?? - WindowWobblyInfos& wwi = windows[w]; - wobblyOpenInit(wwi); - } else { - WindowWobblyInfos new_wwi; - initWobblyInfo(new_wwi, w->geometry()); - wobblyOpenInit(new_wwi); - windows[w] = new_wwi; - } - } -} - -void WobblyWindowsEffect::slotWindowClosed(EffectWindow* w) -{ - if (windows.contains(w)) { - WindowWobblyInfos& wwi = windows[w]; - if (m_closeEffectEnabled) { - wobblyCloseInit(wwi, w); - w->refWindow(); - } else { - freeWobblyInfo(wwi); - windows.remove(w); - if (windows.isEmpty()) - effects->addRepaintFull(); - } - } else if (m_closeEffectEnabled && w->data(WindowClosedGrabRole).value() == nullptr) { - WindowWobblyInfos new_wwi; - initWobblyInfo(new_wwi, w->geometry()); - wobblyCloseInit(new_wwi, w); - windows[w] = new_wwi; - w->refWindow(); - } -} - -void WobblyWindowsEffect::wobblyOpenInit(WindowWobblyInfos& wwi) const -{ - Pair middle = { (wwi.origin[0].x + wwi.origin[15].x) / 2, (wwi.origin[0].y + wwi.origin[15].y) / 2 }; - - for (unsigned int j = 0; j < 4; ++j) { - for (unsigned int i = 0; i < 4; ++i) { - unsigned int idx = j * 4 + i; - wwi.constraint[idx] = false; - wwi.position[idx].x = (wwi.position[idx].x + 3 * middle.x) / 4; - wwi.position[idx].y = (wwi.position[idx].y + 3 * middle.y) / 4; - } - } - wwi.status = Openning; - wwi.can_wobble_top = wwi.can_wobble_left = wwi.can_wobble_right = wwi.can_wobble_bottom = true; -} - -void WobblyWindowsEffect::wobblyCloseInit(WindowWobblyInfos& wwi, EffectWindow* w) const -{ - const QRectF& rect = w->geometry(); - QPointF center = rect.center(); - int x1 = (rect.x() + 3 * center.x()) / 4; - int x2 = (rect.x() + rect.width() + 3 * center.x()) / 4; - int y1 = (rect.y() + 3 * center.y()) / 4; - int y2 = (rect.y() + rect.height() + 3 * center.y()) / 4; - wwi.closeRect.setCoords(x1, y1, x2, y2); - - // for closing, not yet used... - for (unsigned int j = 0; j < 4; ++j) { - for (unsigned int i = 0; i < 4; ++i) { - unsigned int idx = j * 4 + i; - wwi.constraint[idx] = false; - } - } - wwi.status = Closing; -} - void WobblyWindowsEffect::initWobblyInfo(WindowWobblyInfos& wwi, QRect geometry) const { wwi.count = 4 * 4; wwi.width = 4; wwi.height = 4; wwi.bezierWidth = m_xTesselation; wwi.bezierHeight = m_yTesselation; wwi.bezierCount = m_xTesselation * m_yTesselation; wwi.origin = new Pair[wwi.count]; wwi.position = new Pair[wwi.count]; wwi.velocity = new Pair[wwi.count]; wwi.acceleration = new Pair[wwi.count]; wwi.buffer = new Pair[wwi.count]; wwi.constraint = new bool[wwi.count]; wwi.bezierSurface = new Pair[wwi.bezierCount]; wwi.status = Moving; qreal x = geometry.x(), y = geometry.y(); qreal width = geometry.width(), height = geometry.height(); Pair initValue = {x, y}; static const Pair nullPair = {0.0, 0.0}; qreal x_increment = width / (wwi.width - 1.0); qreal y_increment = height / (wwi.height - 1.0); for (unsigned int j = 0; j < 4; ++j) { for (unsigned int i = 0; i < 4; ++i) { unsigned int idx = j * 4 + i; wwi.origin[idx] = initValue; wwi.position[idx] = initValue; wwi.velocity[idx] = nullPair; wwi.constraint[idx] = false; if (i != 4 - 2) { // x grid count - 2, i.e. not the last point initValue.x += x_increment; } else { initValue.x = width + x; } initValue.x = initValue.x; } initValue.x = x; initValue.x = initValue.x; if (j != 4 - 2) { // y grid count - 2, i.e. not the last point initValue.y += y_increment; } else { initValue.y = height + y; } initValue.y = initValue.y; } } void WobblyWindowsEffect::freeWobblyInfo(WindowWobblyInfos& wwi) const { delete[] wwi.origin; delete[] wwi.position; delete[] wwi.velocity; delete[] wwi.acceleration; delete[] wwi.buffer; delete[] wwi.constraint; delete[] wwi.bezierSurface; } WobblyWindowsEffect::Pair WobblyWindowsEffect::computeBezierPoint(const WindowWobblyInfos& wwi, Pair point) const { // compute the input value Pair topleft = wwi.origin[0]; Pair bottomright = wwi.origin[wwi.count-1]; qreal tx = (point.x - topleft.x) / (bottomright.x - topleft.x); qreal ty = (point.y - topleft.y) / (bottomright.y - topleft.y); // compute polynomial coeff qreal px[4]; px[0] = (1 - tx) * (1 - tx) * (1 - tx); px[1] = 3 * (1 - tx) * (1 - tx) * tx; px[2] = 3 * (1 - tx) * tx * tx; px[3] = tx * tx * tx; qreal py[4]; py[0] = (1 - ty) * (1 - ty) * (1 - ty); py[1] = 3 * (1 - ty) * (1 - ty) * ty; py[2] = 3 * (1 - ty) * ty * ty; py[3] = ty * ty * ty; Pair res = {0.0, 0.0}; for (unsigned int j = 0; j < 4; ++j) { for (unsigned int i = 0; i < 4; ++i) { // this assume the grid is 4*4 res.x += px[i] * py[j] * wwi.position[i + j * wwi.width].x; res.y += px[i] * py[j] * wwi.position[i + j * wwi.width].y; } } return res; } namespace { static inline void fixVectorBounds(WobblyWindowsEffect::Pair& vec, qreal min, qreal max) { if (fabs(vec.x) < min) { vec.x = 0.0; } else if (fabs(vec.x) > max) { if (vec.x > 0.0) { vec.x = max; } else { vec.x = -max; } } if (fabs(vec.y) < min) { vec.y = 0.0; } else if (fabs(vec.y) > max) { if (vec.y > 0.0) { vec.y = max; } else { vec.y = -max; } } } #if defined COMPUTE_STATS static inline void computeVectorBounds(WobblyWindowsEffect::Pair& vec, WobblyWindowsEffect::Pair& bound) { if (fabs(vec.x) < bound.x) { bound.x = fabs(vec.x); } else if (fabs(vec.x) > bound.y) { bound.y = fabs(vec.x); } if (fabs(vec.y) < bound.x) { bound.x = fabs(vec.y); } else if (fabs(vec.y) > bound.y) { bound.y = fabs(vec.y); } } #endif } // close the anonymous namespace bool WobblyWindowsEffect::updateWindowWobblyDatas(EffectWindow* w, qreal time) { QRectF rect = w->geometry(); WindowWobblyInfos& wwi = windows[w]; - if (wwi.status == Closing) { - rect = wwi.closeRect; - } - qreal x_length = rect.width() / (wwi.width - 1.0); qreal y_length = rect.height() / (wwi.height - 1.0); #if defined VERBOSE_MODE qCDebug(KWINEFFECTS) << "time " << time; qCDebug(KWINEFFECTS) << "increment x " << x_length << " // y" << y_length; #endif Pair origine = {rect.x(), rect.y()}; for (unsigned int j = 0; j < wwi.height; ++j) { for (unsigned int i = 0; i < wwi.width; ++i) { wwi.origin[wwi.width*j + i] = origine; if (i != wwi.width - 2) { origine.x += x_length; } else { origine.x = rect.width() + rect.x(); } } origine.x = rect.x(); if (j != wwi.height - 2) { origine.y += y_length; } else { origine.y = rect.height() + rect.y(); } } Pair neibourgs[4]; Pair acceleration; qreal acc_sum = 0.0; qreal vel_sum = 0.0; // compute acceleration, velocity and position for each point // for corners // top-left if (wwi.constraint[0]) { Pair window_pos = wwi.origin[0]; Pair current_pos = wwi.position[0]; Pair move = {window_pos.x - current_pos.x, window_pos.y - current_pos.y}; Pair accel = {move.x*m_stiffness, move.y*m_stiffness}; wwi.acceleration[0] = accel; } else { Pair& pos = wwi.position[0]; neibourgs[0] = wwi.position[1]; neibourgs[1] = wwi.position[wwi.width]; acceleration.x = ((neibourgs[0].x - pos.x) - x_length) * m_stiffness + (neibourgs[1].x - pos.x) * m_stiffness; acceleration.y = ((neibourgs[1].y - pos.y) - y_length) * m_stiffness + (neibourgs[0].y - pos.y) * m_stiffness; acceleration.x /= 2; acceleration.y /= 2; wwi.acceleration[0] = acceleration; } // top-right if (wwi.constraint[wwi.width-1]) { Pair window_pos = wwi.origin[wwi.width-1]; Pair current_pos = wwi.position[wwi.width-1]; Pair move = {window_pos.x - current_pos.x, window_pos.y - current_pos.y}; Pair accel = {move.x*m_stiffness, move.y*m_stiffness}; wwi.acceleration[wwi.width-1] = accel; } else { Pair& pos = wwi.position[wwi.width-1]; neibourgs[0] = wwi.position[wwi.width-2]; neibourgs[1] = wwi.position[2*wwi.width-1]; acceleration.x = (x_length - (pos.x - neibourgs[0].x)) * m_stiffness + (neibourgs[1].x - pos.x) * m_stiffness; acceleration.y = ((neibourgs[1].y - pos.y) - y_length) * m_stiffness + (neibourgs[0].y - pos.y) * m_stiffness; acceleration.x /= 2; acceleration.y /= 2; wwi.acceleration[wwi.width-1] = acceleration; } // bottom-left if (wwi.constraint[wwi.width*(wwi.height-1)]) { Pair window_pos = wwi.origin[wwi.width*(wwi.height-1)]; Pair current_pos = wwi.position[wwi.width*(wwi.height-1)]; Pair move = {window_pos.x - current_pos.x, window_pos.y - current_pos.y}; Pair accel = {move.x*m_stiffness, move.y*m_stiffness}; wwi.acceleration[wwi.width*(wwi.height-1)] = accel; } else { Pair& pos = wwi.position[wwi.width*(wwi.height-1)]; neibourgs[0] = wwi.position[wwi.width*(wwi.height-1)+1]; neibourgs[1] = wwi.position[wwi.width*(wwi.height-2)]; acceleration.x = ((neibourgs[0].x - pos.x) - x_length) * m_stiffness + (neibourgs[1].x - pos.x) * m_stiffness; acceleration.y = (y_length - (pos.y - neibourgs[1].y)) * m_stiffness + (neibourgs[0].y - pos.y) * m_stiffness; acceleration.x /= 2; acceleration.y /= 2; wwi.acceleration[wwi.width*(wwi.height-1)] = acceleration; } // bottom-right if (wwi.constraint[wwi.count-1]) { Pair window_pos = wwi.origin[wwi.count-1]; Pair current_pos = wwi.position[wwi.count-1]; Pair move = {window_pos.x - current_pos.x, window_pos.y - current_pos.y}; Pair accel = {move.x*m_stiffness, move.y*m_stiffness}; wwi.acceleration[wwi.count-1] = accel; } else { Pair& pos = wwi.position[wwi.count-1]; neibourgs[0] = wwi.position[wwi.count-2]; neibourgs[1] = wwi.position[wwi.width*(wwi.height-1)-1]; acceleration.x = (x_length - (pos.x - neibourgs[0].x)) * m_stiffness + (neibourgs[1].x - pos.x) * m_stiffness; acceleration.y = (y_length - (pos.y - neibourgs[1].y)) * m_stiffness + (neibourgs[0].y - pos.y) * m_stiffness; acceleration.x /= 2; acceleration.y /= 2; wwi.acceleration[wwi.count-1] = acceleration; } // for borders // top border for (unsigned int i = 1; i < wwi.width - 1; ++i) { if (wwi.constraint[i]) { Pair window_pos = wwi.origin[i]; Pair current_pos = wwi.position[i]; Pair move = {window_pos.x - current_pos.x, window_pos.y - current_pos.y}; Pair accel = {move.x*m_stiffness, move.y*m_stiffness}; wwi.acceleration[i] = accel; } else { Pair& pos = wwi.position[i]; neibourgs[0] = wwi.position[i-1]; neibourgs[1] = wwi.position[i+1]; neibourgs[2] = wwi.position[i+wwi.width]; acceleration.x = (x_length - (pos.x - neibourgs[0].x)) * m_stiffness + ((neibourgs[1].x - pos.x) - x_length) * m_stiffness + (neibourgs[2].x - pos.x) * m_stiffness; acceleration.y = ((neibourgs[2].y - pos.y) - y_length) * m_stiffness + (neibourgs[0].y - pos.y) * m_stiffness + (neibourgs[1].y - pos.y) * m_stiffness; acceleration.x /= 3; acceleration.y /= 3; wwi.acceleration[i] = acceleration; } } // bottom border for (unsigned int i = wwi.width * (wwi.height - 1) + 1; i < wwi.count - 1; ++i) { if (wwi.constraint[i]) { Pair window_pos = wwi.origin[i]; Pair current_pos = wwi.position[i]; Pair move = {window_pos.x - current_pos.x, window_pos.y - current_pos.y}; Pair accel = {move.x*m_stiffness, move.y*m_stiffness}; wwi.acceleration[i] = accel; } else { Pair& pos = wwi.position[i]; neibourgs[0] = wwi.position[i-1]; neibourgs[1] = wwi.position[i+1]; neibourgs[2] = wwi.position[i-wwi.width]; acceleration.x = (x_length - (pos.x - neibourgs[0].x)) * m_stiffness + ((neibourgs[1].x - pos.x) - x_length) * m_stiffness + (neibourgs[2].x - pos.x) * m_stiffness; acceleration.y = (y_length - (pos.y - neibourgs[2].y)) * m_stiffness + (neibourgs[0].y - pos.y) * m_stiffness + (neibourgs[1].y - pos.y) * m_stiffness; acceleration.x /= 3; acceleration.y /= 3; wwi.acceleration[i] = acceleration; } } // left border for (unsigned int i = wwi.width; i < wwi.width*(wwi.height - 1); i += wwi.width) { if (wwi.constraint[i]) { Pair window_pos = wwi.origin[i]; Pair current_pos = wwi.position[i]; Pair move = {window_pos.x - current_pos.x, window_pos.y - current_pos.y}; Pair accel = {move.x*m_stiffness, move.y*m_stiffness}; wwi.acceleration[i] = accel; } else { Pair& pos = wwi.position[i]; neibourgs[0] = wwi.position[i+1]; neibourgs[1] = wwi.position[i-wwi.width]; neibourgs[2] = wwi.position[i+wwi.width]; acceleration.x = ((neibourgs[0].x - pos.x) - x_length) * m_stiffness + (neibourgs[1].x - pos.x) * m_stiffness + (neibourgs[2].x - pos.x) * m_stiffness; acceleration.y = (y_length - (pos.y - neibourgs[1].y)) * m_stiffness + ((neibourgs[2].y - pos.y) - y_length) * m_stiffness + (neibourgs[0].y - pos.y) * m_stiffness; acceleration.x /= 3; acceleration.y /= 3; wwi.acceleration[i] = acceleration; } } // right border for (unsigned int i = 2 * wwi.width - 1; i < wwi.count - 1; i += wwi.width) { if (wwi.constraint[i]) { Pair window_pos = wwi.origin[i]; Pair current_pos = wwi.position[i]; Pair move = {window_pos.x - current_pos.x, window_pos.y - current_pos.y}; Pair accel = {move.x*m_stiffness, move.y*m_stiffness}; wwi.acceleration[i] = accel; } else { Pair& pos = wwi.position[i]; neibourgs[0] = wwi.position[i-1]; neibourgs[1] = wwi.position[i-wwi.width]; neibourgs[2] = wwi.position[i+wwi.width]; acceleration.x = (x_length - (pos.x - neibourgs[0].x)) * m_stiffness + (neibourgs[1].x - pos.x) * m_stiffness + (neibourgs[2].x - pos.x) * m_stiffness; acceleration.y = (y_length - (pos.y - neibourgs[1].y)) * m_stiffness + ((neibourgs[2].y - pos.y) - y_length) * m_stiffness + (neibourgs[0].y - pos.y) * m_stiffness; acceleration.x /= 3; acceleration.y /= 3; wwi.acceleration[i] = acceleration; } } // for the inner points for (unsigned int j = 1; j < wwi.height - 1; ++j) { for (unsigned int i = 1; i < wwi.width - 1; ++i) { unsigned int index = i + j * wwi.width; if (wwi.constraint[index]) { Pair window_pos = wwi.origin[index]; Pair current_pos = wwi.position[index]; Pair move = {window_pos.x - current_pos.x, window_pos.y - current_pos.y}; Pair accel = {move.x*m_stiffness, move.y*m_stiffness}; wwi.acceleration[index] = accel; } else { Pair& pos = wwi.position[index]; neibourgs[0] = wwi.position[index-1]; neibourgs[1] = wwi.position[index+1]; neibourgs[2] = wwi.position[index-wwi.width]; neibourgs[3] = wwi.position[index+wwi.width]; acceleration.x = ((neibourgs[0].x - pos.x) - x_length) * m_stiffness + (x_length - (pos.x - neibourgs[1].x)) * m_stiffness + (neibourgs[2].x - pos.x) * m_stiffness + (neibourgs[3].x - pos.x) * m_stiffness; acceleration.y = (y_length - (pos.y - neibourgs[2].y)) * m_stiffness + ((neibourgs[3].y - pos.y) - y_length) * m_stiffness + (neibourgs[0].y - pos.y) * m_stiffness + (neibourgs[1].y - pos.y) * m_stiffness; acceleration.x /= 4; acceleration.y /= 4; wwi.acceleration[index] = acceleration; } } } heightRingLinearMean(&wwi.acceleration, wwi); #if defined COMPUTE_STATS Pair accBound = {m_maxAcceleration, m_minAcceleration}; Pair velBound = {m_maxVelocity, m_minVelocity}; #endif // compute the new velocity of each vertex. for (unsigned int i = 0; i < wwi.count; ++i) { Pair acc = wwi.acceleration[i]; fixVectorBounds(acc, m_minAcceleration, m_maxAcceleration); #if defined COMPUTE_STATS computeVectorBounds(acc, accBound); #endif Pair& vel = wwi.velocity[i]; vel.x = acc.x * time + vel.x * m_drag; vel.y = acc.y * time + vel.y * m_drag; acc_sum += fabs(acc.x) + fabs(acc.y); } heightRingLinearMean(&wwi.velocity, wwi); // compute the new pos of each vertex. for (unsigned int i = 0; i < wwi.count; ++i) { Pair& pos = wwi.position[i]; Pair& vel = wwi.velocity[i]; fixVectorBounds(vel, m_minVelocity, m_maxVelocity); #if defined COMPUTE_STATS computeVectorBounds(vel, velBound); #endif pos.x += vel.x * time * m_move_factor; pos.y += vel.y * time * m_move_factor; vel_sum += fabs(vel.x) + fabs(vel.y); #if defined VERBOSE_MODE if (wwi.constraint[i]) { qCDebug(KWINEFFECTS) << "Constraint point ** vel : " << vel.x << "," << vel.y << " ** move : " << vel.x*time << "," << vel.y*time; } #endif } if (!wwi.can_wobble_top) { for (unsigned int i = 0; i < wwi.width; ++i) for (unsigned j = 0; j < wwi.width - 1; ++j) wwi.position[i+wwi.width*j].y = wwi.origin[i+wwi.width*j].y; } if (!wwi.can_wobble_bottom) { for (unsigned int i = wwi.width * (wwi.height - 1); i < wwi.count; ++i) for (unsigned j = 0; j < wwi.width - 1; ++j) wwi.position[i-wwi.width*j].y = wwi.origin[i-wwi.width*j].y; } if (!wwi.can_wobble_left) { for (unsigned int i = 0; i < wwi.count; i += wwi.width) for (unsigned j = 0; j < wwi.width - 1; ++j) wwi.position[i+j].x = wwi.origin[i+j].x; } if (!wwi.can_wobble_right) { for (unsigned int i = wwi.width - 1; i < wwi.count; i += wwi.width) for (unsigned j = 0; j < wwi.width - 1; ++j) wwi.position[i-j].x = wwi.origin[i-j].x; } #if defined VERBOSE_MODE # if defined COMPUTE_STATS qCDebug(KWINEFFECTS) << "Acceleration bounds (" << accBound.x << ", " << accBound.y << ")"; qCDebug(KWINEFFECTS) << "Velocity bounds (" << velBound.x << ", " << velBound.y << ")"; # endif qCDebug(KWINEFFECTS) << "sum_acc : " << acc_sum << " *** sum_vel :" << vel_sum; #endif if (wwi.status != Moving && acc_sum < m_stopAcceleration && vel_sum < m_stopVelocity) { - if (wwi.status == Closing) { - w->unrefWindow(); - } freeWobblyInfo(wwi); windows.remove(w); if (windows.isEmpty()) effects->addRepaintFull(); return false; } return true; } void WobblyWindowsEffect::heightRingLinearMean(Pair** data_pointer, WindowWobblyInfos& wwi) { Pair* data = *data_pointer; Pair neibourgs[8]; // for corners // top-left { Pair& res = wwi.buffer[0]; Pair vit = data[0]; neibourgs[0] = data[1]; neibourgs[1] = data[wwi.width]; neibourgs[2] = data[wwi.width+1]; res.x = (neibourgs[0].x + neibourgs[1].x + neibourgs[2].x + 3.0 * vit.x) / 6.0; res.y = (neibourgs[0].y + neibourgs[1].y + neibourgs[2].y + 3.0 * vit.y) / 6.0; } // top-right { Pair& res = wwi.buffer[wwi.width-1]; Pair vit = data[wwi.width-1]; neibourgs[0] = data[wwi.width-2]; neibourgs[1] = data[2*wwi.width-1]; neibourgs[2] = data[2*wwi.width-2]; res.x = (neibourgs[0].x + neibourgs[1].x + neibourgs[2].x + 3.0 * vit.x) / 6.0; res.y = (neibourgs[0].y + neibourgs[1].y + neibourgs[2].y + 3.0 * vit.y) / 6.0; } // bottom-left { Pair& res = wwi.buffer[wwi.width*(wwi.height-1)]; Pair vit = data[wwi.width*(wwi.height-1)]; neibourgs[0] = data[wwi.width*(wwi.height-1)+1]; neibourgs[1] = data[wwi.width*(wwi.height-2)]; neibourgs[2] = data[wwi.width*(wwi.height-2)+1]; res.x = (neibourgs[0].x + neibourgs[1].x + neibourgs[2].x + 3.0 * vit.x) / 6.0; res.y = (neibourgs[0].y + neibourgs[1].y + neibourgs[2].y + 3.0 * vit.y) / 6.0; } // bottom-right { Pair& res = wwi.buffer[wwi.count-1]; Pair vit = data[wwi.count-1]; neibourgs[0] = data[wwi.count-2]; neibourgs[1] = data[wwi.width*(wwi.height-1)-1]; neibourgs[2] = data[wwi.width*(wwi.height-1)-2]; res.x = (neibourgs[0].x + neibourgs[1].x + neibourgs[2].x + 3.0 * vit.x) / 6.0; res.y = (neibourgs[0].y + neibourgs[1].y + neibourgs[2].y + 3.0 * vit.y) / 6.0; } // for borders // top border for (unsigned int i = 1; i < wwi.width - 1; ++i) { Pair& res = wwi.buffer[i]; Pair vit = data[i]; neibourgs[0] = data[i-1]; neibourgs[1] = data[i+1]; neibourgs[2] = data[i+wwi.width]; neibourgs[3] = data[i+wwi.width-1]; neibourgs[4] = data[i+wwi.width+1]; res.x = (neibourgs[0].x + neibourgs[1].x + neibourgs[2].x + neibourgs[3].x + neibourgs[4].x + 5.0 * vit.x) / 10.0; res.y = (neibourgs[0].y + neibourgs[1].y + neibourgs[2].y + neibourgs[3].y + neibourgs[4].y + 5.0 * vit.y) / 10.0; } // bottom border for (unsigned int i = wwi.width * (wwi.height - 1) + 1; i < wwi.count - 1; ++i) { Pair& res = wwi.buffer[i]; Pair vit = data[i]; neibourgs[0] = data[i-1]; neibourgs[1] = data[i+1]; neibourgs[2] = data[i-wwi.width]; neibourgs[3] = data[i-wwi.width-1]; neibourgs[4] = data[i-wwi.width+1]; res.x = (neibourgs[0].x + neibourgs[1].x + neibourgs[2].x + neibourgs[3].x + neibourgs[4].x + 5.0 * vit.x) / 10.0; res.y = (neibourgs[0].y + neibourgs[1].y + neibourgs[2].y + neibourgs[3].y + neibourgs[4].y + 5.0 * vit.y) / 10.0; } // left border for (unsigned int i = wwi.width; i < wwi.width*(wwi.height - 1); i += wwi.width) { Pair& res = wwi.buffer[i]; Pair vit = data[i]; neibourgs[0] = data[i+1]; neibourgs[1] = data[i-wwi.width]; neibourgs[2] = data[i+wwi.width]; neibourgs[3] = data[i-wwi.width+1]; neibourgs[4] = data[i+wwi.width+1]; res.x = (neibourgs[0].x + neibourgs[1].x + neibourgs[2].x + neibourgs[3].x + neibourgs[4].x + 5.0 * vit.x) / 10.0; res.y = (neibourgs[0].y + neibourgs[1].y + neibourgs[2].y + neibourgs[3].y + neibourgs[4].y + 5.0 * vit.y) / 10.0; } // right border for (unsigned int i = 2 * wwi.width - 1; i < wwi.count - 1; i += wwi.width) { Pair& res = wwi.buffer[i]; Pair vit = data[i]; neibourgs[0] = data[i-1]; neibourgs[1] = data[i-wwi.width]; neibourgs[2] = data[i+wwi.width]; neibourgs[3] = data[i-wwi.width-1]; neibourgs[4] = data[i+wwi.width-1]; res.x = (neibourgs[0].x + neibourgs[1].x + neibourgs[2].x + neibourgs[3].x + neibourgs[4].x + 5.0 * vit.x) / 10.0; res.y = (neibourgs[0].y + neibourgs[1].y + neibourgs[2].y + neibourgs[3].y + neibourgs[4].y + 5.0 * vit.y) / 10.0; } // for the inner points for (unsigned int j = 1; j < wwi.height - 1; ++j) { for (unsigned int i = 1; i < wwi.width - 1; ++i) { unsigned int index = i + j * wwi.width; Pair& res = wwi.buffer[index]; Pair& vit = data[index]; neibourgs[0] = data[index-1]; neibourgs[1] = data[index+1]; neibourgs[2] = data[index-wwi.width]; neibourgs[3] = data[index+wwi.width]; neibourgs[4] = data[index-wwi.width-1]; neibourgs[5] = data[index-wwi.width+1]; neibourgs[6] = data[index+wwi.width-1]; neibourgs[7] = data[index+wwi.width+1]; res.x = (neibourgs[0].x + neibourgs[1].x + neibourgs[2].x + neibourgs[3].x + neibourgs[4].x + neibourgs[5].x + neibourgs[6].x + neibourgs[7].x + 8.0 * vit.x) / 16.0; res.y = (neibourgs[0].y + neibourgs[1].y + neibourgs[2].y + neibourgs[3].y + neibourgs[4].y + neibourgs[5].y + neibourgs[6].y + neibourgs[7].y + 8.0 * vit.y) / 16.0; } } Pair* tmp = data; *data_pointer = wwi.buffer; wwi.buffer = tmp; } - -void WobblyWindowsEffect::cancelWindowGrab(KWin::EffectWindow *w, int grabRole) -{ - if (grabRole == WindowAddedGrabRole) { - if (w->data(WindowAddedGrabRole).value() != this) { - auto it = windows.find(w); - if (it != windows.end()) { - freeWobblyInfo(it.value()); - windows.erase(it); - } - } - } else if (grabRole == WindowClosedGrabRole) { - if (w->data(WindowClosedGrabRole).value() != this) { - auto it = windows.find(w); - if (it != windows.end()) { - if (it.value().status == Closing) { - w->unrefWindow(); - } - freeWobblyInfo(it.value()); - windows.erase(it); - } - } - } -} - bool WobblyWindowsEffect::isActive() const { return !windows.isEmpty(); } } // namespace KWin - diff --git a/effects/wobblywindows/wobblywindows.h b/effects/wobblywindows/wobblywindows.h index b9c58a31b..b4465bdd5 100644 --- a/effects/wobblywindows/wobblywindows.h +++ b/effects/wobblywindows/wobblywindows.h @@ -1,219 +1,193 @@ /***************************************************************** KWin - the KDE window manager This file is part of the KDE project. Copyright (C) 2008 Cédric Borgese You can Freely distribute this program under the GNU General Public License. See the file "COPYING" for the exact licensing terms. ******************************************************************/ #ifndef KWIN_WOBBLYWINDOWS_H #define KWIN_WOBBLYWINDOWS_H // Include with base class for effects. #include namespace KWin { struct ParameterSet; /** * Effect which wobble windows */ class WobblyWindowsEffect : public Effect { Q_OBJECT Q_PROPERTY(qreal stiffness READ stiffness) Q_PROPERTY(qreal drag READ drag) Q_PROPERTY(qreal moveFactor READ moveFactor) Q_PROPERTY(qreal xTesselation READ xTesselation) Q_PROPERTY(qreal yTesselation READ yTesselation) Q_PROPERTY(qreal minVelocity READ minVelocity) Q_PROPERTY(qreal maxVelocity READ maxVelocity) Q_PROPERTY(qreal stopVelocity READ stopVelocity) Q_PROPERTY(qreal minAcceleration READ minAcceleration) Q_PROPERTY(qreal maxAcceleration READ maxAcceleration) Q_PROPERTY(qreal stopAcceleration READ stopAcceleration) - Q_PROPERTY(bool moveEffectEnabled READ isMoveEffectEnabled) - Q_PROPERTY(bool openEffectEnabled READ isOpenEffectEnabled) - Q_PROPERTY(bool closeEffectEnabled READ isCloseEffectEnabled) Q_PROPERTY(bool moveWobble READ isMoveWobble) Q_PROPERTY(bool resizeWobble READ isResizeWobble) public: WobblyWindowsEffect(); ~WobblyWindowsEffect() override; void reconfigure(ReconfigureFlags) override; void prePaintScreen(ScreenPrePaintData& data, int time) override; void prePaintWindow(EffectWindow* w, WindowPrePaintData& data, int time) override; void paintWindow(EffectWindow* w, int mask, QRegion region, WindowPaintData& data) override; void postPaintScreen() override; bool isActive() const override; int requestedEffectChainPosition() const override { // Please notice that the Wobbly Windows effect has to be placed // after the Maximize effect in the effect chain, otherwise there // can be visual artifacts when dragging maximized windows. return 70; } // Wobbly model parameters void setStiffness(qreal stiffness); void setDrag(qreal drag); void setVelocityThreshold(qreal velocityThreshold); void setMoveFactor(qreal factor); struct Pair { qreal x; qreal y; }; enum WindowStatus { Free, Moving, - Openning, - Closing }; static bool supported(); // for properties qreal stiffness() const { return m_stiffness; } qreal drag() const { return m_drag; } qreal moveFactor() const { return m_move_factor; } qreal xTesselation() const { return m_xTesselation; } qreal yTesselation() const { return m_yTesselation; } qreal minVelocity() const { return m_minVelocity; } qreal maxVelocity() const { return m_maxVelocity; } qreal stopVelocity() const { return m_stopVelocity; } qreal minAcceleration() const { return m_minAcceleration; } qreal maxAcceleration() const { return m_maxAcceleration; } qreal stopAcceleration() const { return m_stopAcceleration; } - bool isMoveEffectEnabled() const { - return m_moveEffectEnabled; - } - bool isOpenEffectEnabled() const { - return m_openEffectEnabled; - } - bool isCloseEffectEnabled() const { - return m_closeEffectEnabled; - } bool isMoveWobble() const { return m_moveWobble; } bool isResizeWobble() const { return m_resizeWobble; } + public Q_SLOTS: - void slotWindowAdded(KWin::EffectWindow *w); - void slotWindowClosed(KWin::EffectWindow *w); void slotWindowStartUserMovedResized(KWin::EffectWindow *w); void slotWindowStepUserMovedResized(KWin::EffectWindow *w, const QRect &geometry); void slotWindowFinishUserMovedResized(KWin::EffectWindow *w); void slotWindowMaximizeStateChanged(KWin::EffectWindow *w, bool horizontal, bool vertical); private: - - void cancelWindowGrab(KWin::EffectWindow *w, int grabRole); void startMovedResized(EffectWindow* w); void stepMovedResized(EffectWindow* w); bool updateWindowWobblyDatas(EffectWindow* w, qreal time); struct WindowWobblyInfos { Pair* origin; Pair* position; Pair* velocity; Pair* acceleration; Pair* buffer; // if true, the physics system moves this point based only on it "normal" destination // given by the window position, ignoring neighbour points. bool* constraint; unsigned int width; unsigned int height; unsigned int count; Pair* bezierSurface; unsigned int bezierWidth; unsigned int bezierHeight; unsigned int bezierCount; WindowStatus status; - // for closing - QRectF closeRect; - // for resizing. Only sides that have moved will wobble bool can_wobble_top, can_wobble_left, can_wobble_right, can_wobble_bottom; QRect resize_original_rect; }; QHash< const EffectWindow*, WindowWobblyInfos > windows; QRegion m_updateRegion; qreal m_stiffness; qreal m_drag; qreal m_move_factor; // the default tesselation for windows // use qreal instead of int as I really often need // these values as real to do divisions. qreal m_xTesselation; qreal m_yTesselation; qreal m_minVelocity; qreal m_maxVelocity; qreal m_stopVelocity; qreal m_minAcceleration; qreal m_maxAcceleration; qreal m_stopAcceleration; - bool m_moveEffectEnabled; - bool m_openEffectEnabled; - bool m_closeEffectEnabled; - - bool m_moveWobble; // Expands m_moveEffectEnabled + bool m_moveWobble; bool m_resizeWobble; void initWobblyInfo(WindowWobblyInfos& wwi, QRect geometry) const; void freeWobblyInfo(WindowWobblyInfos& wwi) const; - void wobblyOpenInit(WindowWobblyInfos& wwi) const; - void wobblyCloseInit(WindowWobblyInfos& wwi, EffectWindow* w) const; WobblyWindowsEffect::Pair computeBezierPoint(const WindowWobblyInfos& wwi, Pair point) const; static void heightRingLinearMean(Pair** data_pointer, WindowWobblyInfos& wwi); void setParameterSet(const ParameterSet& pset); }; } // namespace KWin #endif // WOBBLYWINDOWS_H diff --git a/effects/wobblywindows/wobblywindows.kcfg b/effects/wobblywindows/wobblywindows.kcfg index 1212fb657..cacab17cc 100644 --- a/effects/wobblywindows/wobblywindows.kcfg +++ b/effects/wobblywindows/wobblywindows.kcfg @@ -1,66 +1,57 @@ 0 Auto true true false 15 80 10 20 20 0.0 1000.0 0.5 0.0 1000.0 5.0 - - true - - - false - - - false -