TabBox: Allow switchers to handle the tabbox hiding

Previously, the switcher item got hidden immediately after
selecting a window, so it wasn't possible to show an exit
transition.

Emit instead an `aboutToHide` signal and let the switchers
that opt-in to handle when to hide the tabbox by just setting
its `visible` property to `false`. In the default case we handle
that signal by immediately hiding the tabbox as usual.

For symmetry, add also a new `aboutToShow` signal which
simplifies setting an enter transition.
This commit is contained in:
Ismael Asensio 2022-07-10 21:21:04 +02:00
parent 98198dc77a
commit 9d8d7e28a1
4 changed files with 44 additions and 7 deletions

View file

@ -114,6 +114,9 @@ Q_SIGNALS:
void screenGeometryChanged(); void screenGeometryChanged();
void itemChanged(); void itemChanged();
void aboutToShow();
void aboutToHide();
private: private:
QAbstractItemModel *m_model; QAbstractItemModel *m_model;
QObject *m_item; QObject *m_item;

View file

@ -27,6 +27,7 @@ SwitcherItem::SwitcherItem(QObject *parent)
, m_visible(false) , m_visible(false)
, m_allDesktops(false) , m_allDesktops(false)
, m_currentIndex(0) , m_currentIndex(0)
, m_automaticallyHide(false)
{ {
m_selectedIndexConnection = connect(tabBox, &TabBoxHandler::selectedIndexChanged, this, [this] { m_selectedIndexConnection = connect(tabBox, &TabBoxHandler::selectedIndexChanged, this, [this] {
if (isVisible()) { if (isVisible()) {
@ -104,6 +105,20 @@ void SwitcherItem::setNoModifierGrab(bool set)
Q_EMIT noModifierGrabChanged(); Q_EMIT noModifierGrabChanged();
} }
bool SwitcherItem::automaticallyHide() const
{
return m_automaticallyHide;
}
void SwitcherItem::setAutomaticallyHide(bool value)
{
if (m_automaticallyHide == value) {
return;
}
m_automaticallyHide = value;
Q_EMIT automaticallyHideChanged();
}
bool SwitcherItem::compositing() bool SwitcherItem::compositing()
{ {
return Compositor::compositing(); return Compositor::compositing();

View file

@ -23,11 +23,12 @@ class SwitcherItem : public QObject
Q_OBJECT Q_OBJECT
Q_PROPERTY(QAbstractItemModel *model READ model NOTIFY modelChanged) Q_PROPERTY(QAbstractItemModel *model READ model NOTIFY modelChanged)
Q_PROPERTY(QRect screenGeometry READ screenGeometry NOTIFY screenGeometryChanged) Q_PROPERTY(QRect screenGeometry READ screenGeometry NOTIFY screenGeometryChanged)
Q_PROPERTY(bool visible READ isVisible NOTIFY visibleChanged) Q_PROPERTY(bool visible READ isVisible WRITE setVisible NOTIFY visibleChanged)
Q_PROPERTY(bool allDesktops READ isAllDesktops NOTIFY allDesktopsChanged) Q_PROPERTY(bool allDesktops READ isAllDesktops NOTIFY allDesktopsChanged)
Q_PROPERTY(int currentIndex READ currentIndex WRITE setCurrentIndex NOTIFY currentIndexChanged) Q_PROPERTY(int currentIndex READ currentIndex WRITE setCurrentIndex NOTIFY currentIndexChanged)
Q_PROPERTY(bool noModifierGrab READ noModifierGrab NOTIFY noModifierGrabChanged) Q_PROPERTY(bool noModifierGrab READ noModifierGrab NOTIFY noModifierGrabChanged)
Q_PROPERTY(bool compositing READ compositing NOTIFY compositingChanged) Q_PROPERTY(bool compositing READ compositing NOTIFY compositingChanged)
Q_PROPERTY(bool automaticallyHide READ automaticallyHide WRITE setAutomaticallyHide NOTIFY automaticallyHideChanged)
/** /**
* The main QML item that will be displayed in the Dialog * The main QML item that will be displayed in the Dialog
@ -52,12 +53,14 @@ public:
return m_noModifierGrab; return m_noModifierGrab;
} }
bool compositing(); bool compositing();
bool automaticallyHide() const;
// for usage from outside // for usage from outside
void setModel(QAbstractItemModel *model); void setModel(QAbstractItemModel *model);
void setAllDesktops(bool all); void setAllDesktops(bool all);
void setVisible(bool visible); void setVisible(bool visible);
void setNoModifierGrab(bool set); void setNoModifierGrab(bool set);
void setAutomaticallyHide(bool value);
Q_SIGNALS: Q_SIGNALS:
void visibleChanged(); void visibleChanged();
@ -68,6 +71,10 @@ Q_SIGNALS:
void itemChanged(); void itemChanged();
void noModifierGrabChanged(); void noModifierGrabChanged();
void compositingChanged(); void compositingChanged();
void automaticallyHideChanged();
void aboutToShow();
void aboutToHide();
private: private:
QAbstractItemModel *m_model; QAbstractItemModel *m_model;
@ -77,6 +84,7 @@ private:
int m_currentIndex; int m_currentIndex;
QMetaObject::Connection m_selectedIndexConnection; QMetaObject::Connection m_selectedIndexConnection;
bool m_noModifierGrab = false; bool m_noModifierGrab = false;
bool m_automaticallyHide = true;
}; };
inline QAbstractItemModel *SwitcherItem::model() const inline QAbstractItemModel *SwitcherItem::model() const

View file

@ -316,6 +316,19 @@ void TabBoxHandlerPrivate::show()
item->setAllDesktops(config.clientDesktopMode() == TabBoxConfig::AllDesktopsClients); item->setAllDesktops(config.clientDesktopMode() == TabBoxConfig::AllDesktopsClients);
item->setCurrentIndex(indexRow); item->setCurrentIndex(indexRow);
item->setNoModifierGrab(q->noModifierGrab()); item->setNoModifierGrab(q->noModifierGrab());
Q_EMIT item->aboutToShow();
// When SwitcherItem gets hidden, destroy also the window and main item
QObject::connect(item, &SwitcherItem::visibleChanged, q, [this, item]() {
if (!item->isVisible()) {
if (QQuickWindow *w = window()) {
w->hide();
w->destroy();
}
m_mainItem = nullptr;
}
});
// everything is prepared, so let's make the whole thing visible // everything is prepared, so let's make the whole thing visible
item->setVisible(true); item->setVisible(true);
} }
@ -391,14 +404,12 @@ void TabBoxHandler::hide(bool abort)
} }
#ifndef KWIN_UNIT_TEST #ifndef KWIN_UNIT_TEST
if (SwitcherItem *item = d->switcherItem()) { if (SwitcherItem *item = d->switcherItem()) {
Q_EMIT item->aboutToHide();
if (item->automaticallyHide()) {
item->setVisible(false); item->setVisible(false);
} }
#endif
if (QQuickWindow *w = d->window()) {
w->hide();
w->destroy();
} }
d->m_mainItem = nullptr; #endif
} }
QModelIndex TabBoxHandler::nextPrev(bool forward) const QModelIndex TabBoxHandler::nextPrev(bool forward) const