recreate presentwindows grids from desktopgrid

Theory:
----------
because PresentWindowsEffect::screenCountChanged() is shortcut
for "if (!isActive())", but the desktopgrid doesn't call
PresentWindowsEffect::setActive (or at least
PresentWindowsEffect::screenCountChanged), so the effect can
"miss" the increasing screen count change (it sees the signal,
but ignores it) and when desktopgrid calls it, it assumes the
m_gridSizes array is big enough (but it isn't)

Steps:
----------
1. effects are loaded, 1 screen present
2. 2nd screen gets added, but inactive effects ignore that
3. desktop grid gets activated, updates according to screen count,
   calls presentwindows for screen #2
4. presentwindows data is only prepared for one screen from step 1
   => BOOM

BUG: 351724
CCBUG: 326032
FIXED-IN: 5.4.2
REVIEW: 124960
This commit is contained in:
Thomas Lübking 2015-08-28 07:50:20 +02:00
parent 5fb67414d2
commit 57f8c6d5f8
5 changed files with 17 additions and 6 deletions

View file

@ -1098,6 +1098,7 @@ void DesktopGridEffect::setup()
if (m_usePresentWindows)
m_proxy = static_cast<PresentWindowsEffectProxy*>(effects->getProxy(BuiltInEffects::nameForEffect(BuiltInEffect::PresentWindows)));
if (isUsingPresentWindows()) {
m_proxy->reCreateGrids(); // revalidation on multiscreen, bug #351724
for (int i = 1; i <= effects->numberOfDesktops(); i++) {
for (int j = 0; j < effects->numScreens(); j++) {
WindowMotionManager manager;

View file

@ -96,7 +96,12 @@ PresentWindowsEffect::PresentWindowsEffect()
connect(effects, SIGNAL(windowDeleted(KWin::EffectWindow*)), this, SLOT(slotWindowDeleted(KWin::EffectWindow*)));
connect(effects, SIGNAL(windowGeometryShapeChanged(KWin::EffectWindow*,QRect)), this, SLOT(slotWindowGeometryShapeChanged(KWin::EffectWindow*,QRect)));
connect(effects, SIGNAL(propertyNotify(KWin::EffectWindow*,long)), this, SLOT(slotPropertyNotify(KWin::EffectWindow*,long)));
connect(effects, &EffectsHandler::numberScreensChanged, this, &PresentWindowsEffect::screenCountChanged);
connect(effects, &EffectsHandler::numberScreensChanged, this,
[this] {
if (isActive())
reCreateGrids();
}
);
}
PresentWindowsEffect::~PresentWindowsEffect()
@ -1489,7 +1494,7 @@ void PresentWindowsEffect::setActive(bool active)
m_hasKeyboardGrab = effects->grabKeyboard(this);
effects->setActiveFullScreenEffect(this);
screenCountChanged();
reCreateGrids();
rearrangeWindows();
setHighlightedWindow(effects->activeWindow());
@ -1866,10 +1871,8 @@ bool PresentWindowsEffect::isActive() const
return m_activated || m_motionManager.managingWindows();
}
void PresentWindowsEffect::screenCountChanged()
void PresentWindowsEffect::reCreateGrids()
{
if (!isActive())
return;
m_gridSizes.clear();
for (int i = 0; i < effects->numScreens(); ++i) {
m_gridSizes.append(GridSize());

View file

@ -225,11 +225,11 @@ public Q_SLOTS:
private Q_SLOTS:
void closeWindow();
void elevateCloseWindow();
void screenCountChanged();
protected:
// Window rearranging
void rearrangeWindows();
void reCreateGrids();
void calculateWindowTransformations(EffectWindowList windowlist, int screen,
WindowMotionManager& motionManager, bool external = false);
void calculateWindowTransformationsClosest(EffectWindowList windowlist, int screen,

View file

@ -39,4 +39,9 @@ void PresentWindowsEffectProxy::calculateWindowTransformations(EffectWindowList
return m_effect->calculateWindowTransformations(windows, screen, manager, true);
}
void PresentWindowsEffectProxy::reCreateGrids()
{
m_effect->reCreateGrids();
}
} // namespace

View file

@ -35,6 +35,8 @@ public:
void calculateWindowTransformations(EffectWindowList windows, int screen, WindowMotionManager& manager);
void reCreateGrids();
private:
PresentWindowsEffect* m_effect;
};