Commit 9ef42ae3 authored by Martin Flöser's avatar Martin Flöser

Move blocking geometry updates functionality to AbstractClient

parent 646eeb8b
......@@ -45,7 +45,10 @@ AbstractClient::AbstractClient()
{
}
AbstractClient::~AbstractClient() = default;
AbstractClient::~AbstractClient()
{
assert(m_blockGeometryUpdates == 0);
}
void AbstractClient::updateMouseGrab()
{
......
......@@ -560,6 +560,17 @@ protected:
virtual int borderTop() const;
virtual int borderBottom() const;
virtual void changeMaximize(bool horizontal, bool vertical, bool adjust) = 0;
void blockGeometryUpdates(bool block);
void blockGeometryUpdates();
void unblockGeometryUpdates();
bool areGeometryUpdatesBlocked() const;
enum PendingGeometry_t {
PendingGeometryNone,
PendingGeometryNormal,
PendingGeometryForced
};
PendingGeometry_t pendingGeometryUpdate() const;
void setPendingGeometryUpdate(PendingGeometry_t update);
private:
void handlePaletteChange();
......@@ -596,6 +607,29 @@ private:
// electric border/quick tiling
QuickTileMode m_electricMode = QuickTileNone;
bool m_electricMaximizing = false;
// geometry
int m_blockGeometryUpdates = 0; // > 0 = New geometry is remembered, but not actually set
PendingGeometry_t m_pendingGeometryUpdate = PendingGeometryNone;
friend class GeometryUpdatesBlocker;
};
/**
* Helper for AbstractClient::blockGeometryUpdates() being called in pairs (true/false)
*/
class GeometryUpdatesBlocker
{
public:
explicit GeometryUpdatesBlocker(AbstractClient* c)
: cl(c) {
cl->blockGeometryUpdates(true);
}
~GeometryUpdatesBlocker() {
cl->blockGeometryUpdates(false);
}
private:
AbstractClient* cl;
};
inline void AbstractClient::move(const QPoint& p, ForceGeometry_t force)
......@@ -618,6 +652,31 @@ inline const QList<AbstractClient*>& AbstractClient::transients() const
return m_transients;
}
inline bool AbstractClient::areGeometryUpdatesBlocked() const
{
return m_blockGeometryUpdates != 0;
}
inline void AbstractClient::blockGeometryUpdates()
{
m_blockGeometryUpdates++;
}
inline void AbstractClient::unblockGeometryUpdates()
{
m_blockGeometryUpdates--;
}
inline AbstractClient::PendingGeometry_t AbstractClient::pendingGeometryUpdate() const
{
return m_pendingGeometryUpdate;
}
inline void AbstractClient::setPendingGeometryUpdate(PendingGeometry_t update)
{
m_pendingGeometryUpdate = update;
}
}
Q_DECLARE_METATYPE(KWin::AbstractClient*)
......
......@@ -121,8 +121,6 @@ Client::Client()
, m_pingTimestamp(XCB_TIME_CURRENT_TIME)
, m_userTime(XCB_TIME_CURRENT_TIME) // Not known yet
, allowed_actions(0)
, block_geometry_updates(0)
, pending_geometry_update(PendingGeometryNone)
, shade_geometry_change(false)
, sm_stacking_order(-1)
, m_electricMaximizingDelay(nullptr)
......@@ -200,7 +198,6 @@ Client::~Client()
assert(m_wrapper == XCB_WINDOW_NONE);
//assert( frameId() == None );
Q_ASSERT(m_decoration == nullptr);
assert(block_geometry_updates == 0);
assert(!check_active_modal);
for (auto it = m_connections.constBegin(); it != m_connections.constEnd(); ++it) {
disconnect(*it);
......@@ -234,7 +231,7 @@ void Client::releaseWindow(bool on_shutdown)
if (moveResizeMode)
leaveMoveResize();
finishWindowRules();
++block_geometry_updates;
blockGeometryUpdates();
if (isOnCurrentDesktop() && isShown(true))
addWorkspaceRepaint(visibleRect());
// Grab X during the release to make removing of properties, setting to withdrawn state
......@@ -273,7 +270,7 @@ void Client::releaseWindow(bool on_shutdown)
m_wrapper.reset();
m_frame.reset();
//frame = None;
--block_geometry_updates; // Don't use GeometryUpdatesBlocker, it would now set the geometry
unblockGeometryUpdates(); // Don't use GeometryUpdatesBlocker, it would now set the geometry
if (!on_shutdown) {
disownDataPassedToDeleted();
del->unrefWindow();
......@@ -302,7 +299,7 @@ void Client::destroyClient()
if (moveResizeMode)
leaveMoveResize();
finishWindowRules();
++block_geometry_updates;
blockGeometryUpdates();
if (isOnCurrentDesktop() && isShown(true))
addWorkspaceRepaint(visibleRect());
setModal(false);
......@@ -315,7 +312,7 @@ void Client::destroyClient()
m_wrapper.reset();
m_frame.reset();
//frame = None;
--block_geometry_updates; // Don't use GeometryUpdatesBlocker, it would now set the geometry
unblockGeometryUpdates(); // Don't use GeometryUpdatesBlocker, it would now set the geometry
disownDataPassedToDeleted();
del->unrefWindow();
checkNonExistentClients();
......
......@@ -572,7 +572,6 @@ private:
void configureRequest(int value_mask, int rx, int ry, int rw, int rh, int gravity, bool from_tool);
NETExtendedStrut strut() const;
int checkShadeGeometry(int w, int h);
void blockGeometryUpdates(bool block);
void getSyncCounter();
void sendSyncRequest();
bool startMoveResize();
......@@ -711,13 +710,6 @@ private:
xcb_timestamp_t m_userTime;
NET::Actions allowed_actions;
QSize client_size;
int block_geometry_updates; // > 0 = New geometry is remembered, but not actually set
enum PendingGeometry_t {
PendingGeometryNone,
PendingGeometryNormal,
PendingGeometryForced
};
PendingGeometry_t pending_geometry_update;
QRect geom_before_block;
QRect deco_rect_before_block;
bool shade_geometry_change;
......@@ -733,7 +725,6 @@ private:
QKeySequence _shortcut;
int sm_stacking_order;
friend struct ResetupRulesProcedure;
friend class GeometryUpdatesBlocker;
QTimer* m_electricMaximizingDelay;
......@@ -758,24 +749,6 @@ private:
QMetaObject::Connection m_edgeRemoveConnection;
};
/**
* Helper for Client::blockGeometryUpdates() being called in pairs (true/false)
*/
class GeometryUpdatesBlocker
{
public:
explicit GeometryUpdatesBlocker(Client* c)
: cl(c) {
cl->blockGeometryUpdates(true);
}
~GeometryUpdatesBlocker() {
cl->blockGeometryUpdates(false);
}
private:
Client* cl;
};
inline xcb_window_t Client::wrapperId() const
{
return m_wrapper;
......
......@@ -1909,23 +1909,23 @@ void Client::setGeometry(int x, int y, int w, int h, ForceGeometry_t force)
client_size = QSize(w - borderLeft() - borderRight(), h - borderTop() - borderBottom());
}
QRect g(x, y, w, h);
if (block_geometry_updates == 0 && g != rules()->checkGeometry(g)) {
if (!areGeometryUpdatesBlocked() && g != rules()->checkGeometry(g)) {
qCDebug(KWIN_CORE) << "forced geometry fail:" << g << ":" << rules()->checkGeometry(g);
}
if (force == NormalGeometrySet && geom == g && pending_geometry_update == PendingGeometryNone)
if (force == NormalGeometrySet && geom == g && pendingGeometryUpdate() == PendingGeometryNone)
return;
geom = g;
if (block_geometry_updates != 0) {
if (pending_geometry_update == PendingGeometryForced)
if (areGeometryUpdatesBlocked()) {
if (pendingGeometryUpdate() == PendingGeometryForced)
{} // maximum, nothing needed
else if (force == ForceGeometrySet)
pending_geometry_update = PendingGeometryForced;
setPendingGeometryUpdate(PendingGeometryForced);
else
pending_geometry_update = PendingGeometryNormal;
setPendingGeometryUpdate(PendingGeometryNormal);
return;
}
QSize oldClientSize = m_frame.geometry().size();
bool resized = (geom_before_block.size() != geom.size() || pending_geometry_update == PendingGeometryForced);
bool resized = (geom_before_block.size() != geom.size() || pendingGeometryUpdate() == PendingGeometryForced);
if (resized) {
resizeDecoration();
m_frame.setGeometry(x, y, w, h);
......@@ -1999,21 +1999,21 @@ void Client::plainResize(int w, int h, ForceGeometry_t force)
client_size = QSize(w - borderLeft() - borderRight(), h - borderTop() - borderBottom());
}
QSize s(w, h);
if (block_geometry_updates == 0 && s != rules()->checkSize(s)) {
if (!areGeometryUpdatesBlocked() && s != rules()->checkSize(s)) {
qCDebug(KWIN_CORE) << "forced size fail:" << s << ":" << rules()->checkSize(s);
}
// resuming geometry updates is handled only in setGeometry()
assert(pending_geometry_update == PendingGeometryNone || block_geometry_updates > 0);
assert(pendingGeometryUpdate() == PendingGeometryNone || areGeometryUpdatesBlocked());
if (force == NormalGeometrySet && geom.size() == s)
return;
geom.setSize(s);
if (block_geometry_updates != 0) {
if (pending_geometry_update == PendingGeometryForced)
if (areGeometryUpdatesBlocked()) {
if (pendingGeometryUpdate() == PendingGeometryForced)
{} // maximum, nothing needed
else if (force == ForceGeometrySet)
pending_geometry_update = PendingGeometryForced;
setPendingGeometryUpdate(PendingGeometryForced);
else
pending_geometry_update = PendingGeometryNormal;
setPendingGeometryUpdate(PendingGeometryNormal);
return;
}
QSize oldClientSize = m_frame.geometry().size();
......@@ -2053,21 +2053,21 @@ void Client::plainResize(int w, int h, ForceGeometry_t force)
void Client::move(int x, int y, ForceGeometry_t force)
{
// resuming geometry updates is handled only in setGeometry()
assert(pending_geometry_update == PendingGeometryNone || block_geometry_updates > 0);
assert(pendingGeometryUpdate() == PendingGeometryNone || areGeometryUpdatesBlocked());
QPoint p(x, y);
if (block_geometry_updates == 0 && p != rules()->checkPosition(p)) {
if (!areGeometryUpdatesBlocked() && p != rules()->checkPosition(p)) {
qCDebug(KWIN_CORE) << "forced position fail:" << p << ":" << rules()->checkPosition(p);
}
if (force == NormalGeometrySet && geom.topLeft() == p)
return;
geom.moveTopLeft(p);
if (block_geometry_updates != 0) {
if (pending_geometry_update == PendingGeometryForced)
if (areGeometryUpdatesBlocked()) {
if (pendingGeometryUpdate() == PendingGeometryForced)
{} // maximum, nothing needed
else if (force == ForceGeometrySet)
pending_geometry_update = PendingGeometryForced;
setPendingGeometryUpdate(PendingGeometryForced);
else
pending_geometry_update = PendingGeometryNormal;
setPendingGeometryUpdate(PendingGeometryNormal);
return;
}
m_frame.move(x, y);
......@@ -2092,20 +2092,20 @@ void Client::move(int x, int y, ForceGeometry_t force)
emit geometryChanged();
}
void Client::blockGeometryUpdates(bool block)
void AbstractClient::blockGeometryUpdates(bool block)
{
if (block) {
if (block_geometry_updates == 0)
pending_geometry_update = PendingGeometryNone;
++block_geometry_updates;
if (m_blockGeometryUpdates == 0)
m_pendingGeometryUpdate = PendingGeometryNone;
++m_blockGeometryUpdates;
} else {
if (--block_geometry_updates == 0) {
if (pending_geometry_update != PendingGeometryNone) {
if (--m_blockGeometryUpdates == 0) {
if (m_pendingGeometryUpdate != PendingGeometryNone) {
if (isShade())
setGeometry(QRect(pos(), adjustedSize()), NormalGeometrySet);
else
setGeometry(geometry(), NormalGeometrySet);
pending_geometry_update = PendingGeometryNone;
m_pendingGeometryUpdate = PendingGeometryNone;
}
}
}
......
......@@ -57,8 +57,8 @@ bool Client::manage(xcb_window_t w, bool isMapped)
}
// From this place on, manage() must not return false
block_geometry_updates = 1;
pending_geometry_update = PendingGeometryForced; // Force update when finishing with geometry changes
blockGeometryUpdates();
setPendingGeometryUpdate(PendingGeometryForced); // Force update when finishing with geometry changes
embedClient(w, attr->visual, attr->colormap, windowGeometry->depth);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment