Use smart pointers to protect access to TabBoxClient
Client holds a SharedPointer to the TabBoxClient and only provides access to a WeakPointer which is passed to TabBox. ClientModel is adjusted to hold a list of WeakPointers instead of the direct pointers. This fixes the following reproducable crash: 1. Configure both primary and secondary TabBox with different layouts 2. Use primary TabBox 3. Close a window, best the one which used to be active 4. Use secondary TabBox -> Crash The reason is that the ClientModel still contains the pointer to the deleted TabBoxClient in step 3 and while creating the layout access to the TabBoxClient is needed to get the Client's icon. By using the weak pointer it can be ensured that we don't try to dereference the deleted pointer and prevent the crash. CCBUG: 290482 CCBUG: 285747 CCBUG: 237345 REVIEW: 105000
This commit is contained in:
parent
f24103481e
commit
d75e7a6d60
8 changed files with 109 additions and 66 deletions
|
@ -187,7 +187,7 @@ Client::Client(Workspace* ws)
|
||||||
|
|
||||||
#ifdef KWIN_BUILD_TABBOX
|
#ifdef KWIN_BUILD_TABBOX
|
||||||
// TabBoxClient
|
// TabBoxClient
|
||||||
m_tabBoxClient = new TabBox::TabBoxClientImpl(this);
|
m_tabBoxClient = QSharedPointer<TabBox::TabBoxClientImpl>(new TabBox::TabBoxClientImpl(this));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
geom = QRect(0, 0, 100, 100); // So that decorations don't start with size being (0,0)
|
geom = QRect(0, 0, 100, 100); // So that decorations don't start with size being (0,0)
|
||||||
|
@ -221,9 +221,6 @@ Client::~Client()
|
||||||
assert(block_geometry_updates == 0);
|
assert(block_geometry_updates == 0);
|
||||||
assert(!check_active_modal);
|
assert(!check_active_modal);
|
||||||
delete bridge;
|
delete bridge;
|
||||||
#ifdef KWIN_BUILD_TABBOX
|
|
||||||
delete m_tabBoxClient;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use destroyClient() or releaseWindow(), Client instances cannot be deleted directly
|
// Use destroyClient() or releaseWindow(), Client instances cannot be deleted directly
|
||||||
|
|
6
client.h
6
client.h
|
@ -621,8 +621,8 @@ public:
|
||||||
};
|
};
|
||||||
void layoutDecorationRects(QRect &left, QRect &top, QRect &right, QRect &bottom, CoordinateMode mode) const;
|
void layoutDecorationRects(QRect &left, QRect &top, QRect &right, QRect &bottom, CoordinateMode mode) const;
|
||||||
|
|
||||||
TabBox::TabBoxClientImpl* tabBoxClient() const {
|
QWeakPointer<TabBox::TabBoxClientImpl> tabBoxClient() const {
|
||||||
return m_tabBoxClient;
|
return m_tabBoxClient.toWeakRef();
|
||||||
}
|
}
|
||||||
bool isFirstInTabBox() const {
|
bool isFirstInTabBox() const {
|
||||||
return m_firstInTabBox;
|
return m_firstInTabBox;
|
||||||
|
@ -945,7 +945,7 @@ private:
|
||||||
// we (instead of Qt) initialize the Pixmaps, and have to free them
|
// we (instead of Qt) initialize the Pixmaps, and have to free them
|
||||||
bool m_responsibleForDecoPixmap;
|
bool m_responsibleForDecoPixmap;
|
||||||
PaintRedirector* paintRedirector;
|
PaintRedirector* paintRedirector;
|
||||||
TabBox::TabBoxClientImpl* m_tabBoxClient;
|
QSharedPointer<TabBox::TabBoxClientImpl> m_tabBoxClient;
|
||||||
bool m_firstInTabBox;
|
bool m_firstInTabBox;
|
||||||
|
|
||||||
bool electricMaximizing;
|
bool electricMaximizing;
|
||||||
|
|
|
@ -63,22 +63,26 @@ QVariant ClientModel::data(const QModelIndex& index, int role) const
|
||||||
int clientIndex = index.row() * columnCount() + index.column();
|
int clientIndex = index.row() * columnCount() + index.column();
|
||||||
if (clientIndex >= m_clientList.count())
|
if (clientIndex >= m_clientList.count())
|
||||||
return QVariant();
|
return QVariant();
|
||||||
|
QSharedPointer<TabBoxClient> client = m_clientList[ clientIndex ].toStrongRef();
|
||||||
|
if (!client) {
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
switch(role) {
|
switch(role) {
|
||||||
case Qt::DisplayRole:
|
case Qt::DisplayRole:
|
||||||
case CaptionRole:
|
case CaptionRole:
|
||||||
return m_clientList[ clientIndex ]->caption();
|
return client->caption();
|
||||||
case ClientRole:
|
case ClientRole:
|
||||||
return qVariantFromValue((void*)m_clientList[ clientIndex ]);
|
return qVariantFromValue((void*)client.data());
|
||||||
case DesktopNameRole: {
|
case DesktopNameRole: {
|
||||||
return tabBox->desktopName(m_clientList[ clientIndex ]);
|
return tabBox->desktopName(client.data());
|
||||||
}
|
}
|
||||||
case WIdRole:
|
case WIdRole:
|
||||||
return qulonglong(m_clientList[ clientIndex ]->window());
|
return qulonglong(client->window());
|
||||||
case MinimizedRole:
|
case MinimizedRole:
|
||||||
return m_clientList[ clientIndex ]->isMinimized();
|
return client->isMinimized();
|
||||||
case CloseableRole:
|
case CloseableRole:
|
||||||
//clients that claim to be first are not closeable
|
//clients that claim to be first are not closeable
|
||||||
return m_clientList[ clientIndex ]->isCloseable() && !m_clientList[ clientIndex ]->isFirstInTabBox();
|
return client->isCloseable() && !client->isFirstInTabBox();
|
||||||
default:
|
default:
|
||||||
return QVariant();
|
return QVariant();
|
||||||
}
|
}
|
||||||
|
@ -87,7 +91,8 @@ QVariant ClientModel::data(const QModelIndex& index, int role) const
|
||||||
QString ClientModel::longestCaption() const
|
QString ClientModel::longestCaption() const
|
||||||
{
|
{
|
||||||
QString caption;
|
QString caption;
|
||||||
foreach (TabBoxClient *client, m_clientList) {
|
foreach (QWeakPointer<TabBoxClient> clientPointer, m_clientList) {
|
||||||
|
QSharedPointer<TabBoxClient> client = clientPointer.toStrongRef();
|
||||||
if (client->caption().size() > caption.size()) {
|
if (client->caption().size() > caption.size()) {
|
||||||
caption = client->caption();
|
caption = client->caption();
|
||||||
}
|
}
|
||||||
|
@ -148,7 +153,7 @@ QModelIndex ClientModel::index(int row, int column, const QModelIndex& parent) c
|
||||||
return createIndex(row, column);
|
return createIndex(row, column);
|
||||||
}
|
}
|
||||||
|
|
||||||
QModelIndex ClientModel::index(TabBoxClient* client) const
|
QModelIndex ClientModel::index(QWeakPointer<TabBoxClient> client) const
|
||||||
{
|
{
|
||||||
if (!m_clientList.contains(client))
|
if (!m_clientList.contains(client))
|
||||||
return QModelIndex();
|
return QModelIndex();
|
||||||
|
@ -165,31 +170,35 @@ void ClientModel::createClientList(bool partialReset)
|
||||||
|
|
||||||
void ClientModel::createClientList(int desktop, bool partialReset)
|
void ClientModel::createClientList(int desktop, bool partialReset)
|
||||||
{
|
{
|
||||||
TabBoxClient* start = tabBox->activeClient();
|
TabBoxClient* start = tabBox->activeClient().toStrongRef().data();
|
||||||
// TODO: new clients are not added at correct position
|
// TODO: new clients are not added at correct position
|
||||||
if (partialReset && !m_clientList.isEmpty())
|
if (partialReset && !m_clientList.isEmpty()) {
|
||||||
start = m_clientList.first();
|
QSharedPointer<TabBoxClient> firstClient = m_clientList.first().toStrongRef();
|
||||||
|
if (firstClient) {
|
||||||
|
start = firstClient.data();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
m_clientList.clear();
|
m_clientList.clear();
|
||||||
QList<TabBoxClient*> stickyClients;
|
QList< QWeakPointer< TabBoxClient > > stickyClients;
|
||||||
|
|
||||||
switch(tabBox->config().clientSwitchingMode()) {
|
switch(tabBox->config().clientSwitchingMode()) {
|
||||||
case TabBoxConfig::FocusChainSwitching: {
|
case TabBoxConfig::FocusChainSwitching: {
|
||||||
TabBoxClient* c = tabBox->nextClientFocusChain(start);
|
TabBoxClient* c = tabBox->nextClientFocusChain(start).data();
|
||||||
TabBoxClient* stop = c;
|
TabBoxClient* stop = c;
|
||||||
while (c) {
|
while (c) {
|
||||||
TabBoxClient* add = tabBox->clientToAddToList(c, desktop);
|
QWeakPointer<TabBoxClient> add = tabBox->clientToAddToList(c, desktop);
|
||||||
if (add != NULL) {
|
if (!add.isNull()) {
|
||||||
if (start == add) {
|
if (start == add.data()) {
|
||||||
m_clientList.removeAll(add);
|
m_clientList.removeAll(add);
|
||||||
m_clientList.prepend(add);
|
m_clientList.prepend(add);
|
||||||
} else
|
} else
|
||||||
m_clientList += add;
|
m_clientList += add;
|
||||||
if (add->isFirstInTabBox()) {
|
if (add.data()->isFirstInTabBox()) {
|
||||||
stickyClients << add;
|
stickyClients << add;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
c = tabBox->nextClientFocusChain(c);
|
c = tabBox->nextClientFocusChain(c).data();
|
||||||
|
|
||||||
if (c == stop)
|
if (c == stop)
|
||||||
break;
|
break;
|
||||||
|
@ -199,25 +208,25 @@ void ClientModel::createClientList(int desktop, bool partialReset)
|
||||||
case TabBoxConfig::StackingOrderSwitching: {
|
case TabBoxConfig::StackingOrderSwitching: {
|
||||||
// TODO: needs improvement
|
// TODO: needs improvement
|
||||||
TabBoxClientList stacking = tabBox->stackingOrder();
|
TabBoxClientList stacking = tabBox->stackingOrder();
|
||||||
TabBoxClient* c = stacking.first();
|
TabBoxClient* c = stacking.first().data();
|
||||||
TabBoxClient* stop = c;
|
TabBoxClient* stop = c;
|
||||||
int index = 0;
|
int index = 0;
|
||||||
while (c) {
|
while (c) {
|
||||||
TabBoxClient* add = tabBox->clientToAddToList(c, desktop);
|
QWeakPointer<TabBoxClient> add = tabBox->clientToAddToList(c, desktop);
|
||||||
if (add != NULL) {
|
if (!add.isNull()) {
|
||||||
if (start == add) {
|
if (start == add.data()) {
|
||||||
m_clientList.removeAll(add);
|
m_clientList.removeAll(add);
|
||||||
m_clientList.prepend(add);
|
m_clientList.prepend(add);
|
||||||
} else
|
} else
|
||||||
m_clientList += add;
|
m_clientList += add;
|
||||||
if (add->isFirstInTabBox()) {
|
if (add.data()->isFirstInTabBox()) {
|
||||||
stickyClients << add;
|
stickyClients << add;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (index >= stacking.size() - 1) {
|
if (index >= stacking.size() - 1) {
|
||||||
c = NULL;
|
c = NULL;
|
||||||
} else {
|
} else {
|
||||||
c = stacking[++index];
|
c = stacking[++index].data();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c == stop)
|
if (c == stop)
|
||||||
|
@ -226,13 +235,13 @@ void ClientModel::createClientList(int desktop, bool partialReset)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
foreach (TabBoxClient *c, stickyClients) {
|
foreach (QWeakPointer< TabBoxClient > c, stickyClients) {
|
||||||
m_clientList.removeAll(c);
|
m_clientList.removeAll(c);
|
||||||
m_clientList.prepend(c);
|
m_clientList.prepend(c);
|
||||||
}
|
}
|
||||||
if (tabBox->config().showDesktopMode() == TabBoxConfig::ShowDesktopClient || m_clientList.isEmpty()) {
|
if (tabBox->config().showDesktopMode() == TabBoxConfig::ShowDesktopClient || m_clientList.isEmpty()) {
|
||||||
TabBoxClient* desktopClient = tabBox->desktopClient();
|
QWeakPointer<TabBoxClient> desktopClient = tabBox->desktopClient();
|
||||||
if (desktopClient)
|
if (!desktopClient.isNull())
|
||||||
m_clientList.append(desktopClient);
|
m_clientList.append(desktopClient);
|
||||||
}
|
}
|
||||||
reset();
|
reset();
|
||||||
|
@ -244,7 +253,10 @@ void ClientModel::close(int i)
|
||||||
if (!ind.isValid()) {
|
if (!ind.isValid()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
m_clientList.at(i)->close();
|
QSharedPointer<TabBoxClient> client = m_clientList.at(i).toStrongRef();
|
||||||
|
if (client) {
|
||||||
|
client->close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClientModel::activate(int i)
|
void ClientModel::activate(int i)
|
||||||
|
|
|
@ -71,7 +71,7 @@ public:
|
||||||
* @return Returns the ModelIndex of given TabBoxClient or an invalid ModelIndex
|
* @return Returns the ModelIndex of given TabBoxClient or an invalid ModelIndex
|
||||||
* if the model does not contain the given TabBoxClient.
|
* if the model does not contain the given TabBoxClient.
|
||||||
*/
|
*/
|
||||||
QModelIndex index(TabBoxClient* client) const;
|
QModelIndex index(QWeakPointer<TabBoxClient> client) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates a new list of TabBoxClients based on the current config.
|
* Generates a new list of TabBoxClients based on the current config.
|
||||||
|
|
|
@ -93,14 +93,14 @@ QString TabBoxHandlerImpl::desktopName(int desktop) const
|
||||||
return Workspace::self()->desktopName(desktop);
|
return Workspace::self()->desktopName(desktop);
|
||||||
}
|
}
|
||||||
|
|
||||||
TabBoxClient* TabBoxHandlerImpl::nextClientFocusChain(TabBoxClient* client) const
|
QWeakPointer<TabBoxClient> TabBoxHandlerImpl::nextClientFocusChain(TabBoxClient* client) const
|
||||||
{
|
{
|
||||||
if (TabBoxClientImpl* c = static_cast< TabBoxClientImpl* >(client)) {
|
if (TabBoxClientImpl* c = static_cast< TabBoxClientImpl* >(client)) {
|
||||||
Client* next = Workspace::self()->tabBox()->nextClientFocusChain(c->client());
|
Client* next = Workspace::self()->tabBox()->nextClientFocusChain(c->client());
|
||||||
if (next)
|
if (next)
|
||||||
return next->tabBoxClient();
|
return next->tabBoxClient();
|
||||||
}
|
}
|
||||||
return NULL;
|
return QWeakPointer<TabBoxClient>();
|
||||||
}
|
}
|
||||||
|
|
||||||
int TabBoxHandlerImpl::nextDesktopFocusChain(int desktop) const
|
int TabBoxHandlerImpl::nextDesktopFocusChain(int desktop) const
|
||||||
|
@ -113,12 +113,12 @@ int TabBoxHandlerImpl::numberOfDesktops() const
|
||||||
return Workspace::self()->numberOfDesktops();
|
return Workspace::self()->numberOfDesktops();
|
||||||
}
|
}
|
||||||
|
|
||||||
TabBoxClient* TabBoxHandlerImpl::activeClient() const
|
QWeakPointer<TabBoxClient> TabBoxHandlerImpl::activeClient() const
|
||||||
{
|
{
|
||||||
if (Workspace::self()->activeClient())
|
if (Workspace::self()->activeClient())
|
||||||
return Workspace::self()->activeClient()->tabBoxClient();
|
return Workspace::self()->activeClient()->tabBoxClient();
|
||||||
else
|
else
|
||||||
return NULL;
|
return QWeakPointer<TabBoxClient>();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TabBoxHandlerImpl::checkDesktop(TabBoxClient* client, int desktop) const
|
bool TabBoxHandlerImpl::checkDesktop(TabBoxClient* client, int desktop) const
|
||||||
|
@ -153,26 +153,35 @@ bool TabBoxHandlerImpl::checkApplications(TabBoxClient* client) const
|
||||||
{
|
{
|
||||||
Client* current = (static_cast< TabBoxClientImpl* >(client))->client();
|
Client* current = (static_cast< TabBoxClientImpl* >(client))->client();
|
||||||
TabBoxClientImpl* c;
|
TabBoxClientImpl* c;
|
||||||
QListIterator< TabBoxClient* > i(clientList());
|
QListIterator< QWeakPointer<TabBoxClient> > i(clientList());
|
||||||
|
|
||||||
switch (config().clientApplicationsMode()) {
|
switch (config().clientApplicationsMode()) {
|
||||||
case TabBoxConfig::OneWindowPerApplication:
|
case TabBoxConfig::OneWindowPerApplication:
|
||||||
// check if the list already contains an entry of this application
|
// check if the list already contains an entry of this application
|
||||||
while (i.hasNext()) {
|
while (i.hasNext()) {
|
||||||
if ((c = dynamic_cast< TabBoxClientImpl* >(i.next()))) {
|
QSharedPointer<TabBoxClient> client = i.next().toStrongRef();
|
||||||
|
if (!client) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ((c = dynamic_cast< TabBoxClientImpl* >(client.data()))) {
|
||||||
if (c->client()->resourceClass() == current->resourceClass()) {
|
if (c->client()->resourceClass() == current->resourceClass()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
case TabBoxConfig::AllWindowsCurrentApplication:
|
case TabBoxConfig::AllWindowsCurrentApplication: {
|
||||||
if ((c = dynamic_cast< TabBoxClientImpl* >(tabBox->activeClient()))) {
|
QSharedPointer<TabBoxClient> pointer = tabBox->activeClient().toStrongRef();
|
||||||
|
if (!pointer) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if ((c = dynamic_cast< TabBoxClientImpl* >(pointer.data()))) {
|
||||||
if (c->client()->resourceClass() == current->resourceClass()) {
|
if (c->client()->resourceClass() == current->resourceClass()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
default: // TabBoxConfig::AllWindowsAllApplications
|
default: // TabBoxConfig::AllWindowsAllApplications
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -205,7 +214,7 @@ bool TabBoxHandlerImpl::checkMultiScreen(TabBoxClient* client) const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TabBoxClient* TabBoxHandlerImpl::clientToAddToList(TabBoxClient* client, int desktop) const
|
QWeakPointer<TabBoxClient> TabBoxHandlerImpl::clientToAddToList(TabBoxClient* client, int desktop) const
|
||||||
{
|
{
|
||||||
Client* ret = NULL;
|
Client* ret = NULL;
|
||||||
Client* current = (static_cast< TabBoxClientImpl* >(client))->client();
|
Client* current = (static_cast< TabBoxClientImpl* >(client))->client();
|
||||||
|
@ -230,7 +239,7 @@ TabBoxClient* TabBoxHandlerImpl::clientToAddToList(TabBoxClient* client, int des
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret->tabBoxClient();
|
return ret->tabBoxClient();
|
||||||
else
|
else
|
||||||
return NULL;
|
return QWeakPointer<TabBoxClient>();
|
||||||
}
|
}
|
||||||
|
|
||||||
TabBoxClientList TabBoxHandlerImpl::stackingOrder() const
|
TabBoxClientList TabBoxHandlerImpl::stackingOrder() const
|
||||||
|
@ -268,7 +277,7 @@ void TabBoxHandlerImpl::elevateClient(TabBoxClient *c, WId tabbox, bool b) const
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
TabBoxClient* TabBoxHandlerImpl::desktopClient() const
|
QWeakPointer<TabBoxClient> TabBoxHandlerImpl::desktopClient() const
|
||||||
{
|
{
|
||||||
foreach (Toplevel *toplevel, Workspace::self()->stackingOrder()) {
|
foreach (Toplevel *toplevel, Workspace::self()->stackingOrder()) {
|
||||||
Client *client = qobject_cast<Client*>(toplevel);
|
Client *client = qobject_cast<Client*>(toplevel);
|
||||||
|
@ -276,7 +285,7 @@ TabBoxClient* TabBoxHandlerImpl::desktopClient() const
|
||||||
return client->tabBoxClient();
|
return client->tabBoxClient();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return NULL;
|
return QWeakPointer<TabBoxClient>();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TabBoxHandlerImpl::showOutline(const QRect &outline)
|
void TabBoxHandlerImpl::showOutline(const QRect &outline)
|
||||||
|
@ -575,8 +584,11 @@ ClientList TabBox::currentClientList()
|
||||||
{
|
{
|
||||||
TabBoxClientList list = m_tabBox->clientList();
|
TabBoxClientList list = m_tabBox->clientList();
|
||||||
ClientList ret;
|
ClientList ret;
|
||||||
foreach (const TabBoxClient * client, list) {
|
foreach (QWeakPointer<TabBoxClient> clientPointer, list) {
|
||||||
if (const TabBoxClientImpl* c = static_cast< const TabBoxClientImpl* >(client))
|
QSharedPointer<TabBoxClient> client = clientPointer.toStrongRef();
|
||||||
|
if (!client)
|
||||||
|
continue;
|
||||||
|
if (const TabBoxClientImpl* c = static_cast< const TabBoxClientImpl* >(client.data()))
|
||||||
ret.append(c->client());
|
ret.append(c->client());
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
@ -46,19 +46,19 @@ public:
|
||||||
virtual ~TabBoxHandlerImpl();
|
virtual ~TabBoxHandlerImpl();
|
||||||
|
|
||||||
virtual int activeScreen() const;
|
virtual int activeScreen() const;
|
||||||
virtual TabBoxClient* activeClient() const;
|
virtual QWeakPointer< TabBoxClient > activeClient() const;
|
||||||
virtual int currentDesktop() const;
|
virtual int currentDesktop() const;
|
||||||
virtual QString desktopName(TabBoxClient* client) const;
|
virtual QString desktopName(TabBoxClient* client) const;
|
||||||
virtual QString desktopName(int desktop) const;
|
virtual QString desktopName(int desktop) const;
|
||||||
virtual TabBoxClient* nextClientFocusChain(TabBoxClient* client) const;
|
virtual QWeakPointer< TabBoxClient > nextClientFocusChain(TabBoxClient* client) const;
|
||||||
virtual int nextDesktopFocusChain(int desktop) const;
|
virtual int nextDesktopFocusChain(int desktop) const;
|
||||||
virtual int numberOfDesktops() const;
|
virtual int numberOfDesktops() const;
|
||||||
virtual TabBoxClientList stackingOrder() const;
|
virtual TabBoxClientList stackingOrder() const;
|
||||||
virtual void elevateClient(TabBoxClient* c, WId tabbox, bool elevate) const;
|
virtual void elevateClient(TabBoxClient* c, WId tabbox, bool elevate) const;
|
||||||
virtual void raiseClient(TabBoxClient *client) const;
|
virtual void raiseClient(TabBoxClient *client) const;
|
||||||
virtual void restack(TabBoxClient *c, TabBoxClient *under);
|
virtual void restack(TabBoxClient *c, TabBoxClient *under);
|
||||||
virtual TabBoxClient* clientToAddToList(TabBoxClient* client, int desktop) const;
|
virtual QWeakPointer< TabBoxClient > clientToAddToList(KWin::TabBox::TabBoxClient* client, int desktop) const;
|
||||||
virtual TabBoxClient* desktopClient() const;
|
virtual QWeakPointer< TabBoxClient > desktopClient() const;
|
||||||
virtual void hideOutline();
|
virtual void hideOutline();
|
||||||
virtual void showOutline(const QRect &outline);
|
virtual void showOutline(const QRect &outline);
|
||||||
virtual QVector< Window > outlineWindowIds() const;
|
virtual QVector< Window > outlineWindowIds() const;
|
||||||
|
|
|
@ -158,8 +158,14 @@ void TabBoxHandlerPrivate::updateHighlightWindows()
|
||||||
// TODO if ( (lastRaisedClientWasMinimized = lastRaisedClient->isMinimized()) )
|
// TODO if ( (lastRaisedClientWasMinimized = lastRaisedClient->isMinimized()) )
|
||||||
// lastRaisedClient->setMinimized( false );
|
// lastRaisedClient->setMinimized( false );
|
||||||
TabBoxClientList order = q->stackingOrder();
|
TabBoxClientList order = q->stackingOrder();
|
||||||
int succIdx = order.indexOf(lastRaisedClient) + 1; // this is likely related to the index parameter?!
|
int succIdx = order.count() + 1;
|
||||||
lastRaisedClientSucc = (succIdx < order.count()) ? order.at(succIdx) : 0;
|
for (int i=0; i<order.count(); ++i) {
|
||||||
|
if (order.at(i).data() == lastRaisedClient) {
|
||||||
|
succIdx = i + 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lastRaisedClientSucc = (succIdx < order.count()) ? order.at(succIdx).data() : 0;
|
||||||
q->raiseClient(lastRaisedClient);
|
q->raiseClient(lastRaisedClient);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -415,7 +421,7 @@ bool TabBoxHandler::containsPos(const QPoint& pos) const
|
||||||
return w->geometry().contains(pos);
|
return w->geometry().contains(pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
QModelIndex TabBoxHandler::index(KWin::TabBox::TabBoxClient* client) const
|
QModelIndex TabBoxHandler::index(QWeakPointer<KWin::TabBox::TabBoxClient> client) const
|
||||||
{
|
{
|
||||||
return d->clientModel()->index(client);
|
return d->clientModel()->index(client);
|
||||||
}
|
}
|
||||||
|
@ -440,13 +446,29 @@ TabBoxClient* TabBoxHandler::client(const QModelIndex& index) const
|
||||||
void TabBoxHandler::createModel(bool partialReset)
|
void TabBoxHandler::createModel(bool partialReset)
|
||||||
{
|
{
|
||||||
switch(d->config.tabBoxMode()) {
|
switch(d->config.tabBoxMode()) {
|
||||||
case TabBoxConfig::ClientTabBox:
|
case TabBoxConfig::ClientTabBox: {
|
||||||
d->clientModel()->createClientList(partialReset);
|
d->clientModel()->createClientList(partialReset);
|
||||||
if (d->lastRaisedClient && !stackingOrder().contains(d->lastRaisedClient))
|
// TODO: C++11 use lambda function
|
||||||
|
bool lastRaised = false;
|
||||||
|
bool lastRaisedSucc = false;
|
||||||
|
foreach (QWeakPointer<TabBoxClient> clientPointer, stackingOrder()) {
|
||||||
|
QSharedPointer<TabBoxClient> client = clientPointer.toStrongRef();
|
||||||
|
if (!client) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (client.data() == d->lastRaisedClient) {
|
||||||
|
lastRaised = true;
|
||||||
|
}
|
||||||
|
if (client.data() == d->lastRaisedClientSucc) {
|
||||||
|
lastRaisedSucc = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (d->lastRaisedClient && !lastRaised)
|
||||||
d->lastRaisedClient = 0;
|
d->lastRaisedClient = 0;
|
||||||
if (d->lastRaisedClientSucc && !stackingOrder().contains(d->lastRaisedClientSucc))
|
if (d->lastRaisedClientSucc && !lastRaisedSucc)
|
||||||
d->lastRaisedClientSucc = 0;
|
d->lastRaisedClientSucc = 0;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case TabBoxConfig::DesktopTabBox:
|
case TabBoxConfig::DesktopTabBox:
|
||||||
d->desktopModel()->createDesktopList();
|
d->desktopModel()->createDesktopList();
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -81,7 +81,7 @@ class ClientModel;
|
||||||
class TabBoxConfig;
|
class TabBoxConfig;
|
||||||
class TabBoxClient;
|
class TabBoxClient;
|
||||||
class TabBoxHandlerPrivate;
|
class TabBoxHandlerPrivate;
|
||||||
typedef QList< TabBoxClient* > TabBoxClientList;
|
typedef QList< QWeakPointer< TabBoxClient > > TabBoxClientList;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class is a wrapper around KWin Workspace. It is used for accessing the
|
* This class is a wrapper around KWin Workspace. It is used for accessing the
|
||||||
|
@ -105,12 +105,12 @@ public:
|
||||||
* @return The current active TabBoxClient or NULL
|
* @return The current active TabBoxClient or NULL
|
||||||
* if there is no active client.
|
* if there is no active client.
|
||||||
*/
|
*/
|
||||||
virtual TabBoxClient* activeClient() const = 0;
|
virtual QWeakPointer<TabBoxClient> activeClient() const = 0;
|
||||||
/**
|
/**
|
||||||
* @param client The client which is starting point to find the next client
|
* @param client The client which is starting point to find the next client
|
||||||
* @return The next TabBoxClient in focus chain
|
* @return The next TabBoxClient in focus chain
|
||||||
*/
|
*/
|
||||||
virtual TabBoxClient* nextClientFocusChain(TabBoxClient* client) const = 0;
|
virtual QWeakPointer<TabBoxClient> nextClientFocusChain(TabBoxClient* client) const = 0;
|
||||||
/**
|
/**
|
||||||
* @param client The client whose desktop name should be retrieved
|
* @param client The client whose desktop name should be retrieved
|
||||||
* @return The desktop name of the given TabBoxClient. If the client is
|
* @return The desktop name of the given TabBoxClient. If the client is
|
||||||
|
@ -172,11 +172,11 @@ public:
|
||||||
* @param allDesktops Add clients from all desktops or only from current
|
* @param allDesktops Add clients from all desktops or only from current
|
||||||
* @return The client to be included in the list or NULL if it isn't to be included
|
* @return The client to be included in the list or NULL if it isn't to be included
|
||||||
*/
|
*/
|
||||||
virtual TabBoxClient* clientToAddToList(TabBoxClient* client, int desktop) const = 0;
|
virtual QWeakPointer<TabBoxClient> clientToAddToList(TabBoxClient* client, int desktop) const = 0;
|
||||||
/**
|
/**
|
||||||
* @return The first desktop window in the stacking order.
|
* @return The first desktop window in the stacking order.
|
||||||
*/
|
*/
|
||||||
virtual TabBoxClient* desktopClient() const = 0;
|
virtual QWeakPointer<TabBoxClient> desktopClient() const = 0;
|
||||||
/**
|
/**
|
||||||
* Activates the currently selected client and closes the TabBox.
|
* Activates the currently selected client and closes the TabBox.
|
||||||
**/
|
**/
|
||||||
|
@ -278,7 +278,7 @@ public:
|
||||||
* if the model does not contain the given TabBoxClient.
|
* if the model does not contain the given TabBoxClient.
|
||||||
* @see ClientModel::index
|
* @see ClientModel::index
|
||||||
*/
|
*/
|
||||||
QModelIndex index(TabBoxClient* client) const;
|
QModelIndex index(QWeakPointer<TabBoxClient> client) const;
|
||||||
/**
|
/**
|
||||||
* @return Returns the current list of TabBoxClients.
|
* @return Returns the current list of TabBoxClients.
|
||||||
* If TabBoxMode is not TabBoxConfig::ClientTabBox an empty list will
|
* If TabBoxMode is not TabBoxConfig::ClientTabBox an empty list will
|
||||||
|
|
Loading…
Reference in a new issue