12#include "wobblywindowsconfig.h"
23#if defined COMPUTE_STATS && !defined VERBOSE_MODE
25#warning "You enable COMPUTE_STATS without VERBOSE_MODE, computed stats will not be printed."
29Q_LOGGING_CATEGORY(KWIN_WOBBLYWINDOWS,
"kwin_effect_wobblywindows", QtWarningMsg)
65static const ParameterSet set_1 = {
79static const ParameterSet set_2 = {
93static const ParameterSet set_3 = {
107static const ParameterSet set_4 = {
121static const ParameterSet pset[5] = {set_0, set_1, set_2, set_3, set_4};
137 if (!windows.empty()) {
139 qCDebug(KWIN_WOBBLYWINDOWS) <<
"Windows list not empty. Left items : " << windows.count();
145 WobblyWindowsConfig::self()->read();
147 QString settingsMode = WobblyWindowsConfig::settings();
148 if (settingsMode != QStringLiteral(
"Custom")) {
149 unsigned int wobblynessLevel = WobblyWindowsConfig::wobblynessLevel();
150 if (wobblynessLevel > 4) {
151 qCDebug(KWIN_WOBBLYWINDOWS) <<
"Wrong value for \"WobblynessLevel\" : " << wobblynessLevel;
154 setParameterSet(pset[wobblynessLevel]);
156 if (WobblyWindowsConfig::advancedMode()) {
157 m_stiffness = WobblyWindowsConfig::stiffness() / 100.0;
158 m_drag = WobblyWindowsConfig::drag() / 100.0;
159 m_move_factor = WobblyWindowsConfig::moveFactor() / 100.0;
162 m_stiffness = WobblyWindowsConfig::stiffness() / 100.0;
163 m_drag = WobblyWindowsConfig::drag() / 100.0;
164 m_move_factor = WobblyWindowsConfig::moveFactor() / 100.0;
166 m_xTesselation = WobblyWindowsConfig::xTesselation();
167 m_yTesselation = WobblyWindowsConfig::yTesselation();
169 m_minVelocity = WobblyWindowsConfig::minVelocity();
170 m_maxVelocity = WobblyWindowsConfig::maxVelocity();
171 m_stopVelocity = WobblyWindowsConfig::stopVelocity();
172 m_minAcceleration = WobblyWindowsConfig::minAcceleration();
173 m_maxAcceleration = WobblyWindowsConfig::maxAcceleration();
174 m_stopAcceleration = WobblyWindowsConfig::stopAcceleration();
177 m_moveWobble = WobblyWindowsConfig::moveWobble();
178 m_resizeWobble = WobblyWindowsConfig::resizeWobble();
180#if defined VERBOSE_MODE
181 qCDebug(KWIN_WOBBLYWINDOWS) <<
"Parameters :\n"
182 <<
"grid(" << m_stiffness <<
", " << m_drag <<
", " << m_move_factor <<
")\n"
183 <<
"velocity(" << m_minVelocity <<
", " << m_maxVelocity <<
", " << m_stopVelocity <<
")\n"
184 <<
"acceleration(" << m_minAcceleration <<
", " << m_maxAcceleration <<
", " << m_stopAcceleration <<
")\n"
185 <<
"tesselation(" << m_xTesselation <<
", " << m_yTesselation <<
")";
194void WobblyWindowsEffect::setParameterSet(
const ParameterSet &pset)
213 this->m_minVelocity = m_minVelocity;
218 m_move_factor = factor;
236static const std::chrono::milliseconds integrationStep(10);
240 auto infoIt = windows.find(w);
241 if (infoIt != windows.end()) {
244 while ((presentTime - infoIt->clock).count() > 0) {
245 const auto delta = std::min(presentTime - infoIt->clock, integrationStep);
246 infoIt->clock += delta;
248 if (!updateWindowWobblyDatas(w, delta.count())) {
260 WindowWobblyInfos &wwi = windows[w];
261 if (!wwi.wobblying) {
271 double right = w->
width();
272 double bottom = w->
height();
275 for (
int i = 0; i < quads.count(); ++i) {
276 for (
int j = 0; j < 4; ++j) {
278 Pair uv = {v.
x() / width, v.
y() / height};
279 Pair newPos = computeBezierPoint(wwi, uv);
280 v.
move(newPos.
x - tx, newPos.
y - ty);
282 left = std::min(left, quads[i].left());
283 top = std::min(top, quads[i].top());
284 right = std::max(right, quads[i].right());
285 bottom = std::max(bottom, quads[i].bottom());
290 (right - left + 1.0) * data.
xScale(),
291 (bottom - top + 1.0) * data.
yScale());
293 dirtyRect.adjust(-1.0, -1.0, 1.0, 1.0);
294 m_updateRegion = m_updateRegion.united(dirtyRect.toRect());
300 if (!m_updateRegion.isEmpty()) {
302 m_updateRegion = QRegion();
324 startMovedResized(w);
330 if (windows.contains(w)) {
331 WindowWobblyInfos &wwi = windows[w];
333 if (rect.y() != wwi.resize_original_rect.y()) {
334 wwi.can_wobble_top =
true;
336 if (rect.x() != wwi.resize_original_rect.x()) {
337 wwi.can_wobble_left =
true;
339 if (rect.right() != wwi.resize_original_rect.right()) {
340 wwi.can_wobble_right =
true;
342 if (rect.bottom() != wwi.resize_original_rect.bottom()) {
343 wwi.can_wobble_bottom =
true;
351 if (windows.contains(w)) {
352 WindowWobblyInfos &wwi = windows[w];
355 if (rect.y() != wwi.resize_original_rect.y()) {
356 wwi.can_wobble_top =
true;
358 if (rect.x() != wwi.resize_original_rect.x()) {
359 wwi.can_wobble_left =
true;
361 if (rect.right() != wwi.resize_original_rect.right()) {
362 wwi.can_wobble_right =
true;
364 if (rect.bottom() != wwi.resize_original_rect.bottom()) {
365 wwi.can_wobble_bottom =
true;
376 if (m_moveWobble && m_resizeWobble) {
380 if (windows.contains(w)) {
381 WindowWobblyInfos &wwi = windows[w];
383 if (rect.y() != wwi.resize_original_rect.y()) {
384 wwi.can_wobble_top =
true;
386 if (rect.x() != wwi.resize_original_rect.x()) {
387 wwi.can_wobble_left =
true;
389 if (rect.right() != wwi.resize_original_rect.right()) {
390 wwi.can_wobble_right =
true;
392 if (rect.bottom() != wwi.resize_original_rect.bottom()) {
393 wwi.can_wobble_bottom =
true;
398void WobblyWindowsEffect::startMovedResized(
EffectWindow *w)
400 if (!windows.contains(w)) {
401 WindowWobblyInfos new_wwi;
403 windows[w] = new_wwi;
407 WindowWobblyInfos &wwi = windows[w];
411 qreal x_increment = rect.width() / (wwi.width - 1.0);
412 qreal y_increment = rect.height() / (wwi.height - 1.0);
414 Pair picked = {
static_cast<qreal
>(
cursorPos().x()),
static_cast<qreal
>(
cursorPos().y())};
415 int indx = (picked.x - rect.x()) / x_increment + 0.5;
416 int indy = (picked.y - rect.y()) / y_increment + 0.5;
417 int pickedPointIndex = indy * wwi.width + indx;
418 if (pickedPointIndex < 0) {
419 qCDebug(KWIN_WOBBLYWINDOWS) <<
"Picked index == " << pickedPointIndex <<
" with (" <<
cursorPos().x() <<
"," <<
cursorPos().y() <<
")";
420 pickedPointIndex = 0;
421 }
else if (
static_cast<unsigned int>(pickedPointIndex) > wwi.count - 1) {
422 qCDebug(KWIN_WOBBLYWINDOWS) <<
"Picked index == " << pickedPointIndex <<
" with (" <<
cursorPos().x() <<
"," <<
cursorPos().y() <<
")";
423 pickedPointIndex = wwi.count - 1;
425#if defined VERBOSE_MODE
426 qCDebug(KWIN_WOBBLYWINDOWS) <<
"Original Picked point -- x : " << picked.x <<
" - y : " << picked.y;
428 wwi.constraint[pickedPointIndex] =
true;
433 wwi.can_wobble_top = wwi.can_wobble_left = wwi.can_wobble_right = wwi.can_wobble_bottom =
false;
436 wwi.can_wobble_top = wwi.can_wobble_left = wwi.can_wobble_right = wwi.can_wobble_bottom =
true;
440void WobblyWindowsEffect::stepMovedResized(EffectWindow *w)
442 QRectF new_geometry = w->frameGeometry();
443 if (!windows.contains(w)) {
444 WindowWobblyInfos new_wwi;
445 initWobblyInfo(new_wwi, new_geometry);
446 windows[w] = new_wwi;
449 WindowWobblyInfos &wwi = windows[w];
453 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());
454 qreal magnitude = throb_direction_out ? 10 : -30;
455 for (
unsigned int j = 0; j < wwi.height; ++j) {
456 for (
unsigned int i = 0; i < wwi.width; ++i) {
457 Pair v = {magnitude * (i / qreal(wwi.width - 1) - 0.5), magnitude * (j / qreal(wwi.height - 1) - 0.5)};
458 wwi.velocity[j * wwi.width + i] = v;
463 for (
unsigned int j = 1; j < wwi.height - 1; ++j) {
464 for (
unsigned int i = 1; i < wwi.width - 1; ++i) {
465 wwi.constraint[j * wwi.width + i] =
true;
470void WobblyWindowsEffect::initWobblyInfo(WindowWobblyInfos &wwi, QRectF geometry)
const
476 wwi.bezierWidth = m_xTesselation;
477 wwi.bezierHeight = m_yTesselation;
478 wwi.bezierCount = m_xTesselation * m_yTesselation;
480 wwi.origin.resize(wwi.count);
481 wwi.position.resize(wwi.count);
482 wwi.velocity.resize(wwi.count);
483 wwi.acceleration.resize(wwi.count);
484 wwi.buffer.resize(wwi.count);
485 wwi.constraint.resize(wwi.count);
487 wwi.bezierSurface.resize(wwi.bezierCount);
490 wwi.clock = std::chrono::duration_cast<std::chrono::milliseconds>(
491 std::chrono::steady_clock::now().time_since_epoch());
493 qreal x = geometry.x(), y = geometry.y();
494 qreal width = geometry.width(), height = geometry.height();
496 Pair initValue = {x, y};
497 static const Pair nullPair = {0.0, 0.0};
499 qreal x_increment = width / (wwi.width - 1.0);
500 qreal y_increment = height / (wwi.height - 1.0);
502 for (
unsigned int j = 0; j < 4; ++j) {
503 for (
unsigned int i = 0; i < 4; ++i) {
504 unsigned int idx = j * 4 + i;
505 wwi.origin[idx] = initValue;
506 wwi.position[idx] = initValue;
507 wwi.velocity[idx] = nullPair;
508 wwi.constraint[idx] =
false;
510 initValue.x += x_increment;
512 initValue.x = width + x;
514 initValue.x = initValue.x;
517 initValue.x = initValue.x;
519 initValue.y += y_increment;
521 initValue.y = height + y;
523 initValue.y = initValue.y;
527WobblyWindowsEffect::Pair WobblyWindowsEffect::computeBezierPoint(
const WindowWobblyInfos &wwi, Pair point)
const
529 const qreal tx = point.x;
530 const qreal ty = point.y;
535 px[0] = (1 - tx) * (1 - tx) * (1 - tx);
536 px[1] = 3 * (1 - tx) * (1 - tx) * tx;
537 px[2] = 3 * (1 - tx) * tx * tx;
538 px[3] = tx * tx * tx;
541 py[0] = (1 - ty) * (1 - ty) * (1 - ty);
542 py[1] = 3 * (1 - ty) * (1 - ty) * ty;
543 py[2] = 3 * (1 - ty) * ty * ty;
544 py[3] = ty * ty * ty;
546 Pair res = {0.0, 0.0};
548 for (
unsigned int j = 0; j < 4; ++j) {
549 for (
unsigned int i = 0; i < 4; ++i) {
551 res.x += px[i] * py[j] * wwi.position[i + j * wwi.width].x;
552 res.y += px[i] * py[j] * wwi.position[i + j * wwi.width].y;
562static inline void fixVectorBounds(WobblyWindowsEffect::Pair &vec, qreal min, qreal max)
564 if (fabs(vec.x) < min) {
566 }
else if (fabs(vec.x) > max) {
574 if (fabs(vec.y) < min) {
576 }
else if (fabs(vec.y) > max) {
585#if defined COMPUTE_STATS
586static inline void computeVectorBounds(WobblyWindowsEffect::Pair &vec, WobblyWindowsEffect::Pair &bound)
588 if (fabs(vec.x) < bound.x) {
589 bound.x = fabs(vec.x);
590 }
else if (fabs(vec.x) > bound.y) {
591 bound.y = fabs(vec.x);
593 if (fabs(vec.y) < bound.x) {
594 bound.x = fabs(vec.y);
595 }
else if (fabs(vec.y) > bound.y) {
596 bound.y = fabs(vec.y);
603bool WobblyWindowsEffect::updateWindowWobblyDatas(EffectWindow *w, qreal time)
605 QRectF rect = w->frameGeometry();
606 WindowWobblyInfos &wwi = windows[w];
608 qreal x_length = rect.width() / (wwi.width - 1.0);
609 qreal y_length = rect.height() / (wwi.height - 1.0);
611#if defined VERBOSE_MODE
612 qCDebug(KWIN_WOBBLYWINDOWS) <<
"time " << time;
613 qCDebug(KWIN_WOBBLYWINDOWS) <<
"increment x " << x_length <<
" // y" << y_length;
616 Pair origine = {rect.x(), rect.y()};
618 for (
unsigned int j = 0; j < wwi.height; ++j) {
619 for (
unsigned int i = 0; i < wwi.width; ++i) {
620 wwi.origin[wwi.width * j + i] = origine;
621 if (i != wwi.width - 2) {
622 origine.x += x_length;
624 origine.x = rect.width() + rect.x();
627 origine.x = rect.x();
628 if (j != wwi.height - 2) {
629 origine.y += y_length;
631 origine.y = rect.height() + rect.y();
647 if (wwi.constraint[0]) {
648 Pair window_pos = wwi.origin[0];
649 Pair current_pos = wwi.position[0];
650 Pair move = {window_pos.x - current_pos.x, window_pos.y - current_pos.y};
651 Pair accel = {move.x * m_stiffness, move.y * m_stiffness};
652 wwi.acceleration[0] = accel;
654 Pair &pos = wwi.position[0];
655 neibourgs[0] = wwi.position[1];
656 neibourgs[1] = wwi.position[wwi.width];
658 acceleration.x = ((neibourgs[0].x - pos.x) - x_length) * m_stiffness + (neibourgs[1].x - pos.x) * m_stiffness;
659 acceleration.y = ((neibourgs[1].y - pos.y) - y_length) * m_stiffness + (neibourgs[0].y - pos.y) * m_stiffness;
664 wwi.acceleration[0] = acceleration;
669 if (wwi.constraint[wwi.width - 1]) {
670 Pair window_pos = wwi.origin[wwi.width - 1];
671 Pair current_pos = wwi.position[wwi.width - 1];
672 Pair move = {window_pos.x - current_pos.x, window_pos.y - current_pos.y};
673 Pair accel = {move.x * m_stiffness, move.y * m_stiffness};
674 wwi.acceleration[wwi.width - 1] = accel;
676 Pair &pos = wwi.position[wwi.width - 1];
677 neibourgs[0] = wwi.position[wwi.width - 2];
678 neibourgs[1] = wwi.position[2 * wwi.width - 1];
680 acceleration.x = (x_length - (pos.x - neibourgs[0].x)) * m_stiffness + (neibourgs[1].x - pos.x) * m_stiffness;
681 acceleration.y = ((neibourgs[1].y - pos.y) - y_length) * m_stiffness + (neibourgs[0].y - pos.y) * m_stiffness;
686 wwi.acceleration[wwi.width - 1] = acceleration;
691 if (wwi.constraint[wwi.width * (wwi.height - 1)]) {
692 Pair window_pos = wwi.origin[wwi.width * (wwi.height - 1)];
693 Pair current_pos = wwi.position[wwi.width * (wwi.height - 1)];
694 Pair move = {window_pos.x - current_pos.x, window_pos.y - current_pos.y};
695 Pair accel = {move.x * m_stiffness, move.y * m_stiffness};
696 wwi.acceleration[wwi.width * (wwi.height - 1)] = accel;
698 Pair &pos = wwi.position[wwi.width * (wwi.height - 1)];
699 neibourgs[0] = wwi.position[wwi.width * (wwi.height - 1) + 1];
700 neibourgs[1] = wwi.position[wwi.width * (wwi.height - 2)];
702 acceleration.x = ((neibourgs[0].x - pos.x) - x_length) * m_stiffness + (neibourgs[1].x - pos.x) * m_stiffness;
703 acceleration.y = (y_length - (pos.y - neibourgs[1].y)) * m_stiffness + (neibourgs[0].y - pos.y) * m_stiffness;
708 wwi.acceleration[wwi.width * (wwi.height - 1)] = acceleration;
713 if (wwi.constraint[wwi.count - 1]) {
714 Pair window_pos = wwi.origin[wwi.count - 1];
715 Pair current_pos = wwi.position[wwi.count - 1];
716 Pair move = {window_pos.x - current_pos.x, window_pos.y - current_pos.y};
717 Pair accel = {move.x * m_stiffness, move.y * m_stiffness};
718 wwi.acceleration[wwi.count - 1] = accel;
720 Pair &pos = wwi.position[wwi.count - 1];
721 neibourgs[0] = wwi.position[wwi.count - 2];
722 neibourgs[1] = wwi.position[wwi.width * (wwi.height - 1) - 1];
724 acceleration.x = (x_length - (pos.x - neibourgs[0].x)) * m_stiffness + (neibourgs[1].x - pos.x) * m_stiffness;
725 acceleration.y = (y_length - (pos.y - neibourgs[1].y)) * m_stiffness + (neibourgs[0].y - pos.y) * m_stiffness;
730 wwi.acceleration[wwi.count - 1] = acceleration;
736 for (
unsigned int i = 1; i < wwi.width - 1; ++i) {
737 if (wwi.constraint[i]) {
738 Pair window_pos = wwi.origin[i];
739 Pair current_pos = wwi.position[i];
740 Pair move = {window_pos.x - current_pos.x, window_pos.y - current_pos.y};
741 Pair accel = {move.x * m_stiffness, move.y * m_stiffness};
742 wwi.acceleration[i] = accel;
744 Pair &pos = wwi.position[i];
745 neibourgs[0] = wwi.position[i - 1];
746 neibourgs[1] = wwi.position[i + 1];
747 neibourgs[2] = wwi.position[i + wwi.width];
749 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;
750 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;
755 wwi.acceleration[i] = acceleration;
760 for (
unsigned int i = wwi.width * (wwi.height - 1) + 1; i < wwi.count - 1; ++i) {
761 if (wwi.constraint[i]) {
762 Pair window_pos = wwi.origin[i];
763 Pair current_pos = wwi.position[i];
764 Pair move = {window_pos.x - current_pos.x, window_pos.y - current_pos.y};
765 Pair accel = {move.x * m_stiffness, move.y * m_stiffness};
766 wwi.acceleration[i] = accel;
768 Pair &pos = wwi.position[i];
769 neibourgs[0] = wwi.position[i - 1];
770 neibourgs[1] = wwi.position[i + 1];
771 neibourgs[2] = wwi.position[i - wwi.width];
773 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;
774 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;
779 wwi.acceleration[i] = acceleration;
784 for (
unsigned int i = wwi.width; i < wwi.width * (wwi.height - 1); i += wwi.width) {
785 if (wwi.constraint[i]) {
786 Pair window_pos = wwi.origin[i];
787 Pair current_pos = wwi.position[i];
788 Pair move = {window_pos.x - current_pos.x, window_pos.y - current_pos.y};
789 Pair accel = {move.x * m_stiffness, move.y * m_stiffness};
790 wwi.acceleration[i] = accel;
792 Pair &pos = wwi.position[i];
793 neibourgs[0] = wwi.position[i + 1];
794 neibourgs[1] = wwi.position[i - wwi.width];
795 neibourgs[2] = wwi.position[i + wwi.width];
797 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;
798 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;
803 wwi.acceleration[i] = acceleration;
808 for (
unsigned int i = 2 * wwi.width - 1; i < wwi.count - 1; i += wwi.width) {
809 if (wwi.constraint[i]) {
810 Pair window_pos = wwi.origin[i];
811 Pair current_pos = wwi.position[i];
812 Pair move = {window_pos.x - current_pos.x, window_pos.y - current_pos.y};
813 Pair accel = {move.x * m_stiffness, move.y * m_stiffness};
814 wwi.acceleration[i] = accel;
816 Pair &pos = wwi.position[i];
817 neibourgs[0] = wwi.position[i - 1];
818 neibourgs[1] = wwi.position[i - wwi.width];
819 neibourgs[2] = wwi.position[i + wwi.width];
821 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;
822 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;
827 wwi.acceleration[i] = acceleration;
832 for (
unsigned int j = 1; j < wwi.height - 1; ++j) {
833 for (
unsigned int i = 1; i < wwi.width - 1; ++i) {
834 unsigned int index = i + j * wwi.width;
836 if (wwi.constraint[index]) {
837 Pair window_pos = wwi.origin[index];
838 Pair current_pos = wwi.position[index];
839 Pair move = {window_pos.x - current_pos.x, window_pos.y - current_pos.y};
840 Pair accel = {move.x * m_stiffness, move.y * m_stiffness};
841 wwi.acceleration[index] = accel;
843 Pair &pos = wwi.position[index];
844 neibourgs[0] = wwi.position[index - 1];
845 neibourgs[1] = wwi.position[index + 1];
846 neibourgs[2] = wwi.position[index - wwi.width];
847 neibourgs[3] = wwi.position[index + wwi.width];
849 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;
850 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;
855 wwi.acceleration[index] = acceleration;
860 heightRingLinearMean(wwi.acceleration, wwi);
862#if defined COMPUTE_STATS
863 Pair accBound = {m_maxAcceleration, m_minAcceleration};
864 Pair velBound = {m_maxVelocity, m_minVelocity};
868 for (
unsigned int i = 0; i < wwi.count; ++i) {
869 Pair acc = wwi.acceleration[i];
870 fixVectorBounds(acc, m_minAcceleration, m_maxAcceleration);
872#if defined COMPUTE_STATS
873 computeVectorBounds(acc, accBound);
876 Pair &vel = wwi.velocity[i];
877 vel.x = acc.x * time + vel.x * m_drag;
878 vel.y = acc.y * time + vel.y * m_drag;
880 acc_sum += fabs(acc.x) + fabs(acc.y);
883 heightRingLinearMean(wwi.velocity, wwi);
886 for (
unsigned int i = 0; i < wwi.count; ++i) {
887 Pair &pos = wwi.position[i];
888 Pair &vel = wwi.velocity[i];
890 fixVectorBounds(vel, m_minVelocity, m_maxVelocity);
891#if defined COMPUTE_STATS
892 computeVectorBounds(vel, velBound);
895 pos.x += vel.x * time * m_move_factor;
896 pos.y += vel.y * time * m_move_factor;
898 vel_sum += fabs(vel.x) + fabs(vel.y);
900#if defined VERBOSE_MODE
901 if (wwi.constraint[i]) {
902 qCDebug(KWIN_WOBBLYWINDOWS) <<
"Constraint point ** vel : " << vel.x <<
"," << vel.y <<
" ** move : " << vel.x * time <<
"," << vel.y * time;
907 if (!wwi.can_wobble_top) {
908 for (
unsigned int i = 0; i < wwi.width; ++i) {
909 for (
unsigned j = 0; j < wwi.width - 1; ++j) {
910 wwi.position[i + wwi.width * j].y = wwi.origin[i + wwi.width * j].y;
914 if (!wwi.can_wobble_bottom) {
915 for (
unsigned int i = wwi.width * (wwi.height - 1); i < wwi.count; ++i) {
916 for (
unsigned j = 0; j < wwi.width - 1; ++j) {
917 wwi.position[i - wwi.width * j].y = wwi.origin[i - wwi.width * j].y;
921 if (!wwi.can_wobble_left) {
922 for (
unsigned int i = 0; i < wwi.count; i += wwi.width) {
923 for (
unsigned j = 0; j < wwi.width - 1; ++j) {
924 wwi.position[i + j].x = wwi.origin[i + j].x;
928 if (!wwi.can_wobble_right) {
929 for (
unsigned int i = wwi.width - 1; i < wwi.count; i += wwi.width) {
930 for (
unsigned j = 0; j < wwi.width - 1; ++j) {
931 wwi.position[i - j].x = wwi.origin[i - j].x;
936#if defined VERBOSE_MODE
937#if defined COMPUTE_STATS
938 qCDebug(KWIN_WOBBLYWINDOWS) <<
"Acceleration bounds (" << accBound.x <<
", " << accBound.y <<
")";
939 qCDebug(KWIN_WOBBLYWINDOWS) <<
"Velocity bounds (" << velBound.x <<
", " << velBound.y <<
")";
941 qCDebug(KWIN_WOBBLYWINDOWS) <<
"sum_acc : " << acc_sum <<
" *** sum_vel :" << vel_sum;
944 wwi.wobblying = !(acc_sum < m_stopAcceleration && vel_sum < m_stopVelocity);
945 if (wwi.status !=
Moving && !wwi.wobblying) {
948 if (windows.isEmpty()) {
952 }
else if (!wwi.wobblying) {
959void WobblyWindowsEffect::heightRingLinearMean(QList<Pair> &data, WindowWobblyInfos &wwi)
967 Pair &res = wwi.buffer[0];
969 neibourgs[0] = data[1];
970 neibourgs[1] = data[wwi.width];
971 neibourgs[2] = data[wwi.width + 1];
973 res.x = (neibourgs[0].x + neibourgs[1].x + neibourgs[2].x + 3.0 * vit.x) / 6.0;
974 res.y = (neibourgs[0].y + neibourgs[1].y + neibourgs[2].y + 3.0 * vit.y) / 6.0;
979 Pair &res = wwi.buffer[wwi.width - 1];
980 Pair vit = data[wwi.width - 1];
981 neibourgs[0] = data[wwi.width - 2];
982 neibourgs[1] = data[2 * wwi.width - 1];
983 neibourgs[2] = data[2 * wwi.width - 2];
985 res.x = (neibourgs[0].x + neibourgs[1].x + neibourgs[2].x + 3.0 * vit.x) / 6.0;
986 res.y = (neibourgs[0].y + neibourgs[1].y + neibourgs[2].y + 3.0 * vit.y) / 6.0;
991 Pair &res = wwi.buffer[wwi.width * (wwi.height - 1)];
992 Pair vit = data[wwi.width * (wwi.height - 1)];
993 neibourgs[0] = data[wwi.width * (wwi.height - 1) + 1];
994 neibourgs[1] = data[wwi.width * (wwi.height - 2)];
995 neibourgs[2] = data[wwi.width * (wwi.height - 2) + 1];
997 res.x = (neibourgs[0].x + neibourgs[1].x + neibourgs[2].x + 3.0 * vit.x) / 6.0;
998 res.y = (neibourgs[0].y + neibourgs[1].y + neibourgs[2].y + 3.0 * vit.y) / 6.0;
1003 Pair &res = wwi.buffer[wwi.count - 1];
1004 Pair vit = data[wwi.count - 1];
1005 neibourgs[0] = data[wwi.count - 2];
1006 neibourgs[1] = data[wwi.width * (wwi.height - 1) - 1];
1007 neibourgs[2] = data[wwi.width * (wwi.height - 1) - 2];
1009 res.x = (neibourgs[0].x + neibourgs[1].x + neibourgs[2].x + 3.0 * vit.x) / 6.0;
1010 res.y = (neibourgs[0].y + neibourgs[1].y + neibourgs[2].y + 3.0 * vit.y) / 6.0;
1016 for (
unsigned int i = 1; i < wwi.width - 1; ++i) {
1017 Pair &res = wwi.buffer[i];
1019 neibourgs[0] = data[i - 1];
1020 neibourgs[1] = data[i + 1];
1021 neibourgs[2] = data[i + wwi.width];
1022 neibourgs[3] = data[i + wwi.width - 1];
1023 neibourgs[4] = data[i + wwi.width + 1];
1025 res.x = (neibourgs[0].x + neibourgs[1].x + neibourgs[2].x + neibourgs[3].x + neibourgs[4].x + 5.0 * vit.x) / 10.0;
1026 res.y = (neibourgs[0].y + neibourgs[1].y + neibourgs[2].y + neibourgs[3].y + neibourgs[4].y + 5.0 * vit.y) / 10.0;
1030 for (
unsigned int i = wwi.width * (wwi.height - 1) + 1; i < wwi.count - 1; ++i) {
1031 Pair &res = wwi.buffer[i];
1033 neibourgs[0] = data[i - 1];
1034 neibourgs[1] = data[i + 1];
1035 neibourgs[2] = data[i - wwi.width];
1036 neibourgs[3] = data[i - wwi.width - 1];
1037 neibourgs[4] = data[i - wwi.width + 1];
1039 res.x = (neibourgs[0].x + neibourgs[1].x + neibourgs[2].x + neibourgs[3].x + neibourgs[4].x + 5.0 * vit.x) / 10.0;
1040 res.y = (neibourgs[0].y + neibourgs[1].y + neibourgs[2].y + neibourgs[3].y + neibourgs[4].y + 5.0 * vit.y) / 10.0;
1044 for (
unsigned int i = wwi.width; i < wwi.width * (wwi.height - 1); i += wwi.width) {
1045 Pair &res = wwi.buffer[i];
1047 neibourgs[0] = data[i + 1];
1048 neibourgs[1] = data[i - wwi.width];
1049 neibourgs[2] = data[i + wwi.width];
1050 neibourgs[3] = data[i - wwi.width + 1];
1051 neibourgs[4] = data[i + wwi.width + 1];
1053 res.x = (neibourgs[0].x + neibourgs[1].x + neibourgs[2].x + neibourgs[3].x + neibourgs[4].x + 5.0 * vit.x) / 10.0;
1054 res.y = (neibourgs[0].y + neibourgs[1].y + neibourgs[2].y + neibourgs[3].y + neibourgs[4].y + 5.0 * vit.y) / 10.0;
1058 for (
unsigned int i = 2 * wwi.width - 1; i < wwi.count - 1; i += wwi.width) {
1059 Pair &res = wwi.buffer[i];
1061 neibourgs[0] = data[i - 1];
1062 neibourgs[1] = data[i - wwi.width];
1063 neibourgs[2] = data[i + wwi.width];
1064 neibourgs[3] = data[i - wwi.width - 1];
1065 neibourgs[4] = data[i + wwi.width - 1];
1067 res.x = (neibourgs[0].x + neibourgs[1].x + neibourgs[2].x + neibourgs[3].x + neibourgs[4].x + 5.0 * vit.x) / 10.0;
1068 res.y = (neibourgs[0].y + neibourgs[1].y + neibourgs[2].y + neibourgs[3].y + neibourgs[4].y + 5.0 * vit.y) / 10.0;
1072 for (
unsigned int j = 1; j < wwi.height - 1; ++j) {
1073 for (
unsigned int i = 1; i < wwi.width - 1; ++i) {
1074 unsigned int index = i + j * wwi.width;
1076 Pair &res = wwi.buffer[index];
1077 Pair &vit = data[index];
1078 neibourgs[0] = data[index - 1];
1079 neibourgs[1] = data[index + 1];
1080 neibourgs[2] = data[index - wwi.width];
1081 neibourgs[3] = data[index + wwi.width];
1082 neibourgs[4] = data[index - wwi.width - 1];
1083 neibourgs[5] = data[index - wwi.width + 1];
1084 neibourgs[6] = data[index + wwi.width - 1];
1085 neibourgs[7] = data[index + wwi.width + 1];
1087 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;
1088 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;
1099 return !windows.isEmpty();
1114 return m_move_factor;
1119 return m_xTesselation;
1124 return m_yTesselation;
1129 return m_minVelocity;
1134 return m_maxVelocity;
1139 return m_stopVelocity;
1144 return m_minAcceleration;
1149 return m_maxAcceleration;
1154 return m_stopAcceleration;
1159 return m_moveWobble;
1164 return m_resizeWobble;
1169#include "moc_wobblywindows.cpp"
Representation of a window used by/for Effect classes.
void windowStartUserMovedResized(KWin::EffectWindow *w)
bool isUserResize() const
void windowStepUserMovedResized(KWin::EffectWindow *w, const QRectF &geometry)
bool isSpecialWindow() const
void windowFinishUserMovedResized(KWin::EffectWindow *w)
void windowMaximizedStateChanged(KWin::EffectWindow *w, bool horizontal, bool vertical)
QRectF frameGeometry() const
bool animationsSupported() const
QList< EffectWindow * > stackingOrder
Q_SCRIPTABLE void addRepaint(const QRectF &r)
void prePaintScreen(ScreenPrePaintData &data, std::chrono::milliseconds presentTime)
void prePaintWindow(EffectWindow *w, WindowPrePaintData &data, std::chrono::milliseconds presentTime)
QRectF clientArea(clientAreaOption, const Output *screen, const VirtualDesktop *desktop) const
KSharedConfigPtr config() const
void windowAdded(KWin::EffectWindow *w)
Q_SCRIPTABLE void addRepaintFull()
void unredirect(EffectWindow *window)
void redirect(EffectWindow *window)
void setVertexSnappingMode(RenderGeometry::VertexSnappingMode mode)
WindowQuadList makeRegularGrid(int xSubdivisions, int ySubdivisions) const
void move(double x, double y)
bool isMoveWobble() const
void slotWindowStepUserMovedResized(KWin::EffectWindow *w, const QRectF &geometry)
~WobblyWindowsEffect() override
void apply(EffectWindow *w, int mask, WindowPaintData &data, WindowQuadList &quads) override
void prePaintScreen(ScreenPrePaintData &data, std::chrono::milliseconds presentTime) override
void setMoveFactor(qreal factor)
void slotWindowAdded(KWin::EffectWindow *w)
void slotWindowStartUserMovedResized(KWin::EffectWindow *w)
void setVelocityThreshold(qreal velocityThreshold)
void postPaintScreen() override
bool isActive() const override
bool isResizeWobble() const
void slotWindowFinishUserMovedResized(KWin::EffectWindow *w)
void slotWindowMaximizeStateChanged(KWin::EffectWindow *w, bool horizontal, bool vertical)
void prePaintWindow(EffectWindow *w, WindowPrePaintData &data, std::chrono::milliseconds presentTime) override
void reconfigure(ReconfigureFlags) override
void setStiffness(qreal stiffness)
static QPointF cursorPos()
qreal yTranslation() const
qreal xTranslation() const
@ PAINT_SCREEN_TRANSFORMED