mirror of
https://github.com/xpipe-io/xpipe.git
synced 2024-11-22 07:30:24 +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) {
|
if (ex instanceof ValidationException) {
|
||||||
ErrorEvent.expected(ex);
|
ErrorEvent.expected(ex);
|
||||||
skippable.set(false);
|
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 {
|
} else {
|
||||||
skippable.set(true);
|
skippable.set(true);
|
||||||
}
|
}
|
||||||
|
|
|
@ -390,7 +390,7 @@ public abstract class StoreEntryComp extends SimpleComp {
|
||||||
wrapper.moveTo(storeCategoryWrapper.getCategory());
|
wrapper.moveTo(storeCategoryWrapper.getCategory());
|
||||||
event.consume();
|
event.consume();
|
||||||
});
|
});
|
||||||
if (storeCategoryWrapper.getParent() == null) {
|
if (storeCategoryWrapper.getParent() == null || storeCategoryWrapper.equals(wrapper.getCategory().getValue())) {
|
||||||
m.setDisable(true);
|
m.setDisable(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -246,11 +246,9 @@ public class StoreViewState {
|
||||||
public int compare(StoreCategoryWrapper o1, StoreCategoryWrapper o2) {
|
public int compare(StoreCategoryWrapper o1, StoreCategoryWrapper o2) {
|
||||||
var o1Root = o1.getRoot();
|
var o1Root = o1.getRoot();
|
||||||
var o2Root = o2.getRoot();
|
var o2Root = o2.getRoot();
|
||||||
|
|
||||||
if (o1Root.equals(getAllConnectionsCategory()) && !o1Root.equals(o2Root)) {
|
if (o1Root.equals(getAllConnectionsCategory()) && !o1Root.equals(o2Root)) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (o2Root.equals(getAllConnectionsCategory()) && !o1Root.equals(o2Root)) {
|
if (o2Root.equals(getAllConnectionsCategory()) && !o1Root.equals(o2Root)) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -267,6 +265,22 @@ public class StoreViewState {
|
||||||
return 1;
|
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());
|
var parent = compare(o1.getParent(), o2.getParent());
|
||||||
if (parent != 0) {
|
if (parent != 0) {
|
||||||
return parent;
|
return parent;
|
||||||
|
|
|
@ -194,10 +194,10 @@ public interface ExternalEditorType extends PrefsChoiceValue {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void launch(Path file) throws Exception {
|
public void launch(Path file) throws Exception {
|
||||||
ExternalApplicationHelper.startAsync(CommandBuilder.of()
|
try (var sc = LocalShell.getShell().start()) {
|
||||||
.add("open", "-a")
|
sc.executeSimpleCommand(CommandBuilder.of()
|
||||||
.addQuoted(applicationName)
|
.add("open", "-a").addQuoted(applicationName).addFile(file.toString()));
|
||||||
.addFile(file.toString()));
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -514,17 +514,11 @@ public interface ExternalTerminalType extends PrefsChoiceValue {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void launch(LaunchConfiguration configuration) throws Exception {
|
public void launch(LaunchConfiguration configuration) throws Exception {
|
||||||
try (ShellControl pc = LocalShell.getShell()) {
|
LocalShell.getShell()
|
||||||
var suffix = "\"" + configuration.getScriptFile().toString().replaceAll("\"", "\\\\\"") + "\"";
|
.executeSimpleCommand(CommandBuilder.of()
|
||||||
pc.osascriptCommand(String.format(
|
.add("open", "-a")
|
||||||
"""
|
.addQuoted("Terminal.app")
|
||||||
activate application "Terminal"
|
.addFile(configuration.getScriptFile()));
|
||||||
delay 1
|
|
||||||
tell app "Terminal" to do script %s
|
|
||||||
""",
|
|
||||||
suffix))
|
|
||||||
.execute();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
ExternalTerminalType ITERM2 = new MacOsType("app.iterm2", "iTerm") {
|
ExternalTerminalType ITERM2 = new MacOsType("app.iterm2", "iTerm") {
|
||||||
|
@ -550,26 +544,11 @@ public interface ExternalTerminalType extends PrefsChoiceValue {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void launch(LaunchConfiguration configuration) throws Exception {
|
public void launch(LaunchConfiguration configuration) throws Exception {
|
||||||
try (ShellControl pc = LocalShell.getShell()) {
|
LocalShell.getShell()
|
||||||
pc.osascriptCommand(String.format(
|
.executeSimpleCommand(CommandBuilder.of()
|
||||||
"""
|
.add("open", "-a")
|
||||||
if application "iTerm" is not running then
|
.addQuoted("iTerm.app")
|
||||||
launch application "iTerm"
|
.addFile(configuration.getScriptFile()));
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
ExternalTerminalType WARP = new MacOsType("app.warp", "Warp") {
|
ExternalTerminalType WARP = new MacOsType("app.warp", "Warp") {
|
||||||
|
|
|
@ -1,9 +1,14 @@
|
||||||
package io.xpipe.app.terminal;
|
package io.xpipe.app.terminal;
|
||||||
|
|
||||||
|
import io.xpipe.app.issue.ErrorEvent;
|
||||||
import io.xpipe.app.prefs.ExternalApplicationHelper;
|
import io.xpipe.app.prefs.ExternalApplicationHelper;
|
||||||
|
import io.xpipe.app.prefs.ExternalApplicationType;
|
||||||
import io.xpipe.app.util.LocalShell;
|
import io.xpipe.app.util.LocalShell;
|
||||||
|
import io.xpipe.app.util.ThreadHelper;
|
||||||
import io.xpipe.app.util.WindowsRegistry;
|
import io.xpipe.app.util.WindowsRegistry;
|
||||||
import io.xpipe.core.process.CommandBuilder;
|
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.nio.file.Path;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
@ -26,7 +31,7 @@ public interface WezTerminalType extends ExternalTerminalType {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
default boolean isRecommended() {
|
default boolean isRecommended() {
|
||||||
return false;
|
return OsType.getLocal() != OsType.WINDOWS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -51,25 +56,62 @@ public interface WezTerminalType extends ExternalTerminalType {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Optional<Path> determineInstallation() {
|
protected Optional<Path> determineInstallation() {
|
||||||
Optional<String> launcherDir;
|
try {
|
||||||
launcherDir = WindowsRegistry.local().readValue(
|
var foundKey = WindowsRegistry.local().findKeyForEqualValueMatchRecursive(WindowsRegistry.HKEY_LOCAL_MACHINE,
|
||||||
WindowsRegistry.HKEY_LOCAL_MACHINE,
|
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall", "http://wezfurlong.org/wezterm");
|
||||||
"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{BCF6F0DA-5B9A-408D-8562-F680AE6E1EAF}_is1",
|
if (foundKey.isPresent()) {
|
||||||
"InstallLocation")
|
var installKey = WindowsRegistry.local().readValue(
|
||||||
.map(p -> p + "\\wezterm-gui.exe");
|
foundKey.get().getHkey(),
|
||||||
return launcherDir.map(Path::of);
|
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() {
|
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
|
@Override
|
||||||
protected CommandBuilder toCommand(LaunchConfiguration configuration) {
|
public void launch(LaunchConfiguration configuration) throws Exception {
|
||||||
return CommandBuilder.of().add("start").addFile(configuration.getScriptFile());
|
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
|
@Override
|
||||||
public void launch(LaunchConfiguration configuration) throws Exception {
|
public void launch(LaunchConfiguration configuration) throws Exception {
|
||||||
var path = LocalShell.getShell()
|
try (var sc = LocalShell.getShell()) {
|
||||||
.command(String.format(
|
var path = sc.command(
|
||||||
"mdfind -name '%s' -onlyin /Applications -onlyin ~/Applications -onlyin /System/Applications 2>/dev/null",
|
String.format("mdfind -name '%s' -onlyin /Applications -onlyin ~/Applications -onlyin /System/Applications 2>/dev/null",
|
||||||
applicationName))
|
applicationName)).readStdoutOrThrow();
|
||||||
.readStdoutOrThrow();
|
var spawn = sc.command(CommandBuilder.of().addFile(Path.of(path)
|
||||||
var c = CommandBuilder.of()
|
.resolve("Contents")
|
||||||
.addFile(Path.of(path)
|
.resolve("MacOS")
|
||||||
.resolve("Contents")
|
.resolve("wezterm").toString())
|
||||||
.resolve("MacOS")
|
.add("cli", "spawn", "--pane-id", "0")
|
||||||
.resolve("wezterm-gui")
|
.addFile(configuration.getScriptFile()))
|
||||||
.toString())
|
.executeAndCheck();
|
||||||
.add("start")
|
if (!spawn) {
|
||||||
.add(configuration.getDialectLaunchCommand());
|
ExternalApplicationHelper.startAsync(CommandBuilder.of()
|
||||||
ExternalApplicationHelper.startAsync(c);
|
.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 {
|
try {
|
||||||
editor.launch(Path.of(localFile).toRealPath());
|
editor.launch(Path.of(localFile).toRealPath());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
ErrorEvent.fromThrowable(e)
|
ErrorEvent.fromThrowable("Unable to launch editor "
|
||||||
.description("Unable to launch editor "
|
|
||||||
+ editor.toTranslatedString().getValue()
|
+ 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()
|
.expected()
|
||||||
.handle();
|
.handle();
|
||||||
}
|
}
|
||||||
|
@ -52,8 +51,7 @@ public class FileOpener {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
ErrorEvent.fromThrowable(e)
|
ErrorEvent.fromThrowable("Unable to open file " + localFile, e)
|
||||||
.description("Unable to open file " + localFile)
|
|
||||||
.handle();
|
.handle();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -68,8 +66,7 @@ public class FileOpener {
|
||||||
pc.executeSimpleCommand("open \"" + localFile + "\"");
|
pc.executeSimpleCommand("open \"" + localFile + "\"");
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
ErrorEvent.fromThrowable(e)
|
ErrorEvent.fromThrowable("Unable to open file " + localFile, e)
|
||||||
.description("Unable to open file " + localFile)
|
|
||||||
.handle();
|
.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.
|
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
|
## 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
|
- 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
|
- 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
|
## Other
|
||||||
|
|
||||||
- You can now add simple RDP connections without a file
|
- 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 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 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 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 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 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 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
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
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
|
networkTimeout=10000
|
||||||
validateDistributionUrl=true
|
validateDistributionUrl=true
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
|
|
2
version
2
version
|
@ -1 +1 @@
|
||||||
9.4-4
|
9.4
|
||||||
|
|
Loading…
Reference in a new issue