Index: client.h =================================================================== --- client.h +++ client.h @@ -43,8 +43,6 @@ class KStartupInfoData; class KStartupInfoId; -struct xcb_sync_alarm_notify_event_t; - namespace KWin { @@ -125,7 +123,6 @@ QPoint inputPos() const { return input_offset; } // Inside of geometry() bool windowEvent(xcb_generic_event_t *e); - void syncEvent(xcb_sync_alarm_notify_event_t* e); NET::WindowType windowType(bool direct = false, int supported_types = 0) const; bool manage(xcb_window_t w, bool isMapped); @@ -340,6 +337,19 @@ void readApplicationMenuObjectPath(Xcb::StringProperty &property); void checkApplicationMenuObjectPath(); + struct SyncRequest { + xcb_sync_counter_t counter; + xcb_sync_int64_t value; + xcb_sync_alarm_t alarm; + xcb_timestamp_t lastTimestamp; + QTimer *timeout, *failsafeTimeout; + bool isPending; + }; + const SyncRequest &getSyncRequest() const { + return syncRequest; + } + void handleSync(); + static void cleanupX11(); public Q_SLOTS: @@ -570,14 +580,7 @@ NET::Actions allowed_actions; QSize client_size; bool shade_geometry_change; - struct { - xcb_sync_counter_t counter; - xcb_sync_int64_t value; - xcb_sync_alarm_t alarm; - xcb_timestamp_t lastTimestamp; - QTimer *timeout, *failsafeTimeout; - bool isPending; - } syncRequest; + SyncRequest syncRequest; static bool check_active_modal; ///< \see Client::checkActiveModal() int sm_stacking_order; friend struct ResetupRulesProcedure; Index: client.cpp =================================================================== --- client.cpp +++ client.cpp @@ -2162,5 +2162,20 @@ readApplicationMenuObjectPath(property); } +void Client::handleSync() +{ + setReadyForPainting(); + setupWindowManagementInterface(); + syncRequest.isPending = false; + if (syncRequest.failsafeTimeout) + syncRequest.failsafeTimeout->stop(); + if (isResize()) { + if (syncRequest.timeout) + syncRequest.timeout->stop(); + performMoveResize(); + } else // setReadyForPainting does as well, but there's a small chance for resize syncs after the resize ended + addRepaintFull(); +} + } // namespace Index: events.cpp =================================================================== --- events.cpp +++ events.cpp @@ -404,12 +404,6 @@ case XCB_FOCUS_OUT: return true; // always eat these, they would tell Qt that KWin is the active app default: - if (eventType == Xcb::Extensions::self()->syncAlarmNotifyEvent() && Xcb::Extensions::self()->isSyncAvailable()) { - for (Client *c : clients) - c->syncEvent(reinterpret_cast< xcb_sync_alarm_notify_event_t* >(e)); - for (Client *c : desktops) - c->syncEvent(reinterpret_cast< xcb_sync_alarm_notify_event_t* >(e)); - } break; } return false; @@ -1241,23 +1235,6 @@ AbstractClient::keyPressEvent(key_code); } -void Client::syncEvent(xcb_sync_alarm_notify_event_t* e) -{ - if (e->alarm == syncRequest.alarm && e->counter_value.hi == syncRequest.value.hi && e->counter_value.lo == syncRequest.value.lo) { - setReadyForPainting(); - setupWindowManagementInterface(); - syncRequest.isPending = false; - if (syncRequest.failsafeTimeout) - syncRequest.failsafeTimeout->stop(); - if (isResize()) { - if (syncRequest.timeout) - syncRequest.timeout->stop(); - performMoveResize(); - } else // setReadyForPainting does as well, but there's a small chance for resize syncs after the resize ended - addRepaintFull(); - } -} - // **************************************** // Unmanaged // **************************************** Index: plugins/platforms/x11/standalone/CMakeLists.txt =================================================================== --- plugins/platforms/x11/standalone/CMakeLists.txt +++ plugins/platforms/x11/standalone/CMakeLists.txt @@ -10,6 +10,7 @@ non_composited_outline.cpp x11_decoration_renderer.cpp xfixes_cursor_event_filter.cpp + sync_filter.cpp ) if(X11_Xinput_FOUND) Index: plugins/platforms/x11/standalone/sync_filter.h =================================================================== --- /dev/null +++ plugins/platforms/x11/standalone/sync_filter.h @@ -0,0 +1,38 @@ +/******************************************************************** + KWin - the KDE window manager + This file is part of the KDE project. + +Copyright (C) 2017 Martin Flöser + +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 . +*********************************************************************/ +#ifndef KWIN_SYNC_FILTER_H +#define KWIN_SYNC_FILTER_H +#include "x11eventfilter.h" + +namespace KWin +{ +class X11Cursor; + +class SyncFilter : public X11EventFilter +{ +public: + explicit SyncFilter(); + + bool event(xcb_generic_event_t *event) override; +}; + +} + +#endif Index: plugins/platforms/x11/standalone/sync_filter.cpp =================================================================== --- /dev/null +++ plugins/platforms/x11/standalone/sync_filter.cpp @@ -0,0 +1,48 @@ +/******************************************************************** + KWin - the KDE window manager + This file is part of the KDE project. + +Copyright (C) 2017 Martin Flöser + +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 . +*********************************************************************/ +#include "sync_filter.h" +#include "client.h" +#include "workspace.h" +#include "xcbutils.h" + +namespace KWin +{ + +SyncFilter::SyncFilter() + : X11EventFilter(QVector{Xcb::Extensions::self()->syncAlarmNotifyEvent()}) +{ +} + +bool SyncFilter::event(xcb_generic_event_t *event) +{ + auto e = reinterpret_cast< xcb_sync_alarm_notify_event_t* >(event); + auto client = workspace()->findClient( + [e] (const Client *c) { + const auto syncRequest = c->getSyncRequest(); + return e->alarm == syncRequest.alarm && e->counter_value.hi == syncRequest.value.hi && e->counter_value.lo == syncRequest.value.lo; + } + ); + if (client) { + client->handleSync(); + } + return false; +} + +} Index: plugins/platforms/x11/standalone/x11_platform.h =================================================================== --- plugins/platforms/x11/standalone/x11_platform.h +++ plugins/platforms/x11/standalone/x11_platform.h @@ -25,8 +25,11 @@ #include +#include + namespace KWin { +class SyncFilter; class XInputIntegration; class WindowSelector; class X11EventFilter; @@ -86,6 +89,7 @@ Display *m_x11Display; QScopedPointer m_windowSelector; QScopedPointer m_screenEdgesFilter; + std::unique_ptr m_syncFilter; }; Index: plugins/platforms/x11/standalone/x11_platform.cpp =================================================================== --- plugins/platforms/x11/standalone/x11_platform.cpp +++ plugins/platforms/x11/standalone/x11_platform.cpp @@ -20,6 +20,7 @@ #include "x11_platform.h" #include "x11cursor.h" #include "edge.h" +#include "sync_filter.h" #include "windowselector.h" #include #include @@ -69,6 +70,13 @@ } } #endif + connect(kwinApp(), &Application::workspaceCreated, this, + [this] { + if (Xcb::Extensions::self()->isSyncAvailable()) { + m_syncFilter = std::make_unique(); + } + } + ); } X11StandalonePlatform::~X11StandalonePlatform()