summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKimmo Hämäläinen <kimmo.hamalainen@nokia.com>2011-01-12 14:50:30 +0200
committerAdam Endrodi <ext-adam.endrodi@nokia.com>2011-01-21 19:43:24 +0200
commit586b22f36c61baf4657e5bc20c9641e28adaf019 (patch)
treea64e8e1ce6671a59a0a6ab41abeb2bc38a878112
parentf7ecd5a5bdb687b609b4b1e37b5ad0847ae8aa35 (diff)
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
-rw-r--r--src/mcompositemanager.cpp59
-rw-r--r--src/mtexturepixmapitem_egl.cpp16
-rw-r--r--src/mwindowpropertycache.cpp181
-rw-r--r--src/mwindowpropertycache.h5
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<Atom> 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);