Plasma

corona.cpp
1 /*
2  SPDX-FileCopyrightText: 2007 Matt Broadstone <[email protected]>
3  SPDX-FileCopyrightText: 2007-2011 Aaron Seigo <[email protected]>
4  SPDX-FileCopyrightText: 2007 Riccardo Iaconelli <[email protected]>
5  SPDX-FileCopyrightText: 2009 Chani Armitage <[email protected]>
6 
7  SPDX-License-Identifier: LGPL-2.0-or-later
8 */
9 
10 #include "corona.h"
11 #include "private/corona_p.h"
12 
13 #include <QDebug>
14 #include <QGuiApplication>
15 #include <QMimeData>
16 #include <QPainter>
17 #include <QScreen>
18 #include <QTimer>
19 
20 #include <KLocalizedString>
21 
22 #include <cmath>
23 
24 #include "containment.h"
25 #include "debug_p.h"
26 #include "pluginloader.h"
27 #include "private/applet_p.h"
28 #include "private/containment_p.h"
29 #include "private/timetracker.h"
30 
31 #if PLASMA_BUILD_DEPRECATED_SINCE(5, 83)
32 #include "packagestructure.h"
33 #include "private/package_p.h"
34 #endif
35 
36 using namespace Plasma;
37 
38 namespace Plasma
39 {
40 Corona::Corona(QObject *parent)
41  : QObject(parent)
42  , d(new CoronaPrivate(this))
43 {
44  d->init();
45 
46 #ifndef NDEBUG
47  if (qEnvironmentVariableIsSet("PLASMA_TRACK_STARTUP")) {
48  new TimeTracker(this);
49  }
50 #endif
51 }
52 
53 Corona::~Corona()
54 {
55  KConfigGroup trans(KSharedConfig::openConfig(), "PlasmaTransientsConfig");
56  trans.deleteGroup();
57 
58  delete d;
59 }
60 
61 #if PLASMA_BUILD_DEPRECATED_SINCE(5, 6)
62 Plasma::Package Corona::package() const
63 {
64  return Package(d->package);
65 }
66 
67 void Corona::setPackage(const Plasma::Package &package)
68 {
69  setKPackage(*package.d->internalPackage);
70  Q_EMIT packageChanged(package);
71 }
72 #endif
73 
74 KPackage::Package Corona::kPackage() const
75 {
76  return d->package;
77 }
78 
79 void Corona::setKPackage(const KPackage::Package &package)
80 {
81  d->package = package;
82  Q_EMIT kPackageChanged(package);
83 }
84 
85 void Corona::saveLayout(const QString &configName) const
86 {
87  KSharedConfigPtr c;
88 
89  if (configName.isEmpty() || configName == d->configName) {
90  c = config();
91  } else {
93  }
94 
95  d->saveLayout(c);
96 }
97 
98 void Corona::exportLayout(KConfigGroup &config, QList<Containment *> containments)
99 {
100  const auto groupList = config.groupList();
101  for (const QString &group : groupList) {
102  KConfigGroup cg(&config, group);
103  cg.deleteGroup();
104  }
105 
106  // temporarily unlock so that removal works
107  Types::ImmutabilityType oldImm = immutability();
108  d->immutability = Types::Mutable;
109 
110  KConfigGroup dest(&config, "Containments");
111  KConfigGroup dummy;
112  for (Plasma::Containment *c : std::as_const(containments)) {
113  c->save(dummy);
114  c->config().reparent(&dest);
115 
116  // ensure the containment is unlocked
117  // this is done directly because we have to bypass any Types::SystemImmutable checks
118  c->Applet::d->immutability = Types::Mutable;
119  const auto lstApplet = c->applets();
120  for (Applet *a : lstApplet) {
121  a->d->immutability = Types::Mutable;
122  }
123 
124  c->destroy();
125  }
126 
127  // restore immutability
128  d->immutability = oldImm;
129 
130  config.sync();
131 }
132 
133 void Corona::requestConfigSync()
134 {
135  // constant controlling how long between requesting a configuration sync
136  // and one happening should occur. currently 10 seconds
137  static const int CONFIG_SYNC_TIMEOUT = 10000;
138 
139  // TODO: should we check into our immutability before doing this?
140 
141  // NOTE: this is a pretty simplistic model: we simply save no more than CONFIG_SYNC_TIMEOUT
142  // after the first time this is called. not much of a heuristic for save points, but
143  // it should at least compress these activities a bit and provide a way for applet
144  // authors to ween themselves from the sync() disease. A more interesting/dynamic
145  // algorithm for determining when to actually sync() to disk might be better, though.
146  if (!d->configSyncTimer->isActive()) {
147  d->configSyncTimer->start(CONFIG_SYNC_TIMEOUT);
148  }
149 }
150 
151 void Corona::requireConfigSync()
152 {
153  d->syncConfig();
154 }
155 
156 void Corona::loadLayout(const QString &configName)
157 {
158  if (!configName.isEmpty() && configName != d->configName) {
159  // if we have a new config name passed in, then use that as the config file for this Corona
160  d->config = nullptr;
161  d->configName = configName;
162  }
163 
164  KConfigGroup conf(config(), QString());
165  if (!config()->groupList().isEmpty()) {
166  d->importLayout(conf, false);
167  } else {
168  loadDefaultLayout();
169  d->notifyContainmentsReady();
170  }
171 
172  KConfigGroup cg(config(), "General");
173  setImmutability((Plasma::Types::ImmutabilityType)cg.readEntry("immutability", (int)Plasma::Types::Mutable));
174 }
175 
176 QList<Plasma::Containment *> Corona::importLayout(const KConfigGroup &conf)
177 {
178  return d->importLayout(conf, true);
179 }
180 
181 #if PLASMA_BUILD_DEPRECATED_SINCE(5, 46)
182 Containment *Corona::containmentForScreen(int screen) const
183 {
184  for (Containment *containment : std::as_const(d->containments)) {
185  if (containment->screen() == screen //
186  && (containment->containmentType() == Plasma::Types::DesktopContainment //
187  || containment->containmentType() == Plasma::Types::CustomContainment)) {
188  return containment;
189  }
190  }
191 
192  return nullptr;
193 }
194 
195 Containment *Corona::containmentForScreen(int screen, const QString &defaultPluginIfNonExistent, const QVariantList &defaultArgs)
196 {
197  return containmentForScreen(screen, QString(), defaultPluginIfNonExistent, defaultArgs);
198 }
199 #endif
200 
201 Containment *Corona::containmentForScreen(int screen, const QString &activity, const QString &defaultPluginIfNonExistent, const QVariantList &defaultArgs)
202 {
203  Containment *containment = nullptr;
204 
205  for (Containment *cont : std::as_const(d->containments)) {
206  /* clang-format off */
207  if (cont->lastScreen() == screen
208  && ((cont->activity().isEmpty() || activity.isEmpty()) || cont->activity() == activity)
209  && (cont->containmentType() == Plasma::Types::DesktopContainment
210  || cont->containmentType() == Plasma::Types::CustomContainment)) { /* clang-format on */
211  containment = cont;
212  }
213  }
214 
215  if (!containment && !defaultPluginIfNonExistent.isEmpty()) {
216  // screen requests are allowed to bypass immutability
217  if (screen >= 0) {
218  Plasma::Types::ImmutabilityType imm = d->immutability;
219  d->immutability = Types::Mutable;
220  containment = d->addContainment(defaultPluginIfNonExistent, defaultArgs, 0, screen, false);
221 
222  d->immutability = imm;
223  }
224  }
225 
226  if (containment) {
227  containment->setActivity(activity);
228  }
229  return containment;
230 }
231 
232 QList<Containment *> Corona::containmentsForActivity(const QString &activity)
233 {
234  QList<Containment *> conts;
235 
236  if (activity.isEmpty()) {
237  return conts;
238  }
239 
240  std::copy_if(d->containments.begin(), d->containments.end(), std::back_inserter(conts), [activity](Containment *cont) {
241  return cont->activity() == activity //
242  && (cont->containmentType() == Plasma::Types::DesktopContainment //
243  || cont->containmentType() == Plasma::Types::CustomContainment);
244  });
245 
246  return conts;
247 }
248 
249 QList<Containment *> Corona::containmentsForScreen(int screen)
250 {
251  QList<Containment *> conts;
252 
253  if (screen < 0) {
254  return conts;
255  }
256 
257  std::copy_if(d->containments.begin(), d->containments.end(), std::back_inserter(conts), [screen](Containment *cont) {
258  return cont->lastScreen() == screen //
259  && (cont->containmentType() == Plasma::Types::DesktopContainment //
260  || cont->containmentType() == Plasma::Types::CustomContainment);
261  });
262 
263  return conts;
264 }
265 
266 QList<Containment *> Corona::containments() const
267 {
268  return d->containments;
269 }
270 
271 bool Corona::isStartupCompleted() const
272 {
273  return d->containmentsStarting <= 0;
274 }
275 
276 KSharedConfigPtr Corona::config() const
277 {
278  if (!d->config) {
279  d->config = KSharedConfig::openConfig(d->configName, KConfig::SimpleConfig);
280  }
281 
282  return d->config;
283 }
284 
285 Containment *Corona::createContainment(const QString &name, const QVariantList &args)
286 {
287  if (d->immutability == Types::Mutable || args.contains(QVariant::fromValue(QStringLiteral("org.kde.plasma:force-create")))) {
288  return d->addContainment(name, args, 0, -1, false);
289  }
290 
291  return nullptr;
292 }
293 
294 Containment *Corona::createContainmentDelayed(const QString &name, const QVariantList &args)
295 {
296  if (d->immutability == Types::Mutable) {
297  return d->addContainment(name, args, 0, -1, true);
298  }
299 
300  return nullptr;
301 }
302 
303 int Corona::screenForContainment(const Containment *) const
304 {
305  return -1;
306 }
307 
308 int Corona::numScreens() const
309 {
310  return 1;
311 }
312 
313 QRegion Corona::availableScreenRegion(int id) const
314 {
315  return QRegion(screenGeometry(id));
316 }
317 
318 QRect Corona::availableScreenRect(int id) const
319 {
320  return screenGeometry(id);
321 }
322 
323 void Corona::loadDefaultLayout()
324 {
325  // Default implementation does nothing
326 }
327 
328 Types::ImmutabilityType Corona::immutability() const
329 {
330  return d->immutability;
331 }
332 
333 void Corona::setImmutability(const Types::ImmutabilityType immutable)
334 {
335  if (d->immutability == immutable || d->immutability == Types::SystemImmutable) {
336  return;
337  }
338 
339 #ifndef NDEBUG
340  // qCDebug(LOG_PLASMA) << "setting immutability to" << immutable;
341 #endif
342  d->immutability = immutable;
343  d->updateContainmentImmutability();
344  // tell non-containments that might care (like plasmaapp or a custom corona)
345  Q_EMIT immutabilityChanged(immutable);
346 
347  // update our actions
348  QAction *action = d->actions.action(QStringLiteral("lock widgets"));
349  if (action) {
350  if (d->immutability == Types::SystemImmutable) {
351  action->setEnabled(false);
352  action->setVisible(false);
353  } else {
354  bool unlocked = d->immutability == Types::Mutable;
355  action->setText(unlocked ? i18n("Lock Widgets") : i18n("Unlock Widgets"));
356  action->setIcon(QIcon::fromTheme(unlocked ? QStringLiteral("object-locked") : QStringLiteral("object-unlocked")));
357  action->setEnabled(true);
358  action->setVisible(true);
359  }
360  }
361 
362  action = d->actions.action(QStringLiteral("edit mode"));
363  if (action) {
364  switch (d->immutability) {
365  case Types::UserImmutable:
366  action->setEnabled(false);
367  action->setVisible(true);
368  break;
369  case Types::SystemImmutable:
370  action->setEnabled(false);
371  action->setVisible(false);
372  break;
373  case Types::Mutable:
374  default:
375  action->setEnabled(true);
376  action->setVisible(true);
377  break;
378  }
379  }
380 
381  if (d->immutability != Types::SystemImmutable) {
382  KConfigGroup cg(config(), "General");
383 
384  // we call the dptr member directly for locked since isImmutable()
385  // also checks kiosk and parent containers
386  cg.writeEntry("immutability", (int)d->immutability);
387  requestConfigSync();
388  }
389 
390  if (d->immutability != Types::Mutable) {
391  setEditMode(false);
392  }
393 }
394 
395 void Corona::setEditMode(bool edit)
396 {
397  if (edit == d->editMode || (edit && d->immutability != Plasma::Types::Mutable)) {
398  return;
399  }
400 
401  QAction *editAction = d->actions.action(QStringLiteral("edit mode"));
402  if (editAction) {
403  if (edit) {
404  editAction->setText(i18n("Exit Edit Mode"));
405  } else {
406  editAction->setText(i18n("Enter Edit Mode"));
407  }
408  }
409 
410  if (!edit) {
411  requireConfigSync();
412  }
413 
414  d->editMode = edit;
415  Q_EMIT editModeChanged(edit);
416 }
417 
418 bool Corona::isEditMode() const
419 {
420  return d->editMode;
421 }
422 
423 QList<Plasma::Types::Location> Corona::freeEdges(int screen) const
424 {
426  /* clang-format off */
427  freeEdges << Plasma::Types::TopEdge
431  /* clang-format on */
432 
433  const auto containments = this->containments();
434  for (Containment *containment : containments) {
435  if (containment->screen() == screen && freeEdges.contains(containment->location())) {
436  freeEdges.removeAll(containment->location());
437  }
438  }
439 
440  return freeEdges;
441 }
442 
443 KActionCollection *Corona::actions() const
444 {
445  return &d->actions;
446 }
447 
448 CoronaPrivate::CoronaPrivate(Corona *corona)
449  : q(corona)
450  , immutability(Types::Mutable)
451  , config(nullptr)
452  , configSyncTimer(new QTimer(corona))
453  , actions(corona)
454  , containmentsStarting(0)
455 {
456  // TODO: make Package path configurable
457 
459  configName = QCoreApplication::instance()->applicationName() + QStringLiteral("-appletsrc");
460  } else {
461  configName = QStringLiteral("plasma-appletsrc");
462  }
463 }
464 
465 CoronaPrivate::~CoronaPrivate()
466 {
467  qDeleteAll(containments);
468 }
469 
470 void CoronaPrivate::init()
471 {
472  desktopDefaultsConfig = KConfigGroup(KSharedConfig::openConfig(package.filePath("defaults")), "Desktop");
473 
474  configSyncTimer->setSingleShot(true);
475  QObject::connect(configSyncTimer, SIGNAL(timeout()), q, SLOT(syncConfig()));
476 
477  // some common actions
478  actions.setConfigGroup(QStringLiteral("Shortcuts"));
479 
480  QAction *lockAction = actions.add<QAction>(QStringLiteral("lock widgets"));
481  QObject::connect(lockAction, SIGNAL(triggered(bool)), q, SLOT(toggleImmutability()));
482  lockAction->setText(i18n("Lock Widgets"));
483  lockAction->setAutoRepeat(true);
484  lockAction->setIcon(QIcon::fromTheme(QStringLiteral("object-locked")));
487 
488  // fake containment/applet actions
489  KActionCollection *containmentActions = AppletPrivate::defaultActions(q); // containment has to start with applet stuff
490  ContainmentPrivate::addDefaultActions(containmentActions); // now it's really containment
491 
492  QAction *editAction = actions.add<QAction>(QStringLiteral("edit mode"));
493  QObject::connect(editAction, &QAction::triggered, q, [this]() {
494  q->setEditMode(!q->isEditMode());
495  });
496  editAction->setText(i18n("Enter Edit Mode"));
497  editAction->setAutoRepeat(true);
498  editAction->setIcon(QIcon::fromTheme(QStringLiteral("document-edit")));
500  editAction->setShortcut(QKeySequence(QStringLiteral("alt+d, e")));
502 }
503 
504 void CoronaPrivate::toggleImmutability()
505 {
506  if (immutability == Types::Mutable) {
507  q->setImmutability(Types::UserImmutable);
508  } else {
509  q->setImmutability(Types::Mutable);
510  }
511 }
512 
513 void CoronaPrivate::saveLayout(KSharedConfigPtr cg) const
514 {
515  KConfigGroup containmentsGroup(cg, "Containments");
516  for (const Containment *containment : containments) {
517  QString cid = QString::number(containment->id());
518  KConfigGroup containmentConfig(&containmentsGroup, cid);
519  containment->save(containmentConfig);
520  }
521 }
522 
523 void CoronaPrivate::updateContainmentImmutability()
524 {
525  for (Containment *c : std::as_const(containments)) {
526  // we need to tell each containment that immutability has been altered
527  c->updateConstraints(Types::ImmutableConstraint);
528  }
529 }
530 
531 void CoronaPrivate::containmentDestroyed(QObject *obj)
532 {
533  // we do a static_cast here since it really isn't an Containment by this
534  // point anymore since we are in the qobject dtor. we don't actually
535  // try and do anything with it, we just need the value of the pointer
536  // so this unsafe looking code is actually just fine.
537  Containment *containment = static_cast<Plasma::Containment *>(obj);
538  int index = containments.indexOf(containment);
539 
540  if (index > -1) {
541  containments.removeAt(index);
542  q->requestConfigSync();
543  }
544 }
545 
546 void CoronaPrivate::syncConfig()
547 {
548  q->config()->sync();
549  Q_EMIT q->configSynced();
550 }
551 
552 Containment *CoronaPrivate::addContainment(const QString &name, const QVariantList &args, uint id, int lastScreen, bool delayedInit)
553 {
554  QString pluginName = name;
555  Containment *containment = nullptr;
556  Applet *applet = nullptr;
557 
558  // qCDebug(LOG_PLASMA) << "Loading" << name << args << id;
559 
560  if (pluginName.isEmpty() || pluginName == QLatin1String("default")) {
561  // default to the desktop containment
562  pluginName = desktopDefaultsConfig.readEntry("Containment", "org.kde.desktopcontainment");
563  }
564 
565  bool loadingNull = pluginName == QLatin1String("null");
566  if (!loadingNull) {
567  applet = PluginLoader::self()->loadApplet(pluginName, id, args);
568  containment = dynamic_cast<Containment *>(applet);
569  if (containment) {
570  containment->setParent(q);
571  }
572  }
573 
574  if (!containment) {
575  if (!loadingNull) {
576 #ifndef NDEBUG
577  // qCDebug(LOG_PLASMA) << "loading of containment" << name << "failed.";
578 #endif
579  }
580 
581  // in case we got a non-Containment from Applet::loadApplet or
582  // a null containment was requested
583  if (applet) {
584  // the applet probably doesn't know what's hit it, so let's pretend it can be
585  // initialized to make assumptions in the applet's dtor safer
586  applet->init();
587  delete applet;
588  }
589  applet = containment = new Containment(q, KPluginMetaData(), QVariantList{QVariant(), QVariant(), id});
590  if (lastScreen >= 0) {
591  containment->d->lastScreen = lastScreen;
592  }
593  // if it's a dummy containment, just say its ui is ready, not blocking the corona
595 
596  // we want to provide something and don't care about the failure to launch
597  containment->setFormFactor(Plasma::Types::Planar);
598  }
599 
600  // if this is a new containment, we need to ensure that there are no stale
601  // configuration data around
602  if (id == 0) {
603  KConfigGroup conf(q->config(), "Containments");
604  conf = KConfigGroup(&conf, QString::number(containment->id()));
605  conf.deleteGroup();
606  }
607 
608  // make sure the containments are sorted by id
609  auto position = std::lower_bound(containments.begin(), containments.end(), containment, [](Plasma::Containment *c1, Plasma::Containment *c2) {
610  return c1->id() < c2->id();
611  });
612  containments.insert(position, containment);
613 
614  QObject::connect(containment, SIGNAL(destroyed(QObject *)), q, SLOT(containmentDestroyed(QObject *)));
617 
618  if (!delayedInit) {
619  containment->init();
620  KConfigGroup cg = containment->config();
621  containment->restore(cg);
623  containment->save(cg);
624  q->requestConfigSync();
625  containment->flushPendingConstraintsEvents();
626  Q_EMIT q->containmentAdded(containment);
627  // if id = 0 a new containment has been created, not restored
628  if (id == 0) {
629  Q_EMIT q->containmentCreated(containment);
630  }
631  }
632 
633  return containment;
634 }
635 
636 QList<Plasma::Containment *> CoronaPrivate::importLayout(const KConfigGroup &conf, bool mergeConfig)
637 {
638  if (!conf.isValid()) {
639  return QList<Containment *>();
640  }
641 
642  QList<Plasma::Containment *> newContainments;
643  QSet<uint> containmentsIds;
644 
645  for (Containment *containment : std::as_const(containments)) {
646  containmentsIds.insert(containment->id());
647  }
648 
649  KConfigGroup containmentsGroup(&conf, "Containments");
650  QStringList groups = containmentsGroup.groupList();
651  std::sort(groups.begin(), groups.end());
652 
653  for (const QString &group : std::as_const(groups)) {
654  KConfigGroup containmentConfig(&containmentsGroup, group);
655 
656  if (containmentConfig.entryMap().isEmpty()) {
657  continue;
658  } else if (containmentConfig.readEntry(QStringLiteral("transient"), false)) {
659  containmentConfig.deleteGroup();
660  continue;
661  }
662 
663  uint cid = group.toUInt();
664  if (containmentsIds.contains(cid)) {
665  cid = ++AppletPrivate::s_maxAppletId;
666  } else if (cid > AppletPrivate::s_maxAppletId) {
667  AppletPrivate::s_maxAppletId = cid;
668  }
669 
670  if (mergeConfig) {
671  KConfigGroup realConf(q->config(), "Containments");
672  realConf = KConfigGroup(&realConf, QString::number(cid));
673  // in case something was there before us
674  realConf.deleteGroup();
675  containmentConfig.copyTo(&realConf);
676  }
677 
678  // qCDebug(LOG_PLASMA) << "got a containment in the config, trying to make a" << containmentConfig.readEntry("plugin", QString()) << "from" << group;
679 #ifndef NDEBUG
680  // qCDebug(LOG_PLASMA) << "!!{} STARTUP TIME" << QTime().msecsTo(QTime::currentTime()) << "Adding Containment" << containmentConfig.readEntry("plugin",
681  // QString());
682 #endif
683  Containment *c = addContainment(containmentConfig.readEntry("plugin", QString()), QVariantList(), cid, -1);
684  if (!c) {
685  continue;
686  }
687 
688  newContainments.append(c);
689  containmentsIds.insert(c->id());
690 
691 #ifndef NDEBUG
692 // qCDebug(LOG_PLASMA) << "!!{} STARTUP TIME" << QTime().msecsTo(QTime::currentTime()) << "Restored Containment" << c->pluginName();
693 #endif
694  }
695 
696  if (!mergeConfig) {
697  notifyContainmentsReady();
698  }
699 
700  return newContainments;
701 }
702 
703 void CoronaPrivate::notifyContainmentsReady()
704 {
705  containmentsStarting = 0;
706  for (Containment *containment : std::as_const(containments)) {
707  if (!containment->isUiReady() && containment->screen() >= 0) {
708  ++containmentsStarting;
709  QObject::connect(containment, &Plasma::Containment::uiReadyChanged, q, [this](bool ready) {
710  containmentReady(ready);
711  });
712  }
713  }
714 
715  if (containmentsStarting <= 0) {
716  Q_EMIT q->startupCompleted();
717  }
718 }
719 
720 void CoronaPrivate::containmentReady(bool ready)
721 {
722  if (!ready) {
723  return;
724  }
725  --containmentsStarting;
726  if (containmentsStarting <= 0) {
727  Q_EMIT q->startupCompleted();
728  }
729 }
730 
731 } // namespace Plasma
732 
733 #include "moc_corona.cpp"
Enums and constants used in Plasma.
Definition: plasma.h:28
void append(const T &value)
void restore(KConfigGroup &group) override
void setFormFactor(Plasma::Types::FormFactor formFactor)
Sets the form factor for this Containment.
QString readEntry(const char *key, const char *aDefault=nullptr) const
void writeEntry(const char *key, const char *value, WriteConfigFlags pFlags=Normal)
QList< QAction * > actions() const
KConfigGroup config() const
Returns the KConfigGroup to access the applets configuration.
Definition: applet.cpp:270
void setShortcutContext(Qt::ShortcutContext context)
@ ImmutableConstraint
the immutability (locked) nature of the applet changed
Definition: plasma.h:44
Namespace for everything in libplasma.
Definition: datamodel.cpp:14
QString number(int n, int base)
void requestConfigSync()
Schedules a flush-to-disk synchronization of the configuration state at the next convenient moment.
Definition: corona.cpp:133
QVariant fromValue(const T &value)
int removeAll(const T &value)
@ CustomContainment
A containment that is neither a desktop nor a panel but something application specific.
Definition: plasma.h:119
Applet * loadApplet(const QString &name, uint appletId=0, const QVariantList &args=QVariantList())
Load an Applet plugin.
uint id() const
Definition: applet.cpp:173
@ UserImmutable
The user has requested a lock down, and can undo the lock down at any time.
Definition: plasma.h:237
@ ControlAction
Generic control, similar to ConfigureAction TODO: better doc.
Definition: plasma.h:132
@ DesktopContainment
A desktop containment.
Definition: plasma.h:116
QIcon fromTheme(const QString &name)
bool isValid() const
void configNeedsSaving()
Emitted when an applet has changed values in its configuration and wishes for them to be saved at the...
@ BottomEdge
Along the bottom of the screen.
Definition: plasma.h:165
void setShortcut(const QKeySequence &shortcut)
void setAutoRepeat(bool)
void deleteGroup(const char *group, WriteConfigFlags flags=Normal)
@ LeftEdge
Along the left side of the screen.
Definition: plasma.h:166
bool contains(const T &value) const const
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
@ Mutable
The item can be modified in any way.
Definition: plasma.h:236
static KSharedConfig::Ptr openConfig(const QString &fileName=QString(), OpenFlags mode=FullConfig, QStandardPaths::StandardLocation type=QStandardPaths::GenericConfigLocation)
void save(KConfigGroup &group) const override
void setIcon(const QIcon &icon)
void uiReadyChanged(bool uiReady)
Emitted when the ui has been fully loaded and is fully working.
QString i18n(const char *text, const TYPE &arg...)
This debugging class is meant to provide an overview of how the objects change over time and hopefull...
Definition: timetracker.h:44
A bookkeeping Scene for Plasma::Applets.
Definition: corona.h:27
virtual void init()
This method is called once the applet is loaded and added to a Corona.
Definition: applet.cpp:168
void screenOwnerChanged(int isScreen)
This signal indicates that a containment has been newly associated (or dissociated) with a physical s...
bool isEmpty() const const
QCoreApplication * instance()
void setText(const QString &text)
@ StartupCompletedConstraint
application startup has completed
Definition: plasma.h:45
bool contains(const T &value) const const
void setVisible(bool)
void setData(const QVariant &userData)
void init() override
Reimplemented from Applet.
Definition: containment.cpp:85
void triggered(bool checked)
void flushPendingConstraintsEvents()
Sends all pending constraints updates to the applet.
Definition: applet.cpp:602
void setEnabled(bool)
@ Planar
The applet lives in a plane and has two degrees of freedom to grow.
Definition: plasma.h:73
QString name(StandardShortcut id)
static PluginLoader * self()
Return the active plugin loader.
void setParent(QObject *parent)
@ UiReadyConstraint
The ui has been completely loaded.
Definition: plasma.h:47
ImmutabilityType
Defines the immutability of items like applets, corona and containments they can be free to modify,...
Definition: plasma.h:235
@ TopEdge
Along the top of the screen.
Definition: plasma.h:164
QSet::iterator insert(const T &value)
QList::iterator begin()
KConfig * config()
bool sync() override
void setActivity(const QString &activityId)
Sets the current activity by id.
object representing an installed Plasma package
Definition: package.h:76
QList::iterator end()
The base class for plugins that provide backgrounds and applet grouping containers.
Definition: containment.h:45
@ RightEdge
Along the right side of the screen.
Definition: plasma.h:167
The base Applet class.
Definition: applet.h:71
void screenChanged(int newScreen)
This signal indicates that a containment has been associated (or dissociated) with a physical screen.
void updateConstraints(Plasma::Types::Constraints constraints=Plasma::Types::AllConstraints)
Called when any of the geometry constraints have been updated.
Definition: applet.cpp:350
ApplicationShortcut
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Tue Feb 7 2023 04:15:01 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.