You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
plasma-workspace/0101-Check-whether-there-is...

102 lines
4.3 KiB

From 829158f830555c031755c6d4348e684779264342 Mon Sep 17 00:00:00 2001
From: Weng Xuetian <wengxt@gmail.com>
Date: Mon, 8 Feb 2016 18:56:59 -0800
Subject: [PATCH 101/105] Check whether there is any BadWindow error before
monitor the event
The tray window itself may be destroyed before we start monitor the
event of it. Check the returned error and skip this window if BadWindow
happens.
FIXED-IN: 5.6.0
BUG: 358719
REVIEW: 127014
---
xembed-sni-proxy/fdoselectionmanager.cpp | 28 +++++++++++++++++++++++-----
xembed-sni-proxy/fdoselectionmanager.h | 2 +-
2 files changed, 24 insertions(+), 6 deletions(-)
diff --git a/xembed-sni-proxy/fdoselectionmanager.cpp b/xembed-sni-proxy/fdoselectionmanager.cpp
index ab91044..9c7163d 100644
--- a/xembed-sni-proxy/fdoselectionmanager.cpp
+++ b/xembed-sni-proxy/fdoselectionmanager.cpp
@@ -83,7 +83,7 @@ void FdoSelectionManager::init()
m_selectionOwner->claim(false);
}
-void FdoSelectionManager::addDamageWatch(xcb_window_t client)
+bool FdoSelectionManager::addDamageWatch(xcb_window_t client)
{
qCDebug(SNIPROXY) << "adding damage watch for " << client;
@@ -94,15 +94,27 @@ void FdoSelectionManager::addDamageWatch(xcb_window_t client)
m_damageWatches[client] = damageId;
xcb_damage_create(c, damageId, client, XCB_DAMAGE_REPORT_LEVEL_NON_EMPTY);
- QScopedPointer<xcb_get_window_attributes_reply_t, QScopedPointerPodDeleter> attr(xcb_get_window_attributes_reply(c, attribsCookie, Q_NULLPTR));
+ xcb_generic_error_t *error = Q_NULLPTR;
+ QScopedPointer<xcb_get_window_attributes_reply_t, QScopedPointerPodDeleter> attr(xcb_get_window_attributes_reply(c, attribsCookie, &error));
+ QScopedPointer<xcb_generic_error_t, QScopedPointerPodDeleter> getAttrError(error);
uint32_t events = XCB_EVENT_MASK_STRUCTURE_NOTIFY;
if (!attr.isNull()) {
events = events | attr->your_event_mask;
}
+ // if window is already gone, there is no need to handle it.
+ if (getAttrError && getAttrError->error_code == XCB_WINDOW) {
+ return false;
+ }
// the event mask will not be removed again. We cannot track whether another component also needs STRUCTURE_NOTIFY (e.g. KWindowSystem).
// if we would remove the event mask again, other areas will break.
- xcb_change_window_attributes(c, client, XCB_CW_EVENT_MASK, &events);
+ const auto changeAttrCookie = xcb_change_window_attributes_checked(c, client, XCB_CW_EVENT_MASK, &events);
+ QScopedPointer<xcb_generic_error_t, QScopedPointerPodDeleter> changeAttrError(xcb_request_check(c, changeAttrCookie));
+ // if window is gone by this point, it will be catched by eventFilter, so no need to check later errors.
+ if (changeAttrError && changeAttrError->error_code == XCB_WINDOW) {
+ return false;
+ }
+ return true;
}
bool FdoSelectionManager::nativeEventFilter(const QByteArray& eventType, void* message, long int* result)
@@ -130,6 +142,11 @@ bool FdoSelectionManager::nativeEventFilter(const QByteArray& eventType, void* m
if (m_proxies[unmappedWId]) {
undock(unmappedWId);
}
+ } else if (responseType == XCB_DESTROY_NOTIFY) {
+ const auto destroyedWId = reinterpret_cast<xcb_destroy_notify_event_t *>(ev)->window;
+ if (m_proxies[destroyedWId]) {
+ undock(destroyedWId);
+ }
} else if (responseType == m_damageEventBase + XCB_DAMAGE_NOTIFY) {
const auto damagedWId = reinterpret_cast<xcb_damage_notify_event_t *>(ev)->drawable;
const auto sniProx = m_proxies[damagedWId];
@@ -153,8 +170,9 @@ void FdoSelectionManager::dock(xcb_window_t winId)
return;
}
- addDamageWatch(winId);
- m_proxies[winId] = new SNIProxy(winId, this);
+ if (addDamageWatch(winId)) {
+ m_proxies[winId] = new SNIProxy(winId, this);
+ }
}
void FdoSelectionManager::undock(xcb_window_t winId)
diff --git a/xembed-sni-proxy/fdoselectionmanager.h b/xembed-sni-proxy/fdoselectionmanager.h
index 650d52f..f70256d 100644
--- a/xembed-sni-proxy/fdoselectionmanager.h
+++ b/xembed-sni-proxy/fdoselectionmanager.h
@@ -48,7 +48,7 @@ private Q_SLOTS:
private:
void init();
- void addDamageWatch(xcb_window_t client);
+ bool addDamageWatch(xcb_window_t client);
void dock(xcb_window_t embed_win);
void undock(xcb_window_t client);
void compositingChanged();
--
2.5.0