mirror of
https://github.com/xpipe-io/xpipe.git
synced 2026-09-25 18:05:39 +00:00
Update PlatformThread.java
This commit is contained in:
+2
-2
@@ -20,8 +20,8 @@ If you are on Linux or macOS, you can easily accomplish that by using [SDKMAN](h
|
||||
```bash
|
||||
curl -s "https://get.sdkman.io" | bash
|
||||
. "$HOME/.sdkman/bin/sdkman-init.sh"
|
||||
sdk install java 25.0.1-graalce
|
||||
sdk default java 25.0.1-graalce
|
||||
sdk install java 25.0.2-graalce
|
||||
sdk default java 25.0.2-graalce
|
||||
```
|
||||
|
||||
On Windows, you have to manually install a JDK, e.g. from [Adoptium](https://adoptium.net/temurin/releases/?version=25).
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
package io.xpipe.app.browser.menu.impl;
|
||||
|
||||
import io.xpipe.app.browser.file.BrowserEntry;
|
||||
import io.xpipe.app.browser.file.BrowserFileSystemTabModel;
|
||||
import io.xpipe.app.browser.menu.BrowserMenuCategory;
|
||||
import io.xpipe.app.browser.menu.BrowserMenuLeafProvider;
|
||||
import io.xpipe.app.comp.RegionBuilder;
|
||||
import io.xpipe.app.comp.base.ModalOverlay;
|
||||
import io.xpipe.app.core.AppI18n;
|
||||
import io.xpipe.app.ext.FileKind;
|
||||
import io.xpipe.app.platform.LabelGraphic;
|
||||
import io.xpipe.app.process.CommandBuilder;
|
||||
import io.xpipe.core.OsType;
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.scene.control.TextField;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class GradleRunMenuProvider implements BrowserMenuLeafProvider {
|
||||
|
||||
@Override
|
||||
public boolean isApplicable(BrowserFileSystemTabModel model, List<BrowserEntry> entries) {
|
||||
if (model.getFileSystem().getShell().isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (entries.size() != 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (entries.getFirst().getRawFileEntry().getKind() != FileKind.FILE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
OsType.Any osType = model.getFileSystem().getShell().orElseThrow().getOsType();
|
||||
var ext = switch (osType) {
|
||||
case OsType.Windows ignored -> "gradlew.bat";
|
||||
default -> "gradlew";
|
||||
};
|
||||
|
||||
if (!entries.getFirst().getFileName().equalsIgnoreCase(ext)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ObservableValue<String> getName(BrowserFileSystemTabModel model, List<BrowserEntry> entries) {
|
||||
return AppI18n.observable("runTask");
|
||||
}
|
||||
|
||||
@Override
|
||||
public BrowserMenuCategory getCategory() {
|
||||
return BrowserMenuCategory.CUSTOM;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LabelGraphic getIcon() {
|
||||
return new LabelGraphic.IconGraphic("mdi2e-elephant");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(BrowserFileSystemTabModel model, List<BrowserEntry> entries) {
|
||||
var tasks = new SimpleStringProperty();
|
||||
var modal = ModalOverlay.of(
|
||||
"gradleTasks",
|
||||
RegionBuilder.of(() -> {
|
||||
var creationName = new TextField();
|
||||
creationName.textProperty().bindBidirectional(tasks);
|
||||
return creationName;
|
||||
})
|
||||
.prefWidth(350));
|
||||
modal.withDefaultButtons(() -> {
|
||||
var fixedTasks = tasks.getValue();
|
||||
if (fixedTasks == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
var parent = entries.getFirst().getRawFileEntry().getPath().getParent();
|
||||
var command = model.getFileSystem().getShell().orElseThrow().command(CommandBuilder.of()
|
||||
.add("sh")
|
||||
.addFile(entries.getFirst().getRawFileEntry().getPath())
|
||||
.add(fixedTasks)
|
||||
);
|
||||
|
||||
model.openTerminalAsync(fixedTasks, parent, command, true);
|
||||
});
|
||||
modal.show();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -193,6 +193,16 @@ public class AppMainWindow {
|
||||
shown = true;
|
||||
}
|
||||
|
||||
public void hide() {
|
||||
PlatformThread.runLaterIfNeeded(() -> {
|
||||
if (!stage.isShowing()) {
|
||||
return;
|
||||
}
|
||||
|
||||
stage.hide();
|
||||
});
|
||||
}
|
||||
|
||||
public void focus() {
|
||||
if (AppPrefs.get() != null
|
||||
&& !AppPrefs.get().focusWindowOnNotifications().get()) {
|
||||
|
||||
@@ -113,12 +113,13 @@ public enum PlatformState {
|
||||
}
|
||||
}
|
||||
|
||||
if (SystemUtils.IS_OS_WINDOWS) {
|
||||
// This is primarily intended to fix Windows unified stage transparency issues
|
||||
// (https://bugs.openjdk.org/browse/JDK-8329382)
|
||||
// But apparently it can also occur without a custom stage on Windows
|
||||
System.setProperty("prism.forceUploadingPainter", "true");
|
||||
}
|
||||
// This issue is now fixed in 27-ea+4
|
||||
// if (SystemUtils.IS_OS_WINDOWS) {
|
||||
// This is primarily intended to fix Windows unified stage transparency issues
|
||||
// (https://bugs.openjdk.org/browse/JDK-8329382)
|
||||
// But apparently it can also occur without a custom stage on Windows
|
||||
// System.setProperty("prism.forceUploadingPainter", "true");
|
||||
// }
|
||||
|
||||
if (AppPrefs.get() != null
|
||||
&& AppPrefs.get().disableHardwareAcceleration().get()) {
|
||||
|
||||
@@ -266,7 +266,8 @@ public class PlatformThread {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (AppOperationMode.isInShutdown()) {
|
||||
// Some other components might already be disposed
|
||||
if (AppOperationMode.isInShutdownHook()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -23,7 +23,6 @@ import java.util.Optional;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public interface ExternalEditorType extends PrefsChoiceValue {
|
||||
|
||||
ExternalEditorType NOTEPAD = new WindowsType() {
|
||||
|
||||
@Override
|
||||
@@ -280,6 +279,70 @@ public interface ExternalEditorType extends PrefsChoiceValue {
|
||||
|
||||
LinuxPathType KIRO_LINUX = new LinuxPathType("app.kiro", "kiro", "https://kiro.dev/");
|
||||
|
||||
LinuxType NEOVIM_LINUX = new LinuxType("app.neovim", "nvim", "https://neovim.io/", null) {
|
||||
@Override
|
||||
public void launch(Path file) throws Exception {
|
||||
TerminalLaunch.builder()
|
||||
.title(file.toString())
|
||||
.localScript(sc -> new ShellScript(CommandBuilder.of()
|
||||
.addFile(getExecutable())
|
||||
.addFile(file.toString())
|
||||
.buildFull(sc)))
|
||||
.logIfEnabled(false)
|
||||
.preferTabs(false)
|
||||
.pauseOnExit(false)
|
||||
.launch();
|
||||
}
|
||||
};
|
||||
|
||||
WindowsType NEOVIM_WINDOWS = new WindowsType() {
|
||||
@Override
|
||||
public String getId() {
|
||||
return "app.neovim";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean detach() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getExecutable() {
|
||||
return "nvim";
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getWebsite() {
|
||||
return "https://neovim.io/";
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Optional<Path> determineInstallation() {
|
||||
var programFiles = AppSystemInfo.ofWindows().getProgramFiles().resolve("Neovim", "bin").resolve("nvim.exe");
|
||||
if (Files.exists(programFiles)) {
|
||||
return Optional.of(programFiles);
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void launch(Path file) throws Exception {
|
||||
TerminalLaunch.builder()
|
||||
.title(file.toString())
|
||||
.localScript(sc -> new ShellScript(CommandBuilder.of()
|
||||
.addFile(findExecutable().toString())
|
||||
.addFile(file)
|
||||
.buildFull(sc)))
|
||||
.logIfEnabled(false)
|
||||
.preferTabs(false)
|
||||
.pauseOnExit(false)
|
||||
.launch();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
WindowsType ZED_WINDOWS = new WindowsType() {
|
||||
|
||||
@Override
|
||||
@@ -356,6 +419,21 @@ public interface ExternalEditorType extends PrefsChoiceValue {
|
||||
ExternalEditorType WINDSURF_MACOS = new MacOsEditor("app.windsurf", "Windsurf", "https://windsurf.com/editor");
|
||||
ExternalEditorType KIRO_MACOS = new MacOsEditor("app.kiro", "Kiro", "https://kiro.dev/");
|
||||
ExternalEditorType TRAE_MACOS = new MacOsEditor("app.trae", "Trae", "https://www.trae.ai/");
|
||||
ExternalEditorType NEOVIM_MACOS = new MacOsEditor("app.neovim", "Neovim", "https://neovim.io/") {
|
||||
@Override
|
||||
public void launch(Path file) throws Exception {
|
||||
TerminalLaunch.builder()
|
||||
.title(file.toString())
|
||||
.localScript(sc -> new ShellScript(CommandBuilder.of()
|
||||
.addFile("nvim")
|
||||
.addFile(file.toString())
|
||||
.buildFull(sc)))
|
||||
.logIfEnabled(false)
|
||||
.preferTabs(false)
|
||||
.pauseOnExit(false)
|
||||
.launch();
|
||||
}
|
||||
};
|
||||
ExternalEditorType CUSTOM = new ExternalEditorType() {
|
||||
|
||||
@Override
|
||||
@@ -380,6 +458,7 @@ public interface ExternalEditorType extends PrefsChoiceValue {
|
||||
.localScript(sc -> new ShellScript(command.buildFull(sc)))
|
||||
.logIfEnabled(false)
|
||||
.preferTabs(false)
|
||||
.pauseOnExit(false)
|
||||
.launch();
|
||||
} else {
|
||||
ExternalApplicationHelper.startAsync(command);
|
||||
@@ -422,7 +501,8 @@ public interface ExternalEditorType extends PrefsChoiceValue {
|
||||
VSCODE_INSIDERS_WINDOWS,
|
||||
VSCODE_WINDOWS,
|
||||
NOTEPADPLUSPLUS,
|
||||
NOTEPAD);
|
||||
NOTEPAD,
|
||||
NEOVIM_WINDOWS);
|
||||
List<GenericPathType> LINUX_EDITORS = List.of(
|
||||
ExternalEditorType.WINDSURF_LINUX,
|
||||
ExternalEditorType.KIRO_LINUX,
|
||||
@@ -435,6 +515,7 @@ public interface ExternalEditorType extends PrefsChoiceValue {
|
||||
PLUMA,
|
||||
LEAFPAD,
|
||||
MOUSEPAD,
|
||||
NEOVIM_LINUX,
|
||||
GNOME,
|
||||
ExternalEditorType.COSMIC_EDIT,
|
||||
ExternalEditorType.WESTON_EDITOR,
|
||||
@@ -451,6 +532,7 @@ public interface ExternalEditorType extends PrefsChoiceValue {
|
||||
VSCODE_MACOS,
|
||||
SUBLIME_MACOS,
|
||||
ZED_MACOS,
|
||||
NEOVIM_MACOS,
|
||||
TEXT_EDIT);
|
||||
List<ExternalEditorType> CROSS_PLATFORM_EDITORS = List.of(FLEET, INTELLIJ, PYCHARM, WEBSTORM, CLION);
|
||||
|
||||
|
||||
@@ -117,7 +117,7 @@ public class TerminalCategory extends AppPrefsCategory {
|
||||
"If you can read this, the terminal integration works", false)))
|
||||
.preferTabs(false)
|
||||
.logIfEnabled(false)
|
||||
.alwaysKeepOpen(true)
|
||||
.pauseOnExit(true)
|
||||
.launch();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -73,7 +73,7 @@ public class TroubleshootCategory extends AppPrefsCategory {
|
||||
var script = AppInstallation.ofCurrent().getDaemonDebugScriptPath();
|
||||
TerminalLaunch.builder()
|
||||
.title(AppNames.ofCurrent().getName() + " Debug")
|
||||
.alwaysKeepOpen(true)
|
||||
.pauseOnExit(true)
|
||||
.localScript(sc -> new ShellScript(
|
||||
sc.getShellDialect().runScriptCommand(sc, script.toString())))
|
||||
.launch();
|
||||
|
||||
@@ -92,7 +92,7 @@ public class BitwardenPasswordManager implements PasswordManager {
|
||||
.localScript(script)
|
||||
.logIfEnabled(false)
|
||||
.preferTabs(false)
|
||||
.alwaysKeepOpen(true)
|
||||
.pauseOnExit(true)
|
||||
.launch();
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ public class DashlanePasswordManager implements PasswordManager {
|
||||
.title("Dashlane login")
|
||||
.localScript(script)
|
||||
.logIfEnabled(false)
|
||||
.alwaysKeepOpen(true)
|
||||
.pauseOnExit(true)
|
||||
.launch();
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -105,7 +105,7 @@ public class KeeperPasswordManager implements PasswordManager {
|
||||
.title("Keeper login")
|
||||
.localScript(script)
|
||||
.logIfEnabled(false)
|
||||
.alwaysKeepOpen(true)
|
||||
.pauseOnExit(true)
|
||||
.launch();
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ public class LastpassPasswordManager implements PasswordManager {
|
||||
.title("LastPass login")
|
||||
.localScript(script)
|
||||
.logIfEnabled(false)
|
||||
.alwaysKeepOpen(true)
|
||||
.pauseOnExit(true)
|
||||
.launch();
|
||||
}
|
||||
return null;
|
||||
|
||||
@@ -56,7 +56,7 @@ public class TerminalDockHubComp extends SimpleRegionBuilder {
|
||||
Platform.runLater(() -> {
|
||||
update(stack);
|
||||
});
|
||||
}, Duration.ofMillis(100));
|
||||
}, Duration.ofMillis(500));
|
||||
}
|
||||
};
|
||||
var update = new ChangeListener<Number>() {
|
||||
|
||||
@@ -110,9 +110,9 @@ public class TerminalDockHubManager {
|
||||
private final AppLayoutModel.QueueEntry queueEntry = new AppLayoutModel.QueueEntry(
|
||||
AppI18n.observable("toggleTerminalDock"), new LabelGraphic.NodeGraphic(() -> {
|
||||
var inner = new FontIcon();
|
||||
inner.iconCodeProperty().bind(PlatformThread.sync(Bindings.createObjectBinding(() -> {
|
||||
return detached.get() || minimized.get() || !showing.get() ? MaterialDesignC.CONSOLE_LINE : MaterialDesignC.CONSOLE;
|
||||
}, detached, minimized, showing)));
|
||||
inner.iconCodeProperty().bind(Bindings.createObjectBinding(() -> {
|
||||
return detached.get() || minimized.get() ? MaterialDesignC.CONSOLE_LINE : MaterialDesignC.CONSOLE;
|
||||
}, detached, minimized));
|
||||
inner.getStyleClass().add("graphic");
|
||||
inner.getStyleClass().add("terminal-dock-button");
|
||||
return inner;
|
||||
|
||||
@@ -72,6 +72,8 @@ public class TerminalDockView {
|
||||
|
||||
public synchronized void trackTerminal(ControllableTerminalSession terminal, boolean dock) {
|
||||
if (viewActive && dock && viewBounds != null) {
|
||||
terminal.own();
|
||||
|
||||
// Bring main window to foreground since initial launch
|
||||
NativeWinWindowControl.MAIN_WINDOW.activate();
|
||||
|
||||
@@ -79,11 +81,6 @@ public class TerminalDockView {
|
||||
// We always want to show the terminal though
|
||||
terminal.show();
|
||||
|
||||
terminal.own();
|
||||
|
||||
// Bring terminal window in front of main window
|
||||
terminal.focus();
|
||||
|
||||
terminal.updatePosition(windowBoundsFunction.apply(viewBounds));
|
||||
updateCustomBounds();
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ public class TerminalLaunch {
|
||||
boolean logIfEnabled = true;
|
||||
|
||||
@Builder.Default
|
||||
boolean alwaysKeepOpen = false;
|
||||
boolean pauseOnExit = AppPrefs.get().terminalAlwaysPauseOnExit().getValue();
|
||||
|
||||
ExternalTerminalType terminal;
|
||||
|
||||
@@ -68,8 +68,7 @@ public class TerminalLaunch {
|
||||
getFullTitle(),
|
||||
directory,
|
||||
request != null ? request : UUID.randomUUID(),
|
||||
logIfEnabled,
|
||||
alwaysKeepOpen,
|
||||
logIfEnabled, pauseOnExit,
|
||||
command);
|
||||
TerminalLauncher.open(List.of(pane), preferTabs, type);
|
||||
}
|
||||
|
||||
@@ -143,8 +143,6 @@ public class TerminalLauncher {
|
||||
config.getProcessControl() instanceof ShellControl
|
||||
? type.additionalInitCommands()
|
||||
: TerminalInitFunction.none());
|
||||
var alwaysPromptRestart = config.isAlwaysKeepOpen()
|
||||
|| AppPrefs.get().terminalAlwaysPauseOnExit().getValue();
|
||||
TerminalLauncherManager.submitAsync(
|
||||
config.getRequest(), config.getProcessControl(), terminalConfig, config.getDirectory(), latch);
|
||||
var effectivePreferTabs =
|
||||
@@ -152,7 +150,7 @@ public class TerminalLauncher {
|
||||
|
||||
var paneIndex = configs.indexOf(config);
|
||||
var paneConfig = TerminalPaneConfiguration.create(
|
||||
config.getRequest(), entry, config.getTitle(), paneIndex, effectivePreferTabs, alwaysPromptRestart);
|
||||
config.getRequest(), entry, config.getTitle(), paneIndex, effectivePreferTabs, config.isAlwaysKeepOpen());
|
||||
paneList.add(paneConfig);
|
||||
}
|
||||
|
||||
|
||||
@@ -89,9 +89,9 @@ public interface WarpTerminalType extends ExternalTerminalType, TrackableTermina
|
||||
|
||||
var scriptArg = URLEncoder.encode(movedScriptFile.toString(), StandardCharsets.UTF_8);
|
||||
if (!configuration.isPreferTabs()) {
|
||||
DesktopHelper.openUrl("warp://action/new_window?path=" + scriptArg);
|
||||
DesktopHelper.openAssociatedApplication("warp://action/new_window?path=" + scriptArg);
|
||||
} else {
|
||||
DesktopHelper.openUrl("warp://action/new_tab?path=" + scriptArg);
|
||||
DesktopHelper.openAssociatedApplication("warp://action/new_tab?path=" + scriptArg);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -125,9 +125,9 @@ public interface WarpTerminalType extends ExternalTerminalType, TrackableTermina
|
||||
public void launch(TerminalLaunchConfiguration configuration) {
|
||||
var pane = configuration.single();
|
||||
if (!configuration.isPreferTabs()) {
|
||||
DesktopHelper.openUrl("warp://action/new_window?path=" + pane.getScriptFile());
|
||||
DesktopHelper.openAssociatedApplication("warp://action/new_window?path=" + pane.getScriptFile());
|
||||
} else {
|
||||
DesktopHelper.openUrl("warp://action/new_tab?path=" + pane.getScriptFile());
|
||||
DesktopHelper.openAssociatedApplication("warp://action/new_tab?path=" + pane.getScriptFile());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ import io.xpipe.app.util.ThreadHelper;
|
||||
import io.xpipe.app.util.WindowsRegistry;
|
||||
import io.xpipe.core.FilePath;
|
||||
|
||||
import io.xpipe.core.OsType;
|
||||
import lombok.SneakyThrows;
|
||||
|
||||
import java.io.IOException;
|
||||
@@ -56,7 +57,11 @@ public interface WezTerminalType extends ExternalTerminalType, TrackableTerminal
|
||||
}
|
||||
|
||||
default Path getSocketDir() {
|
||||
return AppSystemInfo.ofCurrent().getUserHome().resolve(".local", "share", "wezterm");
|
||||
if (OsType.ofLocal() == OsType.LINUX) {
|
||||
return Path.of(System.getenv("XDG_RUNTIME_DIR"), "wezterm");
|
||||
} else {
|
||||
return AppSystemInfo.ofCurrent().getUserHome().resolve(".local", "share", "wezterm");
|
||||
}
|
||||
}
|
||||
|
||||
default Optional<Path> waitForInstanceStart(int count) {
|
||||
@@ -114,6 +119,7 @@ public interface WezTerminalType extends ExternalTerminalType, TrackableTerminal
|
||||
default void launch(TerminalLaunchConfiguration configuration) throws Exception {
|
||||
var base = getWeztermCommandBase();
|
||||
var activeSocket = waitForInstanceStart(1);
|
||||
var tabid = "0";
|
||||
// Always start a new window for split panes as we can't find the pane index to start with
|
||||
if (activeSocket.isEmpty() || configuration.getPanes().size() > 1 || !configuration.isPreferTabs()) {
|
||||
var gui = CommandBuilder.of().add(base.buildSimple().replace("wezterm.exe", "wezterm-gui.exe"));
|
||||
@@ -122,24 +128,36 @@ public interface WezTerminalType extends ExternalTerminalType, TrackableTerminal
|
||||
.add("start", "--always-new-process")
|
||||
.add(configuration.getPanes().getFirst().getDialectLaunchCommand());
|
||||
ExternalApplicationHelper.startAsync(command);
|
||||
activeSocket = waitForInstanceStart(50);
|
||||
if (activeSocket.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
var command = CommandBuilder.of()
|
||||
.add(base)
|
||||
.add("cli", "spawn")
|
||||
.add(configuration.getPanes().getFirst().getDialectLaunchCommand());
|
||||
command.fixedEnvironment("WEZTERM_UNIX_SOCKET", activeSocket.get().toString());
|
||||
LocalShell.getShell()
|
||||
tabid = LocalShell.getShell()
|
||||
.command(command)
|
||||
.withWorkingDirectory(FilePath.of(getSocketDir()))
|
||||
.execute();
|
||||
.readStdoutOrThrow();
|
||||
}
|
||||
|
||||
if (configuration.getPanes().size() > 1) {
|
||||
activeSocket = waitForInstanceStart(50);
|
||||
if (activeSocket.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
var titleCommand = CommandBuilder.of()
|
||||
.add(base)
|
||||
.add("cli", "set-tab-title")
|
||||
.add("--tab-id", tabid)
|
||||
.addQuoted(configuration.getColoredTitle());
|
||||
titleCommand.fixedEnvironment("WEZTERM_UNIX_SOCKET", activeSocket.get().toString());
|
||||
// Sometimes the tab ids don't exist even though it just returned them to us
|
||||
// So just ignore any errors
|
||||
LocalShell.getShell()
|
||||
.command(titleCommand)
|
||||
.withWorkingDirectory(FilePath.of(getSocketDir()))
|
||||
.executeAndCheck();
|
||||
|
||||
if (configuration.getPanes().size() > 1) {
|
||||
var direction = AppPrefs.get().terminalSplitStrategy().getValue();
|
||||
var directionIterator = direction.iterator();
|
||||
for (int i = 1; i < configuration.getPanes().size(); i++) {
|
||||
@@ -163,8 +181,7 @@ public interface WezTerminalType extends ExternalTerminalType, TrackableTerminal
|
||||
activeSocket.get().toString()))
|
||||
.withWorkingDirectory(FilePath.of(getSocketDir()))
|
||||
.execute();
|
||||
directionIterator.next();
|
||||
}
|
||||
directionIterator.next(); }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -28,7 +28,10 @@ public enum AppDistributionType implements Translatable {
|
||||
HOMEBREW("homebrew", true, () -> {
|
||||
var pkg = AppNames.ofCurrent().getKebapName();
|
||||
return new CommandUpdater(
|
||||
ShellScript.lines("brew upgrade --cask xpipe-io/tap/" + pkg, AppRestart.getTerminalRestartCommand()));
|
||||
ShellScript.lines(
|
||||
"brew upgrade --cask xpipe-io/tap/" + pkg,
|
||||
"if [ \"$?\" != 0 ]; then echo \"Update failed ...\"; read key; fi",
|
||||
AppRestart.getTerminalRestartCommand()));
|
||||
}),
|
||||
APT_REPO("apt", true, () -> {
|
||||
var pkg = AppNames.ofCurrent().getKebapName();
|
||||
@@ -36,6 +39,7 @@ public enum AppDistributionType implements Translatable {
|
||||
"echo \"+ sudo apt update && sudo apt install -y " + pkg + "\"",
|
||||
"sudo apt update",
|
||||
"sudo apt install -y " + pkg,
|
||||
"if [ \"$?\" != 0 ]; then echo \"Update failed ...\"; read key; fi",
|
||||
AppRestart.getTerminalRestartCommand()));
|
||||
}),
|
||||
RPM_REPO("rpm", true, () -> {
|
||||
@@ -43,13 +47,15 @@ public enum AppDistributionType implements Translatable {
|
||||
return new CommandUpdater(ShellScript.lines(
|
||||
"echo \"+ sudo yum upgrade " + pkg + " --refresh -y\"",
|
||||
"sudo yum upgrade " + pkg + " --refresh -y",
|
||||
"if [ \"$?\" != 0 ]; then echo \"Update failed ...\"; read key; fi",
|
||||
AppRestart.getTerminalRestartCommand()));
|
||||
}),
|
||||
AUR("aur", true, () -> {
|
||||
var pkg = AppNames.ofCurrent().getKebapName();
|
||||
return new CommandUpdater(ShellScript.lines(
|
||||
"echo \"+ git clone https://aur.archlinux.org/" + pkg + " . && makepkg -si\"",
|
||||
"cd $(mktemp -d) && git clone https://aur.archlinux.org/" + pkg + " . && makepkg -si --noconfirm",
|
||||
"echo \"+ git -c core.autocrlf=false clone https://aur.archlinux.org/" + pkg + " . && makepkg -si\"",
|
||||
"cd $(mktemp -d) && git -c core.autocrlf=false clone https://aur.archlinux.org/" + pkg + " . && makepkg -si --noconfirm",
|
||||
"if [ \"$?\" != 0 ]; then echo \"Update failed ...\"; read key; fi",
|
||||
AppRestart.getTerminalRestartCommand()));
|
||||
}),
|
||||
WEBTOP("webtop", true, () -> new WebtopUpdater()),
|
||||
|
||||
@@ -229,7 +229,7 @@ public class AppInstaller {
|
||||
runinstaller
|
||||
if [ "$?" != 0 ]; then
|
||||
echo "Update failed ..."
|
||||
read -rs -k 1 key
|
||||
read key
|
||||
fi
|
||||
""", file, file, AppRestart.getTerminalRestartCommand()));
|
||||
AppOperationMode.executeAfterShutdown(() -> {
|
||||
|
||||
@@ -16,7 +16,7 @@ import java.util.List;
|
||||
|
||||
public class DesktopHelper {
|
||||
|
||||
public static void openUrl(String uri) {
|
||||
public static void openBrowser(String uri) {
|
||||
if (uri == null) {
|
||||
return;
|
||||
}
|
||||
@@ -56,6 +56,30 @@ public class DesktopHelper {
|
||||
});
|
||||
}
|
||||
|
||||
public static void openAssociatedApplication(String uri) {
|
||||
if (uri == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
URI parsed;
|
||||
try {
|
||||
parsed = URI.create(uri);
|
||||
} catch (IllegalArgumentException e) {
|
||||
ErrorEventFactory.fromThrowable("Invalid URI: " + uri, e.getCause() != null ? e.getCause() : e)
|
||||
.handle();
|
||||
return;
|
||||
}
|
||||
|
||||
// Windows URL open always uses browser
|
||||
if (OsType.ofLocal() == OsType.WINDOWS) {
|
||||
LocalExec.executeAsync("rundll32", "url.dll,FileProtocolHandler", parsed.toString());
|
||||
return;
|
||||
}
|
||||
|
||||
// Other OS use associated app
|
||||
openBrowser(uri);
|
||||
}
|
||||
|
||||
public static void browseFile(Path file) {
|
||||
if (file == null || !Files.exists(file)) {
|
||||
return;
|
||||
|
||||
@@ -11,6 +11,6 @@ public class Hyperlinks {
|
||||
public static final String GITHUB_WEBTOP = "https://github.com/xpipe-io/xpipe-webtop";
|
||||
|
||||
public static void open(String uri) {
|
||||
DesktopHelper.openUrl(uri);
|
||||
DesktopHelper.openBrowser(uri);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,6 +128,7 @@ open module io.xpipe.app {
|
||||
uses CloudSetupProvider;
|
||||
|
||||
provides ActionProvider with
|
||||
GradleRunMenuProvider,
|
||||
RefreshHubLeafProvider,
|
||||
SetupToolActionProvider,
|
||||
XPipeUrlProvider,
|
||||
|
||||
+3
-3
@@ -296,13 +296,13 @@ project.ext {
|
||||
}
|
||||
|
||||
// JavaFX config
|
||||
devJavafxVersion = '26-ea+19'
|
||||
devJavafxVersion = '27-ea+4'
|
||||
platformName = getPlatformName()
|
||||
useBundledJavaFx = fullVersion
|
||||
bundledJdkJavaFx = ModuleFinder.ofSystem().find("javafx.base").isPresent()
|
||||
// Define a custom JavaFX SDK location
|
||||
// customJavaFxLibsPath = file("C:\\Projects\\jfx\\build\\sdk\\lib")
|
||||
// customJavaFxJmodsPath = file("C:\\Projects\\jfx\\build\\jmods")
|
||||
customJavaFxLibsPath = null; // file("C:\\Projects\\jfx\\build\\sdk\\lib")
|
||||
customJavaFxJmodsPath = null; // file("C:\\Projects\\jfx\\build\\jmods")
|
||||
|
||||
// Other
|
||||
deeplApiKey = findProperty('DEEPL_API_KEY') != null ? findProperty('DEEPL_API_KEY') : ""
|
||||
|
||||
Vendored
+1
-1
@@ -1,7 +1,7 @@
|
||||
|
||||
plugins {
|
||||
id 'org.beryx.jlink' version '3.2.1'
|
||||
id("com.netflix.nebula.ospackage") version "12.1.1"
|
||||
id("com.netflix.nebula.ospackage") version "12.2.0"
|
||||
id 'org.gradle.crypto.checksum' version '1.4.0'
|
||||
id 'signing'
|
||||
}
|
||||
|
||||
Vendored
-8
@@ -1,8 +0,0 @@
|
||||
- Fix Pageant and custom SSH agents on Windows not working
|
||||
- Fix Pageant integration using wrong named pipe when multiple users were logged in on Windows
|
||||
- Fix plain directory sync not working for OneDrive directories
|
||||
- Fix terminal docking not working after window had been minimized to system tray
|
||||
- Fix Windows vault lock and hibernation lock not working after window had been minimized to system tray
|
||||
- Fix NullPointer when launching docked terminal via a desktop shortcut when XPipe was not running yet
|
||||
- Fix desktop shortcuts for actions not applying any custom workspace directories
|
||||
- Fix various other NullPointers
|
||||
Vendored
+3
-7
@@ -1,9 +1,5 @@
|
||||
- Fix various SSH agents not working if the socket path contained spaces
|
||||
- Fix terminal docking not working properly on multiple displays with different scale factor
|
||||
- Fix terminal docking sometimes not automatically reattaching windows that were moved back to the dock
|
||||
- The terminal dock indicator icon will now show a different icon to indicate when the terminal is detached
|
||||
- Fix terminal docking not automatically reattaching windows that were moved back to the dock
|
||||
- Fix automatic updater not pausing terminal session when update failed
|
||||
- Automatically delete corrupted git index file when detected
|
||||
- Fix terminal test button not showing for the terminal selection in the settings menu
|
||||
- Fix network switch ports being included in total connection count
|
||||
- Fix various NullPointers
|
||||
- Fix some broken documentation links
|
||||
-
|
||||
|
||||
Vendored
+1
@@ -0,0 +1 @@
|
||||
- Add support for neovim editor (Thanks to @leycm)
|
||||
Vendored
+1
-1
@@ -47,7 +47,7 @@ jlink {
|
||||
options.addAll('--strip-native-debug-symbols', 'exclude-debuginfo-files')
|
||||
}
|
||||
|
||||
if (hasProperty("customJavaFxJmodsPath")) {
|
||||
if (customJavaFxJmodsPath != null) {
|
||||
addExtraModulePath(customJavaFxJmodsPath.toString())
|
||||
} else if (useBundledJavaFx && !bundledJdkJavaFx) {
|
||||
addExtraModulePath(layout.projectDirectory.dir("javafx/${platformName}/${arch}").toString())
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
name=GraalVM Community
|
||||
version=25.0.1
|
||||
version=25.0.2
|
||||
license=GPL2 with the Classpath Exception
|
||||
link=https://www.graalvm.org/
|
||||
+1
-1
@@ -34,7 +34,7 @@ public class RunTerminalScriptActionProvider implements ActionProvider {
|
||||
.entry(ref.get())
|
||||
.title(scriptStore.get().getName())
|
||||
.command(sc.command(script))
|
||||
.alwaysKeepOpen(true)
|
||||
.pauseOnExit(true)
|
||||
.launch();
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -49,7 +49,7 @@ public class PodmanContainerLogsActionProvider implements HubLeafProvider<Podman
|
||||
var d = ref.getStore();
|
||||
var view = d.commandView(d.getCmd().getStore().getHost().getStore().getOrStartSession());
|
||||
TerminalLaunch.builder()
|
||||
.alwaysKeepOpen(true)
|
||||
.pauseOnExit(true)
|
||||
.entry(ref.get())
|
||||
.title("Logs")
|
||||
.command(view.logs(d.getContainerName()))
|
||||
|
||||
@@ -18,7 +18,7 @@ configurations {
|
||||
javafx
|
||||
}
|
||||
|
||||
if (hasProperty("customJavaFxLibsPath")) {
|
||||
if (customJavaFxLibsPath != null) {
|
||||
repositories {
|
||||
flatDir {
|
||||
dirs customJavaFxLibsPath
|
||||
|
||||
Generated
+1
@@ -159,3 +159,4 @@ passbolt=Passbolt
|
||||
yakuake=Yakuake
|
||||
remoteViewer=Virt viewer
|
||||
cosmicEdit=Cosmic Editor
|
||||
neovim=Neovim
|
||||
|
||||
Generated
+2
@@ -760,6 +760,8 @@ shell=Shell
|
||||
hub=Hub
|
||||
script=script
|
||||
genericScript=Generisk
|
||||
gradleTasks=Gradle-opgaver
|
||||
runTask=Kør opgave
|
||||
archiveName=Arkivets navn
|
||||
compress=Komprimere
|
||||
compressContents=Komprimere indhold
|
||||
|
||||
Generated
+2
@@ -766,6 +766,8 @@ shell=Shell
|
||||
hub=Hub
|
||||
script=skript
|
||||
genericScript=Allgemein
|
||||
gradleTasks=Gradle Aufgaben
|
||||
runTask=Aufgabe ausführen
|
||||
archiveName=Name des Archivs
|
||||
compress=Komprimieren
|
||||
compressContents=Inhalte komprimieren
|
||||
|
||||
Generated
+2
@@ -778,6 +778,8 @@ hub=Hub
|
||||
#context: Computer script
|
||||
script=script
|
||||
genericScript=Generic
|
||||
gradleTasks=Gradle tasks
|
||||
runTask=Run task
|
||||
archiveName=Archive name
|
||||
compress=Compress
|
||||
compressContents=Compress contents
|
||||
|
||||
Generated
+2
@@ -742,6 +742,8 @@ shell=Shell
|
||||
hub=Hub
|
||||
script=script
|
||||
genericScript=Genérico
|
||||
gradleTasks=Tareas Gradle
|
||||
runTask=Ejecutar tarea
|
||||
archiveName=Nombre de archivo
|
||||
compress=Comprime
|
||||
compressContents=Comprimir contenidos
|
||||
|
||||
Generated
+2
@@ -761,6 +761,8 @@ shell=Shell
|
||||
hub=Hub
|
||||
script=script
|
||||
genericScript=Générique
|
||||
gradleTasks=Tâches Gradle
|
||||
runTask=Exécuter une tâche
|
||||
archiveName=Nom de l'archive
|
||||
compress=Compresser
|
||||
compressContents=Compresser le contenu
|
||||
|
||||
Generated
+2
@@ -742,6 +742,8 @@ shell=Shell
|
||||
hub=Hub
|
||||
script=skrip
|
||||
genericScript=Umum
|
||||
gradleTasks=Tugas-tugas gradle
|
||||
runTask=Menjalankan tugas
|
||||
archiveName=Nama arsip
|
||||
compress=Kompres
|
||||
compressContents=Mengompres konten
|
||||
|
||||
Generated
+2
@@ -742,6 +742,8 @@ shell=Shell
|
||||
hub=Hub
|
||||
script=script
|
||||
genericScript=Generico
|
||||
gradleTasks=Attività di Gradle
|
||||
runTask=Esegui attività
|
||||
archiveName=Nome dell'archivio
|
||||
compress=Comprimere
|
||||
compressContents=Comprimere i contenuti
|
||||
|
||||
Generated
+2
@@ -742,6 +742,8 @@ shell=シェル
|
||||
hub=ハブ
|
||||
script=スクリプト
|
||||
genericScript=一般的な
|
||||
gradleTasks=Gradleタスク
|
||||
runTask=タスクを実行する
|
||||
archiveName=アーカイブ名
|
||||
compress=圧縮する
|
||||
compressContents=コンテンツを圧縮する
|
||||
|
||||
Generated
+2
@@ -770,6 +770,8 @@ shell=셸
|
||||
hub=Hub
|
||||
script=스크립트
|
||||
genericScript=Generic
|
||||
gradleTasks=그레이들 작업
|
||||
runTask=작업 실행
|
||||
archiveName=아카이브 이름
|
||||
compress=압축
|
||||
compressContents=콘텐츠 압축
|
||||
|
||||
Generated
+2
@@ -742,6 +742,8 @@ shell=Shell
|
||||
hub=Hub
|
||||
script=script
|
||||
genericScript=Algemeen
|
||||
gradleTasks=Gradle taken
|
||||
runTask=Taak uitvoeren
|
||||
archiveName=Naam archief
|
||||
compress=Comprimeren
|
||||
compressContents=Inhoud comprimeren
|
||||
|
||||
Generated
+2
@@ -742,6 +742,8 @@ shell=Powłoka
|
||||
hub=Hub
|
||||
script=skrypt
|
||||
genericScript=Ogólny
|
||||
gradleTasks=Zadania Gradle
|
||||
runTask=Uruchom zadanie
|
||||
archiveName=Nazwa archiwum
|
||||
compress=Kompresja
|
||||
compressContents=Kompresuj zawartość
|
||||
|
||||
Generated
+2
@@ -742,6 +742,8 @@ shell=Shell
|
||||
hub=Hub
|
||||
script=guião
|
||||
genericScript=Genérico
|
||||
gradleTasks=Tarefas Gradle
|
||||
runTask=Executa uma tarefa
|
||||
archiveName=Nome do arquivo
|
||||
compress=Comprimir
|
||||
compressContents=Comprimir conteúdos
|
||||
|
||||
Generated
+2
@@ -807,6 +807,8 @@ hub=Хаб
|
||||
#custom
|
||||
script=Скрипт
|
||||
genericScript=Generic
|
||||
gradleTasks=Задачи Gradle
|
||||
runTask=Выполнить задание
|
||||
archiveName=Название архива
|
||||
compress=Сжать
|
||||
compressContents=Сжать содержимое
|
||||
|
||||
Generated
+2
@@ -742,6 +742,8 @@ shell=Skal
|
||||
hub=Navet
|
||||
script=skript
|
||||
genericScript=Generisk text
|
||||
gradleTasks=Uppgifter för Gradle
|
||||
runTask=Kör uppgift
|
||||
archiveName=Arkivets namn
|
||||
compress=Komprimera
|
||||
compressContents=Komprimera innehåll
|
||||
|
||||
Generated
+2
@@ -742,6 +742,8 @@ shell=Kabuk
|
||||
hub=Hub
|
||||
script=senaryo
|
||||
genericScript=Jenerik
|
||||
gradleTasks=Gradle görevleri
|
||||
runTask=Görevi çalıştır
|
||||
archiveName=Arşiv adı
|
||||
compress=Sıkıştır
|
||||
compressContents=İçeriği sıkıştır
|
||||
|
||||
Generated
+2
@@ -742,6 +742,8 @@ shell=Shell
|
||||
hub=Hub
|
||||
script=script
|
||||
genericScript=Chung chung
|
||||
gradleTasks=Các tác vụ Gradle
|
||||
runTask=Chạy tác vụ
|
||||
archiveName=Tên tệp lưu trữ
|
||||
compress=Nén
|
||||
compressContents=Nén nội dung
|
||||
|
||||
+2
@@ -1049,6 +1049,8 @@ shell=Shell
|
||||
hub=连接中心
|
||||
script=脚本
|
||||
genericScript=通用
|
||||
gradleTasks=Gradle 任务
|
||||
runTask=运行任务
|
||||
#custom
|
||||
archiveName=压缩包名称
|
||||
compress=压缩
|
||||
|
||||
+2
@@ -742,6 +742,8 @@ shell=殼
|
||||
hub=樞紐
|
||||
script=腳本
|
||||
genericScript=通用
|
||||
gradleTasks=Gradle 任務
|
||||
runTask=執行任務
|
||||
archiveName=存檔名稱
|
||||
compress=壓縮
|
||||
compressContents=壓縮內容
|
||||
|
||||
Reference in New Issue
Block a user