2023-09-26 15:33:08 +03:00
|
|
|
/* This file is part of the KDE project
|
|
|
|
Copyright (C) 2023 Ivailo Monev <xakepa10@gmail.com>
|
2014-11-13 19:30:51 +02:00
|
|
|
|
2023-09-26 15:33:08 +03:00
|
|
|
This library is free software; you can redistribute it and/or
|
|
|
|
modify it under the terms of the GNU Library General Public
|
|
|
|
License version 2, as published by the Free Software Foundation.
|
2014-11-13 19:30:51 +02:00
|
|
|
|
2023-09-26 15:33:08 +03:00
|
|
|
This library 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
|
|
|
|
Library General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU Library General Public License
|
|
|
|
along with this library; see the file COPYING.LIB. If not, write to
|
|
|
|
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
|
|
Boston, MA 02110-1301, USA.
|
|
|
|
*/
|
2014-11-13 19:30:51 +02:00
|
|
|
|
2023-09-26 15:33:08 +03:00
|
|
|
#include "pager.h"
|
2023-09-29 16:57:52 +03:00
|
|
|
#include "kworkspace/ktaskmanager.h"
|
2023-09-26 15:33:08 +03:00
|
|
|
|
|
|
|
#include <QX11Info>
|
2023-10-02 02:24:44 +03:00
|
|
|
#include <Plasma/Dialog>
|
2023-10-02 00:32:14 +03:00
|
|
|
#include <Plasma/Animation>
|
2023-09-29 22:33:36 +03:00
|
|
|
#include <Plasma/IconWidget>
|
2023-09-26 15:33:08 +03:00
|
|
|
#include <Plasma/Svg>
|
2014-11-13 19:30:51 +02:00
|
|
|
#include <Plasma/FrameSvg>
|
2023-09-26 15:33:08 +03:00
|
|
|
#include <Plasma/SvgWidget>
|
2014-11-13 19:30:51 +02:00
|
|
|
#include <Plasma/Theme>
|
2023-09-26 21:47:42 +03:00
|
|
|
#include <Plasma/ToolTipManager>
|
2023-09-27 17:55:58 +03:00
|
|
|
#include <KCModuleInfo>
|
2023-09-26 15:33:08 +03:00
|
|
|
#include <KWindowSystem>
|
|
|
|
#include <KIcon>
|
|
|
|
#include <KIconLoader>
|
|
|
|
#include <KDebug>
|
|
|
|
#include <netwm.h>
|
2014-11-13 19:30:51 +02:00
|
|
|
|
2023-09-26 15:33:08 +03:00
|
|
|
// standard issue margin/spacing
|
|
|
|
static const int s_spacing = 4;
|
2014-11-13 19:30:51 +02:00
|
|
|
|
2023-09-29 22:33:36 +03:00
|
|
|
static QString kElementPrefixForDesktop(const int desktop)
|
2014-11-13 19:30:51 +02:00
|
|
|
{
|
2023-09-29 22:33:36 +03:00
|
|
|
if (KWindowSystem::currentDesktop() == desktop) {
|
2023-09-26 15:33:08 +03:00
|
|
|
return QString::fromLatin1("active");
|
|
|
|
}
|
|
|
|
return QString::fromLatin1("normal");
|
2014-11-13 19:30:51 +02:00
|
|
|
}
|
|
|
|
|
2023-09-26 22:29:06 +03:00
|
|
|
static bool kHandleMouseEvent(QGraphicsSceneMouseEvent *event)
|
|
|
|
{
|
|
|
|
if (event->button() == Qt::MiddleButton) {
|
|
|
|
NETRootInfo netrootinfo(QX11Info::display(), NET::WM2ShowingDesktop | NET::Supported);
|
|
|
|
if (!netrootinfo.isSupported(NET::WM2ShowingDesktop)) {
|
|
|
|
kWarning() << "NET::WM2ShowingDesktop is not supported";
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
// that is how the showdesktop does it - it tracks the state internally
|
|
|
|
static bool s_didshow = false;
|
|
|
|
if (netrootinfo.showingDesktop() || s_didshow) {
|
|
|
|
s_didshow = false;
|
|
|
|
netrootinfo.setShowingDesktop(false);
|
|
|
|
} else {
|
|
|
|
s_didshow = true;
|
|
|
|
netrootinfo.setShowingDesktop(true);
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2023-10-02 02:24:44 +03:00
|
|
|
class PagerDialog : public Plasma::Dialog
|
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
public:
|
|
|
|
explicit PagerDialog(QWidget *parent = nullptr);
|
|
|
|
|
|
|
|
void updateTasks(const QList<KTaskManager::Task> &tasks);
|
|
|
|
|
|
|
|
private:
|
|
|
|
QGraphicsScene* m_scene;
|
|
|
|
QGraphicsWidget* m_widget;
|
|
|
|
QGraphicsLinearLayout* m_layout;
|
|
|
|
QList<KTaskManager::Task> m_tasks;
|
|
|
|
};
|
|
|
|
|
|
|
|
PagerDialog::PagerDialog(QWidget *parent)
|
|
|
|
: Plasma::Dialog(parent, Qt::Dialog | Qt::WindowStaysOnTopHint),
|
|
|
|
m_scene(nullptr),
|
|
|
|
m_widget(nullptr),
|
|
|
|
m_layout(nullptr)
|
|
|
|
{
|
|
|
|
m_scene = new QGraphicsScene(this);
|
|
|
|
m_widget = new QGraphicsWidget();
|
|
|
|
|
|
|
|
m_layout = new QGraphicsLinearLayout(m_widget);
|
|
|
|
m_layout->setContentsMargins(0, 0, 0, 0);
|
|
|
|
m_layout->setSpacing(s_spacing);
|
|
|
|
|
|
|
|
m_widget->setLayout(m_layout);
|
|
|
|
|
|
|
|
m_scene->addItem(m_widget);
|
|
|
|
setGraphicsWidget(m_widget);
|
|
|
|
}
|
|
|
|
|
|
|
|
void PagerDialog::updateTasks(const QList<KTaskManager::Task> &tasks)
|
|
|
|
{
|
|
|
|
// TODO:
|
|
|
|
m_tasks = tasks;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2023-09-29 22:33:36 +03:00
|
|
|
class PagerIcon : public Plasma::IconWidget
|
2014-11-13 19:30:51 +02:00
|
|
|
{
|
2023-09-26 15:33:08 +03:00
|
|
|
Q_OBJECT
|
|
|
|
public:
|
2023-09-29 22:33:36 +03:00
|
|
|
explicit PagerIcon(const KTaskManager::Task &task, QGraphicsItem *parent);
|
|
|
|
|
2023-10-02 00:32:14 +03:00
|
|
|
QByteArray taskID() const;
|
|
|
|
void animatedShow();
|
|
|
|
void animatedRemove();
|
|
|
|
void updateIconAndToolTip();
|
|
|
|
|
2023-09-29 22:33:36 +03:00
|
|
|
private Q_SLOTS:
|
|
|
|
void slotClicked();
|
2023-10-02 02:24:44 +03:00
|
|
|
void slotWindowPreviewActivated(const WId window);
|
2023-09-29 22:33:36 +03:00
|
|
|
|
|
|
|
private:
|
|
|
|
KTaskManager::Task m_task;
|
|
|
|
};
|
|
|
|
|
|
|
|
PagerIcon::PagerIcon(const KTaskManager::Task &task, QGraphicsItem *parent)
|
|
|
|
: Plasma::IconWidget(parent),
|
|
|
|
m_task(task)
|
|
|
|
{
|
|
|
|
updateIconAndToolTip();
|
|
|
|
connect(
|
|
|
|
this, SIGNAL(clicked()),
|
|
|
|
this, SLOT(slotClicked())
|
|
|
|
);
|
2023-10-02 02:24:44 +03:00
|
|
|
connect(
|
|
|
|
Plasma::ToolTipManager::self(), SIGNAL(windowPreviewActivated(WId,Qt::MouseButtons,Qt::KeyboardModifiers,QPoint)),
|
|
|
|
this, SLOT(slotWindowPreviewActivated(WId))
|
|
|
|
);
|
2023-10-02 00:32:14 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
QByteArray PagerIcon::taskID() const
|
|
|
|
{
|
|
|
|
return m_task.id;
|
|
|
|
}
|
|
|
|
|
|
|
|
void PagerIcon::animatedShow()
|
|
|
|
{
|
|
|
|
Plasma::Animation *animation = Plasma::Animator::create(Plasma::Animator::FadeAnimation);
|
|
|
|
Q_ASSERT(animation != nullptr);
|
|
|
|
animation->setTargetWidget(this);
|
|
|
|
animation->setProperty("startOpacity", 0.0);
|
|
|
|
animation->setProperty("targetOpacity", 1.0);
|
|
|
|
animation->start(QAbstractAnimation::DeleteWhenStopped);
|
|
|
|
}
|
|
|
|
|
|
|
|
void PagerIcon::animatedRemove()
|
|
|
|
{
|
|
|
|
Plasma::Animation *animation = Plasma::Animator::create(Plasma::Animator::FadeAnimation);
|
|
|
|
Q_ASSERT(animation != nullptr);
|
|
|
|
connect(animation, SIGNAL(finished()), this, SLOT(deleteLater()));
|
|
|
|
animation->setTargetWidget(this);
|
|
|
|
animation->setProperty("startOpacity", 1.0);
|
|
|
|
animation->setProperty("targetOpacity", 0.0);
|
|
|
|
animation->start(QAbstractAnimation::DeleteWhenStopped);
|
2023-09-29 22:33:36 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void PagerIcon::updateIconAndToolTip()
|
|
|
|
{
|
|
|
|
setIcon(m_task.icon);
|
|
|
|
Plasma::ToolTipContent plasmatooltip;
|
|
|
|
plasmatooltip.setMainText(QString::fromLatin1("<center>%1</center>").arg(m_task.name));
|
|
|
|
plasmatooltip.setWindowToPreview(m_task.window);
|
|
|
|
plasmatooltip.setClickable(true);
|
|
|
|
Plasma::ToolTipManager::self()->setContent(this, plasmatooltip);
|
|
|
|
}
|
|
|
|
|
|
|
|
void PagerIcon::slotClicked()
|
|
|
|
{
|
|
|
|
KTaskManager::self()->activateRaiseOrIconify(m_task);
|
|
|
|
}
|
|
|
|
|
2023-10-02 02:24:44 +03:00
|
|
|
void PagerIcon::slotWindowPreviewActivated(const WId window)
|
|
|
|
{
|
|
|
|
// manually hide the tooltip first
|
|
|
|
Plasma::ToolTipManager::self()->hide(this);
|
|
|
|
KWindowSystem::activateWindow(window);
|
|
|
|
KWindowSystem::raiseWindow(window);
|
|
|
|
}
|
|
|
|
|
2014-11-13 19:30:51 +02:00
|
|
|
|
2023-09-29 22:33:36 +03:00
|
|
|
class PagerSvg : public Plasma::SvgWidget
|
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
public:
|
|
|
|
PagerSvg(const int desktop, const Qt::Orientation orientation, QGraphicsItem *parent = nullptr);
|
|
|
|
|
|
|
|
void setLayoutOrientation(const Qt::Orientation orientation);
|
2014-11-13 19:30:51 +02:00
|
|
|
|
2023-09-26 15:33:08 +03:00
|
|
|
protected:
|
|
|
|
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) final;
|
2023-09-26 22:29:06 +03:00
|
|
|
// handled here too
|
|
|
|
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) final;
|
2023-10-02 02:24:44 +03:00
|
|
|
void resizeEvent(QGraphicsSceneResizeEvent *event) final;
|
2014-11-13 19:30:51 +02:00
|
|
|
|
2023-09-26 15:33:08 +03:00
|
|
|
private Q_SLOTS:
|
2023-09-27 23:43:53 +03:00
|
|
|
void slotClicked(const Qt::MouseButton button);
|
|
|
|
void slotUpdate();
|
2023-10-02 00:32:14 +03:00
|
|
|
void slotUpdateSvg();
|
|
|
|
void slotTaskAdded(const KTaskManager::Task &task);
|
2023-09-29 22:33:36 +03:00
|
|
|
void slotTaskChanged(const KTaskManager::Task &task);
|
2023-10-02 00:32:14 +03:00
|
|
|
void slotTaskRemoved(const KTaskManager::Task &task);
|
2023-10-02 02:24:44 +03:00
|
|
|
void slotCheckSpace();
|
|
|
|
void slotShowDialog();
|
2014-11-13 19:30:51 +02:00
|
|
|
|
2023-09-26 15:33:08 +03:00
|
|
|
private:
|
2023-09-29 22:33:36 +03:00
|
|
|
QMutex m_mutex;
|
2023-09-26 15:33:08 +03:00
|
|
|
int m_desktop;
|
|
|
|
Plasma::FrameSvg* m_framesvg;
|
2023-09-29 22:33:36 +03:00
|
|
|
QGraphicsLinearLayout* m_layout;
|
|
|
|
QList<PagerIcon*> m_pagericons;
|
|
|
|
QGraphicsWidget* m_spacer;
|
2023-10-02 02:24:44 +03:00
|
|
|
Plasma::IconWidget* m_pagericon;
|
|
|
|
PagerDialog* m_pagerdialog;
|
2023-09-26 15:33:08 +03:00
|
|
|
};
|
2014-11-13 19:30:51 +02:00
|
|
|
|
2023-09-29 22:33:36 +03:00
|
|
|
PagerSvg::PagerSvg(const int desktop, const Qt::Orientation orientation, QGraphicsItem *parent)
|
2023-09-26 15:33:08 +03:00
|
|
|
: Plasma::SvgWidget(parent),
|
|
|
|
m_desktop(desktop),
|
|
|
|
m_framesvg(nullptr),
|
2023-09-29 22:33:36 +03:00
|
|
|
m_layout(nullptr),
|
2023-10-02 02:24:44 +03:00
|
|
|
m_spacer(nullptr),
|
|
|
|
m_pagericon(nullptr),
|
|
|
|
m_pagerdialog(nullptr)
|
2014-11-13 19:30:51 +02:00
|
|
|
{
|
2023-10-02 00:32:14 +03:00
|
|
|
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
|
|
|
|
2023-09-29 22:33:36 +03:00
|
|
|
m_layout = new QGraphicsLinearLayout(orientation, this);
|
|
|
|
m_layout->setContentsMargins(s_spacing, s_spacing, s_spacing, s_spacing);
|
|
|
|
m_layout->setSpacing(0);
|
|
|
|
|
2023-10-02 00:32:14 +03:00
|
|
|
slotUpdateSvg();
|
2023-09-26 15:33:08 +03:00
|
|
|
setAcceptHoverEvents(true);
|
2023-10-02 00:32:14 +03:00
|
|
|
|
|
|
|
foreach (const KTaskManager::Task &task, KTaskManager::self()->tasks()) {
|
|
|
|
slotTaskAdded(task);
|
|
|
|
}
|
|
|
|
|
2023-09-26 15:33:08 +03:00
|
|
|
connect(
|
|
|
|
this, SIGNAL(clicked(Qt::MouseButton)),
|
|
|
|
this, SLOT(slotClicked(Qt::MouseButton))
|
|
|
|
);
|
|
|
|
connect(
|
|
|
|
KWindowSystem::self(), SIGNAL(currentDesktopChanged(int)),
|
|
|
|
this, SLOT(slotUpdate())
|
|
|
|
);
|
2023-09-29 22:33:36 +03:00
|
|
|
connect(
|
|
|
|
KTaskManager::self(), SIGNAL(taskAdded(KTaskManager::Task)),
|
2023-10-02 00:32:14 +03:00
|
|
|
this, SLOT(slotTaskAdded(KTaskManager::Task))
|
2023-09-29 22:33:36 +03:00
|
|
|
);
|
2023-09-29 17:01:46 +03:00
|
|
|
connect(
|
|
|
|
KTaskManager::self(), SIGNAL(taskChanged(KTaskManager::Task)),
|
2023-09-29 22:33:36 +03:00
|
|
|
this, SLOT(slotTaskChanged(KTaskManager::Task))
|
|
|
|
);
|
|
|
|
connect(
|
|
|
|
KTaskManager::self(), SIGNAL(taskRemoved(KTaskManager::Task)),
|
2023-10-02 00:32:14 +03:00
|
|
|
this, SLOT(slotTaskRemoved(KTaskManager::Task))
|
2023-09-29 17:01:46 +03:00
|
|
|
);
|
2023-09-26 15:33:08 +03:00
|
|
|
connect(
|
|
|
|
Plasma::Theme::defaultTheme(), SIGNAL(themeChanged()),
|
2023-10-02 00:32:14 +03:00
|
|
|
this, SLOT(slotUpdateSvg())
|
2023-09-26 15:33:08 +03:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2023-09-29 22:33:36 +03:00
|
|
|
void PagerSvg::setLayoutOrientation(const Qt::Orientation orientation)
|
2023-09-26 15:33:08 +03:00
|
|
|
{
|
2023-09-29 22:33:36 +03:00
|
|
|
m_layout->setOrientation(orientation);
|
2023-09-26 15:33:08 +03:00
|
|
|
}
|
2014-11-13 19:30:51 +02:00
|
|
|
|
2023-09-26 15:33:08 +03:00
|
|
|
void PagerSvg::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
|
|
|
|
{
|
|
|
|
Q_UNUSED(option);
|
|
|
|
Q_UNUSED(widget);
|
2023-09-29 16:37:04 +03:00
|
|
|
painter->setRenderHint(QPainter::Antialiasing);
|
2023-09-26 15:33:08 +03:00
|
|
|
const QRectF brect = boundingRect();
|
2023-09-29 22:33:36 +03:00
|
|
|
m_framesvg->setElementPrefix(kElementPrefixForDesktop(m_desktop));
|
2023-09-26 15:33:08 +03:00
|
|
|
m_framesvg->resizeFrame(brect.size());
|
|
|
|
m_framesvg->paintFrame(painter, brect);
|
2014-11-13 19:30:51 +02:00
|
|
|
}
|
|
|
|
|
2023-09-26 22:29:06 +03:00
|
|
|
void PagerSvg::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
|
|
|
|
{
|
|
|
|
if (kHandleMouseEvent(event)) {
|
|
|
|
event->accept();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
Plasma::SvgWidget::mouseReleaseEvent(event);
|
|
|
|
}
|
|
|
|
|
2023-10-02 02:24:44 +03:00
|
|
|
void PagerSvg::resizeEvent(QGraphicsSceneResizeEvent *event)
|
|
|
|
{
|
|
|
|
Plasma::SvgWidget::resizeEvent(event);
|
|
|
|
slotCheckSpace();
|
|
|
|
}
|
|
|
|
|
2023-09-27 23:43:53 +03:00
|
|
|
void PagerSvg::slotClicked(const Qt::MouseButton button)
|
|
|
|
{
|
|
|
|
if (button == Qt::LeftButton) {
|
|
|
|
KWindowSystem::setCurrentDesktop(m_desktop);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void PagerSvg::slotUpdate()
|
|
|
|
{
|
|
|
|
update();
|
|
|
|
}
|
|
|
|
|
2023-10-02 00:32:14 +03:00
|
|
|
void PagerSvg::slotUpdateSvg()
|
2014-11-13 19:30:51 +02:00
|
|
|
{
|
2023-09-26 15:33:08 +03:00
|
|
|
if (m_framesvg) {
|
|
|
|
delete m_framesvg;
|
2014-11-13 19:30:51 +02:00
|
|
|
}
|
2023-09-26 15:33:08 +03:00
|
|
|
m_framesvg = new Plasma::FrameSvg(this);
|
|
|
|
m_framesvg->setImagePath("widgets/pager");
|
|
|
|
setSvg(m_framesvg);
|
2023-09-29 22:33:36 +03:00
|
|
|
}
|
|
|
|
|
2023-10-02 00:32:14 +03:00
|
|
|
void PagerSvg::slotTaskAdded(const KTaskManager::Task &task)
|
2023-09-29 22:33:36 +03:00
|
|
|
{
|
|
|
|
QMutexLocker locker(&m_mutex);
|
|
|
|
if (m_spacer) {
|
|
|
|
m_layout->removeItem(m_spacer);
|
|
|
|
}
|
2023-10-02 00:32:14 +03:00
|
|
|
const KWindowInfo kwindowinfo = KWindowSystem::windowInfo(task.window, NET::WMDesktop);
|
|
|
|
if (kwindowinfo.isOnDesktop(m_desktop)) {
|
2023-09-29 22:33:36 +03:00
|
|
|
PagerIcon* pagericon = new PagerIcon(task, this);
|
2023-10-02 02:24:44 +03:00
|
|
|
connect(
|
|
|
|
pagericon, SIGNAL(destroyed()),
|
|
|
|
this, SLOT(slotCheckSpace())
|
|
|
|
);
|
2023-09-29 22:33:36 +03:00
|
|
|
m_pagericons.append(pagericon);
|
2023-10-02 02:24:44 +03:00
|
|
|
m_layout->addItem(pagericon);
|
2023-10-02 00:32:14 +03:00
|
|
|
pagericon->animatedShow();
|
2023-09-29 22:33:36 +03:00
|
|
|
}
|
|
|
|
if (!m_spacer) {
|
|
|
|
m_spacer = new QGraphicsWidget(this);
|
|
|
|
m_spacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
|
|
|
m_spacer->setMinimumSize(0, 0);
|
|
|
|
}
|
|
|
|
m_layout->addItem(m_spacer);
|
2023-10-02 02:24:44 +03:00
|
|
|
if (!m_pagericon) {
|
|
|
|
m_pagericon = new Plasma::IconWidget(this);
|
|
|
|
m_pagericon->setSvg("widgets/arrows", "up-arrow");
|
|
|
|
connect(
|
|
|
|
m_pagericon, SIGNAL(clicked()),
|
|
|
|
this, SLOT(slotShowDialog())
|
|
|
|
);
|
|
|
|
}
|
|
|
|
m_layout->addItem(m_pagericon);
|
|
|
|
locker.unlock();
|
|
|
|
slotCheckSpace();
|
2023-09-29 22:33:36 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void PagerSvg::slotTaskChanged(const KTaskManager::Task &task)
|
|
|
|
{
|
2023-10-02 02:24:44 +03:00
|
|
|
// special case for tasks moved from one virtual desktop to another, the check for showing the
|
|
|
|
// task on m_desktop is there because tasks may be shown on all desktops too
|
2023-09-29 22:33:36 +03:00
|
|
|
const KWindowInfo kwindowinfo = KWindowSystem::windowInfo(task.window, NET::WMDesktop);
|
2023-10-02 00:32:14 +03:00
|
|
|
if (!kwindowinfo.isOnDesktop(m_desktop)) {
|
|
|
|
slotTaskRemoved(task);
|
|
|
|
} else {
|
|
|
|
QMutexLocker locker(&m_mutex);
|
|
|
|
PagerIcon* foundpagericon = nullptr;
|
|
|
|
foreach (PagerIcon* pagericon, m_pagericons) {
|
|
|
|
if (pagericon->taskID() == task.id) {
|
|
|
|
foundpagericon = pagericon;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
locker.unlock();
|
|
|
|
if (!foundpagericon) {
|
|
|
|
slotTaskAdded(task);
|
|
|
|
} else {
|
|
|
|
foundpagericon->updateIconAndToolTip();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void PagerSvg::slotTaskRemoved(const KTaskManager::Task &task)
|
|
|
|
{
|
|
|
|
QMutexLocker locker(&m_mutex);
|
|
|
|
foreach (PagerIcon* pagericon, m_pagericons) {
|
|
|
|
if (pagericon->taskID() == task.id) {
|
|
|
|
m_pagericons.removeAll(pagericon);
|
|
|
|
pagericon->animatedRemove();
|
|
|
|
break;
|
|
|
|
}
|
2023-09-29 16:57:52 +03:00
|
|
|
}
|
2014-11-13 19:30:51 +02:00
|
|
|
}
|
|
|
|
|
2023-10-02 02:24:44 +03:00
|
|
|
void PagerSvg::slotCheckSpace()
|
|
|
|
{
|
|
|
|
// qDebug() << Q_FUNC_INFO << m_spacer->size() << size();
|
|
|
|
if (!m_spacer) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
const QSizeF spacersize = m_spacer->size();
|
|
|
|
bool notenoughspace = false;
|
|
|
|
QMutexLocker locker(&m_mutex);
|
|
|
|
if (m_layout->orientation() == Qt::Horizontal) {
|
|
|
|
notenoughspace = (m_pagericons.size() > 0 && spacersize.width() <= m_pagericons.first()->size().width());
|
|
|
|
} else {
|
|
|
|
notenoughspace = (m_pagericons.size() > 0 && spacersize.height() <= m_pagericons.first()->size().height());
|
|
|
|
}
|
|
|
|
if (notenoughspace) {
|
|
|
|
if (!m_pagerdialog) {
|
|
|
|
m_pagerdialog = new PagerDialog();
|
|
|
|
}
|
|
|
|
// TODO: m_pagerdialog->updateTasks();
|
|
|
|
m_pagericon->setVisible(true);
|
|
|
|
} else {
|
|
|
|
m_pagericon->setVisible(false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void PagerSvg::slotShowDialog()
|
|
|
|
{
|
|
|
|
Q_ASSERT(m_pagerdialog != nullptr);
|
|
|
|
m_pagerdialog->show();
|
|
|
|
}
|
|
|
|
|
2014-11-13 19:30:51 +02:00
|
|
|
|
2023-09-26 15:33:08 +03:00
|
|
|
PagerApplet::PagerApplet(QObject *parent, const QVariantList &args)
|
|
|
|
: Plasma::Applet(parent, args),
|
|
|
|
m_layout(nullptr),
|
|
|
|
m_adddesktopaction(nullptr),
|
|
|
|
m_removedesktopaction(nullptr),
|
2023-09-27 17:55:58 +03:00
|
|
|
m_spacer(nullptr),
|
|
|
|
m_kcmdesktopproxy(nullptr)
|
2023-09-26 15:33:08 +03:00
|
|
|
{
|
|
|
|
KGlobal::locale()->insertCatalog("plasma_applet_pager");
|
|
|
|
setAspectRatioMode(Plasma::AspectRatioMode::IgnoreAspectRatio);
|
|
|
|
setHasConfigurationInterface(true);
|
2023-09-29 22:33:36 +03:00
|
|
|
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
2014-11-13 19:30:51 +02:00
|
|
|
|
2023-09-26 15:33:08 +03:00
|
|
|
m_layout = new QGraphicsLinearLayout(Qt::Horizontal, this);
|
2023-09-26 23:25:26 +03:00
|
|
|
|
|
|
|
// early setup to get proper initial size
|
2023-09-26 15:33:08 +03:00
|
|
|
slotUpdateLayout();
|
|
|
|
adjustSize();
|
2014-11-13 19:30:51 +02:00
|
|
|
}
|
|
|
|
|
2023-09-26 15:33:08 +03:00
|
|
|
void PagerApplet::init()
|
2014-11-13 19:30:51 +02:00
|
|
|
{
|
2023-09-26 15:33:08 +03:00
|
|
|
connect(
|
|
|
|
KWindowSystem::self(), SIGNAL(numberOfDesktopsChanged(int)),
|
|
|
|
this, SLOT(slotUpdateLayout())
|
|
|
|
);
|
2014-11-13 19:30:51 +02:00
|
|
|
}
|
|
|
|
|
2023-09-26 15:33:08 +03:00
|
|
|
void PagerApplet::createConfigurationInterface(KConfigDialog *parent)
|
2014-11-13 19:30:51 +02:00
|
|
|
{
|
2023-09-27 17:55:58 +03:00
|
|
|
m_kcmdesktopproxy = new KCModuleProxy("desktop");
|
|
|
|
parent->addPage(
|
|
|
|
m_kcmdesktopproxy, m_kcmdesktopproxy->moduleInfo().moduleName(),
|
|
|
|
m_kcmdesktopproxy->moduleInfo().icon()
|
|
|
|
);
|
|
|
|
|
2023-09-26 23:25:26 +03:00
|
|
|
connect(parent, SIGNAL(applyClicked()), this, SLOT(slotConfigAccepted()));
|
|
|
|
connect(parent, SIGNAL(okClicked()), this, SLOT(slotConfigAccepted()));
|
2023-09-27 17:55:58 +03:00
|
|
|
connect(m_kcmdesktopproxy, SIGNAL(changed(bool)), parent, SLOT(settingsModified()));
|
2014-11-13 19:30:51 +02:00
|
|
|
}
|
|
|
|
|
2023-09-26 15:33:08 +03:00
|
|
|
QList<QAction*> PagerApplet::contextualActions()
|
2014-11-13 19:30:51 +02:00
|
|
|
{
|
2023-09-26 15:33:08 +03:00
|
|
|
return m_actions;
|
2014-11-13 19:30:51 +02:00
|
|
|
}
|
|
|
|
|
2023-09-26 21:47:42 +03:00
|
|
|
void PagerApplet::wheelEvent(QGraphicsSceneWheelEvent *event)
|
|
|
|
{
|
|
|
|
const int currentdesktop = KWindowSystem::currentDesktop();
|
|
|
|
if (event->delta() < 0) {
|
|
|
|
KWindowSystem::setCurrentDesktop(currentdesktop + 1);
|
|
|
|
} else {
|
|
|
|
KWindowSystem::setCurrentDesktop(currentdesktop - 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-09-26 22:29:06 +03:00
|
|
|
void PagerApplet::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
|
|
|
|
{
|
|
|
|
if (kHandleMouseEvent(event)) {
|
|
|
|
event->accept();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
Plasma::Applet::mouseReleaseEvent(event);
|
|
|
|
}
|
|
|
|
|
2023-09-26 15:33:08 +03:00
|
|
|
void PagerApplet::constraintsEvent(Plasma::Constraints constraints)
|
2014-11-13 19:30:51 +02:00
|
|
|
{
|
2023-09-26 15:33:08 +03:00
|
|
|
// perfect size finder
|
|
|
|
// qDebug() << Q_FUNC_INFO << size();
|
|
|
|
if (constraints & Plasma::SizeConstraint || constraints & Plasma::FormFactorConstraint) {
|
|
|
|
switch (formFactor()) {
|
|
|
|
case Plasma::FormFactor::Horizontal: {
|
|
|
|
m_layout->setOrientation(Qt::Horizontal);
|
2023-09-29 22:33:36 +03:00
|
|
|
updateOrientation();
|
2023-09-26 15:33:08 +03:00
|
|
|
return;
|
2014-11-13 19:30:51 +02:00
|
|
|
}
|
2023-09-26 15:33:08 +03:00
|
|
|
case Plasma::FormFactor::Vertical: {
|
|
|
|
m_layout->setOrientation(Qt::Vertical);
|
2023-09-29 22:33:36 +03:00
|
|
|
updateOrientation();
|
2023-09-26 15:33:08 +03:00
|
|
|
return;
|
2014-11-13 19:30:51 +02:00
|
|
|
}
|
2023-09-26 15:33:08 +03:00
|
|
|
default: {
|
|
|
|
break;
|
2014-11-13 19:30:51 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-09-26 15:33:08 +03:00
|
|
|
const QSizeF appletsize = size();
|
|
|
|
if (appletsize.width() >= appletsize.height()) {
|
|
|
|
m_layout->setOrientation(Qt::Horizontal);
|
2014-11-13 19:30:51 +02:00
|
|
|
} else {
|
2023-09-26 15:33:08 +03:00
|
|
|
m_layout->setOrientation(Qt::Vertical);
|
2014-11-13 19:30:51 +02:00
|
|
|
}
|
2023-09-29 22:33:36 +03:00
|
|
|
updateOrientation();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void PagerApplet::updateOrientation()
|
|
|
|
{
|
|
|
|
QMutexLocker locker(&m_mutex);
|
2023-10-02 02:24:44 +03:00
|
|
|
QSizeF dividedappletsize = size();
|
2023-09-29 22:33:36 +03:00
|
|
|
// somewhat correct
|
|
|
|
if (m_layout->orientation() == Qt::Horizontal) {
|
2023-10-02 02:24:44 +03:00
|
|
|
dividedappletsize.setWidth(dividedappletsize.width() / m_pagersvgs.size());
|
2023-09-29 22:33:36 +03:00
|
|
|
} else {
|
2023-10-02 02:24:44 +03:00
|
|
|
dividedappletsize.setHeight(dividedappletsize.height() / m_pagersvgs.size());
|
2023-09-29 22:33:36 +03:00
|
|
|
}
|
|
|
|
foreach (PagerSvg* pagersvg, m_pagersvgs) {
|
|
|
|
pagersvg->setLayoutOrientation(m_layout->orientation());
|
2023-10-02 02:24:44 +03:00
|
|
|
pagersvg->setMaximumSize(dividedappletsize);
|
2014-11-13 19:30:51 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-09-26 15:33:08 +03:00
|
|
|
void PagerApplet::slotUpdateLayout()
|
2014-11-13 19:30:51 +02:00
|
|
|
{
|
2023-09-26 15:33:08 +03:00
|
|
|
QMutexLocker locker(&m_mutex);
|
|
|
|
foreach (PagerSvg* pagersvg, m_pagersvgs) {
|
|
|
|
m_layout->removeItem(pagersvg);
|
2014-11-13 19:30:51 +02:00
|
|
|
}
|
2023-09-26 15:33:08 +03:00
|
|
|
qDeleteAll(m_pagersvgs);
|
|
|
|
m_pagersvgs.clear();
|
2014-11-13 19:30:51 +02:00
|
|
|
|
2023-09-26 15:33:08 +03:00
|
|
|
const int numberofdesktops = KWindowSystem::numberOfDesktops();
|
2023-10-02 00:32:14 +03:00
|
|
|
m_layout->setContentsMargins(0, 0, 0, 0);
|
2023-09-29 22:33:36 +03:00
|
|
|
const Qt::Orientation orientation = m_layout->orientation();
|
2023-09-26 15:33:08 +03:00
|
|
|
for (int i = 0; i < numberofdesktops; i++) {
|
2023-09-29 22:33:36 +03:00
|
|
|
PagerSvg* pagersvg = new PagerSvg(i + 1, orientation, this);
|
2023-09-26 15:33:08 +03:00
|
|
|
m_layout->addItem(pagersvg);
|
|
|
|
m_pagersvgs.append(pagersvg);
|
2014-11-13 19:30:51 +02:00
|
|
|
}
|
|
|
|
|
2023-09-26 15:33:08 +03:00
|
|
|
m_actions.clear();
|
|
|
|
if (!m_adddesktopaction) {
|
|
|
|
m_adddesktopaction = new QAction(
|
|
|
|
KIcon("list-add"), i18n("&Add Virtual Desktop"),
|
|
|
|
this
|
|
|
|
);
|
2014-11-13 19:30:51 +02:00
|
|
|
}
|
2023-09-26 15:33:08 +03:00
|
|
|
m_actions.append(m_adddesktopaction);
|
|
|
|
connect(
|
|
|
|
m_adddesktopaction, SIGNAL(triggered(bool)),
|
|
|
|
this , SLOT(slotAddDesktop())
|
|
|
|
);
|
|
|
|
if (numberofdesktops > 1) {
|
|
|
|
if (!m_removedesktopaction) {
|
|
|
|
m_removedesktopaction = new QAction(
|
|
|
|
KIcon("list-remove"), i18n("&Remove Last Virtual Desktop"),
|
|
|
|
this
|
|
|
|
);
|
|
|
|
}
|
|
|
|
m_actions.append(m_removedesktopaction);
|
|
|
|
connect(
|
|
|
|
m_removedesktopaction, SIGNAL(triggered(bool)),
|
|
|
|
this , SLOT(slotRemoveDesktop())
|
|
|
|
);
|
2014-11-13 19:30:51 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-09-26 15:33:08 +03:00
|
|
|
void PagerApplet::slotAddDesktop()
|
2014-11-13 19:30:51 +02:00
|
|
|
{
|
2023-09-26 15:33:08 +03:00
|
|
|
NETRootInfo netrootinfo(QX11Info::display(), NET::NumberOfDesktops);
|
|
|
|
netrootinfo.setNumberOfDesktops(netrootinfo.numberOfDesktops() + 1);
|
2014-11-13 19:30:51 +02:00
|
|
|
}
|
|
|
|
|
2023-09-26 15:33:08 +03:00
|
|
|
void PagerApplet::slotRemoveDesktop()
|
2014-11-13 19:30:51 +02:00
|
|
|
{
|
2023-09-26 15:33:08 +03:00
|
|
|
NETRootInfo netrootinfo(QX11Info::display(), NET::NumberOfDesktops);
|
|
|
|
const int numberofdesktops = netrootinfo.numberOfDesktops();
|
|
|
|
if (numberofdesktops > 1) {
|
|
|
|
netrootinfo.setNumberOfDesktops(netrootinfo.numberOfDesktops() - 1);
|
2014-11-13 19:30:51 +02:00
|
|
|
} else {
|
2023-09-26 15:33:08 +03:00
|
|
|
kWarning() << "there is only one desktop";
|
2014-11-13 19:30:51 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-09-26 23:25:26 +03:00
|
|
|
void PagerApplet::slotConfigAccepted()
|
|
|
|
{
|
|
|
|
slotUpdateLayout();
|
2023-09-27 17:55:58 +03:00
|
|
|
m_kcmdesktopproxy->save();
|
2023-09-26 23:25:26 +03:00
|
|
|
emit configNeedsSaving();
|
|
|
|
}
|
|
|
|
|
2015-02-27 09:28:46 +00:00
|
|
|
#include "moc_pager.cpp"
|
2023-09-26 15:33:08 +03:00
|
|
|
#include "pager.moc"
|