11#include <config-kwin.h>
21#include <QQmlComponent>
25#include <QQuickWindow>
26#include <QStandardPaths>
28#include <qpa/qwindowsysteminterface.h>
30#include <KLocalizedString>
31#include <KPackage/Package>
32#include <KPackage/PackageLoader>
57 QQuickWindow *
window()
const;
81 QObject *createSwitcherItem();
86 , m_qmlComponent(nullptr)
107 if (QQuickWindow *w = qobject_cast<QQuickWindow *>(
m_mainItem)) {
110 return m_mainItem->findChild<QQuickWindow *>();
113#ifndef KWIN_UNIT_TEST
121 }
else if (QQuickWindow *w = qobject_cast<QQuickWindow *>(
m_mainItem)) {
135 const QQuickWindow *w =
window();
136 if (w && w->visibility() == QWindow::FullScreen) {
158 if (currentClient && (!desktop || currentClient->
internalId() != desktop->internalId())) {
176 int succIdx = order.count() + 1;
177 for (
int i = 0; i < order.count(); ++i) {
201 if (
window != currentClient) {
219#ifndef KWIN_UNIT_TEST
220QObject *TabBoxHandlerPrivate::createSwitcherItem()
223 QString file = QStandardPaths::locate(
224 QStandardPaths::GenericDataLocation,
225 QStringLiteral(
"plasma/look-and-feel/%1/contents/windowswitcher/WindowSwitcher.qml").arg(
config.
layoutName()));
227 const QString
type = QStringLiteral(
"KWin/WindowSwitcher");
229 KPackage::Package pkg = KPackage::PackageLoader::self()->loadPackage(
type,
config.
layoutName());
231 if (!pkg.isValid()) {
233 qCWarning(KWIN_TABBOX) <<
"Could not load window switcher package" <<
config.
layoutName() <<
". Falling back to default";
237 file = pkg.filePath(
"mainscript");
240 qCDebug(KWIN_TABBOX) <<
"Could not find QML file for window switcher";
245 qCWarning(KWIN_TABBOX) <<
"Component failed to load: " <<
m_qmlComponent->errors();
247 args << QStringLiteral(
"--passivepopup") << i18n(
"The Window Switcher installation is broken, resources are missing.\n"
248 "Contact your distribution about this.")
249 << QStringLiteral(
"20");
250 KProcess::startDetached(QStringLiteral(
"kdialog"), args);
263#ifndef KWIN_UNIT_TEST
265 qmlRegisterType<SwitcherItem>(
"org.kde.kwin", 3, 0,
"TabBoxSwitcher");
271 auto findMainItem = [
this](
const QMap<QString, QObject *> &tabBoxes) -> QObject * {
273 if (it != tabBoxes.constEnd()) {
289 int indexRow =
index.row();
290 if (!item->model()) {
294 item->setCurrentIndex(indexRow);
296 Q_EMIT item->aboutToShow();
300 if (!item->isVisible()) {
301 if (QQuickWindow *w = window()) {
310 item->setVisible(
true);
312 if (QWindow *w = window()) {
314 w->installEventFilter(q);
316#if QT_VERSION < QT_VERSION_CHECK(6, 7, 0)
317 QWindowSystemInterface::handleWindowActivated(w, Qt::TabFocusReason);
319 QWindowSystemInterface::handleFocusWindowChanged(w, Qt::TabFocusReason);
365 QTimer::singleShot(1,
this, &TabBoxHandler::initHighlightWindows);
369void TabBoxHandler::initHighlightWindows()
373 for (
Window *window : stack) {
386#ifndef KWIN_UNIT_TEST
388 Q_EMIT item->aboutToHide();
389 if (item->automaticallyHide()) {
390 item->setVisible(
false);
401 int column = d->
index.column() + 1;
402 int row = d->
index.row();
403 if (column == model->columnCount()) {
406 if (row == model->rowCount()) {
410 ret = model->index(row, column);
411 if (!ret.isValid()) {
412 ret = model->index(0, 0);
415 int column = d->
index.column() - 1;
416 int row = d->
index.row();
418 column = model->columnCount() - 1;
421 row = model->rowCount() - 1;
424 ret = model->index(row, column);
425 if (!ret.isValid()) {
426 row = model->rowCount() - 1;
427 for (
int i = model->columnCount() - 1; i >= 0; i--) {
428 ret = model->index(row, i);
447 if (!
index.isValid()) {
467 QCoreApplication::sendEvent(d->
window(), event);
477 return w->geometry().contains(pos);
494 if (!
index.isValid()) {
506 bool lastRaised =
false;
507 bool lastRaisedSucc =
false;
509 for (
Window *window : clients) {
514 lastRaisedSucc =
true;
532 if (e->type() == QEvent::Wheel && watched == d->
window()) {
533 QWheelEvent *
event =
static_cast<QWheelEvent *
>(e);
535 const int delta = std::abs(event->angleDelta().x()) > std::abs(event->angleDelta().y()) ?
event->angleDelta().x() :
event->angleDelta().y();
540 if (
index.isValid()) {
547 if (
index.isValid()) {
554 return QObject::eventFilter(watched, e);
562#include "moc_tabboxhandler.cpp"
static Scripting * self()
QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const override
QList< Window * > clientList() const
QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const override
void createClientList(bool partialReset=false)
bool isHighlightWindows() const
ClientDesktopMode clientDesktopMode() const
@ AllDesktopsClients
Windows from all desktops are included.
static QString defaultLayoutName()
bool isShowTabBox() const
QString & layoutName() const
void createModel(bool partialReset=false)
virtual void raiseClient(Window *c) const =0
virtual Window * desktopClient() const =0
const QModelIndex & currentIndex() const
bool containsPos(const QPoint &pos) const
virtual void highlightWindows(Window *window=nullptr, QWindow *controller=nullptr)=0
virtual void shadeClient(Window *c, bool b) const =0
void setConfig(const TabBoxConfig &config)
void hide(bool abort=false)
QList< Window * > clientList() const
virtual void grabbedKeyEvent(QKeyEvent *event) const
QModelIndex nextPrev(bool forward) const
bool eventFilter(QObject *watcher, QEvent *event) override
Window * client(const QModelIndex &index) const
virtual bool noModifierGrab() const =0
virtual QList< Window * > stackingOrder() const =0
void selectedIndexChanged()
QModelIndex index(Window *client) const
const TabBoxConfig & config() const
~TabBoxHandler() override
void setCurrentIndex(const QModelIndex &index)
virtual void restack(Window *c, Window *under)=0
virtual void elevateClient(Window *c, QWindow *tabbox, bool elevate) const =0
friend class TabBoxHandlerPrivate
virtual bool isKWinCompositing() const =0
QModelIndex first() const
TabBoxHandler(QObject *parent)
ClientModel * clientModel() const
void endHighlightWindows(bool abort=false)
Window * lastRaisedClientSucc
ClientModel * m_clientModel
bool isHighlightWindows() const
std::unique_ptr< QQmlContext > m_qmlContext
QQuickWindow * window() const
TabBoxHandlerPrivate(TabBoxHandler *q)
QMap< QString, QObject * > m_clientTabBoxes
void updateHighlightWindows()
std::unique_ptr< QQmlComponent > m_qmlComponent
SwitcherItem * switcherItem() const
Window * lastRaisedClient