Merge lp:~mc-return/compiz/compiz0.9.9.merge-plugin-startup into lp:compiz/0.9.10

Proposed by MC Return
Status: Work in progress
Proposed branch: lp:~mc-return/compiz/compiz0.9.9.merge-plugin-startup
Merge into: lp:compiz/0.9.10
Diff against target: 450 lines (+418/-0)
5 files modified
debian/compiz-plugins.install (+1/-0)
plugins/startup/CMakeLists.txt (+5/-0)
plugins/startup/src/startup.cpp (+286/-0)
plugins/startup/src/startup.h (+81/-0)
plugins/startup/startup.xml.in (+45/-0)
To merge this branch: bzr merge lp:~mc-return/compiz/compiz0.9.9.merge-plugin-startup
Reviewer Review Type Date Requested Status
MC Return Needs Information
Compiz Maintainers Pending
Review via email: mp+156684@code.launchpad.net

This proposal supersedes a proposal from 2013-01-08.

Commit message

*Startup:
Added the plug-in "Startup" converted from git to bzr (including full history) to lp:compiz.

Cleaned up code and .xml, so it meets high Compiz standards.

(LP: #1012206)

Description of the change

Another useful plugin lost in the realms of the git repo :)

What can this be used for, one might ask...

Example 1:
You want to autostart some widgets, which should use Compiz' widget layer plugin and reside on their own layer.
To achieve this you have to ensure those widgets start after Compiz (Best option: First Time).

Example 2:
You want to ensure some OpenGL program starts after Compiz, like a GL-dock for example.

To post a comment you must log in.
Revision history for this message
MC Return (mc-return) wrote :

I guess the only thing that is missing here now is to replace this macro:

267 +#define GET_ENV_VAR(ourvar, envvar, error) \
268 + ourvar = getenv(#envvar); \
269 + if (ourvar == NULL) \
270 + { \
271 + compLogMessage ("startup", CompLogLevelError, \
272 + "Environment variable " #envvar " is not set"); \
273 + error = true; \
274 + return; \
275 +}
276 +GET_ENV_VAR (dbus_env_var, DBUS_SESSION_BUS_ADDRESS, error)
277 +GET_ENV_VAR (dsp, DISPLAY, error)
278 +GET_ENV_VAR (home, HOME, error)
279 +#undef GET_ENV_VAR

- but I fear this could blow up my computer and I would be pleased if someone could help with this or give me some good tips on how best to replace this...

review: Needs Information
3303. By MC Return

Minor additional .xml improvements
(indentation, better tooltip)

Revision history for this message
Sam Spilsbury (smspillaz) wrote :

easy:

namespace
{
inline const char * getEnvVar (const char *env, bool &error)
{
    char *value = getenv (env);
    if (value == NULL)
    {
        compLogMessage ("startup", CompLogLevelError, "environment variable %s is not set", env);
        error = true;
        return NULL;
    }
    return value;
}
}

dbus_env_var = getEnvVar (DBUS_SESSION_BUS_ADDRESS, error);
dsp = getEnvVar (DISPLAY, error);
home = getEnvVar (HOME, error);

Although now I've just realized how poorly-written this code is in terms of having a class-scope "error" variable instead of just calling setFailed () on the constructor.

Revision history for this message
MC Return (mc-return) wrote :

> easy:
>
> namespace
> {
> inline const char * getEnvVar (const char *env, bool &error)
> {
> char *value = getenv (env);
> if (value == NULL)
> {
> compLogMessage ("startup", CompLogLevelError, "environment variable %s
> is not set", env);
> error = true;
> return NULL;
> }
> return value;
> }
> }
>
> dbus_env_var = getEnvVar (DBUS_SESSION_BUS_ADDRESS, error);
> dsp = getEnvVar (DISPLAY, error);
> home = getEnvVar (HOME, error);
>
Thanks :)

> Although now I've just realized how poorly-written this code is in terms of
> having a class-scope "error" variable instead of just calling setFailed () on
> the constructor.

I'll fix that.

3304. By MC Return

Merged latest lp:compiz

3305. By MC Return

Improved/harmonized ABI check

3306. By MC Return

Merged latest lp:compiz

Unmerged revisions

3306. By MC Return

Merged latest lp:compiz

3305. By MC Return

Improved/harmonized ABI check

3304. By MC Return

Merged latest lp:compiz

3303. By MC Return

Minor additional .xml improvements
(indentation, better tooltip)

3302. By MC Return

Added . to comment

3301. By MC Return

C++ style for comments
Fixed compilation (macro)

3300. By MC Return

Fixed typo

3299. By MC Return

Merged latest lp:compiz

3298. By MC Return

Fixed indentation
Use prefix instead of postfix increments
if (i == 0) -> if (!i)
C++ style for comments
Added newlines to improve readability

3297. By MC Return

Merged latest lp:compiz

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'debian/compiz-plugins.install'
2--- debian/compiz-plugins.install 2013-02-26 16:48:27 +0000
3+++ debian/compiz-plugins.install 2013-05-18 13:41:27 +0000
4@@ -40,6 +40,7 @@
5 debian/tmp/usr/share/compiz/showmouse
6 debian/tmp/usr/*/compiz/*splash.*
7 debian/tmp/usr/share/compiz/splash
8+debian/tmp/usr/*/compiz/*startup.*
9 debian/tmp/usr/*/compiz/*showrepaint.*
10 debian/tmp/usr/*/compiz/*switcher.*
11 debian/tmp/usr/*/compiz/*td.*
12
13=== added directory 'plugins/startup'
14=== added file 'plugins/startup/CMakeLists.txt'
15--- plugins/startup/CMakeLists.txt 1970-01-01 00:00:00 +0000
16+++ plugins/startup/CMakeLists.txt 2013-05-18 13:41:27 +0000
17@@ -0,0 +1,5 @@
18+find_package (Compiz REQUIRED)
19+
20+include (CompizPlugin)
21+
22+compiz_plugin (startup PLUGINDEPS composite)
23
24=== added directory 'plugins/startup/src'
25=== added file 'plugins/startup/src/startup.cpp'
26--- plugins/startup/src/startup.cpp 1970-01-01 00:00:00 +0000
27+++ plugins/startup/src/startup.cpp 2013-05-18 13:41:27 +0000
28@@ -0,0 +1,286 @@
29+#include "startup.h"
30+
31+
32+COMPIZ_PLUGIN_20090315 (startup, StartupPluginVTable);
33+
34+/* mkdir_p: Creates a directory making parent directories as needed.
35+ * (same as mkdir -p)
36+ */
37+void
38+mkdir_p(CompString &pathname)
39+{
40+ if (mkdir(pathname.c_str(), 0777) < 0)
41+ {
42+ /* If we couldn't make the whole directory because of ENOENT (a
43+ * parent directory doesn't exist), then try recursively to make
44+ * the immediate parent directory. */
45+ if (errno == ENOENT)
46+ {
47+ size_t slash = pathname.rfind('/');
48+
49+ if (slash != CompString::npos)
50+ {
51+ CompString prefix = pathname.substr(0, slash);
52+ mkdir_p(prefix);
53+ mkdir(pathname.c_str(), 0777);
54+ }
55+ }
56+ }
57+}
58+
59+void
60+StartupScreen::RunCommands()
61+{
62+ updateOptions();
63+
64+ if (numCommands < 1);
65+ ranCommands = true;
66+
67+ for (int i = 0; i < numCommands; ++i)
68+ {
69+ /* FIXME: There may be a neater way to set this bool. */
70+ if (!i)
71+ ranCommands = true;
72+
73+ if (error)
74+ {
75+ compLogMessage ("startup", CompLogLevelError, "An error occurred, doing nothing.");
76+ return;
77+ }
78+ /* else
79+ * Run the commands.
80+ * If first time in this session, run all commands except with option 2.
81+ */
82+ if (firstSession && commands[i].interval != 2)
83+ {
84+ screen->runCommand (commands[i].command);
85+ continue;
86+ }
87+ /* If we've already run compiz at least once in this session,
88+ * run all commands with option 1 (Every)
89+ */
90+ if (firstRun && commands[i].interval == 1)
91+ {
92+ screen->runCommand (commands[i].command);
93+ continue;
94+ }
95+ /* Hopefully, these will be all of the commands with option 2 :-P */
96+ if (!firstSession && !alreadyRunning && commands[i].interval == 2)
97+ screen->runCommand (commands[i].command);
98+ }
99+
100+ return;
101+}
102+
103+void
104+StartupScreen::UpdateStatus()
105+{
106+
107+ /* We're only interested in the dbus ID. */
108+ CompString s(dbus_env_var);
109+ size_t idx = s.find("guid=");
110+ CompString dbus_id = s.substr(idx+5) + "\n";
111+
112+
113+ std::fstream lock;
114+ int nCompPid = getpid();
115+ CompString compLockFile = lockdir + "complock" + dsp;
116+ CompString xLockFile = lockdir + "xlock" + dsp;
117+
118+ lock.open(xLockFile.c_str (), std::ios::in);
119+
120+ if (!lock)
121+ {
122+ compLogMessage ("startup", CompLogLevelWarn, "Could not open %s for reading: %s", xLockFile.c_str (), strerror(errno));
123+ compLogMessage ("startup", CompLogLevelWarn, "Perhaps this is the first time using this plugin?");
124+ }
125+ else
126+ {
127+ int nCompLock = 0;
128+ std::stringstream xstrm;
129+ xstrm << lock.rdbuf ();
130+ lock.close ();
131+ lock.open(compLockFile.c_str (), std::ios::in);
132+
133+ if (!lock)
134+ {
135+ compLogMessage ("startup", CompLogLevelWarn, "Could not open %s for reading: %s", compLockFile.c_str (), strerror(errno));
136+ compLogMessage ("startup", CompLogLevelWarn, "Perhaps this is the first time using this plugin?");
137+ }
138+ else
139+ {
140+ lock >> nCompLock;
141+ lock.close ();
142+
143+ if (xstrm.str () == dbus_id)
144+ {
145+ /* Compiz has already been run in this X session. */
146+ if (nCompLock == nCompPid)
147+ {
148+ // Control is reaching this path but compiz is already running
149+ // Plugins are most likely being reloaded
150+ if (!firstRun)
151+ alreadyRunning = true;
152+
153+ return;
154+ }
155+ else
156+ {
157+ lock.open(compLockFile.c_str (), std::ios::out);
158+
159+ if (!lock)
160+ compLogMessage ("startup", CompLogLevelWarn, "Couldn't open %s for writing: %s", compLockFile.c_str (), strerror(errno));
161+ else
162+ {
163+ /* Compiz has just been started. Save it's PID. */
164+ if (!firstSession)
165+ firstRun = true;
166+ lock << nCompPid;
167+ lock.close ();
168+ return;
169+ }
170+ }
171+ }
172+ }
173+ }
174+
175+ mkdir_p(lockdir);
176+ lock.open (xLockFile.c_str (), std::ios::out);
177+
178+ if (!lock)
179+ compLogMessage ("startup", CompLogLevelWarn, "Could not open %s for writing: %s", xLockFile.c_str (), strerror(errno));
180+ else
181+ {
182+ /* First time Compiz has been run in this X session. */
183+ firstSession = true;
184+ lock << dbus_id;
185+ lock.close();
186+ }
187+
188+ lock.open(compLockFile.c_str (), std::ios::out);
189+
190+ if (!lock)
191+ {
192+ compLogMessage ("startup", CompLogLevelWarn, "Could not open %s for writing: %s", compLockFile.c_str (), strerror(errno));
193+ }
194+ else
195+ {
196+ /* Save the PID */
197+ if(firstSession)
198+ lock << nCompPid;
199+
200+ lock.close ();
201+ return;
202+ }
203+
204+ return;
205+}
206+
207+bool
208+StartupWindow::damageRect (bool initial,
209+ const CompRect &rect)
210+{
211+ STARTUP_SCREEN (screen);
212+
213+ if (!ss->ranCommands)
214+ ss->RunCommands();
215+ else
216+ cWindow->damageRectSetEnabled (this, false);
217+
218+ return cWindow->damageRect (initial, rect);
219+}
220+
221+void
222+StartupScreen::updateOptions ()
223+{
224+#define GET_OPTION(opt) CompOption::Value::Vector c##opt = optionGet##opt ();
225+ GET_OPTION (PostStartupCommand);
226+ GET_OPTION (PostStartupInterval);
227+#undef GET_OPTION
228+
229+ if (cPostStartupCommand.size () != cPostStartupInterval.size ())
230+ {
231+ compLogMessage ("startup", CompLogLevelWarn, "Malformed option");
232+ return;
233+ }
234+
235+ commands.clear ();
236+
237+ for (unsigned int i = 0; i < cPostStartupCommand.size (); ++i, ++numCommands)
238+ {
239+ commands.push_back (StartupCommand ());
240+ commands[i].command = cPostStartupCommand[i].s ();
241+ commands[i].interval = cPostStartupInterval[i].i ();
242+ }
243+
244+ UpdateStatus ();
245+
246+ return;
247+}
248+
249+void
250+StartupScreen::optionChanged (CompOption *opt, Options num)
251+{
252+ updateOptions ();
253+}
254+
255+StartupScreen::StartupScreen (CompScreen *screen) :
256+ PluginClassHandler <StartupScreen, CompScreen> (screen),
257+ cScreen (CompositeScreen::get (screen)),
258+ commands ()
259+{
260+ optionSetPostStartupCommandNotify (boost::bind (&StartupScreen::
261+ optionChanged, this, _1, _2));
262+
263+ ranCommands = firstRun = firstSession = alreadyRunning = error = false;
264+
265+ numCommands = 0;
266+
267+#define GET_ENV_VAR(ourvar, envvar, error) \
268+ ourvar = getenv(#envvar); \
269+ if (ourvar == NULL) \
270+ { \
271+ compLogMessage ("startup", CompLogLevelError, \
272+ "Environment variable " #envvar " is not set"); \
273+ error = true; \
274+ return; \
275+}
276+GET_ENV_VAR (dbus_env_var, DBUS_SESSION_BUS_ADDRESS, error)
277+GET_ENV_VAR (dsp, DISPLAY, error)
278+GET_ENV_VAR (home, HOME, error)
279+#undef GET_ENV_VAR
280+
281+ /* We may be at risk of modifying the actual DISPLAY env var here... */
282+ dsp[2] = 0;
283+ /* ...though tests have shown it doesn't happen. */
284+
285+ lockdir = "/.compiz/locks/startup/";
286+ lockdir.insert (0,home);
287+}
288+
289+StartupWindow::StartupWindow (CompWindow *window) :
290+ PluginClassHandler <StartupWindow, CompWindow> (window),
291+ cWindow (CompositeWindow::get (window))
292+{
293+ CompositeWindowInterface::setHandler (cWindow);
294+}
295+
296+StartupScreen::~StartupScreen ()
297+{
298+}
299+
300+StartupWindow::~StartupWindow ()
301+{
302+}
303+
304+bool
305+StartupPluginVTable::init ()
306+{
307+ if (CompPlugin::checkPluginABI ("core", CORE_ABIVERSION) &&
308+ CompPlugin::checkPluginABI ("composite", COMPIZ_COMPOSITE_ABI))
309+ return true;
310+
311+ compLogMessage ("startup", CompLogLevelError, "Unable to verify if core and composite are present\n");
312+
313+ return false;
314+}
315
316=== added file 'plugins/startup/src/startup.h'
317--- plugins/startup/src/startup.h 1970-01-01 00:00:00 +0000
318+++ plugins/startup/src/startup.h 2013-05-18 13:41:27 +0000
319@@ -0,0 +1,81 @@
320+#include <fstream>
321+#include <errno.h>
322+#include <sstream>
323+#include <sys/stat.h>
324+#include <core/core.h>
325+#include <composite/composite.h>
326+
327+#include "startup_options.h"
328+
329+class StartupCommand
330+{
331+ public:
332+
333+ CompString command;
334+ int interval;
335+};
336+
337+typedef std::vector<StartupCommand> StartupCommands;
338+
339+class StartupScreen :
340+ public PluginClassHandler <StartupScreen, CompScreen>,
341+ public StartupOptions
342+{
343+ public:
344+
345+ StartupScreen (CompScreen *);
346+ ~StartupScreen ();
347+
348+ CompositeScreen *cScreen;
349+
350+ bool ranCommands;
351+ bool firstRun;
352+ bool firstSession;
353+ bool alreadyRunning;
354+ bool error;
355+
356+ char *dbus_env_var;
357+ char *dsp;
358+ char *home;
359+
360+ CompString lockdir;
361+
362+ StartupCommands commands;
363+
364+ int numCommands;
365+
366+ void updateOptions ();
367+
368+ void UpdateStatus ();
369+
370+ void RunCommands ();
371+
372+ void optionChanged (CompOption*, Options);
373+};
374+
375+class StartupWindow :
376+ public PluginClassHandler <StartupWindow, CompWindow>,
377+ public CompositeWindowInterface
378+{
379+ public:
380+
381+ StartupWindow (CompWindow *);
382+ ~StartupWindow ();
383+
384+ CompWindow *window;
385+ CompositeWindow *cWindow;
386+
387+ bool
388+ damageRect (bool, const CompRect&);
389+};
390+
391+#define STARTUP_SCREEN(s) \
392+ StartupScreen *ss = StartupScreen::get (s);
393+
394+class StartupPluginVTable :
395+ public CompPlugin::VTableForScreenAndWindow <StartupScreen, StartupWindow>
396+{
397+ public:
398+
399+ bool init ();
400+};
401
402=== added file 'plugins/startup/startup.xml.in'
403--- plugins/startup/startup.xml.in 1970-01-01 00:00:00 +0000
404+++ plugins/startup/startup.xml.in 2013-05-18 13:41:27 +0000
405@@ -0,0 +1,45 @@
406+<?xml version="1.0"?>
407+<compiz>
408+ <plugin name="startup" useBcop="true">
409+ <_short>Startup</_short>
410+ <_long>Define commands to run after Compiz is properly loaded</_long>
411+ <category>Utility</category>
412+ <deps>
413+ <requirement>
414+ <plugin>composite</plugin>
415+ </requirement>
416+ <relation type="after">
417+ <plugin>composite</plugin>
418+ </relation>
419+ </deps>
420+ <options>
421+ <subgroup>
422+ <option name="post_startup_command" type="list">
423+ <_short>Command</_short>
424+ <_long>The command to run.</_long>
425+ <type>string</type>
426+ </option>
427+ <option name="post_startup_interval" type="list">
428+ <_short>Interval</_short>
429+ <_long>Interval the command will be run per X session. First Time: First time Compiz is started. Every Time: Every time Compiz starts. After First: Every time except the first time.</_long>
430+ <type>int</type>
431+ <min>0</min>
432+ <max>2</max>
433+ <desc>
434+ <value>0</value>
435+ <_name>First Time</_name>
436+ </desc>
437+ <desc>
438+ <value>1</value>
439+ <_name>Every Time</_name>
440+ </desc>
441+ <desc>
442+ <value>2</value>
443+ <_name>After First</_name>
444+ </desc>
445+ </option>
446+ </subgroup>
447+ </options>
448+ </plugin>
449+</compiz>
450+

Subscribers

People subscribed via source and target branches

to all changes: