File: lxqtpanel.h

package info (click to toggle)
lxqt-panel 2.1.4-1
  • links: PTS, VCS
  • area: main
  • in suites: sid, trixie
  • size: 15,748 kB
  • sloc: cpp: 27,548; xml: 798; makefile: 19
file content (729 lines) | stat: -rw-r--r-- 29,037 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
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
/* BEGIN_COMMON_COPYRIGHT_HEADER
 * (c)LGPL2+
 *
 * LXQt - a lightweight, Qt based, desktop toolset
 * https://lxqt.org
 *
 * Copyright: 2010-2011 Razor team
 * Authors:
 *   Alexander Sokoloff <sokoloff.a@gmail.com>
 *
 * This program or library is free software; you can redistribute it
 * and/or modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.

 * You should have received a copy of the GNU Lesser General
 * Public License along with this library; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301 USA
 *
 * END_COMMON_COPYRIGHT_HEADER */


#ifndef LXQTPANEL_H
#define LXQTPANEL_H

#include <QFrame>
#include <QString>
#include <QTimer>
#include <QPropertyAnimation>
#include <QPointer>
#include <LXQt/Settings>
#include "ilxqtpanel.h"
#include "lxqtpanelglobals.h"

class QMenu;
class Plugin;
class QAbstractItemModel;

namespace LayerShellQt {
class Window;
}

namespace LXQt {
class Settings;
class PluginInfo;
}
class LXQtPanelLayout;
class ConfigPanelDialog;
class PanelPluginsModel;
class WindowNotifier;

/*! \brief The LXQtPanel class provides a single lxqt-panel. All LXQtPanel
 * instances should be created and handled by LXQtPanelApplication. In turn,
 * all Plugins should be created and handled by LXQtPanels.
 *
 * LXQtPanel is just the panel, it does not incorporate any functionality.
 * Each function of the panel is implemented by Plugins, even the mainmenu
 * (plugin-mainmenu) and the taskbar (plugin-taskbar). So the LXQtPanel is
 * just the container for several Plugins while the different Plugins
 * incorporate the functions of the panel. Without the Plugins, the panel
 * is quite useless because it is just a box occupying space on the screen.
 *
 * LXQtPanel itself is a window (QFrame/QWidget) and this class is mainly
 * responsible for handling the size and position of this window on the
 * screen(s) as well as the different settings. The handling of the plugins
 * is outsourced in PanelPluginsModel and LXQtPanelLayout. PanelPluginsModel
 * is responsible for loading/creating and handling the plugins.
 * LXQtPanelLayout is inherited from QLayout and set as layout to the
 * background of LXQtPanel, so LXQtPanelLayout is responsible for the
 * layout of all the Plugins.
 *
 * \sa LXQtPanelApplication, Plugin, PanelPluginsModel, LXQtPanelLayout.
 */
class LXQT_PANEL_API LXQtPanel : public QFrame, public ILXQtPanel
{
    Q_OBJECT

    Q_PROPERTY(QString position READ qssPosition)

    // for configuration dialog
    friend class ConfigPanelWidget;
    friend class ConfigPluginsWidget;
    friend class ConfigPanelDialog;
    friend class PanelPluginsModel;

public:
    /**
     * @brief Stores how the panel should be aligned. Obviously, this applies
     * only if the panel does not occupy 100 % of the available space. If the
     * panel is vertical, AlignmentLeft means align to the top border of the
     * screen, AlignmentRight means align to the bottom.
     */
    enum Alignment {
        AlignmentLeft   = -1, //!< Align the panel to the left or top
        AlignmentCenter =  0, //!< Center the panel
        AlignmentRight  =  1 //!< Align the panel to the right or bottom
    };

    /**
     * @brief Creates and initializes the LXQtPanel. Performs the following
     * steps:
     * 1. Sets Qt window title, flags, attributes.
     * 2. Creates the panel layout.
     * 3. Prepares the timers.
     * 4. Connects signals and slots.
     * 5. Reads the settings for this panel.
     * 6. Optionally moves the panel to a valid screen (position-dependent).
     * 7. Loads the Plugins.
     * 8. Shows the panel, even if it is hidable (but then, starts the timer).
     * @param configGroup The name of the panel which is used as identifier
     * in the config file.
     * @param settings The settings instance of this lxqt panel application.
     * @param parent Parent QWidget, can be omitted.
     */
    LXQtPanel(const QString &configGroup, LXQt::Settings *settings, QWidget *parent = nullptr);
    virtual ~LXQtPanel();

    /**
     * @brief Returns the name of this panel which is also used as identifier
     * in the config file.
     */
    QString name() { return mConfigGroup; }

    /**
     * @brief Reads all the necessary settings from mSettings and stores them
     * in local variables. Additionally, calls necessary methods like realign()
     * or updateStyleSheet() which need to get called after changing settings.
     */
    void readSettings();

    /**
     * @brief Creates and shows the popup menu (right click menu). If a plugin
     * is given as parameter, the menu will be divided in two groups:
     * plugin-specific options and panel-related options. As these two are
     * shown together, this menu has to be created by LXQtPanel.
     * @param cursorPos The global cursor pos
     * @param plugin The plugin whose menu options will be included in the
     * context menu.
     */
    void showPopupMenu(const QPoint &cursorPos, Plugin *plugin = nullptr);

    // ILXQtPanel overrides ........
    ILXQtPanel::Position position() const override { return mPosition; }
    QRect globalGeometry() const override;
    QRect calculatePopupWindowPos(QPoint const & absolutePos, QSize const & windowSize) const override;
    QRect calculatePopupWindowPos(const ILXQtPanelPlugin *plugin, const QSize &windowSize) const override;
    void willShowWindow(QWidget * w) override;
    void pluginFlagsChanged(const ILXQtPanelPlugin * plugin) override;
    bool isLocked() const override { return mLockPanel; }
    // ........ end of ILXQtPanel overrides

    /**
     * @brief Searches for a Plugin in the Plugins-list of this panel. Takes
     * an ILXQtPanelPlugin as parameter and returns the corresponding Plugin.
     * @param iPlugin ILXQtPanelPlugin that we are looking for.
     * @return The corresponding Plugin if it is loaded in this panel, nullptr
     * otherwise.
     */
    Plugin *findPlugin(const ILXQtPanelPlugin *iPlugin) const;

    // For QSS properties ..................
    /**
     * @brief Returns the position as string
     *
     * \sa positionToStr().
     */
    QString qssPosition() const;

    /**
     * @brief Checks if this LXQtPanel can be placed at a given position
     * on the screen with the given screenNum. The condition for doing so
     * is that the panel is not located between two screens.
     *
     * For example, if position is PositionRight, there should be no screen to
     * the right of the given screen. That means that there should be no
     * screen whose left border has a higher x-coordinate than the x-coordinate
     * of the right border of the given screen. This method iterates over all
     * screens and checks these conditions.
     * @param screenNum screen index as it is used by QDesktopWidget methods
     * @param position position where the panel should be placed
     * @return true if this panel can be placed at the given position on the
     * given screen.
     *
     * \sa findAvailableScreen(), mScreenNum, mActualScreenNum.
     */
    static bool canPlacedOn(int screenNum, LXQtPanel::Position position);
    /**
     * @brief Returns a string representation of the given position. This
     * string is human-readable and can be used in config files.
     * @param position position that should be converted to a string.
     * @return the string representation of the given position, i.e.
     * "Top", "Left", "Right" or "Bottom".
     *
     * \sa strToPosition()
     */
    static QString positionToStr(ILXQtPanel::Position position);
    /**
     * @brief Returns an ILXQtPanel::Position from the given string. This can
     * be used to retrieve ILXQtPanel::Position values from the config files.
     * @param str string that should be converted to ILXQtPanel::Position
     * @param defaultValue value that will be returned if the string can not
     * be converted to an ILXQtPanel::Position.
     * @return ILXQtPanel::Position that was determined from str or
     * defaultValue if str could not be converted.
     *
     * \sa positionToStr()
     */
    static ILXQtPanel::Position strToPosition(const QString &str, ILXQtPanel::Position defaultValue);

    // Settings
    int iconSize() const override { return mIconSize; } //!< Implement ILXQtPanel::iconSize().
    int lineCount() const override { return mLineCount; } //!< Implement ILXQtPanel::lineCount().
    int panelSize() const { return mPanelSize; }
    int length() const { return mLength; }
    bool lengthInPercents() const { return mLengthInPercents; }
    LXQtPanel::Alignment alignment() const { return mAlignment; }
    int screenNum() const { return mScreenNum; }
    QColor fontColor() const { return mFontColor; }
    QColor backgroundColor() const { return mBackgroundColor; }
    QString backgroundImage() const { return mBackgroundImage; }
    int opacity() const { return mOpacity; }
    int reserveSpace() const { return mReserveSpace; }
    bool hidable() const { return mHidable; }
    bool visibleMargin() const { return mVisibleMargin; }
    bool hideOnOverlap() const { return mHideOnOverlap; }
    int animationTime() const { return mAnimationTime; }
    int showDelay() const { return mShowDelayTimer.interval(); }
    QString iconTheme() const;

    /*!
     * \brief Checks if a given Plugin is running and has the
     * ILXQtPanelPlugin::SingleInstance flag set.
     * \param pluginId Plugin Identifier which is the basename of the
     * .desktop file that specifies the plugin.
     * \return true if the Plugin is running and has the
     * ILXQtPanelPlugin::SingleInstance flag set, false otherwise.
     */
    bool isPluginSingletonAndRunning(QString const & pluginId) const;
    /*!
     * \brief Updates the config dialog. Used for updating its icons
     * when the panel-specific icon theme changes.
     */
    void updateConfigDialog() const;

public slots:
    /**
     * @brief Shows the QWidget and makes it visible on all desktops. This
     * method is NOT related to showPanel(), hidePanel() and hidePanelWork()
     * which handle the LXQt hiding by resizing the panel.
     */
    void show();
    /**
     * @brief Shows the panel (immediately) after it had been hidden before.
     * Stops the QTimer mHideTimer. This it NOT the same as QWidget::show()
     * because hiding the panel in LXQt is done by making it very thin. So
     * this method in fact restores the original size of the panel.
     * \param animate flag for the panel show-up animation disabling (\sa mAnimationTime).
     *
     * \sa mHidable, mHidden, mHideTimer, hidePanel(), hidePanelWork()
     */
    void showPanel(bool animate);
    /**
     * @brief Hides the panel (delayed) by starting the QTimer mHideTimer.
     * When this timer times out, hidePanelWork() will be called. So this
     * method is called when the cursor leaves the panel area but the panel
     * will be hidden later.
     *
     * \sa mHidable, mHidden, mHideTimer, showPanel(), hidePanelWork()
     */
    void hidePanel();
    /**
     * @brief Actually hides the panel. Will be invoked when the QTimer
     * mHideTimer times out. That timer will be started by showPanel(). This
     * is NOT the same as QWidget::hide() because hiding the panel in LXQt is
     * done by making the panel very thin. So this method in fact makes the
     * panel very thin while the QWidget stays visible.
     *
     * \sa mHidable, mHidden, mHideTimer, showPanel(), hidePanel()
     */
    void hidePanelWork();

    // Settings
    /**
     * @brief All the setter methods are  designed similar:
     * 1. Check if the given value is different from the current value. If not,
     * do not do anything and return.
     * 2. Set the value.
     * 3. If parameter save is true, call saveSettings(true) to store the
     * new settings on the disk.
     * 4. If necessary, propagate the new value to child objects, e.g. to
     * mLayout.
     * 5. If necessary, call update methods like realign() or
     * updateStyleSheet().
     * @param value The value that should be set.
     * @param save If true, saveSettings(true) will be called.
     */
    void setPanelSize(int value, bool save);
    void setIconSize(int value, bool save); //!< \sa setPanelSize()
    void setLineCount(int value, bool save); //!< \sa setPanelSize()
    void setLength(int length, bool inPercents, bool save); //!< \sa setPanelSize()
    void setPosition(int screen, ILXQtPanel::Position position, bool save); //!< \sa setPanelSize()
    void setAlignment(LXQtPanel::Alignment value, bool save); //!< \sa setPanelSize()
    void setFontColor(QColor color, bool save); //!< \sa setPanelSize()
    void setBackgroundColor(QColor color, bool save); //!< \sa setPanelSize()
    void setBackgroundImage(QString path, bool save); //!< \sa setPanelSize()
    void setOpacity(int opacity, bool save); //!< \sa setPanelSize()
    void setReserveSpace(bool reserveSpace, bool save); //!< \sa setPanelSize()
    void setHidable(bool hidable, bool save); //!< \sa setPanelSize()
    void setVisibleMargin(bool visibleMargin, bool save); //!< \sa setPanelSize()
    void setHideOnOverlap(bool hideOnOverlap, bool save);
    void setAnimationTime(int animationTime, bool save); //!< \sa setPanelSize()
    void setShowDelay(int showDelay, bool save); //!< \sa setPanelSize()
    void setIconTheme(const QString& iconTheme);

    /**
     * @brief Saves the current configuration, i.e. writes the current
     * configuration variables to mSettings.
     * @param later Determines if the settings are written immediately or
     * after a short delay. If later==true, the QTimer mDelaySave is started.
     * As soon as this timer times out, saveSettings(false) will be called. If
     * later==false, settings will be written.
     */
    void saveSettings(bool later=false);
    /**
     * @brief Checks if the panel can be placed on the current screen at the
     * current position. If it can not, it will be moved on another screen
     * where the desired position is possible.
     */
    void ensureVisible();

signals:
    /**
     * @brief This signal gets emitted whenever this panel receives a
     * QEvent::LayoutRequest, i.e. "Widget layout needs to be redone.".
     * The PanelPluginsModel will connect this signal to the individual
     * plugins so they can realign, too.
     */
    void realigned();
    /**
     * @brief This signal gets emitted at the end of
     * userRequestForDeletion() which in turn gets called when the user
     * decides to remove a panel. This signal is used by
     * LXQtPanelApplication to get notified whenever an LXQtPanel should
     * be removed.
     * @param self This LXQtPanel. LXQtPanelApplication will use this
     * parameter to identify the LXQtPanel that should be removed.
     */
    void deletedByUser(LXQtPanel *self);
    /**
     * @brief This signal is just a relay signal. The pluginAdded signal
     * of the PanelPluginsModel (mPlugins) will be connected to this
     * signal. Thereby, we can make this signal of a private member
     * available as a public signal.
     * Currently, this signal is used by LXQtPanelApplication which
     * will further re-emit this signal.
     */
    void pluginAdded();
    /**
     * @brief This signal is just a relay signal. The pluginRemoved signal
     * of the PanelPluginsModel (mPlugins) will be connected to this
     * signal. Thereby, we can make this signal of a private member
     * available as a public signal.
     * Currently, this signal is used by LXQtPanelApplication which
     * will further re-emit this signal.
     */
    void pluginRemoved();

protected:
    /**
     * @brief Overrides QObject::event(QEvent * e). Some functions of
     * the panel will be triggered by these events, e.g. showing/hiding
     * the panel or showing the context menu.
     * @param event The event that was received.
     * @return "QObject::event(QEvent *e) should return true if the event e
     * was recognized and processed." This is done by passing the event to
     * QFrame::event(QEvent *e) at the end.
     */
    bool event(QEvent *event) override;
    /**
     * @brief Overrides QWidget::showEvent(QShowEvent * event). This
     * method is called when a widget (in this case: the LXQtPanel) is
     * shown. The call could happen before and after the widget is shown.
     * This method is just overridden to get notified when the LXQtPanel
     * will be shown. Then, LXQtPanel will call realign().
     * @param event The QShowEvent sent by Qt.
     */
    void showEvent(QShowEvent *event) override;

public slots:
    /**
     * @brief Shows the ConfigPanelDialog and shows the "Config Panel"
     * page, i.e. calls showConfigPanelPage(). If the dialog does not
     * exist yet, it will be created before.
     *
     * The "Configure Panel" button in the context menu of the panel will
     * be connected to this slot so this method gets called whenever the
     * user clicks that button.
     *
     * Furthermore, this method will be called by LXQtPanelApplication
     * when a new plugin gets added (the LXQtPanel instances are handled
     * by LXQtPanelApplication). That is why this method/slot has to be
     * public.
     */
    void showConfigDialog();

private slots:
    /**
     * @brief Shows the ConfigPanelDialog and shows the "Config Plugins"
     * page, i.e. calls showConfigPluginsPage(). If the dialog does not
     * exist yet, it will be created before.
     *
     * The "Manage Widgets" button in the context menu of the panel will
     * be connected to this slot so this method gets called whenever the
     * user clicks that button.
     */
    void showAddPluginDialog();
    /**
     * @brief Recalculates the geometry of the panel and reserves the
     * window manager strut, i.e. it calls setPanelGeometry() and
     * updateWmStrut().
     * Two signals will be connected to this slot:
     * 1. QDesktopWidget::workAreaResized(int screen) which will be emitted
     * when the work area available (on screen) changes.
     * 2. LXQt::Application::themeChanged(), i.e. when the user changes
     * the theme.
     */
    void realign();
    /**
     * @brief Moves a plugin in PanelPluginsModel, i.e. calls
     * PanelPluginsModel::movePlugin(Plugin * plugin, QString const & nameAfter).
     * LXQtPanelLayout::pluginMoved() will be connected to this slot so
     * it gets called whenever a plugin was moved in the layout by the user.
     * @param plug
     */
    void pluginMoved(Plugin * plug);
    /**
     * @brief Removes this panel's entries from the config file and emits
     * the deletedByUser signal.
     * The "Remove Panel" button in the panel's context menu will
     * be connected to this slot, so this method will be called whenever
     * the user clicks "Remove Panel".
     */
    void userRequestForDeletion();

private:
    /**
     * @brief The LXQtPanelLayout of this panel. All the Plugins will be added
     * to the UI via this layout.
     */
    LXQtPanelLayout* mLayout;
    /**
     * @brief The LXQt::Settings instance as retrieved from
     * LXQtPanelApplication.
     */
    LXQt::Settings *mSettings;
    /**
     * @brief The background widget for the panel. This background widget will
     * have the background color or the background image if any of these is
     * set. This background widget will have the LXQtPanelLayout mLayout which
     * will in turn contain all the Plugins.
     */
    QFrame *LXQtPanelWidget;
    /**
     * @brief The name of the panel which will also be used as an identifier
     * for config files.
     */
    QString mConfigGroup;
    /**
     * @brief Pointer to the PanelPluginsModel which will store all the Plugins
     * that are loaded.
     */
    std::unique_ptr<PanelPluginsModel> mPlugins;
    /**
     * @brief object for storing info if some standalone window is shown
     * (for preventing hide)
     */
    std::unique_ptr<WindowNotifier> mStandaloneWindows;

    /**
     * @brief Returns the screen index of a screen on which this panel could
     * be placed at the given position. If possible, the current screen index
     * is preserved. So, if the panel can be placed on the current screen, the
     * index of that screen will be returned.
     * @param position position at which the panel should be placed.
     * @return The current screen index if the panel can be placed on the
     * current screen or the screen index of a screen that it can be placed on.
     *
     * \sa canPlacedOn(), mScreenNum, mActualScreenNum.
     */
    int findAvailableScreen(LXQtPanel::Position position);
    /**
     * @brief Update the window manager struts _NET_WM_PARTIAL_STRUT and
     * _NET_WM_STRUT for this widget. "The purpose of struts is to reserve
     * space at the borders of the desktop. This is very useful for a
     * docking area, a taskbar or a panel, for instance. The Window Manager
     * should take this reserved area into account when constraining window
     * positions - maximized windows, for example, should not cover that
     * area."
     * \sa http://standards.freedesktop.org/wm-spec/wm-spec-latest.html#NETWMSTRUT
     */
    void updateWmStrut();

    /**
     * @brief Loads the plugins, i.e. creates a new PanelPluginsModel.
     * Connects the signals and slots and adds all the plugins to the
     * layout.
     */
    void loadPlugins();

    /**
     * @brief Calculates and sets the geometry (i.e. the position and the size
     * on the screen) of the panel. Considers alignment, position, if the panel
     * is hidden and if its geometry should be set with animation.
     * \param animate flag if showing/hiding the panel should be animated.
     */
    void setPanelGeometry(bool animate = false);
    /**
     * @brief Sets the contents margins of the panel according to its position
     * and hiddenness. All margins are zero for visible panels.
     */
    void setMargins();
    /**
     * @brief Calculates the height of the panel if it is horizontal or the
     * width if the panel is vertical. Considers if the panel is hidden and
     * ensures that the result is at least PANEL_MINIMUM_SIZE.
     * @return The height/width of the panel.
     */
    int getReserveDimension();

    /**
     * @brief Calculates the margins of the layer window under Wayland
     * by considering the hidden state of the panel.
     * @return The margins of the layer window.
     */
    QMargins layerWindowMargins();

    /**
     * @brief Stores the geometry of the non-hidden panel, for use in
     * calculatePopupWindowPos()
     */
    QRect mGeometry;
    /**
     * @brief Stores the size of the panel, i.e. the height of a horizontal
     * panel or the width of a vertical panel in pixels. If the panel is
     * hidden (which is achieved by making the panel very thin), this value
     * is unchanged. So this value stores the size of the non-hidden panel.
     *
     * \sa panelSize(), setPanelSize().
     */
    int mPanelSize;
    /**
     * @brief Stores the edge length of the panel icons in pixels.
     *
     * \sa ILXQtPanel::iconSize(), setIconSize().
     */
    int mIconSize;
    /**
     * @brief Stores the number of lines/rows of the panel.
     *
     * \sa ILXQtPanel::lineCount(), setLineCount().
     */
    int mLineCount;

    /**
     * @brief Stores the length of the panel, i.e. the width of a horizontal
     * panel or the height of a vertical panel. The unit of this value is
     * determined by mLengthInPercents.
     *
     * \sa mLengthInPercents
     */
    int mLength;
    /**
     * @brief Stores if mLength is stored in pixels or relative to the
     * screen size in percents. If true, the length is stored in percents,
     * otherwise in pixels.
     *
     * \sa mLength
     */
    bool mLengthInPercents;

    /**
     * @brief Stores how this panel is aligned. The meaning of this value
     * differs for horizontal and vertical panels.
     *
     * \sa Alignment.
     */
    Alignment mAlignment;

    /**
     * @brief Stores the position where the panel is shown
     */
    ILXQtPanel::Position mPosition;
    /**
     * @brief Returns the index of the screen on which this panel should be
     * shown. This is the user configured value which can differ from the
     * screen that the panel is actually shown on. If the panel can not be
     * shown on the configured screen, LXQtPanel will determine another
     * screen. The screen that the panel is actually shown on is stored in
     * mActualScreenNum.
     *
     * @return The index of the screen on which this panel should be shown.
     *
     * \sa mActualScreenNum, canPlacedOn(), findAvailableScreen().
     */
    int mScreenNum;
    /**
     * @brief screen that the panel is currently shown at (this could
     * differ from mScreenNum).
     *
     * \sa mScreenNum, canPlacedOn(), findAvailableScreen().
     */
    int mActualScreenNum;
    /**
     * @brief QTimer for delayed saving of changed settings. In many cases,
     * instead of storing changes to disk immediately we start this timer.
     * If this timer times out, we store the changes to disk. This has the
     * advantage that we can store a couple of changes with only one write to
     * disk.
     *
     * \sa saveSettings()
     */
    QTimer mDelaySave;
    /**
     * @brief Stores if the panel is hidable, i.e. if the panel will be
     * hidden after the cursor has left the panel area.
     *
     * \sa mVisibleMargin, mHidden, mHideTimer, showPanel(), hidePanel(), hidePanelWork()
     */
    bool mHidable;
    /**
     * @brief Stores if the hidable panel should have a visible margin.
     *
     * \sa mHidable, mHidden, mHideTimer, showPanel(), hidePanel(), hidePanelWork()
     */
    bool mVisibleMargin;
    /**
     * @brief Stores if the panel should hide on overlapping a window.
     *
     * \sa mHidable, mHidden, mHideTimer, showPanel(), hidePanel(), hidePanelWork()
     */
    bool mHideOnOverlap;
    /**
     * @brief Stores if the panel is currently hidden.
     *
     * \sa mHidable, mVisibleMargin, mHideTimer, showPanel(), hidePanel(), hidePanelWork()
     */
    bool mHidden;
    /**
     * @brief QTimer for hiding the panel. When the cursor leaves the panel
     * area, this timer will be started. After this timer has timed out, the
     * panel will actually be hidden.
     *
     * \sa mHidable, mVisibleMargin, mHidden, showPanel(), hidePanel(), hidePanelWork()
     */
    QTimer mHideTimer;
    /**
     * @brief Stores the duration of auto-hide animation.
     *
     * \sa mHidden, mHideTimer, showPanel(), hidePanel(), hidePanelWork()
     */
    int mAnimationTime;
    /**
     * @brief The timer used for showing an auto-hiding panel with delay.
     *
     * \sa showPanel()
     */
    QTimer mShowDelayTimer;

    QColor mFontColor; //!< Font color that is used in the style sheet.
    QColor mBackgroundColor; //!< Background color that is used in the style sheet.
    QString mBackgroundImage; //!< Background image that is used in the style sheet.
    /**
     * @brief Determines the opacity of the background color. The value
     * should be in the range from 0 to 100. This will not affect the opacity
     * of a background image.
     */
    int mOpacity;
    /*!
     * \brief Flag if the panel should reserve the space under it as not usable
     * for "normal" windows. Usable for not 100% wide/hight or hiddable panels,
     * if user wants maximized windows go under the panel.
     *
     * \sa updateWmStrut()
     */
    bool mReserveSpace;

    /**
     * @brief Pointer to the current ConfigPanelDialog if there is any. Make
     * sure to test this pointer for validity because it is lazily loaded.
     */
    QPointer<ConfigPanelDialog> mConfigDialog;

    /**
     * @brief The animation used for showing/hiding an auto-hiding panel.
     */
    QPropertyAnimation *mAnimation; // on X11
    QVariantAnimation *mWAnimation; // on Wayland

    LayerShellQt::Window *mLayerWindow;

    /**
     * @brief Flag for providing the configuration options in panel's context menu
     */
    bool mLockPanel;

    /**
     * @brief Updates the style sheet for the panel. First, the stylesheet is
     * created from the preferences. Then, it is set via
     * QWidget::setStyleSheet().
     */
    void updateStyleSheet();

    /**
     * @brief Checks if the panel overlaps a window.
     */
    bool isPanelOverlapped() const;

    // settings should be kept private for security
    LXQt::Settings *settings() const { return mSettings; }
};


#endif // LXQTPANEL_H