diff --git a/CMakeLists.txt b/CMakeLists.txt
index b11fd72..896e93d 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,154 +1,155 @@
cmake_minimum_required(VERSION 2.8.12 FATAL_ERROR)
project(liquidshell)
find_package(ECM 1.3.0 REQUIRED NO_MODULE)
set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH})
include(KDEInstallDirs)
include(KDECompilerSettings NO_POLICY_SCOPE)
include(KDECMakeSettings)
include(ECMInstallIcons)
find_package(Qt5 5.6 CONFIG REQUIRED COMPONENTS
Core
Widgets
DBus
X11Extras
)
find_package(KF5 REQUIRED COMPONENTS
WindowSystem WidgetsAddons ConfigWidgets Config KIO IconThemes ItemViews Archive
Notifications I18n NetworkManagerQt Service Solid BluezQt KCMUtils Crash DBusAddons
NewStuff
)
set(SOURCES
desktop.cxx
DesktopWidget.cxx
DesktopPanel.cxx
OnScreenVolume.cxx
+ OnScreenBrightness.cxx
ConfigureDesktopDialog.cxx
StartMenu.cxx
Launcher.cxx
QuickLaunch.cxx
IconButton.cxx
AppMenu.cxx
Pager.cxx
PagerButton.cxx
WindowList.cxx
ClockWidget.cxx
ClockWidgetConfigureDialog.cxx
TaskBar.cxx
TaskBarButton.cxx
LockLogout.cxx
SysTray.cxx
SysTrayItem.cxx
SysTrayNotifyItem.cxx
DBusTypes.cxx
SysLoad.cxx
NotificationServer.cxx
NotificationList.cxx
Network.cxx
NetworkList.cxx
DeviceNotifier.cxx
DeviceList.cxx
Battery.cxx
Bluetooth.cxx
PopupMenu.cxx
KdeConnect.cxx
DesktopApplet.cxx
WeatherApplet.cxx
WeatherAppletConfigureDialog.cxx
DiskUsageApplet.cxx
DiskUsageAppletConfigureDialog.cxx
PictureFrameApplet.cxx
PictureFrameAppletConfigureDialog.cxx
)
find_package(packagekitqt5 QUIET)
if ( packagekitqt5_FOUND )
set(SOURCES ${SOURCES}
PkUpdates.cxx
PkUpdateList.cxx
)
add_definitions(-DWITH_PACKAGEKIT)
else()
message(WARNING "PackageKit integration not available. packagekitqt5 development files not found")
endif()
# e.g. on openSuse Leap 42.3 compile fails as a GLib header included uses signals as var
add_definitions(-DQT_NO_SIGNALS_SLOTS_KEYWORDS)
ki18n_wrap_ui(UI_FILES
ConfigureDesktopDialog.ui
WeatherAppletConfigureDialog.ui
DiskUsageAppletConfigureDialog.ui
PictureFrameAppletConfigureDialog.ui
)
set(statusnotifieritem_xml ${KNOTIFICATIONS_DBUS_INTERFACES_DIR}/kf5_org.kde.StatusNotifierItem.xml)
set_source_files_properties(${statusnotifieritem_xml} PROPERTIES
INCLUDE "DBusTypes.hxx"
CLASSNAME OrgKdeStatusNotifierItem
)
qt5_add_dbus_interface(SOURCES ${statusnotifieritem_xml} statusnotifieritem_interface)
qt5_add_dbus_adaptor(SOURCES org.freedesktop.Notifications.xml NotificationServer.hxx NotificationServer)
set(TARGET liquidshell)
add_executable(${TARGET} ${SOURCES} ${UI_FILES})
set_property(TARGET ${TARGET} PROPERTY CXX_STANDARD 11)
target_link_libraries(${TARGET}
Qt5::Core
Qt5::Widgets
Qt5::DBus
Qt5::X11Extras
KF5::WindowSystem
KF5::WidgetsAddons
KF5::ConfigWidgets
KF5::ConfigCore
KF5::KIOCore
KF5::KIOWidgets
KF5::IconThemes
KF5::Notifications
KF5::I18n
KF5::NetworkManagerQt
KF5::Service
KF5::Solid
KF5::BluezQt
KF5::KCMUtils
KF5::Crash
KF5::DBusAddons
KF5::ItemViews
KF5::Archive
KF5::NewStuff
)
if ( packagekitqt5_FOUND )
target_link_libraries(${TARGET} PK::packagekitqt5)
endif()
install(TARGETS ${TARGET} ${INSTALL_TARGETS_DEFAULT_ARGS})
install(FILES org.kde.${TARGET}.desktop DESTINATION ${XDG_APPS_INSTALL_DIR})
configure_file(start_liquidshell start_liquidshell @ONLY)
install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/start_liquidshell DESTINATION ${KDE_INSTALL_BINDIR})
configure_file(liquidshell-session.desktop liquidshell-session.desktop @ONLY)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/liquidshell-session.desktop DESTINATION ${KDE_INSTALL_DATADIR}/xsessions)
install(FILES liquidshell.notifyrc DESTINATION ${KNOTIFYRC_INSTALL_DIR})
ecm_install_icons(ICONS
48-apps-liquidshell.png
DESTINATION ${ICON_INSTALL_DIR}
THEME hicolor)
feature_summary(WHAT ALL INCLUDE_QUIET_PACKAGES)
diff --git a/DesktopWidget.cxx b/DesktopWidget.cxx
index 4ec52de..bde9076 100644
--- a/DesktopWidget.cxx
+++ b/DesktopWidget.cxx
@@ -1,421 +1,423 @@
// SPDX-License-Identifier: GPL-3.0-or-later
/*
Copyright 2017 - 2020 Martin Koller, kollix@aon.at
This file is part of liquidshell.
liquidshell is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
liquidshell is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with liquidshell. If not, see .
*/
#include
#include
#include
#include
#include
#include
#include
+#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
//--------------------------------------------------------------------------------
int DesktopWidget::appletNum = 0;
DesktopWidget *DesktopWidget::instance = nullptr;
//--------------------------------------------------------------------------------
DesktopWidget::DesktopWidget()
: QWidget(nullptr, Qt::WindowDoesNotAcceptFocus)
{
instance = this;
setAttribute(Qt::WA_AlwaysShowToolTips);
setAutoFillBackground(true);
setFixedSize(QApplication::primaryScreen()->virtualSize());
setWindowIcon(QIcon::fromTheme("liquidshell"));
KWindowSystem::setType(winId(), NET::Desktop);
panel = new DesktopPanel(nullptr);
panel->show();
connect(panel, &DesktopPanel::resized, this, &DesktopWidget::placePanel);
placePanel();
connect(KWindowSystem::self(), &KWindowSystem::currentDesktopChanged, this, &DesktopWidget::desktopChanged);
connect(KWindowSystem::self(), &KWindowSystem::numberOfDesktopsChanged, this, &DesktopWidget::loadSettings);
setContextMenuPolicy(Qt::ActionsContextMenu);
QAction *action = new QAction(QIcon::fromTheme("configure"), i18n("Configure Wallpaper..."), this);
connect(action, &QAction::triggered, this, &DesktopWidget::configureWallpaper);
addAction(action);
action = new QAction(i18n("Add Applet"), this);
addAction(action);
QMenu *menu = new QMenu;
action->setMenu(menu);
action = menu->addAction(QIcon::fromTheme("weather-clouds"), i18n("Weather"));
connect(action, &QAction::triggered, [this]() { addApplet("Weather"); });
action = menu->addAction(QIcon::fromTheme("drive-harddisk"), i18n("Disk Usage"));
connect(action, &QAction::triggered, [this]() { addApplet("DiskUsage"); });
action = menu->addAction(QIcon::fromTheme("image-x-generix"), i18n("Picture Frame"));
connect(action, &QAction::triggered, [this]() { addApplet("PictureFrame"); });
action = new QAction(QIcon::fromTheme("preferences-desktop-display"), i18n("Configure Display..."), this);
connect(action, &QAction::triggered, this, &DesktopWidget::configureDisplay);
addAction(action);
action = new QAction(QIcon::fromTheme("system-run"), i18n("Run Command..."), this);
connect(action, &QAction::triggered,
[]()
{
QDBusConnection::sessionBus().send(
QDBusMessage::createMethodCall("org.kde.krunner", "/App",
"org.kde.krunner.App", "display"));
});
addAction(action);
action = new QAction(i18n("Help"), this);
KHelpMenu *helpMenu = new KHelpMenu(this);
helpMenu->action(KHelpMenu::menuHelpContents)->setVisible(false); // no handbook
helpMenu->action(KHelpMenu::menuWhatsThis)->setVisible(false);
action->setMenu(helpMenu->menu());
addAction(action);
// restore applets
KConfig config;
KConfigGroup group = config.group("DesktopApplets");
QStringList appletNames = group.readEntry("applets", QStringList());
for (const QString &appletName : appletNames)
{
DesktopApplet *applet = nullptr;
if ( appletName.startsWith("Weather_") )
applet = new WeatherApplet(this, appletName);
else if ( appletName.startsWith("DiskUsage_") )
applet = new DiskUsageApplet(this, appletName);
else if ( appletName.startsWith("PictureFrame_") )
applet = new PictureFrameApplet(this, appletName);
if ( applet )
{
int num = appletName.mid(appletName.indexOf('_') + 1).toInt();
if ( num > appletNum )
appletNum = num;
applet->loadConfig();
applets.append(applet);
connect(applet, &DesktopApplet::removeThis, this, &DesktopWidget::removeApplet);
}
}
loadSettings();
connect(qApp, &QApplication::primaryScreenChanged, this, &DesktopWidget::placePanel);
connect(qApp, &QApplication::screenAdded,
[this]() { setFixedSize(QApplication::primaryScreen()->virtualSize()); desktopChanged(); });
connect(qApp, &QApplication::screenRemoved,
[this]() { setFixedSize(QApplication::primaryScreen()->virtualSize()); desktopChanged(); });
connect(QApplication::primaryScreen(), &QScreen::virtualGeometryChanged,
[this]() { setFixedSize(QApplication::primaryScreen()->virtualSize()); placePanel(); desktopChanged(); });
new OnScreenVolume(this);
+ new OnScreenBrightness(this);
}
//--------------------------------------------------------------------------------
void DesktopWidget::loadSettings()
{
// simple check for default files matching current desktop size
QStringList dirNames = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation,
"wallpapers", QStandardPaths::LocateDirectory);
QStringList defaultFiles;
const QString geometryString = QString("%1x%2").arg(width()).arg(height());
for (const QString &dirName : dirNames)
{
for (const QString &subdir : QDir(dirName).entryList(QDir::Dirs | QDir::NoDotAndDotDot | QDir::Readable))
{
QDir dir(dirName + '/' + subdir + "/contents/images");
for (const QString &fileName : dir.entryList(QDir::Files | QDir::Readable))
{
if ( fileName.startsWith(geometryString) )
defaultFiles.append(dir.absoluteFilePath(fileName));
}
}
}
KConfig config;
for (int i = wallpapers.count() + 1; i <= KWindowSystem::numberOfDesktops(); i++)
{
KConfigGroup group = config.group(QString("Desktop_%1").arg(i));
Wallpaper wallpaper;
wallpaper.color = group.readEntry("color", QColor(Qt::black));
wallpaper.mode = group.readEntry("wallpaperMode", QString());
int idx = defaultFiles.count() ? ((i - 1) % defaultFiles.count()) : -1;
wallpaper.fileName = group.readEntry("wallpaper", (idx != -1) ? defaultFiles[idx] : QString());
wallpapers.append(wallpaper);
}
wallpapers.resize(KWindowSystem::numberOfDesktops()); // if we had more before, reduce size
wallpapers.squeeze();
desktopChanged();
}
//--------------------------------------------------------------------------------
void DesktopWidget::configureWallpaper()
{
if ( dialog ) // already open, do nothing
return;
bool showingDesktop = KWindowSystem::showingDesktop();
KWindowSystem::setShowingDesktop(true);
int desktopNum = currentDesktop;
Wallpaper origWallpaper = wallpapers[desktopNum];
dialog = new ConfigureDesktopDialog(nullptr, wallpapers[desktopNum]);
connect(dialog, &ConfigureDesktopDialog::changed,
[=]() { wallpapers[desktopNum] = dialog->getWallpaper(); desktopChanged(); });
connect(dialog, &QDialog::finished,
[=](int result)
{
if ( result == QDialog::Rejected )
{
wallpapers[desktopNum] = origWallpaper;
desktopChanged();
}
else // store in config file
{
const Wallpaper &wallpaper = wallpapers[desktopNum];
KConfig config;
KConfigGroup group = config.group(QString("Desktop_%1").arg(desktopNum + 1));
group.writeEntry("color", wallpaper.color);
group.writeEntry("wallpaper", wallpaper.fileName);
group.writeEntry("wallpaperMode", wallpaper.mode);
}
KWindowSystem::setShowingDesktop(showingDesktop); // restore
dialog->deleteLater();
dialog = nullptr;
});
dialog->show(); // not modal
}
//--------------------------------------------------------------------------------
void DesktopWidget::configureDisplay()
{
KCMultiDialog *dialog = new KCMultiDialog(this);
dialog->setAttribute(Qt::WA_DeleteOnClose);
dialog->addModule("kcm_kscreen");
dialog->adjustSize();
dialog->setWindowTitle(i18n("Configure Display"));
dialog->show(); // not modal
}
//--------------------------------------------------------------------------------
void DesktopWidget::placePanel()
{
int panelHeight = qMin(panel->sizeHint().height(), panel->height());
QRect r = QApplication::primaryScreen()->geometry();
QSize vs = QApplication::primaryScreen()->virtualSize();
panel->setGeometry(r.x(), r.y() + r.height() - panelHeight, r.width(), panelHeight);
// struts are to the combined screen geoms, not the single screen
KWindowSystem::setStrut(panel->winId(), 0, 0, 0, panelHeight + vs.height() - r.bottom());
}
//--------------------------------------------------------------------------------
QRect DesktopWidget::availableGeometry()
{
QRect geom = QApplication::primaryScreen()->geometry();
geom.setHeight(geom.height() - instance->panel->height());
return geom;
}
//--------------------------------------------------------------------------------
QSize DesktopWidget::availableSize()
{
return availableGeometry().size();
}
//--------------------------------------------------------------------------------
void DesktopWidget::desktopChanged()
{
// free memory in previous shown desktop
if ( (currentDesktop >= 0) && (currentDesktop < wallpapers.count()) )
wallpapers[currentDesktop].pixmaps.clear();
currentDesktop = KWindowSystem::currentDesktop() - 1; // num to index
if ( currentDesktop >= wallpapers.count() )
return;
Wallpaper &wallpaper = wallpapers[currentDesktop];
if ( wallpaper.color.isValid() )
{
QPalette pal = palette();
pal.setColor(backgroundRole(), wallpaper.color);
setPalette(pal);
}
if ( !wallpaper.fileName.isEmpty() )
{
QPixmap pixmap(wallpaper.fileName);
if ( !pixmap.isNull() )
{
for (int i = 0; i < QApplication::screens().count(); i++)
{
QRect r = QApplication::screens().at(i)->geometry();
QPixmap scaledPixmap = pixmap;
if ( wallpaper.mode == "Scaled" )
scaledPixmap = pixmap.scaled(r.size(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
else if ( wallpaper.mode == "ScaledKeepRatio" )
scaledPixmap = pixmap.scaled(r.size(), Qt::KeepAspectRatio, Qt::SmoothTransformation);
else if ( wallpaper.mode == "ScaledKeepRatioExpand" )
scaledPixmap = pixmap.scaled(r.size(), Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation);
wallpaper.pixmaps.append(scaledPixmap);
}
}
}
update();
// show applets for new desktop
for (DesktopApplet *applet : applets)
{
if ( !applet->isConfiguring() )
applet->setVisible(applet->isOnDesktop(currentDesktop + 1));
}
}
//--------------------------------------------------------------------------------
void DesktopWidget::paintEvent(QPaintEvent *event)
{
Q_UNUSED(event)
if ( currentDesktop < wallpapers.count() )
{
Wallpaper &wallpaper = wallpapers[currentDesktop];
QPainter painter(this);
for (int i = 0; i < QApplication::screens().count(); i++)
{
if ( i < wallpaper.pixmaps.count() )
{
QRect r = QApplication::screens().at(i)->geometry();
painter.setClipRect(r);
painter.drawPixmap(r.x() + (r.width() - wallpaper.pixmaps[i].width()) / 2,
r.y() + (r.height() - wallpaper.pixmaps[i].height()) / 2,
wallpaper.pixmaps[i]);
}
}
}
}
//--------------------------------------------------------------------------------
void DesktopWidget::addApplet(const QString &type)
{
DesktopApplet *applet = nullptr;
if ( type == "Weather" )
{
applet = new WeatherApplet(this, QString("%1_%2").arg(type).arg(++appletNum));
}
else if ( type == "DiskUsage" )
{
applet = new DiskUsageApplet(this, QString("%1_%2").arg(type).arg(++appletNum));
}
else if ( type == "PictureFrame" )
{
applet = new PictureFrameApplet(this, QString("%1_%2").arg(type).arg(++appletNum));
}
if ( applet )
{
applets.append(applet);
applet->loadConfig(); // defaults + size
applet->move(QCursor::pos());
applet->saveConfig();
applet->show();
connect(applet, &DesktopApplet::removeThis, this, &DesktopWidget::removeApplet);
}
saveAppletsList();
}
//--------------------------------------------------------------------------------
void DesktopWidget::removeApplet(DesktopApplet *applet)
{
applets.removeOne(applet);
applet->deleteLater();
saveAppletsList();
}
//--------------------------------------------------------------------------------
void DesktopWidget::saveAppletsList()
{
KConfig config;
KConfigGroup group = config.group("DesktopApplets");
QStringList appletNames;
for (DesktopApplet *applet : applets)
appletNames.append(applet->getId());
group.writeEntry("applets", appletNames);
}
//--------------------------------------------------------------------------------
diff --git a/OnScreenBrightness.cxx b/OnScreenBrightness.cxx
new file mode 100644
index 0000000..9f23cc7
--- /dev/null
+++ b/OnScreenBrightness.cxx
@@ -0,0 +1,91 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+/*
+ Copyright 2020 Martin Koller, kollix@aon.at
+
+ This file is part of liquidshell.
+
+ liquidshell is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ liquidshell is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with liquidshell. If not, see .
+*/
+
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+
+//--------------------------------------------------------------------------------
+
+OnScreenBrightness::OnScreenBrightness(QWidget *parent)
+ : QProgressBar(parent)
+{
+ setWindowFlags(Qt::Window | Qt::FramelessWindowHint | Qt::WindowDoesNotAcceptFocus);
+
+ setFixedSize(400, 40);
+ hide();
+
+ KWindowSystem::setState(winId(), NET::KeepAbove);
+ KWindowSystem::setType(winId(), NET::Dock);
+ KWindowSystem::setOnAllDesktops(winId(), true);
+
+ hideTimer.setInterval(1000);
+ hideTimer.setSingleShot(true);
+ connect(&hideTimer, &QTimer::timeout, this, &QWidget::hide);
+
+ QDBusConnection::sessionBus()
+ .connect("org.kde.Solid.PowerManagement", "/org/kde/Solid/PowerManagement/Actions/BrightnessControl",
+ "org.kde.Solid.PowerManagement.Actions.BrightnessControl", "brightnessChanged",
+ this, SLOT(brightnessChanged(int)));
+
+ QDBusMessage msg =
+ QDBusMessage::createMethodCall("org.kde.Solid.PowerManagement",
+ "/org/kde/Solid/PowerManagement/Actions/BrightnessControl",
+ "org.kde.Solid.PowerManagement.Actions.BrightnessControl",
+ "brightnessMax");
+
+ QDBusConnection::sessionBus().callWithCallback(msg, this, SLOT(gotBrightnessMax(QDBusMessage)), nullptr);
+}
+
+//--------------------------------------------------------------------------------
+
+void OnScreenBrightness::gotBrightnessMax(QDBusMessage msg)
+{
+ QDBusReply reply = msg;
+
+ if ( !reply.isValid() )
+ return;
+
+ int max = reply.value();
+
+ setMaximum(max);
+}
+
+//--------------------------------------------------------------------------------
+
+void OnScreenBrightness::brightnessChanged(int value)
+{
+ setValue(value);
+
+ move((QApplication::primaryScreen()->size().width() - width()) / 2,
+ QApplication::primaryScreen()->size().height() * 0.8);
+
+ show();
+ hideTimer.start();
+}
+
+//--------------------------------------------------------------------------------
diff --git a/Pager.hxx b/OnScreenBrightness.hxx
similarity index 67%
copy from Pager.hxx
copy to OnScreenBrightness.hxx
index 1b249ae..e5fcb08 100644
--- a/Pager.hxx
+++ b/OnScreenBrightness.hxx
@@ -1,46 +1,44 @@
// SPDX-License-Identifier: GPL-3.0-or-later
/*
- Copyright 2017, 2018 Martin Koller, kollix@aon.at
+ Copyright 2020 Martin Koller, kollix@aon.at
This file is part of liquidshell.
liquidshell is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
liquidshell is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with liquidshell. If not, see .
*/
-#ifndef _Pager_H_
-#define _Pager_H_
+#ifndef _OnScreenBrightness_H_
+#define _OnScreenBrightness_H_
-#include
-class QButtonGroup;
-class PagerButton;
-class DesktopPanel;
+#include
+#include
+class QDBusMessage;
+class QDBusError;
-class Pager : public QWidget
+class OnScreenBrightness : public QProgressBar
{
Q_OBJECT
public:
- Pager(DesktopPanel *parent);
+ OnScreenBrightness(QWidget *parent);
private Q_SLOTS:
- void fill();
- void changeDesktop(bool checked);
+ void gotBrightnessMax(QDBusMessage msg);
+ void brightnessChanged(int value);
private:
- QButtonGroup *group;
- QVector buttons;
- bool showIcons = true;
+ QTimer hideTimer;
};
#endif
diff --git a/Pager.cxx b/Pager.cxx
index 4b82eaa..c257278 100644
--- a/Pager.cxx
+++ b/Pager.cxx
@@ -1,142 +1,157 @@
// SPDX-License-Identifier: GPL-3.0-or-later
/*
Copyright 2017, 2018 Martin Koller, kollix@aon.at
This file is part of liquidshell.
liquidshell is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
liquidshell is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with liquidshell. If not, see .
*/
#include
#include
#include
#include
#include
#include
#include
#include
+#include
#include
#include
#include
#include
#include
#include
#include
//--------------------------------------------------------------------------------
Pager::Pager(DesktopPanel *parent)
: QWidget(parent)
{
group = new QButtonGroup(this);
QGridLayout *grid = new QGridLayout(this);
grid->setSpacing(2);
grid->setContentsMargins(QMargins());
connect(KWindowSystem::self(), &KWindowSystem::numberOfDesktopsChanged, this, &Pager::fill);
connect(KWindowSystem::self(), &KWindowSystem::currentDesktopChanged,
[this]()
{
if ( KWindowSystem::currentDesktop() <= buttons.count() )
buttons[KWindowSystem::currentDesktop() - 1]->setChecked(true);
}
);
connect(parent, &DesktopPanel::rowsChanged, this, &Pager::fill);
KConfig config;
KConfigGroup group = config.group("Pager");
if ( !group.hasKey("showIcons") ) // create config entry so that one knows it exists
group.writeEntry("showIcons", true);
showIcons = group.readEntry("showIcons", true);
fill();
QAction *action = new QAction(this);
action->setIcon(QIcon::fromTheme("configure"));
action->setText(i18n("Configure Virtual Desktops..."));
addAction(action);
connect(action, &QAction::triggered,
[this]()
{
auto dialog = new KCMultiDialog(parentWidget());
dialog->setAttribute(Qt::WA_DeleteOnClose);
dialog->setWindowTitle(i18n("Configure Virtual Desktops"));
KCModuleInfo module("kcm_kwin_virtualdesktops");
if ( module.service() )
dialog->addModule("kcm_kwin_virtualdesktops");
else
dialog->addModule("desktop"); // in older KDE versions
dialog->adjustSize();
dialog->show();
}
);
setContextMenuPolicy(Qt::ActionsContextMenu);
}
//--------------------------------------------------------------------------------
void Pager::fill()
{
qDeleteAll(buttons);
buttons.clear();
NETRootInfo ri(QX11Info::connection(), 0, NET::WM2DesktopLayout);
int row = 0, col = 0;
const int MAX_COLUMNS = std::max(1, ri.desktopLayoutColumnsRows().width());
for (int i = 1; i <= KWindowSystem::numberOfDesktops(); i++)
{
PagerButton *b = new PagerButton(i, qobject_cast(parentWidget()), showIcons);
b->setCheckable(true);
b->setFocusPolicy(Qt::NoFocus);
group->addButton(b);
buttons.append(b);
if ( i == KWindowSystem::currentDesktop() )
b->setChecked(true);
connect(b, &PagerButton::clicked, this, &Pager::changeDesktop);
static_cast(layout())->addWidget(b, row, col);
col = (col + 1) % MAX_COLUMNS;
if ( col == 0 ) row++;
}
}
//--------------------------------------------------------------------------------
void Pager::changeDesktop(bool checked)
{
if ( !checked )
return;
int desktopNum = qobject_cast(sender())->getDesktop();
if ( KWindowSystem::currentDesktop() == desktopNum )
KWindowSystem::setShowingDesktop(!KWindowSystem::showingDesktop());
else
KWindowSystem::setCurrentDesktop(desktopNum);
}
//--------------------------------------------------------------------------------
+
+void Pager::wheelEvent(QWheelEvent *event)
+{
+ int desktopNum = KWindowSystem::currentDesktop() - 1 + KWindowSystem::numberOfDesktops();
+
+ if ( event->angleDelta().y() > 0 )
+ desktopNum++;
+ else
+ desktopNum--;
+
+ KWindowSystem::setCurrentDesktop((desktopNum % KWindowSystem::numberOfDesktops()) + 1);
+}
+
+//--------------------------------------------------------------------------------
diff --git a/Pager.hxx b/Pager.hxx
index 1b249ae..7a2a22c 100644
--- a/Pager.hxx
+++ b/Pager.hxx
@@ -1,46 +1,49 @@
// SPDX-License-Identifier: GPL-3.0-or-later
/*
Copyright 2017, 2018 Martin Koller, kollix@aon.at
This file is part of liquidshell.
liquidshell is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
liquidshell is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with liquidshell. If not, see .
*/
#ifndef _Pager_H_
#define _Pager_H_
#include
class QButtonGroup;
class PagerButton;
class DesktopPanel;
class Pager : public QWidget
{
Q_OBJECT
public:
Pager(DesktopPanel *parent);
+ protected:
+ void wheelEvent(QWheelEvent *event) override;
+
private Q_SLOTS:
void fill();
void changeDesktop(bool checked);
private:
QButtonGroup *group;
QVector buttons;
bool showIcons = true;
};
#endif