Refactor Toplevel::opacity

The major difference between this version and the previous is that kwin
no longer forwards the opacity to the app window if it runs as a
window window manager and a compositing manager. As Keith Packard said [1]

> The window manager support is only needed to forward the property from the
> application window to the frame; with the Composite extension, a
> compositing manager can then take that value into account when
> constructing the desktop image.  Any X server can implement the Composite
> extension; the one in the X server project at freedesktop.org is just one
> such.  It would be trivial to implement this extension in a direct FB
> based X server, or any other X server which places windows in off-screen
> images.

There are a couple of reasons to do so: (a) simplifies code, (b) we don't
temper with opacities on override-redirect windows.

[1] https://listman.redhat.com/archives/xdg-list/2003-December/msg00153.html
icc-effect-5.26.4
Vlad Zahorodnii 2021-02-06 00:18:45 +02:00
parent 7995112550
commit 9acf04e2b7
10 changed files with 15 additions and 74 deletions

View File

@ -95,7 +95,6 @@ void Deleted::copyToDeleted(Toplevel* c)
transparent_rect = c->transparentRect();
m_layer = c->layer();
m_frame = c->frameId();
m_opacity = c->opacity();
m_type = c->windowType();
m_windowRole = c->windowRole();
if (WinInfo* cinfo = dynamic_cast< WinInfo* >(info))
@ -252,11 +251,6 @@ xcb_window_t Deleted::frameId() const
return m_frame;
}
double Deleted::opacity() const
{
return m_opacity;
}
QByteArray Deleted::windowRole() const
{
return m_windowRole;

View File

@ -64,7 +64,6 @@ public:
bool wasClient() const {
return m_wasClient;
}
double opacity() const override;
QByteArray windowRole() const override;
const Decoration::Renderer *decorationRenderer() const {
@ -206,7 +205,6 @@ private:
QList<AbstractClient*> m_mainClients;
bool m_wasClient;
Decoration::Renderer *m_decorationRenderer;
double m_opacity;
NET::WindowType m_type = NET::Unknown;
QByteArray m_windowRole;
bool m_fullscreen;

View File

@ -446,7 +446,6 @@ bool X11Client::windowEvent(xcb_generic_event_t *e)
if (findEventWindow(e) == window()) { // avoid doing stuff on frame or wrapper
NET::Properties dirtyProperties;
NET::Properties2 dirtyProperties2;
double old_opacity = opacity();
info->event(e, &dirtyProperties, &dirtyProperties2); // pass through the NET stuff
if ((dirtyProperties & NET::WMName) != 0)
@ -470,8 +469,7 @@ bool X11Client::windowEvent(xcb_generic_event_t *e)
startupIdChanged();
if (dirtyProperties2 & NET::WM2Opacity) {
if (compositing()) {
addRepaintFull();
emit opacityChanged(this, old_opacity);
setOpacity(info->opacityF());
} else {
// forward to the frame if there's possibly another compositing manager running
NETWinInfo i(connection(), frameId(), rootWindow(), NET::Properties(), NET::Properties2());
@ -1298,14 +1296,12 @@ void X11Client::keyPressEvent(uint key_code, xcb_timestamp_t time)
bool Unmanaged::windowEvent(xcb_generic_event_t *e)
{
double old_opacity = opacity();
NET::Properties dirtyProperties;
NET::Properties2 dirtyProperties2;
info->event(e, &dirtyProperties, &dirtyProperties2); // pass through the NET stuff
if (dirtyProperties2 & NET::WM2Opacity) {
if (compositing()) {
addRepaintFull();
emit opacityChanged(this, old_opacity);
setOpacity(info->opacityF());
}
}
if (dirtyProperties2 & NET::WM2OpaqueRegion) {

View File

@ -38,8 +38,6 @@ InternalClient::InternalClient(QWindow *window)
connect(m_internalWindow, &QWindow::opacityChanged, this, &InternalClient::setOpacity);
connect(m_internalWindow, &QWindow::destroyed, this, &InternalClient::destroyClient);
connect(this, &InternalClient::opacityChanged, this, &InternalClient::addRepaintFull);
const QVariant windowType = m_internalWindow->property("kwin_windowType");
if (!windowType.isNull()) {
m_windowType = windowType.value<NET::WindowType>();
@ -149,23 +147,6 @@ NET::WindowType InternalClient::windowType(bool direct, int supported_types) con
return m_windowType;
}
qreal InternalClient::opacity() const
{
return m_opacity;
}
void InternalClient::setOpacity(qreal opacity)
{
if (m_opacity == opacity) {
return;
}
const double oldOpacity = m_opacity;
m_opacity = opacity;
emit opacityChanged(this, oldOpacity);
}
void InternalClient::killWindow()
{
// We don't kill our internal windows.

View File

@ -35,8 +35,6 @@ public:
QSize maxSize() const override;
QRect transparentRect() const override;
NET::WindowType windowType(bool direct = false, int supported_types = 0) const override;
qreal opacity() const override;
void setOpacity(qreal opacity) override;
void killWindow() override;
bool isPopupWindow() const override;
QByteArray windowRole() const override;
@ -88,7 +86,6 @@ private:
QWindow *m_internalWindow = nullptr;
QString m_captionNormal;
QString m_captionSuffix;
qreal m_opacity = 1.0;
NET::WindowType m_windowType = NET::Normal;
Qt::WindowFlags m_internalWindowFlags = Qt::WindowFlags();
bool m_userNoBorder = false;

View File

@ -129,6 +129,7 @@ void Toplevel::copyToDeleted(Toplevel* c)
m_skipCloseAnimation = c->m_skipCloseAnimation;
m_internalFBO = c->m_internalFBO;
m_internalImage = c->m_internalImage;
m_opacity = c->m_opacity;
}
// before being deleted, remove references to everything that's now
@ -249,28 +250,20 @@ bool Toplevel::resourceMatch(const Toplevel *c1, const Toplevel *c2)
qreal Toplevel::opacity() const
{
if (!info) {
return 1.0;
}
if (info->opacity() == 0xffffffff)
return 1.0;
return info->opacity() * 1.0 / 0xffffffff;
return m_opacity;
}
void Toplevel::setOpacity(qreal new_opacity)
void Toplevel::setOpacity(qreal opacity)
{
if (!info) {
opacity = qBound(0.0, opacity, 1.0);
if (m_opacity == opacity) {
return;
}
qreal old_opacity = opacity();
new_opacity = qBound(0.0, new_opacity, 1.0);
if (old_opacity == new_opacity)
return;
info->setOpacity(static_cast< unsigned long >(new_opacity * 0xffffffff));
const qreal oldOpacity = m_opacity;
m_opacity = opacity;
if (compositing()) {
addRepaintFull();
emit opacityChanged(this, old_opacity);
emit opacityChanged(this, oldOpacity);
}
}

View File

@ -448,8 +448,8 @@ public:
xcb_visualid_t visual() const;
bool shape() const;
QRegion inputShape() const;
virtual void setOpacity(qreal opacity);
virtual qreal opacity() const;
void setOpacity(qreal opacity);
qreal opacity() const;
int depth() const;
bool hasAlpha() const;
virtual bool setupCompositing();
@ -756,6 +756,7 @@ private:
KWaylandServer::SurfaceInterface *m_surface = nullptr;
// when adding new data members, check also copyToDeleted()
qreal m_screenScale = 1.0;
qreal m_opacity = 1.0;
};
inline xcb_window_t Toplevel::window() const

View File

@ -107,23 +107,6 @@ bool WaylandClient::isLocalhost() const
return true;
}
qreal WaylandClient::opacity() const
{
return m_opacity;
}
void WaylandClient::setOpacity(qreal opacity)
{
const qreal newOpacity = qBound(0.0, opacity, 1.0);
if (newOpacity == m_opacity) {
return;
}
const qreal oldOpacity = m_opacity;
m_opacity = newOpacity;
addRepaintFull();
emit opacityChanged(this, oldOpacity);
}
AbstractClient *WaylandClient::findModal(bool allow_itself)
{
Q_UNUSED(allow_itself)

View File

@ -34,8 +34,6 @@ public:
pid_t pid() const override;
bool isLockScreen() const override;
bool isLocalhost() const override;
qreal opacity() const override;
void setOpacity(qreal opacity) override;
AbstractClient *findModal(bool allow_itself = false) override;
void resizeWithChecks(const QSize &size, ForceGeometry_t force = NormalGeometrySet) override;
void setFrameGeometry(const QRect &rect, ForceGeometry_t force = NormalGeometrySet) override;
@ -81,7 +79,6 @@ private:
QString m_captionNormal;
QString m_captionSuffix;
qreal m_opacity = 1.0;
QRect m_requestedFrameGeometry;
QRect m_bufferGeometry;
QRect m_requestedClientGeometry;

View File

@ -777,6 +777,7 @@ bool X11Client::manage(xcb_window_t w, bool isMapped)
demandAttention();
if (info->state() & NET::Modal)
setModal(true);
setOpacity(info->opacityF());
setFullScreen(rules()->checkFullScreen(info->state() & NET::FullScreen, !isMapped), false);
}
@ -876,7 +877,7 @@ bool X11Client::manage(xcb_window_t w, bool isMapped)
return;
}
NETWinInfo info(connection(), frameId(), rootWindow(), NET::Properties(), NET::Properties2());
info.setOpacity(static_cast<unsigned long>(opacity() * 0xffffffff));
info.setOpacityF(opacity());
}
);