File: shellcorona.h

package info (click to toggle)
plasma-workspace 4%3A5.27.5-2%2Bdeb12u2
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 102,040 kB
  • sloc: cpp: 121,800; xml: 3,238; python: 645; perl: 586; sh: 254; javascript: 113; ruby: 62; makefile: 15; ansic: 13
file content (311 lines) | stat: -rw-r--r-- 9,172 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
/*
    SPDX-FileCopyrightText: 2008 Aaron Seigo <aseigo@kde.org>
    SPDX-FileCopyrightText: 2013 Sebastian Kügler <sebas@kde.org>
    SPDX-FileCopyrightText: 2013 Ivan Cukic <ivan.cukic@kde.org>
    SPDX-FileCopyrightText: 2013 Marco Martin <mart@kde.org>

    SPDX-License-Identifier: LGPL-2.0-or-later
*/

#pragma once

#include "config-X11.h"
#include "plasma/corona.h"

#include <QDBusContext>
#include <QDBusVariant>
#include <QSet>
#include <QTimer>

#include <KConfigWatcher>
#include <KPackage/Package>

class DesktopView;
class PanelView;
class QMenu;
class QScreen;
class ScreenPool;
class StrutManager;
class ShellContainmentConfig;

namespace KActivities
{
class Controller;
} // namespace KActivities

namespace KDeclarative
{
class QmlObjectSharedEngine;
} // namespace KDeclarative

namespace KScreen
{
class Output;
} // namespace KScreen

namespace Plasma
{
class Applet;
} // namespace Plasma

namespace KWayland
{
namespace Client
{
class PlasmaShell;
class PlasmaShellSurface;
class PlasmaWindow;
class PlasmaWindowManagement;
}
}

class ShellCorona : public Plasma::Corona, QDBusContext
{
    Q_OBJECT
    Q_PROPERTY(QString shell READ shell WRITE setShell)
    Q_PROPERTY(int numScreens READ numScreens)
    Q_CLASSINFO("D-Bus Interface", "org.kde.PlasmaShell")

public:
    explicit ShellCorona(QObject *parent = nullptr);
    ~ShellCorona() override;

    KPackage::Package lookAndFeelPackage();
    void init();

    /**
     * Where to save global configuration that doesn't have anything to do with the scene (e.g. views)
     */
    KSharedConfig::Ptr applicationConfig();

    int numScreens() const override;
    Q_INVOKABLE QRect screenGeometry(int id) const override;
    Q_INVOKABLE QRegion availableScreenRegion(int id) const override;
    Q_INVOKABLE QRect availableScreenRect(int id) const override;

    // plasmashellCorona's value
    QRegion _availableScreenRegion(int id) const;
    QRect _availableScreenRect(int id) const;

    Q_INVOKABLE QStringList availableActivities() const;

    PanelView *panelView(Plasma::Containment *containment) const;
    void restorePreviousWindow();

    // This one is a bit of an hack but are just for desktop scripting
    void insertActivity(const QString &id, const QString &plugin);

    Plasma::Containment *setContainmentTypeForScreen(int screen, const QString &plugin);

    void removeDesktop(DesktopView *desktopView);

    /**
     * @returns a new containment associated with the specified @p activity and @p screen.
     */
    Plasma::Containment *createContainmentForActivity(const QString &activity, int screenNum);

    KWayland::Client::PlasmaShell *waylandPlasmaShellInterface() const;

    ScreenPool *screenPool() const;

    QList<int> screenIds() const;

    QString defaultContainmentPlugin() const;

    static QString defaultShell();

    // Set all Desktop containments (for all activities) associated to a given screen to this new screen.
    // swapping ones that had newScreen to oldScreen if existing. Panels are ignored
    void swapDesktopScreens(int oldScreen, int newScreen);

    // Set a single containment to a new screen.
    // If it is a Desktop contaiment, swap it with the other containment that was associated with same screen and activity if existent
    void setScreenForContainment(Plasma::Containment *containment, int screen);

    // Grab a screenshot of the contaiment if it has a view in an async fashion
    // containmentPreviewReady will be emitted when done
    // If there is no view, this will have no effect
    void grabContainmentPreview(Plasma::Containment *containment);

    // If a containment preview has been grabbed, for this containment, return its path
    QString containmentPreviewPath(Plasma::Containment *containment) const;

    /**
     * Whether "accent color from wallpaper" option is enabled in global settings
     */
    bool accentColorFromWallpaperEnabled() const;

Q_SIGNALS:
    void glInitializationFailed();
    // A preview for this containment has been rendered and saved to disk
    void containmentPreviewReady(Plasma::Containment *containment, const QString &path);
    void accentColorFromWallpaperEnabledChanged();
    void colorChanged(const QColor &color);
    // This API is used only by autotests, do we need something else?
    void screenOrderChanged(QList<QScreen *> screens);

public Q_SLOTS:
    /**
     * Request saving applicationConfig on disk, it's event compressed, not immediate
     */
    void requestApplicationConfigSync();

    /**
     * Cycle through all panels
     */
    void slotCyclePanelFocus();

    /**
     * Sets the shell that the corona should display
     */
    void setShell(const QString &shell);

    /**
     * Gets the currently shown shell
     */
    QString shell() const;

    /// DBUS methods
    void toggleDashboard();
    void setDashboardShown(bool show);
    void toggleActivityManager();
    void toggleWidgetExplorer();
    QString evaluateScript(const QString &string);
    void activateLauncherMenu();
    QRgb color() const;

    QByteArray dumpCurrentLayoutJS() const;

    /**
     * loads the shell layout from a look and feel package,
     * resetting it to the default layout exported in the
     * look and feel package
     */
    void loadLookAndFeelDefaultLayout(const QString &layout);

    Plasma::Containment *addPanel(const QString &plugin);

    void nextActivity();
    void previousActivity();
    void stopCurrentActivity();

    void setTestModeLayout(const QString &layout)
    {
        m_testModeLayout = layout;
    }

    int panelCount() const
    {
        return m_panelViews.count();
    }

    void refreshCurrentShell();

protected Q_SLOTS:
    /**
     * Loads the layout and performs the needed checks
     */
    void load();

    /**
     * Unloads everything
     */
    void unload();

    /**
     * Loads the default (system wide) layout for this user
     **/
    void loadDefaultLayout() override;

    /**
     * Execute any update script
     */
    void processUpdateScripts();

    int screenForContainment(const Plasma::Containment *containment) const override;

    void showAlternativesForApplet(Plasma::Applet *applet);

private Q_SLOTS:
    void createWaitingPanels();
    void handleContainmentAdded(Plasma::Containment *c);
    void syncAppConfig();
    void checkActivities();
    void currentActivityChanged(const QString &newActivity);
    void activityAdded(const QString &id);
    void activityRemoved(const QString &id);
    void checkAddPanelAction();
    void addPanel();
    void addPanel(QAction *action);
    void populateAddPanelsMenu();

    void addOutput(QScreen *screen);

    void panelContainmentDestroyed(QObject *cont);
    void handleScreenRemoved(QScreen *screen);
    void handleScreenOrderChanged(QList<QScreen *> screens);

    void activateTaskManagerEntry(int index);

private:
    void sanitizeScreenLayout(const QString &configFileName);
    void updateStruts();
    void configurationChanged(const QString &path);
    DesktopView *desktopForScreen(QScreen *screen) const;
    void setupWaylandIntegration();
    void executeSetupPlasmoidScript(Plasma::Containment *containment, Plasma::Applet *applet);
    void checkAllDesktopsUiReady(bool ready);
    void activateLauncherMenu(const QString &screenName);
    void handleColorRequestedFromDBus(const QDBusMessage &msg);

#ifndef NDEBUG
    void screenInvariants() const;
#endif

    KSharedConfig::Ptr m_config;
    QString m_configPath;

    // Accent color setting
    KConfigWatcher::Ptr m_accentColorConfigWatcher;
    bool m_accentColorFromWallpaperEnabled = false;
    QMetaObject::Connection m_fakeColorRequestConn;

    ScreenPool *m_screenPool;
    QString m_shell;
    KActivities::Controller *m_activityController;
    QMap<const Plasma::Containment *, PanelView *> m_panelViews;
    // map from QScreen to desktop view
    QHash<int, DesktopView *> m_desktopViewForScreen;
    QHash<const Plasma::Containment *, int> m_pendingScreenChanges;
    KConfigGroup m_desktopDefaultsConfig;
    KConfigGroup m_lnfDefaultsConfig;
    QList<Plasma::Containment *> m_waitingPanels;
    QHash<QString, QString> m_activityContainmentPlugins;
    QAction *m_addPanelAction;
    std::unique_ptr<QMenu> m_addPanelsMenu;
    KPackage::Package m_lookAndFeelPackage;

    // Used to restore the previous activated window after the panel loses focus
    KWayland::Client::PlasmaShellSurface *m_shellSurface = nullptr;
#if HAVE_X11
    WId m_previousWId = 0;
#endif
    bool m_blockRestorePreviousWindow = false;

    QTimer m_waitingPanelsTimer;
    QTimer m_appConfigSyncTimer;
#ifndef NDEBUG
    QTimer m_invariantsTimer;
#endif
    KWayland::Client::PlasmaShell *m_waylandPlasmaShell;
    // For getting the active window on Wayland
    KWayland::Client::PlasmaWindowManagement *m_waylandWindowManagement = nullptr;
    KWayland::Client::PlasmaWindow *m_previousPlasmaWindow = nullptr;
    bool m_closingDown : 1;
    bool m_screenReorderInProgress = false;
    QString m_testModeLayout;

    StrutManager *m_strutManager;
    QPointer<ShellContainmentConfig> m_shellContainmentConfig;
    friend class ShellTest;
};