From 586b22f36c61baf4657e5bc20c9641e28adaf019 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kimmo=20H=E4m=E4l=E4inen?= Date: Wed, 12 Jan 2011 14:50:30 +0200 Subject: Plug some leaks reported in NB#194581 and some robustness improvements - MCompAtoms::getAtomArray: don't leak data even if it's in wrong format - MCompAtoms::get_opacity_prop/getAtom(): init data to zero since API contract does not say it's set to zero - find_primary_output(): init contype to zero for the above reason; don't leak contype even if the format is wrong - unmapEvent(): skip synthetic UnmapNotifys; call XRemoveFromSaveSet() for non-toplevels only - mapRequestEvent(): Call XAddToSaveSet() for framed windows only (currently commented out) because it does not make sense for top-levels - mapEvent(): skip synthetic MapNotifys and MapNotifys for non-top-levels early - x11EventFilter(): forget about windows reparented away from the root/frame - All libxcb code: use _unchecked variants for all request functions, otherwise we leak any errors (reaped with xcb_request_check()) - make glEGLImageTargetTexture2DOES static - MTexturePixmapItem::init(): work also in case the window is unmapped (which should not ever happen but the code checked it so make it work) - MTexturePixmapItem::isDirectRendered(): no need to delete child QObject - MTexturePixmapItem::cleanup(): it's enough to check egl_image to see if needs to be freed - MTexturePixmapItem::doTFP(): comment out the warning because it happens during normal code execution (it's normal that windows get unmapped) - MWindowPropertyCache::init(): mark wm_state_query initially false so it's easier to understand for stupid developers like me - MWindowPropertyCache::init_invalid(): initialise real_geom and statusbar_geom because they can be accessed through public API even for invalid objects - MWindowPropertyCache::MWindowPropertyCache(): remove warning -- it's normal to have destroyed windows - MWindowPropertyCache::~MWindowPropertyCache(): free custom_region for invalid objects also; simplify code by using xcb_discard_reply() where possible (it's also non-blocking) - MWindowPropertyCache::hasAlpha(): don't return true for invalid objects - MWindowPropertyCache::isDecorator(): assume false on failure - MWindowPropertyCache::meegoStackingLayer(): assume 0 on failure - MWindowPropertyCache::getWMHints(): don't leak when we have invalid object and multiple calls - MWindowPropertyCache::windowState(): it's enough to check wm_state_query; assume MCompAtoms::NORMAL on failure - MWindowPropertyCache::damageTracking(): invalid object does not need damage --- src/mcompositemanager.cpp | 59 ++++++++------ src/mtexturepixmapitem_egl.cpp | 16 ++-- src/mwindowpropertycache.cpp | 181 +++++++++++++++++++++-------------------- src/mwindowpropertycache.h | 5 +- 4 files changed, 135 insertions(+), 126 deletions(-) diff --git a/src/mcompositemanager.cpp b/src/mcompositemanager.cpp index 81f391b..84b262d 100644 --- a/src/mcompositemanager.cpp +++ b/src/mcompositemanager.cpp @@ -292,9 +292,8 @@ QVector MCompAtoms::getAtomArray(Window w, Atom array_atom) if (!ret.isEmpty()) memcpy(ret.data(), data, ret.size() * sizeof(Atom)); - - if (data) XFree((void *) data); } + if (data) XFree(data); return ret; } @@ -306,7 +305,7 @@ unsigned int MCompAtoms::get_opacity_prop(Display *dpy, Window w, unsigned int d int format; unsigned long n, left; - unsigned char *data; + unsigned char *data = 0; int result = XGetWindowProperty(QX11Info::display(), w, atoms[_NET_WM_WINDOW_OPACITY], 0L, 1L, False, XA_CARDINAL, &actual, &format, &n, &left, &data); @@ -363,12 +362,12 @@ Atom MCompAtoms::getAtom(Window w, Atoms atomtype) Atom actual; int format; unsigned long n, left; - unsigned char *data; + unsigned char *data = 0; int result = XGetWindowProperty(QX11Info::display(), w, atoms[atomtype], 0L, 1L, False, XA_ATOM, &actual, &format, &n, &left, &data); - if (result == Success && data != None) { + if (result == Success && data) { Atom a; memcpy(&a, data, sizeof(Atom)); XFree((void *) data); @@ -549,7 +548,7 @@ static RROutput find_primary_output() for (i = 0, primary = None; i < scres->noutput && primary == None; i++) { Atom t; int fmt; - unsigned char *contype; + unsigned char *contype = 0; unsigned long nitems, rem; if (XRRGetOutputProperty(dpy, scres->outputs[i], ATOM(RROUTPUT_CTYPE), @@ -557,7 +556,7 @@ static RROutput find_primary_output() &fmt, &nitems, &rem, &contype) == Success) { if (t == XA_ATOM && fmt == 32 && nitems == 1 && *(Atom *)contype == ATOM(RROUTPUT_PANEL)) { - unsigned char *alpha_mode; + unsigned char *alpha_mode = 0; /* Does the primary output support alpha blending? */ primary = scres->outputs[i]; @@ -567,11 +566,11 @@ static RROutput find_primary_output() &alpha_mode) == Success) { has_alpha_mode = t == XA_INTEGER && fmt == 32 && nitems == 1; - XFree(alpha_mode); } + if (alpha_mode) XFree(alpha_mode); } - XFree(contype); } + if (contype) XFree(contype); } XRRFreeScreenResources(scres); @@ -1166,7 +1165,7 @@ bool MCompositeManagerPrivate::possiblyUnredirectTopmostWindow() void MCompositeManagerPrivate::unmapEvent(XUnmapEvent *e) { - if (e->event != QX11Info::appRootWindow()) + if (e->send_event == True || e->event != QX11Info::appRootWindow()) // handle root's SubstructureNotifys (top-levels) only return; configure_reqs.remove(e->window); @@ -1175,7 +1174,8 @@ void MCompositeManagerPrivate::unmapEvent(XUnmapEvent *e) wpc = prop_caches.value(e->window); wpc->setBeingMapped(false); wpc->setIsMapped(false); - if (!wpc->isInputOnly()) + if (!wpc->isInputOnly() + && wpc->parentWindow() != QX11Info::appRootWindow()) XRemoveFromSaveSet(QX11Info::display(), e->window); } @@ -1486,8 +1486,6 @@ void MCompositeManagerPrivate::mapRequestEvent(XMapRequestEvent *e) // we know the parent due to SubstructureRedirectMask on root window pc->setParentWindow(RootWindow(dpy, 0)); } - if(!pc->isInputOnly()) - XAddToSaveSet(QX11Info::display(), e->window); MCompAtoms::Type wtype = pc->windowType(); QRect a = pc->realGeometry(); @@ -1546,6 +1544,8 @@ void MCompositeManagerPrivate::mapRequestEvent(XMapRequestEvent *e) } else { #if 0 /* FIXME/TODO: this does NOT work when mdecorator starts after the first decorated window is shown. See NB#196194 */ + if (!pc->isInputOnly()) + XAddToSaveSet(QX11Info::display(), e->window); // it will be non-toplevel, so mask needs to be set here XSelectInput(dpy, e->window, StructureNotifyMask | ColormapChangeMask | @@ -2294,7 +2294,8 @@ void MCompositeManagerPrivate::mapEvent(XMapEvent *e) return; } if (win == localwin || win == localwin_parent || win == close_button_win - || win == home_button_win) + || win == home_button_win || e->send_event == True + || e->event != QX11Info::appRootWindow()) return; MWindowPropertyCache *wpc; @@ -2983,14 +2984,24 @@ bool MCompositeManagerPrivate::x11EventFilter(XEvent *event) XAllowEvents(QX11Info::display(), ReplayKeyboard, event->xkey.time); keyEvent(&event->xkey); break; case ReparentNotify: - // TODO: handle if one of our top-levels is reparented away - // Prevent this event from internally cascading inside Qt. Causing some - // random crashes in XCheckTypedWindowEvent if (prop_caches.contains(((XReparentEvent*)event)->window)) { - MWindowPropertyCache *pc = - prop_caches.value(((XReparentEvent*)event)->window); - if (((XReparentEvent*)event)->parent != pc->parentWindow()) - pc->setParentWindow(((XReparentEvent*)event)->parent); + Window window = ((XReparentEvent*)event)->window; + Window new_parent = ((XReparentEvent*)event)->parent; + MWindowPropertyCache *pc = prop_caches.value(window); + if (new_parent != pc->parentWindow()) { + if (new_parent != QX11Info::appRootWindow() && + !framed_windows.contains(window)) { + // if new parent is not root/frame, forget about the window + if (!pc->isInputOnly() + && pc->parentWindow() != QX11Info::appRootWindow()) + XRemoveFromSaveSet(QX11Info::display(), window); + MCompositeWindow *i = COMPOSITE_WINDOW(window); + if (i) i->deleteLater(); + removeWindow(window); + prop_caches.remove(window); + } + pc->setParentWindow(new_parent); + } } break; default: @@ -3082,14 +3093,14 @@ void MCompositeManagerPrivate::redirectWindows() for (i = 0; i < children; ++i) { xcb_get_window_attributes_reply_t *attr; attr = xcb_get_window_attributes_reply(xcb_conn, - xcb_get_window_attributes(xcb_conn, kids[i]), 0); + xcb_get_window_attributes_unchecked(xcb_conn, kids[i]), 0); if (!attr || attr->_class == XCB_WINDOW_CLASS_INPUT_ONLY) { if (attr) free(attr); continue; } xcb_get_geometry_reply_t *geom; geom = xcb_get_geometry_reply(xcb_conn, - xcb_get_geometry(xcb_conn, kids[i]), 0); + xcb_get_geometry_unchecked(xcb_conn, kids[i]), 0); if (!geom) { free(attr); continue; @@ -4213,7 +4224,7 @@ void MCompositeManager::xtrace(const char *fun, const char *msg, int lmsg) // point (it has to wait for the reply). Use xcb rather than libx11 // because the latter maintains a hashtable of known Atom:s. free(xcb_intern_atom_reply(p->d->xcb_conn, - xcb_intern_atom(p->d->xcb_conn, False, + xcb_intern_atom_unchecked(p->d->xcb_conn, False, lmsg, msg), NULL)); } diff --git a/src/mtexturepixmapitem_egl.cpp b/src/mtexturepixmapitem_egl.cpp index 43d2da7..33004b0 100644 --- a/src/mtexturepixmapitem_egl.cpp +++ b/src/mtexturepixmapitem_egl.cpp @@ -39,7 +39,7 @@ static PFNEGLCREATEIMAGEKHRPROC eglCreateImageKHR = 0; static PFNEGLDESTROYIMAGEKHRPROC eglDestroyImageKHR = 0; -PFNGLEGLIMAGETARGETTEXTURE2DOESPROC glEGLImageTargetTexture2DOES = 0; +static PFNGLEGLIMAGETARGETTEXTURE2DOESPROC glEGLImageTargetTexture2DOES = 0; static EGLint attribs[] = { EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE }; class EglTextureManager @@ -122,11 +122,7 @@ EGLDisplay EglResourceManager::dpy = 0; void MTexturePixmapItem::init() { - if (isValid() && !propertyCache()->isMapped()) { - qWarning("MTexturePixmapItem::%s(): Failed getting offscreen pixmap", - __func__); - return; - } else if (!isValid() || propertyCache()->isInputOnly()) + if (!isValid() || propertyCache()->isInputOnly()) return; if (!d->eglresource) @@ -223,7 +219,6 @@ bool MTexturePixmapItem::isDirectRendered() const MTexturePixmapItem::~MTexturePixmapItem() { cleanup(); - delete d; } void MTexturePixmapItem::initCustomTfp() @@ -237,7 +232,7 @@ void MTexturePixmapItem::cleanup() { EGLDisplay dpy = d->eglresource->dpy; - if (!d->custom_tfp && d->egl_image != EGL_NO_IMAGE_KHR) { + if (d->egl_image != EGL_NO_IMAGE_KHR) { EGLImageKHR egl_image = d->egl_image; eglDestroyImageKHR(dpy, egl_image); d->egl_image = EGL_NO_IMAGE_KHR; @@ -453,8 +448,9 @@ void MTexturePixmapItem::doTFP() (EGLClientBuffer)d->windowp, attribs); if (d->egl_image == EGL_NO_IMAGE_KHR) { - qWarning("MTexturePixmapItem::%s(): Cannot create EGL image: 0x%x", - __func__, eglGetError()); + // window is probably unmapped + /*qWarning("MTexturePixmapItem::%s(): Cannot create EGL image: 0x%x", + __func__, eglGetError());*/ return; } else { glBindTexture(GL_TEXTURE_2D, d->textureId); diff --git a/src/mwindowpropertycache.cpp b/src/mwindowpropertycache.cpp index 09620c7..4a161b1 100644 --- a/src/mwindowpropertycache.cpp +++ b/src/mwindowpropertycache.cpp @@ -43,7 +43,7 @@ void MWindowPropertyCache::init() shape_rects_valid = false; real_geom_valid = false; net_wm_state_valid = false; - wm_state_query = true; + wm_state_query = false; has_alpha = -1; global_alpha = -1; video_global_alpha = -1; @@ -96,6 +96,8 @@ void MWindowPropertyCache::init_invalid() memset(&xcb_cannot_minimize_cookie, 0, sizeof(xcb_always_mapped_cookie)); memset(&xcb_pict_formats_cookie, 0, sizeof(xcb_pict_formats_cookie)); memset(&xcb_shape_rects_cookie, 0, sizeof(xcb_shape_rects_cookie)); + memset(&real_geom, 0, sizeof(real_geom)); + memset(&statusbar_geom, 0, sizeof(statusbar_geom)); } MWindowPropertyCache::MWindowPropertyCache(Window w, @@ -107,16 +109,16 @@ MWindowPropertyCache::MWindowPropertyCache(Window w, init(); if (!wa) { attrs = xcb_get_window_attributes_reply(xcb_conn, - xcb_get_window_attributes(xcb_conn, window), 0); + xcb_get_window_attributes_unchecked(xcb_conn, window), 0); if (!attrs) { - qWarning("%s: invalid window 0x%lx", __func__, window); + //qWarning("%s: invalid window 0x%lx", __func__, window); init_invalid(); return; } } else attrs = wa; if (!geom) - xcb_real_geom_cookie = xcb_get_geometry(xcb_conn, window); + xcb_real_geom_cookie = xcb_get_geometry_unchecked(xcb_conn, window); else { xcb_real_geom = geom; real_geom = QRect(xcb_real_geom->x, xcb_real_geom->y, @@ -132,53 +134,57 @@ MWindowPropertyCache::MWindowPropertyCache(Window w, XShapeSelectInput(QX11Info::display(), window, ShapeNotifyMask); } - xcb_is_decorator_cookie = xcb_get_property(xcb_conn, 0, window, + xcb_is_decorator_cookie = xcb_get_property_unchecked(xcb_conn, 0, window, ATOM(_MEEGOTOUCH_DECORATOR_WINDOW), XCB_ATOM_CARDINAL, 0, 1); - xcb_transient_for_cookie = xcb_get_property(xcb_conn, 0, window, + xcb_transient_for_cookie = xcb_get_property_unchecked(xcb_conn, 0, window, XCB_ATOM_WM_TRANSIENT_FOR, XCB_ATOM_WINDOW, 0, 1); - xcb_meego_layer_cookie = xcb_get_property(xcb_conn, 0, window, + xcb_meego_layer_cookie = xcb_get_property_unchecked(xcb_conn, 0, window, ATOM(_MEEGO_STACKING_LAYER), XCB_ATOM_CARDINAL, 0, 1); - xcb_window_type_cookie = xcb_get_property(xcb_conn, 0, window, + xcb_window_type_cookie = xcb_get_property_unchecked(xcb_conn, 0, window, ATOM(_NET_WM_WINDOW_TYPE), XCB_ATOM_ATOM, 0, MAX_TYPES); - xcb_pict_formats_cookie = xcb_render_query_pict_formats(xcb_conn); - xcb_decor_buttons_cookie = xcb_get_property(xcb_conn, 0, window, + // FIXME: pict formats do not seem window-specific -- get them only once + xcb_pict_formats_cookie = xcb_render_query_pict_formats_unchecked(xcb_conn); + xcb_decor_buttons_cookie = xcb_get_property_unchecked(xcb_conn, 0, window, ATOM(_MEEGOTOUCH_DECORATOR_BUTTONS), XCB_ATOM_CARDINAL, 0, 8); - xcb_orientation_angle_cookie = xcb_get_property(xcb_conn, 0, window, + xcb_orientation_angle_cookie = xcb_get_property_unchecked(xcb_conn, 0, window, ATOM(_MEEGOTOUCH_ORIENTATION_ANGLE), XCB_ATOM_CARDINAL, 0, 1); - xcb_statusbar_cookie = xcb_get_property(xcb_conn, 0, window, + xcb_statusbar_cookie = xcb_get_property_unchecked(xcb_conn, 0, window, ATOM(_MEEGOTOUCH_MSTATUSBAR_GEOMETRY), XCB_ATOM_CARDINAL, 0, 4); - xcb_wm_protocols_cookie = xcb_get_property(xcb_conn, 0, window, + xcb_wm_protocols_cookie = xcb_get_property_unchecked(xcb_conn, 0, window, ATOM(WM_PROTOCOLS), XCB_ATOM_ATOM, 0, 100); - xcb_wm_state_cookie = xcb_get_property(xcb_conn, 0, window, + xcb_wm_state_cookie = xcb_get_property_unchecked(xcb_conn, 0, window, ATOM(WM_STATE), ATOM(WM_STATE), 0, 1); - xcb_wm_hints_cookie = xcb_get_property(xcb_conn, 0, window, + wm_state_query = true; + xcb_wm_hints_cookie = xcb_get_property_unchecked(xcb_conn, 0, window, XCB_ATOM_WM_HINTS, XCB_ATOM_WM_HINTS, 0, 10); - xcb_icon_geom_cookie = xcb_get_property(xcb_conn, 0, window, + xcb_icon_geom_cookie = xcb_get_property_unchecked(xcb_conn, 0, window, ATOM(_NET_WM_ICON_GEOMETRY), XCB_ATOM_CARDINAL, 0, 4); - xcb_global_alpha_cookie = xcb_get_property(xcb_conn, 0, window, + xcb_global_alpha_cookie = xcb_get_property_unchecked(xcb_conn, 0, window, ATOM(_MEEGOTOUCH_GLOBAL_ALPHA), XCB_ATOM_CARDINAL, 0, 1); - xcb_video_global_alpha_cookie = xcb_get_property(xcb_conn, 0, window, + xcb_video_global_alpha_cookie = xcb_get_property_unchecked(xcb_conn, 0, + window, ATOM(_MEEGOTOUCH_VIDEO_ALPHA), XCB_ATOM_CARDINAL, 0, 1); - xcb_shape_rects_cookie = xcb_shape_get_rectangles(xcb_conn, window, + xcb_shape_rects_cookie = xcb_shape_get_rectangles_unchecked(xcb_conn, + window, ShapeBounding); - xcb_net_wm_state_cookie = xcb_get_property(xcb_conn, 0, window, + xcb_net_wm_state_cookie = xcb_get_property_unchecked(xcb_conn, 0, window, ATOM(_NET_WM_STATE), XCB_ATOM_ATOM, 0, 100); - xcb_always_mapped_cookie = xcb_get_property(xcb_conn, 0, window, + xcb_always_mapped_cookie = xcb_get_property_unchecked(xcb_conn, 0, window, ATOM(_MEEGOTOUCH_ALWAYS_MAPPED), XCB_ATOM_CARDINAL, 0, 1); - xcb_cannot_minimize_cookie = xcb_get_property(xcb_conn, 0, window, + xcb_cannot_minimize_cookie = xcb_get_property_unchecked(xcb_conn, 0, window, ATOM(_MEEGOTOUCH_CANNOT_MINIMIZE), XCB_ATOM_CARDINAL, 0, 1); // add any transients to the transients list @@ -202,6 +208,7 @@ MWindowPropertyCache::MWindowPropertyCache() MWindowPropertyCache::~MWindowPropertyCache() { + if (custom_region) delete custom_region; if (!is_valid) { // no pending XCB requests if (wmhints) @@ -228,53 +235,29 @@ MWindowPropertyCache::~MWindowPropertyCache() MWindowPropertyCache *p = m->d->prop_caches.value(transient_for, 0); if (p) p->transients.removeAll(window); } - xcb_get_property_reply_t *r; - if (transient_for == (Window)-1) { - r = xcb_get_property_reply(xcb_conn, xcb_transient_for_cookie, 0); - if (r) free(r); - } - if (always_mapped < 0) { - r = xcb_get_property_reply(xcb_conn, xcb_always_mapped_cookie, 0); - if (r) free(r); - } - if (cannot_minimize < 0) { - r = xcb_get_property_reply(xcb_conn, xcb_cannot_minimize_cookie, 0); - if (r) free(r); - } + if (transient_for == (Window)-1) + xcb_discard_reply(xcb_conn, xcb_transient_for_cookie.sequence); + if (always_mapped < 0) + xcb_discard_reply(xcb_conn, xcb_always_mapped_cookie.sequence); + if (cannot_minimize < 0) + xcb_discard_reply(xcb_conn, xcb_cannot_minimize_cookie.sequence); desktopView(false); // free the reply if it has been requested - if (meego_layer < 0) { - r = xcb_get_property_reply(xcb_conn, xcb_meego_layer_cookie, 0); - if (r) free(r); - } - if (is_decorator < 0) { - r = xcb_get_property_reply(xcb_conn, xcb_is_decorator_cookie, 0); - if (r) free(r); - } - if (window_type == MCompAtoms::INVALID) { - r = xcb_get_property_reply(xcb_conn, xcb_window_type_cookie, 0); - if (r) free(r); - } - if (has_alpha < 0) { - xcb_render_query_pict_formats_reply_t *pfr; - pfr = xcb_render_query_pict_formats_reply(xcb_conn, - xcb_pict_formats_cookie, 0); - if (pfr) free(pfr); - } - if (!decor_buttons_valid) { - r = xcb_get_property_reply(xcb_conn, xcb_decor_buttons_cookie, 0); - if (r) free(r); - } - if (!wm_protocols_valid) { - r = xcb_get_property_reply(xcb_conn, xcb_wm_protocols_cookie, 0); - if (r) free(r); - } - if (custom_region_request_fired) { - r = xcb_get_property_reply(xcb_conn, xcb_custom_region_cookie, 0); - if (r) free(r); - } + if (meego_layer < 0) + xcb_discard_reply(xcb_conn, xcb_meego_layer_cookie.sequence); + if (is_decorator < 0) + xcb_discard_reply(xcb_conn, xcb_is_decorator_cookie.sequence); + if (window_type == MCompAtoms::INVALID) + xcb_discard_reply(xcb_conn, xcb_window_type_cookie.sequence); + if (has_alpha < 0) + xcb_discard_reply(xcb_conn, xcb_pict_formats_cookie.sequence); + if (!decor_buttons_valid) + xcb_discard_reply(xcb_conn, xcb_decor_buttons_cookie.sequence); + if (!wm_protocols_valid) + xcb_discard_reply(xcb_conn, xcb_wm_protocols_cookie.sequence); + if (custom_region_request_fired) + xcb_discard_reply(xcb_conn, xcb_custom_region_cookie.sequence); xcb_discard_reply(xcb_conn, xcb_orientation_angle_cookie.sequence); xcb_discard_reply(xcb_conn, xcb_statusbar_cookie.sequence); - if (custom_region) delete custom_region; if (wm_state_query) windowState(); if (!icon_geometry_valid) @@ -293,7 +276,7 @@ MWindowPropertyCache::~MWindowPropertyCache() bool MWindowPropertyCache::hasAlpha() { if (!is_valid || has_alpha >= 0) - return has_alpha ? true : false; + return has_alpha == 1 ? true : false; // the following code is replacing a XRenderFindVisualFormat() call... xcb_render_query_pict_formats_reply_t *pict_formats_reply; @@ -375,7 +358,8 @@ const QRegion &MWindowPropertyCache::customRegion(bool request_only) if (request_only || (!custom_region && !custom_region_request_fired)) { if (custom_region_request_fired) customRegion(false); // free the old reply - xcb_custom_region_cookie = xcb_get_property(xcb_conn, 0, window, + xcb_custom_region_cookie = xcb_get_property_unchecked(xcb_conn, 0, + window, ATOM(_MEEGOTOUCH_CUSTOM_REGION), XCB_ATOM_CARDINAL, 0, 10 * 4); custom_region_request_fired = true; @@ -475,7 +459,7 @@ int MWindowPropertyCache::desktopView(bool request_only) if (request_fired) // free the old reply desktopView(false); - c = xcb_get_property(xcb_conn, 0, window, + c = xcb_get_property_unchecked(xcb_conn, 0, window, ATOM(_MEEGOTOUCH_DESKTOP_VIEW), XCB_ATOM_CARDINAL, 0, 1); request_fired = true; @@ -506,7 +490,8 @@ bool MWindowPropertyCache::isDecorator() else is_decorator = 0; free(r); - } + } else + is_decorator = 0; } return is_decorator == 1; } @@ -522,7 +507,8 @@ unsigned int MWindowPropertyCache::meegoStackingLayer() else meego_layer = 0; free(r); - } + } else + meego_layer = 0; } if (meego_layer > 6) meego_layer = 6; return (unsigned)meego_layer; @@ -564,8 +550,12 @@ XID MWindowPropertyCache::windowGroup() const XWMHints &MWindowPropertyCache::getWMHints() { - if (!is_valid) - goto empty_value; + if (!is_valid) { + if (!wmhints) + goto empty_value; + else + return *wmhints; + } if (!wmhints) { xcb_get_property_reply_t *r; r = xcb_get_property_reply(xcb_conn, xcb_wm_hints_cookie, 0); @@ -603,7 +593,8 @@ bool MWindowPropertyCache::propertyEvent(XPropertyEvent *e) if (p) p->transients.removeAll(window); } transient_for = (Window)-1; - xcb_transient_for_cookie = xcb_get_property(xcb_conn, 0, window, + xcb_transient_for_cookie = xcb_get_property_unchecked(xcb_conn, 0, + window, XCB_ATOM_WM_TRANSIENT_FOR, XCB_ATOM_WINDOW, 0, 1); return true; @@ -612,7 +603,8 @@ bool MWindowPropertyCache::propertyEvent(XPropertyEvent *e) // collect the old reply alwaysMapped(); always_mapped = -1; - xcb_always_mapped_cookie = xcb_get_property(xcb_conn, 0, window, + xcb_always_mapped_cookie = xcb_get_property_unchecked(xcb_conn, 0, + window, ATOM(_MEEGOTOUCH_ALWAYS_MAPPED), XCB_ATOM_CARDINAL, 0, 1); emit alwaysMappedChanged(this); @@ -621,7 +613,8 @@ bool MWindowPropertyCache::propertyEvent(XPropertyEvent *e) // collect the old reply cannotMinimize(); cannot_minimize = -1; - xcb_cannot_minimize_cookie = xcb_get_property(xcb_conn, 0, window, + xcb_cannot_minimize_cookie = xcb_get_property_unchecked(xcb_conn, 0, + window, ATOM(_MEEGOTOUCH_CANNOT_MINIMIZE), XCB_ATOM_CARDINAL, 0, 1); } else if (e->atom == ATOM(_MEEGOTOUCH_DESKTOP_VIEW)) { @@ -632,7 +625,7 @@ bool MWindowPropertyCache::propertyEvent(XPropertyEvent *e) getWMHints(); XFree(wmhints); wmhints = 0; - xcb_wm_hints_cookie = xcb_get_property(xcb_conn, 0, window, + xcb_wm_hints_cookie = xcb_get_property_unchecked(xcb_conn, 0, window, XCB_ATOM_WM_HINTS, XCB_ATOM_WM_HINTS, 0, 10); return true; } else if (e->atom == ATOM(_NET_WM_WINDOW_TYPE)) { @@ -640,7 +633,7 @@ bool MWindowPropertyCache::propertyEvent(XPropertyEvent *e) // collect the old reply windowType(); window_type = MCompAtoms::INVALID; - xcb_window_type_cookie = xcb_get_property(xcb_conn, 0, window, + xcb_window_type_cookie = xcb_get_property_unchecked(xcb_conn, 0, window, ATOM(_NET_WM_WINDOW_TYPE), XCB_ATOM_ATOM, 0, MAX_TYPES); } else if (e->atom == ATOM(_NET_WM_ICON_GEOMETRY)) { @@ -648,7 +641,7 @@ bool MWindowPropertyCache::propertyEvent(XPropertyEvent *e) // collect the old reply iconGeometry(); icon_geometry_valid = false; - xcb_icon_geom_cookie = xcb_get_property(xcb_conn, 0, window, + xcb_icon_geom_cookie = xcb_get_property_unchecked(xcb_conn, 0, window, ATOM(_NET_WM_ICON_GEOMETRY), XCB_ATOM_CARDINAL, 0, 4); emit iconGeometryUpdated(); @@ -657,7 +650,8 @@ bool MWindowPropertyCache::propertyEvent(XPropertyEvent *e) // collect the old reply globalAlpha(); global_alpha = -1; - xcb_global_alpha_cookie = xcb_get_property(xcb_conn, 0, window, + xcb_global_alpha_cookie = xcb_get_property_unchecked(xcb_conn, 0, + window, ATOM(_MEEGOTOUCH_GLOBAL_ALPHA), XCB_ATOM_CARDINAL, 0, 1); } else if (e->atom == ATOM(_MEEGOTOUCH_VIDEO_ALPHA)) { @@ -665,26 +659,28 @@ bool MWindowPropertyCache::propertyEvent(XPropertyEvent *e) // collect the old reply videoGlobalAlpha(); video_global_alpha = -1; - xcb_video_global_alpha_cookie = xcb_get_property(xcb_conn, 0, window, - ATOM(_MEEGOTOUCH_VIDEO_ALPHA), + xcb_video_global_alpha_cookie = xcb_get_property_unchecked(xcb_conn, 0, + window, ATOM(_MEEGOTOUCH_VIDEO_ALPHA), XCB_ATOM_CARDINAL, 0, 1); } else if (e->atom == ATOM(_MEEGOTOUCH_DECORATOR_BUTTONS)) { if (!decor_buttons_valid) // collect the old reply buttonGeometryHelper(); decor_buttons_valid = false; - xcb_decor_buttons_cookie = xcb_get_property(xcb_conn, 0, window, + xcb_decor_buttons_cookie = xcb_get_property_unchecked(xcb_conn, 0, + window, ATOM(_MEEGOTOUCH_DECORATOR_BUTTONS), XCB_ATOM_CARDINAL, 0, 8); emit meegoDecoratorButtonsChanged(window); } else if (e->atom == ATOM(_MEEGOTOUCH_ORIENTATION_ANGLE)) { xcb_discard_reply(xcb_conn, xcb_orientation_angle_cookie.sequence); - xcb_orientation_angle_cookie = xcb_get_property(xcb_conn, 0, window, + xcb_orientation_angle_cookie = xcb_get_property_unchecked(xcb_conn, 0, + window, ATOM(_MEEGOTOUCH_ORIENTATION_ANGLE), XCB_ATOM_CARDINAL, 0, 1); } else if (e->atom == ATOM(_MEEGOTOUCH_MSTATUSBAR_GEOMETRY)) { xcb_discard_reply(xcb_conn, xcb_statusbar_cookie.sequence); - xcb_statusbar_cookie = xcb_get_property(xcb_conn, 0, window, + xcb_statusbar_cookie = xcb_get_property_unchecked(xcb_conn, 0, window, ATOM(_MEEGOTOUCH_MSTATUSBAR_GEOMETRY), XCB_ATOM_CARDINAL, 0, 4); } else if (e->atom == ATOM(WM_PROTOCOLS)) { @@ -692,7 +688,8 @@ bool MWindowPropertyCache::propertyEvent(XPropertyEvent *e) // collect the old reply supportedProtocols(); wm_protocols_valid = false; - xcb_wm_protocols_cookie = xcb_get_property(xcb_conn, 0, window, + xcb_wm_protocols_cookie = xcb_get_property_unchecked(xcb_conn, 0, + window, ATOM(WM_PROTOCOLS), XCB_ATOM_ATOM, 0, 100); } else if (e->atom == ATOM(_NET_WM_STATE)) { @@ -700,14 +697,15 @@ bool MWindowPropertyCache::propertyEvent(XPropertyEvent *e) // collect the old reply netWmState(); net_wm_state_valid = false; - xcb_net_wm_state_cookie = xcb_get_property(xcb_conn, 0, window, + xcb_net_wm_state_cookie = xcb_get_property_unchecked(xcb_conn, 0, + window, ATOM(_NET_WM_STATE), XCB_ATOM_ATOM, 0, 100); } else if (e->atom == ATOM(WM_STATE)) { if (wm_state_query) // collect the old reply windowState(); - xcb_wm_state_cookie = xcb_get_property(xcb_conn, 0, window, + xcb_wm_state_cookie = xcb_get_property_unchecked(xcb_conn, 0, window, ATOM(WM_STATE), ATOM(WM_STATE), 0, 1); wm_state_query = true; return true; @@ -716,7 +714,7 @@ bool MWindowPropertyCache::propertyEvent(XPropertyEvent *e) // collect the old reply meegoStackingLayer(); meego_layer = -1; - xcb_meego_layer_cookie = xcb_get_property(xcb_conn, 0, window, + xcb_meego_layer_cookie = xcb_get_property_unchecked(xcb_conn, 0, window, ATOM(_MEEGO_STACKING_LAYER), XCB_ATOM_CARDINAL, 0, 1); if (window_state == NormalState) { @@ -733,7 +731,7 @@ bool MWindowPropertyCache::propertyEvent(XPropertyEvent *e) int MWindowPropertyCache::windowState() { - if (is_valid && wm_state_query) { + if (wm_state_query) { xcb_get_property_reply_t *r; r = xcb_get_property_reply(xcb_conn, xcb_wm_state_cookie, 0); if (r && (unsigned)xcb_get_property_value_length(r) >= sizeof(CARD32)) @@ -968,6 +966,9 @@ MCompAtoms::Type MWindowPropertyCache::windowType() return window_type; } free(r); + } else { + window_type = MCompAtoms::NORMAL; + return window_type; } if (a[0] == ATOM(_NET_WM_WINDOW_TYPE_DESKTOP)) diff --git a/src/mwindowpropertycache.h b/src/mwindowpropertycache.h index cba854f..3611347 100644 --- a/src/mwindowpropertycache.h +++ b/src/mwindowpropertycache.h @@ -95,7 +95,8 @@ public: if (!shape_rects_valid) shapeRegion(); shape_rects_valid = false; - xcb_shape_rects_cookie = xcb_shape_get_rectangles(xcb_conn, window, + xcb_shape_rects_cookie = xcb_shape_get_rectangles_unchecked(xcb_conn, + window, ShapeBounding); } @@ -256,7 +257,7 @@ public: void damageTracking(bool enabled) { - if (damage_object && enabled) + if (!is_valid || (damage_object && enabled)) return; if (damage_object && !enabled) { XDamageDestroy(QX11Info::display(), damage_object); -- cgit v1.2.3