KWin
Loading...
Searching...
No Matches
kscreen.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: 2013 Martin Gräßlin <mgraesslin@kde.org>
6
7 SPDX-License-Identifier: GPL-2.0-or-later
8*/
9// own
10#include "kscreen.h"
11#include "core/output.h"
13// KConfigSkeleton
14#include "kscreenconfig.h"
15#include <QDebug>
16
42Q_LOGGING_CATEGORY(KWIN_KSCREEN, "kwin_effect_kscreen", QtWarningMsg)
43
44namespace KWin
45{
46
48 : Effect()
49 , m_atom(effects->waylandDisplay() ? XCB_ATOM_NONE : effects->announceSupportProperty("_KDE_KWIN_KSCREEN_SUPPORT", this))
50{
51 KscreenConfig::instance(effects->config());
52 if (!effects->waylandDisplay()) {
53 connect(effects, &EffectsHandler::propertyNotify, this, &KscreenEffect::propertyNotify);
54 connect(effects, &EffectsHandler::xcbConnectionChanged, this, [this]() {
55 m_atom = effects->announceSupportProperty(QByteArrayLiteral("_KDE_KWIN_KSCREEN_SUPPORT"), this);
56 });
57 }
59
60 const QList<Output *> screens = effects->screens();
61 for (auto screen : screens) {
62 addScreen(screen);
63 }
64 connect(effects, &EffectsHandler::screenAdded, this, &KscreenEffect::addScreen);
65 connect(effects, &EffectsHandler::screenRemoved, this, [this](KWin::Output *screen) {
66 m_waylandStates.remove(screen);
67 });
68}
69
73
74void KscreenEffect::addScreen(Output *screen)
75{
76 connect(screen, &Output::wakeUp, this, [this, screen] {
77 auto &state = m_waylandStates[screen];
78 state.m_timeLine.setDuration(std::chrono::milliseconds(animationTime<KscreenConfig>(250)));
79 setState(state, StateFadingIn);
80 });
81 connect(screen, &Output::aboutToTurnOff, this, [this, screen](std::chrono::milliseconds dimmingIn) {
82 auto &state = m_waylandStates[screen];
83 state.m_timeLine.setDuration(dimmingIn);
84 setState(state, StateFadingOut);
85 });
86}
87
88void KscreenEffect::reconfigure(ReconfigureFlags flags)
89{
90 KscreenConfig::self()->read();
91 m_xcbState.m_timeLine.setDuration(
92 std::chrono::milliseconds(animationTime<KscreenConfig>(250)));
93}
94
95void KscreenEffect::prePaintScreen(ScreenPrePaintData &data, std::chrono::milliseconds presentTime)
96{
97 if (isScreenActive(data.screen)) {
98 auto &state = !effects->waylandDisplay() ? m_xcbState : m_waylandStates[data.screen];
99 m_currentScreen = data.screen;
100
101 if (state.m_state == StateFadingIn || state.m_state == StateFadingOut) {
102 state.m_timeLine.advance(presentTime);
103 if (state.m_timeLine.done()) {
104 switchState(state);
105 if (state.m_state == StateNormal) {
106 m_waylandStates.remove(data.screen);
107 }
108 }
109 }
110 }
111
112 effects->prePaintScreen(data, presentTime);
113}
114
116{
117 if (isScreenActive(m_currentScreen)) {
118 auto &state = !effects->waylandDisplay() ? m_xcbState : m_waylandStates[m_currentScreen];
119 if (state.m_state == StateFadingIn || state.m_state == StateFadingOut) {
121 }
122 }
123 m_currentScreen = nullptr;
124}
125
126void KscreenEffect::prePaintWindow(EffectWindow *w, WindowPrePaintData &data, std::chrono::milliseconds presentTime)
127{
128 auto screen = w->screen();
129 if (isScreenActive(screen)) {
130 auto &state = !effects->waylandDisplay() ? m_xcbState : m_waylandStates[screen];
131 if (state.m_state != StateNormal) {
132 data.setTranslucent();
133 }
134 }
135 effects->prePaintWindow(w, data, presentTime);
136}
137
138void KscreenEffect::paintWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, QRegion region, WindowPaintData &data)
139{
140 auto screen = w->screen();
141 if (isScreenActive(screen)) {
142 auto &state = !effects->waylandDisplay() ? m_xcbState : m_waylandStates[screen];
143 // fade to black and fully opaque
144 switch (state.m_state) {
145 case StateFadingOut:
146 data.setOpacity(data.opacity() + (1.0 - data.opacity()) * state.m_timeLine.value());
147 data.multiplyBrightness(1.0 - state.m_timeLine.value());
148 break;
149 case StateFadedOut:
150 data.multiplyOpacity(0.0);
151 data.multiplyBrightness(0.0);
152 break;
153 case StateFadingIn:
154 data.setOpacity(data.opacity() + (1.0 - data.opacity()) * (1.0 - state.m_timeLine.value()));
155 data.multiplyBrightness(state.m_timeLine.value());
156 break;
157 default:
158 // no adjustment
159 break;
160 }
161 }
162 effects->paintWindow(renderTarget, viewport, w, mask, region, data);
163}
164
165void KscreenEffect::setState(ScreenState &state, FadeOutState newState)
166{
167 if (state.m_state == newState) {
168 return;
169 }
170
171 state.m_state = newState;
172 state.m_timeLine.reset();
174}
175
176void KscreenEffect::propertyNotify(EffectWindow *window, long int atom)
177{
178 if (window || atom != m_atom || m_atom == XCB_ATOM_NONE) {
179 return;
180 }
181
182 const QByteArray byteData = effects->readRootProperty(m_atom, XCB_ATOM_CARDINAL, 32);
183 const uint32_t *data = byteData.isEmpty() ? nullptr : reinterpret_cast<const uint32_t *>(byteData.data());
184 if (!data || data[0] >= LastState) { // Property was deleted
185 if (data) {
186 qCDebug(KWIN_KSCREEN) << "Incorrect Property state, immediate stop: " << data[0];
187 }
188 setState(m_xcbState, StateNormal);
189 return;
190 }
191
192 setState(m_xcbState, FadeOutState(data[0]));
193}
194
195void KscreenEffect::switchState(ScreenState &state)
196{
197 long value = -1l;
198 if (state.m_state == StateFadingOut) {
199 state.m_state = StateFadedOut;
200 value = 2l;
201 } else if (state.m_state == StateFadingIn) {
202 state.m_state = StateNormal;
203 value = 0l;
204 }
205 if (value != -1l && m_atom != XCB_ATOM_NONE) {
206 xcb_change_property(effects->xcbConnection(), XCB_PROP_MODE_REPLACE, effects->x11RootWindow(), m_atom, XCB_ATOM_CARDINAL, 32, 1, &value);
207 }
208}
209
211{
212 return !m_waylandStates.isEmpty() || (!effects->waylandDisplay() && m_atom && m_xcbState.m_state != StateNormal);
213}
214
215bool KscreenEffect::isScreenActive(Output *screen) const
216{
217 return m_waylandStates.contains(screen) || (!effects->waylandDisplay() && m_atom && m_xcbState.m_state != StateNormal);
218}
219
220} // namespace KWin
221
222#include "moc_kscreen.cpp"
Base class for all KWin effects.
Definition effect.h:535
Representation of a window used by/for Effect classes.
KWin::Output * screen
void screenAdded(KWin::Output *screen)
Display * waylandDisplay() const
void propertyNotify(KWin::EffectWindow *w, long atom)
void screenRemoved(KWin::Output *screen)
QByteArray readRootProperty(long atom, long type, int format) const
void paintWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, const QRegion &region, WindowPaintData &data)
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 prePaintScreen(ScreenPrePaintData &data, std::chrono::milliseconds presentTime)
QList< Output * > screens() const
void prePaintWindow(EffectWindow *w, WindowPrePaintData &data, std::chrono::milliseconds presentTime)
xcb_connection_t * xcbConnection() const
xcb_window_t x11RootWindow() const
KSharedConfigPtr config() const
Q_SCRIPTABLE void addRepaintFull()
void prePaintScreen(ScreenPrePaintData &data, std::chrono::milliseconds presentTime) override
Definition kscreen.cpp:95
~KscreenEffect() override
Definition kscreen.cpp:70
void prePaintWindow(EffectWindow *w, WindowPrePaintData &data, std::chrono::milliseconds presentTime) override
Definition kscreen.cpp:126
void reconfigure(ReconfigureFlags flags) override
Definition kscreen.cpp:88
void paintWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, QRegion region, WindowPaintData &data) override
Definition kscreen.cpp:138
bool isActive() const override
Definition kscreen.cpp:210
void postPaintScreen() override
Definition kscreen.cpp:115
void aboutToTurnOff(std::chrono::milliseconds time)
void setDuration(std::chrono::milliseconds duration)
Definition timeline.cpp:103
qreal multiplyOpacity(qreal factor)
Definition effect.cpp:309
void setOpacity(qreal opacity)
Definition effect.cpp:279
qreal multiplyBrightness(qreal factor)
Definition effect.cpp:321
qreal opacity() const
Definition effect.cpp:259
@ ReconfigureAll
Definition effect.h:601
EffectsHandler * effects