1 /*
2     SPDX-FileCopyrightText: 2016 Smith AR <audoban@openmailbox.org>
3     SPDX-FileCopyrightText: 2016 Michail Vourlakos <mvourlakos@gmail.com>
4     SPDX-License-Identifier: GPL-2.0-or-later
5 */
6 
7 #ifndef VIEW_H
8 #define VIEW_H
9 
10 // local
11 #include <coretypes.h>
12 #include "containmentinterface.h"
13 #include "effects.h"
14 #include "parabolic.h"
15 #include "positioner.h"
16 #include "eventssink.h"
17 #include "visibilitymanager.h"
18 #include "indicator/indicator.h"
19 #include "settings/primaryconfigview.h"
20 #include "windowstracker/windowstracker.h"
21 #include "../data/viewdata.h"
22 #include "../shortcuts/globalshortcuts.h"
23 #include "../layout/genericlayout.h"
24 #include "../plasma/quick/containmentview.h"
25 #include "../plasma/quick/configview.h"
26 
27 // C++
28 #include <array>
29 
30 // Qt
31 #include <QQuickView>
32 #include <QMenu>
33 #include <QMetaObject>
34 #include <QMimeData>
35 #include <QScreen>
36 #include <QPointer>
37 #include <QTimer>
38 
39 
40 namespace Plasma {
41 class Types;
42 class Corona;
43 class Containment;
44 }
45 
46 namespace PlasmaQuick {
47 class AppletQuickItem;
48 }
49 
50 
51 namespace KWayland {
52 namespace Client {
53 class PlasmaShellSurface;
54 }
55 }
56 
57 namespace Latte {
58 class Corona;
59 class Interfaces;
60 class GenericLayout;
61 
62 namespace ViewPart {
63 class ContextMenu;
64 }
65 }
66 
67 namespace Latte {
68 
69 class View : public PlasmaQuick::ContainmentView
70 {
71     Q_OBJECT
72 
73     Q_PROPERTY(Latte::Types::ViewType type READ type WRITE setType NOTIFY typeChanged)
74 
75     Q_PROPERTY(bool alternativesIsShown READ alternativesIsShown NOTIFY alternativesIsShownChanged)
76     Q_PROPERTY(bool behaveAsPlasmaPanel READ behaveAsPlasmaPanel WRITE setBehaveAsPlasmaPanel NOTIFY behaveAsPlasmaPanelChanged)
77     Q_PROPERTY(bool byPassWM READ byPassWM WRITE setByPassWM NOTIFY byPassWMChanged)
78     Q_PROPERTY(bool containsDrag READ containsDrag NOTIFY containsDragChanged)
79     Q_PROPERTY(bool contextMenuIsShown READ contextMenuIsShown NOTIFY contextMenuIsShownChanged)
80     Q_PROPERTY(bool inSettingsAdvancedMode READ inSettingsAdvancedMode NOTIFY inSettingsAdvancedModeChanged)
81 
82     Q_PROPERTY(bool inEditMode READ inEditMode NOTIFY inEditModeChanged)
83     Q_PROPERTY(bool isPreferredForShortcuts READ isPreferredForShortcuts WRITE setIsPreferredForShortcuts NOTIFY isPreferredForShortcutsChanged)
84     Q_PROPERTY(bool onPrimary READ onPrimary WRITE setOnPrimary NOTIFY onPrimaryChanged)
85     Q_PROPERTY(bool screenEdgeMarginEnabled READ screenEdgeMarginEnabled WRITE setScreenEdgeMarginEnabled NOTIFY screenEdgeMarginEnabledChanged)
86 
87     //! values to be used from Smart surrounding Views
88     Q_PROPERTY(bool isTouchingBottomViewAndIsBusy READ isTouchingBottomViewAndIsBusy WRITE setIsTouchingBottomViewAndIsBusy NOTIFY isTouchingBottomViewAndIsBusyChanged)
89     Q_PROPERTY(bool isTouchingTopViewAndIsBusy READ isTouchingTopViewAndIsBusy WRITE setIsTouchingTopViewAndIsBusy NOTIFY isTouchingTopViewAndIsBusyChanged)
90 
91     Q_PROPERTY(int alignment READ alignment WRITE setAlignment NOTIFY alignmentChanged)
92     Q_PROPERTY(int fontPixelSize READ fontPixelSize WRITE setFontPixelSize NOTIFY fontPixelSizeChanged)
93     Q_PROPERTY(int x READ x NOTIFY xChanged)
94     Q_PROPERTY(int y READ y NOTIFY yChanged)
95     Q_PROPERTY(int width READ width NOTIFY widthChanged)
96     Q_PROPERTY(int height READ height NOTIFY heightChanged)
97     Q_PROPERTY(int editThickness READ editThickness NOTIFY editThicknessChanged)
98     Q_PROPERTY(int maxThickness READ maxThickness WRITE setMaxThickness NOTIFY maxThicknessChanged)
99     Q_PROPERTY(int normalThickness READ normalThickness WRITE setNormalThickness NOTIFY normalThicknessChanged)
100     Q_PROPERTY(int maxNormalThickness READ maxNormalThickness WRITE setMaxNormalThickness NOTIFY maxNormalThicknessChanged)
101     Q_PROPERTY(int headThicknessGap READ headThicknessGap WRITE setHeadThicknessGap NOTIFY headThicknessGapChanged)
102     Q_PROPERTY(int screenEdgeMargin READ screenEdgeMargin WRITE setScreenEdgeMargin NOTIFY screenEdgeMarginChanged)
103 
104     Q_PROPERTY(float maxLength READ maxLength WRITE setMaxLength NOTIFY maxLengthChanged)
105     Q_PROPERTY(float offset READ offset WRITE setOffset NOTIFY offsetChanged)
106 
107     Q_PROPERTY(QString name READ name NOTIFY nameChanged)
108 
109     Q_PROPERTY(QQuickItem *colorizer READ colorizer WRITE setColorizer NOTIFY colorizerChanged)
110     Q_PROPERTY(QQuickItem *metrics READ metrics WRITE setMetrics NOTIFY metricsChanged)
111 
112     Q_PROPERTY(QVariantList containmentActions READ containmentActions NOTIFY containmentActionsChanged)
113 
114     Q_PROPERTY(Latte::Layout::GenericLayout *layout READ layout WRITE setLayout NOTIFY layoutChanged)
115     Q_PROPERTY(Latte::ViewPart::Effects *effects READ effects NOTIFY effectsChanged)
116     Q_PROPERTY(Latte::ViewPart::ContainmentInterface *extendedInterface READ extendedInterface NOTIFY extendedInterfaceChanged)
117     Q_PROPERTY(Latte::ViewPart::Indicator *indicator READ indicator NOTIFY indicatorChanged)
118     Q_PROPERTY(Latte::ViewPart::Parabolic *parabolic READ parabolic NOTIFY parabolicChanged)
119     Q_PROPERTY(Latte::ViewPart::Positioner *positioner READ positioner NOTIFY positionerChanged)
120     Q_PROPERTY(Latte::ViewPart::EventsSink *sink READ sink NOTIFY sinkChanged)
121     Q_PROPERTY(Latte::ViewPart::VisibilityManager *visibility READ visibility NOTIFY visibilityChanged)
122     Q_PROPERTY(Latte::ViewPart::WindowsTracker *windowsTracker READ windowsTracker NOTIFY windowsTrackerChanged)
123 
124     Q_PROPERTY(Latte::Interfaces *interfacesGraphicObj READ interfacesGraphicObj WRITE setInterfacesGraphicObj NOTIFY interfacesGraphicObjChanged)
125 
126     Q_PROPERTY(QRect absoluteGeometry READ absoluteGeometry NOTIFY absoluteGeometryChanged)
127     Q_PROPERTY(QRect localGeometry READ localGeometry WRITE setLocalGeometry NOTIFY localGeometryChanged)
128     Q_PROPERTY(QRect screenGeometry READ screenGeometry NOTIFY screenGeometryChanged)
129 
130 public:
131     View(Plasma::Corona *corona, QScreen *targetScreen = nullptr, bool byPassX11WM = false);
132     virtual ~View();
133 
134     void init(Plasma::Containment *plasma_containment = nullptr);
135 
136     Types::ViewType type() const;
137     void setType(Types::ViewType type);
138 
139     bool alternativesIsShown() const;
140     void setAlternativesIsShown(bool show);
141 
142     bool inDelete() const;
143     bool inReadyState() const;
144 
145     bool onPrimary() const;
146     void setOnPrimary(bool flag);
147 
148     bool behaveAsPlasmaPanel() const;
149     void setBehaveAsPlasmaPanel(bool behavior);
150 
151     bool containsDrag() const;
152     bool containsMouse() const;
153 
154     bool contextMenuIsShown() const;
155 
156     bool byPassWM() const;
157     void setByPassWM(bool bypass);
158 
159     bool inEditMode() const;
160 
161     bool isFloatingPanel() const;
162 
163     bool isPreferredForShortcuts() const;
164     void setIsPreferredForShortcuts(bool preferred);
165 
166     bool inSettingsAdvancedMode() const;
167 
168     bool isTouchingBottomViewAndIsBusy() const;
169     void setIsTouchingBottomViewAndIsBusy(bool touchAndBusy);
170 
171     bool isTouchingTopViewAndIsBusy() const;
172     void setIsTouchingTopViewAndIsBusy(bool touchAndBusy);
173 
174     bool screenEdgeMarginEnabled() const;
175     void setScreenEdgeMarginEnabled(bool enabled);
176 
177     int fontPixelSize() const;
178     void setFontPixelSize(int size);
179 
180     int editThickness() const;
181 
182     int maxThickness() const;
183     void setMaxThickness(int thickness);
184 
185     int normalThickness() const;
186     void setNormalThickness(int thickness);
187 
188     int maxNormalThickness() const;
189     void setMaxNormalThickness(int thickness);
190 
191     int headThicknessGap() const;
192     void setHeadThicknessGap(int thickness);
193 
194     int screenEdgeMargin() const;
195     void setScreenEdgeMargin(int margin);
196 
197     int alignment() const;
198     void setAlignment(int alignment);
199 
200     float maxLength() const;
201     void setMaxLength(float length);
202 
203     float offset() const;
204     void setOffset(float offset);
205 
206     QRect absoluteGeometry() const;
207     QRect screenGeometry() const;
208 
209     QRect localGeometry() const;
210     void setLocalGeometry(const QRect &geometry);
211 
212     QString validTitle() const;
213 
214     QString name() const;
215     void setName(const QString &newname);
216 
217     bool isOnActivity(const QString &activity) const;
218     bool isOnAllActivities() const;
219 
220     QStringList activities() const;
221     void setActivities(const QStringList &ids);
222 
223     bool settingsWindowIsShown();
224     void showSettingsWindow();
225 
226     QQuickItem *colorizer() const;
227     void setColorizer(QQuickItem *colorizer);
228 
229     QQuickItem *metrics() const;
230     void setMetrics(QQuickItem *metrics);
231 
232     QVariantList containmentActions() const;
233 
234     QQuickView *configView();
235 
236     Latte::Data::View data() const;
237 
238     ViewPart::Effects *effects() const;
239     ViewPart::ContextMenu *contextMenu() const;
240     ViewPart::ContainmentInterface *extendedInterface() const;
241     ViewPart::Indicator *indicator() const;
242     ViewPart::Parabolic *parabolic() const;
243     ViewPart::Positioner *positioner() const;
244     ViewPart::EventsSink *sink() const;
245     ViewPart::VisibilityManager *visibility() const;
246     ViewPart::WindowsTracker *windowsTracker() const;
247 
248     Latte::Interfaces *interfacesGraphicObj() const;
249     void setInterfacesGraphicObj(Latte::Interfaces *ifaces);
250 
251     Layout::GenericLayout *layout() const;
252     void setLayout(Layout::GenericLayout *layout);
253 
254     KWayland::Client::PlasmaShellSurface *surface();
255 
256     //! release grab and restore mouse state
257     void unblockMouse(int x, int y);
258 
259     void reconsiderScreen();
260 
261     //! these are signals that create crashes, such a example is the availableScreenRectChanged from corona
262     //! when its containment is destroyed
263     void disconnectSensitiveSignals();
264 
265     //! used from ViewSettingsFactory in order to move Configuration Windows to different View
266     void releaseConfigView();
267 
268 public slots:
269     Q_INVOKABLE void newView(const QString &templateFile);
270     Q_INVOKABLE void removeView();
271     Q_INVOKABLE void duplicateView();
272     Q_INVOKABLE void exportTemplate();
273 
274     Q_INVOKABLE bool mimeContainsPlasmoid(QMimeData *mimeData, QString name);
275 
276     void updateAbsoluteGeometry(bool bypassChecks = false);
277 
278     Q_INVOKABLE bool isHighestPriorityView();
279     Q_INVOKABLE QAction *action(const QString &name);
280 
281 protected slots:
282     void showConfigurationInterface(Plasma::Applet *applet) override;
283     void showWidgetExplorer(const QPointF &point);
284 
285 protected:
286     bool event(QEvent *ev) override;
287     void mousePressEvent(QMouseEvent *event) override;
288 
289 signals:
290     void eventTriggered(QEvent *ev);
291     void mousePressed(const QPoint pos, const int button);
292     void mouseReleased(const QPoint pos, const int button);
293     void wheelScrolled(const QPoint pos, const QPoint angleDelta, const int buttons);
294 
295     void activitiesChanged();
296     void alternativesIsShownChanged();
297     void alignmentChanged();
298     void behaveAsPlasmaPanelChanged();
299     void byPassWMChanged();
300     void colorizerChanged();
301     void configWindowGeometryChanged(); // is called from config windows
302     void containmentActionsChanged();
303     void containsDragChanged();
304     void contextMenuIsShownChanged();
305     void dockLocationChanged();
306     void editThicknessChanged();
307     void effectsChanged();
308     void extendedInterfaceChanged();
309     void fontPixelSizeChanged();
310     void forcedShown(); //[workaround] forced shown to avoid a KWin issue that hides windows when closing activities
311     void geometryChanged();
312     void widthChanged();
313     void headThicknessGapChanged();
314     void heightChanged();
315     void inEditModeChanged();
316     void indicatorChanged();
317     void inSettingsAdvancedModeChanged();
318     void interfacesGraphicObjChanged();
319     void isPreferredForShortcutsChanged();
320     void isTouchingBottomViewAndIsBusyChanged();
321     void isTouchingTopViewAndIsBusyChanged();
322     void layoutChanged();
323     void localGeometryChanged();
324     void maxLengthChanged();
325     void maxThicknessChanged();
326     void metricsChanged();
327     void normalThicknessChanged();
328     void maxNormalThicknessChanged();
329     void nameChanged();
330     void offsetChanged();
331     void onPrimaryChanged();
332     void parabolicChanged();
333     void positionerChanged();
334     void screenEdgeMarginChanged();
335     void screenEdgeMarginEnabledChanged();
336     void screenGeometryChanged();
337     void sinkChanged();
338     void typeChanged();
339     void visibilityChanged();
340     void windowsTrackerChanged();
341     void xChanged();
342     void yChanged();
343 
344     void absoluteGeometryChanged(const QRect &geometry);
345 
346     void indicatorPluginChanged(const QString &indicatorId);
347     void indicatorPluginRemoved(const QString &indicatorId);
348     void userRequestedViewType(const int &type);
349 
350     //! are used to trigger the Corona relevant signals and in that
351     //! way we can disable any such signaling all together, e.g. through disconnectSensitiveSignals()
352     void availableScreenRectChangedFrom(Latte::View *origin);
353     void availableScreenRegionChangedFrom(Latte::View *origin);
354 
355 private slots:
356     void applyActivitiesToWindows();
357     void availableScreenRectChangedFromSlot(View *origin);
358     void hideWindowsForSlidingOut();
359     void preferredViewForShortcutsChangedSlot(Latte::View *view);
360     void releaseGrab();
361     void reloadSource();
362     void updateTransientWindowsTracking();
363     void statusChanged(Plasma::Types::ItemStatus);
364 
365     void addTransientWindow(QWindow *window);
366     void removeTransientWindow(const bool &visible);
367 
368     //! workaround in order for top panels to be always on top
369     void topViewAlwaysOnTop();
370     void verticalUnityViewHasFocus();
371 
372     //!workround for when kwin hides view when an activity is closing
373     void showHiddenViewFromActivityStopping();
374 
375     void restoreConfig();
376     void saveConfig();
377 
378 private:
379     void initSignalingForLocationChangeSliding();
380     void setupWaylandIntegration();
381     void updateAppletContainsMethod();
382 
383     void setContainsDrag(bool contains);
384 
385 private:
386     Plasma::Containment *containmentById(uint id);
387 
388     bool m_alternativesIsShown{false};
389     bool m_behaveAsPlasmaPanel{false};
390     bool m_byPassWM{true};
391     bool m_containsDrag{false};
392     bool m_containsMouse{false};
393     bool m_inDelete{false};
394     bool m_isPreferredForShortcuts{false};
395     bool m_onPrimary{true};
396     bool m_screenEdgeMarginEnabled{false};
397 
398     bool m_isTouchingBottomViewAndIsBusy{false};
399     bool m_isTouchingTopViewAndIsBusy{false};
400 
401     int m_fontPixelSize{ -1};
402     int m_maxThickness{256};
403     int m_normalThickness{256};
404     int m_maxNormalThickness{256};
405     int m_headThicknessGap{0};
406     int m_screenEdgeMargin{-1};
407     float m_maxLength{1};
408     float m_offset{0};
409 
410     Types::Alignment m_alignment{Types::Center};
411     Types::ViewType m_type{Types::DockView};
412 
413     QRect m_localGeometry;
414     QRect m_absoluteGeometry;
415 
416     QString m_name;
417 
418     QStringList m_activities;
419 
420     //! HACK: In order to avoid crashes when the View is added and removed
421     //! immediately during startup
422     QTimer m_initLayoutTimer;
423 
424     //! HACK: Timers in order to handle KWin faulty
425     //! behavior that hides Views when closing Activities
426     //! with no actual reason
427     QTimer m_visibleHackTimer1;
428     QTimer m_visibleHackTimer2;
429 
430     QTimer m_releaseGrabTimer;
431     int m_releaseGrab_x;
432     int m_releaseGrab_y;
433 
434     Layout::GenericLayout *m_layout{nullptr};
435 
436     QQuickItem *m_colorizer{nullptr};
437     QQuickItem *m_metrics{nullptr};
438 
439     QPointer<PlasmaQuick::ConfigView> m_appletConfigView;
440     QPointer<ViewPart::PrimaryConfigView> m_primaryConfigView;
441 
442     QPointer<ViewPart::ContextMenu> m_contextMenu;
443     QPointer<ViewPart::Effects> m_effects;
444     QPointer<ViewPart::Indicator> m_indicator;
445     QPointer<ViewPart::ContainmentInterface> m_interface;
446     QPointer<ViewPart::Parabolic> m_parabolic;
447     QPointer<ViewPart::Positioner> m_positioner;
448     QPointer<ViewPart::EventsSink> m_sink;
449     QPointer<ViewPart::VisibilityManager> m_visibility;
450     QPointer<ViewPart::WindowsTracker> m_windowsTracker;
451 
452     QPointer<Latte::Interfaces> m_interfacesGraphicObj;
453 
454     //! Connections to release and bound for the assigned layout
455     QList<QMetaObject::Connection> connectionsLayout;
456 
457     //! track transientWindows
458     QList<QWindow *> m_transientWindows;
459 
460     QPointer<Latte::Corona> m_corona;
461 
462     KWayland::Client::PlasmaShellSurface *m_shellSurface{nullptr};
463 };
464 
465 }
466 
467 #endif
468