File indexing completed on 2024-05-05 05:34:20
0001 /* 0002 * SPDX-FileCopyrightText: 2012 Alejandro Fiestas Olivares <afiestas@kde.org> 0003 * SPDX-FileCopyrightText: 2014 Daniel Vrátil <dvratil@redhat.com> 0004 * 0005 * SPDX-License-Identifier: LGPL-2.1-or-later 0006 */ 0007 0008 #pragma once 0009 0010 #include "kscreen_export.h" 0011 #include "output.h" 0012 #include "screen.h" 0013 #include "types.h" 0014 0015 #include <QHash> 0016 #include <QMetaType> 0017 #include <QObject> 0018 0019 #include <cstdint> 0020 #include <optional> 0021 0022 namespace KScreen 0023 { 0024 class Output; 0025 0026 /** 0027 * Represents a (or the) screen configuration. 0028 * 0029 * This is the main class of KScreen, with it you can use 0030 * the static methods current() to get the systems config and 0031 * setConfig() to apply a config to the system. 0032 * 0033 * Also, you can instantiate an empty Config, this is usually done 0034 * to create a config (with the objective of setting it) from scratch 0035 * and for example unserialize a saved config to it. 0036 * 0037 */ 0038 class KSCREEN_EXPORT Config : public QObject 0039 { 0040 Q_OBJECT 0041 Q_PROPERTY(ScreenPtr screen READ screen) 0042 Q_PROPERTY(OutputList outputs READ outputs) 0043 0044 public: 0045 enum class ValidityFlag { 0046 None = 0x0, 0047 RequireAtLeastOneEnabledScreen = 0x1, 0048 }; 0049 Q_ENUM(ValidityFlag) 0050 Q_DECLARE_FLAGS(ValidityFlags, ValidityFlag) 0051 0052 /** This indicates which features the used backend supports. 0053 * 0054 * @see supportedFeatures 0055 * @since 5.7 0056 */ 0057 enum class Feature { 0058 None = 0, ///< None of the mentioned features are supported. 0059 PrimaryDisplay = 1, ///< The backend knows about the concept of a primary display 0060 Writable = 1 << 1, ///< The backend supports setting the config, it's not read-only. 0061 PerOutputScaling = 1 << 2, ///< The backend supports scaling each output individually. 0062 OutputReplication = 1 << 3, ///< The backend supports replication of outputs. 0063 AutoRotation = 1 << 4, ///< The backend supports automatic rotation of outputs. 0064 TabletMode = 1 << 5, ///< The backend supports querying if a device is in tablet mode. 0065 SynchronousOutputChanges = 1 << 6, ///< The backend supports blocking until the output setting changes are applied 0066 XwaylandScales = 1 << 7, ///< The backend supports adapting Xwayland clients to a certain scale 0067 }; 0068 Q_ENUM(Feature) 0069 Q_DECLARE_FLAGS(Features, Feature) 0070 0071 /** 0072 * Validates that a config can be applied in the current system 0073 * 0074 * Each system has different constrains, this method will test 0075 * the given config with those constrains to see if it 0076 * can be applied. 0077 * 0078 * @arg config to be checked 0079 * @flags enable additional optional checks 0080 * @return true if the configuration can be applied, false if not. 0081 * @since 5.3.0 0082 */ 0083 static bool canBeApplied(const ConfigPtr &config, ValidityFlags flags); 0084 0085 /** 0086 * Validates that a config can be applied in the current system 0087 * 0088 * Each system has different constrains, this method will test 0089 * the given config with those constrains to see if it 0090 * can be applied. 0091 * 0092 * @arg config to be checked 0093 * @return true if the configuration can be applied, false if not. 0094 */ 0095 static bool canBeApplied(const ConfigPtr &config); 0096 0097 /** 0098 * Instantiate an empty config 0099 * 0100 * Usually you do not want to use this constructor since there are some 0101 * values that make no sense to set (for example you want the Screen of 0102 * the current systme). 0103 * 0104 * So usually what you do is call current() and then modify 0105 * whatever you need. 0106 */ 0107 explicit Config(); 0108 ~Config() override; 0109 0110 /** 0111 * Duplicates the config 0112 * 0113 * @return a new Config instance with same property values 0114 */ 0115 ConfigPtr clone() const; 0116 0117 /** 0118 * Returns an identifying hash for this config in regards to its 0119 * connected outputs. 0120 * 0121 * The hash is calculated with a sorted combination of all 0122 * connected output hashes. 0123 * 0124 * @return sorted hash combination of all connected outputs 0125 * @since 5.15 0126 */ 0127 QString connectedOutputsHash() const; 0128 0129 ScreenPtr screen() const; 0130 void setScreen(const ScreenPtr &screen); 0131 0132 OutputPtr output(int outputId) const; 0133 OutputList outputs() const; 0134 OutputList connectedOutputs() const; 0135 0136 /** 0137 * Find primary output. Primary output is the output with priority 1. May be 0138 * null. 0139 */ 0140 OutputPtr primaryOutput() const; 0141 /** 0142 * Setting output to be the primary one is equivalent to setting its 0143 * priority to 1. 0144 */ 0145 void setPrimaryOutput(const OutputPtr &output); 0146 /** 0147 * Add an output to this configuration. 0148 * 0149 * This method does not ensure consistency of priorities, it is up to the 0150 * caller to perform necessary adjustments afterwards. The reason is that it 0151 * might be used in a loop (such as adding all outputs) where committing 0152 * intermediate states is undesirable. 0153 */ 0154 void addOutput(const OutputPtr &output); 0155 /** 0156 * Remove an output with matching ID from this configuration. 0157 * 0158 * This method does not ensure consistency of priorities, it is up to the 0159 * caller to perform necessary adjustments afterwards. The reason is that it 0160 * might be used in a loop (such as removing all outputs) where committing 0161 * intermediate states is undesirable. 0162 */ 0163 void removeOutput(int outputId); 0164 /** 0165 * Replace all existing outputs with the given ones. 0166 * 0167 * Unlike addOutput and removeOutput which operate on individual items 0168 * presumably in a loop, this method will call adjustPriorities() before 0169 * returning. 0170 */ 0171 void setOutputs(const OutputList &outputs); 0172 0173 /** 0174 * Set output's priority and call adjustPriorities() trying to retain 0175 * relative ordering of the output. Setting priority to zero with this 0176 * method will disable the output, otherwise the output will be enabled. 0177 */ 0178 void setOutputPriority(const OutputPtr &output, uint32_t priority); 0179 0180 void setOutputPriorities(QMap<OutputPtr, uint32_t> &priorities); 0181 0182 /** 0183 * Ensure consistency and continuity of priorities. 0184 * 0185 * Most methods operating on outputs are doing so in loop, where committing 0186 * intermediate states is undesirable. This method restores the balance by 0187 * settings priority of all disabled outputs to 0, disabling all outputs 0188 * whose priority is 0 (i.e. it works in both directions), and sorting all 0189 * the remaining ones, such that they are numbered strictly sequentially 0190 * starting from 1. 0191 * @param keep The output, which priority should stay as close as possible 0192 * to its current one. It is not possible to guarantee, but the algorithm 0193 * will do its best to prioritize this output among others, if there happens 0194 * to be multiple ones with the same priority number. 0195 */ 0196 void adjustPriorities(std::optional<OutputPtr> keep = std::nullopt); 0197 0198 bool isValid() const; 0199 void setValid(bool valid); 0200 0201 void apply(const ConfigPtr &other); 0202 0203 /** Indicates features supported by the backend. This exists to allow the user 0204 * to find out which of the features offered by libkscreen are actually supported 0205 * by the backend. Not all backends are writable (QScreen, for example is 0206 * read-only, only XRandR, but not KWayland support the primary display, etc.). 0207 * 0208 * @return Flags for features that are supported for this config, determined by 0209 * the backend. 0210 * @see setSupportedFeatures 0211 * @since 5.7 0212 */ 0213 Features supportedFeatures() const; 0214 0215 /** Sets the features supported by this backend. This should not be called by the 0216 * user, but by the backend. 0217 * 0218 * @see supportedFeatures 0219 * @since 5.7 0220 */ 0221 void setSupportedFeatures(const Features &features); 0222 0223 /** 0224 * Indicates that the device supports switching between a default and a tablet mode. This is 0225 * common for convertibles. 0226 * 0227 * @return true when tablet mode is available, otherwise false 0228 * @see setTabletModeAvailable 0229 * @since 5.18 0230 */ 0231 bool tabletModeAvailable() const; 0232 0233 /** Sets if the device supports a tablet mode. This should not be called by the 0234 * user, but by the backend. 0235 * 0236 * @see tabletModeAvailable 0237 * @since 5.18 0238 */ 0239 void setTabletModeAvailable(bool available); 0240 0241 /** 0242 * Indicates that the device is currently in tablet mode. 0243 * 0244 * @return true when in tablet mode, otherwise false 0245 * @see setTabletModeEngaged 0246 * @since 5.18 0247 */ 0248 bool tabletModeEngaged() const; 0249 0250 /** 0251 * Sets if the device is currently in tablet mode. This should not be called by the 0252 * user, but by the backend. 0253 * 0254 * @see tabletModeEngaged 0255 * @since 5.18 0256 */ 0257 void setTabletModeEngaged(bool engaged); 0258 0259 QRect outputGeometryForOutput(const KScreen::Output &output) const; 0260 0261 QSizeF logicalSizeForOutput(const KScreen::Output &output) const; 0262 0263 /** 0264 * Returns the logical size of the output, converted to an integer. 0265 * 0266 * Takes the ceiling of non-integer sizes. 0267 */ 0268 QSize logicalSizeForOutputInt(const KScreen::Output &output) const; 0269 0270 Q_SIGNALS: 0271 void outputAdded(const KScreen::OutputPtr &output); 0272 void outputRemoved(int outputId); 0273 void prioritiesChanged(); 0274 0275 private: 0276 Q_DISABLE_COPY(Config) 0277 0278 class Private; 0279 Private *const d; 0280 }; 0281 0282 } // KScreen namespace 0283 0284 Q_DECLARE_OPERATORS_FOR_FLAGS(KScreen::Config::Features) 0285 0286 KSCREEN_EXPORT QDebug operator<<(QDebug dbg, const KScreen::ConfigPtr &config);