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.
102 lines
4.3 KiB
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
|
|
|