Strip QHash::operator[] from present window effect
also rewrite of the regular grid assignment - was a) a suboptimal implementation b) required because otherwise broken in desktopgrid proxy mode (which btw. polluted the effect through QHash::operator[]) BUG:262485
This commit is contained in:
parent
bfd922d7fa
commit
48939462da
2 changed files with 252 additions and 239 deletions
|
@ -257,42 +257,47 @@ void PresentWindowsEffect::prePaintWindow(EffectWindow *w, WindowPrePaintData &d
|
||||||
{
|
{
|
||||||
// TODO: We should also check to see if any windows are fading just in case fading takes longer
|
// TODO: We should also check to see if any windows are fading just in case fading takes longer
|
||||||
// than moving the windows when the effect is deactivated.
|
// than moving the windows when the effect is deactivated.
|
||||||
if ((m_activated || m_motionManager.areWindowsMoving()) && m_windowData.contains(w)) {
|
if (m_activated || m_motionManager.areWindowsMoving()) {
|
||||||
|
DataHash::iterator winData = m_windowData.find(w);
|
||||||
|
if (winData == m_windowData.end()) {
|
||||||
|
effects->prePaintWindow(w, data, time);
|
||||||
|
return;
|
||||||
|
}
|
||||||
w->enablePainting(EffectWindow::PAINT_DISABLED_BY_MINIMIZE); // Display always
|
w->enablePainting(EffectWindow::PAINT_DISABLED_BY_MINIMIZE); // Display always
|
||||||
w->enablePainting(EffectWindow::PAINT_DISABLED_BY_DESKTOP);
|
w->enablePainting(EffectWindow::PAINT_DISABLED_BY_DESKTOP);
|
||||||
if (m_windowData[w].visible)
|
if (winData->visible)
|
||||||
w->enablePainting(EffectWindow::PAINT_DISABLED_BY_CLIENT_GROUP);
|
w->enablePainting(EffectWindow::PAINT_DISABLED_BY_CLIENT_GROUP);
|
||||||
|
|
||||||
// Calculate window's opacity
|
// Calculate window's opacity
|
||||||
// TODO: Minimized windows or windows not on the current desktop are only 75% visible?
|
// TODO: Minimized windows or windows not on the current desktop are only 75% visible?
|
||||||
if (m_windowData[w].visible) {
|
if (winData->visible) {
|
||||||
if (m_windowData[w].deleted)
|
if (winData->deleted)
|
||||||
m_windowData[w].opacity = qMax(0.0, m_windowData[w].opacity - time / m_fadeDuration);
|
winData->opacity = qMax(0.0, winData->opacity - time / m_fadeDuration);
|
||||||
else
|
else
|
||||||
m_windowData[w].opacity = qMin(/*( w->isMinimized() || !w->isOnCurrentDesktop() ) ? 0.75 :*/ 1.0,
|
winData->opacity = qMin(/*(w->isMinimized() || !w->isOnCurrentDesktop()) ? 0.75 :*/ 1.0,
|
||||||
m_windowData[w].opacity + time / m_fadeDuration);
|
winData->opacity + time / m_fadeDuration);
|
||||||
} else
|
} else
|
||||||
m_windowData[w].opacity = qMax(0.0, m_windowData[w].opacity - time / m_fadeDuration);
|
winData->opacity = qMax(0.0, winData->opacity - time / m_fadeDuration);
|
||||||
if (m_windowData[w].opacity == 0.0) {
|
if (winData->opacity <= 0.0) {
|
||||||
// don't disable painting for panels if show panel is set
|
// don't disable painting for panels if show panel is set
|
||||||
if (!w->isDock() || (w->isDock() && !m_showPanel))
|
if (!(m_showPanel && w->isDock()))
|
||||||
w->disablePainting(EffectWindow::PAINT_DISABLED);
|
w->disablePainting(EffectWindow::PAINT_DISABLED);
|
||||||
} else if (m_windowData[w].opacity != 1.0)
|
} else if (winData->opacity != 1.0)
|
||||||
data.setTranslucent();
|
data.setTranslucent();
|
||||||
|
|
||||||
// Calculate window's brightness
|
// Calculate window's brightness
|
||||||
if (w == m_highlightedWindow || w == m_closeWindow || !m_activated)
|
if (w == m_highlightedWindow || w == m_closeWindow || !m_activated)
|
||||||
m_windowData[w].highlight = qMin(1.0, m_windowData[w].highlight + time / m_fadeDuration);
|
winData->highlight = qMin(1.0, winData->highlight + time / m_fadeDuration);
|
||||||
else
|
else
|
||||||
m_windowData[w].highlight = qMax(0.0, m_windowData[w].highlight - time / m_fadeDuration);
|
winData->highlight = qMax(0.0, winData->highlight - time / m_fadeDuration);
|
||||||
|
|
||||||
// Closed windows
|
// Closed windows
|
||||||
if (m_windowData[w].deleted) {
|
if (winData->deleted) {
|
||||||
data.setTranslucent();
|
data.setTranslucent();
|
||||||
if (m_windowData[w].opacity <= 0.0 && m_windowData[w].referenced) {
|
if (winData->opacity <= 0.0 && winData->referenced) {
|
||||||
// it's possible that another effect has referenced the window
|
// it's possible that another effect has referenced the window
|
||||||
// we have to keep the window in the list to prevent flickering
|
// we have to keep the window in the list to prevent flickering
|
||||||
m_windowData[w].referenced = false;
|
winData->referenced = false;
|
||||||
w->unrefWindow();
|
w->unrefWindow();
|
||||||
} else
|
} else
|
||||||
w->enablePainting(EffectWindow::PAINT_DISABLED_BY_DELETE);
|
w->enablePainting(EffectWindow::PAINT_DISABLED_BY_DELETE);
|
||||||
|
@ -310,16 +315,17 @@ void PresentWindowsEffect::prePaintWindow(EffectWindow *w, WindowPrePaintData &d
|
||||||
|
|
||||||
void PresentWindowsEffect::paintWindow(EffectWindow *w, int mask, QRegion region, WindowPaintData &data)
|
void PresentWindowsEffect::paintWindow(EffectWindow *w, int mask, QRegion region, WindowPaintData &data)
|
||||||
{
|
{
|
||||||
if ((m_activated || m_motionManager.areWindowsMoving()) && m_windowData.contains(w)) {
|
if (m_activated || m_motionManager.areWindowsMoving()) {
|
||||||
if (w->isDock() && m_showPanel) {
|
DataHash::const_iterator winData = m_windowData.find(w);
|
||||||
|
if (winData == m_windowData.constEnd() || (w->isDock() && m_showPanel)) {
|
||||||
// in case the panel should be shown just display it without any changes
|
// in case the panel should be shown just display it without any changes
|
||||||
effects->paintWindow(w, mask, region, data);
|
effects->paintWindow(w, mask, region, data);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply opacity and brightness
|
// Apply opacity and brightness
|
||||||
data.opacity *= m_windowData[w].opacity;
|
data.opacity *= winData->opacity;
|
||||||
data.brightness *= interpolate(0.7, 1.0, m_windowData[w].highlight);
|
data.brightness *= interpolate(0.7, 1.0, winData->highlight);
|
||||||
|
|
||||||
if (m_motionManager.isManaging(w)) {
|
if (m_motionManager.isManaging(w)) {
|
||||||
m_motionManager.apply(w, data);
|
m_motionManager.apply(w, data);
|
||||||
|
@ -333,7 +339,7 @@ void PresentWindowsEffect::paintWindow(EffectWindow *w, int mask, QRegion region
|
||||||
if (m_showIcons) {
|
if (m_showIcons) {
|
||||||
QPoint point(rect.x() + rect.width() * 0.95,
|
QPoint point(rect.x() + rect.width() * 0.95,
|
||||||
rect.y() + rect.height() * 0.95);
|
rect.y() + rect.height() * 0.95);
|
||||||
m_windowData[w].iconFrame->setPosition(point);
|
winData->iconFrame->setPosition(point);
|
||||||
#ifdef KWIN_HAVE_OPENGL_COMPOSITING
|
#ifdef KWIN_HAVE_OPENGL_COMPOSITING
|
||||||
if (effects->compositingType() == KWin::OpenGLCompositing && data.shader) {
|
if (effects->compositingType() == KWin::OpenGLCompositing && data.shader) {
|
||||||
const float a = 0.9 * data.opacity * m_decalOpacity * 0.75;
|
const float a = 0.9 * data.opacity * m_decalOpacity * 0.75;
|
||||||
|
@ -342,12 +348,12 @@ void PresentWindowsEffect::paintWindow(EffectWindow *w, int mask, QRegion region
|
||||||
data.shader->setUniform(GLShader::ModulationConstant, QVector4D(a, a, a, a));
|
data.shader->setUniform(GLShader::ModulationConstant, QVector4D(a, a, a, a));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
m_windowData[w].iconFrame->render(region, 0.9 * data.opacity * m_decalOpacity, 0.75);
|
winData->iconFrame->render(region, 0.9 * data.opacity * m_decalOpacity, 0.75);
|
||||||
}
|
}
|
||||||
if (m_showCaptions) {
|
if (m_showCaptions) {
|
||||||
QPoint point(rect.x() + rect.width() / 2,
|
QPoint point(rect.x() + rect.width() / 2,
|
||||||
rect.y() + rect.height() / 2);
|
rect.y() + rect.height() / 2);
|
||||||
m_windowData[w].textFrame->setPosition(point);
|
winData->textFrame->setPosition(point);
|
||||||
#ifdef KWIN_HAVE_OPENGL_COMPOSITING
|
#ifdef KWIN_HAVE_OPENGL_COMPOSITING
|
||||||
if (effects->compositingType() == KWin::OpenGLCompositing && data.shader) {
|
if (effects->compositingType() == KWin::OpenGLCompositing && data.shader) {
|
||||||
const float a = 0.9 * data.opacity * m_decalOpacity * 0.75;
|
const float a = 0.9 * data.opacity * m_decalOpacity * 0.75;
|
||||||
|
@ -356,7 +362,7 @@ void PresentWindowsEffect::paintWindow(EffectWindow *w, int mask, QRegion region
|
||||||
data.shader->setUniform(GLShader::ModulationConstant, QVector4D(a, a, a, a));
|
data.shader->setUniform(GLShader::ModulationConstant, QVector4D(a, a, a, a));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
m_windowData[w].textFrame->render(region, 0.9 * data.opacity * m_decalOpacity, 0.75);
|
winData->textFrame->render(region, 0.9 * data.opacity * m_decalOpacity, 0.75);
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
effects->paintWindow(w, mask, region, data);
|
effects->paintWindow(w, mask, region, data);
|
||||||
|
@ -371,24 +377,25 @@ void PresentWindowsEffect::slotWindowAdded(EffectWindow *w)
|
||||||
{
|
{
|
||||||
if (!m_activated)
|
if (!m_activated)
|
||||||
return;
|
return;
|
||||||
m_windowData[w].visible = isVisibleWindow(w);
|
WindowData *winData = &m_windowData[w];
|
||||||
m_windowData[w].opacity = 0.0;
|
winData->visible = isVisibleWindow(w);
|
||||||
m_windowData[w].highlight = 0.0;
|
winData->opacity = 0.0;
|
||||||
m_windowData[w].textFrame = effects->effectFrame(EffectFrameUnstyled, false);
|
winData->highlight = 0.0;
|
||||||
|
winData->textFrame = effects->effectFrame(EffectFrameUnstyled, false);
|
||||||
QFont font;
|
QFont font;
|
||||||
font.setBold(true);
|
font.setBold(true);
|
||||||
font.setPointSize(12);
|
font.setPointSize(12);
|
||||||
m_windowData[w].textFrame->setFont(font);
|
winData->textFrame->setFont(font);
|
||||||
m_windowData[w].iconFrame = effects->effectFrame(EffectFrameUnstyled, false);
|
winData->iconFrame = effects->effectFrame(EffectFrameUnstyled, false);
|
||||||
m_windowData[w].iconFrame->setAlignment(Qt::AlignRight | Qt::AlignBottom);
|
winData->iconFrame->setAlignment(Qt::AlignRight | Qt::AlignBottom);
|
||||||
m_windowData[w].iconFrame->setIcon(w->icon());
|
winData->iconFrame->setIcon(w->icon());
|
||||||
if (isSelectableWindow(w)) {
|
if (isSelectableWindow(w)) {
|
||||||
m_motionManager.manage(w);
|
m_motionManager.manage(w);
|
||||||
rearrangeWindows();
|
rearrangeWindows();
|
||||||
}
|
}
|
||||||
if (w == effects->findWindow(m_closeView->winId())) {
|
if (w == effects->findWindow(m_closeView->winId())) {
|
||||||
m_windowData[w].visible = true;
|
winData->visible = true;
|
||||||
m_windowData[w].highlight = 1.0;
|
winData->highlight = 1.0;
|
||||||
m_closeWindow = w;
|
m_closeWindow = w;
|
||||||
w->setData(WindowForceBlurRole, QVariant(true));
|
w->setData(WindowForceBlurRole, QVariant(true));
|
||||||
}
|
}
|
||||||
|
@ -398,10 +405,11 @@ void PresentWindowsEffect::slotWindowClosed(EffectWindow *w)
|
||||||
{
|
{
|
||||||
if (m_managerWindow == w)
|
if (m_managerWindow == w)
|
||||||
m_managerWindow = NULL;
|
m_managerWindow = NULL;
|
||||||
if (!m_windowData.contains(w))
|
DataHash::iterator winData = m_windowData.find(w);
|
||||||
|
if (winData == m_windowData.end())
|
||||||
return;
|
return;
|
||||||
m_windowData[w].deleted = true;
|
winData->deleted = true;
|
||||||
m_windowData[w].referenced = true;
|
winData->referenced = true;
|
||||||
w->refWindow();
|
w->refWindow();
|
||||||
if (m_highlightedWindow == w)
|
if (m_highlightedWindow == w)
|
||||||
setHighlightedWindow(findFirstWindow());
|
setHighlightedWindow(findFirstWindow());
|
||||||
|
@ -411,8 +419,8 @@ void PresentWindowsEffect::slotWindowClosed(EffectWindow *w)
|
||||||
}
|
}
|
||||||
rearrangeWindows();
|
rearrangeWindows();
|
||||||
|
|
||||||
foreach (EffectWindow * w, m_motionManager.managedWindows()) {
|
foreach (EffectWindow *w, m_motionManager.managedWindows()) {
|
||||||
DataHash::iterator winData = m_windowData.find( w );
|
winData = m_windowData.find(w);
|
||||||
if (winData != m_windowData.end() && !winData->deleted)
|
if (winData != m_windowData.end() && !winData->deleted)
|
||||||
return; // found one that is not deleted? then we go on
|
return; // found one that is not deleted? then we go on
|
||||||
}
|
}
|
||||||
|
@ -421,11 +429,12 @@ void PresentWindowsEffect::slotWindowClosed(EffectWindow *w)
|
||||||
|
|
||||||
void PresentWindowsEffect::slotWindowDeleted(EffectWindow *w)
|
void PresentWindowsEffect::slotWindowDeleted(EffectWindow *w)
|
||||||
{
|
{
|
||||||
if (!m_windowData.contains(w))
|
DataHash::iterator winData = m_windowData.find(w);
|
||||||
|
if (winData == m_windowData.end())
|
||||||
return;
|
return;
|
||||||
delete m_windowData[w].textFrame;
|
delete winData->textFrame;
|
||||||
delete m_windowData[w].iconFrame;
|
delete winData->iconFrame;
|
||||||
m_windowData.remove(w);
|
m_windowData.erase(winData);
|
||||||
m_motionManager.unmanage(w);
|
m_motionManager.unmanage(w);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -474,10 +483,12 @@ void PresentWindowsEffect::windowInputMouseEvent(Window w, QEvent *e)
|
||||||
// We cannot use m_motionManager.windowAtPoint() as the window might not be visible
|
// We cannot use m_motionManager.windowAtPoint() as the window might not be visible
|
||||||
EffectWindowList windows = m_motionManager.managedWindows();
|
EffectWindowList windows = m_motionManager.managedWindows();
|
||||||
bool hovering = false;
|
bool hovering = false;
|
||||||
for (int i = 0; i < windows.size(); i++) {
|
for (int i = 0; i < windows.size(); ++i) {
|
||||||
assert(m_windowData.contains(windows.at(i)));
|
DataHash::const_iterator winData = m_windowData.find(windows.at(i));
|
||||||
|
if (winData == m_windowData.constEnd())
|
||||||
|
continue;
|
||||||
if (m_motionManager.transformedGeometry(windows.at(i)).contains(cursorPos()) &&
|
if (m_motionManager.transformedGeometry(windows.at(i)).contains(cursorPos()) &&
|
||||||
m_windowData[windows.at(i)].visible && !m_windowData[windows.at(i)].deleted) {
|
winData->visible && !winData->deleted) {
|
||||||
hovering = true;
|
hovering = true;
|
||||||
if (windows.at(i) && m_highlightedWindow != windows.at(i))
|
if (windows.at(i) && m_highlightedWindow != windows.at(i))
|
||||||
setHighlightedWindow(windows.at(i));
|
setHighlightedWindow(windows.at(i));
|
||||||
|
@ -844,26 +855,26 @@ void PresentWindowsEffect::rearrangeWindows()
|
||||||
else
|
else
|
||||||
windowlist = m_motionManager.managedWindows();
|
windowlist = m_motionManager.managedWindows();
|
||||||
foreach (EffectWindow * w, m_motionManager.managedWindows()) {
|
foreach (EffectWindow * w, m_motionManager.managedWindows()) {
|
||||||
if (m_windowData[w].deleted)
|
DataHash::iterator winData = m_windowData.find(w);
|
||||||
|
if (winData == m_windowData.end() || winData->deleted)
|
||||||
continue; // don't include closed windows
|
continue; // don't include closed windows
|
||||||
windowlists[w->screen()].append(w);
|
windowlists[w->screen()].append(w);
|
||||||
assert(m_windowData.contains(w));
|
winData->visible = true;
|
||||||
m_windowData[w].visible = true;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Can we move this filtering somewhere else?
|
// Can we move this filtering somewhere else?
|
||||||
foreach (EffectWindow * w, m_motionManager.managedWindows()) {
|
foreach (EffectWindow * w, m_motionManager.managedWindows()) {
|
||||||
assert(m_windowData.contains(w));
|
DataHash::iterator winData = m_windowData.find(w);
|
||||||
if (m_windowData[w].deleted)
|
if (winData == m_windowData.end() || winData->deleted)
|
||||||
continue; // don't include closed windows
|
continue; // don't include closed windows
|
||||||
if (w->caption().contains(m_windowFilter, Qt::CaseInsensitive) ||
|
if (w->caption().contains(m_windowFilter, Qt::CaseInsensitive) ||
|
||||||
w->windowClass().contains(m_windowFilter, Qt::CaseInsensitive) ||
|
w->windowClass().contains(m_windowFilter, Qt::CaseInsensitive) ||
|
||||||
w->windowRole().contains(m_windowFilter, Qt::CaseInsensitive)) {
|
w->windowRole().contains(m_windowFilter, Qt::CaseInsensitive)) {
|
||||||
windowlist.append(w);
|
windowlist.append(w);
|
||||||
windowlists[w->screen()].append(w);
|
windowlists[w->screen()].append(w);
|
||||||
m_windowData[w].visible = true;
|
winData->visible = true;
|
||||||
} else
|
} else
|
||||||
m_windowData[w].visible = false;
|
winData->visible = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (windowlist.isEmpty()) {
|
if (windowlist.isEmpty()) {
|
||||||
|
@ -873,8 +884,8 @@ void PresentWindowsEffect::rearrangeWindows()
|
||||||
|
|
||||||
// We filtered out the highlighted window
|
// We filtered out the highlighted window
|
||||||
if (m_highlightedWindow) {
|
if (m_highlightedWindow) {
|
||||||
assert(m_windowData.contains(m_highlightedWindow));
|
DataHash::iterator winData = m_windowData.find(m_highlightedWindow);
|
||||||
if (m_windowData[m_highlightedWindow].visible == false)
|
if (winData != m_windowData.end() && !winData->visible)
|
||||||
setHighlightedWindow(findFirstWindow());
|
setHighlightedWindow(findFirstWindow());
|
||||||
} else if (m_tabBoxEnabled)
|
} else if (m_tabBoxEnabled)
|
||||||
setHighlightedWindow(effects->currentTabBoxWindow());
|
setHighlightedWindow(effects->currentTabBoxWindow());
|
||||||
|
@ -911,12 +922,15 @@ void PresentWindowsEffect::rearrangeWindows()
|
||||||
// Resize text frames if required
|
// Resize text frames if required
|
||||||
QFontMetrics* metrics = NULL; // All fonts are the same
|
QFontMetrics* metrics = NULL; // All fonts are the same
|
||||||
foreach (EffectWindow * w, m_motionManager.managedWindows()) {
|
foreach (EffectWindow * w, m_motionManager.managedWindows()) {
|
||||||
|
DataHash::iterator winData = m_windowData.find(w);
|
||||||
|
if (winData == m_windowData.end())
|
||||||
|
continue;
|
||||||
if (!metrics)
|
if (!metrics)
|
||||||
metrics = new QFontMetrics(m_windowData[w].textFrame->font());
|
metrics = new QFontMetrics(winData->textFrame->font());
|
||||||
QRect geom = m_motionManager.targetGeometry(w).toRect();
|
QRect geom = m_motionManager.targetGeometry(w).toRect();
|
||||||
QString string = metrics->elidedText(w->caption(), Qt::ElideRight, geom.width() * 0.9);
|
QString string = metrics->elidedText(w->caption(), Qt::ElideRight, geom.width() * 0.9);
|
||||||
if (string != m_windowData[w].textFrame->text())
|
if (string != winData->textFrame->text())
|
||||||
m_windowData[w].textFrame->setText(string);
|
winData->textFrame->setText(string);
|
||||||
}
|
}
|
||||||
delete metrics;
|
delete metrics;
|
||||||
}
|
}
|
||||||
|
@ -936,6 +950,13 @@ void PresentWindowsEffect::calculateWindowTransformations(EffectWindowList windo
|
||||||
m_windowData.clear();
|
m_windowData.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int distance(QPoint &pos1, QPoint &pos2)
|
||||||
|
{
|
||||||
|
const int xdiff = pos1.x() - pos2.x();
|
||||||
|
const int ydiff = pos1.y() - pos2.y();
|
||||||
|
return int(sqrt(float(xdiff*xdiff + ydiff*ydiff)));
|
||||||
|
}
|
||||||
|
|
||||||
void PresentWindowsEffect::calculateWindowTransformationsClosest(EffectWindowList windowlist, int screen,
|
void PresentWindowsEffect::calculateWindowTransformationsClosest(EffectWindowList windowlist, int screen,
|
||||||
WindowMotionManager& motionManager)
|
WindowMotionManager& motionManager)
|
||||||
{
|
{
|
||||||
|
@ -957,43 +978,68 @@ void PresentWindowsEffect::calculateWindowTransformationsClosest(EffectWindowLis
|
||||||
}
|
}
|
||||||
|
|
||||||
// Assign slots
|
// Assign slots
|
||||||
foreach (EffectWindow * w, windowlist)
|
int slotWidth = area.width() / columns;
|
||||||
m_windowData[w].slot = -1;
|
int slotHeight = area.height() / rows;
|
||||||
|
QVector<EffectWindow*> takenSlots;
|
||||||
|
takenSlots.resize(rows*columns);
|
||||||
|
takenSlots.fill(0);
|
||||||
|
|
||||||
if (m_tabBoxEnabled) {
|
if (m_tabBoxEnabled) {
|
||||||
// Rearrange in the correct order. As rearrangeWindows() is only ever
|
// Rearrange in the correct order. As rearrangeWindows() is only ever
|
||||||
// called once so we can use effects->currentTabBoxWindow() here.
|
// called once so we can use effects->currentTabBoxWindow() here.
|
||||||
int selectedWindow = qMax(0, windowlist.indexOf(effects->currentTabBoxWindow()));
|
int selectedWindow = qMax(0, windowlist.indexOf(effects->currentTabBoxWindow()));
|
||||||
int slot = 0;
|
int j = 0;
|
||||||
for (int i = selectedWindow; i < windowlist.count(); i++)
|
for (int i = selectedWindow; i < windowlist.count(); ++i)
|
||||||
m_windowData[windowlist[i]].slot = slot++;
|
takenSlots[j++] = windowlist[i];
|
||||||
for (int i = selectedWindow - 1; i >= 0; i--)
|
for (int i = selectedWindow - 1; i >= 0; --i)
|
||||||
m_windowData[windowlist[i]].slot = slot++;
|
takenSlots[j++] = windowlist[i];
|
||||||
} else {
|
} else {
|
||||||
for (;;) {
|
|
||||||
// Assign each window to the closest available slot
|
// precalculate all slot centers
|
||||||
assignSlots(windowlist, area, columns, rows);
|
QVector<QPoint> slotCenters;
|
||||||
// Leave only the closest window in each slot, remove further conflicts
|
slotCenters.resize(rows*columns);
|
||||||
getBestAssignments(windowlist);
|
for (int x = 0; x < columns; ++x)
|
||||||
bool allAssigned = true;
|
for (int y = 0; y < rows; ++y) {
|
||||||
foreach (EffectWindow * w, windowlist)
|
slotCenters[x + y*columns] = QPoint(area.x() + slotWidth * x + slotWidth / 2,
|
||||||
if (m_windowData[w].slot == -1) {
|
area.y() + slotHeight * y + slotHeight / 2);
|
||||||
allAssigned = false;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
if (allAssigned)
|
|
||||||
break;
|
// Assign each window to the closest available slot
|
||||||
|
EffectWindowList tmpList = windowlist; // use a QLinkedList copy instead?
|
||||||
|
QPoint otherPos;
|
||||||
|
while (!tmpList.isEmpty()) {
|
||||||
|
EffectWindow *w = tmpList.first();
|
||||||
|
int slotCandidate = -1, slotCandidateDistance = INT_MAX;
|
||||||
|
QPoint pos = w->geometry().center();
|
||||||
|
for (int i = 0; i < columns*rows; ++i) { // all slots
|
||||||
|
const int dist = distance(pos, slotCenters[i]);
|
||||||
|
if (dist < slotCandidateDistance) { // window is interested in this slot
|
||||||
|
EffectWindow *occupier = takenSlots[i];
|
||||||
|
assert(occupier != w);
|
||||||
|
if (!occupier || dist < distance((otherPos = occupier->geometry().center()), slotCenters[i])) {
|
||||||
|
// either nobody lives here, or we're better - takeover the slot if it's our best
|
||||||
|
slotCandidate = i;
|
||||||
|
slotCandidateDistance = dist;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert(slotCandidate != -1);
|
||||||
|
if (takenSlots[slotCandidate])
|
||||||
|
tmpList << takenSlots[slotCandidate]; // occupier needs a new home now :p
|
||||||
|
tmpList.removeAll(w);
|
||||||
|
takenSlots[slotCandidate] = w; // ...and we rumble in =)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int slotWidth = area.width() / columns;
|
for (int slot = 0; slot < columns*rows; ++slot) {
|
||||||
int slotHeight = area.height() / rows;
|
EffectWindow *w = takenSlots[slot];
|
||||||
foreach (EffectWindow * w, windowlist) {
|
if (!w) // some slots might be empty
|
||||||
assert(m_windowData[w].slot != -1);
|
continue;
|
||||||
|
|
||||||
// Work out where the slot is
|
// Work out where the slot is
|
||||||
QRect target(
|
QRect target(
|
||||||
area.x() + (m_windowData[w].slot % columns) * slotWidth,
|
area.x() + (slot % columns) * slotWidth,
|
||||||
area.y() + (m_windowData[w].slot / columns) * slotHeight,
|
area.y() + (slot / columns) * slotHeight,
|
||||||
slotWidth, slotHeight);
|
slotWidth, slotHeight);
|
||||||
target.adjust(10, 10, -10, -10); // Borders
|
target.adjust(10, 10, -10, -10); // Borders
|
||||||
double scale;
|
double scale;
|
||||||
|
@ -1142,7 +1188,10 @@ void PresentWindowsEffect::calculateWindowTransformationsKompose(EffectWindowLis
|
||||||
EffectWindow* window = windowlist[pos];
|
EffectWindow* window = windowlist[pos];
|
||||||
QRect target = geometryRects[pos];
|
QRect target = geometryRects[pos];
|
||||||
target.setY(target.y() + topOffset);
|
target.setY(target.y() + topOffset);
|
||||||
m_windowData[window].slot = pos;
|
// @Marrtin: any idea what this is good for?
|
||||||
|
// DataHash::iterator winData = m_windowData.find(window);
|
||||||
|
// if (winData != m_windowData.end())
|
||||||
|
// winData->slot = pos;
|
||||||
motionManager.moveWindow(window, target);
|
motionManager.moveWindow(window, target);
|
||||||
|
|
||||||
//kDebug(1212) << "Window '" << window->caption() << "' gets moved to (" <<
|
//kDebug(1212) << "Window '" << window->caption() << "' gets moved to (" <<
|
||||||
|
@ -1161,8 +1210,8 @@ void PresentWindowsEffect::calculateWindowTransformationsNatural(EffectWindowLis
|
||||||
// just have a single window on a Xinerama screen or have two windows that do not touch.
|
// just have a single window on a Xinerama screen or have two windows that do not touch.
|
||||||
// TODO: Work out why this happens, is most likely a bug in the manager.
|
// TODO: Work out why this happens, is most likely a bug in the manager.
|
||||||
foreach (EffectWindow * w, windowlist)
|
foreach (EffectWindow * w, windowlist)
|
||||||
if (motionManager.transformedGeometry(w) == w->geometry())
|
if (motionManager.transformedGeometry(w) == w->geometry())
|
||||||
motionManager.reset(w);
|
motionManager.reset(w);
|
||||||
|
|
||||||
if (windowlist.count() == 1) {
|
if (windowlist.count() == 1) {
|
||||||
// Just move the window to its original location to save time
|
// Just move the window to its original location to save time
|
||||||
|
@ -1200,26 +1249,29 @@ void PresentWindowsEffect::calculateWindowTransformationsNatural(EffectWindowLis
|
||||||
do {
|
do {
|
||||||
overlap = false;
|
overlap = false;
|
||||||
foreach (EffectWindow * w, windowlist) {
|
foreach (EffectWindow * w, windowlist) {
|
||||||
|
QRect *target_w = &targets[w];
|
||||||
foreach (EffectWindow * e, windowlist) {
|
foreach (EffectWindow * e, windowlist) {
|
||||||
if (w != e && targets[w].adjusted(-5, -5, 5, 5).intersects(
|
if (w == e)
|
||||||
targets[e].adjusted(-5, -5, 5, 5))) {
|
continue;
|
||||||
|
QRect *target_e = &targets[e];
|
||||||
|
if (target_w->adjusted(-5, -5, 5, 5).intersects(target_e->adjusted(-5, -5, 5, 5))) {
|
||||||
overlap = true;
|
overlap = true;
|
||||||
|
|
||||||
// Determine pushing direction
|
// Determine pushing direction
|
||||||
QPoint diff(targets[e].center() - targets[w].center());
|
QPoint diff(target_e->center() - target_w->center());
|
||||||
// Prevent dividing by zero and non-movement
|
// Prevent dividing by zero and non-movement
|
||||||
if (diff.x() == 0 && diff.y() == 0)
|
if (diff.x() == 0 && diff.y() == 0)
|
||||||
diff.setX(1);
|
diff.setX(1);
|
||||||
// Try to keep screen aspect ratio
|
// Try to keep screen aspect ratio
|
||||||
//if ( bounds.height() / bounds.width() > area.height() / area.width() )
|
//if (bounds.height() / bounds.width() > area.height() / area.width())
|
||||||
// diff.setY( diff.y() / 2 );
|
// diff.setY(diff.y() / 2);
|
||||||
//else
|
//else
|
||||||
// diff.setX( diff.x() / 2 );
|
// diff.setX(diff.x() / 2);
|
||||||
// Approximate a vector of between 10px and 20px in magnitude in the same direction
|
// Approximate a vector of between 10px and 20px in magnitude in the same direction
|
||||||
diff *= m_accuracy / double(diff.manhattanLength());
|
diff *= m_accuracy / double(diff.manhattanLength());
|
||||||
// Move both windows apart
|
// Move both windows apart
|
||||||
targets[w].translate(-diff);
|
target_w->translate(-diff);
|
||||||
targets[e].translate(diff);
|
target_e->translate(diff);
|
||||||
|
|
||||||
// Try to keep the bounding rect the same aspect as the screen so that more
|
// Try to keep the bounding rect the same aspect as the screen so that more
|
||||||
// screen real estate is utilised. We do this by splitting the screen into nine
|
// screen real estate is utilised. We do this by splitting the screen into nine
|
||||||
|
@ -1231,8 +1283,8 @@ void PresentWindowsEffect::calculateWindowTransformationsNatural(EffectWindowLis
|
||||||
// in some situations. We need to do this even when expanding later just in case
|
// in some situations. We need to do this even when expanding later just in case
|
||||||
// all windows are the same size.
|
// all windows are the same size.
|
||||||
// (We are using an old bounding rect for this, hopefully it doesn't matter)
|
// (We are using an old bounding rect for this, hopefully it doesn't matter)
|
||||||
int xSection = (targets[w].x() - bounds.x()) / (bounds.width() / 3);
|
int xSection = (target_w->x() - bounds.x()) / (bounds.width() / 3);
|
||||||
int ySection = (targets[w].y() - bounds.y()) / (bounds.height() / 3);
|
int ySection = (target_w->y() - bounds.y()) / (bounds.height() / 3);
|
||||||
diff = QPoint(0, 0);
|
diff = QPoint(0, 0);
|
||||||
if (xSection != 1 || ySection != 1) { // Remove this if you want the center to pull as well
|
if (xSection != 1 || ySection != 1) { // Remove this if you want the center to pull as well
|
||||||
if (xSection == 1)
|
if (xSection == 1)
|
||||||
|
@ -1241,21 +1293,21 @@ void PresentWindowsEffect::calculateWindowTransformationsNatural(EffectWindowLis
|
||||||
ySection = (directions[w] % 2 ? 2 : 0);
|
ySection = (directions[w] % 2 ? 2 : 0);
|
||||||
}
|
}
|
||||||
if (xSection == 0 && ySection == 0)
|
if (xSection == 0 && ySection == 0)
|
||||||
diff = QPoint(bounds.topLeft() - targets[w].center());
|
diff = QPoint(bounds.topLeft() - target_w->center());
|
||||||
if (xSection == 2 && ySection == 0)
|
if (xSection == 2 && ySection == 0)
|
||||||
diff = QPoint(bounds.topRight() - targets[w].center());
|
diff = QPoint(bounds.topRight() - target_w->center());
|
||||||
if (xSection == 2 && ySection == 2)
|
if (xSection == 2 && ySection == 2)
|
||||||
diff = QPoint(bounds.bottomRight() - targets[w].center());
|
diff = QPoint(bounds.bottomRight() - target_w->center());
|
||||||
if (xSection == 0 && ySection == 2)
|
if (xSection == 0 && ySection == 2)
|
||||||
diff = QPoint(bounds.bottomLeft() - targets[w].center());
|
diff = QPoint(bounds.bottomLeft() - target_w->center());
|
||||||
if (diff.x() != 0 || diff.y() != 0) {
|
if (diff.x() != 0 || diff.y() != 0) {
|
||||||
diff *= m_accuracy / double(diff.manhattanLength());
|
diff *= m_accuracy / double(diff.manhattanLength());
|
||||||
targets[w].translate(diff);
|
target_w->translate(diff);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update bounding rect
|
// Update bounding rect
|
||||||
bounds = bounds.united(targets[w]);
|
bounds = bounds.united(*target_w);
|
||||||
bounds = bounds.united(targets[e]);
|
bounds = bounds.united(*target_e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1279,13 +1331,15 @@ void PresentWindowsEffect::calculateWindowTransformationsNatural(EffectWindowLis
|
||||||
);
|
);
|
||||||
|
|
||||||
// Move all windows back onto the screen and set their scale
|
// Move all windows back onto the screen and set their scale
|
||||||
foreach (EffectWindow * w, windowlist)
|
QHash<EffectWindow*, QRect>::iterator target = targets.begin();
|
||||||
targets[w] = QRect(
|
while (target != targets.end()) {
|
||||||
(targets[w].x() - bounds.x()) * scale + area.x(),
|
target->setRect((target->x() - bounds.x()) * scale + area.x(),
|
||||||
(targets[w].y() - bounds.y()) * scale + area.y(),
|
(target->y() - bounds.y()) * scale + area.y(),
|
||||||
targets[w].width() * scale,
|
target->width() * scale,
|
||||||
targets[w].height() * scale
|
target->height() * scale
|
||||||
);
|
);
|
||||||
|
++target;
|
||||||
|
}
|
||||||
|
|
||||||
// Try to fill the gaps by enlarging windows if they have the space
|
// Try to fill the gaps by enlarging windows if they have the space
|
||||||
if (m_fillGaps) {
|
if (m_fillGaps) {
|
||||||
|
@ -1298,61 +1352,61 @@ void PresentWindowsEffect::calculateWindowTransformationsNatural(EffectWindowLis
|
||||||
moved = false;
|
moved = false;
|
||||||
foreach (EffectWindow * w, windowlist) {
|
foreach (EffectWindow * w, windowlist) {
|
||||||
QRect oldRect;
|
QRect oldRect;
|
||||||
|
QRect *target = &targets[w];
|
||||||
// This may cause some slight distortion if the windows are enlarged a large amount
|
// This may cause some slight distortion if the windows are enlarged a large amount
|
||||||
int widthDiff = m_accuracy;
|
int widthDiff = m_accuracy;
|
||||||
int heightDiff = heightForWidth(w, targets[w].width() + widthDiff) - targets[w].height();
|
int heightDiff = heightForWidth(w, target->width() + widthDiff) - target->height();
|
||||||
int xDiff = widthDiff / 2; // Also move a bit in the direction of the enlarge, allows the
|
int xDiff = widthDiff / 2; // Also move a bit in the direction of the enlarge, allows the
|
||||||
int yDiff = heightDiff / 2; // center windows to be enlarged if there is gaps on the side.
|
int yDiff = heightDiff / 2; // center windows to be enlarged if there is gaps on the side.
|
||||||
|
|
||||||
// Attempt enlarging to the top-right
|
// Attempt enlarging to the top-right
|
||||||
oldRect = targets[w];
|
oldRect = *target;
|
||||||
targets[w] = QRect(
|
target->setRect(target->x() + xDiff,
|
||||||
targets[w].x() + xDiff,
|
target->y() - yDiff - heightDiff,
|
||||||
targets[w].y() - yDiff - heightDiff,
|
target->width() + widthDiff,
|
||||||
targets[w].width() + widthDiff,
|
target->height() + heightDiff
|
||||||
targets[w].height() + heightDiff
|
);
|
||||||
);
|
|
||||||
if (isOverlappingAny(w, targets, borderRegion))
|
if (isOverlappingAny(w, targets, borderRegion))
|
||||||
targets[w] = oldRect;
|
*target = oldRect;
|
||||||
else
|
else
|
||||||
moved = true;
|
moved = true;
|
||||||
|
|
||||||
// Attempt enlarging to the bottom-right
|
// Attempt enlarging to the bottom-right
|
||||||
oldRect = targets[w];
|
oldRect = *target;
|
||||||
targets[w] = QRect(
|
target->setRect(
|
||||||
targets[w].x() + xDiff,
|
target->x() + xDiff,
|
||||||
targets[w].y() + yDiff,
|
target->y() + yDiff,
|
||||||
targets[w].width() + widthDiff,
|
target->width() + widthDiff,
|
||||||
targets[w].height() + heightDiff
|
target->height() + heightDiff
|
||||||
);
|
);
|
||||||
if (isOverlappingAny(w, targets, borderRegion))
|
if (isOverlappingAny(w, targets, borderRegion))
|
||||||
targets[w] = oldRect;
|
*target = oldRect;
|
||||||
else
|
else
|
||||||
moved = true;
|
moved = true;
|
||||||
|
|
||||||
// Attempt enlarging to the bottom-left
|
// Attempt enlarging to the bottom-left
|
||||||
oldRect = targets[w];
|
oldRect = *target;
|
||||||
targets[w] = QRect(
|
target->setRect(
|
||||||
targets[w].x() - xDiff - widthDiff,
|
target->x() - xDiff - widthDiff,
|
||||||
targets[w].y() + yDiff,
|
target->y() + yDiff,
|
||||||
targets[w].width() + widthDiff,
|
target->width() + widthDiff,
|
||||||
targets[w].height() + heightDiff
|
target->height() + heightDiff
|
||||||
);
|
);
|
||||||
if (isOverlappingAny(w, targets, borderRegion))
|
if (isOverlappingAny(w, targets, borderRegion))
|
||||||
targets[w] = oldRect;
|
*target = oldRect;
|
||||||
else
|
else
|
||||||
moved = true;
|
moved = true;
|
||||||
|
|
||||||
// Attempt enlarging to the top-left
|
// Attempt enlarging to the top-left
|
||||||
oldRect = targets[w];
|
oldRect = *target;
|
||||||
targets[w] = QRect(
|
target->setRect(
|
||||||
targets[w].x() - xDiff - widthDiff,
|
target->x() - xDiff - widthDiff,
|
||||||
targets[w].y() - yDiff - heightDiff,
|
target->y() - yDiff - heightDiff,
|
||||||
targets[w].width() + widthDiff,
|
target->width() + widthDiff,
|
||||||
targets[w].height() + heightDiff
|
target->height() + heightDiff
|
||||||
);
|
);
|
||||||
if (isOverlappingAny(w, targets, borderRegion))
|
if (isOverlappingAny(w, targets, borderRegion))
|
||||||
targets[w] = oldRect;
|
*target = oldRect;
|
||||||
else
|
else
|
||||||
moved = true;
|
moved = true;
|
||||||
}
|
}
|
||||||
|
@ -1362,12 +1416,13 @@ void PresentWindowsEffect::calculateWindowTransformationsNatural(EffectWindowLis
|
||||||
// We can't add this to the loop above as it would cause a never-ending loop so we have to make
|
// We can't add this to the loop above as it would cause a never-ending loop so we have to make
|
||||||
// do with the less-than-optimal space usage with using this method.
|
// do with the less-than-optimal space usage with using this method.
|
||||||
foreach (EffectWindow * w, windowlist) {
|
foreach (EffectWindow * w, windowlist) {
|
||||||
double scale = targets[w].width() / double(w->width());
|
QRect *target = &targets[w];
|
||||||
|
double scale = target->width() / double(w->width());
|
||||||
if (scale > 2.0 || (scale > 1.0 && (w->width() > 300 || w->height() > 300))) {
|
if (scale > 2.0 || (scale > 1.0 && (w->width() > 300 || w->height() > 300))) {
|
||||||
scale = (w->width() > 300 || w->height() > 300) ? 1.0 : 2.0;
|
scale = (w->width() > 300 || w->height() > 300) ? 1.0 : 2.0;
|
||||||
targets[w] = QRect(
|
target->setRect(
|
||||||
targets[w].center().x() - int(w->width() * scale) / 2,
|
target->center().x() - int(w->width() * scale) / 2,
|
||||||
targets[w].center().y() - int(w->height() * scale) / 2,
|
target->center().y() - int(w->height() * scale) / 2,
|
||||||
w->width() * scale,
|
w->width() * scale,
|
||||||
w->height() * scale);
|
w->height() * scale);
|
||||||
}
|
}
|
||||||
|
@ -1376,76 +1431,23 @@ void PresentWindowsEffect::calculateWindowTransformationsNatural(EffectWindowLis
|
||||||
|
|
||||||
// Notify the motion manager of the targets
|
// Notify the motion manager of the targets
|
||||||
foreach (EffectWindow * w, windowlist)
|
foreach (EffectWindow * w, windowlist)
|
||||||
motionManager.moveWindow(w, targets[w]);
|
motionManager.moveWindow(w, targets.value(w));
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
// Helper functions for window rearranging
|
|
||||||
|
|
||||||
void PresentWindowsEffect::assignSlots(EffectWindowList windowlist, const QRect &area, int columns, int rows)
|
|
||||||
{
|
|
||||||
QVector< bool > taken;
|
|
||||||
taken.fill(false, columns * rows);
|
|
||||||
foreach (EffectWindow * w, windowlist)
|
|
||||||
if (m_windowData[w].slot != -1)
|
|
||||||
taken[ m_windowData[w].slot ] = true;
|
|
||||||
int slotWidth = area.width() / columns;
|
|
||||||
int slotHeight = area.height() / rows;
|
|
||||||
foreach (EffectWindow * w, windowlist) {
|
|
||||||
WindowData *wData = &m_windowData[w];
|
|
||||||
if (wData->slot != -1)
|
|
||||||
continue; // it already has a slot
|
|
||||||
QPoint pos = w->geometry().center();
|
|
||||||
if (pos.x() < area.left())
|
|
||||||
pos.setX(area.left());
|
|
||||||
if (pos.x() > area.right())
|
|
||||||
pos.setX(area.right());
|
|
||||||
if (pos.y() < area.top())
|
|
||||||
pos.setY(area.top());
|
|
||||||
if (pos.y() > area.bottom())
|
|
||||||
pos.setY(area.bottom());
|
|
||||||
int distance = INT_MAX;
|
|
||||||
for (int x = 0; x < columns; x++)
|
|
||||||
for (int y = 0; y < rows; y++) {
|
|
||||||
int slot = x + y * columns;
|
|
||||||
if (taken[slot])
|
|
||||||
continue;
|
|
||||||
int xdiff = pos.x() - (area.x() + slotWidth * x + slotWidth / 2);
|
|
||||||
int ydiff = pos.y() - (area.y() + slotHeight * y + slotHeight / 2);
|
|
||||||
int dist = int(sqrt(double(xdiff * xdiff + ydiff * ydiff)));
|
|
||||||
if (dist < distance) {
|
|
||||||
distance = dist;
|
|
||||||
wData->slot = slot;
|
|
||||||
wData->slot_distance = distance;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void PresentWindowsEffect::getBestAssignments(EffectWindowList windowlist)
|
|
||||||
{
|
|
||||||
foreach (EffectWindow * w1, windowlist) {
|
|
||||||
WindowData *windowData1 = &m_windowData[w1];
|
|
||||||
foreach (EffectWindow * w2, windowlist) {
|
|
||||||
WindowData *windowData2 = &m_windowData[w2];
|
|
||||||
if (w1 != w2 && windowData1->slot == windowData2->slot &&
|
|
||||||
windowData1->slot_distance >= windowData2->slot_distance)
|
|
||||||
windowData1->slot = -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool PresentWindowsEffect::isOverlappingAny(EffectWindow *w, const QHash<EffectWindow*, QRect> &targets, const QRegion &border)
|
bool PresentWindowsEffect::isOverlappingAny(EffectWindow *w, const QHash<EffectWindow*, QRect> &targets, const QRegion &border)
|
||||||
{
|
{
|
||||||
if (border.intersects(targets[w]))
|
QHash<EffectWindow*, QRect>::const_iterator winTarget = targets.find(w);
|
||||||
|
if (winTarget == targets.constEnd())
|
||||||
|
return false;
|
||||||
|
if (border.intersects(*winTarget))
|
||||||
return true;
|
return true;
|
||||||
// Is there a better way to do this?
|
// Is there a better way to do this?
|
||||||
QHash<EffectWindow*, QRect>::const_iterator i;
|
QHash<EffectWindow*, QRect>::const_iterator target;
|
||||||
for (i = targets.constBegin(); i != targets.constEnd(); ++i) {
|
for (target = targets.constBegin(); target != targets.constEnd(); ++target) {
|
||||||
if (w == i.key())
|
if (target == winTarget)
|
||||||
continue;
|
continue;
|
||||||
if (targets[w].adjusted(-5, -5, 5, 5).intersects(
|
if (winTarget->adjusted(-5, -5, 5, 5).intersects(target->adjusted(-5, -5, 5, 5)))
|
||||||
i.value().adjusted(-5, -5, 5, 5)))
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -1475,37 +1477,44 @@ void PresentWindowsEffect::setActive(bool active, bool closingTab)
|
||||||
|
|
||||||
// Add every single window to m_windowData (Just calling [w] creates it)
|
// Add every single window to m_windowData (Just calling [w] creates it)
|
||||||
foreach (EffectWindow * w, effects->stackingOrder()) {
|
foreach (EffectWindow * w, effects->stackingOrder()) {
|
||||||
if (m_windowData.contains(w)) // Happens if we reactivate before the ending animation finishes
|
DataHash::iterator winData;
|
||||||
continue;
|
if ((winData = m_windowData.find(w)) != m_windowData.end()) {
|
||||||
m_windowData[w].visible = isVisibleWindow(w);
|
winData->visible = isVisibleWindow(w);
|
||||||
m_windowData[w].deleted = false;
|
continue; // Happens if we reactivate before the ending animation finishes
|
||||||
m_windowData[w].referenced = false;
|
}
|
||||||
m_windowData[w].opacity = 0.0;
|
winData = m_windowData.insert(w, WindowData());
|
||||||
|
winData->visible = isVisibleWindow(w);
|
||||||
|
winData->deleted = false;
|
||||||
|
winData->referenced = false;
|
||||||
|
winData->opacity = 0.0;
|
||||||
if (w->isOnCurrentDesktop() && !w->isMinimized())
|
if (w->isOnCurrentDesktop() && !w->isMinimized())
|
||||||
m_windowData[w].opacity = 1.0;
|
winData->opacity = 1.0;
|
||||||
m_windowData[w].highlight = 1.0;
|
winData->highlight = 1.0;
|
||||||
m_windowData[w].textFrame = effects->effectFrame(EffectFrameUnstyled, false);
|
winData->textFrame = effects->effectFrame(EffectFrameUnstyled, false);
|
||||||
QFont font;
|
QFont font;
|
||||||
font.setBold(true);
|
font.setBold(true);
|
||||||
font.setPointSize(12);
|
font.setPointSize(12);
|
||||||
m_windowData[w].textFrame->setFont(font);
|
winData->textFrame->setFont(font);
|
||||||
m_windowData[w].iconFrame = effects->effectFrame(EffectFrameUnstyled, false);
|
winData->iconFrame = effects->effectFrame(EffectFrameUnstyled, false);
|
||||||
m_windowData[w].iconFrame->setAlignment(Qt::AlignRight | Qt::AlignBottom);
|
winData->iconFrame->setAlignment(Qt::AlignRight | Qt::AlignBottom);
|
||||||
m_windowData[w].iconFrame->setIcon(w->icon());
|
winData->iconFrame->setIcon(w->icon());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_tabBoxEnabled) {
|
if (m_tabBoxEnabled) {
|
||||||
|
DataHash::iterator winData;
|
||||||
foreach (EffectWindow * w, effects->currentTabBoxWindowList()) {
|
foreach (EffectWindow * w, effects->currentTabBoxWindowList()) {
|
||||||
if (!w)
|
if (!w)
|
||||||
continue;
|
continue;
|
||||||
m_motionManager.manage(w);
|
m_motionManager.manage(w);
|
||||||
assert(m_windowData.contains(w));
|
if ((winData = m_windowData.find(w)) != m_windowData.end())
|
||||||
m_windowData[w].visible = effects->currentTabBoxWindowList().contains(w);
|
winData->visible = effects->currentTabBoxWindowList().contains(w);
|
||||||
}
|
}
|
||||||
// Hide windows not in the list
|
// Hide windows not in the list
|
||||||
foreach (EffectWindow * w, effects->stackingOrder())
|
foreach (EffectWindow * w, effects->stackingOrder()) {
|
||||||
m_windowData[w].visible = isVisibleWindow(w) &&
|
if ((winData = m_windowData.find(w)) != m_windowData.end())
|
||||||
(!isSelectableWindow(w) || effects->currentTabBoxWindowList().contains(w));
|
winData->visible = isVisibleWindow(w) &&
|
||||||
|
(!isSelectableWindow(w) || effects->currentTabBoxWindowList().contains(w));
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// Filter out special windows such as panels and taskbars
|
// Filter out special windows such as panels and taskbars
|
||||||
foreach (EffectWindow * w, effects->stackingOrder())
|
foreach (EffectWindow * w, effects->stackingOrder())
|
||||||
|
@ -1522,7 +1531,7 @@ void PresentWindowsEffect::setActive(bool active, bool closingTab)
|
||||||
while (i != m_windowData.end()) {
|
while (i != m_windowData.end()) {
|
||||||
delete i.value().textFrame;
|
delete i.value().textFrame;
|
||||||
delete i.value().iconFrame;
|
delete i.value().iconFrame;
|
||||||
i++;
|
++i;
|
||||||
}
|
}
|
||||||
m_windowData.clear();
|
m_windowData.clear();
|
||||||
|
|
||||||
|
@ -1536,7 +1545,7 @@ void PresentWindowsEffect::setActive(bool active, bool closingTab)
|
||||||
effects->setActiveFullScreenEffect(this);
|
effects->setActiveFullScreenEffect(this);
|
||||||
|
|
||||||
m_gridSizes.clear();
|
m_gridSizes.clear();
|
||||||
for (int i = 0; i < effects->numScreens(); i++)
|
for (int i = 0; i < effects->numScreens(); ++i)
|
||||||
m_gridSizes.append(GridSize());
|
m_gridSizes.append(GridSize());
|
||||||
|
|
||||||
rearrangeWindows();
|
rearrangeWindows();
|
||||||
|
@ -1559,9 +1568,10 @@ void PresentWindowsEffect::setActive(bool active, bool closingTab)
|
||||||
if (activeWindow && !activeWindow->isOnAllDesktops())
|
if (activeWindow && !activeWindow->isOnAllDesktops())
|
||||||
desktop = activeWindow->desktop();
|
desktop = activeWindow->desktop();
|
||||||
foreach (EffectWindow * w, effects->stackingOrder()) {
|
foreach (EffectWindow * w, effects->stackingOrder()) {
|
||||||
assert(m_windowData.contains(w));
|
DataHash::iterator winData = m_windowData.find(w);
|
||||||
m_windowData[w].visible = (w->isOnDesktop(desktop) || w->isOnAllDesktops()) &&
|
if (winData != m_windowData.end())
|
||||||
!w->isMinimized() && (w->visibleInClientGroup() || m_windowData[w].visible);
|
winData->visible = (w->isOnDesktop(desktop) || w->isOnAllDesktops()) &&
|
||||||
|
!w->isMinimized() && (w->visibleInClientGroup() || winData->visible);
|
||||||
}
|
}
|
||||||
delete m_closeView;
|
delete m_closeView;
|
||||||
m_closeView = 0;
|
m_closeView = 0;
|
||||||
|
@ -1701,7 +1711,8 @@ EffectWindow* PresentWindowsEffect::relativeWindow(EffectWindow *w, int xdiff, i
|
||||||
detectRect = QRect(0, wArea.y(), area.width(), wArea.height());
|
detectRect = QRect(0, wArea.y(), area.width(), wArea.height());
|
||||||
next = NULL;
|
next = NULL;
|
||||||
foreach (EffectWindow * e, m_motionManager.managedWindows()) {
|
foreach (EffectWindow * e, m_motionManager.managedWindows()) {
|
||||||
if (!m_windowData[e].visible)
|
DataHash::const_iterator winData = m_windowData.find(e);
|
||||||
|
if (winData == m_windowData.end() || !winData->visible)
|
||||||
continue;
|
continue;
|
||||||
QRectF eArea = m_motionManager.transformedGeometry(e);
|
QRectF eArea = m_motionManager.transformedGeometry(e);
|
||||||
if (eArea.intersects(detectRect) &&
|
if (eArea.intersects(detectRect) &&
|
||||||
|
@ -1730,7 +1741,8 @@ EffectWindow* PresentWindowsEffect::relativeWindow(EffectWindow *w, int xdiff, i
|
||||||
detectRect = QRect(0, wArea.y(), area.width(), wArea.height());
|
detectRect = QRect(0, wArea.y(), area.width(), wArea.height());
|
||||||
next = NULL;
|
next = NULL;
|
||||||
foreach (EffectWindow * e, m_motionManager.managedWindows()) {
|
foreach (EffectWindow * e, m_motionManager.managedWindows()) {
|
||||||
if (!m_windowData[e].visible)
|
DataHash::const_iterator winData = m_windowData.find(e);
|
||||||
|
if (winData == m_windowData.end() || !winData->visible)
|
||||||
continue;
|
continue;
|
||||||
QRectF eArea = m_motionManager.transformedGeometry(e);
|
QRectF eArea = m_motionManager.transformedGeometry(e);
|
||||||
if (eArea.intersects(detectRect) &&
|
if (eArea.intersects(detectRect) &&
|
||||||
|
@ -1764,7 +1776,8 @@ EffectWindow* PresentWindowsEffect::relativeWindow(EffectWindow *w, int xdiff, i
|
||||||
detectRect = QRect(wArea.x(), 0, wArea.width(), area.height());
|
detectRect = QRect(wArea.x(), 0, wArea.width(), area.height());
|
||||||
next = NULL;
|
next = NULL;
|
||||||
foreach (EffectWindow * e, m_motionManager.managedWindows()) {
|
foreach (EffectWindow * e, m_motionManager.managedWindows()) {
|
||||||
if (!m_windowData[e].visible)
|
DataHash::const_iterator winData = m_windowData.find(e);
|
||||||
|
if (winData == m_windowData.end() || !winData->visible)
|
||||||
continue;
|
continue;
|
||||||
QRectF eArea = m_motionManager.transformedGeometry(e);
|
QRectF eArea = m_motionManager.transformedGeometry(e);
|
||||||
if (eArea.intersects(detectRect) &&
|
if (eArea.intersects(detectRect) &&
|
||||||
|
@ -1793,7 +1806,8 @@ EffectWindow* PresentWindowsEffect::relativeWindow(EffectWindow *w, int xdiff, i
|
||||||
detectRect = QRect(wArea.x(), 0, wArea.width(), area.height());
|
detectRect = QRect(wArea.x(), 0, wArea.width(), area.height());
|
||||||
next = NULL;
|
next = NULL;
|
||||||
foreach (EffectWindow * e, m_motionManager.managedWindows()) {
|
foreach (EffectWindow * e, m_motionManager.managedWindows()) {
|
||||||
if (!m_windowData[e].visible)
|
DataHash::const_iterator winData = m_windowData.find(e);
|
||||||
|
if (winData == m_windowData.end() || !winData->visible)
|
||||||
continue;
|
continue;
|
||||||
QRectF eArea = m_motionManager.transformedGeometry(e);
|
QRectF eArea = m_motionManager.transformedGeometry(e);
|
||||||
if (eArea.intersects(detectRect) &&
|
if (eArea.intersects(detectRect) &&
|
||||||
|
@ -1826,10 +1840,13 @@ EffectWindow* PresentWindowsEffect::findFirstWindow() const
|
||||||
EffectWindow *topLeft = NULL;
|
EffectWindow *topLeft = NULL;
|
||||||
QRectF topLeftGeometry;
|
QRectF topLeftGeometry;
|
||||||
foreach (EffectWindow * w, m_motionManager.managedWindows()) {
|
foreach (EffectWindow * w, m_motionManager.managedWindows()) {
|
||||||
|
DataHash::const_iterator winData = m_windowData.find(w);
|
||||||
|
if (winData == m_windowData.end())
|
||||||
|
continue;
|
||||||
QRectF geometry = m_motionManager.transformedGeometry(w);
|
QRectF geometry = m_motionManager.transformedGeometry(w);
|
||||||
if (m_windowData[w].visible == false)
|
if (winData->visible == false)
|
||||||
continue; // Not visible
|
continue; // Not visible
|
||||||
if (m_windowData[w].deleted)
|
if (winData->deleted)
|
||||||
continue; // Window has been closed
|
continue; // Window has been closed
|
||||||
if (topLeft == NULL) {
|
if (topLeft == NULL) {
|
||||||
topLeft = w;
|
topLeft = w;
|
||||||
|
|
|
@ -74,8 +74,6 @@ private:
|
||||||
bool referenced;
|
bool referenced;
|
||||||
double opacity;
|
double opacity;
|
||||||
double highlight;
|
double highlight;
|
||||||
int slot;
|
|
||||||
int slot_distance;
|
|
||||||
EffectFrame* textFrame;
|
EffectFrame* textFrame;
|
||||||
EffectFrame* iconFrame;
|
EffectFrame* iconFrame;
|
||||||
};
|
};
|
||||||
|
@ -185,8 +183,6 @@ protected:
|
||||||
inline int heightForWidth(EffectWindow *w, int width) {
|
inline int heightForWidth(EffectWindow *w, int width) {
|
||||||
return int((width / double(w->width())) * w->height());
|
return int((width / double(w->width())) * w->height());
|
||||||
}
|
}
|
||||||
void assignSlots(EffectWindowList windowlist, const QRect &area, int columns, int rows);
|
|
||||||
void getBestAssignments(EffectWindowList windowlist);
|
|
||||||
bool isOverlappingAny(EffectWindow *w, const QHash<EffectWindow*, QRect> &targets, const QRegion &border);
|
bool isOverlappingAny(EffectWindow *w, const QHash<EffectWindow*, QRect> &targets, const QRegion &border);
|
||||||
|
|
||||||
// Filter box
|
// Filter box
|
||||||
|
|
Loading…
Reference in a new issue