Changeset View
Changeset View
Standalone View
Standalone View
effects/slide/slide.cpp
Show All 14 Lines | |||||
15 | but WITHOUT ANY WARRANTY; without even the implied warranty of | 15 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | GNU General Public License for more details. | 17 | GNU General Public License for more details. | ||
18 | 18 | | |||
19 | You should have received a copy of the GNU General Public License | 19 | You should have received a copy of the GNU General Public License | ||
20 | along with this program. If not, see <http://www.gnu.org/licenses/>. | 20 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
21 | *********************************************************************/ | 21 | *********************************************************************/ | ||
22 | 22 | | |||
23 | // Qt | | |||
24 | #include <QEasingCurve> | | |||
25 | | ||||
26 | // KWayland | 23 | // KWayland | ||
27 | #include <KWayland/Server/surface_interface.h> | 24 | #include <KWayland/Server/surface_interface.h> | ||
28 | #include <KWayland/Server/blur_interface.h> | 25 | #include <KWayland/Server/blur_interface.h> | ||
29 | #include <KWayland/Server/contrast_interface.h> | 26 | #include <KWayland/Server/contrast_interface.h> | ||
30 | 27 | | |||
31 | #include "slide.h" | 28 | #include "slide.h" | ||
32 | // KConfigSkeleton | 29 | // KConfigSkeleton | ||
33 | #include "slideconfig.h" | 30 | #include "slideconfig.h" | ||
34 | 31 | | |||
35 | namespace KWin | 32 | namespace KWin | ||
36 | { | 33 | { | ||
37 | 34 | | |||
38 | SlideEffect::SlideEffect() | 35 | SlideEffect::SlideEffect() | ||
39 | { | 36 | { | ||
40 | initConfig<SlideConfig>(); | 37 | initConfig<SlideConfig>(); | ||
41 | reconfigure(ReconfigureAll); | 38 | reconfigure(ReconfigureAll); | ||
42 | 39 | | |||
43 | QEasingCurve curve(QEasingCurve::OutCubic); | 40 | m_timeLine.setEasingCurve(QEasingCurve::OutCubic); | ||
44 | m_timeline.setEasingCurve(curve); | | |||
45 | 41 | | |||
46 | connect(effects, static_cast<void (EffectsHandler::*)(int,int,EffectWindow*)>(&EffectsHandler::desktopChanged), | 42 | connect(effects, static_cast<void (EffectsHandler::*)(int,int,EffectWindow*)>(&EffectsHandler::desktopChanged), | ||
47 | this, &SlideEffect::desktopChanged); | 43 | this, &SlideEffect::desktopChanged); | ||
48 | connect(effects, &EffectsHandler::windowAdded, | 44 | connect(effects, &EffectsHandler::windowAdded, | ||
49 | this, &SlideEffect::windowAdded); | 45 | this, &SlideEffect::windowAdded); | ||
50 | connect(effects, &EffectsHandler::windowDeleted, | 46 | connect(effects, &EffectsHandler::windowDeleted, | ||
51 | this, &SlideEffect::windowDeleted); | 47 | this, &SlideEffect::windowDeleted); | ||
52 | connect(effects, &EffectsHandler::numberDesktopsChanged, | 48 | connect(effects, &EffectsHandler::numberDesktopsChanged, | ||
53 | this, &SlideEffect::numberDesktopsChanged); | 49 | this, &SlideEffect::numberDesktopsChanged); | ||
54 | connect(effects, &EffectsHandler::numberScreensChanged, | 50 | connect(effects, &EffectsHandler::numberScreensChanged, | ||
55 | this, &SlideEffect::numberScreensChanged); | 51 | this, &SlideEffect::numberScreensChanged); | ||
56 | } | 52 | } | ||
57 | 53 | | |||
58 | bool SlideEffect::supported() | 54 | bool SlideEffect::supported() | ||
59 | { | 55 | { | ||
60 | return effects->animationsSupported(); | 56 | return effects->animationsSupported(); | ||
61 | } | 57 | } | ||
62 | 58 | | |||
63 | void SlideEffect::reconfigure(ReconfigureFlags) | 59 | void SlideEffect::reconfigure(ReconfigureFlags) | ||
64 | { | 60 | { | ||
65 | SlideConfig::self()->read(); | 61 | SlideConfig::self()->read(); | ||
66 | 62 | | |||
67 | const int d = animationTime( | 63 | m_timeLine.setDuration( | ||
68 | SlideConfig::duration() > 0 ? SlideConfig::duration() : 500); | 64 | std::chrono::milliseconds(animationTime<SlideConfig>(500))); | ||
69 | m_timeline.setDuration(d); | | |||
70 | 65 | | |||
71 | m_hGap = SlideConfig::horizontalGap(); | 66 | m_hGap = SlideConfig::horizontalGap(); | ||
72 | m_vGap = SlideConfig::verticalGap(); | 67 | m_vGap = SlideConfig::verticalGap(); | ||
73 | m_slideDocks = SlideConfig::slideDocks(); | 68 | m_slideDocks = SlideConfig::slideDocks(); | ||
74 | m_slideBackground = SlideConfig::slideBackground(); | 69 | m_slideBackground = SlideConfig::slideBackground(); | ||
75 | } | 70 | } | ||
76 | 71 | | |||
77 | void SlideEffect::prePaintScreen(ScreenPrePaintData& data, int time) | 72 | void SlideEffect::prePaintScreen(ScreenPrePaintData& data, int time) | ||
78 | { | 73 | { | ||
79 | if (m_active) { | 74 | m_timeLine.update(std::chrono::milliseconds(time)); | ||
80 | m_timeline.setCurrentTime(m_timeline.currentTime() + time); | 75 | | ||
81 | data.mask |= PAINT_SCREEN_TRANSFORMED | 76 | data.mask |= PAINT_SCREEN_TRANSFORMED | ||
82 | | PAINT_SCREEN_BACKGROUND_FIRST; | 77 | | PAINT_SCREEN_BACKGROUND_FIRST; | ||
83 | } | | |||
84 | 78 | | |||
85 | effects->prePaintScreen(data, time); | 79 | effects->prePaintScreen(data, time); | ||
86 | } | 80 | } | ||
87 | 81 | | |||
88 | /** | 82 | /** | ||
89 | * Wrap vector @p diff around grid @p w x @p h. | 83 | * Wrap vector @p diff around grid @p w x @p h. | ||
90 | * | 84 | * | ||
91 | * Wrapping is done in such a way that magnitude of x and y component of vector | 85 | * Wrapping is done in such a way that magnitude of x and y component of vector | ||
▲ Show 20 Lines • Show All 44 Lines • ▼ Show 20 Line(s) | 129 | if (! m_active) { | |||
136 | effects->paintScreen(mask, region, data); | 130 | effects->paintScreen(mask, region, data); | ||
137 | return; | 131 | return; | ||
138 | } | 132 | } | ||
139 | 133 | | |||
140 | const bool wrap = effects->optionRollOverDesktops(); | 134 | const bool wrap = effects->optionRollOverDesktops(); | ||
141 | const int w = workspaceWidth(); | 135 | const int w = workspaceWidth(); | ||
142 | const int h = workspaceHeight(); | 136 | const int h = workspaceHeight(); | ||
143 | 137 | | |||
144 | QPoint currentPos = m_startPos + m_diff * m_timeline.currentValue(); | 138 | QPoint currentPos = m_startPos + m_diff * m_timeLine.value(); | ||
145 | 139 | | |||
146 | // When "Desktop navigation wraps around" checkbox is checked, currentPos | 140 | // When "Desktop navigation wraps around" checkbox is checked, currentPos | ||
147 | // can be outside the rectangle Rect{x:-w, y:-h, width:2*w, height: 2*h}, | 141 | // can be outside the rectangle Rect{x:-w, y:-h, width:2*w, height: 2*h}, | ||
148 | // so we map currentPos back to the rect. | 142 | // so we map currentPos back to the rect. | ||
149 | if (wrap) { | 143 | if (wrap) { | ||
150 | currentPos.setX(currentPos.x() % w); | 144 | currentPos.setX(currentPos.x() % w); | ||
151 | currentPos.setY(currentPos.y() % h); | 145 | currentPos.setY(currentPos.y() % h); | ||
152 | } | 146 | } | ||
▲ Show 20 Lines • Show All 135 Lines • ▼ Show 20 Line(s) | 281 | { | |||
288 | if (m_active && isTranslated(w)) { | 282 | if (m_active && isTranslated(w)) { | ||
289 | data += m_paintCtx.translation; | 283 | data += m_paintCtx.translation; | ||
290 | } | 284 | } | ||
291 | effects->paintWindow(w, mask, region, data); | 285 | effects->paintWindow(w, mask, region, data); | ||
292 | } | 286 | } | ||
293 | 287 | | |||
294 | void SlideEffect::postPaintScreen() | 288 | void SlideEffect::postPaintScreen() | ||
295 | { | 289 | { | ||
296 | if (m_active) { | 290 | if (m_timeLine.done()) { | ||
297 | if (m_timeline.currentValue() == 1) { | | |||
298 | stop(); | 291 | stop(); | ||
299 | } | 292 | } | ||
293 | | ||||
300 | effects->addRepaintFull(); | 294 | effects->addRepaintFull(); | ||
301 | } | | |||
302 | effects->postPaintScreen(); | 295 | effects->postPaintScreen(); | ||
303 | } | 296 | } | ||
304 | 297 | | |||
305 | /** | 298 | /** | ||
306 | * Get position of the top-left corner of desktop @p id within desktop grid with gaps. | 299 | * Get position of the top-left corner of desktop @p id within desktop grid with gaps. | ||
307 | * @param id ID of a virtual desktop | 300 | * @param id ID of a virtual desktop | ||
308 | */ | 301 | */ | ||
309 | QPoint SlideEffect::desktopCoords(int id) const | 302 | QPoint SlideEffect::desktopCoords(int id) const | ||
▲ Show 20 Lines • Show All 112 Lines • ▼ Show 20 Line(s) | |||||
422 | { | 415 | { | ||
423 | m_movingWindow = movingWindow; | 416 | m_movingWindow = movingWindow; | ||
424 | 417 | | |||
425 | const bool wrap = effects->optionRollOverDesktops(); | 418 | const bool wrap = effects->optionRollOverDesktops(); | ||
426 | const int w = workspaceWidth(); | 419 | const int w = workspaceWidth(); | ||
427 | const int h = workspaceHeight(); | 420 | const int h = workspaceHeight(); | ||
428 | 421 | | |||
429 | if (m_active) { | 422 | if (m_active) { | ||
430 | QPoint passed = m_diff * m_timeline.currentValue(); | 423 | QPoint passed = m_diff * m_timeLine.value(); | ||
431 | QPoint currentPos = m_startPos + passed; | 424 | QPoint currentPos = m_startPos + passed; | ||
432 | QPoint delta = desktopCoords(current) - desktopCoords(old); | 425 | QPoint delta = desktopCoords(current) - desktopCoords(old); | ||
433 | if (wrap) { | 426 | if (wrap) { | ||
434 | wrapDiff(delta, w, h); | 427 | wrapDiff(delta, w, h); | ||
435 | } | 428 | } | ||
436 | m_diff += delta - passed; | 429 | m_diff += delta - passed; | ||
437 | m_startPos = currentPos; | 430 | m_startPos = currentPos; | ||
438 | m_timeline.setCurrentTime(0); | 431 | // TODO: Figure out how to smooth movement. | ||
432 | m_timeLine.reset(); | ||||
439 | return; | 433 | return; | ||
440 | } | 434 | } | ||
441 | 435 | | |||
442 | const auto windows = effects->stackingOrder(); | 436 | const auto windows = effects->stackingOrder(); | ||
443 | for (EffectWindow* w : windows) { | 437 | for (EffectWindow* w : windows) { | ||
444 | if (shouldForceBlur(w)) { | 438 | if (shouldForceBlur(w)) { | ||
445 | w->setData(WindowForceBlurRole, QVariant(true)); | 439 | w->setData(WindowForceBlurRole, QVariant(true)); | ||
446 | m_forcedRoles.blur << w; | 440 | m_forcedRoles.blur << w; | ||
447 | } | 441 | } | ||
448 | if (shouldForceBackgroundContrast(w)) { | 442 | if (shouldForceBackgroundContrast(w)) { | ||
449 | w->setData(WindowForceBackgroundContrastRole, QVariant(true)); | 443 | w->setData(WindowForceBackgroundContrastRole, QVariant(true)); | ||
450 | m_forcedRoles.backgroundContrast << w; | 444 | m_forcedRoles.backgroundContrast << w; | ||
451 | } | 445 | } | ||
452 | if (shouldElevate(w)) { | 446 | if (shouldElevate(w)) { | ||
453 | effects->setElevatedWindow(w, true); | 447 | effects->setElevatedWindow(w, true); | ||
454 | m_elevatedWindows << w; | 448 | m_elevatedWindows << w; | ||
455 | } | 449 | } | ||
456 | } | 450 | } | ||
457 | 451 | | |||
458 | m_diff = desktopCoords(current) - desktopCoords(old); | 452 | m_diff = desktopCoords(current) - desktopCoords(old); | ||
459 | if (wrap) { | 453 | if (wrap) { | ||
460 | wrapDiff(m_diff, w, h); | 454 | wrapDiff(m_diff, w, h); | ||
461 | } | 455 | } | ||
462 | m_startPos = desktopCoords(old); | 456 | m_startPos = desktopCoords(old); | ||
463 | m_timeline.setCurrentTime(0); | 457 | m_timeLine.reset(); | ||
464 | m_active = true; | 458 | m_active = true; | ||
465 | effects->setActiveFullScreenEffect(this); | 459 | effects->setActiveFullScreenEffect(this); | ||
466 | effects->addRepaintFull(); | 460 | effects->addRepaintFull(); | ||
467 | } | 461 | } | ||
468 | 462 | | |||
469 | void SlideEffect::stop() | 463 | void SlideEffect::stop() | ||
470 | { | 464 | { | ||
471 | for (EffectWindow* w : m_forcedRoles.blur) { | 465 | for (EffectWindow* w : m_forcedRoles.blur) { | ||
472 | w->setData(WindowForceBlurRole, QVariant()); | 466 | w->setData(WindowForceBlurRole, QVariant()); | ||
473 | } | 467 | } | ||
474 | m_forcedRoles.blur.clear(); | 468 | m_forcedRoles.blur.clear(); | ||
475 | 469 | | |||
476 | for (EffectWindow* w : m_forcedRoles.backgroundContrast) { | 470 | for (EffectWindow* w : m_forcedRoles.backgroundContrast) { | ||
477 | w->setData(WindowForceBackgroundContrastRole, QVariant()); | 471 | w->setData(WindowForceBackgroundContrastRole, QVariant()); | ||
478 | } | 472 | } | ||
479 | m_forcedRoles.backgroundContrast.clear(); | 473 | m_forcedRoles.backgroundContrast.clear(); | ||
480 | 474 | | |||
481 | for (EffectWindow* w : m_elevatedWindows) { | 475 | for (EffectWindow* w : m_elevatedWindows) { | ||
482 | effects->setElevatedWindow(w, false); | 476 | effects->setElevatedWindow(w, false); | ||
483 | } | 477 | } | ||
484 | m_elevatedWindows.clear(); | 478 | m_elevatedWindows.clear(); | ||
485 | 479 | | |||
486 | m_paintCtx.fullscreenWindows.clear(); | 480 | m_paintCtx.fullscreenWindows.clear(); | ||
487 | m_timeline.setCurrentTime(0); | | |||
488 | m_movingWindow = nullptr; | 481 | m_movingWindow = nullptr; | ||
489 | m_active = false; | 482 | m_active = false; | ||
490 | effects->setActiveFullScreenEffect(nullptr); | 483 | effects->setActiveFullScreenEffect(nullptr); | ||
491 | } | 484 | } | ||
492 | 485 | | |||
493 | void SlideEffect::desktopChanged(int old, int current, EffectWindow* with) | 486 | void SlideEffect::desktopChanged(int old, int current, EffectWindow* with) | ||
494 | { | 487 | { | ||
495 | if (effects->activeFullScreenEffect() && effects->activeFullScreenEffect() != this) { | 488 | if (effects->activeFullScreenEffect() && effects->activeFullScreenEffect() != this) { | ||
▲ Show 20 Lines • Show All 55 Lines • Show Last 20 Lines |