kwin/src/outputconfigurationstore.h
Xaver Hugl 7e095412aa outputconfigurationstore: add a fallback for when edid parsing fails
When edid parsing fails, KWin will base output settings on the connector, which
isn't great on its own, but at least works in many cases. When the edid can be
parsed later though, the display settings will reset because now the edid identifier
is used to exclude the old config (in which the latter is missing).
To work around that, this commit adds output identification based on the edid hash,
which is also not ideal, but can be safely matched with in case no output config
with a matching edid identifier exists.
2024-01-23 19:34:06 +00:00

105 lines
3.4 KiB
C++

/*
KWin - the KDE window manager
This file is part of the KDE project.
SPDX-FileCopyrightText: 2023 Xaver Hugl <xaver.hugl@gmail.com>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#pragma once
#include "core/output.h"
#include <QList>
#include <QPoint>
#include <QSize>
#include <memory>
#include <optional>
#include <tuple>
#include <unordered_map>
class QOrientationReading;
namespace KWin
{
class OutputConfiguration;
class OutputConfigurationStore
{
public:
OutputConfigurationStore();
~OutputConfigurationStore();
enum class ConfigType {
Preexisting,
Generated,
};
std::optional<std::tuple<OutputConfiguration, QList<Output *>, ConfigType>> queryConfig(const QList<Output *> &outputs, bool isLidClosed, QOrientationReading *orientation, bool isTabletMode);
void storeConfig(const QList<Output *> &allOutputs, bool isLidClosed, const OutputConfiguration &config, const QList<Output *> &outputOrder);
bool isAutoRotateActive(const QList<Output *> &outputs, bool isTabletMode) const;
private:
void applyOrientationReading(OutputConfiguration &config, const QList<Output *> &outputs, QOrientationReading *orientation, bool isTabletMode);
std::optional<std::pair<OutputConfiguration, QList<Output *>>> generateLidClosedConfig(const QList<Output *> &outputs);
std::pair<OutputConfiguration, QList<Output *>> generateConfig(const QList<Output *> &outputs, bool isLidClosed);
std::shared_ptr<OutputMode> chooseMode(Output *output) const;
double chooseScale(Output *output, OutputMode *mode) const;
double targetDpi(Output *output) const;
void load();
void save();
struct ModeData
{
QSize size;
uint32_t refreshRate;
};
struct OutputState
{
// identification data
std::optional<QString> edidIdentifier;
std::optional<QString> connectorName;
// empty if invalid
QString edidHash;
QString mstPath;
// actual state
std::optional<ModeData> mode;
std::optional<double> scale;
std::optional<OutputTransform> transform;
std::optional<OutputTransform> manualTransform;
std::optional<uint32_t> overscan;
std::optional<Output::RgbRange> rgbRange;
std::optional<VrrPolicy> vrrPolicy;
std::optional<bool> highDynamicRange;
std::optional<uint32_t> sdrBrightness;
std::optional<bool> wideColorGamut;
std::optional<Output::AutoRotationPolicy> autoRotation;
std::optional<QString> iccProfilePath;
std::optional<double> maxPeakBrightnessOverride;
std::optional<double> maxAverageBrightnessOverride;
std::optional<double> minBrightnessOverride;
std::optional<double> sdrGamutWideness;
};
struct SetupState
{
size_t outputIndex;
QPoint position;
bool enabled;
int priority;
};
struct Setup
{
bool lidClosed = false;
QList<SetupState> outputs;
};
std::pair<OutputConfiguration, QList<Output *>> setupToConfig(Setup *setup, const std::unordered_map<Output *, size_t> &outputMap) const;
std::optional<std::pair<Setup *, std::unordered_map<Output *, size_t>>> findSetup(const QList<Output *> &outputs, bool lidClosed);
std::optional<size_t> findOutput(Output *output, const QList<Output *> &allOutputs) const;
QList<OutputState> m_outputs;
QList<Setup> m_setups;
};
}