Merge branch 'davidedmundson/containmentcleanup2'
This commit is contained in:
commit
a36c2787b9
@ -25,7 +25,7 @@
|
||||
#include <QMouseEvent>
|
||||
#include <QTimer>
|
||||
#include <QQuickWindow>
|
||||
|
||||
#include <QScreen>
|
||||
#include <QDebug>
|
||||
|
||||
static const int PressAndHoldDelay = 800;
|
||||
@ -107,12 +107,12 @@ void MouseEventListener::hoverMoveEvent(QHoverEvent * event)
|
||||
}
|
||||
|
||||
QQuickWindow *w = window();
|
||||
QPoint screenPos = QPoint();
|
||||
QPoint screenPos;
|
||||
if (w) {
|
||||
w->mapToGlobal(event->pos());
|
||||
screenPos = w->mapToGlobal(event->pos());
|
||||
}
|
||||
|
||||
KDeclarativeMouseEvent dme(event->pos().x(), event->pos().y(), screenPos.x(), screenPos.y(), Qt::NoButton, Qt::NoButton, event->modifiers());
|
||||
KDeclarativeMouseEvent dme(event->pos().x(), event->pos().y(), screenPos.x(), screenPos.y(), Qt::NoButton, Qt::NoButton, event->modifiers(), 0);
|
||||
emit positionChanged(&dme);
|
||||
}
|
||||
|
||||
@ -137,8 +137,8 @@ void MouseEventListener::mousePressEvent(QMouseEvent *me)
|
||||
}
|
||||
m_buttonDownPos[me->button()] = me->pos();
|
||||
|
||||
KDeclarativeMouseEvent dme(me->pos().x(), me->pos().y(), me->screenPos().x(), me->screenPos().y(), me->button(), me->buttons(), me->modifiers());
|
||||
m_pressAndHoldEvent = new KDeclarativeMouseEvent(me->pos().x(), me->pos().y(), me->screenPos().x(), me->screenPos().y(), me->button(), me->buttons(), me->modifiers());
|
||||
KDeclarativeMouseEvent dme(me->pos().x(), me->pos().y(), me->screenPos().x(), me->screenPos().y(), me->button(), me->buttons(), me->modifiers(), screenForGlobalPos(me->globalPos()));
|
||||
m_pressAndHoldEvent = new KDeclarativeMouseEvent(me->pos().x(), me->pos().y(), me->screenPos().x(), me->screenPos().y(), me->button(), me->buttons(), me->modifiers(), screenForGlobalPos(me->globalPos()));
|
||||
emit pressed(&dme);
|
||||
m_pressed = true;
|
||||
|
||||
@ -152,7 +152,7 @@ void MouseEventListener::mouseMoveEvent(QMouseEvent *me)
|
||||
return;
|
||||
}
|
||||
|
||||
KDeclarativeMouseEvent dme(me->pos().x(), me->pos().y(), me->screenPos().x(), me->screenPos().y(), me->button(), me->buttons(), me->modifiers());
|
||||
KDeclarativeMouseEvent dme(me->pos().x(), me->pos().y(), me->screenPos().x(), me->screenPos().y(), me->button(), me->buttons(), me->modifiers(), screenForGlobalPos(me->globalPos()));
|
||||
emit positionChanged(&dme);
|
||||
}
|
||||
|
||||
@ -163,7 +163,7 @@ void MouseEventListener::mouseReleaseEvent(QMouseEvent *me)
|
||||
return;
|
||||
}
|
||||
|
||||
KDeclarativeMouseEvent dme(me->pos().x(), me->pos().y(), me->screenPos().x(), me->screenPos().y(), me->button(), me->buttons(), me->modifiers());
|
||||
KDeclarativeMouseEvent dme(me->pos().x(), me->pos().y(), me->screenPos().x(), me->screenPos().y(), me->button(), me->buttons(), me->modifiers(), screenForGlobalPos(me->globalPos()));
|
||||
m_pressed = false;
|
||||
emit released(&dme);
|
||||
|
||||
@ -217,8 +217,8 @@ bool MouseEventListener::childMouseEventFilter(QQuickItem *item, QEvent *event)
|
||||
|
||||
//the parent will receive events in its own coordinates
|
||||
const QPointF myPos = item->mapToItem(this, me->pos());
|
||||
KDeclarativeMouseEvent dme(myPos.x(), myPos.y(), me->screenPos().x(), me->screenPos().y(), me->button(), me->buttons(), me->modifiers());
|
||||
m_pressAndHoldEvent = new KDeclarativeMouseEvent(myPos.x(), myPos.y(), me->screenPos().x(), me->screenPos().y(), me->button(), me->buttons(), me->modifiers());
|
||||
KDeclarativeMouseEvent dme(myPos.x(), myPos.y(), me->screenPos().x(), me->screenPos().y(), me->button(), me->buttons(), me->modifiers(), screenForGlobalPos(me->globalPos()));
|
||||
m_pressAndHoldEvent = new KDeclarativeMouseEvent(myPos.x(), myPos.y(), me->screenPos().x(), me->screenPos().y(), me->button(), me->buttons(), me->modifiers(), screenForGlobalPos(me->globalPos()));
|
||||
//qDebug() << "pressed in sceneEventFilter";
|
||||
m_buttonDownPos[me->button()] = me->pos();
|
||||
emit pressed(&dme);
|
||||
@ -236,14 +236,14 @@ bool MouseEventListener::childMouseEventFilter(QQuickItem *item, QEvent *event)
|
||||
const QPointF myPos = item->mapToItem(this, he->pos());
|
||||
|
||||
QQuickWindow *w = window();
|
||||
QPoint screenPos = QPoint();
|
||||
QPoint screenPos;
|
||||
if (w) {
|
||||
w->mapToGlobal(myPos.toPoint());
|
||||
screenPos = w->mapToGlobal(myPos.toPoint());
|
||||
}
|
||||
|
||||
KDeclarativeMouseEvent dme(myPos.x(), myPos.y(), screenPos.x(), screenPos.y(), Qt::NoButton, Qt::NoButton, he->modifiers());
|
||||
KDeclarativeMouseEvent dme(myPos.x(), myPos.y(), screenPos.x(), screenPos.y(), Qt::NoButton, Qt::NoButton, he->modifiers(), 0);
|
||||
//qDebug() << "positionChanged..." << dme.x() << dme.y();
|
||||
m_pressAndHoldEvent = new KDeclarativeMouseEvent(myPos.x(), myPos.y(), screenPos.x(), screenPos.y(), Qt::NoButton, Qt::NoButton, he->modifiers());
|
||||
m_pressAndHoldEvent = new KDeclarativeMouseEvent(myPos.x(), myPos.y(), screenPos.x(), screenPos.y(), Qt::NoButton, Qt::NoButton, he->modifiers(),0);
|
||||
emit positionChanged(&dme);
|
||||
break;
|
||||
}
|
||||
@ -255,9 +255,9 @@ bool MouseEventListener::childMouseEventFilter(QQuickItem *item, QEvent *event)
|
||||
}
|
||||
|
||||
const QPointF myPos = item->mapToItem(this, me->pos());
|
||||
KDeclarativeMouseEvent dme(myPos.x(), myPos.y(), me->screenPos().x(), me->screenPos().y(), me->button(), me->buttons(), me->modifiers());
|
||||
KDeclarativeMouseEvent dme(myPos.x(), myPos.y(), me->screenPos().x(), me->screenPos().y(), me->button(), me->buttons(), me->modifiers(), screenForGlobalPos(me->globalPos()));
|
||||
//qDebug() << "positionChanged..." << dme.x() << dme.y();
|
||||
m_pressAndHoldEvent = new KDeclarativeMouseEvent(myPos.x(), myPos.y(), me->screenPos().x(), me->screenPos().y(), me->button(), me->buttons(), me->modifiers());
|
||||
m_pressAndHoldEvent = new KDeclarativeMouseEvent(myPos.x(), myPos.y(), me->screenPos().x(), me->screenPos().y(), me->button(), me->buttons(), me->modifiers(), screenForGlobalPos(me->globalPos()));
|
||||
emit positionChanged(&dme);
|
||||
break;
|
||||
}
|
||||
@ -266,7 +266,7 @@ bool MouseEventListener::childMouseEventFilter(QQuickItem *item, QEvent *event)
|
||||
QMouseEvent *me = static_cast<QMouseEvent *>(event);
|
||||
|
||||
const QPointF myPos = item->mapToItem(this, me->pos());
|
||||
KDeclarativeMouseEvent dme(myPos.x(), myPos.y(), me->screenPos().x(), me->screenPos().y(), me->button(), me->buttons(), me->modifiers());
|
||||
KDeclarativeMouseEvent dme(myPos.x(), myPos.y(), me->screenPos().x(), me->screenPos().y(), me->button(), me->buttons(), me->modifiers(), screenForGlobalPos(me->globalPos()));
|
||||
m_pressed = false;
|
||||
|
||||
emit released(&dme);
|
||||
@ -292,5 +292,16 @@ bool MouseEventListener::childMouseEventFilter(QQuickItem *item, QEvent *event)
|
||||
// return false;
|
||||
}
|
||||
|
||||
QScreen* MouseEventListener::screenForGlobalPos(const QPoint& globalPos)
|
||||
{
|
||||
foreach(QScreen *screen, QGuiApplication::screens()) {
|
||||
if (screen->geometry().contains(globalPos)) {
|
||||
return screen;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#include "mouseeventlistener.moc"
|
||||
|
||||
|
@ -33,19 +33,22 @@ class KDeclarativeMouseEvent : public QObject
|
||||
Q_PROPERTY(int button READ button)
|
||||
Q_PROPERTY(Qt::MouseButtons buttons READ buttons)
|
||||
Q_PROPERTY(Qt::KeyboardModifiers modifiers READ modifiers)
|
||||
Q_PROPERTY(QScreen* screen READ screen CONSTANT)
|
||||
|
||||
public:
|
||||
KDeclarativeMouseEvent(int x, int y, int screenX, int screenY,
|
||||
Qt::MouseButton button,
|
||||
Qt::MouseButtons buttons,
|
||||
Qt::KeyboardModifiers modifiers)
|
||||
Qt::KeyboardModifiers modifiers,
|
||||
QScreen* screen)
|
||||
: m_x(x),
|
||||
m_y(y),
|
||||
m_screenX(screenX),
|
||||
m_screenY(screenY),
|
||||
m_button(button),
|
||||
m_buttons(buttons),
|
||||
m_modifiers(modifiers)
|
||||
m_modifiers(modifiers),
|
||||
m_screen(screen)
|
||||
{}
|
||||
|
||||
int x() const { return m_x; }
|
||||
@ -55,6 +58,7 @@ public:
|
||||
int button() const { return m_button; }
|
||||
Qt::MouseButtons buttons() const { return m_buttons; }
|
||||
Qt::KeyboardModifiers modifiers() const { return m_modifiers; }
|
||||
QScreen* screen() const { return m_screen; }
|
||||
|
||||
// only for internal usage
|
||||
void setX(int x) { m_x = x; }
|
||||
@ -68,6 +72,7 @@ private:
|
||||
Qt::MouseButton m_button;
|
||||
Qt::MouseButtons m_buttons;
|
||||
Qt::KeyboardModifiers m_modifiers;
|
||||
QScreen *m_screen;
|
||||
};
|
||||
|
||||
class KDeclarativeWheelEvent : public QObject
|
||||
@ -173,6 +178,8 @@ private Q_SLOTS:
|
||||
void handlePressAndHold();
|
||||
|
||||
private:
|
||||
static QScreen* screenForGlobalPos(const QPoint &globalPos);
|
||||
|
||||
QPointF buttonDownPos(int btn) const;
|
||||
bool m_pressed;
|
||||
KDeclarativeMouseEvent* m_pressAndHoldEvent;
|
||||
|
@ -178,9 +178,6 @@ void Containment::restore(KConfigGroup &group)
|
||||
restoreContents(group);
|
||||
setImmutability((Types::ImmutabilityType)group.readEntry("immutability", (int)Types::Mutable));
|
||||
|
||||
//qDebug() << "setScreen from restore";
|
||||
d->setScreen(group.readEntry("screen", d->screen));
|
||||
|
||||
KConfigGroup cfg = KConfigGroup(corona()->config(), "ActionPlugins");
|
||||
cfg = KConfigGroup(&cfg, QString::number(containmentType()));
|
||||
|
||||
@ -230,7 +227,7 @@ void Containment::save(KConfigGroup &g) const
|
||||
// locking is saved in Applet::save
|
||||
Applet::save(group);
|
||||
|
||||
group.writeEntry("screen", d->screen);
|
||||
// group.writeEntry("screen", d->screen);
|
||||
group.writeEntry("lastScreen", d->lastScreen);
|
||||
group.writeEntry("formfactor", (int)d->formFactor);
|
||||
group.writeEntry("location", (int)d->location);
|
||||
@ -429,14 +426,9 @@ QList<Applet *> Containment::applets() const
|
||||
return d->applets;
|
||||
}
|
||||
|
||||
void Containment::setScreen(int newScreen)
|
||||
{
|
||||
d->setScreen(newScreen);
|
||||
}
|
||||
|
||||
int Containment::screen() const
|
||||
{
|
||||
return d->screen;
|
||||
return corona()->screenForContainment(this);
|
||||
}
|
||||
|
||||
int Containment::lastScreen() const
|
||||
@ -546,6 +538,23 @@ QString Containment::activity() const
|
||||
return d->activityId;
|
||||
}
|
||||
|
||||
void Containment::reactToScreenChange()
|
||||
{
|
||||
int newScreen = screen();
|
||||
|
||||
KConfigGroup c = config();
|
||||
if (newScreen >= 0) {
|
||||
d->lastScreen = newScreen;
|
||||
c.writeEntry("lastScreen", d->lastScreen);
|
||||
}
|
||||
emit configNeedsSaving();
|
||||
emit screenChanged(newScreen);
|
||||
|
||||
if (newScreen >= 0) {
|
||||
emit activate();
|
||||
}
|
||||
}
|
||||
|
||||
} // Plasma namespace
|
||||
|
||||
|
||||
|
@ -133,15 +133,6 @@ class PLASMA_EXPORT Containment : public Applet
|
||||
*/
|
||||
QList<Applet *> applets() const;
|
||||
|
||||
/**
|
||||
* Sets the physical screen this Containment is associated with.
|
||||
*
|
||||
* @param screen the screen number this containment is the desktop for, or -1
|
||||
* if it is not serving as the desktop for any screen
|
||||
* @param desktop the virtual desktop to also associate this this screen with
|
||||
*/
|
||||
void setScreen(int screen);
|
||||
|
||||
/**
|
||||
* @return the screen number this containment is serving as the desktop for
|
||||
* or -1 if none
|
||||
@ -243,14 +234,12 @@ Q_SIGNALS:
|
||||
void showAddWidgetsInterface(const QPointF &pos);
|
||||
|
||||
/**
|
||||
* This signal indicates that a containment has been newly
|
||||
* This signal indicates that a containment has been
|
||||
* associated (or dissociated) with a physical screen.
|
||||
*
|
||||
* @param wasScreen the screen it was associated with
|
||||
* @param isScreen the screen it is now associated with
|
||||
* @param containment the containment switching screens
|
||||
* @param newScreen the screen it is now associated with
|
||||
*/
|
||||
void screenChanged(int wasScreen, int isScreen, Plasma::Containment *containment);
|
||||
void screenChanged(int newScreen);
|
||||
|
||||
/**
|
||||
* Emitted when the user wants to configure/change the containment, or an applet inside it.
|
||||
@ -317,6 +306,8 @@ Q_SIGNALS:
|
||||
*/
|
||||
void setDrawWallpaper(bool drawWallpaper);
|
||||
|
||||
void reactToScreenChange();
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Called when the contents of the containment should be saved. By default this saves
|
||||
|
@ -175,22 +175,6 @@ Containment *Corona::containmentForScreen(int screen) const
|
||||
return 0;
|
||||
}
|
||||
|
||||
Containment *Corona::containmentForScreen(int screen, const QString &defaultPluginIfNonExistent)
|
||||
{
|
||||
Containment *containment = containmentForScreen(screen);
|
||||
if (!containment && !defaultPluginIfNonExistent.isEmpty()) {
|
||||
// screen requests are allowed to bypass immutability
|
||||
if (screen >= 0 && screen < numScreens()) {
|
||||
containment = d->addContainment(defaultPluginIfNonExistent, QVariantList(), 0);
|
||||
if (containment) {
|
||||
containment->setScreen(screen);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return containment;
|
||||
}
|
||||
|
||||
QList<Containment*> Corona::containments() const
|
||||
{
|
||||
return d->containments;
|
||||
@ -214,6 +198,12 @@ Containment *Corona::createContainment(const QString &name, const QVariantList &
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Corona::screenForContainment(const Containment* containment) const
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int Corona::numScreens() const
|
||||
{
|
||||
return 1;
|
||||
|
@ -99,17 +99,6 @@ public:
|
||||
*/
|
||||
Containment *containmentForScreen(int screen) const;
|
||||
|
||||
/**
|
||||
* Returns the Containment for a given physical screen and desktop, creating one
|
||||
* if none exists
|
||||
*
|
||||
* @param screen number of the physical screen to locate
|
||||
* @param defaultPluginIfNonExistent the plugin to load by default; "null" is an empty
|
||||
* Containment and "default" creates the default plugin
|
||||
* @since 4.6
|
||||
*/
|
||||
Containment *containmentForScreen(int screen, const QString &defaultPluginIfNonExistent);
|
||||
|
||||
/**
|
||||
* Returns the number of screens available to plasma.
|
||||
* Subclasses should override this method as the default
|
||||
@ -168,6 +157,12 @@ public:
|
||||
*/
|
||||
void exportLayout(KConfigGroup &config, QList<Containment*> containments);
|
||||
|
||||
/**
|
||||
* @returns the id of the screen which is showing @p containment
|
||||
* -1 is returned if the containment is not associated with a screen.
|
||||
*/
|
||||
virtual int screenForContainment(const Containment *containment) const;
|
||||
|
||||
public Q_SLOTS:
|
||||
/**
|
||||
* Load applet layout from a config file. The results will be added to the
|
||||
|
@ -71,85 +71,6 @@ void ContainmentPrivate::addDefaultActions(KActionCollection *actions, Containme
|
||||
appletBrowserAction->setData(Plasma::Types::AddAction);
|
||||
}
|
||||
|
||||
void ContainmentPrivate::setScreen(int newScreen)
|
||||
{
|
||||
// What we want to do in here is:
|
||||
// * claim the screen as our own
|
||||
// * signal whatever may be watching this containment about the switch
|
||||
// * if we are a full screen containment, then:
|
||||
// * resize to match the screen if we're that kind of containment
|
||||
// * kick other full-screen containments off this screen
|
||||
// * if we had a screen, then give our screen to the containment
|
||||
// we kick out
|
||||
//
|
||||
// a screen of -1 means no associated screen.
|
||||
Corona *corona = q->corona();
|
||||
Q_ASSERT(corona);
|
||||
|
||||
//if it's an offscreen widget, don't allow to claim a screen, after all it's *off*screen
|
||||
//TODO: port away qgv
|
||||
/* should decide in a different way if this is a dashboard containment
|
||||
if (corona->offscreenWidgets().contains(q)) {
|
||||
return;
|
||||
}*/
|
||||
|
||||
if (newScreen < -1) {
|
||||
newScreen = -1;
|
||||
}
|
||||
|
||||
//qDebug() << activity() << "setting screen to " << newScreen << "and type is" << type;
|
||||
|
||||
Containment *swapScreensWith(0);
|
||||
const bool isDesktopContainment = type == Plasma::Types::DesktopContainment ||
|
||||
type == Plasma::Types::CustomContainment;
|
||||
if (isDesktopContainment) {
|
||||
if (newScreen > -1) {
|
||||
// sanity check to make sure someone else doesn't have this screen already!
|
||||
Containment *currently = corona->containmentForScreen(newScreen);
|
||||
if (currently && currently != q) {
|
||||
#ifndef NDEBUG
|
||||
// qDebug() << "currently is on screen" << currently->screen()
|
||||
// << "desktop" << currently->desktop()
|
||||
// << "and is" << currently->activity()
|
||||
// << (QObject*)currently << "i'm" << (QObject*)q;
|
||||
#endif
|
||||
currently->setScreen(-1);
|
||||
swapScreensWith = currently;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int oldScreen = screen;
|
||||
screen = newScreen;
|
||||
|
||||
q->updateConstraints(Plasma::Types::ScreenConstraint);
|
||||
|
||||
if (oldScreen != newScreen) {
|
||||
#ifndef NDEBUG
|
||||
// qDebug() << "going to signal change for" << q
|
||||
// << ", old screen & desktop:" << oldScreen
|
||||
// << ", new:" << screen << desktop;
|
||||
#endif
|
||||
KConfigGroup c = q->config();
|
||||
c.writeEntry("screen", screen);
|
||||
if (newScreen != -1) {
|
||||
lastScreen = newScreen;
|
||||
c.writeEntry("lastScreen", lastScreen);
|
||||
}
|
||||
emit q->configNeedsSaving();
|
||||
emit q->screenChanged(oldScreen, newScreen, q);
|
||||
}
|
||||
|
||||
if (swapScreensWith) {
|
||||
//qDebug() << "setScreen due to swap, part 2";
|
||||
swapScreensWith->setScreen(oldScreen);
|
||||
}
|
||||
|
||||
if (newScreen >= 0) {
|
||||
emit q->activate();
|
||||
}
|
||||
}
|
||||
|
||||
KConfigGroup ContainmentPrivate::containmentActionsConfig() const
|
||||
{
|
||||
KConfigGroup cfg = KConfigGroup(q->corona()->config(), "ActionPlugins");
|
||||
|
@ -49,7 +49,6 @@ public:
|
||||
: q(c),
|
||||
formFactor(Types::Planar),
|
||||
location(Types::Floating),
|
||||
screen(-1), // no screen
|
||||
lastScreen(-1), // never had a screen
|
||||
type(Plasma::Types::NoContainmentType),
|
||||
drawWallpaper(false)
|
||||
@ -67,7 +66,6 @@ public:
|
||||
|
||||
void triggerShowAddWidgets();
|
||||
void checkStatus(Plasma::Types::ItemStatus status);
|
||||
void setScreen(int newScreen);
|
||||
|
||||
/**
|
||||
* Called when constraints have been updated on this containment to provide
|
||||
@ -103,7 +101,6 @@ public:
|
||||
QSet <Applet *> loadingApplets;
|
||||
QString wallpaper;
|
||||
QHash<QString, ContainmentActions*> localActionPlugins;
|
||||
int screen;
|
||||
int lastScreen;
|
||||
QString activityId;
|
||||
Types::ContainmentType type;
|
||||
|
@ -74,6 +74,7 @@ void PlasmaQuickViewPrivate::setContainment(Plasma::Containment *cont)
|
||||
//FIXME:we need a way to reparent to *NO* graphics item, but this makes Qt crash
|
||||
oldGraphicObject->setParent(containment.data());
|
||||
}
|
||||
containment.data()->reactToScreenChange();
|
||||
}
|
||||
|
||||
containment = cont;
|
||||
@ -88,6 +89,7 @@ void PlasmaQuickViewPrivate::setContainment(Plasma::Containment *cont)
|
||||
emit q->containmentChanged();
|
||||
|
||||
if (cont) {
|
||||
cont->reactToScreenChange();
|
||||
QObject::connect(cont, &Plasma::Containment::locationChanged,
|
||||
q, &PlasmaQuickView::locationChanged);
|
||||
QObject::connect(cont, &Plasma::Containment::formFactorChanged,
|
||||
@ -168,7 +170,7 @@ PlasmaQuickView::PlasmaQuickView(Plasma::Corona *corona, QWindow *parent)
|
||||
setColor(Qt::transparent);
|
||||
|
||||
|
||||
QObject::connect(screen(), &QScreen::virtualGeometryChanged,
|
||||
QObject::connect(screen(), &QScreen::geometryChanged,
|
||||
this, &PlasmaQuickView::screenGeometryChanged);
|
||||
|
||||
if (!corona->package().isValid()) {
|
||||
|
@ -198,7 +198,8 @@ Plasma::Applet *ContainmentInterface::addApplet(const QString &plugin, const QVa
|
||||
|
||||
emit appletAdded(appletGraphicObject, pos.x(), pos.y());
|
||||
emit appletsChanged();
|
||||
}
|
||||
} else
|
||||
blockSignals(false);
|
||||
return applet;
|
||||
}
|
||||
|
||||
|
@ -42,34 +42,23 @@
|
||||
Activity::Activity(const QString &id, Plasma::Corona *parent)
|
||||
: QObject(parent),
|
||||
m_id(id),
|
||||
m_plugin("org.kde.desktopcontainment"),
|
||||
m_plugin("org.kde.desktopcontainment"),//FIXME ask the corona
|
||||
m_info(new KActivities::Info(id, this)),
|
||||
m_activityConsumer(new KActivities::Consumer(this)),
|
||||
m_corona(parent),
|
||||
m_current(false)
|
||||
{
|
||||
m_name = m_info->name();
|
||||
m_icon = m_info->icon();
|
||||
|
||||
connect(m_info, SIGNAL(infoChanged()), this, SLOT(activityChanged()));
|
||||
connect(m_info, SIGNAL(stateChanged(KActivities::Info::State)), this, SLOT(activityStateChanged(KActivities::Info::State)));
|
||||
connect(m_info, SIGNAL(started()), this, SLOT(opened()));
|
||||
connect(m_info, SIGNAL(stopped()), this, SLOT(closed()));
|
||||
connect(m_info, SIGNAL(removed()), this, SLOT(removed()));
|
||||
connect(m_info, SIGNAL(stateChanged(KActivities::Info::State)), this, SIGNAL(stateChanged()));
|
||||
connect(m_info, SIGNAL(started()), this, SIGNAL(opened()));
|
||||
connect(m_info, SIGNAL(stopped()), this, SIGNAL(closed()));
|
||||
connect(m_info, SIGNAL(removed()), this, SIGNAL(removed()));
|
||||
connect(m_info, SIGNAL(removed()), this, SLOT(cleanupActivity()));
|
||||
|
||||
connect(m_activityConsumer, SIGNAL(currentActivityChanged(QString)), this, SLOT(checkIfCurrent()));
|
||||
checkIfCurrent();
|
||||
|
||||
//find your containments
|
||||
foreach (Plasma::Containment *cont, m_corona->containments()) {
|
||||
if ((cont->containmentType() == Plasma::Types::DesktopContainment ||
|
||||
cont->containmentType() == Plasma::Types::CustomContainment) &&
|
||||
cont->activity() == id) {
|
||||
insertContainment(cont);
|
||||
}
|
||||
}
|
||||
|
||||
//qDebug() << m_containments.size();
|
||||
}
|
||||
|
||||
Activity::~Activity()
|
||||
@ -82,12 +71,6 @@ void Activity::activityChanged()
|
||||
setIcon(m_info->icon());
|
||||
}
|
||||
|
||||
void Activity::activityStateChanged(KActivities::Info::State state)
|
||||
{
|
||||
Q_UNUSED(state)
|
||||
emit stateChanged();
|
||||
}
|
||||
|
||||
QString Activity::id()
|
||||
{
|
||||
return m_id;
|
||||
@ -132,227 +115,39 @@ void Activity::remove()
|
||||
KActivities::Controller().removeActivity(m_id);
|
||||
}
|
||||
|
||||
void Activity::removed()
|
||||
void Activity::cleanupActivity()
|
||||
{
|
||||
if (! m_containments.isEmpty()) {
|
||||
//FIXME only m_corona has authority to remove properly
|
||||
qDebug() << "!!!!! if your widgets are locked you've hit a BUG now";
|
||||
foreach (Plasma::Containment *c, m_containments) {
|
||||
c->destroy();
|
||||
}
|
||||
}
|
||||
|
||||
const QString name = "activities/" + m_id;
|
||||
QFile::remove(QStandardPaths::writableLocation(QStandardPaths::DataLocation)+QChar('/')+name);
|
||||
}
|
||||
|
||||
Plasma::Containment* Activity::containmentForScreen(int screen)
|
||||
{
|
||||
Plasma::Containment *containment = m_containments.value(screen);
|
||||
|
||||
if (!containment) {
|
||||
qDebug() << "adding containment for" << screen;
|
||||
// first look to see if there are any unnasigned containments that are candidates for
|
||||
// being sucked into this Activity
|
||||
foreach (Plasma::Containment *c, m_corona->containments()) {
|
||||
if ((c->containmentType() == Plasma::Types::DesktopContainment ||
|
||||
c->containmentType() == Plasma::Types::CustomContainment) &&
|
||||
c->activity().isEmpty() &&
|
||||
m_containments.key(c, -2) == -2) {
|
||||
containment = c;
|
||||
containment->setScreen(screen);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!containment) {
|
||||
// we ask for the containment for the screen with a default plugin, because
|
||||
// this allows the corona to either grab one for us that already exists matching
|
||||
// screen, or create a new one. this also works regardless of immutability
|
||||
containment = m_corona->containmentForScreen(screen, m_plugin);
|
||||
|
||||
if (!containment || !containment->activity().isEmpty()) {
|
||||
// possibly a plugin failure, let's go for the default
|
||||
containment = m_corona->containmentForScreen(screen, "org.kde.desktopcontainment");
|
||||
}
|
||||
|
||||
//we don't want to steal contaiments from other activities
|
||||
if (!containment) {
|
||||
// we failed to even get the default; we're screwed.
|
||||
Q_ASSERT(false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!containment->activity().isEmpty() &&
|
||||
containment->activity() != m_id) {
|
||||
// we got a containment, but it belongs to some other activity; let's unassign it
|
||||
// from a screen and grab a new one
|
||||
containment->setScreen(-1);
|
||||
containment = m_corona->containmentForScreen(screen, m_plugin);
|
||||
|
||||
if (!containment) {
|
||||
// possibly a plugin failure, let's go for the default
|
||||
containment = m_corona->containmentForScreen(screen, "org.kde.desktopcontainment");
|
||||
}
|
||||
|
||||
if (containment) {
|
||||
containment->setScreen(screen);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (containment) {
|
||||
insertContainment(containment, screen);
|
||||
m_corona->requestConfigSync();
|
||||
}
|
||||
} else if (containment->screen() != screen) {
|
||||
// ensure the containment _also_ knows which screen we think it is on;
|
||||
// can happen when swapping between activities without stopping them first
|
||||
containment->setScreen(screen);
|
||||
}
|
||||
|
||||
QAction *closeAction = containment->actions()->action("remove");
|
||||
if (closeAction) {
|
||||
closeAction->setEnabled(false);
|
||||
closeAction->setVisible(false);
|
||||
}
|
||||
|
||||
return containment;
|
||||
}
|
||||
|
||||
void Activity::activate()
|
||||
{
|
||||
KActivities::Controller().setCurrentActivity(m_id);
|
||||
}
|
||||
|
||||
void Activity::ensureActive()
|
||||
{
|
||||
if (m_containments.isEmpty()) {
|
||||
opened();
|
||||
}
|
||||
|
||||
checkScreens();
|
||||
}
|
||||
|
||||
void Activity::checkScreens()
|
||||
{
|
||||
//ensure there's a containment for every screen & desktop.
|
||||
int numScreens = m_corona->numScreens();
|
||||
|
||||
for (int screen = 0; screen < numScreens; ++screen) {
|
||||
containmentForScreen(screen);
|
||||
}
|
||||
}
|
||||
|
||||
void Activity::setName(const QString &name)
|
||||
{
|
||||
if (m_name == name) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_name = name;
|
||||
}
|
||||
|
||||
void Activity::setIcon(const QString &icon)
|
||||
{
|
||||
if (m_icon == icon) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_icon = icon;
|
||||
}
|
||||
|
||||
void Activity::save(KConfig &external)
|
||||
{
|
||||
foreach (const QString &group, external.groupList()) {
|
||||
KConfigGroup cg(&external, group);
|
||||
cg.deleteGroup();
|
||||
}
|
||||
|
||||
//TODO: multi-screen saving/restoring, where each screen can be
|
||||
// independently restored: put each screen's containments into a
|
||||
// different group, e.g. [Screens][0][Containments], [Screens][1][Containments], etc
|
||||
KConfigGroup dest(&external, "Containments");
|
||||
KConfigGroup dummy;
|
||||
foreach (Plasma::Containment *c, m_containments) {
|
||||
c->save(dummy);
|
||||
KConfigGroup group(&dest, QString::number(c->id()));
|
||||
c->config().copyTo(&group);
|
||||
}
|
||||
|
||||
external.sync();
|
||||
}
|
||||
|
||||
void Activity::close()
|
||||
{
|
||||
KActivities::Controller().stopActivity(m_id);
|
||||
}
|
||||
|
||||
void Activity::closed()
|
||||
KConfigGroup Activity::config() const
|
||||
{
|
||||
const QString name = "activities/" + m_id;
|
||||
KConfig external(name, KConfig::SimpleConfig, QStandardPaths::GenericDataLocation);
|
||||
|
||||
//passing an empty string for the group name turns a kconfig into a kconfiggroup
|
||||
KConfigGroup group = external.group(QString());
|
||||
m_corona->exportLayout(group, m_containments.values());
|
||||
|
||||
//hrm, shouldn't the containments' deleted signals have done this for us?
|
||||
if (!m_containments.isEmpty()) {
|
||||
qDebug() << "isn't close supposed to *remove* containments??";
|
||||
m_containments.clear();
|
||||
}
|
||||
}
|
||||
|
||||
void Activity::replaceContainment(Plasma::Containment* containment)
|
||||
{
|
||||
insertContainment(containment, true);
|
||||
}
|
||||
|
||||
void Activity::insertContainment(Plasma::Containment* cont, bool force)
|
||||
{
|
||||
int screen = cont->lastScreen();
|
||||
|
||||
qDebug() << screen;
|
||||
if (screen == -1) {
|
||||
//the migration can't set lastScreen, so maybe we need to assign the containment here
|
||||
qDebug() << "found a lost one";
|
||||
screen = 0;
|
||||
}
|
||||
|
||||
if (!force && m_containments.contains(screen)) {
|
||||
//this almost certainly means someone has been meddling where they shouldn't
|
||||
//but we should protect them from harm anyways
|
||||
qDebug() << "@!@!@!@!@!@@@@rejecting containment!!!";
|
||||
cont->setActivity(QString());
|
||||
return;
|
||||
}
|
||||
|
||||
insertContainment(cont, screen);
|
||||
}
|
||||
|
||||
void Activity::insertContainment(Plasma::Containment* containment, int screen)
|
||||
{
|
||||
//ensure it's hooked up
|
||||
containment->setActivity(m_id);
|
||||
|
||||
m_containments.insert(screen, containment);
|
||||
connect(containment, SIGNAL(destroyed(QObject*)), this, SLOT(containmentDestroyed(QObject*)));
|
||||
}
|
||||
|
||||
void Activity::containmentDestroyed(QObject *object)
|
||||
{
|
||||
//safe here because we are not accessing it
|
||||
Plasma::Containment *deletedCont = static_cast<Plasma::Containment *>(object);
|
||||
|
||||
QHash<int, Plasma::Containment*>::iterator i;
|
||||
for (i = m_containments.begin(); i != m_containments.end(); ++i) {
|
||||
Plasma::Containment *cont = i.value();
|
||||
if (cont == deletedCont) {
|
||||
m_containments.remove(i.key());
|
||||
break;
|
||||
}
|
||||
}
|
||||
return external.group(QString());
|
||||
}
|
||||
|
||||
void Activity::open()
|
||||
@ -360,38 +155,6 @@ void Activity::open()
|
||||
KActivities::Controller().startActivity(m_id);
|
||||
}
|
||||
|
||||
void Activity::opened()
|
||||
{
|
||||
if (!m_containments.isEmpty()) {
|
||||
qDebug() << "already open!";
|
||||
return;
|
||||
}
|
||||
|
||||
const QString fileName = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QString("/activities/" + m_id);
|
||||
qDebug() << "&&&&&&&&&&&&&&&" << fileName;
|
||||
if (QFile::exists(fileName)) {
|
||||
{
|
||||
KConfig external(fileName, KConfig::SimpleConfig);
|
||||
|
||||
foreach (Plasma::Containment *newContainment, m_corona->importLayout(external.group(QByteArray()))) {
|
||||
insertContainment(newContainment);
|
||||
//ensure it's hooked up (if something odd happened we don't want orphan containments)
|
||||
newContainment->setActivity(m_id);
|
||||
}
|
||||
}
|
||||
|
||||
QFile::remove(fileName);
|
||||
}
|
||||
|
||||
if (m_containments.isEmpty()) {
|
||||
//TODO check if we need more for screens/desktops
|
||||
qDebug() << "open failed (bad file?). creating new containment";
|
||||
checkScreens();
|
||||
}
|
||||
|
||||
m_corona->requireConfigSync();
|
||||
}
|
||||
|
||||
void Activity::setDefaultPlugin(const QString &plugin)
|
||||
{
|
||||
m_plugin = plugin;
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include <QHash>
|
||||
|
||||
#include <kactivities/info.h>
|
||||
#include <kconfiggroup.h>
|
||||
|
||||
class QSize;
|
||||
class QString;
|
||||
@ -81,22 +82,6 @@ public:
|
||||
*/
|
||||
KActivities::Info::State state();
|
||||
|
||||
/**
|
||||
* save (copy) the activity out to an @p external config
|
||||
*/
|
||||
void save(KConfig &external);
|
||||
|
||||
/**
|
||||
* return the containment that belongs on @p screen and @p desktop
|
||||
* or null if none exists
|
||||
*/
|
||||
Plasma::Containment* containmentForScreen(int screen);
|
||||
|
||||
/**
|
||||
* make this activity's containments the active ones, loading them if necessary
|
||||
*/
|
||||
void ensureActive();
|
||||
|
||||
/**
|
||||
* set the plugin to use when creating new containments
|
||||
*/
|
||||
@ -107,11 +92,17 @@ public:
|
||||
*/
|
||||
const KActivities::Info * info() const;
|
||||
|
||||
KConfigGroup config() const;
|
||||
|
||||
Q_SIGNALS:
|
||||
void infoChanged();
|
||||
void stateChanged();
|
||||
void currentStatusChanged();
|
||||
|
||||
void removed();
|
||||
void opened();
|
||||
void closed();
|
||||
|
||||
public Q_SLOTS:
|
||||
void setName(const QString &name);
|
||||
void setIcon(const QString &icon);
|
||||
@ -136,34 +127,18 @@ public Q_SLOTS:
|
||||
*/
|
||||
void open();
|
||||
|
||||
/**
|
||||
* forcibly insert a containment, replacing the one on its screen/desktop
|
||||
*/
|
||||
void replaceContainment(Plasma::Containment* containment);
|
||||
|
||||
private Q_SLOTS:
|
||||
void containmentDestroyed(QObject *object);
|
||||
void activityChanged();
|
||||
void activityStateChanged(KActivities::Info::State);
|
||||
void checkIfCurrent();
|
||||
|
||||
void removed();
|
||||
void opened();
|
||||
void closed();
|
||||
void cleanupActivity();
|
||||
|
||||
private:
|
||||
void insertContainment(Plasma::Containment* cont, bool force=false);
|
||||
void insertContainment(Plasma::Containment* containment, int screen);
|
||||
void checkScreens();
|
||||
|
||||
QString m_id;
|
||||
QString m_name;
|
||||
QString m_icon;
|
||||
QString m_plugin;
|
||||
QHash<int, Plasma::Containment*> m_containments;
|
||||
KActivities::Info *m_info;
|
||||
KActivities::Consumer *m_activityConsumer;
|
||||
Plasma::Corona *m_corona;
|
||||
bool m_current;
|
||||
};
|
||||
|
||||
|
@ -40,6 +40,8 @@ PanelConfigView::PanelConfigView(Plasma::Containment *containment, PanelView *pa
|
||||
m_containment(containment),
|
||||
m_panelView(panelView)
|
||||
{
|
||||
setScreen(panelView->screen());
|
||||
connect(panelView, &PanelView::screenChanged, [=](QScreen *screen){setScreen(screen); syncGeometry();});
|
||||
|
||||
setFlags(Qt::FramelessWindowHint);
|
||||
|
||||
|
@ -35,7 +35,7 @@ class PanelView : public PlasmaQuickView
|
||||
Q_PROPERTY(int length READ length WRITE setLength NOTIFY lengthChanged)
|
||||
Q_PROPERTY(int maximumLength READ maximumLength WRITE setMaximumLength NOTIFY maximumLengthChanged)
|
||||
Q_PROPERTY(int minimumLength READ minimumLength WRITE setMinimumLength NOTIFY minimumLengthChanged)
|
||||
Q_PROPERTY(QScreen *screen READ screen NOTIFY screenChanged)
|
||||
Q_PROPERTY(QScreen *screen READ screen WRITE setScreen NOTIFY screenChanged)
|
||||
Q_PROPERTY(VisibilityMode visibilityMode READ visibilityMode WRITE setVisibilityMode)
|
||||
|
||||
public:
|
||||
|
@ -82,13 +82,6 @@ int Containment::screen() const
|
||||
return d->containment.data()->screen();
|
||||
}
|
||||
|
||||
void Containment::setScreen(int screen)
|
||||
{
|
||||
if (d->containment) {
|
||||
d->containment.data()->setScreen(screen);
|
||||
}
|
||||
}
|
||||
|
||||
QString Containment::wallpaperPlugin() const
|
||||
{
|
||||
return d->wallpaperPlugin;
|
||||
|
@ -37,6 +37,7 @@ namespace WorkspaceScripting
|
||||
class Containment : public Applet
|
||||
{
|
||||
Q_OBJECT
|
||||
///FIXME: add NOTIFY
|
||||
Q_PROPERTY(QString version READ version)
|
||||
Q_PROPERTY(QStringList configKeys READ configKeys)
|
||||
Q_PROPERTY(QStringList configGroups READ configGroups)
|
||||
@ -50,7 +51,7 @@ class Containment : public Applet
|
||||
Q_PROPERTY(QString type READ type)
|
||||
Q_PROPERTY(QString formFactor READ formFactor)
|
||||
Q_PROPERTY(QList<int> widgetIds READ widgetIds)
|
||||
Q_PROPERTY(int screen READ screen WRITE setScreen)
|
||||
Q_PROPERTY(int screen READ screen)
|
||||
Q_PROPERTY(int id READ id)
|
||||
|
||||
public:
|
||||
@ -66,7 +67,6 @@ public:
|
||||
void setName(const QString &name);
|
||||
|
||||
int screen() const;
|
||||
void setScreen(int screen);
|
||||
|
||||
Plasma::Applet *applet() const;
|
||||
Plasma::Containment *containment() const;
|
||||
|
@ -44,7 +44,7 @@ class Panel : public Containment
|
||||
Q_PROPERTY(QString type READ type)
|
||||
Q_PROPERTY(QString formFactor READ formFactor)
|
||||
Q_PROPERTY(QList<int> widgetIds READ widgetIds)
|
||||
Q_PROPERTY(int screen READ screen WRITE setScreen)
|
||||
Q_PROPERTY(int screen READ screen)
|
||||
Q_PROPERTY(QString location READ location WRITE setLocation)
|
||||
Q_PROPERTY(int id READ id)
|
||||
|
||||
|
@ -140,7 +140,6 @@ QScriptValue ScriptEngine::createContainment(const QString &type, const QString
|
||||
// some defaults
|
||||
c->setFormFactor(Plasma::Types::Horizontal);
|
||||
c->setLocation(Plasma::Types::TopEdge);
|
||||
c->setScreen(env->defaultPanelScreen());
|
||||
}
|
||||
c->updateConstraints(Plasma::Types::AllConstraints | Plasma::Types::StartupCompletedConstraint);
|
||||
c->flushPendingConstraintsEvents();
|
||||
|
@ -72,12 +72,12 @@ public:
|
||||
QList <DesktopView *> views;
|
||||
KActivities::Controller *activityController;
|
||||
KActivities::Consumer *activityConsumer;
|
||||
QHash <Plasma::Containment *, PanelView *> panelViews;
|
||||
QHash <const Plasma::Containment *, PanelView *> panelViews;
|
||||
KConfigGroup desktopDefaultsConfig;
|
||||
WorkspaceScripting::DesktopScriptEngine * scriptEngine;
|
||||
QList<Plasma::Containment *> waitingPanels;
|
||||
QSet<Plasma::Containment *> loadingDesktops;
|
||||
QHash<QString, Activity*> activities;
|
||||
QHash<QString, QHash<int, Plasma::Containment*> > desktopContainments;
|
||||
QTimer *waitingPanelsTimer;
|
||||
QAction *addPanelAction;
|
||||
QMenu *addPanelsMenu;
|
||||
@ -103,15 +103,8 @@ ShellCorona::ShellCorona(QObject *parent)
|
||||
connect(&d->appConfigSyncTimer, &QTimer::timeout,
|
||||
this, &ShellCorona::syncAppConfig);
|
||||
|
||||
connect(d->desktopWidget, &QDesktopWidget::resized,
|
||||
this, &ShellCorona::screenResized );
|
||||
connect(d->desktopWidget, &QDesktopWidget::workAreaResized,
|
||||
this, &ShellCorona::workAreaResized);
|
||||
|
||||
connect(this, &ShellCorona::containmentAdded,
|
||||
this, &ShellCorona::handleContainmentAdded);
|
||||
connect(this, &ShellCorona::screenOwnerChanged,
|
||||
this, &ShellCorona::updateScreenOwner);
|
||||
|
||||
d->scriptEngine = new WorkspaceScripting::DesktopScriptEngine(this, true);
|
||||
|
||||
@ -166,13 +159,15 @@ void ShellCorona::setShell(const QString &shell)
|
||||
unload();
|
||||
|
||||
d->shell = shell;
|
||||
KConfigGroup config(KSharedConfig::openConfig(), "General");
|
||||
Plasma::Package package = Plasma::PluginLoader::self()->loadPackage("Plasma/Shell");
|
||||
package.setPath(shell);
|
||||
setPackage(package);
|
||||
|
||||
load();
|
||||
//TODO: panel views should be synced here: either creating views for panels without, or deleting views for panels that don't have one anymore
|
||||
if (d->activityConsumer->serviceStatus() == KActivities::Consumer::Unknown) {
|
||||
connect(d->activityConsumer, SIGNAL(serviceStatusChanged(Consumer::ServiceStatus)), SLOT(load()), Qt::UniqueConnection);
|
||||
} else {
|
||||
load();
|
||||
}
|
||||
}
|
||||
|
||||
QString ShellCorona::shell() const
|
||||
@ -182,16 +177,36 @@ QString ShellCorona::shell() const
|
||||
|
||||
void ShellCorona::load()
|
||||
{
|
||||
if (d->shell.isEmpty()) return;
|
||||
if (d->shell.isEmpty() || d->activityConsumer->serviceStatus() == KActivities::Consumer::Unknown)
|
||||
return;
|
||||
disconnect(d->activityConsumer, SIGNAL(serviceStatusChanged(Consumer::ServiceStatus)), this, SLOT(load()));
|
||||
|
||||
loadLayout("plasma-" + d->shell + "-appletsrc");
|
||||
|
||||
checkActivities();
|
||||
if (containments().isEmpty()) {
|
||||
loadDefaultLayout();
|
||||
foreach(Plasma::Containment* containment, containments()) {
|
||||
containment->setActivity(d->activityConsumer->currentActivity());
|
||||
}
|
||||
}
|
||||
|
||||
processUpdateScripts();
|
||||
checkActivities();
|
||||
foreach(Plasma::Containment* containment, containments()) {
|
||||
if (containment->formFactor() == Plasma::Types::Horizontal ||
|
||||
containment->formFactor() == Plasma::Types::Vertical) {
|
||||
if (!d->waitingPanels.contains(containment)) {
|
||||
d->waitingPanels << containment;
|
||||
}
|
||||
} else {
|
||||
//FIXME ideally fix this, or at least document the crap out of it
|
||||
int screen = containment->lastScreen();
|
||||
if (screen < 0) {
|
||||
screen = d->desktopContainments[containment->activity()].count();
|
||||
}
|
||||
insertContainment(containment->activity(), screen, containment);
|
||||
}
|
||||
}
|
||||
|
||||
for (QScreen *screen : QGuiApplication::screens()) {
|
||||
screenAdded(screen);
|
||||
@ -199,13 +214,14 @@ void ShellCorona::load()
|
||||
connect(qApp, &QGuiApplication::screenAdded,
|
||||
this, &ShellCorona::screenAdded);
|
||||
|
||||
checkScreens();
|
||||
if (!d->waitingPanels.isEmpty()) {
|
||||
d->waitingPanelsTimer->start();
|
||||
}
|
||||
}
|
||||
|
||||
void ShellCorona::unload()
|
||||
{
|
||||
if (d->shell.isEmpty()) return;
|
||||
|
||||
qDeleteAll(containments());
|
||||
}
|
||||
|
||||
@ -239,92 +255,11 @@ void ShellCorona::processUpdateScripts()
|
||||
}
|
||||
}
|
||||
|
||||
Activity* ShellCorona::activity(const QString &id)
|
||||
{
|
||||
if (!d->activities.contains(id)) {
|
||||
//the add signal comes late sometimes
|
||||
activityAdded(id);
|
||||
}
|
||||
return d->activities.value(id);
|
||||
}
|
||||
|
||||
KActivities::Controller *ShellCorona::activityController()
|
||||
{
|
||||
return d->activityController;
|
||||
}
|
||||
|
||||
void ShellCorona::checkScreens(bool signalWhenExists)
|
||||
{
|
||||
// quick sanity check to ensure we have containments for each screen
|
||||
int num = numScreens();
|
||||
for (int i = 0; i < num; ++i) {
|
||||
checkScreen(i, signalWhenExists);
|
||||
}
|
||||
}
|
||||
|
||||
void ShellCorona::checkScreen(int screen, bool signalWhenExists)
|
||||
{
|
||||
// signalWhenExists is there to allow PlasmaApp to know when to create views
|
||||
// it does this only on containment addition, but in the case of a screen being
|
||||
// added and the containment already existing for that screen, no signal is emitted
|
||||
// and so PlasmaApp does not know that it needs to create a view for it. to avoid
|
||||
// taking care of that case in PlasmaApp (which would duplicate some of the code below,
|
||||
// ShellCorona will, when signalWhenExists is true, emit a containmentAdded signal
|
||||
// even if the containment actually existed prior to this method being called.
|
||||
//
|
||||
//note: the signal actually triggers view creation only for panels, atm.
|
||||
//desktop views are created in response to containment's screenChanged signal instead, which is
|
||||
//buggy (sometimes the containment thinks it's already on the screen, so no view is created)
|
||||
|
||||
//TODO: restore activities
|
||||
Activity *currentActivity = activity(d->activityController->currentActivity());
|
||||
//ensure the desktop(s) have a containment and view
|
||||
checkDesktop(currentActivity, signalWhenExists, screen);
|
||||
|
||||
|
||||
//ensure the panels get views too
|
||||
if (signalWhenExists) {
|
||||
foreach (Plasma::Containment * c, containments()) {
|
||||
if (c->screen() != screen) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Plasma::Types::ContainmentType t = c->containmentType();
|
||||
if (t == Plasma::Types::PanelContainment ||
|
||||
t == Plasma::Types::CustomPanelContainment) {
|
||||
emit containmentAdded(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ShellCorona::checkDesktop(Activity *activity, bool signalWhenExists, int screen)
|
||||
{
|
||||
Plasma::Containment *c = activity->containmentForScreen(screen);
|
||||
|
||||
//TODO: remove following when activities are restored
|
||||
if (!c) {
|
||||
c = createContainment(d->desktopDefaultsConfig.readEntry("Containment", "org.kde.desktopcontainment"));
|
||||
}
|
||||
|
||||
if (!c) {
|
||||
return;
|
||||
}
|
||||
|
||||
c->setScreen(screen);
|
||||
if (screen >= 0 || d->views.count() >= screen + 1) {
|
||||
d->views[screen]->setContainment(c);
|
||||
} else {
|
||||
qWarning() << "Invalid screen";
|
||||
}
|
||||
c->flushPendingConstraintsEvents();
|
||||
requestApplicationConfigSync();
|
||||
|
||||
if (signalWhenExists) {
|
||||
emit containmentAdded(c);
|
||||
}
|
||||
}
|
||||
|
||||
int ShellCorona::numScreens() const
|
||||
{
|
||||
return d->desktopWidget->screenCount();
|
||||
@ -353,54 +288,68 @@ PanelView *ShellCorona::panelView(Plasma::Containment *containment) const
|
||||
|
||||
///// SLOTS
|
||||
|
||||
void ShellCorona::screenCountChanged(int newCount)
|
||||
{
|
||||
qDebug() << "New screen count" << newCount;
|
||||
}
|
||||
|
||||
void ShellCorona::screenResized(int screen)
|
||||
{
|
||||
qDebug() << "Screen resized" << screen;
|
||||
}
|
||||
|
||||
void ShellCorona::workAreaResized(int screen)
|
||||
{
|
||||
qDebug() << "Work area resized" << screen;
|
||||
}
|
||||
|
||||
void ShellCorona::screenAdded(QScreen *screen)
|
||||
{
|
||||
DesktopView *view = new DesktopView(this, screen);
|
||||
d->views << view;
|
||||
view->show();
|
||||
const QString currentActivity = d->activityController->currentActivity();
|
||||
|
||||
if (!d->views.isEmpty() && screen == QGuiApplication::primaryScreen()) {
|
||||
DesktopView* oldPrimaryView = d->views.first();
|
||||
QScreen* oldPrimaryScreen = oldPrimaryView->screen();
|
||||
|
||||
//move any panels that were preivously on the old primary screen to the new primary screen
|
||||
foreach (PanelView *panelView, d->panelViews) {
|
||||
if (oldPrimaryScreen==panelView->screen())
|
||||
panelView->setScreen(screen);
|
||||
}
|
||||
|
||||
Plasma::Containment* primaryContainment = oldPrimaryView->containment();
|
||||
oldPrimaryView->setContainment(0);
|
||||
view->setContainment(primaryContainment);
|
||||
|
||||
d->views.prepend(view);
|
||||
view = oldPrimaryView;
|
||||
} else {
|
||||
d->views.append(view);
|
||||
}
|
||||
|
||||
int screenNum = d->views.count()-1;
|
||||
Plasma::Containment *containment = d->desktopContainments[currentActivity][screenNum];
|
||||
if(!containment) {
|
||||
containment = createContainmentForActivity(currentActivity, screenNum);
|
||||
}
|
||||
view->setContainment(containment);
|
||||
|
||||
connect(screen, SIGNAL(destroyed(QObject*)), SLOT(screenRemoved(QObject*)));
|
||||
view->show();
|
||||
}
|
||||
|
||||
|
||||
Plasma::Containment* ShellCorona::createContainmentForActivity(const QString& activity, int screenNum)
|
||||
{
|
||||
Plasma::Containment* containment = createContainment(d->desktopDefaultsConfig.readEntry("Containment", "org.kde.desktopcontainment"));
|
||||
containment->setActivity(activity);
|
||||
insertContainment(activity, screenNum, containment);
|
||||
return containment;
|
||||
}
|
||||
|
||||
void ShellCorona::screenRemoved(QObject *screen)
|
||||
{
|
||||
qDebug() << "screen removed " << qobject_cast<QScreen*>(screen)->name();
|
||||
|
||||
//desktop containments
|
||||
for (auto i = d->views.begin(); i != d->views.end() ; i++) {
|
||||
if ((*i)->screen() == screen) {
|
||||
(*i)->deleteLater();
|
||||
d->views.erase(i);
|
||||
(*i)->containment()->reactToScreenChange();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ShellCorona::checkLoadingDesktopsComplete()
|
||||
{
|
||||
Plasma::Containment *c = qobject_cast<Plasma::Containment *>(sender());
|
||||
if (c) {
|
||||
disconnect(c, &Plasma::Containment::uiReadyChanged,
|
||||
this, &ShellCorona::checkLoadingDesktopsComplete);
|
||||
d->loadingDesktops.remove(c);
|
||||
}
|
||||
|
||||
if (d->loadingDesktops.isEmpty()) {
|
||||
d->waitingPanelsTimer->start();
|
||||
} else {
|
||||
d->waitingPanelsTimer->stop();
|
||||
//move all panels on a deleted screen to the primary screen
|
||||
foreach (PanelView *view, d->panelViews) {
|
||||
view->setScreen(QGuiApplication::primaryScreen());
|
||||
}
|
||||
}
|
||||
|
||||
@ -408,60 +357,20 @@ void ShellCorona::createWaitingPanels()
|
||||
{
|
||||
foreach (Plasma::Containment *cont, d->waitingPanels) {
|
||||
d->panelViews[cont] = new PanelView(this);
|
||||
|
||||
//keep screen suggestions within bounds of screens we actually have
|
||||
int screen = qBound(0, cont->lastScreen(), QGuiApplication::screens().size() -1);
|
||||
|
||||
d->panelViews[cont]->setScreen(QGuiApplication::screens()[screen]);
|
||||
d->panelViews[cont]->setContainment(cont);
|
||||
}
|
||||
d->waitingPanels.clear();
|
||||
}
|
||||
|
||||
void ShellCorona::updateScreenOwner(int wasScreen, int isScreen, Plasma::Containment *containment)
|
||||
{
|
||||
qDebug() << "Was screen" << wasScreen << "Is screen" << isScreen <<"Containment" << containment << containment->title();
|
||||
|
||||
if (containment->formFactor() == Plasma::Types::Horizontal ||
|
||||
containment->formFactor() == Plasma::Types::Vertical) {
|
||||
|
||||
if (isScreen >= 0) {
|
||||
if (!d->waitingPanels.contains(containment)) {
|
||||
d->waitingPanels << containment;
|
||||
}
|
||||
} else {
|
||||
if (d->panelViews.contains(containment)) {
|
||||
d->panelViews[containment]->setContainment(0);
|
||||
d->panelViews[containment]->deleteLater();
|
||||
d->panelViews.remove(containment);
|
||||
d->waitingPanels.removeAll(containment);
|
||||
}
|
||||
}
|
||||
checkLoadingDesktopsComplete();
|
||||
|
||||
//Desktop view
|
||||
} else {
|
||||
|
||||
if (containment->isUiReady()) {
|
||||
d->loadingDesktops.remove(containment);
|
||||
checkLoadingDesktopsComplete();
|
||||
} else {
|
||||
d->loadingDesktops.insert(containment);
|
||||
connect(containment, &Plasma::Containment::uiReadyChanged,
|
||||
this, &ShellCorona::checkLoadingDesktopsComplete);
|
||||
}
|
||||
|
||||
if (isScreen < 0 || d->views.count() < isScreen + 1) {
|
||||
qWarning() << "Invalid screen";
|
||||
return;
|
||||
}
|
||||
|
||||
d->views[isScreen]->setContainment(containment);
|
||||
}
|
||||
}
|
||||
|
||||
void ShellCorona::handleContainmentAdded(Plasma::Containment* c)
|
||||
{
|
||||
connect(c, &Plasma::Containment::showAddWidgetsInterface,
|
||||
this, &ShellCorona::toggleWidgetExplorer);
|
||||
connect(c, &QObject::destroyed, [=] (QObject *o) {
|
||||
d->loadingDesktops.remove(static_cast<Plasma::Containment *>(o));
|
||||
});
|
||||
}
|
||||
|
||||
void ShellCorona::toggleWidgetExplorer()
|
||||
@ -510,13 +419,11 @@ void ShellCorona::setDashboardShown(bool show)
|
||||
|
||||
void ShellCorona::checkActivities()
|
||||
{
|
||||
qDebug() << "containments to start with" << containments().count();
|
||||
|
||||
KActivities::Consumer::ServiceStatus status = d->activityController->serviceStatus();
|
||||
//qDebug() << "$%$%$#%$%$%Status:" << status;
|
||||
if (status != KActivities::Consumer::Running) {
|
||||
//panic and give up - better than causing a mess
|
||||
qDebug() << "No ActivityManager? Help, I've fallen and I can't get up!";
|
||||
qDebug() << "ShellCorona::checkActivities is called whilst activity daemon is still connecting";
|
||||
return;
|
||||
}
|
||||
|
||||
@ -542,11 +449,14 @@ void ShellCorona::checkActivities()
|
||||
|
||||
void ShellCorona::currentActivityChanged(const QString &newActivity)
|
||||
{
|
||||
Activity *act = activity(newActivity);
|
||||
qDebug() << "Activity changed:" << newActivity << act;
|
||||
qDebug() << "Activity changed:" << newActivity;
|
||||
|
||||
if (act) {
|
||||
act->ensureActive();
|
||||
for(int i = 0; i<d->views.count(); ++i) {
|
||||
Plasma::Containment* c = d->desktopContainments[newActivity][i];
|
||||
if(!c) {
|
||||
c = createContainmentForActivity(newActivity, i);
|
||||
}
|
||||
d->views[i]->setContainment(c);
|
||||
}
|
||||
}
|
||||
|
||||
@ -559,9 +469,6 @@ void ShellCorona::activityAdded(const QString &id)
|
||||
}
|
||||
|
||||
Activity *a = new Activity(id, this);
|
||||
if (a->isCurrent()) {
|
||||
a->ensureActive();
|
||||
}
|
||||
d->activities.insert(id, a);
|
||||
}
|
||||
|
||||
@ -637,7 +544,7 @@ void ShellCorona::addPanel(const QString &plugin)
|
||||
QList<Plasma::Types::Location> availableLocations;
|
||||
availableLocations << Plasma::Types::LeftEdge << Plasma::Types::TopEdge << Plasma::Types::RightEdge << Plasma::Types::BottomEdge;
|
||||
|
||||
foreach (Plasma::Containment *cont, d->panelViews.keys()) {
|
||||
foreach (const Plasma::Containment *cont, d->panelViews.keys()) {
|
||||
availableLocations.removeAll(cont->location());
|
||||
}
|
||||
Plasma::Types::Location loc;
|
||||
@ -656,8 +563,6 @@ void ShellCorona::addPanel(const QString &plugin)
|
||||
panel->setFormFactor(Plasma::Types::Horizontal);
|
||||
break;
|
||||
}
|
||||
panel->setScreen(0);
|
||||
|
||||
|
||||
d->waitingPanels << panel;
|
||||
d->waitingPanelsTimer->start();
|
||||
@ -673,6 +578,63 @@ void ShellCorona::printScriptMessage(const QString &message)
|
||||
qDebug() << message;
|
||||
}
|
||||
|
||||
int ShellCorona::screenForContainment(const Plasma::Containment *containment) const
|
||||
{
|
||||
QScreen* s = nullptr;
|
||||
for (int i=0; i<d->views.size(); i++) {
|
||||
if (d->views[i]->containment() == containment) {
|
||||
s = d->views[i]->screen();
|
||||
}
|
||||
}
|
||||
if(!s) {
|
||||
PanelView *view = d->panelViews[containment];
|
||||
if (view) {
|
||||
s = view->screen();
|
||||
}
|
||||
}
|
||||
return s? qApp->screens().indexOf(s) : -1;
|
||||
}
|
||||
|
||||
void ShellCorona::activityOpened()
|
||||
{
|
||||
Activity* activity = qobject_cast<Activity*>(sender());
|
||||
QList<Plasma::Containment*> cs = importLayout(activity->config());
|
||||
for(Plasma::Containment *containment : cs) {
|
||||
insertContainment(activity->name(), containment->lastScreen(), containment);
|
||||
}
|
||||
}
|
||||
|
||||
void ShellCorona::activityClosed()
|
||||
{
|
||||
Activity* activity = qobject_cast<Activity*>(sender());
|
||||
KConfigGroup cg = activity->config();
|
||||
exportLayout(cg, d->desktopContainments.value(activity->name()).values());
|
||||
}
|
||||
|
||||
void ShellCorona::activityRemoved()
|
||||
{
|
||||
//when an activity is removed delete all associated desktop containments
|
||||
Activity* activity = qobject_cast<Activity*>(sender());
|
||||
|
||||
QHash< int, Plasma::Containment* > containmentHash = d->desktopContainments.take(activity->name());
|
||||
for(auto a : containmentHash) {
|
||||
a->destroy();
|
||||
}
|
||||
}
|
||||
|
||||
void ShellCorona::insertContainment(const QString &activity, int screenNum, Plasma::Containment* containment)
|
||||
{
|
||||
d->desktopContainments[activity][screenNum] = containment;
|
||||
|
||||
//when a containment gets deleted update our map of containments
|
||||
connect(containment, &QObject::destroyed, [=](QObject *obj) {
|
||||
auto containment = qobject_cast<Plasma::Containment*>(obj);
|
||||
d->desktopContainments[containment->activity()].remove(containment->lastScreen());
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Desktop corona handler
|
||||
|
||||
|
||||
|
@ -54,17 +54,6 @@ public:
|
||||
KSharedConfig::Ptr applicationConfig();
|
||||
|
||||
WorkspaceScripting::DesktopScriptEngine * scriptEngine() const;
|
||||
/**
|
||||
* Ensures we have the necessary containments for every screen
|
||||
*/
|
||||
void checkScreens(bool signalWhenExists = false);
|
||||
|
||||
/**
|
||||
* Ensures we have the necessary containments for the given screen
|
||||
*/
|
||||
void checkScreen(int screen, bool signalWhenExists = false);
|
||||
|
||||
void checkDesktop(Activity *activity, bool signalWhenExists, int screen);
|
||||
|
||||
int numScreens() const;
|
||||
QRect screenGeometry(int id) const;
|
||||
@ -73,8 +62,6 @@ public:
|
||||
|
||||
PanelView *panelView(Plasma::Containment *containment) const;
|
||||
|
||||
Activity* activity(const QString &id);
|
||||
|
||||
KActivities::Controller *activityController();
|
||||
|
||||
public Q_SLOTS:
|
||||
@ -94,13 +81,8 @@ public Q_SLOTS:
|
||||
QString shell() const;
|
||||
|
||||
protected Q_SLOTS:
|
||||
void screenCountChanged(int newCount);
|
||||
void screenResized(int screen);
|
||||
void workAreaResized(int screen);
|
||||
|
||||
void screenAdded(QScreen *screen);
|
||||
void screenRemoved(QObject *screen);
|
||||
void updateScreenOwner(int wasScreen, int isScreen, Plasma::Containment *containment);
|
||||
|
||||
void printScriptError(const QString &error);
|
||||
void printScriptMessage(const QString &message);
|
||||
@ -125,8 +107,9 @@ protected Q_SLOTS:
|
||||
*/
|
||||
void processUpdateScripts();
|
||||
|
||||
int screenForContainment(const Plasma::Containment *containment) const;
|
||||
|
||||
private Q_SLOTS:
|
||||
void checkLoadingDesktopsComplete();
|
||||
void createWaitingPanels();
|
||||
void handleContainmentAdded(Plasma::Containment *c);
|
||||
void toggleWidgetExplorer();
|
||||
@ -142,7 +125,17 @@ private Q_SLOTS:
|
||||
void addPanel(QAction *action);
|
||||
void addPanel(const QString &plugin);
|
||||
|
||||
void activityOpened();
|
||||
void activityClosed();
|
||||
void activityRemoved();
|
||||
|
||||
private:
|
||||
/**
|
||||
* @returns a new containment associated with the specified @p activity and @p screen.
|
||||
*/
|
||||
Plasma::Containment* createContainmentForActivity(const QString& activity, int screenNum);
|
||||
void insertContainment(const QString &activity, int screenNum, Plasma::Containment *containment);
|
||||
|
||||
class Private;
|
||||
const QScopedPointer<Private> d;
|
||||
};
|
||||
|
@ -148,8 +148,10 @@ void ShellManager::deregisterHandler(QObject * handler)
|
||||
handler->disconnect(this);
|
||||
}
|
||||
|
||||
if (d->currentHandler == handler)
|
||||
if (d->currentHandler == handler) {
|
||||
d->currentHandler = nullptr;
|
||||
updateShell();
|
||||
}
|
||||
}
|
||||
|
||||
void ShellManager::requestShellUpdate()
|
||||
@ -202,7 +204,6 @@ void ShellManager::updateShell()
|
||||
d->currentHandler = handler;
|
||||
d->currentHandler->setProperty("loaded", true);
|
||||
|
||||
// d->corona->setShell(d->currentHandler->property("shell").toString());
|
||||
emit shellChanged(d->currentHandler->property("shell").toString());
|
||||
}
|
||||
|
||||
|
@ -22,7 +22,15 @@
|
||||
|
||||
#include <QObject>
|
||||
|
||||
|
||||
/**
|
||||
* ShellManager creates a ShellCorona instance and manages it.
|
||||
*
|
||||
* Shell manager loads "handlers" from QML files which suggests which shell
|
||||
* corona should currently be active.
|
||||
* For example switching between tablet and desktop shells on hardware changes.
|
||||
*
|
||||
* This class also provides crash handling.
|
||||
*/
|
||||
|
||||
class ShellManager: public QObject {
|
||||
Q_OBJECT
|
||||
|
Loading…
Reference in New Issue
Block a user