mirror of
https://github.com/xpipe-io/xpipe.git
synced 2024-09-19 13:51:23 +00:00
Various fixes
This commit is contained in:
parent
4adb18249b
commit
d6cb3bf2bd
|
@ -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()
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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());
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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());
|
||||||
|
|
|
@ -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(() -> {
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
5
dist/changelogs/11.0.md
vendored
5
dist/changelogs/11.0.md
vendored
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
diff "$1" "$2"
|
diff "$1" "$2" && echo "File contents are identical"
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue