Beispiel #1
0
KScreen::ConfigPtr Generator::idealConfig(const KScreen::ConfigPtr &currentConfig)
{
    Q_ASSERT(currentConfig);

//     KDebug::Block idealBlock("Ideal Config");
    KScreen::ConfigPtr config = currentConfig->clone();

    disableAllDisconnectedOutputs(config->outputs());

    KScreen::OutputList connectedOutputs = config->connectedOutputs();
    qCDebug(KSCREEN_KDED) << "Connected outputs: " << connectedOutputs.count();

    if (connectedOutputs.isEmpty()) {
        return config;
    }

    if (connectedOutputs.count() == 1) {
        singleOutput(connectedOutputs);
        return config;
    }

    if (isLaptop()) {
        laptop(connectedOutputs);
        return fallbackIfNeeded(config);
    }

    qCDebug(KSCREEN_KDED) << "Extend to Right";
    extendToRight(connectedOutputs);

    return fallbackIfNeeded(config);
}
Beispiel #2
0
KScreen::ConfigPtr Generator::fallbackIfNeeded(const KScreen::ConfigPtr &config)
{
    qCDebug(KSCREEN_KDED) << "fallbackIfNeeded()";

    KScreen::ConfigPtr newConfig;

    //If the ideal config can't be applied, try clonning
    if (!KScreen::Config::canBeApplied(config)) {
        if (isLaptop()) {
            newConfig = displaySwitch(Generator::Clone); // Try to clone at our best
        } else {
            newConfig = config;
            KScreen::OutputList connectedOutputs = config->connectedOutputs();
            if (connectedOutputs.isEmpty()) {
                return config;
            }
            connectedOutputs.value(connectedOutputs.keys().first())->setPrimary(true);
            cloneScreens(connectedOutputs);
        }
    } else {
        newConfig = config;
    }

    //If after trying to clone at our best, we fail... return current
    if (!KScreen::Config::canBeApplied(newConfig)) {
        qCDebug(KSCREEN_KDED) << "Config cannot be applied";
        newConfig = config;
    }

    return config;
}
Beispiel #3
0
void LoadSettings::loadConfiguration(KScreen::ConfigPtr config)
{
    QSettings settings("LXQt", "lxqt-config-monitor");
    QJsonDocument document = QJsonDocument::fromJson( settings.value("currentConfig").toByteArray() );
    QJsonObject json = document.object();
    QJsonArray array = json["outputs"].toArray();
    KScreen::OutputList outputs = config->outputs();
    for (const KScreen::OutputPtr &output : outputs)
    {
        qDebug() << "Output: " << output->name();
        for(int i=0;i<array.size();i++)
        {
            QJsonObject monitorSettings = array[i].toObject();
            if( monitorSettings["name"] == output->name() )
            {
                KScreen::Edid* edid = output->edid();
                if (edid && edid->isValid())
                    if( monitorSettings["hash"].toString() != edid->hash() )
                    {
                        qDebug() << "Hash: " << monitorSettings["hash"].toString() << "==" << edid->hash();
                        return exit(1); // Saved settings are from other monitor
                    }
                if( monitorSettings["connected"].toBool() != output->isConnected() )
                    return exit(2); // Saved settings are from other monitor
                if( !output->isConnected() )
                    continue;
                output->setEnabled( monitorSettings["enabled"].toBool() );
                output->setPrimary( monitorSettings["primary"].toBool() );
                output->setPos( QPoint(monitorSettings["xPos"].toInt(),monitorSettings["yPos"].toInt()) );
                output->setCurrentModeId( monitorSettings["currentMode"].toString() );
                output->setRotation( (KScreen::Output::Rotation)(monitorSettings["rotation"].toInt()) );
            }
        }
    }

    if (KScreen::Config::canBeApplied(config))
        KScreen::SetConfigOperation(config).exec();

    exit(0);
}
Beispiel #4
0
MonitorWidget::MonitorWidget(KScreen::OutputPtr output, KScreen::ConfigPtr config, QWidget* parent) :
    QGroupBox(parent)
{
    this->output = output;
    this->config = config;

    ui.setupUi(this);

    ui.enabledCheckbox->setChecked(output->isEnabled());

    QList <KScreen::ModePtr> modeList = output->modes().values();

    // Remove duplicate sizes
    QMap<QString, KScreen::ModePtr> noDuplicateModes;
    for(const KScreen::ModePtr &mode : qAsConst(modeList))
    {
        if( noDuplicateModes.keys().contains(modeToString(mode)) )
        {
            KScreen::ModePtr actual = noDuplicateModes[modeToString(mode)];
            bool isActualPreferred = output->preferredModes().contains(actual->id());
            bool isModePreferred = output->preferredModes().contains(mode->id());
            if( ( mode->refreshRate() > actual->refreshRate() && !isActualPreferred ) || isModePreferred )
                noDuplicateModes[modeToString(mode)] = mode;
        }
        else
            noDuplicateModes[modeToString(mode)] = mode;
    }

    // Sort modes by size
    modeList = noDuplicateModes.values();
    qSort(modeList.begin(), modeList.end(), sizeBiggerThan);

    // Add each mode to the list
    for (const KScreen::ModePtr &mode : qAsConst(modeList))
    {
        ui.resolutionCombo->addItem(modeToString(mode), mode->id());
        if(output->preferredModes().contains(mode->id()))
        {
             // Make bold preferredModes
             QFont font = ui.resolutionCombo->font();
             font.setBold(true);
             ui.resolutionCombo->setItemData(ui.resolutionCombo->count()-1, font, Qt::FontRole);
        }
    }
    connect(ui.resolutionCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(onResolutionChanged(int)));

    // Select actual mode in list
    if (output->currentMode())
    {
        // Set the current mode in dropdown
        int idx = ui.resolutionCombo->findData(output->currentMode()->id());
        if (idx < 0)
        {
            // Select mode with same size
            for (const KScreen::ModePtr &mode : qAsConst(modeList))
            {
                if( mode->size() == output->currentMode()->size() )
                    idx = ui.resolutionCombo->findData(output->currentMode()->id());
            }
        }
        if(idx < 0)
            idx = ui.resolutionCombo->findData(output->preferredMode()->id());
        if (idx >= 0)
            ui.resolutionCombo->setCurrentIndex(idx);
    }
    updateRefreshRates();


    // Update EDID information
    // KScreen doesn't make much public but that's ok...
    KScreen::Edid* edid = output->edid();
    if (edid && edid->isValid())
    {
        ui.outputInfoLabel->setText(
            tr("Name: %1\n").arg(edid->name()) %
            tr("Vendor: %1\n").arg(edid->vendor()) %
            tr("Serial: %1\n").arg(edid->serial()) %
            tr("Display size: %1cm x %2cm\n").arg(edid->width()).arg(edid->height()) %
            tr("Serial number: %1\n").arg(edid->serial()) %
            tr("EISA device ID: %1\n").arg(edid->eisaId())
        );
    }

    if (config->connectedOutputs().count() == 1)
    {
        setOnlyMonitor(true);
        // There isn't always a primary output. Gross.
        output->setPrimary(true);
    }

    ui.xPosSpinBox->setValue(output->pos().x());
    ui.yPosSpinBox->setValue(output->pos().y());

    // Behavior chooser
    if (output->isPrimary())
        ui.behaviorCombo->setCurrentIndex(PrimaryDisplay);
    else
        ui.behaviorCombo->setCurrentIndex(ExtendDisplay);

    // Insert orientations
    ui.orientationCombo->addItem(tr("None"), KScreen::Output::None);
    ui.orientationCombo->addItem(tr("Left"), KScreen::Output::Left);
    ui.orientationCombo->addItem(tr("Right"), KScreen::Output::Right);
    ui.orientationCombo->addItem(tr("Inverted"), KScreen::Output::Inverted);
    switch(output->rotation())
    {
    case KScreen::Output::None:
            ui.orientationCombo->setCurrentIndex(0);
        break;
    case KScreen::Output::Left:
        ui.orientationCombo->setCurrentIndex(1);
        break;
    case KScreen::Output::Right:
            ui.orientationCombo->setCurrentIndex(2);
        break;
    case KScreen::Output::Inverted:
        ui.orientationCombo->setCurrentIndex(3);
        break;
    }

    connect(ui.enabledCheckbox, SIGNAL(toggled(bool)), this, SLOT(onEnabledChanged(bool)));
    connect(ui.behaviorCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(onBehaviorChanged(int)));
    connect(ui.xPosSpinBox, SIGNAL(valueChanged(int)), this, SLOT(onPositionChanged(int)));
    connect(ui.yPosSpinBox, SIGNAL(valueChanged(int)), this, SLOT(onPositionChanged(int)));
    connect(ui.orientationCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(onOrientationChanged(int)));

    // Force update behavior visibility
    onBehaviorChanged(ui.behaviorCombo->currentIndex());
}
Beispiel #5
0
KScreen::ConfigPtr Generator::displaySwitch(DisplaySwitchAction action)
{
//     KDebug::Block switchBlock("Display Switch");
    KScreen::ConfigPtr config = m_currentConfig;
    Q_ASSERT(config);


    KScreen::OutputList connectedOutputs = config->connectedOutputs();

    // There's not much else we can do with only one output
    if (connectedOutputs.count() < 2) {
        singleOutput(connectedOutputs);
        return config;
    }

    // We cannot try all possible combinations with two and more outputs
    if (connectedOutputs.count() > 2) {
        extendToRight(connectedOutputs);
        return config;
    }

    KScreen::OutputPtr embedded, external;
    embedded = embeddedOutput(connectedOutputs);
    // If we don't have an embedded output (desktop with two external screens
    // for instance), then pretend one of them is embedded
    if (!embedded) {
        embedded = connectedOutputs.value(connectedOutputs.keys().first());
    }
    // Just to be sure
    if (embedded->modes().isEmpty()) {
        return config;
    }

    if (action == Generator::Clone) {
        qCDebug(KSCREEN_KDED) << "Cloning";
        embedded->setPrimary(true);
        cloneScreens(connectedOutputs);
        return config;
    }

    connectedOutputs.remove(embedded->id());
    external = connectedOutputs.value(connectedOutputs.keys().first());
    // Just to be sure
    if (external->modes().isEmpty()) {
        return config;
    }

    switch (action) {
    case Generator::ExtendToLeft: {
        qCDebug(KSCREEN_KDED) << "Extend to left";
        external->setPos(QPoint(0,0));
        external->setEnabled(true);
        const KScreen::ModePtr extMode = bestModeForOutput(external);
        Q_ASSERT(extMode);
        external->setCurrentModeId(extMode->id());

        Q_ASSERT(external->currentMode()); // we must have a mode now
        const QSize size = external->currentMode()->size();
        embedded->setPos(QPoint(size.width(), 0));
        embedded->setEnabled(true);
        embedded->setPrimary(true);
        const KScreen::ModePtr embeddedMode = bestModeForOutput(embedded);
        Q_ASSERT(embeddedMode);
        embedded->setCurrentModeId(embeddedMode->id());

        return config;
    }
    case Generator::TurnOffEmbedded: {
        qCDebug(KSCREEN_KDED) << "Turn off embedded (laptop)";
        embedded->setEnabled(false);
        embedded->setPrimary(false);

        external->setEnabled(true);
        external->setPrimary(true);
        const KScreen::ModePtr extMode = bestModeForOutput(external);
        Q_ASSERT(extMode);
        external->setCurrentModeId(extMode->id());
        return config;
    }
    case Generator::TurnOffExternal: {
        qCDebug(KSCREEN_KDED) << "Turn off external screen";
        embedded->setPos(QPoint(0,0));
        embedded->setEnabled(true);
        embedded->setPrimary(true);
        const KScreen::ModePtr embeddedMode = bestModeForOutput(embedded);
        Q_ASSERT(embeddedMode);
        embedded->setCurrentModeId(embeddedMode->id());

        external->setEnabled(false);
        external->setPrimary(false);
        return config;
    }
    case Generator::ExtendToRight: {
        qCDebug(KSCREEN_KDED) << "Extend to the right";
        embedded->setPos(QPoint(0,0));
        embedded->setEnabled(true);
        embedded->setPrimary(true);
        const KScreen::ModePtr embeddedMode = bestModeForOutput(embedded);
        Q_ASSERT(embeddedMode);
        embedded->setCurrentModeId(embeddedMode->id());


        Q_ASSERT(embedded->currentMode()); // we must have a mode now
        const QSize size = embedded->currentMode()->size();
        external->setPos(QPoint(size.width(), 0));
        external->setEnabled(true);
        external->setPrimary(false);
        const KScreen::ModePtr extMode = bestModeForOutput(external);
        Q_ASSERT(extMode);
        external->setCurrentModeId(extMode->id());

        return config;
    }
    default:
        // None: just return config
        // Clone: handled above
        break;
    } // switch

    return config;
}