File indexing completed on 2024-05-05 09:51:31
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 // negative means none of these 0082 if (currentIoSched >= 0) { 0083 QAbstractButton *iosched = ioScheduler->button(currentIoSched); 0084 if (iosched) { 0085 iosched->setChecked(true); // Check the current io scheduler 0086 } 0087 } 0088 0089 ioScheduler->setExclusive(true); 0090 0091 setSliderRange(); // Update the slider ranges before trying to set their current values 0092 if (ioniceSupported) { 0093 ui->sliderIO->setValue(currentIoPrio); 0094 } 0095 ui->sliderCPU->setValue(currentCpuPrio); 0096 0097 ui->imgCPU->setPixmap(QIcon::fromTheme(QStringLiteral("cpu")).pixmap(128, 128)); 0098 ui->imgIO->setPixmap(QIcon::fromTheme(QStringLiteral("drive-harddisk")).pixmap(128, 128)); 0099 0100 newCPUPriority = 40; 0101 0102 connect(cpuScheduler, &QButtonGroup::idClicked, this, &ReniceDlg::cpuSchedulerChanged); 0103 connect(ioScheduler, &QButtonGroup::idClicked, this, &ReniceDlg::updateUi); 0104 connect(ui->sliderCPU, &QAbstractSlider::valueChanged, this, &ReniceDlg::cpuSliderChanged); 0105 connect(ui->sliderIO, &QAbstractSlider::valueChanged, this, &ReniceDlg::ioSliderChanged); 0106 0107 updateUi(); 0108 0109 mainLayout->addWidget(buttonBox); 0110 } 0111 0112 ReniceDlg::~ReniceDlg() 0113 { 0114 delete ui; 0115 } 0116 0117 void ReniceDlg::ioSliderChanged(int value) 0118 { 0119 ui->sliderIO->setToolTip(QString::number(value)); 0120 } 0121 0122 void ReniceDlg::cpuSchedulerChanged(int value) 0123 { 0124 if (value != previous_cpuscheduler) { 0125 if ((value == (int)KSysGuard::Process::Other || value == KSysGuard::Process::Batch) 0126 && (previous_cpuscheduler == (int)KSysGuard::Process::Fifo || previous_cpuscheduler == (int)KSysGuard::Process::RoundRobin)) { 0127 int slider = -ui->sliderCPU->value() * 2 / 5 + 20; 0128 setSliderRange(); 0129 ui->sliderCPU->setValue(slider); 0130 } else if ((previous_cpuscheduler == (int)KSysGuard::Process::Other || previous_cpuscheduler == KSysGuard::Process::Batch) 0131 && (value == (int)KSysGuard::Process::Fifo || value == (int)KSysGuard::Process::RoundRobin)) { 0132 int slider = (-ui->sliderCPU->value() + 20) * 5 / 2; 0133 setSliderRange(); 0134 ui->sliderCPU->setValue(slider); 0135 } 0136 } 0137 previous_cpuscheduler = value; 0138 updateUi(); 0139 } 0140 0141 void ReniceDlg::cpuSliderChanged(int value) 0142 { 0143 if (ioniceSupported) { 0144 if (cpuScheduler->checkedId() == (int)KSysGuard::Process::Other || cpuScheduler->checkedId() == (int)KSysGuard::Process::Batch) { 0145 if (ioScheduler->checkedId() == -1 || ioScheduler->checkedId() == (int)KSysGuard::Process::None) { 0146 // ionice is 'Normal', thus automatically calculated based on cpunice 0147 ui->sliderIO->setValue((value + 20) / 5); 0148 } 0149 } 0150 } 0151 ui->sliderCPU->setToolTip(QString::number(value)); 0152 } 0153 0154 void ReniceDlg::updateUi() 0155 { 0156 bool cpuPrioEnabled = (cpuScheduler->checkedId() != -1); 0157 bool ioPrioEnabled = (ioniceSupported && ioScheduler->checkedId() != -1 && ioScheduler->checkedId() != (int)KSysGuard::Process::Idle 0158 && ioScheduler->checkedId() != (int)KSysGuard::Process::None); 0159 0160 ui->sliderCPU->setEnabled(cpuPrioEnabled); 0161 ui->lblCpuLow->setEnabled(cpuPrioEnabled); 0162 ui->lblCpuHigh->setEnabled(cpuPrioEnabled); 0163 0164 ui->sliderIO->setEnabled(ioPrioEnabled); 0165 ui->lblIOLow->setEnabled(ioPrioEnabled); 0166 ui->lblIOHigh->setEnabled(ioPrioEnabled); 0167 0168 ui->radioIONormal->setEnabled(ioniceSupported); 0169 ui->radioIdle->setEnabled(ioniceSupported); 0170 ui->radioRealTime->setEnabled(ioniceSupported); 0171 ui->radioBestEffort->setEnabled(ioniceSupported); 0172 0173 setSliderRange(); 0174 cpuSliderChanged(ui->sliderCPU->value()); 0175 ioSliderChanged(ui->sliderIO->value()); 0176 } 0177 0178 void ReniceDlg::setSliderRange() 0179 { 0180 if (cpuScheduler->checkedId() == (int)KSysGuard::Process::Other || cpuScheduler->checkedId() == (int)KSysGuard::Process::Batch 0181 || cpuScheduler->checkedId() == (int)KSysGuard::Process::Interactive) { 0182 // 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 0183 // later 0184 if (ui->sliderCPU->value() > 20) { 0185 ui->sliderCPU->setValue(20); 0186 } 0187 ui->sliderCPU->setInvertedAppearance(true); 0188 ui->sliderCPU->setMinimum(-20); 0189 ui->sliderCPU->setMaximum(19); 0190 ui->sliderCPU->setTickInterval(5); 0191 } else { 0192 if (ui->sliderCPU->value() < 1) { 0193 ui->sliderCPU->setValue(1); 0194 } 0195 ui->sliderCPU->setInvertedAppearance(false); 0196 ui->sliderCPU->setMinimum(1); 0197 ui->sliderCPU->setMaximum(99); 0198 ui->sliderCPU->setTickInterval(12); 0199 } 0200 } 0201 0202 void ReniceDlg::slotOk() 0203 { 0204 newCPUPriority = ui->sliderCPU->value(); 0205 newIOPriority = ui->sliderIO->value(); 0206 newCPUSched = cpuScheduler->checkedId(); 0207 newIOSched = ioScheduler->checkedId(); 0208 accept(); 0209 }