KWin
Loading...
Searching...
No Matches
effecthandler.cpp
Go to the documentation of this file.
1/*
2 KWin - the KDE window manager
3 This file is part of the KDE project.
4
5 SPDX-FileCopyrightText: 2006 Lubos Lunak <l.lunak@kde.org>
6 SPDX-FileCopyrightText: 2009 Lucas Murray <lmurray@undefinedfire.com>
7 SPDX-FileCopyrightText: 2018 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
8
9 SPDX-License-Identifier: GPL-2.0-or-later
10*/
11
13
14#include "config-kwin.h"
15
16#include "compositor.h"
17#include "core/output.h"
18#include "core/renderbackend.h"
19#include "core/rendertarget.h"
20#include "core/renderviewport.h"
22#include "effect/effectloader.h"
24#include "effectsadaptor.h"
25#include "input.h"
26#include "input_event.h"
27#include "inputmethod.h"
28#include "inputpanelv1window.h"
29#include "keyboard_input.h"
30#include "opengl/glshader.h"
32#include "opengl/gltexture.h"
33#include "osd.h"
34#include "pointer_input.h"
35#include "scene/itemrenderer.h"
36#include "scene/windowitem.h"
38#include "screenedge.h"
39#include "scripting/scripting.h"
40#include "sm.h"
41#include "virtualdesktops.h"
42#include "wayland_server.h"
44#include "workspace.h"
45#include "x11window.h"
46
47#if KWIN_BUILD_ACTIVITIES
48#include "activities.h"
49#endif
50#if KWIN_BUILD_TABBOX
51#include "tabbox/tabbox.h"
52#endif
53#if KWIN_BUILD_SCREENLOCKER
54#include "screenlockerwatcher.h"
55#endif
56
57#include <KDecoration2/Decoration>
58#include <KDecoration2/DecorationSettings>
59
60#include <QFontMetrics>
61#include <QMatrix4x4>
62#include <QPainter>
63#include <QPixmap>
64#include <QTimeLine>
65#include <QVariant>
66#include <QWindow>
67#include <QtMath>
68
69namespace KWin
70{
71
72static QByteArray readWindowProperty(xcb_window_t win, xcb_atom_t atom, xcb_atom_t type, int format)
73{
74 if (win == XCB_WINDOW_NONE) {
75 return QByteArray();
76 }
77 uint32_t len = 32768;
78 for (;;) {
79 Xcb::Property prop(false, win, atom, XCB_ATOM_ANY, 0, len);
80 if (prop.isNull()) {
81 // get property failed
82 return QByteArray();
83 }
84 if (prop->bytes_after > 0) {
85 len *= 2;
86 continue;
87 }
88 return prop.toByteArray(format, type);
89 }
90}
91
92static xcb_atom_t registerSupportProperty(const QByteArray &propertyName)
93{
94 auto c = kwinApp()->x11Connection();
95 if (!c) {
96 return XCB_ATOM_NONE;
97 }
98 // get the atom for the propertyName
99 UniqueCPtr<xcb_intern_atom_reply_t> atomReply(xcb_intern_atom_reply(c,
100 xcb_intern_atom_unchecked(c, false, propertyName.size(), propertyName.constData()),
101 nullptr));
102 if (!atomReply) {
103 return XCB_ATOM_NONE;
104 }
105 // announce property on root window
106 unsigned char dummy = 0;
107 xcb_change_property(c, XCB_PROP_MODE_REPLACE, kwinApp()->x11RootWindow(), atomReply->atom, atomReply->atom, 8, 1, &dummy);
108 // TODO: add to _NET_SUPPORTED
109 return atomReply->atom;
110}
111
112//****************************************
113// EffectsHandler
114//****************************************
115
117 : keyboard_grab_effect(nullptr)
118 , fullscreen_effect(nullptr)
119 , compositing_type(compositor->backend()->compositingType())
120 , m_compositor(compositor)
121 , m_scene(scene)
122 , m_effectLoader(new EffectLoader(this))
123 , m_trackingCursorChanges(0)
124{
126 return;
127 }
128 KWin::effects = this;
129
130 qRegisterMetaType<QList<KWin::EffectWindow *>>();
131 qRegisterMetaType<KWin::SessionState>();
132 connect(m_effectLoader, &AbstractEffectLoader::effectLoaded, this, [this](Effect *effect, const QString &name) {
133 effect_order.insert(effect->requestedEffectChainPosition(), EffectPair(name, effect));
134 loaded_effects << EffectPair(name, effect);
136 });
137 m_effectLoader->setConfig(kwinApp()->config());
138 new EffectsAdaptor(this);
139 QDBusConnection dbus = QDBusConnection::sessionBus();
140 dbus.registerObject(QStringLiteral("/Effects"), this);
141
143
145 VirtualDesktopManager *vds = VirtualDesktopManager::self();
146 connect(ws, &Workspace::showingDesktopChanged, this, [this](bool showing, bool animated) {
147 if (animated) {
148 Q_EMIT showingDesktopChanged(showing);
149 }
150 });
151 connect(ws, &Workspace::currentDesktopChanged, this, [this](VirtualDesktop *old, Window *window) {
152 VirtualDesktop *newDesktop = VirtualDesktopManager::self()->currentDesktop();
153 Q_EMIT desktopChanged(old, newDesktop, window ? window->effectWindow() : nullptr);
154 });
155 connect(ws, &Workspace::currentDesktopChanging, this, [this](VirtualDesktop *currentDesktop, QPointF offset, KWin::Window *window) {
156 Q_EMIT desktopChanging(currentDesktop, offset, window ? window->effectWindow() : nullptr);
157 });
158 connect(ws, &Workspace::currentDesktopChangingCancelled, this, [this]() {
160 });
161 connect(ws, &Workspace::windowAdded, this, [this](Window *window) {
163 Q_EMIT windowAdded(window->effectWindow());
164 });
165 connect(ws, &Workspace::windowActivated, this, [this](Window *window) {
166 Q_EMIT windowActivated(window ? window->effectWindow() : nullptr);
167 });
168 connect(ws, &Workspace::deletedRemoved, this, [this](KWin::Window *d) {
169 Q_EMIT windowDeleted(d->effectWindow());
170 });
172 connect(vds, &VirtualDesktopManager::layoutChanged, this, [this](int width, int height) {
173 Q_EMIT desktopGridSizeChanged(QSize(width, height));
174 Q_EMIT desktopGridWidthChanged(width);
175 Q_EMIT desktopGridHeightChanged(height);
176 });
182#if KWIN_BUILD_ACTIVITIES
183 if (Activities *activities = Workspace::self()->activities()) {
184 connect(activities, &Activities::added, this, &EffectsHandler::activityAdded);
185 connect(activities, &Activities::removed, this, &EffectsHandler::activityRemoved);
187 }
188#endif
190#if KWIN_BUILD_TABBOX
191 TabBox::TabBox *tabBox = workspace()->tabbox();
196#endif
198#if KWIN_BUILD_SCREENLOCKER
199 connect(kwinApp()->screenLockerWatcher(), &ScreenLockerWatcher::locked, this, &EffectsHandler::screenLockingChanged);
200 connect(kwinApp()->screenLockerWatcher(), &ScreenLockerWatcher::aboutToLock, this, &EffectsHandler::screenAboutToLock);
201#endif
202
203 connect(kwinApp(), &Application::x11ConnectionChanged, this, [this]() {
204 registered_atoms.clear();
205 for (auto it = m_propertiesForEffects.keyBegin(); it != m_propertiesForEffects.keyEnd(); it++) {
206 const auto atom = registerSupportProperty(*it);
207 if (atom == XCB_ATOM_NONE) {
208 continue;
209 }
211 m_managedProperties.insert(*it, atom);
212 registerPropertyType(atom, true);
213 }
214 if (kwinApp()->x11Connection()) {
215 m_x11WindowPropertyNotify = std::make_unique<WindowPropertyNotifyX11Filter>(this);
216 } else {
218 }
219 Q_EMIT xcbConnectionChanged();
220 });
221
222 if (kwinApp()->x11Connection()) {
223 m_x11WindowPropertyNotify = std::make_unique<WindowPropertyNotifyX11Filter>(this);
224 }
225
226 // connect all clients
227 for (Window *window : ws->windows()) {
229 }
230
233
234 if (auto inputMethod = kwinApp()->inputMethod()) {
236 }
237
238 reconfigure();
239}
240
246
248{
249 return kwinApp()->x11RootWindow();
250}
251
252xcb_connection_t *EffectsHandler::xcbConnection() const
253{
254 return kwinApp()->x11Connection();
255}
256
261
266
268{
269 for (const EffectPair &pair : std::as_const(loaded_effects)) {
270 destroyEffect(pair.second);
271 }
272
273 effect_order.clear();
275
277}
278
280{
281 connect(window, &Window::closed, this, [this, window]() {
282 if (window->effectWindow()) {
283 Q_EMIT windowClosed(window->effectWindow());
284 }
285 });
286}
287
292
293// the idea is that effects call this function again which calls the next one
294void EffectsHandler::prePaintScreen(ScreenPrePaintData &data, std::chrono::milliseconds presentTime)
295{
297 (*m_currentPaintScreenIterator++)->prePaintScreen(data, presentTime);
299 }
300 // no special final code
301}
302
303void EffectsHandler::paintScreen(const RenderTarget &renderTarget, const RenderViewport &viewport, int mask, const QRegion &region, Output *screen)
304{
306 (*m_currentPaintScreenIterator++)->paintScreen(renderTarget, viewport, mask, region, screen);
308 } else {
309 m_scene->finalPaintScreen(renderTarget, viewport, mask, region, screen);
310 }
311}
312
314{
318 }
319 // no special final code
320}
321
322void EffectsHandler::prePaintWindow(EffectWindow *w, WindowPrePaintData &data, std::chrono::milliseconds presentTime)
323{
325 (*m_currentPaintWindowIterator++)->prePaintWindow(w, data, presentTime);
327 }
328 // no special final code
329}
330
331void EffectsHandler::paintWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, const QRegion &region, WindowPaintData &data)
332{
334 (*m_currentPaintWindowIterator++)->paintWindow(renderTarget, viewport, w, mask, region, data);
336 } else {
337 m_scene->finalPaintWindow(renderTarget, viewport, w, mask, region, data);
338 }
339}
340
349
351{
352 for (int i = 0; i < loaded_effects.size(); ++i) {
353 if (loaded_effects.at(i).second->provides(ef)) {
354 return loaded_effects.at(i).second;
355 }
356 }
357 return nullptr;
358}
359
360void EffectsHandler::drawWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, const QRegion &region, WindowPaintData &data)
361{
363 (*m_currentDrawWindowIterator++)->drawWindow(renderTarget, viewport, w, mask, region, data);
365 } else {
366 m_scene->finalDrawWindow(renderTarget, viewport, w, mask, region, data);
367 }
368}
369
370void EffectsHandler::renderWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, const QRegion &region, WindowPaintData &data)
371{
372 m_scene->finalDrawWindow(renderTarget, viewport, w, mask, region, data);
373}
374
376{
377 return false;
378}
379
381{
382 return true;
383}
384
385// start another painting pass
387{
388 m_activeEffects.clear();
389 m_activeEffects.reserve(loaded_effects.count());
390 for (QList<KWin::EffectPair>::const_iterator it = loaded_effects.constBegin(); it != loaded_effects.constEnd(); ++it) {
391 if (it->second->isActive()) {
392 m_activeEffects << it->second;
393 }
394 }
398}
399
401{
402 if (fullscreen_effect == e) {
403 return;
404 }
405 const bool activeChanged = (e == nullptr || fullscreen_effect == nullptr);
408 if (activeChanged) {
411 }
412}
413
418
423
425{
426 if (keyboard_grab_effect != nullptr) {
427 return false;
428 }
429 if (!doGrabKeyboard()) {
430 return false;
431 }
432 keyboard_grab_effect = effect;
433 return true;
434}
435
437{
438 return true;
439}
440
442{
443 Q_ASSERT(keyboard_grab_effect != nullptr);
445 keyboard_grab_effect = nullptr;
446 input()->keyboard()->update();
447}
448
452
454{
455 if (keyboard_grab_effect != nullptr) {
457 }
458}
459
460void EffectsHandler::startMouseInterception(Effect *effect, Qt::CursorShape shape)
461{
462 if (m_grabbedMouseEffects.contains(effect)) {
463 return;
464 }
465 m_grabbedMouseEffects.append(effect);
466 if (m_grabbedMouseEffects.size() != 1) {
467 return;
468 }
470}
471
473{
475
476 // We want to allow global shortcuts to be triggered when moving a
477 // window so it is possible to pick up a window and then move it to a
478 // different desktop by using the global shortcut to switch desktop.
479 // However, that means that some other things can also be triggered. If
480 // an effect that fill the screen gets triggered that way, we end up in a
481 // weird state where the move will restart after the effect closes. So to
482 // avoid that, abort move/resize if a full screen effect starts.
483 if (workspace()->moveResizeWindow()) {
485 }
486}
487
489{
490 if (!m_grabbedMouseEffects.contains(effect)) {
491 return;
492 }
493 m_grabbedMouseEffects.removeAll(effect);
494 if (m_grabbedMouseEffects.isEmpty()) {
496 }
497}
498
503
505{
506 return m_grabbedMouseEffects.count() > 0;
507}
508
509bool EffectsHandler::touchDown(qint32 id, const QPointF &pos, std::chrono::microseconds time)
510{
511 // TODO: reverse call order?
512 for (auto it = loaded_effects.constBegin(); it != loaded_effects.constEnd(); ++it) {
513 if (it->second->touchDown(id, pos, time)) {
514 return true;
515 }
516 }
517 return false;
518}
519
520bool EffectsHandler::touchMotion(qint32 id, const QPointF &pos, std::chrono::microseconds time)
521{
522 // TODO: reverse call order?
523 for (auto it = loaded_effects.constBegin(); it != loaded_effects.constEnd(); ++it) {
524 if (it->second->touchMotion(id, pos, time)) {
525 return true;
526 }
527 }
528 return false;
529}
530
531bool EffectsHandler::touchUp(qint32 id, std::chrono::microseconds time)
532{
533 // TODO: reverse call order?
534 for (auto it = loaded_effects.constBegin(); it != loaded_effects.constEnd(); ++it) {
535 if (it->second->touchUp(id, time)) {
536 return true;
537 }
538 }
539 return false;
540}
541
543{
544 // TODO: reverse call order?
545 for (auto it = loaded_effects.constBegin(); it != loaded_effects.constEnd(); ++it) {
546 if (it->second->tabletToolEvent(event)) {
547 return true;
548 }
549 }
550 return false;
551}
552
553bool EffectsHandler::tabletToolButtonEvent(uint button, bool pressed, const TabletToolId &tabletToolId, std::chrono::microseconds time)
554{
555 // TODO: reverse call order?
556 for (auto it = loaded_effects.constBegin(); it != loaded_effects.constEnd(); ++it) {
557 if (it->second->tabletToolButtonEvent(button, pressed, tabletToolId.m_uniqueId)) {
558 return true;
559 }
560 }
561 return false;
562}
563
564bool EffectsHandler::tabletPadButtonEvent(uint button, bool pressed, const TabletPadId &tabletPadId, std::chrono::microseconds time)
565{
566 // TODO: reverse call order?
567 for (auto it = loaded_effects.constBegin(); it != loaded_effects.constEnd(); ++it) {
568 if (it->second->tabletPadButtonEvent(button, pressed, tabletPadId.data)) {
569 return true;
570 }
571 }
572 return false;
573}
574
575bool EffectsHandler::tabletPadStripEvent(int number, int position, bool isFinger, const TabletPadId &tabletPadId, std::chrono::microseconds time)
576{
577 // TODO: reverse call order?
578 for (auto it = loaded_effects.constBegin(); it != loaded_effects.constEnd(); ++it) {
579 if (it->second->tabletPadStripEvent(number, position, isFinger, tabletPadId.data)) {
580 return true;
581 }
582 }
583 return false;
584}
585
586bool EffectsHandler::tabletPadRingEvent(int number, int position, bool isFinger, const TabletPadId &tabletPadId, std::chrono::microseconds time)
587{
588 // TODO: reverse call order?
589 for (auto it = loaded_effects.constBegin(); it != loaded_effects.constEnd(); ++it) {
590 if (it->second->tabletPadRingEvent(number, position, isFinger, tabletPadId.data)) {
591 return true;
592 }
593 }
594 return false;
595}
596
597void EffectsHandler::registerPointerShortcut(Qt::KeyboardModifiers modifiers, Qt::MouseButton pointerButtons, QAction *action)
598{
599 input()->registerPointerShortcut(modifiers, pointerButtons, action);
600}
601
602void EffectsHandler::registerAxisShortcut(Qt::KeyboardModifiers modifiers, PointerAxisDirection axis, QAction *action)
603{
604 input()->registerAxisShortcut(modifiers, axis, action);
605}
606
607void EffectsHandler::registerTouchpadSwipeShortcut(SwipeDirection dir, uint fingerCount, QAction *onUp, std::function<void(qreal)> progressCallback)
608{
609 input()->registerTouchpadSwipeShortcut(dir, fingerCount, onUp, progressCallback);
610}
611
612void EffectsHandler::registerTouchpadPinchShortcut(PinchDirection dir, uint fingerCount, QAction *onUp, std::function<void(qreal)> progressCallback)
613{
614 input()->registerTouchpadPinchShortcut(dir, fingerCount, onUp, progressCallback);
615}
616
617void EffectsHandler::registerTouchscreenSwipeShortcut(SwipeDirection direction, uint fingerCount, QAction *action, std::function<void(qreal)> progressCallback)
618{
619 input()->registerTouchscreenSwipeShortcut(direction, fingerCount, action, progressCallback);
620}
621
623{
624 if (Cursors::self()->mouse()) {
626 }
627}
628
630{
631 if (Cursors::self()->mouse()) {
633 }
634}
635
637{
638 return keyboard_grab_effect != nullptr;
639}
640
642{
643 if (reg) {
644 ++registered_atoms[atom]; // initialized to 0 if not present yet
645 } else {
646 if (--registered_atoms[atom] == 0) {
647 registered_atoms.remove(atom);
648 }
649 }
650}
651
652xcb_atom_t EffectsHandler::announceSupportProperty(const QByteArray &propertyName, Effect *effect)
653{
654 PropertyEffectMap::iterator it = m_propertiesForEffects.find(propertyName);
655 if (it != m_propertiesForEffects.end()) {
656 // property has already been registered for an effect
657 // just append Effect and return the atom stored in m_managedProperties
658 if (!it.value().contains(effect)) {
659 it.value().append(effect);
660 }
661 return m_managedProperties.value(propertyName, XCB_ATOM_NONE);
662 }
663 m_propertiesForEffects.insert(propertyName, QList<Effect *>() << effect);
664 const auto atom = registerSupportProperty(propertyName);
665 if (atom == XCB_ATOM_NONE) {
666 return atom;
667 }
669 m_managedProperties.insert(propertyName, atom);
670 registerPropertyType(atom, true);
671 return atom;
672}
673
674void EffectsHandler::removeSupportProperty(const QByteArray &propertyName, Effect *effect)
675{
676 PropertyEffectMap::iterator it = m_propertiesForEffects.find(propertyName);
677 if (it == m_propertiesForEffects.end()) {
678 // property is not registered - nothing to do
679 return;
680 }
681 if (!it.value().contains(effect)) {
682 // property is not registered for given effect - nothing to do
683 return;
684 }
685 it.value().removeAll(effect);
686 if (!it.value().isEmpty()) {
687 // property still registered for another effect - nothing further to do
688 return;
689 }
690 const xcb_atom_t atom = m_managedProperties.take(propertyName);
691 registerPropertyType(atom, false);
692 m_propertiesForEffects.remove(propertyName);
693 m_compositor->removeSupportProperty(atom); // delayed removal
694}
695
696QByteArray EffectsHandler::readRootProperty(long atom, long type, int format) const
697{
698 if (!kwinApp()->x11Connection()) {
699 return QByteArray();
700 }
701 return readWindowProperty(kwinApp()->x11RootWindow(), atom, type, format);
702}
703
705{
706 auto window = effectWindow->window();
707 if (window->isClient()) {
708 Workspace::self()->activateWindow(window, true);
709 }
710}
711
716
717void EffectsHandler::moveWindow(EffectWindow *w, const QPoint &pos, bool snap, double snapAdjust)
718{
719 auto window = w->window();
720 if (!window->isClient() || !window->isMovable()) {
721 return;
722 }
723
724 if (snap) {
725 window->move(Workspace::self()->adjustWindowPosition(window, pos, true, snapAdjust));
726 } else {
727 window->move(pos);
728 }
729}
730
731void EffectsHandler::windowToDesktops(EffectWindow *w, const QList<VirtualDesktop *> &desktops)
732{
733 auto window = w->window();
734 if (!window->isClient() || window->isDesktop() || window->isDock()) {
735 return;
736 }
737 window->setDesktops(desktops);
738}
739
741{
742 auto window = w->window();
743 if (window->isClient() && !window->isDesktop() && !window->isDock()) {
744 Workspace::self()->sendWindowToOutput(window, screen);
745 }
746}
747
749{
751}
752
754{
755#if KWIN_BUILD_ACTIVITIES
756 if (!Workspace::self()->activities()) {
757 return QString();
758 }
759 return Workspace::self()->activities()->current();
760#else
761 return QString();
762#endif
763}
764
766{
767 return VirtualDesktopManager::self()->currentDesktop();
768}
769
770QList<VirtualDesktop *> EffectsHandler::desktops() const
771{
772 return VirtualDesktopManager::self()->desktops();
773}
774
776{
777 VirtualDesktopManager::self()->setCurrent(desktop);
778}
779
781{
782 return VirtualDesktopManager::self()->grid().size();
783}
784
786{
787 return desktopGridSize().width();
788}
789
791{
792 return desktopGridSize().height();
793}
794
796{
797 return desktopGridWidth() * Workspace::self()->geometry().width();
798}
799
801{
802 return desktopGridHeight() * Workspace::self()->geometry().height();
803}
804
806{
807 return VirtualDesktopManager::self()->grid().at(coords);
808}
809
811{
812 return VirtualDesktopManager::self()->grid().gridCoords(desktop);
813}
814
816{
817 QPoint coords = VirtualDesktopManager::self()->grid().gridCoords(desktop);
818 if (coords.x() == -1) {
819 return QPoint(-1, -1);
820 }
821 const QSize displaySize = Workspace::self()->geometry().size();
822 return QPoint(coords.x() * displaySize.width(), coords.y() * displaySize.height());
823}
824
826{
827 return VirtualDesktopManager::self()->inDirection(desktop, VirtualDesktopManager::Direction::Up, wrap);
828}
829
831{
832 return VirtualDesktopManager::self()->inDirection(desktop, VirtualDesktopManager::Direction::Right, wrap);
833}
834
836{
837 return VirtualDesktopManager::self()->inDirection(desktop, VirtualDesktopManager::Direction::Down, wrap);
838}
839
841{
842 return VirtualDesktopManager::self()->inDirection(desktop, VirtualDesktopManager::Direction::Left, wrap);
843}
844
846{
847 return desktop->name();
848}
849
854
859
861{
862 if (X11Window *w = Workspace::self()->findClient(Predicate::WindowMatch, id)) {
863 return w->effectWindow();
864 }
865 if (X11Window *w = Workspace::self()->findUnmanaged(id)) {
866 return w->effectWindow();
867 }
868 return nullptr;
869}
870
872{
873 if (waylandServer()) {
874 if (Window *w = waylandServer()->findWindow(surf)) {
875 return w->effectWindow();
876 }
877 }
878 return nullptr;
879}
880
882{
883 if (Window *window = workspace()->findInternal(w)) {
884 return window->effectWindow();
885 }
886 return nullptr;
887}
888
890{
891 if (Window *window = workspace()->findWindow(id)) {
892 return window->effectWindow();
893 }
894 return nullptr;
895}
896
897QList<EffectWindow *> EffectsHandler::stackingOrder() const
898{
899 QList<Window *> list = workspace()->stackingOrder();
900 QList<EffectWindow *> ret;
901 for (Window *t : list) {
902 if (EffectWindow *w = t->effectWindow()) {
903 ret.append(w);
904 }
905 }
906 return ret;
907}
908
910{
911 WindowItem *item = w->windowItem();
912
913 if (set) {
914 item->elevate();
915 } else {
916 item->deelevate();
917 }
918}
919
921{
922#if KWIN_BUILD_TABBOX
923 auto window = w->window();
924 if (window->isClient()) {
925 workspace()->tabbox()->setCurrentClient(window);
926 }
927#endif
928}
929
930QList<EffectWindow *> EffectsHandler::currentTabBoxWindowList() const
931{
932#if KWIN_BUILD_TABBOX
933 const auto clients = workspace()->tabbox()->currentClientList();
934 QList<EffectWindow *> ret;
935 ret.reserve(clients.size());
936 std::transform(std::cbegin(clients), std::cend(clients),
937 std::back_inserter(ret),
938 [](auto client) {
939 return client->effectWindow();
940 });
941 return ret;
942#else
943 return QList<EffectWindow *>();
944#endif
945}
946
948{
949#if KWIN_BUILD_TABBOX
950 workspace()->tabbox()->reference();
951#endif
952}
953
955{
956#if KWIN_BUILD_TABBOX
957 workspace()->tabbox()->unreference();
958#endif
959}
960
962{
963#if KWIN_BUILD_TABBOX
964 workspace()->tabbox()->close();
965#endif
966}
967
969{
970#if KWIN_BUILD_TABBOX
971 if (auto c = workspace()->tabbox()->currentClient()) {
972 return c->effectWindow();
973 }
974#endif
975 return nullptr;
976}
977
982
983void EffectsHandler::addRepaint(const QRect &r)
984{
986}
987
988void EffectsHandler::addRepaint(const QRectF &r)
989{
990 m_compositor->scene()->addRepaint(r.toAlignedRect());
991}
992
993void EffectsHandler::addRepaint(const QRegion &r)
994{
996}
997
998void EffectsHandler::addRepaint(int x, int y, int w, int h)
999{
1000 m_compositor->scene()->addRepaint(x, y, w, h);
1001}
1002
1004{
1005 return workspace()->activeOutput();
1006}
1007
1008QRectF EffectsHandler::clientArea(clientAreaOption opt, const Output *screen, const VirtualDesktop *desktop) const
1009{
1010 return Workspace::self()->clientArea(opt, screen, desktop);
1011}
1012
1013QRectF EffectsHandler::clientArea(clientAreaOption opt, const EffectWindow *effectWindow) const
1014{
1015 const Window *window = effectWindow->window();
1016 return Workspace::self()->clientArea(opt, window);
1017}
1018
1019QRectF EffectsHandler::clientArea(clientAreaOption opt, const QPoint &p, const VirtualDesktop *desktop) const
1020{
1021 const Output *output = Workspace::self()->outputAt(p);
1022 return Workspace::self()->clientArea(opt, output, desktop);
1023}
1024
1026{
1027 return Workspace::self()->geometry();
1028}
1029
1031{
1032 return Workspace::self()->geometry().size();
1033}
1034
1035void EffectsHandler::defineCursor(Qt::CursorShape shape)
1036{
1038}
1039
1041{
1042 if (m_grabbedMouseEffects.isEmpty()) {
1043 return false;
1044 }
1045 for (Effect *effect : std::as_const(m_grabbedMouseEffects)) {
1046 effect->windowInputMouseEvent(e);
1047 }
1048 return true;
1049}
1050
1052{
1053 if (m_grabbedMouseEffects.isEmpty()) {
1054 return false;
1055 }
1056 for (Effect *effect : std::as_const(m_grabbedMouseEffects)) {
1057 effect->windowInputMouseEvent(e);
1058 }
1059 return true;
1060}
1061
1062void EffectsHandler::connectNotify(const QMetaMethod &signal)
1063{
1064 if (signal == QMetaMethod::fromSignal(&EffectsHandler::cursorShapeChanged)) {
1068 }
1070 }
1071 QObject::connectNotify(signal);
1072}
1073
1074void EffectsHandler::disconnectNotify(const QMetaMethod &signal)
1075{
1076 if (signal == QMetaMethod::fromSignal(&EffectsHandler::cursorShapeChanged)) {
1077 Q_ASSERT(m_trackingCursorChanges > 0);
1078 if (!--m_trackingCursorChanges) {
1081 }
1082 }
1083 QObject::disconnectNotify(signal);
1084}
1085
1087{
1088 if (m_grabbedMouseEffects.isEmpty()) {
1089 return;
1090 }
1092}
1093
1097
1099{
1100 return Cursors::self()->mouse()->pos();
1101}
1102
1104{
1105 workspace()->screenEdges()->reserve(border, effect, "borderActivated");
1106}
1107
1109{
1110 workspace()->screenEdges()->unreserve(border, effect);
1111}
1112
1114{
1115 workspace()->screenEdges()->reserveTouch(border, action);
1116}
1117
1119{
1120 workspace()->screenEdges()->reserveTouch(border, action, progressCallback);
1121}
1122
1124{
1125 workspace()->screenEdges()->unreserveTouch(border, action);
1126}
1127
1129{
1130 return m_scene->renderer()->painter();
1131}
1132
1133void EffectsHandler::toggleEffect(const QString &name)
1134{
1135 if (isEffectLoaded(name)) {
1136 unloadEffect(name);
1137 } else {
1138 loadEffect(name);
1139 }
1140}
1141
1143{
1144 QStringList listModules;
1145 listModules.reserve(loaded_effects.count());
1146 std::transform(loaded_effects.constBegin(), loaded_effects.constEnd(),
1147 std::back_inserter(listModules),
1148 [](const EffectPair &pair) {
1149 return pair.first;
1150 });
1151 return listModules;
1152}
1153
1155{
1157}
1158
1159bool EffectsHandler::loadEffect(const QString &name)
1160{
1163
1164 return m_effectLoader->loadEffect(name);
1165}
1166
1167void EffectsHandler::unloadEffect(const QString &name)
1168{
1169 auto it = std::find_if(effect_order.begin(), effect_order.end(),
1170 [name](EffectPair &pair) {
1171 return pair.first == name;
1172 });
1173 if (it == effect_order.end()) {
1174 qCDebug(KWIN_CORE) << "EffectsHandler::unloadEffect : Effect not loaded :" << name;
1175 return;
1176 }
1177
1178 qCDebug(KWIN_CORE) << "EffectsHandler::unloadEffect : Unloading Effect :" << name;
1179 destroyEffect((*it).second);
1180 effect_order.erase(it);
1182
1184}
1185
1187{
1189
1190 if (fullscreen_effect == effect) {
1192 }
1193
1194 if (keyboard_grab_effect == effect) {
1196 }
1197
1198 stopMouseInterception(effect);
1199
1200 const QList<QByteArray> properties = m_propertiesForEffects.keys();
1201 for (const QByteArray &property : properties) {
1202 removeSupportProperty(property, effect);
1203 }
1204
1205 delete effect;
1206}
1207
1209{
1211 for (const EffectPair &pair : loaded_effects) {
1212 pair.second->reconfigure(Effect::ReconfigureAll);
1213 }
1214}
1215
1216void EffectsHandler::reconfigureEffect(const QString &name)
1217{
1218 for (QList<EffectPair>::const_iterator it = loaded_effects.constBegin(); it != loaded_effects.constEnd(); ++it) {
1219 if ((*it).first == name) {
1220 kwinApp()->config()->reparseConfiguration();
1222 (*it).second->reconfigure(Effect::ReconfigureAll);
1223 return;
1224 }
1225 }
1226}
1227
1228bool EffectsHandler::isEffectLoaded(const QString &name) const
1229{
1230 auto it = std::find_if(loaded_effects.constBegin(), loaded_effects.constEnd(),
1231 [&name](const EffectPair &pair) {
1232 return pair.first == name;
1233 });
1234 return it != loaded_effects.constEnd();
1235}
1236
1237bool EffectsHandler::isEffectSupported(const QString &name)
1238{
1239 // If the effect is loaded, it is obviously supported.
1240 if (isEffectLoaded(name)) {
1241 return true;
1242 }
1243
1244 // next checks might require a context
1246
1247 return m_effectLoader->isEffectSupported(name);
1248}
1249
1250QList<bool> EffectsHandler::areEffectsSupported(const QStringList &names)
1251{
1252 QList<bool> retList;
1253 retList.reserve(names.count());
1254 std::transform(names.constBegin(), names.constEnd(),
1255 std::back_inserter(retList),
1256 [this](const QString &name) {
1257 return isEffectSupported(name);
1258 });
1259 return retList;
1260}
1261
1263{
1264 QString effectName;
1265 for (QList<EffectPair>::const_iterator it = loaded_effects.constBegin(); it != loaded_effects.constEnd(); ++it) {
1266 if ((*it).second == effect) {
1267 effectName = (*it).first;
1268 break;
1269 }
1270 }
1271 if (!effectName.isNull()) {
1272 unloadEffect(effectName);
1273 m_effectLoader->loadEffect(effectName);
1274 }
1275}
1276
1278{
1279 loaded_effects.clear();
1280 m_activeEffects.clear(); // it's possible to have a reconfigure and a quad rebuild between two paint cycles - bug #308201
1281
1282 loaded_effects.reserve(effect_order.count());
1283 std::copy(effect_order.constBegin(), effect_order.constEnd(),
1284 std::back_inserter(loaded_effects));
1285
1286 m_activeEffects.reserve(loaded_effects.count());
1287
1291}
1292
1294{
1295 QStringList ret;
1296 for (QList<KWin::EffectPair>::const_iterator it = loaded_effects.constBegin(),
1297 end = loaded_effects.constEnd();
1298 it != end; ++it) {
1299 if (it->second->isActive()) {
1300 ret << it->first;
1301 }
1302 }
1303 return ret;
1304}
1305
1306bool EffectsHandler::isEffectActive(const QString &pluginId) const
1307{
1308 auto it = std::find_if(loaded_effects.cbegin(), loaded_effects.cend(), [&pluginId](const EffectPair &p) {
1309 return p.first == pluginId;
1310 });
1311 if (it == loaded_effects.cend()) {
1312 return false;
1313 }
1314 return it->second->isActive();
1315}
1316
1318{
1319 return std::any_of(m_activeEffects.constBegin(), m_activeEffects.constEnd(), [](const Effect *effect) {
1320 return effect->blocksDirectScanout();
1321 });
1322}
1323
1325{
1326 if (waylandServer()) {
1327 return waylandServer()->display();
1328 }
1329 return nullptr;
1330}
1331
1333{
1334 switch (kwopt) {
1335 case CloseButtonCorner: {
1336 // TODO: this could become per window and be derived from the actual position in the deco
1337 const auto settings = Workspace::self()->decorationBridge()->settings();
1338 return settings && settings->decorationButtonsLeft().contains(KDecoration2::DecorationButtonType::Close) ? Qt::TopLeftCorner : Qt::TopRightCorner;
1339 }
1344 default:
1345 return QVariant(); // an invalid one
1346 }
1347}
1348
1349QString EffectsHandler::supportInformation(const QString &name) const
1350{
1351 auto it = std::find_if(loaded_effects.constBegin(), loaded_effects.constEnd(),
1352 [name](const EffectPair &pair) {
1353 return pair.first == name;
1354 });
1355 if (it == loaded_effects.constEnd()) {
1356 return QString();
1357 }
1358
1359 QString support((*it).first + QLatin1String(":\n"));
1360 const QMetaObject *metaOptions = (*it).second->metaObject();
1361 for (int i = 0; i < metaOptions->propertyCount(); ++i) {
1362 const QMetaProperty property = metaOptions->property(i);
1363 if (qstrcmp(property.name(), "objectName") == 0) {
1364 continue;
1365 }
1366 support += QString::fromUtf8(property.name()) + QLatin1String(": ") + (*it).second->property(property.name()).toString() + QLatin1Char('\n');
1367 }
1368
1369 return support;
1370}
1371
1373{
1374#if KWIN_BUILD_SCREENLOCKER
1375 return kwinApp()->screenLockerWatcher()->isLocked();
1376#else
1377 return false;
1378#endif
1379}
1380
1381QString EffectsHandler::debug(const QString &name, const QString &parameter) const
1382{
1383 QString internalName = name.toLower();
1384 for (QList<EffectPair>::const_iterator it = loaded_effects.constBegin(); it != loaded_effects.constEnd(); ++it) {
1385 if ((*it).first == internalName) {
1386 return it->second->debug(parameter);
1387 }
1388 }
1389 return QString();
1390}
1391
1396
1401
1403{
1404 static const QByteArray forceEnvVar = qgetenv("KWIN_EFFECTS_FORCE_ANIMATIONS");
1405 if (!forceEnvVar.isEmpty()) {
1406 static const int forceValue = forceEnvVar.toInt();
1407 return forceValue == 1;
1408 }
1409 return m_scene->animationsSupported();
1410}
1411
1412void EffectsHandler::highlightWindows(const QList<EffectWindow *> &windows)
1413{
1415 if (!e) {
1416 return;
1417 }
1418 e->perform(Effect::HighlightWindows, QVariantList{QVariant::fromValue(windows)});
1419}
1420
1422{
1423 return kwinApp()->cursorImage();
1424}
1425
1430
1435
1437{
1438 kwinApp()->startInteractiveWindowSelection([callback](KWin::Window *window) {
1439 if (window && window->effectWindow()) {
1440 callback(window->effectWindow());
1441 } else {
1442 callback(nullptr);
1443 }
1444 });
1445}
1446
1447void EffectsHandler::startInteractivePositionSelection(std::function<void(const QPointF &)> callback)
1448{
1449 kwinApp()->startInteractivePositionSelection(callback);
1450}
1451
1452void EffectsHandler::showOnScreenMessage(const QString &message, const QString &iconName)
1453{
1454 OSD::show(message, iconName);
1455}
1456
1457void EffectsHandler::hideOnScreenMessage(OnScreenMessageHideFlags flags)
1458{
1459 OSD::HideFlags osdFlags;
1462 }
1463 OSD::hide(osdFlags);
1464}
1465
1466KSharedConfigPtr EffectsHandler::config() const
1467{
1468 return kwinApp()->config();
1469}
1470
1471KSharedConfigPtr EffectsHandler::inputConfig() const
1472{
1473 return kwinApp()->inputConfig();
1474}
1475
1476Effect *EffectsHandler::findEffect(const QString &name) const
1477{
1478 auto it = std::find_if(loaded_effects.constBegin(), loaded_effects.constEnd(), [name](const EffectPair &pair) {
1479 return pair.first == name;
1480 });
1481 if (it == loaded_effects.constEnd()) {
1482 return nullptr;
1483 }
1484 return (*it).second;
1485}
1486
1488{
1489 if (!w->isVisible()) {
1490 return;
1491 }
1493 GLTexture *t = w->bufferAsTexture();
1494 if (!t) {
1495 return;
1496 }
1497
1499 const qreal a = w->opacity();
1500 if (a != 1.0) {
1501 traits |= ShaderTrait::Modulate;
1502 }
1503
1504 GLShader *shader = ShaderManager::instance()->pushShader(traits);
1505 const QRectF rect = scaledRect(w->geometry(), viewport.scale());
1506
1507 QMatrix4x4 mvp(viewport.projectionMatrix());
1508 mvp.translate(rect.x(), rect.y());
1510
1511 if (a != 1.0) {
1512 shader->setUniform(GLShader::Vec4Uniform::ModulationConstant, QVector4D(a, a, a, a));
1513 }
1514 shader->setColorspaceUniformsFromSRGB(renderTarget.colorDescription());
1515
1516 const bool alphaBlending = w->hasAlphaChannel() || (a != 1.0);
1517 if (alphaBlending) {
1518 glEnable(GL_BLEND);
1519 glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
1520 }
1521
1522 t->render(rect.size());
1523
1524 if (alphaBlending) {
1525 glDisable(GL_BLEND);
1526 }
1527
1529 } else if (compositingType() == QPainterCompositing) {
1530 QPainter *painter = effects->scenePainter();
1531 const QImage buffer = w->bufferAsImage();
1532 if (buffer.isNull()) {
1533 return;
1534 }
1535 painter->save();
1536 painter->setOpacity(w->opacity());
1537 painter->drawImage(w->geometry(), buffer);
1538 painter->restore();
1539 }
1540}
1541
1546
1547QList<Output *> EffectsHandler::screens() const
1548{
1549 return Workspace::self()->outputs();
1550}
1551
1552Output *EffectsHandler::screenAt(const QPoint &point) const
1553{
1554 return Workspace::self()->outputAt(point);
1555}
1556
1557Output *EffectsHandler::findScreen(const QString &name) const
1558{
1559 const auto outputs = Workspace::self()->outputs();
1560 for (Output *screen : outputs) {
1561 if (screen->name() == name) {
1562 return screen;
1563 }
1564 }
1565 return nullptr;
1566}
1567
1569{
1570 return Workspace::self()->outputs().value(screenId);
1571}
1572
1574{
1575 return Cursors::self()->isCursorHidden();
1576}
1577
1579{
1580 if (!kwinApp()->inputMethod() || !kwinApp()->inputMethod()->isEnabled()) {
1581 return nullptr;
1582 }
1583
1584 auto panel = kwinApp()->inputMethod()->panel();
1585 if (panel) {
1586 return panel->effectWindow();
1587 }
1588 return nullptr;
1589}
1590
1592{
1593 if (!kwinApp()->inputMethod() || !kwinApp()->inputMethod()->isEnabled()) {
1594 return true;
1595 }
1596
1597 auto panel = kwinApp()->inputMethod()->panel();
1598 if (panel) {
1599 return panel->mode() == InputPanelV1Window::Mode::Overlay;
1600 }
1601 return true;
1602}
1603
1604QQmlEngine *EffectsHandler::qmlEngine() const
1605{
1606 return Scripting::self()->qmlEngine();
1607}
1608
1610
1611} // namespace
1612
1613#include "moc_effecthandler.cpp"
1614#include "moc_globals.cpp"
void effectLoaded(KWin::Effect *effect, const QString &name)
The loader emits this signal when it successfully loaded an effect.
void added(const QString &id)
void currentChanged(const QString &id)
void removed(const QString &id)
void x11ConnectionChanged()
WorkspaceScene * scene() const
Definition compositor.h:60
void keepSupportProperty(xcb_atom_t atom)
void removeSupportProperty(xcb_atom_t atom)
QPointF pos()
Definition cursor.cpp:204
void mouseChanged(const QPointF &pos, const QPointF &oldpos, Qt::MouseButtons buttons, Qt::MouseButtons oldbuttons, Qt::KeyboardModifiers modifiers, Qt::KeyboardModifiers oldmodifiers)
void startMousePolling()
Definition cursor.cpp:283
void startCursorTracking()
Enables tracking changes of cursor images.
Definition cursor.cpp:308
void cursorChanged()
Signal emitted when the cursor image changes.
void stopCursorTracking()
Disables tracking changes of cursor images.
Definition cursor.cpp:316
void stopMousePolling()
Definition cursor.cpp:291
void hideCursor()
Definition cursor.cpp:69
static Cursors * self()
Definition cursor.cpp:35
bool isCursorHidden() const
Definition cursor.cpp:85
void showCursor()
Definition cursor.cpp:77
Cursor * mouse() const
Definition cursor.h:266
std::unique_ptr< KDecoration2::DecorationSettingsPrivate > settings(KDecoration2::DecorationSettings *parent) override
Class holding the Wayland server display loop.
Definition display.h:34
Base class for all KWin effects.
Definition effect.h:535
void clear() override
Clears the load queue, that is all scheduled Effects are discarded from loading.
QStringList listOfKnownEffects() const override
All the Effects this loader knows of.
void setConfig(KSharedConfig::Ptr config) override
The KSharedConfig this EffectLoader should operate on.
bool isEffectSupported(const QString &name) const override
Whether the Effect with the given name is supported by the compositing backend.
void queryAndLoadAll() override
The Effect Loader should query its store for all available effects and try to load them.
bool loadEffect(const QString &name) override
Synchronous loading of the Effect with the given name.
Representation of a window used by/for Effect classes.
WindowItem * windowItem() const
Window * window() const
Manager class that handles all the effects.
void showingDesktopChanged(bool)
std::unique_ptr< WindowPropertyNotifyX11Filter > m_x11WindowPropertyNotify
void screenAdded(KWin::Output *screen)
void setupWindowConnections(KWin::Window *window)
bool hasKeyboardGrab() const
Display * waylandDisplay() const
Q_SCRIPTABLE bool isEffectSupported(const QString &name)
void desktopGridSizeChanged(const QSize &size)
void drawWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, const QRegion &region, WindowPaintData &data)
EffectsIterator m_currentPaintWindowIterator
Q_SCRIPTABLE void unloadEffect(const QString &name)
void screenLockingChanged(bool locked)
void windowDeleted(KWin::EffectWindow *w)
void stopMouseInterception(Effect *effect)
CompositingType compositing_type
bool animationsSupported() const
Q_SCRIPTABLE KWin::VirtualDesktop * desktopAbove(KWin::VirtualDesktop *desktop=nullptr, bool wrap=true) const
Q_SCRIPTABLE KWin::EffectWindow * findWindow(WId id) const
QPoint desktopGridCoords(VirtualDesktop *desktop) const
void removeSupportProperty(const QByteArray &propertyName, Effect *effect)
Removes support for the feature with the given name. If there is no other Effect left which has annou...
void paintScreen(const RenderTarget &renderTarget, const RenderViewport &viewport, int mask, const QRegion &region, Output *screen)
Q_SCRIPTABLE void windowToDesktops(KWin::EffectWindow *w, const QList< KWin::VirtualDesktop * > &desktops)
void currentActivityChanged(const QString &id)
void screenRemoved(KWin::Output *screen)
void reloadEffect(Effect *effect)
Q_SCRIPTABLE KWin::VirtualDesktop * desktopBelow(KWin::VirtualDesktop *desktop=nullptr, bool wrap=true) const
void desktopChanging(KWin::VirtualDesktop *currentDesktop, QPointF offset, KWin::EffectWindow *with)
QList< Effect * > m_grabbedMouseEffects
EffectsIterator m_currentPaintScreenIterator
void destroyEffect(Effect *effect)
bool blocksDirectScanout() const
bool isMouseInterception() const
QQmlEngine * qmlEngine() const
void activateWindow(KWin::EffectWindow *c)
Effect * provides(Effect::Feature ef)
Q_SCRIPTABLE QString desktopName(KWin::VirtualDesktop *desktop) const
void windowActivated(KWin::EffectWindow *w)
QList< EffectWindow * > stackingOrder
QStringList loadedEffects
void startInteractivePositionSelection(std::function< void(const QPointF &)> callback)
void highlightWindows(const QList< EffectWindow * > &windows)
EffectLoader * m_effectLoader
Q_SCRIPTABLE void addRepaint(const QRectF &r)
Compositor * m_compositor
void grabbedKeyboardEvent(QKeyEvent *e)
PropertyEffectMap m_propertiesForEffects
Q_SCRIPTABLE bool loadEffect(const QString &name)
void showOnScreenMessage(const QString &message, const QString &iconName=QString())
QHash< long, int > registered_atoms
void tabBoxKeyEvent(QKeyEvent *event)
void unregisterTouchBorder(ElectricBorder border, QAction *action)
bool makeOpenGLContextCurrent()
Makes the OpenGL compositing context current.
CompositingType compositingType
Q_SCRIPTABLE QString debug(const QString &name, const QString &parameter=QString()) const
void registerPointerShortcut(Qt::KeyboardModifiers modifiers, Qt::MouseButton pointerButtons, QAction *action)
Registers a global pointer shortcut with the provided action.
Q_SCRIPTABLE void setElevatedWindow(KWin::EffectWindow *w, bool set)
bool tabletPadButtonEvent(uint button, bool pressed, const KWin::TabletPadId &tabletPadId, std::chrono::microseconds time)
QByteArray readRootProperty(long atom, long type, int format) const
virtual void defineCursor(Qt::CursorShape shape)
bool tabletToolEvent(KWin::TabletEvent *event)
void setActiveFullScreenEffect(Effect *e)
QPoint desktopCoords(VirtualDesktop *desktop) const
Q_SCRIPTABLE void moveWindow(KWin::EffectWindow *w, const QPoint &pos, bool snap=false, double snapAdjust=1.0)
void startMouseInterception(Effect *effect, Qt::CursorShape shape)
void desktopRemoved(KWin::VirtualDesktop *desktop)
virtual void doCheckInputWindowStacking()
virtual bool doGrabKeyboard()
Output * screenAt(const QPoint &point) const
void setTabBoxWindow(EffectWindow *)
KSharedConfigPtr inputConfig() const
Output * findScreen(const QString &name) const
void paintWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, const QRegion &region, WindowPaintData &data)
bool grabKeyboard(Effect *effect)
void connectNotify(const QMetaMethod &signal) override
Q_SCRIPTABLE void reconfigureEffect(const QString &name)
KWin::VirtualDesktop * currentDesktop
void doneOpenGLContextCurrent()
Makes a null OpenGL context current resulting in no context being current.
void setShowingDesktop(bool showing)
KWin::EffectWindow * activeWindow
xcb_atom_t announceSupportProperty(const QByteArray &propertyName, Effect *effect)
Announces support for the feature with the given name. If no other Effect has announced support for t...
void reserveElectricBorder(ElectricBorder border, Effect *effect)
void desktopAdded(KWin::VirtualDesktop *desktop)
void registerAxisShortcut(Qt::KeyboardModifiers modifiers, PointerAxisDirection axis, QAction *action)
Registers a global axis shortcut with the provided action.
QVariant kwinOption(KWinOption kwopt)
KWin::EffectWindow * inputPanel
bool checkInputWindowEvent(QMouseEvent *e)
virtual void doUngrabKeyboard()
void virtualScreenGeometryChanged()
Q_SCRIPTABLE void toggleEffect(const QString &name)
QList< EffectWindow * > currentTabBoxWindowList() const
Q_SCRIPTABLE QString supportInformation(const QString &name) const
bool touchMotion(qint32 id, const QPointF &pos, std::chrono::microseconds time)
QHash< QByteArray, qulonglong > m_managedProperties
Effect * findEffect(const QString &name) const
Q_SCRIPTABLE QList< bool > areEffectsSupported(const QStringList &names)
QList< EffectPair > loaded_effects
void prePaintScreen(ScreenPrePaintData &data, std::chrono::milliseconds presentTime)
bool hasDecorationShadows() const
virtual void doStartMouseInterception(Qt::CursorShape shape)
void registerTouchpadPinchShortcut(PinchDirection dir, uint fingerCount, QAction *onUp, std::function< void(qreal)> progressCallback={})
EffectsIterator m_currentDrawWindowIterator
void registerTouchpadSwipeShortcut(SwipeDirection dir, uint fingerCount, QAction *onUp, std::function< void(qreal)> progressCallback={})
Registers a global touchpad swipe gesture shortcut with the provided action.
bool touchUp(qint32 id, std::chrono::microseconds time)
EffectsList m_activeEffects
void desktopGridWidthChanged(int width)
Q_SCRIPTABLE bool isEffectLoaded(const QString &name) const
Q_SCRIPTABLE void windowToScreen(KWin::EffectWindow *w, Output *screen)
void setCurrentDesktop(KWin::VirtualDesktop *desktop)
virtual void doStopMouseInterception()
QList< Output * > screens() const
EffectWindow * currentTabBoxWindow() const
void disconnectNotify(const QMetaMethod &signal) override
QStringList listOfEffects
bool isOpenGLCompositing() const
Whether the Compositor is OpenGL based (either GL 1 or 2).
Q_SCRIPTABLE KWin::VirtualDesktop * desktopToRight(KWin::VirtualDesktop *desktop=nullptr, bool wrap=true) const
void registerTouchscreenSwipeShortcut(SwipeDirection direction, uint fingerCount, QAction *action, std::function< void(qreal)> progressCallback)
Registers a global touchscreen swipe gesture shortcut with the provided action.
void renderOffscreenQuickView(const RenderTarget &renderTarget, const RenderViewport &viewport, OffscreenQuickView *effectQuickView) const
KWin::SessionState sessionState
bool tabletPadRingEvent(int number, int position, bool isFinger, const KWin::TabletPadId &tabletPadId, std::chrono::microseconds time)
void prePaintWindow(EffectWindow *w, WindowPrePaintData &data, std::chrono::milliseconds presentTime)
WorkspaceScene * m_scene
EffectsHandler(Compositor *compositor, WorkspaceScene *scene)
void activityRemoved(const QString &id)
bool tabletToolButtonEvent(uint button, bool pressed, const KWin::TabletToolId &tabletToolId, std::chrono::microseconds time)
void startInteractiveWindowSelection(std::function< void(KWin::EffectWindow *)> callback)
QMultiMap< int, EffectPair > effect_order
void desktopChanged(KWin::VirtualDesktop *oldDesktop, KWin::VirtualDesktop *newDesktop, KWin::EffectWindow *with)
xcb_connection_t * xcbConnection() const
void screenEdgeApproaching(ElectricBorder border, qreal factor, const QRect &geometry)
void desktopGridHeightChanged(int height)
void mouseChanged(const QPointF &pos, const QPointF &oldpos, Qt::MouseButtons buttons, Qt::MouseButtons oldbuttons, Qt::KeyboardModifiers modifiers, Qt::KeyboardModifiers oldmodifiers)
void hideOnScreenMessage(OnScreenMessageHideFlags flags=OnScreenMessageHideFlags())
void unreserveElectricBorder(ElectricBorder border, Effect *effect)
PlatformCursorImage cursorImage() const
std::function< void(ElectricBorder border, const QPointF &, Output *screen)> TouchBorderCallback
void registerRealtimeTouchBorder(ElectricBorder border, QAction *action, TouchBorderCallback progressCallback)
Q_SCRIPTABLE KWin::VirtualDesktop * desktopToLeft(KWin::VirtualDesktop *desktop=nullptr, bool wrap=true) const
QRectF clientArea(clientAreaOption, const Output *screen, const VirtualDesktop *desktop) const
void registerPropertyType(long atom, bool reg)
bool isInputPanelOverlay() const
void desktopChangingCancelled()
xcb_window_t x11RootWindow() const
bool touchDown(qint32 id, const QPointF &pos, std::chrono::microseconds time)
QList< KWin::VirtualDesktop * > desktops
void hasActiveFullScreenEffectChanged()
KSharedConfigPtr config() const
QStringList activeEffects
KWin::Output * activeScreen
void windowAdded(KWin::EffectWindow *w)
void renderWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, const QRegion &region, WindowPaintData &data)
Q_SCRIPTABLE void addRepaintFull()
VirtualDesktop * desktopAtCoords(QPoint coords) const
Effect * activeFullScreenEffect() const
void registerTouchBorder(ElectricBorder border, QAction *action)
QPainter * scenePainter()
Provides access to the QPainter which is rendering to the back buffer.
bool isEffectActive(const QString &pluginId) const
void activeFullScreenEffectChanged()
void activityAdded(const QString &id)
bool tabletPadStripEvent(int number, int position, bool isFinger, const KWin::TabletPadId &tabletPadId, std::chrono::microseconds time)
void postPaintWindow(EffectWindow *w)
void tabBoxAdded(int mode)
void virtualScreenSizeChanged()
bool setColorspaceUniformsFromSRGB(const ColorDescription &dst)
Definition glshader.cpp:457
bool setUniform(const char *name, float value)
Definition glshader.cpp:301
void render(const QSizeF &size)
void registerPointerShortcut(Qt::KeyboardModifiers modifiers, Qt::MouseButton pointerButtons, QAction *action)
Definition input.cpp:3314
void registerTouchscreenSwipeShortcut(SwipeDirection direction, uint32_t fingerCount, QAction *action, std::function< void(qreal)> progressCallback={})
KeyboardInputRedirection * keyboard() const
Definition input.h:216
void registerAxisShortcut(Qt::KeyboardModifiers modifiers, PointerAxisDirection axis, QAction *action)
void registerTouchpadPinchShortcut(PinchDirection direction, uint32_t fingerCount, QAction *onUp, std::function< void(qreal)> progressCallback={})
PointerInputRedirection * pointer() const
Definition input.h:220
void registerTouchpadSwipeShortcut(SwipeDirection direction, uint32_t fingerCount, QAction *onUp, std::function< void(qreal)> progressCallback={})
virtual QPainter * painter() const
The KwinQuickView class provides a convenient API for exporting QtQuick scenes as buffers that can be...
double animationTimeFactor() const
Definition options.cpp:1005
void animationSpeedChanged()
bool isRollOverDesktops() const
Definition options.h:385
void setEffectsOverrideCursor(Qt::CursorShape shape)
const ColorDescription & colorDescription() const
QMatrix4x4 projectionMatrix() const
void addRepaintFull()
Definition scene.cpp:81
void addRepaint(const QRegion &region)
Definition scene.cpp:91
ItemRenderer * renderer() const
Definition scene.cpp:76
void unreserveTouch(ElectricBorder border, QAction *action)
void approaching(ElectricBorder border, qreal factor, const QRect &geometry)
void reserve(ElectricBorder border, QObject *object, const char *callback)
bool isDesktopSwitchingMovingClients() const
Definition screenedge.h:554
void unreserve(ElectricBorder border, QObject *object)
void reserveTouch(ElectricBorder border, QAction *action, TouchCallback::CallbackFunction callback=nullptr)
bool isDesktopSwitching() const
Definition screenedge.h:549
void locked(bool locked)
static Scripting * self()
Definition scripting.h:393
QQmlEngine * qmlEngine() const
Definition scripting.h:368
SessionState state() const
Definition sm.cpp:361
static ShaderManager * instance()
GLShader * pushShader(ShaderTraits traits)
Resource representing a wl_surface.
Definition surface.h:80
void tabBoxKeyEvent(QKeyEvent *)
Manages the number of available virtual desktops, the layout of those and which virtual desktop is th...
void layoutChanged(int columns, int rows)
void desktopAdded(KWin::VirtualDesktop *desktop)
void desktopRemoved(KWin::VirtualDesktop *desktop)
Display * display() const
void endInteractiveMoveResize()
Definition window.cpp:2614
EffectWindow * effectWindow()
Definition window.cpp:279
bool move
Definition window.h:437
void setDesktops(QList< VirtualDesktop * > desktops)
Definition window.cpp:726
Window * activeWindow() const
Definition workspace.h:767
QRectF clientArea(clientAreaOption, const Output *output, const VirtualDesktop *desktop) const
ScreenEdges * screenEdges() const
void outputAdded(KWin::Output *)
void activateWindow(Window *window, bool force=false)
void currentDesktopChangingCancelled()
const QList< Window * > & stackingOrder() const
Definition workspace.h:788
void sendWindowToOutput(Window *window, Output *output)
void stackingOrderChanged()
Output * activeOutput() const
void showingDesktopChanged(bool showing, bool animated)
Window * moveResizeWindow()
Definition workspace.h:396
void currentDesktopChanged(KWin::VirtualDesktop *previousDesktop, KWin::Window *)
void currentDesktopChanging(KWin::VirtualDesktop *currentDesktop, QPointF delta, KWin::Window *)
void windowActivated(KWin::Window *)
Decoration::DecorationBridge * decorationBridge() const
static Workspace * self()
Definition workspace.h:91
void windowAdded(KWin::Window *)
QList< Output * > outputs() const
Definition workspace.h:762
const QList< Window * > windows() const
Definition workspace.h:248
void setShowingDesktop(bool showing, bool animated=true)
QRect geometry() const
Output * outputAt(const QPointF &pos) const
void outputRemoved(KWin::Output *)
void geometryChanged()
SessionManager * sessionManager() const
Definition workspace.h:799
void deletedRemoved(KWin::Window *)
virtual bool makeOpenGLContextCurrent()
void finalPaintScreen(const RenderTarget &renderTarget, const RenderViewport &viewport, int mask, const QRegion &region, Output *screen)
void finalDrawWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, const QRegion &region, WindowPaintData &data)
virtual void doneOpenGLContextCurrent()
void finalPaintWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, const QRegion &region, WindowPaintData &data)
virtual bool animationsSupported() const =0
virtual int requestedEffectChainPosition() const
Definition effect.cpp:495
virtual bool perform(Feature feature, const QVariantList &arguments)
Definition effect.cpp:515
virtual void grabbedKeyboardEvent(QKeyEvent *e)
Definition effect.cpp:403
@ ReconfigureAll
Definition effect.h:601
@ HighlightWindows
Definition effect.h:579
void show(const QString &message, const QString &iconName, int timeout)
Definition osd.cpp:35
void hide(HideFlags flags)
Definition osd.cpp:66
TabBoxHandler * tabBox
PointerAxisDirection
The direction in which a pointer axis is moved.
Definition globals.h:104
Session::Type type
Definition session.cpp:17
SessionState
Definition globals.h:132
clientAreaOption
Definition globals.h:48
KWinOption
Definition globals.h:95
@ CloseButtonCorner
Definition globals.h:96
@ SwitchDesktopOnScreenEdgeMovingWindows
Definition globals.h:98
@ SwitchDesktopOnScreenEdge
Definition globals.h:97
GLenum format
Definition gltexture.cpp:49
ElectricBorder
Definition globals.h:60
WaylandServer * waylandServer()
Workspace * workspace()
Definition workspace.h:830
PinchDirection
Definition globals.h:123
CompositingType
Definition globals.h:28
@ QPainterCompositing
Definition globals.h:39
@ NoCompositing
Definition globals.h:29
@ OpenGLCompositing
Definition globals.h:37
Options * options
Definition main.cpp:73
SwipeDirection
Directions for swipe gestures.
Definition globals.h:115
InputRedirection * input()
Definition input.h:549
QPair< QString, Effect * > EffectPair
KWIN_EXPORT QRectF scaledRect(const QRectF &rect, qreal scale)
Definition globals.h:243
EffectsHandler * effects