File indexing completed on 2024-04-28 05:27:37
0001 /* 0002 SPDX-FileCopyrightText: 2016 Sebastian Kügler <sebas@kde.org> 0003 0004 Work sponsored by the LiMux project of the city of Munich: 0005 SPDX-FileCopyrightText: 2018 Kai Uwe Broulik <kde@broulik.de> 0006 0007 SPDX-FileCopyrightText: 2022 David Redondo <kde@david-redondo.de> 0008 SPDX-FileCopyrightText: 2023 Xaver Hugl <xaver.hugl@gmail.com> 0009 0010 SPDX-License-Identifier: GPL-2.0-or-later 0011 */ 0012 0013 #include "osdaction.h" 0014 0015 #include <KLocalizedString> 0016 #include <KScreen/Config> 0017 #include <KScreen/Mode> 0018 #include <KScreen/Output> 0019 #include <KScreen/SetConfigOperation> 0020 #include <QPoint> 0021 0022 using namespace KScreen; 0023 0024 QList<OsdAction> OsdAction::availableActions() 0025 { 0026 return { 0027 {SwitchToExternal, i18nd("kscreen_common", "Switch to external screen"), QStringLiteral("osd-shutd-laptop")}, 0028 {SwitchToInternal, i18nd("kscreen_common", "Switch to laptop screen"), QStringLiteral("osd-shutd-screen")}, 0029 {Clone, i18nd("kscreen_common", "Unify outputs"), QStringLiteral("osd-duplicate")}, 0030 {ExtendLeft, i18nd("kscreen_common", "Extend to left"), QStringLiteral("osd-sbs-left")}, 0031 {ExtendRight, i18nd("kscreen_common", "Extend to right"), QStringLiteral("osd-sbs-sright")}, 0032 {NoAction, i18nd("kscreen_common", "Leave unchanged"), QStringLiteral("dialog-cancel")}, 0033 }; 0034 } 0035 0036 void OsdAction::applyAction(const QSharedPointer<KScreen::Config> &config, Action action) 0037 { 0038 if (config->outputs().size() != 2) { 0039 return; 0040 } 0041 const auto copy = config->clone(); 0042 const auto outputs = copy->outputs(); 0043 auto internalIt = std::find_if(outputs.begin(), outputs.end(), [](const auto &output) { 0044 return output->type() == KScreen::Output::Type::Panel; 0045 }); 0046 if (internalIt == outputs.end()) { 0047 internalIt = outputs.begin(); 0048 } 0049 const auto internal = *internalIt; 0050 const auto external = *std::find_if(outputs.begin(), outputs.end(), [&internal](const auto &output) { 0051 return output != internal; 0052 }); 0053 switch (action) { 0054 case KScreen::OsdAction::Action::NoAction: 0055 return; 0056 case KScreen::OsdAction::Action::SwitchToExternal: 0057 internal->setEnabled(false); 0058 external->setEnabled(true); 0059 external->setPos(QPoint()); 0060 break; 0061 case KScreen::OsdAction::Action::SwitchToInternal: 0062 internal->setEnabled(true); 0063 internal->setPos(QPoint()); 0064 external->setEnabled(false); 0065 break; 0066 case KScreen::OsdAction::Action::Clone: { 0067 internal->setEnabled(true); 0068 external->setEnabled(true); 0069 internal->setPos(QPoint()); 0070 external->setPos(QPoint()); 0071 QList<KScreen::ModePtr> commonModes; 0072 const auto internalModes = internal->modes(); 0073 const auto externalModes = external->modes(); 0074 for (const auto &mode : internalModes) { 0075 const bool shared = std::any_of(externalModes.begin(), externalModes.end(), [&mode](const auto &otherMode) { 0076 return mode->size() == otherMode->size(); 0077 }); 0078 if (shared) { 0079 commonModes.push_back(mode); 0080 } 0081 } 0082 if (commonModes.isEmpty()) { 0083 return; 0084 } 0085 std::sort(commonModes.begin(), commonModes.end(), [](const auto &left, const auto &right) { 0086 return left->size().width() < right->size().width() && left->size().height() < right->size().height(); 0087 }); 0088 const auto biggestSize = commonModes.back()->size(); 0089 const auto findBestMode = [&biggestSize](const KScreen::OutputPtr &output) { 0090 auto list = output->modes(); 0091 list.erase(std::remove_if(list.begin(), 0092 list.end(), 0093 [&biggestSize](const auto &mode) { 0094 return mode->size() != biggestSize; 0095 }), 0096 list.end()); 0097 return *std::max_element(list.begin(), list.end(), [](const auto &left, const auto &right) { 0098 return left->refreshRate() < right->refreshRate(); 0099 }); 0100 }; 0101 internal->setCurrentModeId(findBestMode(internal)->id()); 0102 external->setCurrentModeId(findBestMode(external)->id()); 0103 external->setScale(internal->scale()); 0104 break; 0105 } 0106 case KScreen::OsdAction::Action::ExtendRight: { 0107 internal->setEnabled(true); 0108 external->setEnabled(true); 0109 internal->setPos(QPoint()); 0110 const double internalScale = internal->scale(); 0111 external->setPos(QPoint(std::ceil(internal->currentMode()->size().width() / internalScale), 0)); 0112 break; 0113 } 0114 case KScreen::OsdAction::Action::ExtendLeft: { 0115 internal->setEnabled(true); 0116 external->setEnabled(true); 0117 external->setPos(QPoint()); 0118 const double externalScale = external->scale(); 0119 internal->setPos(QPoint(std::ceil(external->currentMode()->size().width() / externalScale), 0)); 0120 break; 0121 } 0122 } 0123 new KScreen::SetConfigOperation(copy); 0124 } 0125 0126 #include "moc_osdaction.cpp"