Add a dedicated X11EventFilter for forwarding property events to the effect system

Summary:
So far both Workspace and Toplevel emitted signals for every property
notify event on the root window and the respective Toplevel windows. The
signals were only used in EffectsHandlerImpl to forward to the effect
system in case the property which changed is registered by an effect.

This change introduces a dedicated event filter for this which is only
created in EffectsHandlerImpl in case an X11 connection is available. It
supports a restart of the X11 system.

The signals used so far are removed from Workspace and Toplevel.

Reviewers: #kwin, #plasma

Subscribers: plasma-devel, kwin

Tags: #kwin

Differential Revision: https://phabricator.kde.org/D7853
icc-effect-5.14.5
Martin Flöser 2017-09-16 19:25:33 +02:00
parent e492f9e298
commit 0ed609590b
8 changed files with 109 additions and 28 deletions

View File

@ -457,6 +457,7 @@ set(kwin_KDEINIT_SRCS
was_user_interaction_x11_filter.cpp
moving_client_x11_filter.cpp
effects_mouse_interception_x11_filter.cpp
window_property_notify_x11_filter.cpp
)
if(KWIN_BUILD_TABBOX)

View File

@ -43,6 +43,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "screenlockerwatcher.h"
#include "thumbnailitem.h"
#include "virtualdesktops.h"
#include "window_property_notify_x11_filter.h"
#include "workspace.h"
#include "kwinglutils.h"
@ -192,13 +193,6 @@ EffectsHandlerImpl::EffectsHandlerImpl(Compositor *compositor, Scene *scene)
);
connect(vds, &VirtualDesktopManager::countChanged, this, &EffectsHandler::numberDesktopsChanged);
connect(Cursor::self(), &Cursor::mouseChanged, this, &EffectsHandler::mouseChanged);
connect(ws, &Workspace::propertyNotify, this,
[this](long int atom) {
if (!registered_atoms.contains(atom))
return;
emit propertyNotify(nullptr, atom);
}
);
connect(screens(), &Screens::countChanged, this, &EffectsHandler::numberScreensChanged);
connect(screens(), &Screens::sizeChanged, this, &EffectsHandler::virtualScreenSizeChanged);
connect(screens(), &Screens::geometryChanged, this, &EffectsHandler::virtualScreenGeometryChanged);
@ -232,10 +226,19 @@ EffectsHandlerImpl::EffectsHandlerImpl(Compositor *compositor, Scene *scene)
m_managedProperties.insert(*it, atom);
registerPropertyType(atom, true);
}
if (kwinApp()->x11Connection()) {
m_x11WindowPropertyNotify = std::make_unique<WindowPropertyNotifyX11Filter>(this);
} else {
m_x11WindowPropertyNotify.reset();
}
emit xcbConnectionChanged();
}
);
if (kwinApp()->x11Connection()) {
m_x11WindowPropertyNotify = std::make_unique<WindowPropertyNotifyX11Filter>(this);
}
// connect all clients
for (Client *c : ws->clientList()) {
setupClientConnections(c);
@ -342,7 +345,6 @@ void EffectsHandlerImpl::setupClientConnections(Client* c)
{
setupAbstractClientConnections(c);
connect(c, &Client::paddingChanged, this, &EffectsHandlerImpl::slotPaddingChanged);
connect(c, &Client::propertyNotify, this, &EffectsHandlerImpl::slotPropertyNotify);
}
void EffectsHandlerImpl::setupUnmanagedConnections(Unmanaged* u)
@ -352,7 +354,6 @@ void EffectsHandlerImpl::setupUnmanagedConnections(Unmanaged* u)
connect(u, &Unmanaged::geometryShapeChanged, this, &EffectsHandlerImpl::slotGeometryShapeChanged);
connect(u, &Unmanaged::paddingChanged, this, &EffectsHandlerImpl::slotPaddingChanged);
connect(u, &Unmanaged::damaged, this, &EffectsHandlerImpl::slotWindowDamaged);
connect(u, &Unmanaged::propertyNotify, this, &EffectsHandlerImpl::slotPropertyNotify);
}
void EffectsHandlerImpl::reconfigure()
@ -808,13 +809,6 @@ void EffectsHandlerImpl::desktopResized(const QSize &size)
emit screenGeometryChanged(size);
}
void EffectsHandlerImpl::slotPropertyNotify(Toplevel* t, long int atom)
{
if (!registered_atoms.contains(atom))
return;
emit propertyNotify(t->effectWindow(), atom);
}
void EffectsHandlerImpl::registerPropertyType(long atom, bool reg)
{
if (reg)

View File

@ -60,6 +60,7 @@ class Deleted;
class EffectLoader;
class EffectsMouseInterceptionX11Filter;
class Unmanaged;
class WindowPropertyNotifyX11Filter;
class KWIN_EXPORT EffectsHandlerImpl : public EffectsHandler
{
@ -255,6 +256,10 @@ public:
void highlightWindows(const QVector<EffectWindow *> &windows);
bool isPropertyTypeRegistered(xcb_atom_t atom) const {
return registered_atoms.contains(atom);
}
public Q_SLOTS:
void slotCurrentTabAboutToChange(EffectWindow* from, EffectWindow* to);
void slotTabAdded(EffectWindow* from, EffectWindow* to);
@ -282,7 +287,6 @@ protected Q_SLOTS:
void slotGeometryShapeChanged(KWin::Toplevel *t, const QRect &old);
void slotPaddingChanged(KWin::Toplevel *t, const QRect &old);
void slotWindowDamaged(KWin::Toplevel *t, const QRect& r);
void slotPropertyNotify(KWin::Toplevel *t, long atom);
protected:
void connectNotify(const QMetaMethod &signal) override;
@ -321,6 +325,7 @@ private:
EffectLoader *m_effectLoader;
int m_trackingCursorChanges;
std::unique_ptr<EffectsMouseInterceptionX11Filter> m_x11MouseInterception;
std::unique_ptr<WindowPropertyNotifyX11Filter> m_x11WindowPropertyNotify;
};
class EffectWindowImpl : public EffectWindow

View File

@ -282,14 +282,6 @@ bool Workspace::workspaceEvent(xcb_generic_event_t *e)
} else if (Unmanaged* c = findUnmanaged(eventWindow)) {
if (c->windowEvent(e))
return true;
} else {
// We want to pass root window property events to effects
if (eventType == XCB_PROPERTY_NOTIFY) {
auto *event = reinterpret_cast<xcb_property_notify_event_t*>(e);
if (event->window == rootWindow()) {
emit propertyNotify(event->atom);
}
}
}
}
@ -1370,7 +1362,6 @@ void Toplevel::propertyNotifyEvent(xcb_property_notify_event_t *e)
getSkipCloseAnimation();
break;
}
emit propertyNotify(this, e->atom);
}
void Toplevel::clientMessageEvent(xcb_client_message_event_t *e)

View File

@ -440,7 +440,6 @@ public:
Q_SIGNALS:
void opacityChanged(KWin::Toplevel* toplevel, qreal oldOpacity);
void damaged(KWin::Toplevel* toplevel, const QRect& damage);
void propertyNotify(KWin::Toplevel* toplevel, long a);
void geometryChanged();
void geometryShapeChanged(KWin::Toplevel* toplevel, const QRect& old);
void paddingChanged(KWin::Toplevel* toplevel, const QRect& old);

View File

@ -0,0 +1,50 @@
/********************************************************************
KWin - the KDE window manager
This file is part of the KDE project.
Copyright (C) 2017 Martin Flöser <mgraesslin@kde.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*********************************************************************/
#include "window_property_notify_x11_filter.h"
#include "effects.h"
#include "unmanaged.h"
#include "workspace.h"
namespace KWin
{
WindowPropertyNotifyX11Filter::WindowPropertyNotifyX11Filter(EffectsHandlerImpl *effects)
: X11EventFilter(QVector<int>{XCB_PROPERTY_NOTIFY})
, m_effects(effects)
{
}
bool WindowPropertyNotifyX11Filter::event(xcb_generic_event_t *event)
{
const auto *pe = reinterpret_cast<xcb_property_notify_event_t*>(event);
if (!m_effects->isPropertyTypeRegistered(pe->atom)) {
return false;
}
if (pe->window == kwinApp()->x11RootWindow()) {
emit m_effects->propertyNotify(nullptr, pe->atom);
} else if (const auto c = workspace()->findClient(Predicate::WindowMatch, pe->window)) {
emit m_effects->propertyNotify(c->effectWindow(), pe->atom);
} else if (const auto c = workspace()->findUnmanaged(pe->window)) {
emit m_effects->propertyNotify(c->effectWindow(), pe->atom);
}
return false;
}
}

View File

@ -0,0 +1,42 @@
/********************************************************************
KWin - the KDE window manager
This file is part of the KDE project.
Copyright (C) 2017 Martin Flöser <mgraesslin@kde.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*********************************************************************/
#ifndef KWIN_WINDOW_PROPERTY_NOTIFY_X11_FILTER_H
#define KWIN_WINDOW_PROPERTY_NOTIFY_X11_FILTER_H
#include "x11eventfilter.h"
namespace KWin
{
class EffectsHandlerImpl;
class WindowPropertyNotifyX11Filter : public X11EventFilter
{
public:
explicit WindowPropertyNotifyX11Filter(EffectsHandlerImpl *effects);
bool event(xcb_generic_event_t *event) override;
private:
EffectsHandlerImpl *m_effects;
};
}
#endif

View File

@ -483,7 +483,6 @@ Q_SIGNALS:
void unmanagedAdded(KWin::Unmanaged*);
void unmanagedRemoved(KWin::Unmanaged*);
void deletedRemoved(KWin::Deleted*);
void propertyNotify(long a);
void configChanged();
void reinitializeCompositing();
void showingDesktopChanged(bool showing);