Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
618f5ad010 | ||
|
|
29fef7cb33 | ||
|
|
74ce2c20be | ||
|
|
e8fefe4ebe |
Generated
+2
-2
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "mrterm",
|
"name": "mrterm",
|
||||||
"version": "0.4.1",
|
"version": "0.4.3",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "mrterm",
|
"name": "mrterm",
|
||||||
"version": "0.4.1",
|
"version": "0.4.3",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@xterm/addon-fit": "^0.11.0",
|
"@xterm/addon-fit": "^0.11.0",
|
||||||
|
|||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "mrterm",
|
"name": "mrterm",
|
||||||
"productName": "MrTerm",
|
"productName": "MrTerm",
|
||||||
"version": "0.4.1",
|
"version": "0.4.3",
|
||||||
"description": "Moderner SSH-, SFTP- und RDP-Client",
|
"description": "Moderner SSH-, SFTP- und RDP-Client",
|
||||||
"main": "src/main/main.js",
|
"main": "src/main/main.js",
|
||||||
"author": "MrBlake",
|
"author": "MrBlake",
|
||||||
|
|||||||
+15
-2
@@ -7,14 +7,27 @@ const os = require('os');
|
|||||||
const path = require('path');
|
const path = require('path');
|
||||||
const i18n = require('../i18n');
|
const i18n = require('../i18n');
|
||||||
|
|
||||||
// Startet ein Programm und liefert den Exit-Code ('ENOENT', falls es nicht existiert)
|
// Startet ein Programm und liefert den Exit-Code ('ENOENT', falls es nicht existiert).
|
||||||
function run(cmd, args) {
|
// Electron/Chromium setzt unter Linux PR_SET_NO_NEW_PRIVS, das alle Kindprozesse erben – dann
|
||||||
|
// funktionieren weder pkexec noch sudo. Deshalb über systemd-run --user starten: Elternprozess ist
|
||||||
|
// dann der systemd-User-Manager, ohne diesen Schalter.
|
||||||
|
const GUI_ENV = ['DISPLAY', 'WAYLAND_DISPLAY', 'XAUTHORITY', 'XDG_RUNTIME_DIR', 'XDG_SESSION_TYPE', 'DBUS_SESSION_BUS_ADDRESS'];
|
||||||
|
function spawnCode(cmd, args) {
|
||||||
return new Promise((resolve) => {
|
return new Promise((resolve) => {
|
||||||
const p = spawn(cmd, args, { stdio: 'ignore' });
|
const p = spawn(cmd, args, { stdio: 'ignore' });
|
||||||
p.on('error', (e) => resolve(e.code === 'ENOENT' ? 'ENOENT' : e.message));
|
p.on('error', (e) => resolve(e.code === 'ENOENT' ? 'ENOENT' : e.message));
|
||||||
p.on('exit', (c) => resolve(c));
|
p.on('exit', (c) => resolve(c));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
let hasSystemdRun;
|
||||||
|
async function run(cmd, args) {
|
||||||
|
if (hasSystemdRun === undefined) hasSystemdRun = (await spawnCode('systemd-run', ['--user', '--quiet', '--wait', '--collect', 'true'])) === 0;
|
||||||
|
if (!hasSystemdRun) return spawnCode(cmd, args);
|
||||||
|
const inPath = cmd.includes('/') ? fs.existsSync(cmd) : (process.env.PATH || '').split(':').some((d) => d && fs.existsSync(path.join(d, cmd)));
|
||||||
|
if (!inPath) return 'ENOENT';
|
||||||
|
const env = GUI_ENV.filter((k) => process.env[k]).flatMap((k) => ['-E', `${k}=${process.env[k]}`]);
|
||||||
|
return spawnCode('systemd-run', ['--user', '--quiet', '--wait', '--collect', ...env, '--', cmd, ...args]);
|
||||||
|
}
|
||||||
|
|
||||||
// Fallback ohne Polkit-Agent: pacman -U per sudo in einem Terminalfenster; wartet, bis das Fenster geschlossen ist.
|
// Fallback ohne Polkit-Agent: pacman -U per sudo in einem Terminalfenster; wartet, bis das Fenster geschlossen ist.
|
||||||
// Der Erfolg wird über eine Marker-Datei erkannt, da nicht jedes Terminal den Exit-Code durchreicht.
|
// Der Erfolg wird über eine Marker-Datei erkannt, da nicht jedes Terminal den Exit-Code durchreicht.
|
||||||
|
|||||||
@@ -1018,6 +1018,7 @@ class TerminalSession {
|
|||||||
this.term.loadAddon(this.search);
|
this.term.loadAddon(this.search);
|
||||||
this.term.loadAddon(new WebLinksAddon.WebLinksAddon((_e, url) => api.call('shell:open', url)));
|
this.term.loadAddon(new WebLinksAddon.WebLinksAddon((_e, url) => api.call('shell:open', url)));
|
||||||
this.term.open($('.term', this.el));
|
this.term.open($('.term', this.el));
|
||||||
|
$('.term', this.el).style.background = termTheme().background; // Innenabstand in Terminalfarbe
|
||||||
this.term.onData((d) => { if (this.alive) api.ssh.write(this.id, d); else if (d === '\r' && this.ended) this.reconnect(); });
|
this.term.onData((d) => { if (this.alive) api.ssh.write(this.id, d); else if (d === '\r' && this.ended) this.reconnect(); });
|
||||||
this.term.onResize(({ cols, rows }) => { if (this.alive) api.ssh.resize(this.id, cols, rows); });
|
this.term.onResize(({ cols, rows }) => { if (this.alive) api.ssh.resize(this.id, cols, rows); });
|
||||||
this.term.onSelectionChange(() => { if (settings().copyOnSelect && this.term.hasSelection()) api.call('clipboard:write', this.term.getSelection()); });
|
this.term.onSelectionChange(() => { if (settings().copyOnSelect && this.term.hasSelection()) api.call('clipboard:write', this.term.getSelection()); });
|
||||||
@@ -1091,6 +1092,7 @@ class TerminalSession {
|
|||||||
applySettings() {
|
applySettings() {
|
||||||
const st = settings();
|
const st = settings();
|
||||||
Object.assign(this.term.options, { fontFamily: st.fontFamily, fontSize: st.fontSize, cursorStyle: st.cursorStyle, cursorBlink: st.cursorBlink, scrollback: st.scrollback, theme: termTheme() });
|
Object.assign(this.term.options, { fontFamily: st.fontFamily, fontSize: st.fontSize, cursorStyle: st.cursorStyle, cursorBlink: st.cursorBlink, scrollback: st.scrollback, theme: termTheme() });
|
||||||
|
$('.term', this.el).style.background = termTheme().background;
|
||||||
this.doFit();
|
this.doFit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -238,6 +238,7 @@ body.in-session #sidebar { display: none; }
|
|||||||
.session .term { flex: 1; min-width: 0; min-height: 0; overflow: hidden; }
|
.session .term { flex: 1; min-width: 0; min-height: 0; overflow: hidden; }
|
||||||
/* Innenabstand am .xterm-Element: FitAddon zieht nur dessen Padding ab (am Elternelement würde es mitgezählt) */
|
/* Innenabstand am .xterm-Element: FitAddon zieht nur dessen Padding ab (am Elternelement würde es mitgezählt) */
|
||||||
.session .term .xterm { height: 100%; padding: 8px 0 4px 10px; }
|
.session .term .xterm { height: 100%; padding: 8px 0 4px 10px; }
|
||||||
|
.session .term .xterm-viewport { background-color: transparent !important; } /* sonst schwarzer Rand im Innenabstand */
|
||||||
.session .overlay { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; flex-direction: column; gap: 16px; background: var(--overlay); z-index: 3; }
|
.session .overlay { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; flex-direction: column; gap: 16px; background: var(--overlay); z-index: 3; }
|
||||||
.session .overlay .spinner { width: 36px; height: 36px; border: 3px solid var(--border); border-top-color: var(--accent); border-radius: 50%; animation: spin 0.9s linear infinite; }
|
.session .overlay .spinner { width: 36px; height: 36px; border: 3px solid var(--border); border-top-color: var(--accent); border-radius: 50%; animation: spin 0.9s linear infinite; }
|
||||||
.session .overlay .msg { color: var(--muted); max-width: 520px; text-align: center; }
|
.session .overlay .msg { color: var(--muted); max-width: 520px; text-align: center; }
|
||||||
|
|||||||
Reference in New Issue
Block a user