Port TabGroup from Client to AbstractClient
First step towards a return of window tabbing.
This commit is contained in:
parent
a02797ca06
commit
7defd93047
6 changed files with 50 additions and 38 deletions
|
@ -119,6 +119,16 @@ TabGroup *AbstractClient::tabGroup() const
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AbstractClient::setTabGroup(TabGroup* group)
|
||||||
|
{
|
||||||
|
Q_UNUSED(group)
|
||||||
|
}
|
||||||
|
|
||||||
|
void AbstractClient::setClientShown(bool shown)
|
||||||
|
{
|
||||||
|
Q_UNUSED(shown)
|
||||||
|
}
|
||||||
|
|
||||||
bool AbstractClient::untab(const QRect &toGeometry, bool clientRemoved)
|
bool AbstractClient::untab(const QRect &toGeometry, bool clientRemoved)
|
||||||
{
|
{
|
||||||
Q_UNUSED(toGeometry)
|
Q_UNUSED(toGeometry)
|
||||||
|
|
|
@ -423,6 +423,8 @@ public:
|
||||||
}
|
}
|
||||||
virtual void setFullScreen(bool set, bool user = true) = 0;
|
virtual void setFullScreen(bool set, bool user = true) = 0;
|
||||||
virtual TabGroup *tabGroup() const;
|
virtual TabGroup *tabGroup() const;
|
||||||
|
virtual void setTabGroup(TabGroup* group);
|
||||||
|
virtual void setClientShown(bool shown);
|
||||||
Q_INVOKABLE virtual bool untab(const QRect &toGeometry = QRect(), bool clientRemoved = false);
|
Q_INVOKABLE virtual bool untab(const QRect &toGeometry = QRect(), bool clientRemoved = false);
|
||||||
virtual bool isCurrentTab() const;
|
virtual bool isCurrentTab() const;
|
||||||
virtual QRect geometryRestore() const = 0;
|
virtual QRect geometryRestore() const = 0;
|
||||||
|
|
4
client.h
4
client.h
|
@ -270,14 +270,14 @@ public:
|
||||||
/**
|
/**
|
||||||
* Set tab group - this is to be invoked by TabGroup::add/remove(client) and NO ONE ELSE
|
* Set tab group - this is to be invoked by TabGroup::add/remove(client) and NO ONE ELSE
|
||||||
*/
|
*/
|
||||||
void setTabGroup(TabGroup* group);
|
void setTabGroup(TabGroup* group) override;
|
||||||
/*
|
/*
|
||||||
* If shown is true the client is mapped and raised, if false
|
* If shown is true the client is mapped and raised, if false
|
||||||
* the client is unmapped and hidden, this function is called
|
* the client is unmapped and hidden, this function is called
|
||||||
* when the tabbing group of the client switches its visible
|
* when the tabbing group of the client switches its visible
|
||||||
* client.
|
* client.
|
||||||
*/
|
*/
|
||||||
void setClientShown(bool shown);
|
void setClientShown(bool shown) override;
|
||||||
/*
|
/*
|
||||||
* When a click is done in the decoration and it calls the group
|
* 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
|
* to change the visible client it starts to move-resize the new
|
||||||
|
|
38
tabgroup.cpp
38
tabgroup.cpp
|
@ -27,7 +27,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
namespace KWin
|
namespace KWin
|
||||||
{
|
{
|
||||||
|
|
||||||
TabGroup::TabGroup(Client *c)
|
TabGroup::TabGroup(AbstractClient *c)
|
||||||
: m_clients()
|
: m_clients()
|
||||||
, m_current(c)
|
, m_current(c)
|
||||||
, m_minSize(c->minSize())
|
, m_minSize(c->minSize())
|
||||||
|
@ -58,7 +58,7 @@ void TabGroup::activatePrev()
|
||||||
setCurrent(m_clients.at((index > 0) ? index - 1 : m_clients.count() - 1));
|
setCurrent(m_clients.at((index > 0) ? index - 1 : m_clients.count() - 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TabGroup::add(Client* c, Client *other, bool after, bool becomeVisible)
|
bool TabGroup::add(AbstractClient* c, AbstractClient *other, bool after, bool becomeVisible)
|
||||||
{
|
{
|
||||||
Q_ASSERT(!c->tabGroup());
|
Q_ASSERT(!c->tabGroup());
|
||||||
|
|
||||||
|
@ -144,7 +144,7 @@ bool TabGroup::add(Client* c, Client *other, bool after, bool becomeVisible)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TabGroup::remove(Client* c)
|
bool TabGroup::remove(AbstractClient* c)
|
||||||
{
|
{
|
||||||
if (!c)
|
if (!c)
|
||||||
return false;
|
return false;
|
||||||
|
@ -189,15 +189,15 @@ void TabGroup::closeAll()
|
||||||
// after this function exits.
|
// after this function exits.
|
||||||
// However later Wayland support or similar might not share this bahaviour - and we really had
|
// However later Wayland support or similar might not share this bahaviour - and we really had
|
||||||
// enough trouble with a polluted client list around the tabbing code ....
|
// enough trouble with a polluted client list around the tabbing code ....
|
||||||
ClientList list(m_clients);
|
auto list(m_clients);
|
||||||
for (ClientList::const_iterator i = list.constBegin(), end = list.constEnd(); i != end; ++i)
|
for (auto i = list.constBegin(), end = list.constEnd(); i != end; ++i)
|
||||||
if (*i != m_current)
|
if (*i != m_current)
|
||||||
(*i)->closeWindow();
|
(*i)->closeWindow();
|
||||||
|
|
||||||
m_current->closeWindow();
|
m_current->closeWindow();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TabGroup::move(Client *c, Client *other, bool after)
|
void TabGroup::move(AbstractClient *c, AbstractClient *other, bool after)
|
||||||
{
|
{
|
||||||
if (c == other)
|
if (c == other)
|
||||||
return;
|
return;
|
||||||
|
@ -222,10 +222,10 @@ void TabGroup::move(Client *c, Client *other, bool after)
|
||||||
|
|
||||||
bool TabGroup::isActive() const
|
bool TabGroup::isActive() const
|
||||||
{
|
{
|
||||||
return contains(dynamic_cast<Client*>(Workspace::self()->activeClient()));
|
return contains(Workspace::self()->activeClient());
|
||||||
}
|
}
|
||||||
|
|
||||||
void TabGroup::setCurrent(Client* c, bool force)
|
void TabGroup::setCurrent(AbstractClient* c, bool force)
|
||||||
{
|
{
|
||||||
if ((c == m_current && !force) || !contains(c))
|
if ((c == m_current && !force) || !contains(c))
|
||||||
return;
|
return;
|
||||||
|
@ -236,18 +236,18 @@ void TabGroup::setCurrent(Client* c, bool force)
|
||||||
|
|
||||||
m_current = c;
|
m_current = c;
|
||||||
c->setClientShown(true); // reduce flicker?
|
c->setClientShown(true); // reduce flicker?
|
||||||
for (ClientList::const_iterator i = m_clients.constBegin(), end = m_clients.constEnd(); i != end; ++i)
|
for (auto i = m_clients.constBegin(), end = m_clients.constEnd(); i != end; ++i)
|
||||||
(*i)->setClientShown((*i) == m_current);
|
(*i)->setClientShown((*i) == m_current);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TabGroup::sync(const char *property, Client *c)
|
void TabGroup::sync(const char *property, AbstractClient *c)
|
||||||
{
|
{
|
||||||
if (c->metaObject()->indexOfProperty(property) > -1) {
|
if (c->metaObject()->indexOfProperty(property) > -1) {
|
||||||
qCWarning(KWIN_CORE, "caught attempt to sync non dynamic property: %s", property);
|
qCWarning(KWIN_CORE, "caught attempt to sync non dynamic property: %s", property);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
QVariant v = c->property(property);
|
QVariant v = c->property(property);
|
||||||
for (ClientList::iterator i = m_clients.begin(), end = m_clients.end(); i != end; ++i) {
|
for (auto i = m_clients.begin(), end = m_clients.end(); i != end; ++i) {
|
||||||
if (*i != m_current)
|
if (*i != m_current)
|
||||||
(*i)->setProperty(property, v);
|
(*i)->setProperty(property, v);
|
||||||
}
|
}
|
||||||
|
@ -263,7 +263,7 @@ void TabGroup::updateMinMaxSize()
|
||||||
m_minSize = QSize(0, 0);
|
m_minSize = QSize(0, 0);
|
||||||
m_maxSize = QSize(INT_MAX, INT_MAX);
|
m_maxSize = QSize(INT_MAX, INT_MAX);
|
||||||
|
|
||||||
for (ClientList::const_iterator i = m_clients.constBegin(); i != m_clients.constEnd(); ++i) {
|
for (auto i = m_clients.constBegin(); i != m_clients.constEnd(); ++i) {
|
||||||
m_minSize = m_minSize.expandedTo((*i)->minSize());
|
m_minSize = m_minSize.expandedTo((*i)->minSize());
|
||||||
m_maxSize = m_maxSize.boundedTo((*i)->maxSize());
|
m_maxSize = m_maxSize.boundedTo((*i)->maxSize());
|
||||||
}
|
}
|
||||||
|
@ -276,7 +276,7 @@ void TabGroup::updateMinMaxSize()
|
||||||
const QSize size = m_current->clientSize().expandedTo(m_minSize).boundedTo(m_maxSize);
|
const QSize size = m_current->clientSize().expandedTo(m_minSize).boundedTo(m_maxSize);
|
||||||
if (size != m_current->clientSize()) {
|
if (size != m_current->clientSize()) {
|
||||||
const QRect r(m_current->pos(), m_current->sizeForClientSize(size));
|
const QRect r(m_current->pos(), m_current->sizeForClientSize(size));
|
||||||
for (ClientList::const_iterator i = m_clients.constBegin(), end = m_clients.constEnd(); i != end; ++i)
|
for (auto i = m_clients.constBegin(), end = m_clients.constEnd(); i != end; ++i)
|
||||||
(*i)->setGeometry(r);
|
(*i)->setGeometry(r);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -290,7 +290,7 @@ void TabGroup::blockStateUpdates(bool more) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TabGroup::updateStates(Client* main, States states, Client* only)
|
void TabGroup::updateStates(AbstractClient* main, States states, AbstractClient* only)
|
||||||
{
|
{
|
||||||
if (main == only)
|
if (main == only)
|
||||||
return; // there's no need to only align "us" to "us"
|
return; // there's no need to only align "us" to "us"
|
||||||
|
@ -302,15 +302,15 @@ void TabGroup::updateStates(Client* main, States states, Client* only)
|
||||||
states |= m_pendingUpdates;
|
states |= m_pendingUpdates;
|
||||||
m_pendingUpdates = TabGroup::None;
|
m_pendingUpdates = TabGroup::None;
|
||||||
|
|
||||||
ClientList toBeRemoved, onlyDummy;
|
QVector<AbstractClient*> toBeRemoved, onlyDummy;
|
||||||
ClientList *list = &m_clients;
|
auto *list = &m_clients;
|
||||||
if (only) {
|
if (only) {
|
||||||
onlyDummy << only;
|
onlyDummy << only;
|
||||||
list = &onlyDummy;
|
list = &onlyDummy;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (ClientList::const_iterator i = list->constBegin(), end = list->constEnd(); i != end; ++i) {
|
for (auto i = list->constBegin(), end = list->constEnd(); i != end; ++i) {
|
||||||
Client *c = (*i);
|
auto *c = (*i);
|
||||||
if (c != main) {
|
if (c != main) {
|
||||||
if ((states & Minimized) && c->isMinimized() != main->isMinimized()) {
|
if ((states & Minimized) && c->isMinimized() != main->isMinimized()) {
|
||||||
if (main->isMinimized())
|
if (main->isMinimized())
|
||||||
|
@ -353,7 +353,7 @@ void TabGroup::updateStates(Client* main, States states, Client* only)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (ClientList::const_iterator i = toBeRemoved.constBegin(), end = toBeRemoved.constEnd(); i != end; ++i)
|
for (auto i = toBeRemoved.constBegin(), end = toBeRemoved.constEnd(); i != end; ++i)
|
||||||
remove(*i);
|
remove(*i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
32
tabgroup.h
32
tabgroup.h
|
@ -28,7 +28,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
namespace KWin
|
namespace KWin
|
||||||
{
|
{
|
||||||
|
|
||||||
class Client;
|
class AbstractClient;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class represents a group of clients for use in window tabbing. All
|
* This class represents a group of clients for use in window tabbing. All
|
||||||
|
@ -52,7 +52,7 @@ public:
|
||||||
/**
|
/**
|
||||||
* Creates a new group containing \p c.
|
* Creates a new group containing \p c.
|
||||||
*/
|
*/
|
||||||
explicit TabGroup(Client* c);
|
explicit TabGroup(AbstractClient* c);
|
||||||
~TabGroup();
|
~TabGroup();
|
||||||
|
|
||||||
enum State {
|
enum State {
|
||||||
|
@ -87,7 +87,7 @@ public:
|
||||||
/**
|
/**
|
||||||
* Whether client \p c is member of this group
|
* Whether client \p c is member of this group
|
||||||
*/
|
*/
|
||||||
bool contains(Client* c) const;
|
bool contains(AbstractClient* c) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The amount of clients in this group
|
* The amount of clients in this group
|
||||||
|
@ -107,22 +107,22 @@ public:
|
||||||
/**
|
/**
|
||||||
* Returns the list of all the clients contained in this group in their current order.
|
* Returns the list of all the clients contained in this group in their current order.
|
||||||
*/
|
*/
|
||||||
const ClientList &clients() const;
|
const QVector<AbstractClient*> &clients() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the currently visible client.
|
* Returns the currently visible client.
|
||||||
*/
|
*/
|
||||||
Client* current() const;
|
AbstractClient* current() const;
|
||||||
/**
|
/**
|
||||||
* Makes \p c the visible client in the group - force is only used when the window becomes ready for painting.
|
* Makes \p c the visible client in the group - force is only used when the window becomes ready for painting.
|
||||||
* Any other usage just causes pointless action
|
* Any other usage just causes pointless action
|
||||||
*/
|
*/
|
||||||
void setCurrent(Client* c, bool force = false);
|
void setCurrent(AbstractClient* c, bool force = false);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Alignes the dynamic Qt @param property of all clients to the one of @param c
|
* Alignes the dynamic Qt @param property of all clients to the one of @param c
|
||||||
*/
|
*/
|
||||||
void sync(const char *property, Client *c);
|
void sync(const char *property, AbstractClient *c);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns combined minimum size of all clients in the group.
|
* Returns combined minimum size of all clients in the group.
|
||||||
|
@ -138,7 +138,7 @@ public:
|
||||||
* \p main as the primary client to copy the settings off. If \p only is set then only
|
* \p main as the primary client to copy the settings off. If \p only is set then only
|
||||||
* that client is updated to match \p main.
|
* that client is updated to match \p main.
|
||||||
*/
|
*/
|
||||||
void updateStates(Client* main, States states, Client* only = NULL);
|
void updateStates(AbstractClient* main, States states, AbstractClient* only = NULL);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* updates geometry restrictions of this group, basically called from Client::getWmNormalHints(), otherwise rather private
|
* updates geometry restrictions of this group, basically called from Client::getWmNormalHints(), otherwise rather private
|
||||||
|
@ -152,21 +152,21 @@ Q_SIGNALS:
|
||||||
private:
|
private:
|
||||||
friend class Client;
|
friend class Client;
|
||||||
// friend bool Client::tabTo(Client*, bool, bool);
|
// friend bool Client::tabTo(Client*, bool, bool);
|
||||||
bool add(KWin::Client *c, Client *other, bool behind, bool activateC);
|
bool add(KWin::AbstractClient *c, AbstractClient *other, bool behind, bool activateC);
|
||||||
void move(KWin::Client* c, KWin::Client* before, bool behind);
|
void move(KWin::AbstractClient* c, KWin::AbstractClient* before, bool behind);
|
||||||
|
|
||||||
// friend bool Client::untab(const QRect&);
|
// friend bool Client::untab(const QRect&);
|
||||||
bool remove(KWin::Client *c);
|
bool remove(KWin::AbstractClient *c);
|
||||||
|
|
||||||
ClientList m_clients;
|
QVector<AbstractClient*> m_clients;
|
||||||
Client *m_current;
|
AbstractClient *m_current;
|
||||||
QSize m_minSize;
|
QSize m_minSize;
|
||||||
QSize m_maxSize;
|
QSize m_maxSize;
|
||||||
int m_stateUpdatesBlocked;
|
int m_stateUpdatesBlocked;
|
||||||
States m_pendingUpdates;
|
States m_pendingUpdates;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline bool TabGroup::contains(Client* c) const
|
inline bool TabGroup::contains(AbstractClient* c) const
|
||||||
{
|
{
|
||||||
return c && m_clients.contains(c);
|
return c && m_clients.contains(c);
|
||||||
}
|
}
|
||||||
|
@ -176,7 +176,7 @@ inline int TabGroup::count() const
|
||||||
return m_clients.count();
|
return m_clients.count();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline const ClientList &TabGroup::clients() const
|
inline const QVector<AbstractClient*> &TabGroup::clients() const
|
||||||
{
|
{
|
||||||
return m_clients;
|
return m_clients;
|
||||||
}
|
}
|
||||||
|
@ -186,7 +186,7 @@ inline bool TabGroup::isEmpty() const
|
||||||
return m_clients.isEmpty();
|
return m_clients.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline Client* TabGroup::current() const
|
inline AbstractClient* TabGroup::current() const
|
||||||
{
|
{
|
||||||
return m_current;
|
return m_current;
|
||||||
}
|
}
|
||||||
|
|
|
@ -534,7 +534,7 @@ void UserActionsMenu::rebuildTabListPopup()
|
||||||
|
|
||||||
m_switchToTabMenu->addSeparator();
|
m_switchToTabMenu->addSeparator();
|
||||||
|
|
||||||
for (QList<Client*>::const_iterator i = m_client.data()->tabGroup()->clients().constBegin(),
|
for (auto i = m_client.data()->tabGroup()->clients().constBegin(),
|
||||||
end = m_client.data()->tabGroup()->clients().constEnd(); i != end; ++i) {
|
end = m_client.data()->tabGroup()->clients().constEnd(); i != end; ++i) {
|
||||||
if ((*i)->noBorder() || *i == m_client.data()->tabGroup()->current())
|
if ((*i)->noBorder() || *i == m_client.data()->tabGroup()->current())
|
||||||
continue; // cannot tab there anyway
|
continue; // cannot tab there anyway
|
||||||
|
|
Loading…
Reference in a new issue