7e095412aa
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.
105 lines
3.4 KiB
C++
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;
|
|
};
|
|
}
|