7#include "waylandstartuptasksmodel.h"
8#include "libtaskmanager_debug.h"
11#include <KConfigGroup>
12#include <KConfigWatcher>
14#include <qwayland-plasma-window-management.h>
19#include <QtWaylandClient/QWaylandClientExtensionTemplate>
21using namespace Qt::StringLiterals;
26class PlasmaActivation :
public QObject,
public QtWayland::org_kde_plasma_activation
30 PlasmaActivation(::org_kde_plasma_activation *
object)
31 : QtWayland::org_kde_plasma_activation(object)
34 ~PlasmaActivation()
override
38 void org_kde_plasma_activation_app_id(
const QString &app_id)
override
42 void org_kde_plasma_activation_finished()
override
47 void appId(
const QString &appId);
50class PlasmaActivationFeedback :
public QWaylandClientExtensionTemplate<PlasmaActivationFeedback>,
public QtWayland::org_kde_plasma_activation_feedback
54 PlasmaActivationFeedback()
55 : QWaylandClientExtensionTemplate(1)
57 connect(
this, &QWaylandClientExtension::activeChanged,
this, [
this] {
63 ~PlasmaActivationFeedback()
70 void newActivation(PlasmaActivation *activation);
73 void org_kde_plasma_activation_feedback_activation(::org_kde_plasma_activation *
id)
override
75 Q_EMIT newActivation(
new PlasmaActivation(
id));
79class Q_DECL_HIDDEN WaylandStartupTasksModel::Private
82 Private(WaylandStartupTasksModel *q);
84 void addActivation(PlasmaActivation *activation);
85 void removeActivation(PlasmaActivation *activation);
95 std::unique_ptr<PlasmaActivation> activation;
98 WaylandStartupTasksModel *q;
99 KConfigWatcher::Ptr configWatcher =
nullptr;
100 std::unique_ptr<PlasmaActivationFeedback> feedback =
nullptr;
101 std::vector<Startup> startups;
102 std::chrono::seconds startupTimeout = std::chrono::seconds::zero();
105WaylandStartupTasksModel::Private::Private(WaylandStartupTasksModel *q)
110void WaylandStartupTasksModel::Private::init()
120void WaylandStartupTasksModel::Private::loadConfig()
122 KConfigGroup feedbackConfig(configWatcher->config(), u
"FeedbackStyle"_s);
124 if (!feedbackConfig.readEntry(
"TaskbarButton",
true)) {
125 q->beginResetModel();
132 const KConfigGroup taskbarButtonConfig(configWatcher->config(), u
"TaskbarButtonSettings"_s);
133 startupTimeout = std::chrono::seconds(taskbarButtonConfig.readEntry(
"Timeout", 5));
135 feedback = std::make_unique<PlasmaActivationFeedback>();
137 QObject::connect(feedback.get(), &PlasmaActivationFeedback::activeChanged, q, [
this] {
138 if (!feedback->isActive()) {
139 q->beginResetModel();
145 QObject::connect(feedback.get(), &PlasmaActivationFeedback::newActivation, q, [
this](PlasmaActivation *activation) {
146 addActivation(activation);
150void WaylandStartupTasksModel::Private::addActivation(PlasmaActivation *activation)
156 if (desktopFilePath.
isEmpty()) {
157 qCWarning(TASKMANAGER_DEBUG) <<
"Got invalid activation app_id:" << appId;
161 const QUrl launcherUrl(
QString(u
"applications:" + desktopFileName));
164 const int count = startups.size();
166 startups.push_back(Startup{
167 .name = appData.name,
168 .icon = appData.icon,
169 .applicationId = appId,
170 .launcherUrl = launcherUrl,
171 .activation = std::unique_ptr<PlasmaActivation>(activation),
178 removeActivation(activation);
181 timeoutTimer->
start(startupTimeout);
184 QObject::connect(activation, &PlasmaActivation::finished, q, [
this, activation]() {
185 removeActivation(activation);
189void WaylandStartupTasksModel::Private::removeActivation(PlasmaActivation *activation)
191 auto it = std::find_if(startups.begin(), startups.end(), [activation](
const Startup &startup) {
192 return startup.activation.get() == activation;
194 if (it == startups.end()) {
197 const int position = std::distance(startups.begin(), it);
198 q->beginRemoveRows(
QModelIndex(), position, position);
203WaylandStartupTasksModel::WaylandStartupTasksModel(
QObject *parent)
204 : AbstractTasksModel(parent)
205 , d(new Private(this))
210WaylandStartupTasksModel::~WaylandStartupTasksModel()
217 if (!index.
isValid() ||
static_cast<size_t>(index.
row()) >= d->startups.size()) {
221 const auto &data = d->startups[index.
row()];
226 }
else if (role == AppId) {
227 return data.applicationId;
228 }
else if (role == AppName) {
230 }
else if (role == LauncherUrl || role == LauncherUrlWithoutIcon) {
231 return data.launcherUrl;
232 }
else if (role == IsStartup) {
234 }
else if (role == CanLaunchNewInstance) {
236 }
else if (role == IsOnAllVirtualDesktops) {
240 return AbstractTasksModel::data(index, role);
243int WaylandStartupTasksModel::rowCount(
const QModelIndex &parent)
const
245 return parent.
isValid() ? 0 : d->startups.size();
250#include "waylandstartuptasksmodel.moc"
static Ptr create(const KSharedConfig::Ptr &config)
void configChanged(const KConfigGroup &group, const QByteArrayList &names)
static KSharedConfig::Ptr openConfig(const QString &fileName=QString(), OpenFlags mode=FullConfig, QStandardPaths::StandardLocation type=QStandardPaths::GenericConfigLocation)
void init(KXmlGuiWindow *window, KGameDifficulty *difficulty=nullptr)
QString name(GameStandardAction id)
bool isValid() const const
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
QString locate(StandardLocation type, const QString &fileName, LocateOptions options)
bool isEmpty() const const
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
void setSingleShot(bool singleShot)
QUrl fromLocalFile(const QString &localFile)