[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-commits
Subject: [kwin] /: Move TabGroup functionality from Client to AbstractClient
From: Martin_Flöser <null () kde ! org>
Date: 2018-05-20 18:18:31
Message-ID: E1fKSud-0000hA-1I () code ! kde ! org
[Download RAW message or body]
Git commit 46d8b87646cd4f90533ab8642eb0dfeb0d93d33b by Martin Flöser.
Committed on 20/05/2018 at 17:50.
Pushed by graesslin into branch 'master'.
Move TabGroup functionality from Client to AbstractClient
Only setClientShown remains in Client. This might need a dedicated
implementation for ShellClient.
M +72 -9 abstract_client.cpp
M +44 -4 abstract_client.h
M +11 -90 client.cpp
M +0 -45 client.h
M +1 -1 manage.cpp
M +1 -0 tabgroup.h
https://commits.kde.org/kwin/46d8b87646cd4f90533ab8642eb0dfeb0d93d33b
diff --git a/abstract_client.cpp b/abstract_client.cpp
index bc3774d73..1e3a21e79 100644
--- a/abstract_client.cpp
+++ b/abstract_client.cpp
@@ -114,14 +114,10 @@ bool AbstractClient::isTransient() const
return false;
}
-TabGroup *AbstractClient::tabGroup() const
-{
- return nullptr;
-}
-
void AbstractClient::setTabGroup(TabGroup* group)
{
- Q_UNUSED(group)
+ tab_group = group;
+ emit tabGroupChanged();
}
void AbstractClient::setClientShown(bool shown)
@@ -131,16 +127,83 @@ void AbstractClient::setClientShown(bool shown)
bool AbstractClient::untab(const QRect &toGeometry, bool clientRemoved)
{
- Q_UNUSED(toGeometry)
- Q_UNUSED(clientRemoved)
+ TabGroup *group = tab_group;
+ if (group && group->remove(this)) { // remove sets the tabgroup to "0", \
therefore the pointer is cached + if (group->isEmpty()) {
+ delete group;
+ }
+ if (clientRemoved)
+ return true; // there's been a broadcast signal that this client is now \
removed - don't touch it + setClientShown(!(isMinimized() || isShade()));
+ bool keepSize = toGeometry.size() == size();
+ bool changedSize = false;
+ if (quickTileMode() != QuickTileMode(QuickTileFlag::None)) {
+ changedSize = true;
+ setQuickTileMode(QuickTileFlag::None); // if we leave a quicktiled \
group, assume that the user wants to untile + }
+ if (toGeometry.isValid()) {
+ if (maximizeMode() != MaximizeRestore) {
+ changedSize = true;
+ maximize(MaximizeRestore); // explicitly calling for a geometry -> \
unmaximize + }
+ if (keepSize && changedSize) {
+ setGeometryRestore(geometry()); // checkWorkspacePosition() invokes \
it + QPoint cpoint = Cursor::pos();
+ QPoint point = cpoint;
+ point.setX((point.x() - toGeometry.x()) * geometryRestore().width() \
/ toGeometry.width()); + point.setY((point.y() - toGeometry.y()) * \
geometryRestore().height() / toGeometry.height()); + auto \
geometry_restore = geometryRestore(); + \
geometry_restore.moveTo(cpoint-point); + \
setGeometryRestore(geometry_restore); + } else {
+ setGeometryRestore(toGeometry); // checkWorkspacePosition() invokes \
it + }
+ setGeometry(geometryRestore());
+ checkWorkspacePosition();
+ }
+ return true;
+ }
return false;
}
-bool AbstractClient::isCurrentTab() const
+bool AbstractClient::tabTo(AbstractClient *other, bool behind, bool activate)
{
+ Q_ASSERT(other && other != this);
+
+ if (tab_group && tab_group == other->tabGroup()) { // special case: move inside \
group + tab_group->move(this, other, behind);
+ return true;
+ }
+
+ GeometryUpdatesBlocker blocker(this);
+ const bool wasBlocking = signalsBlocked();
+ blockSignals(true); // prevent client emitting "retabbed to nowhere" cause it's \
about to be entabbed the next moment + untab();
+ blockSignals(wasBlocking);
+
+ TabGroup *newGroup = other->tabGroup() ? other->tabGroup() : new \
TabGroup(other); +
+ if (!newGroup->add(this, other, behind, activate)) {
+ if (newGroup->count() < 2) { // adding "c" to "to" failed for whatever \
reason + newGroup->remove(other);
+ delete newGroup;
+ }
+ return false;
+ }
return true;
}
+void AbstractClient::syncTabGroupFor(QString property, bool fromThisClient)
+{
+ if (tab_group)
+ tab_group->sync(property.toAscii().data(), fromThisClient ? this : \
tab_group->current()); +}
+
+bool AbstractClient::isCurrentTab() const
+{
+ return !tab_group || tab_group->current() == this;
+}
+
xcb_timestamp_t AbstractClient::userTime() const
{
return XCB_TIME_CURRENT_TIME;
diff --git a/abstract_client.h b/abstract_client.h
index c7401a8f8..c5259b664 100644
--- a/abstract_client.h
+++ b/abstract_client.h
@@ -272,6 +272,10 @@ class KWIN_EXPORT AbstractClient : public Toplevel
* considered unresponsive. This usually indicates that the application froze or \
crashed.
*/
Q_PROPERTY(bool unresponsive READ unresponsive NOTIFY unresponsiveChanged)
+ /**
+ * The "Window Tabs" Group this Client belongs to.
+ **/
+ Q_PROPERTY(KWin::TabGroup* tabGroup READ tabGroup NOTIFY tabGroupChanged \
SCRIPTABLE false)
public:
virtual ~AbstractClient();
@@ -422,11 +426,34 @@ public:
return m_minimized;
}
virtual void setFullScreen(bool set, bool user = true) = 0;
- virtual TabGroup *tabGroup() const;
- virtual void setTabGroup(TabGroup* group);
+ // Tabbing functions
+ Q_INVOKABLE inline bool tabBefore(AbstractClient *other, bool activate) { return \
tabTo(other, false, activate); } + Q_INVOKABLE inline bool \
tabBehind(AbstractClient *other, bool activate) { return tabTo(other, true, \
activate); } + /**
+ * Syncs the *dynamic* @param property @param fromThisClient or the @link \
currentTab() to + * all members of the @link tabGroup() (if there is one)
+ *
+ * eg. if you call:
+ * client->setProperty("kwin_tiling_floats", true);
+ * client->syncTabGroupFor("kwin_tiling_floats", true)
+ * all clients in this tabGroup will have \
::property("kwin_tiling_floats").toBool() == true + *
+ * WARNING: non dynamic properties are ignored - you're not supposed to \
alter/update such explicitly + */
+ Q_INVOKABLE void syncTabGroupFor(QString property, bool fromThisClient = false);
+ TabGroup *tabGroup() const;
+ /**
+ * Set tab group - this is to be invoked by TabGroup::add/remove(client) and NO \
ONE ELSE + */
+ void setTabGroup(TabGroup* group);
virtual void setClientShown(bool shown);
- Q_INVOKABLE virtual bool untab(const QRect &toGeometry = QRect(), bool \
clientRemoved = false);
- virtual bool isCurrentTab() const;
+ Q_INVOKABLE bool untab(const QRect &toGeometry = QRect(), bool clientRemoved = \
false); + /*
+ * When a click is done in the decoration and it calls the group
+ * to change the visible client it starts to move-resize the new
+ * client, this function stops it.
+ */
+ bool isCurrentTab() const;
virtual QRect geometryRestore() const = 0;
virtual MaximizeMode maximizeMode() const = 0;
void maximize(MaximizeMode);
@@ -732,6 +759,11 @@ Q_SIGNALS:
void hasApplicationMenuChanged(bool);
void applicationMenuActiveChanged(bool);
void unresponsiveChanged(bool);
+ /**
+ * Emitted whenever the Client's TabGroup changed. That is whenever the Client \
is moved to + * another group, but not when a Client gets added or removed to the \
Client's ClientGroup. + **/
+ void tabGroupChanged();
protected:
AbstractClient();
@@ -1031,6 +1063,8 @@ protected:
void finishWindowRules();
void discardTemporaryRules();
+ bool tabTo(AbstractClient *other, bool behind, bool activate);
+
private:
void handlePaletteChange();
QSharedPointer<TabBox::TabBoxClientImpl> m_tabBoxClient;
@@ -1108,6 +1142,7 @@ private:
QKeySequence _shortcut;
WindowRules m_rules;
+ TabGroup* tab_group = nullptr;
static bool s_haveResizeEffect;
};
@@ -1175,6 +1210,11 @@ inline void \
AbstractClient::setPendingGeometryUpdate(PendingGeometry_t update) \
m_pendingGeometryUpdate = update; }
+inline TabGroup* AbstractClient::tabGroup() const
+{
+ return tab_group;
+}
+
}
Q_DECLARE_METATYPE(KWin::AbstractClient*)
diff --git a/client.cpp b/client.cpp
index 23fca9222..8dd910e3c 100644
--- a/client.cpp
+++ b/client.cpp
@@ -108,7 +108,6 @@ Client::Client()
, shadeHoverTimer(NULL)
, m_colormap(XCB_COLORMAP_NONE)
, in_group(NULL)
- , tab_group(NULL)
, ping_timer(NULL)
, m_killHelperPID(0)
, m_pingTimestamp(XCB_TIME_CURRENT_TIME)
@@ -167,6 +166,17 @@ Client::Client()
}
});
+ connect(this, &Client::tabGroupChanged, this,
+ [this] {
+ auto group = tabGroup();
+ if (group) {
+ unsigned long data[] = {qHash(group)}; //->id();
+ m_client.changeProperty(atoms->kde_net_wm_tab_group, \
XCB_ATOM_CARDINAL, 32, 1, data); + }
+ else
+ m_client.deleteProperty(atoms->kde_net_wm_tab_group);
+ });
+
// SELI TODO: Initialize xsizehints??
}
@@ -1506,95 +1516,6 @@ void Client::fetchIconicName()
}
}
-bool Client::tabTo(Client *other, bool behind, bool activate)
-{
- Q_ASSERT(other && other != this);
-
- if (tab_group && tab_group == other->tabGroup()) { // special case: move inside \
group
- tab_group->move(this, other, behind);
- return true;
- }
-
- GeometryUpdatesBlocker blocker(this);
- const bool wasBlocking = signalsBlocked();
- blockSignals(true); // prevent client emitting "retabbed to nowhere" cause it's \
about to be entabbed the next moment
- untab();
- blockSignals(wasBlocking);
-
- TabGroup *newGroup = other->tabGroup() ? other->tabGroup() : new \
TabGroup(other);
-
- if (!newGroup->add(this, other, behind, activate)) {
- if (newGroup->count() < 2) { // adding "c" to "to" failed for whatever \
reason
- newGroup->remove(other);
- delete newGroup;
- }
- return false;
- }
- return true;
-}
-
-bool Client::untab(const QRect &toGeometry, bool clientRemoved)
-{
- TabGroup *group = tab_group;
- if (group && group->remove(this)) { // remove sets the tabgroup to "0", \
therefore the pointer is cached
- if (group->isEmpty()) {
- delete group;
- }
- if (clientRemoved)
- return true; // there's been a broadcast signal that this client is now \
removed - don't touch it
- setClientShown(!(isMinimized() || isShade()));
- bool keepSize = toGeometry.size() == size();
- bool changedSize = false;
- if (quickTileMode() != QuickTileMode(QuickTileFlag::None)) {
- changedSize = true;
- setQuickTileMode(QuickTileFlag::None); // if we leave a quicktiled \
group, assume that the user wants to untile
- }
- if (toGeometry.isValid()) {
- if (maximizeMode() != MaximizeRestore) {
- changedSize = true;
- maximize(MaximizeRestore); // explicitly calling for a geometry -> \
unmaximize
- }
- if (keepSize && changedSize) {
- geom_restore = geometry(); // checkWorkspacePosition() invokes it
- QPoint cpoint = Cursor::pos();
- QPoint point = cpoint;
- point.setX((point.x() - toGeometry.x()) * geom_restore.width() / \
toGeometry.width());
- point.setY((point.y() - toGeometry.y()) * geom_restore.height() / \
toGeometry.height());
- geom_restore.moveTo(cpoint-point);
- } else {
- geom_restore = toGeometry; // checkWorkspacePosition() invokes it
- }
- setGeometry(geom_restore);
- checkWorkspacePosition();
- }
- return true;
- }
- return false;
-}
-
-void Client::setTabGroup(TabGroup *group)
-{
- tab_group = group;
- if (group) {
- unsigned long data[] = {qHash(group)}; //->id();
- m_client.changeProperty(atoms->kde_net_wm_tab_group, XCB_ATOM_CARDINAL, 32, \
1, data);
- }
- else
- m_client.deleteProperty(atoms->kde_net_wm_tab_group);
- emit tabGroupChanged();
-}
-
-bool Client::isCurrentTab() const
-{
- return !tab_group || tab_group->current() == this;
-}
-
-void Client::syncTabGroupFor(QString property, bool fromThisClient)
-{
- if (tab_group)
- tab_group->sync(property.toAscii().data(), fromThisClient ? this : \
tab_group->current());
-}
-
void Client::setClientShown(bool shown)
{
if (deleting)
diff --git a/client.h b/client.h
index 288c4b18d..755b4fd3b 100644
--- a/client.h
+++ b/client.h
@@ -70,10 +70,6 @@ class KWIN_EXPORT Client
* Because of that no changed signal is provided.
*/
Q_PROPERTY(QSize basicUnit READ basicUnit)
- /**
- * The "Window Tabs" Group this Client belongs to.
- **/
- Q_PROPERTY(KWin::TabGroup* tabGroup READ tabGroup NOTIFY tabGroupChanged \
SCRIPTABLE false) /**
* A client can block compositing. That is while the Client is alive and the \
state is set,
* Compositing is suspended and is resumed when there are no Clients blocking \
compositing any @@ -250,27 +246,6 @@ public:
StrutRects strutRects() const;
bool hasStrut() const override;
- // Tabbing functions
- TabGroup* tabGroup() const override; // Returns a pointer to client_group
- Q_INVOKABLE inline bool tabBefore(Client *other, bool activate) { return \
tabTo(other, false, activate); }
- Q_INVOKABLE inline bool tabBehind(Client *other, bool activate) { return \
tabTo(other, true, activate); }
- /**
- * Syncs the *dynamic* @param property @param fromThisClient or the @link \
currentTab() to
- * all members of the @link tabGroup() (if there is one)
- *
- * eg. if you call:
- * client->setProperty("kwin_tiling_floats", true);
- * client->syncTabGroupFor("kwin_tiling_floats", true)
- * all clients in this tabGroup will have \
::property("kwin_tiling_floats").toBool() == true
- *
- * WARNING: non dynamic properties are ignored - you're not supposed to \
alter/update such explicitly
- */
- Q_INVOKABLE void syncTabGroupFor(QString property, bool fromThisClient = false);
- Q_INVOKABLE bool untab(const QRect &toGeometry = QRect(), bool clientRemoved = \
false) override;
- /**
- * Set tab group - this is to be invoked by TabGroup::add/remove(client) and NO \
ONE ELSE
- */
- void setTabGroup(TabGroup* group) override;
/*
* If shown is true the client is mapped and raised, if false
* the client is unmapped and hidden, this function is called
@@ -278,12 +253,6 @@ public:
* client.
*/
void setClientShown(bool shown) override;
- /*
- * When a click is done in the decoration and it calls the group
- * to change the visible client it starts to move-resize the new
- * client, this function stops it.
- */
- bool isCurrentTab() const override;
/**
* Whether or not the window has a strut that expands through the invisible area \
of @@ -407,12 +376,6 @@ Q_SIGNALS:
void clientManaging(KWin::Client*);
void clientFullScreenSet(KWin::Client*, bool, bool);
- /**
- * Emitted whenever the Client's TabGroup changed. That is whenever the Client \
is moved to
- * another group, but not when a Client gets added or removed to the Client's \
ClientGroup.
- **/
- void tabGroupChanged();
-
/**
* Emitted whenever the Client want to show it menu
*/
@@ -497,8 +460,6 @@ private:
void updateInputWindow();
- bool tabTo(Client *other, bool behind, bool activate);
-
Xcb::Property fetchShowOnScreenEdge() const;
void readShowOnScreenEdge(Xcb::Property &property);
/**
@@ -562,7 +523,6 @@ private:
xcb_colormap_t m_colormap;
QString cap_normal, cap_iconic, cap_suffix;
Group* in_group;
- TabGroup* tab_group;
QTimer* ping_timer;
qint64 m_killHelperPID;
xcb_timestamp_t m_pingTimestamp;
@@ -634,11 +594,6 @@ inline Group* Client::group()
return in_group;
}
-inline TabGroup* Client::tabGroup() const
-{
- return tab_group;
-}
-
inline bool Client::isShown(bool shaded_is_shown) const
{
return !isMinimized() && (!isShade() || shaded_is_shown) && !hidden &&
diff --git a/manage.cpp b/manage.cpp
index efa607e45..68b28df9c 100644
--- a/manage.cpp
+++ b/manage.cpp
@@ -370,7 +370,7 @@ bool Client::manage(xcb_window_t w, bool isMapped)
}
}
}
- if (!(tab_group || isMapped || session)) {
+ if (!(tabGroup() || isMapped || session)) {
// Attempt to automatically group similar windows
Client* similar = findAutogroupCandidate();
if (similar && !similar->noBorder()) {
diff --git a/tabgroup.h b/tabgroup.h
index 544910f8c..f4f6b4439 100644
--- a/tabgroup.h
+++ b/tabgroup.h
@@ -150,6 +150,7 @@ Q_SIGNALS:
void maxSizeChanged();
private:
+ friend class AbstractClient;
friend class Client;
// friend bool Client::tabTo(Client*, bool, bool);
bool add(KWin::AbstractClient *c, AbstractClient *other, bool behind, bool \
activateC);
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic