Bug 1635494 - Kill processes from about:processes;r=florian,flod

This adds a new button to kill processes.

Differential Revision: https://phabricator.services.mozilla.com/D82555
This commit is contained in:
David Teller 2020-07-22 10:05:14 +00:00
Родитель c74fd2537a
Коммит c7e969effc
4 изменённых файлов: 112 добавлений и 16 удалений

Просмотреть файл

@ -10,6 +10,7 @@ html {
body {
overflow-x: hidden;
}
#process-table {
-moz-user-select: none;
font-size: 1em;
@ -48,13 +49,19 @@ td:nth-child(1) {
/* At least one column needs to have a flexible width,
so no width specified for td:nth-child(2) */
td:nth-child(3) {
width: 10%;
width: 10%;
}
td:nth-child(4) {
width: 10%;
width: 10%;
}
td:nth-child(5) {
width: 10%;
width: 10%;
}
td:nth-child(6) {
width: 10%;
}
td:nth-child(7) {
width: 16px;
}
#process-thead > tr {
@ -73,7 +80,8 @@ td:nth-child(5) {
}
td {
padding: 5px 10px;
min-height: 2em;
min-height: 1.5em;
max-height: 1.5em;
color: var(--in-content-text-color);
max-width: 70vw;
overflow: hidden;
@ -167,3 +175,25 @@ td {
#process-tbody > tr.thread {
font-size-adjust: 0.5;
}
.killing {
opacity: 0.3;
transition-property: "opacity";
transition-duration: 1s;
}
.killed {
opacity: 0.3;
}
/* icons */
.close-icon {
background: url("chrome://global/skin/icons/delete.svg") no-repeat center;
opacity: 0;
}
tr:-moz-any([selected], :hover) > .close-icon {
opacity: 1;
}
.close-icon:hover {
background-color: var(--in-content-button-background);
}

Просмотреть файл

@ -5,6 +5,11 @@
# Page title
about-processes-title = Process Manager
## Tooltips
about-processes-shutdown-process =
.title = Kill process
## Column headers
about-processes-column-id = Id

Просмотреть файл

@ -22,6 +22,7 @@
<td class="clickable" id="column-cpu-user" data-l10n-id="about-processes-column-cpu-user"></td> <!-- CPU user. -->
<td class="clickable" id="column-cpu-kernel" data-l10n-id="about-processes-column-cpu-kernel"></td> <!-- CPU kernel. -->
<td class="clickable" id="column-cpu-threads" data-l10n-id="about-processes-column-threads"></td>
<td id="column-kill"></td><!-- Kill button. -->
</tr>
</thead>
<tbody id="process-tbody"></tbody>

Просмотреть файл

@ -229,7 +229,10 @@ var State = {
var View = {
_fragment: document.createDocumentFragment(),
// Processes that we killed during the previous iteration.
_killedRecently: [],
async commit() {
this._killedRecently.length = 0;
let tbody = document.getElementById("process-tbody");
// Force translation to happen before we insert the new content in the DOM
@ -329,6 +332,33 @@ var View = {
classes: ["numberOfThreads"],
});
// Column: Kill button – but not for all processes.
let killButton = this._addCell(row, {
content: "",
classes: ["action-icon"],
});
if (data.type == "socket") {
// We can't kill this process. Let's not pretend that we can.
// Don't display the kill button.
} else if (this._killedRecently.some(pid => pid == data.pid)) {
// We're racing between the "kill" action and the visual refresh.
// In a few cases, we could end up with the visual refresh showing
// a process as un-killed while we actually just killed it.
//
// We still want to display the process in case something actually
// went bad and the user needs the information to realize this.
// But we also want to make it visible that the process is being
// killed.
row.classList.add("killed");
} else {
// Otherwise, let's display the kill button.
killButton.classList.add("close-icon");
document.l10n.setAttributes(
killButton,
"about-processes-shutdown-process"
);
}
this._fragment.appendChild(row);
return row;
},
@ -391,13 +421,21 @@ var View = {
classes: ["numberOfThreads"],
});
// Column: Buttons (empty)
this._addCell(row, {
content: "",
classes: [],
});
this._fragment.appendChild(row);
return row;
},
_addCell(row, { content, classes }) {
let elt = document.createElement("td");
this._setTextAndTooltip(elt, content);
if (content) {
this._setTextAndTooltip(elt, content);
}
elt.classList.add(...classes);
row.appendChild(elt);
return elt;
@ -541,19 +579,13 @@ var Control = {
tbody.addEventListener("click", event => {
this._updateLastMouseEvent();
// Handle showing or hiding subitems of a row.
let target = event.target;
if (target.classList.contains("twisty")) {
let row = target.parentNode.parentNode;
let id = row.process.pid;
if (target.classList.toggle("open")) {
this._openItems.add(id);
this._showChildren(row);
View.insertAfterRow(row);
} else {
this._openItems.delete(id);
this._removeSubtree(row);
}
// Handle showing or hiding subitems of a row.
this._handleTwisty(target);
return;
} else if (target.classList.contains("close-icon")) {
this._handleClose(target);
return;
}
@ -756,6 +788,34 @@ var Control = {
return order;
});
},
_handleTwisty(target) {
let row = target.parentNode.parentNode;
let id = row.process.pid;
if (target.classList.toggle("open")) {
this._openItems.add(id);
this._showChildren(row);
View.insertAfterRow(row);
} else {
this._openItems.delete(id);
this._removeSubtree(row);
}
},
_handleClose(target) {
const ProcessTools = Cc["@mozilla.org/processtools-service;1"].getService(
Ci.nsIProcessToolsService
);
let row = target.parentNode;
let pid = row.process.pid;
ProcessTools.kill(pid);
row.classList.add("killing");
target.classList.remove("close-icon");
// Make sure that the user can't click twice on the kill button.
// Otherwise, chaos might ensure. Plus we risk crashing under Windows.
View._killedRecently.push(pid);
},
};
window.onload = async function() {