mirror of
https://github.com/xpipe-io/xpipe.git
synced 2024-11-21 23:20:23 +00:00
Fixes
This commit is contained in:
parent
3dea8ba8ee
commit
435c157eb9
11 changed files with 126 additions and 74 deletions
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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") {
|
||||
|
|
|
@ -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()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
11
dist/changelogs/9.4_incremental.md
vendored
11
dist/changelogs/9.4_incremental.md
vendored
|
@ -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
|
||||
|
|
Binary file not shown.
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
|
@ -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
|
||||
|
|
2
version
2
version
|
@ -1 +1 @@
|
|||
9.4-4
|
||||
9.4
|
||||
|
|
Loading…
Reference in a new issue