summaryrefslogtreecommitdiff
path: root/src/mcompositemanager.cpp
diff options
context:
space:
mode:
authorKimmo Hämäläinen <kimmo.hamalainen@nokia.com>2011-01-12 14:50:30 +0200
committerKimmo Hämäläinen <kimmo.hamalainen@nokia.com>2011-01-12 14:50:30 +0200
commit17072e870c66950cb6e7cc299f62f621b93fefd0 (patch)
tree296d5e0b9a5c77d692c004c7180e3a5352177907 /src/mcompositemanager.cpp
parenta477607177328c547d2c1c7354709f3b94692e33 (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
Diffstat (limited to 'src/mcompositemanager.cpp')
-rw-r--r--src/mcompositemanager.cpp59
1 files changed, 35 insertions, 24 deletions
diff --git a/src/mcompositemanager.cpp b/src/mcompositemanager.cpp
index a868e4d..bd31939 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);
}
@@ -1478,8 +1478,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();
@@ -1538,6 +1536,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 |
@@ -2289,7 +2289,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;
@@ -2977,14 +2978,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:
@@ -3075,14 +3086,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;
@@ -4206,7 +4217,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));
}