Store AbstractOutput in Toplevel

Since AbstractOutput is used more than int screen ids in kwin, it's
worth storing AbstractOutput for better performance.
This commit is contained in:
Vlad Zahorodnii 2021-08-28 18:34:58 +03:00 committed by Aleix Pol Gonzalez
parent 6ca411a84a
commit a1f1039b58
5 changed files with 42 additions and 39 deletions

View file

@ -61,8 +61,8 @@ AbstractClient::AbstractClient()
{
connect(this, &AbstractClient::clientStartUserMovedResized, this, &AbstractClient::moveResizedChanged);
connect(this, &AbstractClient::clientFinishUserMovedResized, this, &AbstractClient::moveResizedChanged);
connect(this, &AbstractClient::clientStartUserMovedResized, this, &AbstractClient::removeCheckScreenConnection);
connect(this, &AbstractClient::clientFinishUserMovedResized, this, &AbstractClient::setupCheckScreenConnection);
connect(this, &AbstractClient::clientStartUserMovedResized, this, &AbstractClient::removeCheckOutputConnection);
connect(this, &AbstractClient::clientFinishUserMovedResized, this, &AbstractClient::setupCheckOutputConnection);
connect(this, &AbstractClient::paletteChanged, this, &AbstractClient::triggerDecorationRepaint);
@ -981,7 +981,7 @@ void AbstractClient::finishInteractiveMoveResize(bool cancel)
}
moveResize(moveResizeGeom);
}
checkScreen(); // needs to be done because clientFinishUserMovedResized has not yet re-activated online alignment
checkOutput(); // needs to be done because clientFinishUserMovedResized has not yet re-activated online alignment
if (output() != interactiveMoveResizeStartOutput()) {
if (isFullScreen() || isElectricBorderMaximizing()) {
updateGeometryRestoresForFullscreen(output());

View file

@ -44,12 +44,10 @@ Toplevel::Toplevel()
, effect_window(nullptr)
, m_clientMachine(new ClientMachine(this))
, m_wmClientLeader(XCB_WINDOW_NONE)
, m_screen(0)
, m_skipCloseAnimation(false)
{
connect(screens(), &Screens::changed, this, &Toplevel::checkScreen);
connect(screens(), &Screens::countChanged, this, &Toplevel::checkScreen);
setupCheckScreenConnection();
connect(screens(), &Screens::changed, this, &Toplevel::screenChanged);
setupCheckOutputConnection();
connect(this, &Toplevel::bufferGeometryChanged, this, &Toplevel::inputTransformationChanged);
// Only for compatibility reasons, drop in the next major release.
@ -126,7 +124,7 @@ void Toplevel::copyToDeleted(Toplevel* c)
m_clientMachine->setParent(this);
m_wmClientLeader = c->wmClientLeader();
opaque_region = c->opaqueRegion();
m_screen = c->m_screen;
m_output = c->m_output;
m_skipCloseAnimation = c->m_skipCloseAnimation;
m_internalFBO = c->m_internalFBO;
m_internalImage = c->m_internalImage;
@ -367,46 +365,44 @@ void Toplevel::deleteEffectWindow()
effect_window = nullptr;
}
void Toplevel::checkScreen()
void Toplevel::checkOutput()
{
if (screens()->count() == 1) {
if (m_screen != 0) {
m_screen = 0;
Q_EMIT screenChanged();
}
} else {
const int s = screens()->number(frameGeometry().center());
if (s != m_screen) {
m_screen = s;
Q_EMIT screenChanged();
}
}
qreal newScale = screens()->scale(m_screen);
if (newScale != m_screenScale) {
m_screenScale = newScale;
Q_EMIT screenScaleChanged();
}
setOutput(kwinApp()->platform()->outputAt(frameGeometry().center()));
}
void Toplevel::setupCheckScreenConnection()
void Toplevel::setupCheckOutputConnection()
{
connect(this, &Toplevel::frameGeometryChanged, this, &Toplevel::checkScreen);
checkScreen();
connect(this, &Toplevel::frameGeometryChanged, this, &Toplevel::checkOutput);
checkOutput();
}
void Toplevel::removeCheckScreenConnection()
void Toplevel::removeCheckOutputConnection()
{
disconnect(this, &Toplevel::frameGeometryChanged, this, &Toplevel::checkScreen);
disconnect(this, &Toplevel::frameGeometryChanged, this, &Toplevel::checkOutput);
}
int Toplevel::screen() const
{
return m_screen;
return kwinApp()->platform()->enabledOutputs().indexOf(m_output);
}
AbstractOutput *Toplevel::output() const
{
return kwinApp()->platform()->findOutput(screen());
return m_output;
}
void Toplevel::setOutput(AbstractOutput *output)
{
if (m_output != output) {
m_output = output;
Q_EMIT screenChanged();
}
qreal newScale = m_output->scale();
if (newScale != m_screenScale) {
m_screenScale = newScale;
Q_EMIT screenScaleChanged();
}
}
qreal Toplevel::screenScale() const

View file

@ -346,6 +346,7 @@ public:
bool isOnActiveOutput() const;
int screen() const; // the screen where the center is
AbstractOutput *output() const;
void setOutput(AbstractOutput *output);
/**
* The scale of the screen this window is currently on
* @note The buffer scale can be different.
@ -662,9 +663,9 @@ protected Q_SLOTS:
* Checks whether the screen number for this Toplevel changed and updates if needed.
* Any method changing the geometry of the Toplevel should call this method.
*/
void checkScreen();
void setupCheckScreenConnection();
void removeCheckScreenConnection();
void checkOutput();
void setupCheckOutputConnection();
void removeCheckOutputConnection();
void setReadyForPainting();
protected:
@ -720,7 +721,7 @@ private:
QRegion opaque_region;
mutable QRegion m_shapeRegion;
mutable bool m_shapeRegionIsValid = false;
int m_screen;
AbstractOutput *m_output = nullptr;
bool m_skipCloseAnimation;
quint32 m_surfaceId = 0;
KWaylandServer::SurfaceInterface *m_surface = nullptr;

View file

@ -102,7 +102,7 @@ bool Unmanaged::track(xcb_window_t w)
m_bufferGeometry = geo.rect();
m_frameGeometry = geo.rect();
m_clientGeometry = geo.rect();
checkScreen();
checkOutput();
m_visual = attr->visual;
bit_depth = geo->depth;
info = new NETWinInfo(connection(), w, rootWindow(),

View file

@ -1213,7 +1213,13 @@ void Workspace::slotOutputEnabled(AbstractOutput *output)
void Workspace::slotOutputDisabled(AbstractOutput *output)
{
// TODO: Send clients on the given output to other outputs.
const auto stack = xStackingOrder();
for (Toplevel *toplevel : stack) {
if (toplevel->output() == output) {
toplevel->setOutput(kwinApp()->platform()->outputAt(toplevel->frameGeometry().center()));
}
}
disconnect(output, &AbstractOutput::geometryChanged, this, &Workspace::desktopResized);
desktopResized();
}