Introduce a proper screen property in Toplevel

Instead of calculating the screen number each time screen() is invoked,
the screen number gets stored in a private member variable and evaluated
whenever either the screen count changes or the Toplevel's geometry
changes. During move/resize the screen property doesn't get updated. The
update is delayed till the end of the move/resize operation.

REVIEW: 109715
icc-effect-5.14.5
Martin Gräßlin 2013-03-26 07:45:08 +01:00
parent 556d71933b
commit 6d6b013720
5 changed files with 58 additions and 7 deletions

View File

@ -219,6 +219,8 @@ Client::Client(Workspace* ws)
connect(this, SIGNAL(clientStepUserMovedResized(KWin::Client*,QRect)), SIGNAL(geometryChanged()));
connect(this, SIGNAL(clientStartUserMovedResized(KWin::Client*)), SIGNAL(moveResizedChanged()));
connect(this, SIGNAL(clientFinishUserMovedResized(KWin::Client*)), SIGNAL(moveResizedChanged()));
connect(this, SIGNAL(clientStartUserMovedResized(KWin::Client*)), SLOT(removeCheckScreenConnection()));
connect(this, SIGNAL(clientFinishUserMovedResized(KWin::Client*)), SLOT(setupCheckScreenConnection()));
connect(clientMachine(), SIGNAL(localhostChanged()), SLOT(updateCaption()));
connect(options, SIGNAL(condensedTitleChanged()), SLOT(updateCaption()));

View File

@ -2064,6 +2064,7 @@ void Client::move(int x, int y, ForceGeometry_t force)
// Update states of all other windows in this group
if (tabGroup())
tabGroup()->updateStates(this, TabGroup::Geometry);
emit geometryChanged();
}
void Client::blockGeometryUpdates(bool block)

View File

@ -29,6 +29,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "shadow.h"
#include "xcbutils.h"
#include <QDesktopWidget>
namespace KWin
{
@ -49,8 +51,12 @@ Toplevel::Toplevel(Workspace* ws)
, unredirect(false)
, unredirectSuspend(false)
, m_damageReplyPending(false)
, m_screen(0)
{
connect(this, SIGNAL(damaged(KWin::Toplevel*,QRect)), SIGNAL(needsRepaint()));
connect(QApplication::desktop(), SIGNAL(screenCountChanged(int)), SLOT(checkScreen()));
connect(QApplication::desktop(), SIGNAL(resized(int)), SLOT(checkScreen()));
setupCheckScreenConnection();
}
Toplevel::~Toplevel()
@ -140,6 +146,7 @@ void Toplevel::copyToDeleted(Toplevel* c)
wmClientLeaderWin = c->wmClientLeader();
window_role = c->windowRole();
opaque_region = c->opaqueRegion();
m_screen = c->m_screen;
// this needs to be done already here, otherwise 'c' could very likely
// call discardWindowPixmap() in something called during cleanup
c->window_pix = None;
@ -324,14 +331,38 @@ void Toplevel::deleteEffectWindow()
effect_window = NULL;
}
void Toplevel::checkScreen()
{
if (Workspace::self()->numScreens() == 1) {
if (m_screen != 0) {
m_screen = 0;
emit screenChanged();
}
return;
}
const int s = Workspace::self()->screenNumber(geometry().center());
if (s != m_screen) {
m_screen = s;
emit screenChanged();
}
}
void Toplevel::setupCheckScreenConnection()
{
connect(this, SIGNAL(geometryShapeChanged(KWin::Toplevel*,QRect)), SLOT(checkScreen()));
connect(this, SIGNAL(geometryChanged()), SLOT(checkScreen()));
checkScreen();
}
void Toplevel::removeCheckScreenConnection()
{
disconnect(this, SIGNAL(geometryShapeChanged(KWin::Toplevel*,QRect)), this, SLOT(checkScreen()));
disconnect(this, SIGNAL(geometryChanged()), this, SLOT(checkScreen()));
}
int Toplevel::screen() const
{
int s = workspace()->screenNumber(geometry().center());
if (s < 0) {
kDebug(1212) << "Invalid screen: Center" << geometry().center() << ", screen" << s;
return 0;
}
return s;
return m_screen;
}
bool Toplevel::isOnScreen(int screen) const

View File

@ -57,7 +57,7 @@ class Toplevel
Q_PROPERTY(int height READ height)
Q_PROPERTY(qreal opacity READ opacity WRITE setOpacity NOTIFY opacityChanged)
Q_PROPERTY(QPoint pos READ pos)
Q_PROPERTY(int screen READ screen)
Q_PROPERTY(int screen READ screen NOTIFY screenChanged)
Q_PROPERTY(QSize size READ size)
Q_PROPERTY(int width READ width)
Q_PROPERTY(qulonglong windowId READ window CONSTANT)
@ -326,6 +326,21 @@ signals:
**/
void needsRepaint();
void activitiesChanged(KWin::Toplevel* toplevel);
/**
* Emitted whenever the Toplevel's screen changes. This can happen either in consequence to
* a screen being removed/added or if the Toplevel's geometry changes.
* @since 4.11
**/
void screenChanged();
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();
protected:
virtual ~Toplevel();
@ -394,6 +409,7 @@ private:
bool m_damageReplyPending;
QRegion opaque_region;
xcb_xfixes_fetch_region_cookie_t m_regionCookie;
int m_screen;
// when adding new data members, check also copyToDeleted()
};

View File

@ -55,6 +55,7 @@ bool Unmanaged::track(Window w)
setWindowHandles(w, w); // the window is also the frame
XSelectInput(display(), w, attr.your_event_mask | StructureNotifyMask | PropertyChangeMask);
geom = QRect(attr.x, attr.y, attr.width, attr.height);
checkScreen();
vis = attr.visual;
bit_depth = attr.depth;
unsigned long properties[ 2 ];