From 0455fa9ef98966af9979b2fbc36affd5b34ea853 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Fl=C3=B6ser?= Date: Thu, 3 Aug 2017 16:31:20 +0200 Subject: [PATCH] Only send active window changes to X11 root window if the X11 window changed Summary: So far KWin always updated the active window property even if the actual window id hasn't changed. E.g. if a Wayland window was active and another Wayland window gets activated the window id was and stays 0. Nevertheless KWin updated the property causing wakeups in X server and any application listening to property changes on the root window. Futhermore this situation is an information leak: we leak when a Wayland window gets activated to X11. To solve this problem RootInfo caches the active window id and only updates if it changes. Test Plan: Verified with xev -root that the active window does not get updated needlessly. Reviewers: #kwin, #plasma Subscribers: plasma-devel, kwin Tags: #kwin Differential Revision: https://phabricator.kde.org/D7096 --- activation.cpp | 2 +- netinfo.cpp | 11 +++++++++++ netinfo.h | 5 +++++ 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/activation.cpp b/activation.cpp index 554dfb082b..9ded1a0569 100644 --- a/activation.cpp +++ b/activation.cpp @@ -271,7 +271,7 @@ void Workspace::setActiveClient(AbstractClient* c) updateStackingOrder(); // e.g. fullscreens have different layer when active/not-active if (rootInfo()) { - rootInfo()->setActiveWindow(active_client ? active_client->window() : 0); + rootInfo()->setActiveClient(active_client); } emit clientActivated(active_client); diff --git a/netinfo.cpp b/netinfo.cpp index 326f6b1fb5..9da14d63f0 100644 --- a/netinfo.cpp +++ b/netinfo.cpp @@ -138,6 +138,7 @@ void RootInfo::destroy() RootInfo::RootInfo(xcb_window_t w, const char *name, NET::Properties properties, NET::WindowTypes types, NET::States states, NET::Properties2 properties2, NET::Actions actions, int scr) : NETRootInfo(connection(), w, name, properties, types, states, properties2, actions, scr) + , m_activeWindow(activeWindow()) { } @@ -224,6 +225,16 @@ void RootInfo::changeShowingDesktop(bool showing) Workspace::self()->setShowingDesktop(showing); } +void RootInfo::setActiveClient(AbstractClient *client) +{ + const xcb_window_t w = client ? client->window() : xcb_window_t{XCB_WINDOW_NONE}; + if (m_activeWindow == w) { + return; + } + m_activeWindow = w; + setActiveWindow(m_activeWindow); +} + // **************************************** // WinInfo // **************************************** diff --git a/netinfo.h b/netinfo.h index 46a91b1402..b5f8a2e620 100644 --- a/netinfo.h +++ b/netinfo.h @@ -30,6 +30,7 @@ along with this program. If not, see . namespace KWin { +class AbstractClient; class Client; /** @@ -44,6 +45,8 @@ public: static RootInfo *create(); static void destroy(); + void setActiveClient(AbstractClient *client); + protected: virtual void changeNumberOfDesktops(int n) override; virtual void changeCurrentDesktop(int d) override; @@ -60,6 +63,8 @@ private: NET::States states, NET::Properties2 properties2, NET::Actions actions, int scr = -1); static RootInfo *s_self; friend RootInfo *rootInfo(); + + xcb_window_t m_activeWindow; }; inline RootInfo *rootInfo()