File indexing completed on 2024-05-12 13:37:06
0001 /* 0002 KSysGuard, the KDE System Guard 0003 0004 SPDX-FileCopyrightText: 1999 Chris Schlaeger <cs@kde.org> 0005 SPDX-FileCopyrightText: 2007 John Tapsell <tapsell@kde.org> 0006 0007 SPDX-License-Identifier: LGPL-2.0-or-later 0008 0009 0010 */ 0011 #include "ReniceDlg.h" 0012 0013 #include <klocalizedstring.h> 0014 0015 #include "processcore/process.h" 0016 #include "ui_ReniceDlgUi.h" 0017 #include <QButtonGroup> 0018 #include <QDialogButtonBox> 0019 #include <QListWidget> 0020 #include <QPushButton> 0021 #include <QVBoxLayout> 0022 0023 ReniceDlg::ReniceDlg(QWidget *parent, const QStringList &processes, int currentCpuPrio, int currentCpuSched, int currentIoPrio, int currentIoSched) 0024 : QDialog(parent) 0025 { 0026 setObjectName(QStringLiteral("Renice Dialog")); 0027 setModal(true); 0028 setWindowTitle(i18n("Set Priority")); 0029 QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this); 0030 previous_cpuscheduler = 0; 0031 0032 if (currentIoSched == KSysGuard::Process::None) { 0033 // CurrentIoSched == 0 means that the priority is set automatically. 0034 // Using the formula given by the linux kernel Documentation/block/ioprio 0035 currentIoPrio = (currentCpuPrio + 20) / 5; 0036 } 0037 if (currentIoSched == (int)KSysGuard::Process::BestEffort && currentIoPrio == (currentCpuPrio + 20) / 5) { 0038 // Unfortunately, in linux you can't ever set a process back to being None. So we fake it :) 0039 currentIoSched = KSysGuard::Process::None; 0040 } 0041 ioniceSupported = (currentIoPrio != -2); 0042 0043 QVBoxLayout *mainLayout = new QVBoxLayout(this); 0044 0045 QPushButton *okButton = buttonBox->button(QDialogButtonBox::Ok); 0046 okButton->setDefault(true); 0047 okButton->setShortcut(Qt::CTRL | Qt::Key_Return); 0048 connect(buttonBox, &QDialogButtonBox::accepted, this, &ReniceDlg::slotOk); 0049 connect(buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject); 0050 0051 QWidget *widget = new QWidget(this); 0052 mainLayout->addWidget(widget); 0053 ui = new Ui_ReniceDlgUi(); 0054 ui->setupUi(widget); 0055 ui->listWidget->insertItems(0, processes); 0056 0057 cpuScheduler = new QButtonGroup(this); 0058 cpuScheduler->addButton(ui->radioNormal, (int)KSysGuard::Process::Other); 0059 #ifndef Q_OS_SOLARIS 0060 cpuScheduler->addButton(ui->radioBatch, (int)KSysGuard::Process::Batch); 0061 #else 0062 cpuScheduler->addButton(ui->radioBatch, (int)KSysGuard::Process::Interactive); 0063 ui->radioBatch->setText(i18nc("Scheduler", "Interactive")); 0064 #endif 0065 cpuScheduler->addButton(ui->radioFIFO, (int)KSysGuard::Process::Fifo); 0066 cpuScheduler->addButton(ui->radioRR, (int)KSysGuard::Process::RoundRobin); 0067 if (currentCpuSched >= 0) { // negative means none of these 0068 QAbstractButton *sched = cpuScheduler->button(currentCpuSched); 0069 if (sched) { 0070 sched->setChecked(true); // Check the current scheduler 0071 previous_cpuscheduler = currentCpuSched; 0072 } 0073 } 0074 cpuScheduler->setExclusive(true); 0075 0076 ioScheduler = new QButtonGroup(this); 0077 ioScheduler->addButton(ui->radioIONormal, (int)KSysGuard::Process::None); 0078 ioScheduler->addButton(ui->radioIdle, (int)KSysGuard::Process::Idle); 0079 ioScheduler->addButton(ui->radioRealTime, (int)KSysGuard::Process::RealTime); 0080 ioScheduler->addButton(ui->radioBestEffort, (int)KSysGuard::Process::BestEffort); 0081 if (currentIoSched >= 0) { // negative means none of these 0082 QAbstractButton *iosched = ioScheduler->button(currentIoSched); 0083 if (iosched) 0084 iosched->setChecked(true); // Check the current io scheduler 0085 } 0086 0087 ioScheduler->setExclusive(true); 0088 0089 setSliderRange(); // Update the slider ranges before trying to set their current values 0090 if (ioniceSupported) 0091 ui->sliderIO->setValue(currentIoPrio); 0092 ui->sliderCPU->setValue(currentCpuPrio); 0093 0094 ui->imgCPU->setPixmap(QIcon::fromTheme(QStringLiteral("cpu")).pixmap(128, 128)); 0095 ui->imgIO->setPixmap(QIcon::fromTheme(QStringLiteral("drive-harddisk")).pixmap(128, 128)); 0096 0097 newCPUPriority = 40; 0098 0099 connect(cpuScheduler, SIGNAL(buttonClicked(int)), this, SLOT(cpuSchedulerChanged(int))); 0100 connect(ioScheduler, SIGNAL(buttonClicked(int)), this, SLOT(updateUi())); 0101 connect(ui->sliderCPU, &QAbstractSlider::valueChanged, this, &ReniceDlg::cpuSliderChanged); 0102 connect(ui->sliderIO, &QAbstractSlider::valueChanged, this, &ReniceDlg::ioSliderChanged); 0103 0104 updateUi(); 0105 0106 mainLayout->addWidget(buttonBox); 0107 } 0108 0109 ReniceDlg::~ReniceDlg() 0110 { 0111 delete ui; 0112 } 0113 0114 void ReniceDlg::ioSliderChanged(int value) 0115 { 0116 ui->sliderIO->setToolTip(QString::number(value)); 0117 } 0118 0119 void ReniceDlg::cpuSchedulerChanged(int value) 0120 { 0121 if (value != previous_cpuscheduler) { 0122 if ((value == (int)KSysGuard::Process::Other || value == KSysGuard::Process::Batch) 0123 && (previous_cpuscheduler == (int)KSysGuard::Process::Fifo || previous_cpuscheduler == (int)KSysGuard::Process::RoundRobin)) { 0124 int slider = -ui->sliderCPU->value() * 2 / 5 + 20; 0125 setSliderRange(); 0126 ui->sliderCPU->setValue(slider); 0127 } else if ((previous_cpuscheduler == (int)KSysGuard::Process::Other || previous_cpuscheduler == KSysGuard::Process::Batch) 0128 && (value == (int)KSysGuard::Process::Fifo || value == (int)KSysGuard::Process::RoundRobin)) { 0129 int slider = (-ui->sliderCPU->value() + 20) * 5 / 2; 0130 setSliderRange(); 0131 ui->sliderCPU->setValue(slider); 0132 } 0133 } 0134 previous_cpuscheduler = value; 0135 updateUi(); 0136 } 0137 0138 void ReniceDlg::cpuSliderChanged(int value) 0139 { 0140 if (ioniceSupported) { 0141 if (cpuScheduler->checkedId() == (int)KSysGuard::Process::Other || cpuScheduler->checkedId() == (int)KSysGuard::Process::Batch) { 0142 if (ioScheduler->checkedId() == -1 || ioScheduler->checkedId() == (int)KSysGuard::Process::None) { 0143 // ionice is 'Normal', thus automatically calculated based on cpunice 0144 ui->sliderIO->setValue((value + 20) / 5); 0145 } 0146 } 0147 } 0148 ui->sliderCPU->setToolTip(QString::number(value)); 0149 } 0150 0151 void ReniceDlg::updateUi() 0152 { 0153 bool cpuPrioEnabled = (cpuScheduler->checkedId() != -1); 0154 bool ioPrioEnabled = (ioniceSupported && ioScheduler->checkedId() != -1 && ioScheduler->checkedId() != (int)KSysGuard::Process::Idle 0155 && ioScheduler->checkedId() != (int)KSysGuard::Process::None); 0156 0157 ui->sliderCPU->setEnabled(cpuPrioEnabled); 0158 ui->lblCpuLow->setEnabled(cpuPrioEnabled); 0159 ui->lblCpuHigh->setEnabled(cpuPrioEnabled); 0160 0161 ui->sliderIO->setEnabled(ioPrioEnabled); 0162 ui->lblIOLow->setEnabled(ioPrioEnabled); 0163 ui->lblIOHigh->setEnabled(ioPrioEnabled); 0164 0165 ui->radioIONormal->setEnabled(ioniceSupported); 0166 ui->radioIdle->setEnabled(ioniceSupported); 0167 ui->radioRealTime->setEnabled(ioniceSupported); 0168 ui->radioBestEffort->setEnabled(ioniceSupported); 0169 0170 setSliderRange(); 0171 cpuSliderChanged(ui->sliderCPU->value()); 0172 ioSliderChanged(ui->sliderIO->value()); 0173 } 0174 0175 void ReniceDlg::setSliderRange() 0176 { 0177 if (cpuScheduler->checkedId() == (int)KSysGuard::Process::Other || cpuScheduler->checkedId() == (int)KSysGuard::Process::Batch 0178 || cpuScheduler->checkedId() == (int)KSysGuard::Process::Interactive) { 0179 // The slider is setting the priority, so goes from 19 to -20. We cannot actually do this with a slider, so instead we go from -19 to 20, and negate 0180 // later 0181 if (ui->sliderCPU->value() > 20) 0182 ui->sliderCPU->setValue(20); 0183 ui->sliderCPU->setInvertedAppearance(true); 0184 ui->sliderCPU->setMinimum(-20); 0185 ui->sliderCPU->setMaximum(19); 0186 ui->sliderCPU->setTickInterval(5); 0187 } else { 0188 if (ui->sliderCPU->value() < 1) 0189 ui->sliderCPU->setValue(1); 0190 ui->sliderCPU->setInvertedAppearance(false); 0191 ui->sliderCPU->setMinimum(1); 0192 ui->sliderCPU->setMaximum(99); 0193 ui->sliderCPU->setTickInterval(12); 0194 } 0195 } 0196 0197 void ReniceDlg::slotOk() 0198 { 0199 newCPUPriority = ui->sliderCPU->value(); 0200 newIOPriority = ui->sliderIO->value(); 0201 newCPUSched = cpuScheduler->checkedId(); 0202 newIOSched = ioScheduler->checkedId(); 0203 accept(); 0204 }