summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSam Spilsbury <sam.spilsbury@canonical.com>2010-12-06 21:18:53 +0800
committerSam Spilsbury <sam.spilsbury@canonical.com>2010-12-06 21:18:53 +0800
commitb81ec866e1b0c20dcd77c442141aed9f4ea14cf3 (patch)
treeccfd9ed291bc4ec98f988b1c4ddb62f425723297 /src
parent51e01727d309f39e3f42ecf6b53b4ebb31a385dc (diff)
downloadunity-window-decorator-b81ec866e1b0c20dcd77c442141aed9f4ea14cf3.tar.gz
unity-window-decorator-b81ec866e1b0c20dcd77c442141aed9f4ea14cf3.tar.bz2
Fix startup order.
Previously we were doing something like this: init -> screen init -> init core plugin screen -> create windows -> eventLoop -> updatePlugins -> initPlugin (initScreen (initWindow))). This order has a number of problems with it - namely that config plugins will be loaded on one full pass of the event loop and then core options are initialized, before which we were doing certain startup procedures on the default options, which resulted in strange race condition bugs. Also, if we are compositing we have a brief (visible) switch from 2D mode to 3D mode - in reality we want to be in 3D mode ASAP. The new order is init -> updatePlugins (load plugins specified on command line) -> screen init -> load command line plugins -> update plugins (load new plugins specified by config plugins on the command line) -> init screens -> create window (init plugins for window) -> eventLoop. This means that it takes longer for us to get to the event loop, but at least we can zip through the initialization phase quite quickly
Diffstat (limited to 'src')
-rw-r--r--src/main.cpp97
-rw-r--r--src/plugin.cpp22
-rw-r--r--src/privatescreen.h27
-rw-r--r--src/screen.cpp130
4 files changed, 183 insertions, 93 deletions
diff --git a/src/main.cpp b/src/main.cpp
index ea8b509..94f4dcc 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -59,8 +59,8 @@ bool useCow = true;
unsigned int pluginClassHandlerIndex = 0;
-static void
-usage (void)
+void
+CompManager::usage ()
{
printf ("Usage: %s "
"[--replace] "
@@ -99,35 +99,20 @@ signalHandler (int sig)
}
}
-int
-main (int argc, char **argv)
+bool
+CompManager::parseArguments (int argc, char **argv)
{
- char *displayName = 0;
- std::vector<CompString> plugins;
- int i;
- bool disableSm = false;
- char *clientId = NULL;
-
- programName = argv[0];
- programArgc = argc;
- programArgv = argv;
-
- signal (SIGHUP, signalHandler);
- signal (SIGCHLD, signalHandler);
- signal (SIGINT, signalHandler);
- signal (SIGTERM, signalHandler);
-
- for (i = 1; i < argc; i++)
+ for (int i = 1; i < argc; i++)
{
if (!strcmp (argv[i], "--help"))
{
usage ();
- return 0;
+ return false;
}
else if (!strcmp (argv[i], "--version"))
{
printf (PACKAGE_STRING "\n");
- return 0;
+ return false;
}
else if (!strcmp (argv[i], "--debug"))
{
@@ -183,14 +168,32 @@ main (int argc, char **argv)
}
}
+ return true;
+}
+
+CompManager::CompManager () :
+ disableSm (false)
+{
+}
+
+bool
+CompManager::init ()
+{
screen = new CompScreen ();
- if (!screen)
- return 1;
+
+ if (!screen || !screen->priv)
+ return false;
+
+ if (screen->priv->createFailed ())
+ {
+ delete screen;
+ return false;
+ }
modHandler = new ModifierHandler ();
if (!modHandler)
- return 1;
+ return false;
if (!plugins.empty ())
{
@@ -210,21 +213,59 @@ main (int argc, char **argv)
o->set (value);
}
- if (!screen->init (displayName))
- return 1;
+ screen->priv->dirtyPluginList = true;
+ screen->priv->updatePlugins ();
- modHandler->updateModifierMappings ();
+ if (!screen->init (displayName))
+ return false;
if (!disableSm)
CompSession::init (clientId);
+ return true;
+}
+
+void
+CompManager::run ()
+{
screen->eventLoop ();
+}
+void
+CompManager::fini ()
+{
if (!disableSm)
CompSession::close ();
delete screen;
delete modHandler;
+}
+
+
+
+int
+main (int argc, char **argv)
+{
+ CompManager manager;
+
+ programName = argv[0];
+ programArgc = argc;
+ programArgv = argv;
+
+ signal (SIGHUP, signalHandler);
+ signal (SIGCHLD, signalHandler);
+ signal (SIGINT, signalHandler);
+ signal (SIGTERM, signalHandler);
+
+ if (!manager.parseArguments (argc, argv))
+ return 0;
+
+ if (!manager.init ())
+ return 1;
+
+ manager.run ();
+
+ manager.fini ();
if (restartSignal)
{
diff --git a/src/plugin.cpp b/src/plugin.cpp
index f9d8954..dd5bc7e8 100644
--- a/src/plugin.cpp
+++ b/src/plugin.cpp
@@ -264,8 +264,8 @@ UnloadPluginProc loaderUnloadPlugin = dlloaderUnloadPlugin;
ListPluginsProc loaderListPlugins = dlloaderListPlugins;
-static bool
-initPlugin (CompPlugin *p)
+bool
+CompManager::initPlugin (CompPlugin *p)
{
if (!p->vTable->init ())
@@ -275,7 +275,7 @@ initPlugin (CompPlugin *p)
return false;
}
- if (screen)
+ if (screen && screen->priv->initialized)
{
if (!p->vTable->initScreen (screen))
{
@@ -294,8 +294,8 @@ initPlugin (CompPlugin *p)
return true;
}
-static void
-finiPlugin (CompPlugin *p)
+void
+CompManager::finiPlugin (CompPlugin *p)
{
if (screen)
@@ -351,18 +351,18 @@ CompScreen::finiPluginForScreen (CompPlugin *p)
bool
CompPlugin::screenInitPlugins (CompScreen *s)
{
- CompPlugin::List::reverse_iterator rit = plugins.rbegin ();
+ CompPlugin::List::iterator it = plugins.begin ();
CompPlugin *p = NULL;
- while (rit != plugins.rend ())
+ while (it != plugins.end ())
{
- p = (*rit);
+ p = (*it);
if (p->vTable->initScreen (s))
s->initPluginForScreen (p);
- rit++;
+ it++;
}
return true;
@@ -491,7 +491,7 @@ CompPlugin::push (CompPlugin *p)
plugins.push_front (p);
- if (!initPlugin (p))
+ if (!CompManager::initPlugin (p))
{
compLogMessage ("core", CompLogLevelError,
"Couldn't activate plugin '%s'", name);
@@ -518,7 +518,7 @@ CompPlugin::pop (void)
pluginsMap.erase (p->vTable->name ().c_str ());
- finiPlugin (p);
+ CompManager::finiPlugin (p);
plugins.pop_front ();
diff --git a/src/privatescreen.h b/src/privatescreen.h
index 04c5865..a62509d 100644
--- a/src/privatescreen.h
+++ b/src/privatescreen.h
@@ -291,6 +291,9 @@ class PrivateScreen : public CoreOptions {
CompWindow *
focusTopMostWindow ();
+ bool
+ createFailed ();
+
public:
PrivateScreen *priv;
@@ -429,4 +432,28 @@ class PrivateScreen : public CoreOptions {
bool initialized;
};
+class CompManager
+{
+ public:
+
+ CompManager ();
+
+ bool init ();
+ void run ();
+ void fini ();
+
+ bool parseArguments (int, char **);
+ void usage ();
+
+ static bool initPlugin (CompPlugin *p);
+ static void finiPlugin (CompPlugin *p);
+
+ private:
+
+ std::list <CompString> plugins;
+ bool disableSm;
+ char *clientId;
+ char *displayName;
+};
+
#endif
diff --git a/src/screen.cpp b/src/screen.cpp
index 2a5fd74..a7f47b9 100644
--- a/src/screen.cpp
+++ b/src/screen.cpp
@@ -4083,13 +4083,46 @@ CompScreen::screenInfo ()
return priv->screenInfo;
}
+bool
+PrivateScreen::createFailed ()
+{
+ return !screenInitalized;
+}
+
CompScreen::CompScreen ():
PluginClassStorage (screenPluginClassIndices),
priv (NULL)
{
+ CompPrivate p;
+ CompOption::Value::Vector vList;
+ CompPlugin *corePlugin;
+
priv = new PrivateScreen (this);
assert (priv);
+
screenInitalized = true;
+
+ corePlugin = CompPlugin::load ("core");
+ if (!corePlugin)
+ {
+ compLogMessage ("core", CompLogLevelFatal,
+ "Couldn't load core plugin");
+ screenInitalized = false;
+ }
+
+ if (!CompPlugin::push (corePlugin))
+ {
+ compLogMessage ("core", CompLogLevelFatal,
+ "Couldn't activate core plugin");
+ screenInitalized = false;
+ }
+
+ p.uval = CORE_ABIVERSION;
+ storeValue ("core_ABI", p);
+
+ vList.push_back ("core");
+
+ priv->plugin.set (CompOption::TypeString, vList);
}
bool
@@ -4118,31 +4151,6 @@ CompScreen::init (const char *name)
int nvisinfo;
XSetWindowAttributes attrib;
- CompOption::Value::Vector vList;
-
- CompPlugin *corePlugin = CompPlugin::load ("core");
- if (!corePlugin)
- {
- compLogMessage ("core", CompLogLevelFatal,
- "Couldn't load core plugin");
- return false;
- }
-
- if (!CompPlugin::push (corePlugin))
- {
- compLogMessage ("core", CompLogLevelFatal,
- "Couldn't activate core plugin");
- return false;
- }
-
- CompPrivate p;
- p.uval = CORE_ABIVERSION;
- storeValue ("core_ABI", p);
-
- vList.push_back ("core");
-
- priv->plugin.set (CompOption::TypeString, vList);
-
dpy = priv->dpy = XOpenDisplay (name);
if (!priv->dpy)
{
@@ -4286,6 +4294,8 @@ CompScreen::init (const char *name)
} while (event.type != DestroyNotify);
}
+ modHandler->updateModifierMappings ();
+
CompScreen::checkForError (dpy);
XGrabServer (dpy);
@@ -4314,9 +4324,6 @@ CompScreen::init (const char *name)
return false;
}
- priv->vpSize.setWidth (priv->optionGetHsize ());
- priv->vpSize.setHeight (priv->optionGetVsize ());
-
for (i = 0; i < SCREEN_EDGE_NUM; i++)
{
priv->screenEdge[i].id = None;
@@ -4393,24 +4400,6 @@ CompScreen::init (const char *name)
priv->getDesktopHints ();
- /* TODO: bailout properly when objectInitPlugins fails */
- assert (CompPlugin::screenInitPlugins (this));
-
- XQueryTree (dpy, priv->root,
- &rootReturn, &parentReturn,
- &children, &nchildren);
-
- for (unsigned int i = 0; i < nchildren; i++)
- new CompWindow (children[i], i ? children[i - 1] : 0);
-
- foreach (CompWindow *w, priv->windows)
- {
- if (w->isViewable ())
- w->priv->activeNum = priv->activeNum++;
- }
-
- XFree (children);
-
attrib.override_redirect = 1;
attrib.event_mask = PropertyChangeMask;
@@ -4458,6 +4447,47 @@ CompScreen::init (const char *name)
priv->setAudibleBell (priv->optionGetAudibleBell ());
+ priv->pingTimer.setTimes (priv->optionGetPingDelay (),
+ priv->optionGetPingDelay () + 500);
+
+ priv->pingTimer.start ();
+
+ priv->addScreenActions ();
+
+ priv->initialized = true;
+
+ /* TODO: Bailout properly when screenInitPlugins fails
+ * TODO: It would be nicer if this line could mean
+ * "init all the screens", but unfortunately it only inits
+ * plugins loaded on the command line screen's and then
+ * we need to call updatePlugins () to init the remaining
+ * screens from option changes */
+ assert (CompPlugin::screenInitPlugins (this));
+
+ /* The active plugins list might have been changed - load any
+ * new plugins */
+
+ if (priv->dirtyPluginList)
+ priv->updatePlugins ();
+
+ priv->vpSize.setWidth (priv->optionGetHsize ());
+ priv->vpSize.setHeight (priv->optionGetVsize ());
+
+ XQueryTree (dpy, priv->root,
+ &rootReturn, &parentReturn,
+ &children, &nchildren);
+
+ for (unsigned int i = 0; i < nchildren; i++)
+ new CompWindow (children[i], i ? children[i - 1] : 0);
+
+ foreach (CompWindow *w, priv->windows)
+ {
+ if (w->isViewable ())
+ w->priv->activeNum = priv->activeNum++;
+ }
+
+ XFree (children);
+
XGetInputFocus (dpy, &focus, &revertTo);
/* move input focus to root window so that we get a FocusIn event when
@@ -4479,14 +4509,6 @@ CompScreen::init (const char *name)
focusDefaultWindow ();
}
- priv->pingTimer.setTimes (priv->optionGetPingDelay (),
- priv->optionGetPingDelay () + 500);
-
- priv->pingTimer.start ();
-
- priv->initialized = true;
- priv->addScreenActions ();
-
return true;
}