[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    [plasma-workspace] xembed-sni-proxy: Check whether there is any BadWindow error before monitor the e
From:       Weng Xuetian <wengxt () gmail ! com>
Date:       2016-02-09 3:31:12
Message-ID: E1aSz1E-0001vU-KB () scm ! kde ! org
[Download RAW message or body]

Git commit 829158f830555c031755c6d4348e684779264342 by Weng Xuetian.
Committed on 09/02/2016 at 03:29.
Pushed by xuetianweng into branch 'master'.

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

M  +23   -5    xembed-sni-proxy/fdoselectionmanager.cpp
M  +1    -1    xembed-sni-proxy/fdoselectionmanager.h

http://commits.kde.org/plasma-workspace/829158f830555c031755c6d4348e684779264342

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();


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic