Various fixes

This commit is contained in:
crschnick 2024-08-24 12:40:00 +00:00
parent 4adb18249b
commit d6cb3bf2bd
16 changed files with 64 additions and 21 deletions

View file

@ -12,7 +12,7 @@ public class SshLaunchExchangeImpl extends SshLaunchExchange {
@Override @Override
public Object handle(HttpExchange exchange, Request msg) throws Exception { public Object handle(HttpExchange exchange, Request msg) throws Exception {
var usedDialect = ShellDialects.ALL.stream() var usedDialect = ShellDialects.getStartableDialects().stream()
.filter(dialect -> dialect.getExecutableName().equalsIgnoreCase(msg.getArguments())) .filter(dialect -> dialect.getExecutableName().equalsIgnoreCase(msg.getArguments()))
.findFirst(); .findFirst();
if (msg.getArguments() != null if (msg.getArguments() != null
@ -21,6 +21,8 @@ public class SshLaunchExchangeImpl extends SshLaunchExchange {
throw new BeaconClientException("Unexpected argument: " + msg.getArguments()); throw new BeaconClientException("Unexpected argument: " + msg.getArguments());
} }
// There are sometimes multiple requests by a terminal client (e.g. Termius)
// This might fail sometimes, but it is expected
var r = TerminalLauncherManager.waitForNextLaunch(); var r = TerminalLauncherManager.waitForNextLaunch();
var c = ProcessControlProvider.get() var c = ProcessControlProvider.get()
.getEffectiveLocalDialect() .getEffectiveLocalDialect()

View file

@ -166,7 +166,7 @@ public class BrowserTransferModel {
var target = downloads.resolve(file.getFileName()); var target = downloads.resolve(file.getFileName());
// Prevent DirectoryNotEmptyException // Prevent DirectoryNotEmptyException
if (Files.exists(target) && Files.isDirectory(target)) { if (Files.exists(target) && Files.isDirectory(target)) {
Files.delete(target); FileUtils.deleteDirectory(target.toFile());
} }
Files.move(file, target, StandardCopyOption.REPLACE_EXISTING); Files.move(file, target, StandardCopyOption.REPLACE_EXISTING);
} }

View file

@ -634,6 +634,10 @@ public final class BrowserFileListComp extends SimpleComp {
var it = getTableRow().getItem(); var it = getTableRow().getItem();
editing.setValue(null); editing.setValue(null);
ThreadHelper.runAsync(() -> { ThreadHelper.runAsync(() -> {
if (it == null) {
return;
}
var r = fileList.rename(it, newValue); var r = fileList.rename(it, newValue);
Platform.runLater(() -> { Platform.runLater(() -> {
updateItem(getItem(), isEmpty()); updateItem(getItem(), isEmpty());

View file

@ -99,7 +99,8 @@ public final class BrowserFileListModel {
} }
public BrowserEntry rename(BrowserEntry old, String newName) { public BrowserEntry rename(BrowserEntry old, String newName) {
if (fileSystemModel == null if (old == null || newName == null
|| fileSystemModel == null
|| fileSystemModel.isClosed() || fileSystemModel.isClosed()
|| fileSystemModel.getCurrentPath().get() == null) { || fileSystemModel.getCurrentPath().get() == null) {
return old; return old;

View file

@ -142,7 +142,7 @@ public class OpenFileSystemComp extends SimpleComp {
} }
keyEvent.consume(); keyEvent.consume();
}); });
InputHelper.onKeyCombination(root, new KeyCodeCombination(KeyCode.BACK_SPACE), true, keyEvent -> { InputHelper.onKeyCombination(root, new KeyCodeCombination(KeyCode.BACK_SPACE), false, keyEvent -> {
var p = model.getCurrentParentDirectory(); var p = model.getCurrentParentDirectory();
if (p != null) { if (p != null) {
model.cdAsync(p.getPath()); model.cdAsync(p.getPath());

View file

@ -10,6 +10,7 @@ import io.xpipe.app.fxcomps.util.PlatformThread;
import io.xpipe.app.issue.ErrorEvent; import io.xpipe.app.issue.ErrorEvent;
import io.xpipe.app.issue.TrackEvent; import io.xpipe.app.issue.TrackEvent;
import io.xpipe.app.update.UpdateChangelogAlert; import io.xpipe.app.update.UpdateChangelogAlert;
import io.xpipe.app.util.NativeBridge;
import io.xpipe.app.util.ThreadHelper; import io.xpipe.app.util.ThreadHelper;
import javafx.stage.Stage; import javafx.stage.Stage;
@ -37,6 +38,7 @@ public class GuiMode extends PlatformMode {
AppGreetings.showIfNeeded(); AppGreetings.showIfNeeded();
AppPtbCheck.check(); AppPtbCheck.check();
NativeBridge.init();
TrackEvent.info("Waiting for window setup completion ..."); TrackEvent.info("Waiting for window setup completion ...");
PlatformThread.runLaterIfNeededBlocking(() -> { PlatformThread.runLaterIfNeededBlocking(() -> {

View file

@ -46,7 +46,7 @@ public class NativeMacOsWindowControl {
try { try {
lib.get().setAppearance(new NativeLong(nsWindow), seamlessFrame, darkMode); lib.get().setAppearance(new NativeLong(nsWindow), seamlessFrame, darkMode);
if (seamlessFrame) { if (seamlessFrame) {
ThreadHelper.sleep(250); ThreadHelper.sleep(150);
} }
} catch (Throwable e) { } catch (Throwable e) {
ErrorEvent.fromThrowable(e).handle(); ErrorEvent.fromThrowable(e).handle();

View file

@ -1,5 +1,6 @@
package io.xpipe.app.terminal; package io.xpipe.app.terminal;
import io.xpipe.app.beacon.AppBeaconServer;
import io.xpipe.app.comp.base.MarkdownComp; import io.xpipe.app.comp.base.MarkdownComp;
import io.xpipe.app.core.AppCache; import io.xpipe.app.core.AppCache;
import io.xpipe.app.core.AppI18n; import io.xpipe.app.core.AppI18n;
@ -13,6 +14,7 @@ import io.xpipe.core.process.*;
import io.xpipe.core.store.FilePath; import io.xpipe.core.store.FilePath;
import io.xpipe.core.util.FailableFunction; import io.xpipe.core.util.FailableFunction;
import io.xpipe.core.util.XPipeInstallation;
import javafx.scene.control.Alert; import javafx.scene.control.Alert;
import javafx.scene.control.ButtonBar; import javafx.scene.control.ButtonBar;
import javafx.scene.control.ButtonType; import javafx.scene.control.ButtonType;
@ -238,6 +240,14 @@ public interface ExternalTerminalType extends PrefsChoiceValue {
@Override @Override
protected void execute(Path file, LaunchConfiguration configuration) throws Exception { protected void execute(Path file, LaunchConfiguration configuration) throws Exception {
try (var sc = LocalShell.getShell()) { try (var sc = LocalShell.getShell()) {
// Since mobaxterm uses its own cygwin environment, we have to provide the beacon auth secret to the tmp there as well
// Otherwise it can't connect
var slashTemp = Path.of(System.getenv("APPDATA"), "MobaXterm", "slash", "tmp");
if (Files.exists(slashTemp)) {
var authFileName = XPipeInstallation.getLocalBeaconAuthFile().getFileName().toString();
Files.writeString(Path.of(slashTemp.toString(), authFileName),AppBeaconServer.get().getLocalAuthSecret());
}
var fixedFile = configuration var fixedFile = configuration
.getScriptFile() .getScriptFile()
.toString() .toString()

View file

@ -23,7 +23,7 @@ public class DesktopShortcuts {
$S.Arguments = '%s' $S.Arguments = '%s'
$S.Save() $S.Save()
""", """,
executable, shortcutPath, icon, args); executable, shortcutPath, icon, args).replaceAll("\n", ";");
LocalShell.getLocalPowershell().executeSimpleCommand(content); LocalShell.getLocalPowershell().executeSimpleCommand(content);
return shortcutPath; return shortcutPath;
} }

View file

@ -1,6 +1,7 @@
package io.xpipe.app.util; package io.xpipe.app.util;
import io.xpipe.app.issue.ErrorEvent; import io.xpipe.app.issue.ErrorEvent;
import io.xpipe.core.process.OsType;
import io.xpipe.core.util.XPipeInstallation; import io.xpipe.core.util.XPipeInstallation;
import com.sun.jna.Library; import com.sun.jna.Library;
@ -15,6 +16,13 @@ public class NativeBridge {
private static MacOsLibrary macOsLibrary; private static MacOsLibrary macOsLibrary;
private static boolean loadingFailed; private static boolean loadingFailed;
public static void init() {
// Preload
if (OsType.getLocal() == OsType.MACOS) {
getMacOsLibrary();
}
}
public static Optional<MacOsLibrary> getMacOsLibrary() { public static Optional<MacOsLibrary> getMacOsLibrary() {
if (macOsLibrary == null && !loadingFailed) { if (macOsLibrary == null && !loadingFailed) {
try { try {

View file

@ -28,7 +28,7 @@ public interface OsType {
List<String> determineInterestingPaths(ShellControl pc) throws Exception; List<String> determineInterestingPaths(ShellControl pc) throws Exception;
String getHomeDirectory(ShellControl pc) throws Exception; String getUserHomeDirectory(ShellControl pc) throws Exception;
String getFileSystemSeparator(); String getFileSystemSeparator();
@ -55,7 +55,7 @@ public interface OsType {
@Override @Override
public List<String> determineInterestingPaths(ShellControl pc) throws Exception { public List<String> determineInterestingPaths(ShellControl pc) throws Exception {
var home = getHomeDirectory(pc); var home = getUserHomeDirectory(pc);
return List.of( return List.of(
home, home,
FileNames.join(home, "Documents"), FileNames.join(home, "Documents"),
@ -64,7 +64,7 @@ public interface OsType {
} }
@Override @Override
public String getHomeDirectory(ShellControl pc) throws Exception { public String getUserHomeDirectory(ShellControl pc) throws Exception {
return pc.executeSimpleStringCommand( return pc.executeSimpleStringCommand(
pc.getShellDialect().getPrintEnvironmentVariableCommand("USERPROFILE")); pc.getShellDialect().getPrintEnvironmentVariableCommand("USERPROFILE"));
} }
@ -95,10 +95,10 @@ public interface OsType {
@Override @Override
public List<String> determineInterestingPaths(ShellControl pc) throws Exception { public List<String> determineInterestingPaths(ShellControl pc) throws Exception {
var home = getHomeDirectory(pc); var home = getUserHomeDirectory(pc);
return List.of( return List.of(
home, home,
"/home", FileNames.getParent(home),
FileNames.join(home, "Downloads"), FileNames.join(home, "Downloads"),
FileNames.join(home, "Documents"), FileNames.join(home, "Documents"),
"/etc", "/etc",
@ -107,7 +107,7 @@ public interface OsType {
} }
@Override @Override
public String getHomeDirectory(ShellControl pc) throws Exception { public String getUserHomeDirectory(ShellControl pc) throws Exception {
return pc.executeSimpleStringCommand(pc.getShellDialect().getPrintEnvironmentVariableCommand("HOME")); return pc.executeSimpleStringCommand(pc.getShellDialect().getPrintEnvironmentVariableCommand("HOME"));
} }
@ -149,7 +149,7 @@ public interface OsType {
@Override @Override
public List<String> determineInterestingPaths(ShellControl pc) throws Exception { public List<String> determineInterestingPaths(ShellControl pc) throws Exception {
var home = getHomeDirectory(pc); var home = getUserHomeDirectory(pc);
return List.of( return List.of(
home, home,
FileNames.join(home, "Downloads"), FileNames.join(home, "Downloads"),
@ -162,7 +162,7 @@ public interface OsType {
} }
@Override @Override
public String getHomeDirectory(ShellControl pc) throws Exception { public String getUserHomeDirectory(ShellControl pc) throws Exception {
return pc.executeSimpleStringCommand(pc.getShellDialect().getPrintEnvironmentVariableCommand("HOME")); return pc.executeSimpleStringCommand(pc.getShellDialect().getPrintEnvironmentVariableCommand("HOME"));
} }

View file

@ -17,7 +17,6 @@ open module io.xpipe.core {
requires com.fasterxml.jackson.databind; requires com.fasterxml.jackson.databind;
requires java.net.http; requires java.net.http;
requires static lombok; requires static lombok;
requires java.sql;
uses com.fasterxml.jackson.databind.Module; uses com.fasterxml.jackson.databind.Module;
uses ProcessControlProvider; uses ProcessControlProvider;

View file

@ -18,7 +18,7 @@ These work via a local SSH bridge that is managed by XPipe.
## Teleport support ## Teleport support
There is now support to add your teleport connections that are available via tsh. You can do that by searching for available connections on any system which has tsh installed. There is now support to add your teleport connections that are available via tsh. You can do that by searching for available connections on any system which has tsh installed. This is a separate integration from SSH, SSH config entries for teleport proxies do not work and are automatically filtered out. It solely works through the tsh tool.
This feature is available in the Professional edition and is freely available to anyone for two weeks after this release using the Pro Preview. This feature is available in the Professional edition and is freely available to anyone for two weeks after this release using the Pro Preview.
@ -53,9 +53,12 @@ I received plenty of user feedback and had time to observe the inner workings of
- Fix download move operation failing when moving a directory that already existed in the downloads folder - Fix download move operation failing when moving a directory that already existed in the downloads folder
- Fix some scrollbars unnecessarily showing - Fix some scrollbars unnecessarily showing
- Fix file browser list jumping around on first show - Fix file browser list jumping around on first show
- Fix missing libxtst6 dependency on some debian-based systems
- Fix file browser root session not applying same color of original connection
## Other ## Other
- Categories can now be assigned colors
- There is now support to view and change users/groups in the file browser - There is now support to view and change users/groups in the file browser
- External git vault data files are now also encrypted by default - External git vault data files are now also encrypted by default
- Rework state information display for proxmox VMs - Rework state information display for proxmox VMs

View file

@ -5,14 +5,17 @@ import io.xpipe.app.browser.action.LeafAction;
import io.xpipe.app.browser.file.BrowserEntry; import io.xpipe.app.browser.file.BrowserEntry;
import io.xpipe.app.browser.fs.OpenFileSystemModel; import io.xpipe.app.browser.fs.OpenFileSystemModel;
import io.xpipe.app.core.AppI18n; import io.xpipe.app.core.AppI18n;
import io.xpipe.app.issue.ErrorEvent;
import io.xpipe.app.prefs.AppPrefs; import io.xpipe.app.prefs.AppPrefs;
import io.xpipe.app.util.TerminalLauncher; import io.xpipe.app.util.TerminalLauncher;
import io.xpipe.core.process.CommandBuilder; import io.xpipe.core.process.CommandBuilder;
import io.xpipe.core.process.ProcessOutputException;
import io.xpipe.core.process.ShellControl; import io.xpipe.core.process.ShellControl;
import javafx.beans.value.ObservableValue; import javafx.beans.value.ObservableValue;
import java.util.List; import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
public abstract class MultiExecuteSelectionAction implements BranchAction { public abstract class MultiExecuteSelectionAction implements BranchAction {
@ -63,10 +66,21 @@ public abstract class MultiExecuteSelectionAction implements BranchAction {
model.withShell( model.withShell(
pc -> { pc -> {
var cmd = createCommand(pc, model, entries); var cmd = createCommand(pc, model, entries);
pc.command(cmd) AtomicReference<String> out = new AtomicReference<>();
AtomicReference<String> err = new AtomicReference<>();
long exitCode;
try (var command = pc.command(cmd)
.withWorkingDirectory( .withWorkingDirectory(
model.getCurrentDirectory().getPath()) model.getCurrentDirectory().getPath()).start()) {
.execute(); var r = command.readStdoutAndStderr();
out.set(r[0]);
err.set(r[1]);
exitCode = command.getExitCode();
}
// Only throw actual error output
if (exitCode != 0) {
throw ErrorEvent.expected(ProcessOutputException.of(exitCode, out.get(), err.get()));
}
}, },
false); false);
} }

View file

@ -1 +1 @@
diff "$1" "$2" diff "$1" "$2" && echo "File contents are identical"

View file

@ -488,7 +488,7 @@ closeOtherTabs=Close other tabs
closeAllTabs=Close all tabs closeAllTabs=Close all tabs
closeLeftTabs=Close tabs to the left closeLeftTabs=Close tabs to the left
closeRightTabs=Close tabs to the right closeRightTabs=Close tabs to the right
addSerial=Serial ... addSerial=Serial (Experimental) ...
connect=Connect connect=Connect
workspaces=Workspaces workspaces=Workspaces
manageWorkspaces=Manage workspaces manageWorkspaces=Manage workspaces