Merge lp:~vanvugt/compiz-core/fix-930412 into lp:compiz-core

Proposed by Daniel van Vugt
Status: Merged
Merged at revision: 2997
Proposed branch: lp:~vanvugt/compiz-core/fix-930412
Merge into: lp:compiz-core
Diff against target: 211 lines (+51/-54)
4 files modified
src/action.cpp (+3/-0)
src/privatescreen.h (+0/-2)
src/screen.cpp (+36/-50)
xslt/bcop.xslt (+12/-2)
To merge this branch: bzr merge lp:~vanvugt/compiz-core/fix-930412
Reviewer Review Type Date Requested Status
Sam Spilsbury Approve
Review via email: mp+92720@code.launchpad.net

Commit message

Fixed: Core keybindings like Alt+F4 not being registered due to bad construct/init ordering (LP: #930412)

Description of the change

Fixed: Core keybindings like Alt+F4 not being registered due to bad construct/init ordering (LP: #930412)

Moved CoreOptions initialization to ensure that it only happens after the critical parts of PrivateScreen::init are done. This ensures ::screen and PrivateScreen::dpy are both initialized before CoreOptions, so that CompAction::KeyBinding::fromString no longer fails due to screen being NULL.

To post a comment you must log in.
Revision history for this message
Sam Spilsbury (smspillaz) wrote :

177 - <xsl:text>Options ();
178 + <xsl:text>Options (bool init = true);
179 virtual ~</xsl:text>
180 <xsl:value-of select="$Plugin"/>
181 <xsl:text>Options ();
182
183 + void initOptions ();
184 +
185 virtual CompOption::Vector &amp; getOptions ();
186 virtual bool setOption (const CompString &amp;name, CompOption::Value &amp;value);
187
188 @@ -1090,7 +1092,7 @@
189 <xsl:value-of select="$Plugin"/>
190 <xsl:text>Options::</xsl:text>
191 <xsl:value-of select="$Plugin"/>
192 - <xsl:text>Options () :
193 + <xsl:text>Options (bool init /* = true */) :

I'll take this now because it does actually fix the problem, but there are three things I don't like in this approach, and after 0.9.7.0 we should seek to change

1. We are changing bcop for the sake of core's initialization order and adding a default parameter for the sake of working around it.
2. This generally goes against the RAII principles of bcop
3. We'll need to trigger a rebuild of all the plugins.

The (more invasive) way I think this should be done would be to have a separate class Keybindings who PrivateScreen inherits from first before CoreOptions. This way we can DI a Display * into Keybindings and ensure that the relevant data is initialized before CoreOption's constructor is called.

Like I say, its invasive and I'd rather see the problem fixed before release.

Please merge.

review: Approve
Revision history for this message
Daniel van Vugt (vanvugt) wrote :

I don't think "We'll need to trigger a rebuild of all the plugins". Existing plugins using the old generated code will still work without a rebuild if necessary.

Also regarding generated *Options, it is bad design to have so much activity in the constructor of any class (which happens to be the cause of this bug). I think separating initialization from construction was always going to be cleaner. I don't think any of this qualifies as a hack. In fact, this proposal removes hacks such as PrivateScreen::addScreenActions ()

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

On Mon, 13 Feb 2012, Daniel van Vugt wrote:

> Also regarding generated *Options, it is bad design to have so much activity in the constructor of any class (which happens to be the cause of this bug). I think separating initialization from construction was always going to be cleaner. I don't think any of this qualifies as a hack. In fact, this proposal removes hacks such as PrivateScreen::addScreenActions ()
>

I generally prefer to keep as much init code in constructors as possible
as a matter of principle. I don't like the idea of having ::init* on
objects because it means that there is coupling between the ::init* and
other functions.

Of course, the only place I'm willing to throw aside that rule is where
you need to make virtual function call in a constructor, but I generally
try to rework my design if I have to do that.

> --
> https://code.launchpad.net/~vanvugt/compiz-core/fix-930412/+merge/92720
> You are reviewing the proposed merge of lp:~vanvugt/compiz-core/fix-930412 into lp:compiz-core.
>

Revision history for this message
Tim Penhey (thumper) wrote :

Well, the point of a constructor is to make an object in a well
defined, consistent state.

There is nothing wrong with an extra init if it is needed.

Revision history for this message
Daniel van Vugt (vanvugt) wrote :

It's a principle that sounded messy to me when I was first taught it. However in this bug you will see that having complex initialization in the constructors of CoreOptions and PrivateScreen were the cause of this bug.

Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

> Also regarding generated *Options, it is bad design to have so much activity
> in the constructor of any class (which happens to be the cause of this bug). I
> think separating initialization from construction was always going to be
> cleaner. I don't think any of this qualifies as a hack. In fact, this proposal
> removes hacks such as PrivateScreen::addScreenActions ()

There are a whole host of issues surrounding the initialisation process. But I don't agree that separating initialisation from construction is the right approach. A constructor should put a the instance into a *usable* state - neither more nor less. And that, in many cases implies "much activity".

The classes involved are neither coherent nor weakly coupled and that is the source of the problems. Separating out concerns is the right approach.

Revision history for this message
Daniel van Vugt (vanvugt) wrote :

I would be happy to review and approve any more elegant solution that is proposed...

One could also argue that the "screen" global variable is the cause of this bug. If the global variable didn't exist then this bug wouldn't either.

Revision history for this message
Tim Penhey (thumper) wrote :

Can we file a bug then for the next release to do this with separating out concerns?

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/action.cpp'
2--- src/action.cpp 2012-01-24 08:24:18 +0000
3+++ src/action.cpp 2012-02-13 08:23:17 +0000
4@@ -26,6 +26,7 @@
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <string.h>
8+#include <cassert>
9
10 #include <core/option.h>
11 #include <core/action.h>
12@@ -158,6 +159,8 @@
13 size_t pos, start = 0;
14 KeySym keysym;
15
16+ /* This assertion is a regression test for LP: #930412 */
17+ assert (screen);
18 if (!screen)
19 return false;
20
21
22=== modified file 'src/privatescreen.h'
23--- src/privatescreen.h 2012-02-08 15:07:30 +0000
24+++ src/privatescreen.h 2012-02-13 08:23:17 +0000
25@@ -370,8 +370,6 @@
26
27 void disableEdge (int edge);
28
29- void addScreenActions ();
30-
31 CompWindow *
32 focusTopMostWindow ();
33
34
35=== modified file 'src/screen.cpp'
36--- src/screen.cpp 2012-02-09 15:03:04 +0000
37+++ src/screen.cpp 2012-02-13 08:23:17 +0000
38@@ -3257,24 +3257,10 @@
39 }
40 }
41
42-/* add actions that should be automatically added as no screens
43- existed when they were initialized. */
44-void
45-PrivateScreen::addScreenActions ()
46-{
47- foreach (CompOption &o, mOptions)
48- {
49- if (!o.isAction ())
50- continue;
51-
52- if (o.value ().action ().state () & CompAction::StateAutoGrab)
53- screen->addAction (&o.value ().action ());
54- }
55-}
56-
57 bool
58 CompScreenImpl::addAction (CompAction *action)
59 {
60+ assert (priv->initialized);
61 if (!priv->initialized)
62 return false;
63
64@@ -4735,6 +4721,8 @@
65
66 reshape (attrib.width, attrib.height);
67
68+ initialized = true;
69+ initOptions ();
70 detectOutputDevices ();
71 updateOutputDevices ();
72
73@@ -4805,7 +4793,6 @@
74 XSync (dpy, FALSE);
75
76 /* Start initializing windows here */
77- initialized = true;
78
79 for (unsigned int i = 0; i < nchildren; i++)
80 {
81@@ -4893,7 +4880,38 @@
82
83 pingTimer.start ();
84
85- addScreenActions ();
86+ optionSetCloseWindowKeyInitiate (CompScreenImpl::closeWin);
87+ optionSetCloseWindowButtonInitiate (CompScreenImpl::closeWin);
88+ optionSetRaiseWindowKeyInitiate (CompScreenImpl::raiseWin);
89+ optionSetRaiseWindowButtonInitiate (CompScreenImpl::raiseWin);
90+ optionSetLowerWindowKeyInitiate (CompScreenImpl::lowerWin);
91+ optionSetLowerWindowButtonInitiate (CompScreenImpl::lowerWin);
92+
93+ optionSetUnmaximizeWindowKeyInitiate (CompScreenImpl::unmaximizeWin);
94+
95+ optionSetMinimizeWindowKeyInitiate (CompScreenImpl::minimizeWin);
96+ optionSetMinimizeWindowButtonInitiate (CompScreenImpl::minimizeWin);
97+ optionSetMaximizeWindowKeyInitiate (CompScreenImpl::maximizeWin);
98+ optionSetMaximizeWindowHorizontallyKeyInitiate (
99+ CompScreenImpl::maximizeWinHorizontally);
100+ optionSetMaximizeWindowVerticallyKeyInitiate (
101+ CompScreenImpl::maximizeWinVertically);
102+
103+ optionSetWindowMenuKeyInitiate (CompScreenImpl::windowMenu);
104+ optionSetWindowMenuButtonInitiate (CompScreenImpl::windowMenu);
105+
106+ optionSetShowDesktopKeyInitiate (CompScreenImpl::showDesktop);
107+ optionSetShowDesktopEdgeInitiate (CompScreenImpl::showDesktop);
108+
109+ optionSetToggleWindowMaximizedKeyInitiate (CompScreenImpl::toggleWinMaximized);
110+ optionSetToggleWindowMaximizedButtonInitiate (CompScreenImpl::toggleWinMaximized);
111+
112+ optionSetToggleWindowMaximizedHorizontallyKeyInitiate (
113+ CompScreenImpl::toggleWinMaximizedHorizontally);
114+ optionSetToggleWindowMaximizedVerticallyKeyInitiate (
115+ CompScreenImpl::toggleWinMaximizedVertically);
116+
117+ optionSetToggleWindowShadedKeyInitiate (CompScreenImpl::shadeWin);
118
119 if (dirtyPluginList)
120 updatePlugins ();
121@@ -4907,6 +4925,7 @@
122 }
123
124 PrivateScreen::PrivateScreen (CompScreen *screen) :
125+ CoreOptions (false),
126 source(0),
127 timeout(0),
128 fileWatch (0),
129@@ -4970,39 +4989,6 @@
130
131 memset (&history, 0, sizeof (Window) * ACTIVE_WINDOW_HISTORY_NUM);
132
133- optionSetCloseWindowKeyInitiate (CompScreenImpl::closeWin);
134- optionSetCloseWindowButtonInitiate (CompScreenImpl::closeWin);
135- optionSetRaiseWindowKeyInitiate (CompScreenImpl::raiseWin);
136- optionSetRaiseWindowButtonInitiate (CompScreenImpl::raiseWin);
137- optionSetLowerWindowKeyInitiate (CompScreenImpl::lowerWin);
138- optionSetLowerWindowButtonInitiate (CompScreenImpl::lowerWin);
139-
140- optionSetUnmaximizeWindowKeyInitiate (CompScreenImpl::unmaximizeWin);
141-
142- optionSetMinimizeWindowKeyInitiate (CompScreenImpl::minimizeWin);
143- optionSetMinimizeWindowButtonInitiate (CompScreenImpl::minimizeWin);
144- optionSetMaximizeWindowKeyInitiate (CompScreenImpl::maximizeWin);
145- optionSetMaximizeWindowHorizontallyKeyInitiate (
146- CompScreenImpl::maximizeWinHorizontally);
147- optionSetMaximizeWindowVerticallyKeyInitiate (
148- CompScreenImpl::maximizeWinVertically);
149-
150- optionSetWindowMenuKeyInitiate (CompScreenImpl::windowMenu);
151- optionSetWindowMenuButtonInitiate (CompScreenImpl::windowMenu);
152-
153- optionSetShowDesktopKeyInitiate (CompScreenImpl::showDesktop);
154- optionSetShowDesktopEdgeInitiate (CompScreenImpl::showDesktop);
155-
156- optionSetToggleWindowMaximizedKeyInitiate (CompScreenImpl::toggleWinMaximized);
157- optionSetToggleWindowMaximizedButtonInitiate (CompScreenImpl::toggleWinMaximized);
158-
159- optionSetToggleWindowMaximizedHorizontallyKeyInitiate (
160- CompScreenImpl::toggleWinMaximizedHorizontally);
161- optionSetToggleWindowMaximizedVerticallyKeyInitiate (
162- CompScreenImpl::toggleWinMaximizedVertically);
163-
164- optionSetToggleWindowShadedKeyInitiate (CompScreenImpl::shadeWin);
165-
166 TimeoutHandler::SetDefault (dTimeoutHandler);
167 }
168
169
170=== modified file 'xslt/bcop.xslt'
171--- xslt/bcop.xslt 2012-02-01 14:03:38 +0000
172+++ xslt/bcop.xslt 2012-02-13 08:23:17 +0000
173@@ -941,11 +941,13 @@
174
175 </xsl:text>
176 <xsl:value-of select="$Plugin"/>
177- <xsl:text>Options ();
178+ <xsl:text>Options (bool init = true);
179 virtual ~</xsl:text>
180 <xsl:value-of select="$Plugin"/>
181 <xsl:text>Options ();
182
183+ void initOptions ();
184+
185 virtual CompOption::Vector &amp; getOptions ();
186 virtual bool setOption (const CompString &amp;name, CompOption::Value &amp;value);
187
188@@ -1090,7 +1092,7 @@
189 <xsl:value-of select="$Plugin"/>
190 <xsl:text>Options::</xsl:text>
191 <xsl:value-of select="$Plugin"/>
192- <xsl:text>Options () :
193+ <xsl:text>Options (bool init /* = true */) :
194 mOptions (</xsl:text>
195 <xsl:value-of select="$Plugin"/>
196 <xsl:text>Options::OptionNum),
197@@ -1098,6 +1100,14 @@
198 <xsl:value-of select="$Plugin"/>
199 <xsl:text>Options::OptionNum)
200 {
201+ if (init)
202+ initOptions ();
203+}
204+
205+void
206+</xsl:text>
207+<xsl:value-of select="$Plugin"/><xsl:text>Options::initOptions ()
208+{
209 </xsl:text>
210 <xsl:if test="/compiz/plugin[@name=$pName]/descendant-or-self::option[@type = 'action'] or
211 /compiz/plugin[@name=$pName]/descendant-or-self::option[@type = 'key'] or

Subscribers

People subscribed via source and target branches