[wayland] Handle damage events from SurfaceInterface

On Wayland we get the damage from the SurfaceInterface instead of
using a damage handle. This change ensures that the damage handle
interaction is only used on platform X11, while on Wayland we get
the damage from the SurfaceInterface directly.
This commit is contained in:
Martin Gräßlin 2015-02-24 10:54:28 +01:00
parent 70a9c580fc
commit 659c416879
5 changed files with 52 additions and 9 deletions

View file

@ -2455,6 +2455,15 @@ void Client::setDecoratedClient(QPointer< Decoration::DecoratedClientImpl > clie
m_decoratedClient = client;
}
void Client::addDamage(const QRegion &damage)
{
if (!ready_for_painting) { // avoid "setReadyForPainting()" function calling overhead
if (syncRequest.counter == XCB_NONE) // cannot detect complete redraw, consider done now
setReadyForPainting();
}
Toplevel::addDamage(damage);
}
} // namespace
#include "client.moc"

View file

@ -740,6 +740,7 @@ private:
protected:
virtual void debug(QDebug& stream) const;
virtual bool shouldUnredirect() const;
void addDamage(const QRegion &damage) override;
private Q_SLOTS:
void delayedSetShortcut();

View file

@ -898,8 +898,10 @@ bool Toplevel::setupCompositing()
if (damage_handle != XCB_NONE)
return false;
damage_handle = xcb_generate_id(connection());
xcb_damage_create(connection(), damage_handle, frameId(), XCB_DAMAGE_REPORT_LEVEL_NON_EMPTY);
if (kwinApp()->operationMode() == Application::OperationModeX11) {
damage_handle = xcb_generate_id(connection());
xcb_damage_create(connection(), damage_handle, frameId(), XCB_DAMAGE_REPORT_LEVEL_NON_EMPTY);
}
damage_region = QRegion(0, 0, width(), height());
effect_window = new EffectWindowImpl(this);
@ -920,7 +922,7 @@ bool Toplevel::setupCompositing()
void Toplevel::finishCompositing(ReleaseReason releaseReason)
{
if (damage_handle == XCB_NONE)
if (kwinApp()->operationMode() == Application::OperationModeX11 && damage_handle == XCB_NONE)
return;
Compositor::self()->checkUnredirect(true);
if (effect_window->window() == this) { // otherwise it's already passed to Deleted, don't free data
@ -928,7 +930,8 @@ void Toplevel::finishCompositing(ReleaseReason releaseReason)
delete effect_window;
}
if (releaseReason != ReleaseReason::Destroyed) {
if (kwinApp()->operationMode() == Application::OperationModeX11 &&
releaseReason != ReleaseReason::Destroyed) {
xcb_damage_destroy(connection(), damage_handle);
}
@ -981,6 +984,11 @@ bool Toplevel::resetAndFetchDamage()
if (!m_isDamaged)
return false;
if (kwinApp()->operationMode() != Application::OperationModeX11) {
m_isDamaged = false;
return true;
}
xcb_connection_t *conn = connection();
// Create a new region and copy the damage region to it,

View file

@ -31,6 +31,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "shadow.h"
#include "xcbutils.h"
#if HAVE_WAYLAND
#include <KWayland/Server/surface_interface.h>
#endif
#include <QDebug>
namespace KWin
@ -474,6 +478,31 @@ void Toplevel::sendKeybordKeyEvent(uint32_t key, InputRedirection::KeyboardKeySt
Q_UNUSED(state)
}
#if HAVE_WAYLAND
void Toplevel::setSurface(KWayland::Server::SurfaceInterface *surface)
{
if (m_surface == surface) {
return;
}
using namespace KWayland::Server;
if (m_surface) {
disconnect(m_surface, &SurfaceInterface::damaged, this, &Toplevel::addDamage);
}
m_surface = surface;
connect(m_surface, &SurfaceInterface::damaged, this, &Toplevel::addDamage);
}
#endif
void Toplevel::addDamage(const QRegion &damage)
{
m_isDamaged = true;
damage_region += damage;
repaints_region += damage;
for (const QRect &r : damage.rects()) {
emit damaged(this, r);
}
}
} // namespace
#include "toplevel.moc"

View file

@ -441,6 +441,7 @@ protected:
virtual void clientMessageEvent(xcb_client_message_event_t *e);
void discardWindowPixmap();
void addDamageFull();
virtual void addDamage(const QRegion &damage);
Xcb::Property fetchWmClientLeader() const;
void readWmClientLeader(Xcb::Property &p);
void getWmClientLeader();
@ -740,11 +741,6 @@ inline KWayland::Server::SurfaceInterface *Toplevel::surface() const
{
return m_surface;
}
inline void Toplevel::setSurface(KWayland::Server::SurfaceInterface *surface)
{
m_surface = surface;
}
#endif
template <class T, class U>