File indexing completed on 2024-04-21 05:46:37

0001 // SPDX-License-Identifier: GPL-3.0-or-later
0002 /*
0003   Copyright 2017, 2018 Martin Koller, kollix@aon.at
0004 
0005   This file is part of liquidshell.
0006 
0007   liquidshell is free software: you can redistribute it and/or modify
0008   it under the terms of the GNU General Public License as published by
0009   the Free Software Foundation, either version 3 of the License, or
0010   (at your option) any later version.
0011 
0012   liquidshell is distributed in the hope that it will be useful,
0013   but WITHOUT ANY WARRANTY; without even the implied warranty of
0014   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
0015   GNU General Public License for more details.
0016 
0017   You should have received a copy of the GNU General Public License
0018   along with liquidshell.  If not, see <http://www.gnu.org/licenses/>.
0019 */
0020 
0021 #include <Pager.hxx>
0022 #include <PagerButton.hxx>
0023 #include <DesktopPanel.hxx>
0024 #include <KWinCompat.hxx>
0025 
0026 #include <QGridLayout>
0027 #include <QButtonGroup>
0028 #include <QPushButton>
0029 #include <QX11Info>
0030 #include <QAction>
0031 #include <QWheelEvent>
0032 #include <QDebug>
0033 
0034 #include <KLocalizedString>
0035 #include <KCMultiDialog>
0036 #include <KConfig>
0037 #include <KConfigGroup>
0038 #include <KPluginMetaData>
0039 #include <kcmutils_version.h>
0040 #include <netwm.h>
0041 
0042 //--------------------------------------------------------------------------------
0043 
0044 Pager::Pager(DesktopPanel *parent)
0045   : QWidget(parent)
0046 {
0047   group = new QButtonGroup(this);
0048 
0049   QGridLayout *grid = new QGridLayout(this);
0050   grid->setSpacing(2);
0051   grid->setContentsMargins(QMargins());
0052 
0053   connect(KWinCompat::self(), &KWinCompat::numberOfDesktopsChanged, this, &Pager::fill);
0054 
0055   connect(KWinCompat::self(), &KWinCompat::currentDesktopChanged,
0056           [this]()
0057           {
0058             if ( KWinCompat::currentDesktop() <= buttons.count() )
0059               buttons[KWinCompat::currentDesktop() - 1]->setChecked(true);
0060           }
0061          );
0062 
0063   connect(parent, &DesktopPanel::rowsChanged, this, &Pager::fill);
0064 
0065   KConfig config;
0066   KConfigGroup group = config.group("Pager");
0067   if ( !group.hasKey("showIcons") )  // create config entry so that one knows it exists
0068     group.writeEntry("showIcons", true);
0069 
0070   showIcons  = group.readEntry("showIcons", true);
0071 
0072   fill();
0073 
0074   QAction *action = new QAction(this);
0075   action->setIcon(QIcon::fromTheme("configure"));
0076   action->setText(i18n("Configure Virtual Desktops..."));
0077   addAction(action);
0078   connect(action, &QAction::triggered,
0079           [this]()
0080           {
0081             auto dialog = new KCMultiDialog(parentWidget());
0082             dialog->setAttribute(Qt::WA_DeleteOnClose);
0083             dialog->setWindowTitle(i18n("Configure Virtual Desktops"));
0084 
0085 #if KCMUTILS_VERSION >= QT_VERSION_CHECK(5, 85, 0)
0086             KPluginMetaData data("plasma/kcms/systemsettings/kcm_kwin_virtualdesktops");
0087 
0088             if ( !data.isValid() )
0089               data = KPluginMetaData::findPluginById("kcms", "kcm_kwin_virtualdesktops");
0090 
0091             if ( data.isValid() )
0092               dialog->addModule(data);
0093 #else
0094             {
0095               KCModuleInfo module("kcm_kwin_virtualdesktops");
0096               if ( module.service() )
0097                 dialog->addModule("kcm_kwin_virtualdesktops");
0098               else
0099                 dialog->addModule("desktop");  // in older KDE versions
0100             }
0101 #endif
0102 
0103             dialog->adjustSize();
0104             dialog->show();
0105           }
0106          );
0107   setContextMenuPolicy(Qt::ActionsContextMenu);
0108 }
0109 
0110 //--------------------------------------------------------------------------------
0111 
0112 void Pager::fill()
0113 {
0114   qDeleteAll(buttons);
0115   buttons.clear();
0116 
0117 #if QT_VERSION >= QT_VERSION_CHECK(5,15,0)
0118   NETRootInfo ri(QX11Info::connection(), NET::Property(), NET::WM2DesktopLayout);
0119 #else
0120   NETRootInfo ri(QX11Info::connection(), 0, NET::WM2DesktopLayout);
0121 #endif
0122 
0123   int row = 0, col = 0;
0124   const int MAX_COLUMNS = std::max(1, ri.desktopLayoutColumnsRows().width());
0125 
0126   for (int i = 1; i <= KWinCompat::numberOfDesktops(); i++)
0127   {
0128     PagerButton *b = new PagerButton(i, qobject_cast<DesktopPanel *>(parentWidget()), showIcons);
0129 
0130     b->setCheckable(true);
0131     b->setFocusPolicy(Qt::NoFocus);
0132     group->addButton(b);
0133     buttons.append(b);
0134 
0135     if ( i == KWinCompat::currentDesktop() )
0136       b->setChecked(true);
0137 
0138     connect(b, &PagerButton::clicked, this, &Pager::changeDesktop);
0139 
0140     static_cast<QGridLayout *>(layout())->addWidget(b, row, col);
0141     col = (col + 1) % MAX_COLUMNS;
0142     if ( col == 0 ) row++;
0143   }
0144 }
0145 
0146 //--------------------------------------------------------------------------------
0147 
0148 void Pager::changeDesktop(bool checked)
0149 {
0150   if ( !checked )
0151     return;
0152 
0153   int desktopNum = qobject_cast<PagerButton *>(sender())->getDesktop();
0154 
0155   if ( KWinCompat::currentDesktop() == desktopNum )
0156     KWindowSystem::setShowingDesktop(!KWindowSystem::showingDesktop());
0157   else
0158     KWinCompat::setCurrentDesktop(desktopNum);
0159 }
0160 
0161 //--------------------------------------------------------------------------------
0162 
0163 void Pager::wheelEvent(QWheelEvent *event)
0164 {
0165   int desktopNum = KWinCompat::currentDesktop() - 1 + KWinCompat::numberOfDesktops();
0166 
0167   if ( event->angleDelta().y() > 0 )
0168     desktopNum++;
0169   else
0170     desktopNum--;
0171 
0172   KWinCompat::setCurrentDesktop((desktopNum % KWinCompat::numberOfDesktops()) + 1);
0173 }
0174 
0175 //--------------------------------------------------------------------------------