This commit is contained in:
crschnick 2024-06-02 08:38:15 +00:00
parent 3dea8ba8ee
commit 435c157eb9
11 changed files with 126 additions and 74 deletions

View file

@ -286,6 +286,10 @@ public class StoreCreationComp extends DialogComp {
if (ex instanceof ValidationException) {
ErrorEvent.expected(ex);
skippable.set(false);
} else if (ex instanceof StackOverflowError) {
// Cycles in connection graphs can fail hard but are expected
ErrorEvent.expected(ex);
skippable.set(false);
} else {
skippable.set(true);
}

View file

@ -390,7 +390,7 @@ public abstract class StoreEntryComp extends SimpleComp {
wrapper.moveTo(storeCategoryWrapper.getCategory());
event.consume();
});
if (storeCategoryWrapper.getParent() == null) {
if (storeCategoryWrapper.getParent() == null || storeCategoryWrapper.equals(wrapper.getCategory().getValue())) {
m.setDisable(true);
}

View file

@ -246,11 +246,9 @@ public class StoreViewState {
public int compare(StoreCategoryWrapper o1, StoreCategoryWrapper o2) {
var o1Root = o1.getRoot();
var o2Root = o2.getRoot();
if (o1Root.equals(getAllConnectionsCategory()) && !o1Root.equals(o2Root)) {
return -1;
}
if (o2Root.equals(getAllConnectionsCategory()) && !o1Root.equals(o2Root)) {
return 1;
}
@ -267,6 +265,22 @@ public class StoreViewState {
return 1;
}
if (o1.getDepth() > o2.getDepth()) {
if (o1.getParent() == o2) {
return 1;
}
return compare(o1.getParent(), o2);
}
if (o1.getDepth() < o2.getDepth()) {
if (o2.getParent() == o1) {
return -1;
}
return compare(o1, o2.getParent());
}
var parent = compare(o1.getParent(), o2.getParent());
if (parent != 0) {
return parent;

View file

@ -194,10 +194,10 @@ public interface ExternalEditorType extends PrefsChoiceValue {
@Override
public void launch(Path file) throws Exception {
ExternalApplicationHelper.startAsync(CommandBuilder.of()
.add("open", "-a")
.addQuoted(applicationName)
.addFile(file.toString()));
try (var sc = LocalShell.getShell().start()) {
sc.executeSimpleCommand(CommandBuilder.of()
.add("open", "-a").addQuoted(applicationName).addFile(file.toString()));
}
}
}

View file

@ -514,17 +514,11 @@ public interface ExternalTerminalType extends PrefsChoiceValue {
@Override
public void launch(LaunchConfiguration configuration) throws Exception {
try (ShellControl pc = LocalShell.getShell()) {
var suffix = "\"" + configuration.getScriptFile().toString().replaceAll("\"", "\\\\\"") + "\"";
pc.osascriptCommand(String.format(
"""
activate application "Terminal"
delay 1
tell app "Terminal" to do script %s
""",
suffix))
.execute();
}
LocalShell.getShell()
.executeSimpleCommand(CommandBuilder.of()
.add("open", "-a")
.addQuoted("Terminal.app")
.addFile(configuration.getScriptFile()));
}
};
ExternalTerminalType ITERM2 = new MacOsType("app.iterm2", "iTerm") {
@ -550,26 +544,11 @@ public interface ExternalTerminalType extends PrefsChoiceValue {
@Override
public void launch(LaunchConfiguration configuration) throws Exception {
try (ShellControl pc = LocalShell.getShell()) {
pc.osascriptCommand(String.format(
"""
if application "iTerm" is not running then
launch application "iTerm"
delay 1
tell application "iTerm"
tell current tab of current window
close
end tell
end tell
end if
tell application "iTerm"
activate
create window with default profile command "%s"
end tell
""",
configuration.getScriptFile().toString().replaceAll("\"", "\\\\\"")))
.execute();
}
LocalShell.getShell()
.executeSimpleCommand(CommandBuilder.of()
.add("open", "-a")
.addQuoted("iTerm.app")
.addFile(configuration.getScriptFile()));
}
};
ExternalTerminalType WARP = new MacOsType("app.warp", "Warp") {

View file

@ -1,9 +1,14 @@
package io.xpipe.app.terminal;
import io.xpipe.app.issue.ErrorEvent;
import io.xpipe.app.prefs.ExternalApplicationHelper;
import io.xpipe.app.prefs.ExternalApplicationType;
import io.xpipe.app.util.LocalShell;
import io.xpipe.app.util.ThreadHelper;
import io.xpipe.app.util.WindowsRegistry;
import io.xpipe.core.process.CommandBuilder;
import io.xpipe.core.process.OsType;
import io.xpipe.core.process.ShellControl;
import java.nio.file.Path;
import java.util.Optional;
@ -26,7 +31,7 @@ public interface WezTerminalType extends ExternalTerminalType {
@Override
default boolean isRecommended() {
return false;
return OsType.getLocal() != OsType.WINDOWS;
}
@Override
@ -51,25 +56,62 @@ public interface WezTerminalType extends ExternalTerminalType {
@Override
protected Optional<Path> determineInstallation() {
Optional<String> launcherDir;
launcherDir = WindowsRegistry.local().readValue(
WindowsRegistry.HKEY_LOCAL_MACHINE,
"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{BCF6F0DA-5B9A-408D-8562-F680AE6E1EAF}_is1",
"InstallLocation")
.map(p -> p + "\\wezterm-gui.exe");
return launcherDir.map(Path::of);
try {
var foundKey = WindowsRegistry.local().findKeyForEqualValueMatchRecursive(WindowsRegistry.HKEY_LOCAL_MACHINE,
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall", "http://wezfurlong.org/wezterm");
if (foundKey.isPresent()) {
var installKey = WindowsRegistry.local().readValue(
foundKey.get().getHkey(),
foundKey.get().getKey(),
"InstallLocation");
if (installKey.isPresent()) {
return installKey.map(p -> p + "\\wezterm-gui.exe").map(Path::of);
}
}
} catch (Exception ex) {
ErrorEvent.fromThrowable(ex).omit().handle();
}
try (ShellControl pc = LocalShell.getShell()) {
if (pc.executeSimpleBooleanCommand(pc.getShellDialect().getWhichCommand("wezterm-gui"))) {
return Optional.of(Path.of("wezterm-gui"));
}
} catch (Exception e) {
ErrorEvent.fromThrowable(e).omit().handle();
}
return Optional.empty();
}
}
class Linux extends SimplePathType implements WezTerminalType {
class Linux extends ExternalApplicationType implements WezTerminalType {
public Linux() {
super("app.wezterm", "wezterm-gui", true);
super("app.wezterm");
}
public boolean isAvailable() {
try (ShellControl pc = LocalShell.getShell()) {
return pc.executeSimpleBooleanCommand(pc.getShellDialect().getWhichCommand("wezterm")) &&
pc.executeSimpleBooleanCommand(pc.getShellDialect().getWhichCommand("wezterm-gui"));
} catch (Exception e) {
ErrorEvent.fromThrowable(e).omit().handle();
return false;
}
}
@Override
protected CommandBuilder toCommand(LaunchConfiguration configuration) {
return CommandBuilder.of().add("start").addFile(configuration.getScriptFile());
public void launch(LaunchConfiguration configuration) throws Exception {
var spawn = LocalShell.getShell().command(CommandBuilder.of().addFile("wezterm")
.add("cli", "spawn")
.addFile(configuration.getScriptFile()))
.executeAndCheck();
if (!spawn) {
ExternalApplicationHelper.startAsync(CommandBuilder.of()
.addFile("wezterm-gui")
.add("start")
.addFile(configuration.getScriptFile()));
}
}
}
@ -81,20 +123,27 @@ public interface WezTerminalType extends ExternalTerminalType {
@Override
public void launch(LaunchConfiguration configuration) throws Exception {
var path = LocalShell.getShell()
.command(String.format(
"mdfind -name '%s' -onlyin /Applications -onlyin ~/Applications -onlyin /System/Applications 2>/dev/null",
applicationName))
.readStdoutOrThrow();
var c = CommandBuilder.of()
.addFile(Path.of(path)
.resolve("Contents")
.resolve("MacOS")
.resolve("wezterm-gui")
.toString())
.add("start")
.add(configuration.getDialectLaunchCommand());
ExternalApplicationHelper.startAsync(c);
try (var sc = LocalShell.getShell()) {
var path = sc.command(
String.format("mdfind -name '%s' -onlyin /Applications -onlyin ~/Applications -onlyin /System/Applications 2>/dev/null",
applicationName)).readStdoutOrThrow();
var spawn = sc.command(CommandBuilder.of().addFile(Path.of(path)
.resolve("Contents")
.resolve("MacOS")
.resolve("wezterm").toString())
.add("cli", "spawn", "--pane-id", "0")
.addFile(configuration.getScriptFile()))
.executeAndCheck();
if (!spawn) {
ExternalApplicationHelper.startAsync(CommandBuilder.of()
.addFile(Path.of(path)
.resolve("Contents")
.resolve("MacOS")
.resolve("wezterm-gui").toString())
.add("start")
.addFile(configuration.getScriptFile()));
}
}
}
}
}

View file

@ -28,10 +28,9 @@ public class FileOpener {
try {
editor.launch(Path.of(localFile).toRealPath());
} catch (Exception e) {
ErrorEvent.fromThrowable(e)
.description("Unable to launch editor "
ErrorEvent.fromThrowable("Unable to launch editor "
+ editor.toTranslatedString().getValue()
+ ".\nMaybe try to use a different editor in the settings.")
+ ".\nMaybe try to use a different editor in the settings.", e)
.expected()
.handle();
}
@ -52,8 +51,7 @@ public class FileOpener {
}
}
} catch (Exception e) {
ErrorEvent.fromThrowable(e)
.description("Unable to open file " + localFile)
ErrorEvent.fromThrowable("Unable to open file " + localFile, e)
.handle();
}
}
@ -68,8 +66,7 @@ public class FileOpener {
pc.executeSimpleCommand("open \"" + localFile + "\"");
}
} catch (Exception e) {
ErrorEvent.fromThrowable(e)
.description("Unable to open file " + localFile)
ErrorEvent.fromThrowable("Unable to open file " + localFile, e)
.handle();
}
}

View file

@ -8,7 +8,7 @@ The file transfer mechanism when editing files had some flaws, which under rare
The entire transfer implementation has been rewritten to iron out these issues and increase reliability. Other file browser actions have also been made more reliable.
There seems to be another separate issue with a PowerShell bug when connecting to a Windows system, causing file uploads of more than around 1MB to stall. For now, xpipe can fall back to pwsh if it is installed to work around this issue.
There seems to be another separate issue with a PowerShell bug when connecting to a Windows system, causing file uploads to be slow. For now, xpipe can fall back to pwsh if it is installed to work around this issue.
## Git vault improvements
@ -17,6 +17,13 @@ The conflict resolution has been improved
- In case of a merge conflict, overwriting local changes will now preserve all connections that are not added to the git vault, including local connections
- You now have the option to force push changes when a conflict occurs while XPipe is saving while running, not requiring a restart anymore
## Terminal improvements
The terminal integration got reworked for some terminals:
- iTerm can now launch tabs instead of individual windows. There were also a few issues fixed that prevented it from launching sometimes
- WezTerm now supports tabs on Linux and macOS. The Windows installation detection has been improved to detect all installed versions
- Terminal.app will now launch faster
## Other
- You can now add simple RDP connections without a file
@ -29,6 +36,8 @@ The conflict resolution has been improved
- Fix possibility of selecting own children connections as hosts, causing a stack overflow. Please don't try to create cycles in your connection graphs
- Fix vault secrets not correctly updating unless restarted when changing vault passphrase
- Fix connection launcher desktop shortcuts and URLs not properly executing if xpipe is not running
- Fix move to ... menu sometimes not ordering categories correctly
- Fix SSH command failing on macOS with homebrew openssh package installed
- Fix SSH connections not opening the correct shell environment on Windows systems when username contained spaces due to an OpenSSH bug
- Fix newly added connections not having the correct order
- Fix error messages of external editor programs not being shown when they failed to start

View file

@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-rc-1-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-all.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME

View file

@ -1 +1 @@
9.4-4
9.4