diff --git a/CMakeLists.txt b/CMakeLists.txt --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -509,6 +509,7 @@ xdgshellclient.cpp xkb.cpp xwl/xwayland_interface.cpp + sync_filter.cpp ) if (CMAKE_SYSTEM_NAME MATCHES "Linux") diff --git a/main.h b/main.h --- a/main.h +++ b/main.h @@ -190,6 +190,14 @@ return m_terminating; } + bool updatingXTimer() { + return m_updatingXTimer; + } + + void setUpdatingXTimer(bool updating) { + m_updatingXTimer = updating; + } + static void setupMalloc(); static void setupLocalizedString(); @@ -259,6 +267,7 @@ #endif Platform *m_platform = nullptr; bool m_terminating = false; + bool m_updatingXTimer = false; }; inline static Application *kwinApp() diff --git a/main.cpp b/main.cpp --- a/main.cpp +++ b/main.cpp @@ -365,7 +365,19 @@ // no timestamp return; case XCB_PROPERTY_NOTIFY: - time = reinterpret_cast(event)->time; + { + xcb_property_notify_event_t *propertyNotify = reinterpret_cast(event); + time = propertyNotify->time; + + // updateXTime handling + if (kwinApp()->m_updatingXTimer && propertyNotify->window == m_rootWindow + && propertyNotify->atom == atoms->clipboard + ) { + kwinApp()->setX11Time(time, Application::TimestampUpdate::Always); + xcb_delete_property(connection(), m_rootWindow, atoms->clipboard); + m_updatingXTimer = false; + } + } break; case XCB_SELECTION_CLEAR: time = reinterpret_cast(event)->time; diff --git a/platform.h b/platform.h --- a/platform.h +++ b/platform.h @@ -41,6 +41,8 @@ namespace KWin { +class SyncFilter; + namespace ColorCorrect { class Manager; } @@ -364,13 +366,9 @@ virtual OverlayWindow *createOverlayWindow(); /** - * Allows a platform to update the X11 timestamp. - * Mostly for the X11 standalone platform to interact with QX11Info. - * - * Default implementation does nothing. This means code relying on the X timestamp being up to date, - * might not be working. E.g. synced X11 window resizing + * Allows a platform to update the X11 timestamp, asynchrounously. */ - virtual void updateXTime(); + void updateXTime(); /** * Creates the OutlineVisual for the given @p outline. @@ -562,6 +560,7 @@ bool m_supportsGammaControl = false; bool m_supportsOutputChanges = false; CompositingType m_selectedCompositor = NoCompositing; + std::unique_ptr m_syncFilter; }; } diff --git a/platform.cpp b/platform.cpp --- a/platform.cpp +++ b/platform.cpp @@ -34,6 +34,10 @@ #include "wayland_server.h" #include "colorcorrection/manager.h" +#include "xcb/xproto.h" +#include "atoms.h" +#include "sync_filter.h" + #include #include @@ -47,6 +51,14 @@ setSoftWareCursor(false); m_colorCorrect = new ColorCorrect::Manager(this); connect(Cursors::self(), &Cursors::currentCursorRendered, this, &Platform::cursorRendered); + + connect(kwinApp(), &Application::workspaceCreated, this, + [this] { + if (Xcb::Extensions::self()->isSyncAvailable()) { + m_syncFilter = std::make_unique(); + } + } + ); } Platform::~Platform() @@ -501,8 +513,30 @@ return nullptr; } + +/* + Updates xTime(). This used to simply fetch current timestamp from the server, + but that can cause xTime() to be newer than timestamp of events that are + still in our events queue, thus e.g. making XSetInputFocus() caused by such + event to be ignored. Therefore events queue is searched for first + event with timestamp, and extra PropertyNotify is generated in order to make + sure such event is found. +*/ void Platform::updateXTime() { + // change a dummy property so that we get an event caught in Application::updateX11Time + xcb_window_t window = rootWindow(); + + xcb_change_property(connection(), XCB_PROP_MODE_APPEND, window, atoms->clipboard, + XCB_ATOM_INTEGER, 32, 0, nullptr); + xcb_flush(connection()); + + // from xcb_aux_sync + xcb_get_input_focus_cookie_t cookie = xcb_get_input_focus(connection()); + free(xcb_get_input_focus_reply(connection(), cookie, 0)); + + // will update + kwinApp()->setUpdatingXTimer(true); } OutlineVisual *Platform::createOutline(Outline *outline) diff --git a/plugins/platforms/x11/standalone/CMakeLists.txt b/plugins/platforms/x11/standalone/CMakeLists.txt --- a/plugins/platforms/x11/standalone/CMakeLists.txt +++ b/plugins/platforms/x11/standalone/CMakeLists.txt @@ -7,7 +7,6 @@ overlaywindow_x11.cpp screenedges_filter.cpp screens_xrandr.cpp - sync_filter.cpp windowselector.cpp x11_decoration_renderer.cpp x11_output.cpp diff --git a/plugins/platforms/x11/standalone/x11_platform.h b/plugins/platforms/x11/standalone/x11_platform.h --- a/plugins/platforms/x11/standalone/x11_platform.h +++ b/plugins/platforms/x11/standalone/x11_platform.h @@ -29,7 +29,6 @@ namespace KWin { -class SyncFilter; class XInputIntegration; class WindowSelector; class X11EventFilter; @@ -63,7 +62,6 @@ OverlayWindow *createOverlayWindow() override; - void updateXTime() override; OutlineVisual *createOutline(Outline *outline) override; Decoration::Renderer *createDecorationRenderer(Decoration::DecoratedClientImpl *client) override; @@ -103,7 +101,6 @@ Display *m_x11Display; QScopedPointer m_windowSelector; QScopedPointer m_screenEdgesFilter; - std::unique_ptr m_syncFilter; QVector m_outputs; }; diff --git a/plugins/platforms/x11/standalone/x11_platform.cpp b/plugins/platforms/x11/standalone/x11_platform.cpp --- a/plugins/platforms/x11/standalone/x11_platform.cpp +++ b/plugins/platforms/x11/standalone/x11_platform.cpp @@ -20,7 +20,6 @@ #include "x11_platform.h" #include "x11cursor.h" #include "edge.h" -#include "sync_filter.h" #include "windowselector.h" #include #include @@ -74,13 +73,6 @@ } } #endif - connect(kwinApp(), &Application::workspaceCreated, this, - [this] { - if (Xcb::Extensions::self()->isSyncAvailable()) { - m_syncFilter = std::make_unique(); - } - } - ); setSupportsGammaControl(true); } @@ -348,22 +340,6 @@ return new OverlayWindowX11(); } -/* - Updates xTime(). This used to simply fetch current timestamp from the server, - but that can cause xTime() to be newer than timestamp of events that are - still in our events queue, thus e.g. making XSetInputFocus() caused by such - event to be ignored. Therefore events queue is searched for first - event with timestamp, and extra PropertyNotify is generated in order to make - sure such event is found. -*/ -void X11StandalonePlatform::updateXTime() -{ - // NOTE: QX11Info::getTimestamp does not yet search the event queue as the old - // solution did. This means there might be regressions currently. See the - // documentation above on how it should be done properly. - kwinApp()->setX11Time(QX11Info::getTimestamp(), Application::TimestampUpdate::Always); -} - OutlineVisual *X11StandalonePlatform::createOutline(Outline *outline) { // first try composited Outline diff --git a/plugins/platforms/x11/standalone/sync_filter.h b/sync_filter.h rename from plugins/platforms/x11/standalone/sync_filter.h rename to sync_filter.h diff --git a/plugins/platforms/x11/standalone/sync_filter.cpp b/sync_filter.cpp rename from plugins/platforms/x11/standalone/sync_filter.cpp rename to sync_filter.cpp diff --git a/x11client.cpp b/x11client.cpp --- a/x11client.cpp +++ b/x11client.cpp @@ -2344,9 +2344,7 @@ void X11Client::getSyncCounter() { - // TODO: make sync working on XWayland - static const bool isX11 = kwinApp()->operationMode() == Application::OperationModeX11; - if (!Xcb::Extensions::self()->isSyncAvailable() || !isX11) + if (!Xcb::Extensions::self()->isSyncAvailable()) return; Xcb::Property syncProp(false, window(), atoms->net_wm_sync_request_counter, XCB_ATOM_CARDINAL, 0, 1);