summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSam Spilsbury <smspillaz@gmail.com>2011-01-13 07:59:23 +0800
committerSam Spilsbury <smspillaz@gmail.com>2011-01-13 07:59:23 +0800
commit9bd6d03c3d74a2e4d31874c1118df300b43142ba (patch)
treeb984bdf5563280d2499f8effc80adbb62ad52dce /src
parentecc61dc04567947e92cbb9686c1041619abc05b1 (diff)
downloadmobileperf-9bd6d03c3d74a2e4d31874c1118df300b43142ba.tar.gz
mobileperf-9bd6d03c3d74a2e4d31874c1118df300b43142ba.tar.bz2
Don't create CompWindow and initialize plugins until MapRequest.
Having all plugins track windows on CreateNotify doesn't make any sense because they are not visible, and the ones that they would need to track would be override-redirect anyways. Also tracking windows in this way broke reparenting in such a way that a number of buggy applications using xembed (eg gnome-panel applets and Adobe Flash would consistently crash).
Diffstat (limited to 'src')
-rw-r--r--src/event.cpp36
-rw-r--r--src/privatescreen.h3
-rw-r--r--src/privatewindow.h22
-rw-r--r--src/screen.cpp10
-rw-r--r--src/window.cpp43
5 files changed, 95 insertions, 19 deletions
diff --git a/src/event.cpp b/src/event.cpp
index 987433b..ecb89f8 100644
--- a/src/event.cpp
+++ b/src/event.cpp
@@ -1029,13 +1029,15 @@ CompScreen::handleEvent (XEvent *event)
{
/* Track the window if it was created on this
* screen, otherwise we still need to register
- * for FocusChangeMask */
+ * for FocusChangeMask. Also, we don't want to
+ * manage it straight away - in reality we want
+ * that to wait until the map request */
if (wa.root == priv->root)
- new CompWindow (event->xcreatewindow.window, priv->getTopWindow ());
+ new CoreWindow (event->xcreatewindow.window);
else
XSelectInput (priv->dpy, event->xcreatewindow.window,
- FocusChangeMask);
- }
+ FocusChangeMask);
+ }
break;
case DestroyNotify:
w = findWindow (event->xdestroywindow.window);
@@ -1051,8 +1053,8 @@ CompScreen::handleEvent (XEvent *event)
{
if (w->priv->pendingMaps)
{
- if (!w->priv->frame)
- w->priv->reparent ();
+ //if (!w->priv->frame)
+ //w->priv->reparent ();
w->priv->managed = true;
}
@@ -1113,7 +1115,13 @@ CompScreen::handleEvent (XEvent *event)
w = findWindow (event->xreparent.window);
if (!w && event->xreparent.parent == priv->root)
{
- new CompWindow (event->xreparent.window, priv->getTopWindow ());
+ CoreWindow *cw = new CoreWindow (event->xreparent.window);
+
+ if (cw)
+ {
+ cw->manage (priv->getTopWindow ());
+ delete cw;
+ }
}
else if (w && !(event->xreparent.parent == w->priv->wrapper ||
event->xreparent.parent == priv->root))
@@ -1540,7 +1548,19 @@ CompScreen::handleEvent (XEvent *event)
modHandler->updateModifierMappings ();
break;
case MapRequest:
- w = findWindow (event->xmaprequest.window);
+ /* Create the CompWindow structure here */
+ w = NULL;
+
+ foreach (CoreWindow *cw, priv->createdWindows)
+ {
+ if (cw->priv->id == event->xmaprequest.window)
+ {
+ w = cw->manage (priv->getTopWindow ());
+ delete cw;
+ break;
+ }
+ }
+
if (w)
{
XWindowAttributes attr;
diff --git a/src/privatescreen.h b/src/privatescreen.h
index 961daf2..b6975cc 100644
--- a/src/privatescreen.h
+++ b/src/privatescreen.h
@@ -39,6 +39,8 @@
CompPlugin::VTable * getCoreVTable ();
+class CoreWindow;
+
extern bool shutDown;
extern bool restartSignal;
@@ -358,6 +360,7 @@ class PrivateScreen : public CoreOptions {
CompScreen *screen;
+ std::list <CoreWindow *> createdWindows;
CompWindowList windows;
CompWindow::Map windowsMap;
diff --git a/src/privatewindow.h b/src/privatewindow.h
index 99d0c4e..eb86932 100644
--- a/src/privatewindow.h
+++ b/src/privatewindow.h
@@ -46,7 +46,7 @@ typedef CompWindowExtents CompFullscreenMonitorSet;
class PrivateWindow {
public:
- PrivateWindow (CompWindow *window);
+ PrivateWindow (CoreWindow *window);
~PrivateWindow ();
void recalcNormalHints ();
@@ -302,4 +302,24 @@ class PrivateWindow {
Time lastCloseRequestTime;
};
+/* Minimal tracking of the window which happens
+ * on CreateNotify */
+
+class CoreWindow
+{
+ public:
+
+ CoreWindow (Window id);
+
+ CompWindow * manage (Window id);
+
+ friend class PrivateWindow;
+ friend class PrivateScreen;
+ friend class CompScreen;
+
+ private:
+
+ PrivateWindow *priv;
+};
+
#endif
diff --git a/src/screen.cpp b/src/screen.cpp
index 706d1a7..5410f58 100644
--- a/src/screen.cpp
+++ b/src/screen.cpp
@@ -4571,7 +4571,15 @@ CompScreen::init (const char *name)
&children, &nchildren);
for (unsigned int i = 0; i < nchildren; i++)
- new CompWindow (children[i], i ? children[i - 1] : 0);
+ {
+ CoreWindow *cw = new CoreWindow (children[i]);
+
+ if (cw)
+ {
+ cw->manage (i ? children[i - 1] : 0);
+ delete cw;
+ }
+ }
foreach (CompWindow *w, priv->windows)
{
diff --git a/src/window.cpp b/src/window.cpp
index 7da262d..ac56ef4 100644
--- a/src/window.cpp
+++ b/src/window.cpp
@@ -5116,14 +5116,29 @@ CompWindow::syncAlarm ()
return priv->syncAlarm;
}
+CompWindow *
+CoreWindow::manage (Window aboveId)
+{
+ screen->priv->createdWindows.remove (this);
+ return new CompWindow (aboveId, priv);
+}
+
+/*
+ * On CreateNotify we only want to do some very basic
+ * initialization on the windows, and we need to be
+ * tracking things like eg override-redirect windows
+ * for compositing, although only on MapRequest do
+ * we actually care about them (and let the plugins
+ * care about them too)
+ */
-CompWindow::CompWindow (Window id,
- Window aboveId) :
- PluginClassStorage (windowPluginClassIndices)
+CoreWindow::CoreWindow (Window id)
{
priv = new PrivateWindow (this);
assert (priv);
+ screen->priv->createdWindows.push_back (this);
+
/* Failure means that window has been destroyed. We still have to add the
window to the window list as we might get configure requests which
require us to stack other windows relative to it. Setting some default
@@ -5158,15 +5173,13 @@ CompWindow::CompWindow (Window id,
priv->id = id;
- priv->alpha = (depth () == 32);
+ priv->alpha = (priv->attrib.depth == 32);
priv->lastPong = screen->priv->lastPing;
if (screen->XShape ())
XShapeSelectInput (screen->dpy (), id, ShapeNotifyMask);
- screen->insertWindow (this, aboveId);
-
- if (windowClass () != InputOnly)
+ if (priv->attrib.c_class != InputOnly)
{
priv->region = CompRegion (priv->attrib.x, priv->attrib.y,
priv->width, priv->height);
@@ -5181,6 +5194,17 @@ CompWindow::CompWindow (Window id,
{
priv->attrib.map_state = IsUnmapped;
}
+}
+
+CompWindow::CompWindow (Window aboveId, PrivateWindow *priv) :
+ PluginClassStorage (windowPluginClassIndices),
+ priv (priv)
+{
+ // TODO: Reparent first!
+
+ priv->window = this;
+
+ screen->insertWindow (this, aboveId);
priv->wmType = screen->priv->getWindowType (priv->id);
priv->protocols = screen->priv->getProtocols (priv->id);
@@ -5221,6 +5245,7 @@ CompWindow::CompWindow (Window id,
if (!overrideRedirect ())
{
+ // needs to happen right after maprequest
if (!priv->frame)
priv->reparent ();
priv->managed = true;
@@ -5276,6 +5301,7 @@ CompWindow::CompWindow (Window id,
{
if (screen->priv->getWmState (priv->id) == IconicState)
{
+ // before everything else in maprequest
if (!priv->frame)
priv->reparent ();
priv->managed = true;
@@ -5359,9 +5385,8 @@ CompWindow::~CompWindow ()
delete priv;
}
-PrivateWindow::PrivateWindow (CompWindow *window) :
+PrivateWindow::PrivateWindow (CoreWindow *window) :
priv (this),
- window (window),
refcnt (1),
id (None),
frame (None),