Create a dedicated X11Filter for Client sync events and move it to X11 platform
Summary: On Wayland we have the sync disabled as it doesn't work properly. This allows us to also move the sync event handling into the X11 standalone platform. The code is slightly refactored: instead of passing the event to each Client, we search for the matching Client. For that the SyncAlaram struct is added to public section of Client. The method to handle the sync doesn't need the event any more and is moved from events.cpp to client.cpp. Test Plan: Run Xephyr+kwin_x11, resized a window and verified through gdb breakpoint that the sync still works Reviewers: #kwin, #plasma Subscribers: plasma-devel Tags: #plasma Differential Revision: https://phabricator.kde.org/D7942
This commit is contained in:
parent
8f4b6a8973
commit
2e868c50df
8 changed files with 128 additions and 34 deletions
15
client.cpp
15
client.cpp
|
@ -2155,5 +2155,20 @@ void Client::checkApplicationMenuObjectPath()
|
|||
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
|
||||
|
||||
|
|
25
client.h
25
client.h
|
@ -43,8 +43,6 @@ class QTimer;
|
|||
class KStartupInfoData;
|
||||
class KStartupInfoId;
|
||||
|
||||
struct xcb_sync_alarm_notify_event_t;
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
|
||||
|
@ -121,7 +119,6 @@ public:
|
|||
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);
|
||||
|
@ -336,6 +333,19 @@ public:
|
|||
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:
|
||||
|
@ -563,14 +573,7 @@ private:
|
|||
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;
|
||||
|
|
23
events.cpp
23
events.cpp
|
@ -386,12 +386,6 @@ bool Workspace::workspaceEvent(xcb_generic_event_t *e)
|
|||
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;
|
||||
|
@ -1223,23 +1217,6 @@ void Client::keyPressEvent(uint key_code, xcb_timestamp_t time)
|
|||
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
|
||||
// ****************************************
|
||||
|
|
|
@ -12,6 +12,7 @@ set(X11PLATFORM_SOURCES
|
|||
xfixes_cursor_event_filter.cpp
|
||||
effects_x11.cpp
|
||||
effects_mouse_interception_x11_filter.cpp
|
||||
sync_filter.cpp
|
||||
)
|
||||
|
||||
if(X11_Xinput_FOUND)
|
||||
|
|
48
plugins/platforms/x11/standalone/sync_filter.cpp
Normal file
48
plugins/platforms/x11/standalone/sync_filter.cpp
Normal file
|
@ -0,0 +1,48 @@
|
|||
/********************************************************************
|
||||
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 "sync_filter.h"
|
||||
#include "client.h"
|
||||
#include "workspace.h"
|
||||
#include "xcbutils.h"
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
|
||||
SyncFilter::SyncFilter()
|
||||
: X11EventFilter(QVector<int>{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;
|
||||
}
|
||||
|
||||
}
|
38
plugins/platforms/x11/standalone/sync_filter.h
Normal file
38
plugins/platforms/x11/standalone/sync_filter.h
Normal file
|
@ -0,0 +1,38 @@
|
|||
/********************************************************************
|
||||
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_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
|
|
@ -20,6 +20,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
#include "x11_platform.h"
|
||||
#include "x11cursor.h"
|
||||
#include "edge.h"
|
||||
#include "sync_filter.h"
|
||||
#include "windowselector.h"
|
||||
#include <config-kwin.h>
|
||||
#include <kwinconfig.h>
|
||||
|
@ -70,6 +71,13 @@ X11StandalonePlatform::X11StandalonePlatform(QObject *parent)
|
|||
}
|
||||
}
|
||||
#endif
|
||||
connect(kwinApp(), &Application::workspaceCreated, this,
|
||||
[this] {
|
||||
if (Xcb::Extensions::self()->isSyncAvailable()) {
|
||||
m_syncFilter = std::make_unique<SyncFilter>();
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
X11StandalonePlatform::~X11StandalonePlatform()
|
||||
|
|
|
@ -25,8 +25,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
|
||||
#include <QObject>
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
class SyncFilter;
|
||||
class XInputIntegration;
|
||||
class WindowSelector;
|
||||
class X11EventFilter;
|
||||
|
@ -89,6 +92,7 @@ private:
|
|||
Display *m_x11Display;
|
||||
QScopedPointer<WindowSelector> m_windowSelector;
|
||||
QScopedPointer<X11EventFilter> m_screenEdgesFilter;
|
||||
std::unique_ptr<SyncFilter> m_syncFilter;
|
||||
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue