#pragma once #include "lts_multi_monitor_export.h" #include #include #include namespace LtsMultiMonitor { class LtsScreenBase; class MultiMonitorSelectorBase; class LtsScreenContainer; class LTSMULTIMONITOR_EXPORT LtsMultiMonitor : public QObject { Q_OBJECT public: static LtsMultiMonitor *getInstance(); /** * @brief selectScreen - Behaviour is undefined for widgets that are already placed on a screen. * @param widget to put on the screen * @param forceSelection selectScreen puts 'widget' on the main screen, if it's not currently occupied * by another widget - set to true if the user should select which screen 'widget' should be put on * instead of putting it on the main screen if it's not already occupied * @param swap * @return true if widget was in fact put on the screen - false if there is no screen free or the selection was aborted by the user */ bool selectScreen(QWidget *widget, LtsScreenContainer *swap = nullptr, bool putOnMainIfFree = true, bool ltsScreenNormalOnly = false, const QVector &irreplacableWidgets = {}); // WARNING: widget might be deleted after calling this (e.g. user closed the widget) - do not access widget after calling this! bool selectAndSwap(QWidget *widget); void setEnableMultiMonitorMode() { m_active = true; } void setDebugMultiMonitorMode() { m_debugMargins = true; } bool isActive() const { return m_active; } LtsScreenBase *widgetsScreen(QWidget *widget); /** * @brief putScreen is called only by LtsSession if a screen id preset for * a log-off-saved app was available * @param widget * @param screenId * @param screenPart * @return */ void freezeMagicCorner(int screenId); void unfreezeMagicCorner(int screenId); bool putScreen(QWidget *widget, int screenId, int screenPart); bool putScreenAutomatically(QWidget *widget); static void place(QWidget *widget); void setSkipScreen(int screenId, int subScreenId = -1) { m_skipScreenId = screenId; m_subSkipScreenId = subScreenId; } LtsScreenBase *mainScreen() const { return m_mainScreen; } int screenCount() const; // NOTE: screen count is 0 if mmm is inactive private slots: void screenDied(); private: LtsMultiMonitor(); ~LtsMultiMonitor(); static void cleanupLtsMultiMonitor(); void init(); bool cancelAndProcessIfInactive(QWidget *widget) const; static bool isWidgetSecondary(QWidget *widget) ; /** * @brief overlapBaseLayouts // NOTE: call 'init' before 'overlapBaseLayouts' * @param widget * @return */ bool overlapBaseLayouts(QWidget *widget); bool isOverlapBaseLayouts() const; QVector m_screens; int m_nextScreenId { 0 }; LtsScreenBase *m_mainScreen; // TODO C++17: std::optional bool m_active; bool m_initialized; int m_skipScreenId; int m_subSkipScreenId; //QWidget *m_dummy; bool m_overlapBaseLayouts; bool m_debugMargins; signals: void signalQuitLoop(); void signalSelected(); void signalScreenCountChanged(int); void signalMakeAllSwole(); }; } // namespace LtsMultiMonitor