From fc6be847fe1fa01dbc690bde3e31368045d2e5d7 Mon Sep 17 00:00:00 2001 From: crschnick Date: Fri, 20 Mar 2026 07:34:47 +0000 Subject: [PATCH] Rework --- .../file/BrowserConnectionListFilterComp.java | 4 ++-- .../file/BrowserFileSystemTabModel.java | 2 +- .../file/BrowserQuickAccessContextMenu.java | 6 +++++- .../impl/compress/UnzipActionProvider.java | 13 ++++--------- .../menu/impl/compress/ZipActionProvider.java | 12 +++++------- ...eComp.java => StoreCategoryChoiceComp.java} | 9 ++++++--- .../app/hub/comp/StoreCategoryWrapper.java | 2 ++ .../xpipe/app/hub/comp/StoreChoicePopover.java | 2 +- .../io/xpipe/app/hub/comp/StoreViewState.java | 18 ++++++++++++++++++ .../io/xpipe/app/process/ScriptHelper.java | 11 +++++++---- .../io/xpipe/app/process/ShellDialect.java | 2 ++ dist/changelog/22.0.md | 1 + .../ScriptCollectionSourceImportDialog.java | 2 +- .../io/xpipe/ext/base/script/ScriptStore.java | 2 +- 14 files changed, 56 insertions(+), 30 deletions(-) rename app/src/main/java/io/xpipe/app/hub/comp/{DataStoreCategoryChoiceComp.java => StoreCategoryChoiceComp.java} (89%) diff --git a/app/src/main/java/io/xpipe/app/browser/file/BrowserConnectionListFilterComp.java b/app/src/main/java/io/xpipe/app/browser/file/BrowserConnectionListFilterComp.java index f77805a75..55022952b 100644 --- a/app/src/main/java/io/xpipe/app/browser/file/BrowserConnectionListFilterComp.java +++ b/app/src/main/java/io/xpipe/app/browser/file/BrowserConnectionListFilterComp.java @@ -4,7 +4,7 @@ import io.xpipe.app.comp.SimpleRegionBuilder; import io.xpipe.app.comp.base.FilterComp; import io.xpipe.app.comp.base.HorizontalComp; import io.xpipe.app.core.AppFontSizes; -import io.xpipe.app.hub.comp.DataStoreCategoryChoiceComp; +import io.xpipe.app.hub.comp.StoreCategoryChoiceComp; import io.xpipe.app.hub.comp.StoreCategoryWrapper; import io.xpipe.app.hub.comp.StoreViewState; import io.xpipe.app.util.ObservableSubscriber; @@ -28,7 +28,7 @@ public final class BrowserConnectionListFilterComp extends SimpleRegionBuilder { @Override protected Region createSimple() { - var category = new DataStoreCategoryChoiceComp( + var category = new StoreCategoryChoiceComp( StoreViewState.get().getAllConnectionsCategory(), StoreViewState.get().getActiveCategory(), this.category, diff --git a/app/src/main/java/io/xpipe/app/browser/file/BrowserFileSystemTabModel.java b/app/src/main/java/io/xpipe/app/browser/file/BrowserFileSystemTabModel.java index 32f41fbb4..bf6400ab2 100644 --- a/app/src/main/java/io/xpipe/app/browser/file/BrowserFileSystemTabModel.java +++ b/app/src/main/java/io/xpipe/app/browser/file/BrowserFileSystemTabModel.java @@ -590,7 +590,7 @@ public final class BrowserFileSystemTabModel extends BrowserStoreSessionTab { - expandDirectoryMenu(empty); + if (!keyBasedNavigation) { + expandDirectoryMenu(empty); + } }) .start(); } diff --git a/app/src/main/java/io/xpipe/app/browser/menu/impl/compress/UnzipActionProvider.java b/app/src/main/java/io/xpipe/app/browser/menu/impl/compress/UnzipActionProvider.java index 33568ab23..5c293551f 100644 --- a/app/src/main/java/io/xpipe/app/browser/menu/impl/compress/UnzipActionProvider.java +++ b/app/src/main/java/io/xpipe/app/browser/menu/impl/compress/UnzipActionProvider.java @@ -34,17 +34,12 @@ public class UnzipActionProvider implements BrowserActionProvider { public void executeImpl() throws Exception { var sc = model.getFileSystem().getShell().orElseThrow(); if (sc.getOsType() == OsType.WINDOWS) { - if (ShellDialects.isPowershell(sc)) { + sc.enforceDialect(ShellDialects.POWERSHELL, p -> { for (BrowserEntry entry : getEntries()) { - runPowershellCommand(sc, model, entry); + runPowershellCommand(p, model, entry); } - } else { - try (var sub = sc.subShell(ShellDialects.POWERSHELL)) { - for (BrowserEntry entry : getEntries()) { - runPowershellCommand(sub, model, entry); - } - } - } + return null; + }); } else { for (BrowserEntry entry : getEntries()) { var command = CommandBuilder.of() diff --git a/app/src/main/java/io/xpipe/app/browser/menu/impl/compress/ZipActionProvider.java b/app/src/main/java/io/xpipe/app/browser/menu/impl/compress/ZipActionProvider.java index 6f07dd570..eac7b6de1 100644 --- a/app/src/main/java/io/xpipe/app/browser/menu/impl/compress/ZipActionProvider.java +++ b/app/src/main/java/io/xpipe/app/browser/menu/impl/compress/ZipActionProvider.java @@ -5,6 +5,7 @@ import io.xpipe.app.browser.action.BrowserActionProvider; import io.xpipe.app.browser.file.BrowserEntry; import io.xpipe.app.ext.FileKind; import io.xpipe.app.process.CommandBuilder; +import io.xpipe.app.process.ShellControl; import io.xpipe.app.process.ShellDialects; import io.xpipe.core.FilePath; import io.xpipe.core.OsType; @@ -53,13 +54,10 @@ public class ZipActionProvider implements BrowserActionProvider { } } - if (ShellDialects.isPowershell(sc)) { - sc.command(command).withWorkingDirectory(base).execute(); - } else { - try (var sub = sc.subShell(ShellDialects.POWERSHELL)) { - sub.command(command).withWorkingDirectory(base).execute(); - } - } + sc.enforceDialect(ShellDialects.POWERSHELL, p -> { + p.command(command).withWorkingDirectory(base).execute(); + return null; + }); } else { var command = CommandBuilder.of().add("zip", "-q", "-y", "-r", "-"); for (BrowserEntry entry : getEntries()) { diff --git a/app/src/main/java/io/xpipe/app/hub/comp/DataStoreCategoryChoiceComp.java b/app/src/main/java/io/xpipe/app/hub/comp/StoreCategoryChoiceComp.java similarity index 89% rename from app/src/main/java/io/xpipe/app/hub/comp/DataStoreCategoryChoiceComp.java rename to app/src/main/java/io/xpipe/app/hub/comp/StoreCategoryChoiceComp.java index ab4afd5f1..d4456f962 100644 --- a/app/src/main/java/io/xpipe/app/hub/comp/DataStoreCategoryChoiceComp.java +++ b/app/src/main/java/io/xpipe/app/hub/comp/StoreCategoryChoiceComp.java @@ -1,6 +1,7 @@ package io.xpipe.app.hub.comp; import io.xpipe.app.comp.SimpleRegionBuilder; +import io.xpipe.app.comp.base.PrettyImageHelper; import io.xpipe.app.platform.PlatformThread; import javafx.beans.property.Property; @@ -15,7 +16,7 @@ import lombok.Value; import java.util.function.Predicate; -public class DataStoreCategoryChoiceComp extends SimpleRegionBuilder { +public class StoreCategoryChoiceComp extends SimpleRegionBuilder { private final StoreCategoryWrapper root; private final Property external; @@ -23,7 +24,7 @@ public class DataStoreCategoryChoiceComp extends SimpleRegionBuilder { private final boolean applyExternalInitially; private final Predicate filter; - public DataStoreCategoryChoiceComp( + public StoreCategoryChoiceComp( StoreCategoryWrapper root, Property external, Property value, @@ -57,7 +58,7 @@ public class DataStoreCategoryChoiceComp extends SimpleRegionBuilder { if (!applyExternalInitially) { value.setValue(last); } - var box = new ComboBox<>(StoreViewState.get().getSortedCategories(root, false).filtered(filter).getList()); + var box = new ComboBox<>(StoreViewState.get().getSortedCategories(root, true).filtered(filter).getList()); box.setValue(value.getValue()); box.valueProperty().addListener((observable, oldValue, newValue) -> { value.setValue(newValue); @@ -83,9 +84,11 @@ public class DataStoreCategoryChoiceComp extends SimpleRegionBuilder { super.updateItem(w, empty); textProperty().unbind(); if (w != null) { + setGraphic(PrettyImageHelper.ofFixedSizeSquare(w.getIconFile().getValue(), 16).build()); textProperty().bind(w.getShownName()); setPadding(new Insets(6, 6, 6, 8 + (indent ? w.getDepth() * 8 : 0))); } else { + setGraphic(null); setText("None"); } } diff --git a/app/src/main/java/io/xpipe/app/hub/comp/StoreCategoryWrapper.java b/app/src/main/java/io/xpipe/app/hub/comp/StoreCategoryWrapper.java index 051878019..a75fe765e 100644 --- a/app/src/main/java/io/xpipe/app/hub/comp/StoreCategoryWrapper.java +++ b/app/src/main/java/io/xpipe/app/hub/comp/StoreCategoryWrapper.java @@ -227,6 +227,8 @@ public class StoreCategoryWrapper { Optional.ofNullable(getParent()).ifPresent(storeCategoryWrapper -> { storeCategoryWrapper.update(); }); + + StoreViewState.get().refreshActiveCategory(); } private String translatedName(String original) { diff --git a/app/src/main/java/io/xpipe/app/hub/comp/StoreChoicePopover.java b/app/src/main/java/io/xpipe/app/hub/comp/StoreChoicePopover.java index 8d3f988bb..c9736fd41 100644 --- a/app/src/main/java/io/xpipe/app/hub/comp/StoreChoicePopover.java +++ b/app/src/main/java/io/xpipe/app/hub/comp/StoreChoicePopover.java @@ -138,7 +138,7 @@ public class StoreChoicePopover { }, initialExpanded); - var category = new DataStoreCategoryChoiceComp( + var category = new StoreCategoryChoiceComp( rootCategory != null ? rootCategory.getRoot() : null, StoreViewState.get().getActiveCategory(), selectedCategory, diff --git a/app/src/main/java/io/xpipe/app/hub/comp/StoreViewState.java b/app/src/main/java/io/xpipe/app/hub/comp/StoreViewState.java index b7db6ad1c..41b02d5d9 100644 --- a/app/src/main/java/io/xpipe/app/hub/comp/StoreViewState.java +++ b/app/src/main/java/io/xpipe/app/hub/comp/StoreViewState.java @@ -185,6 +185,20 @@ public class StoreViewState { return batchModeSelectionSet.contains(entry); } + public void refreshActiveCategory() { + if (getActiveCategory().getValue().isHierarchyExpanded()) { + return; + } + + StoreCategoryWrapper current = getActiveCategory().getValue(); + while ((current = current.getParent()) != null) { + if (current.getParent() == null || current.getParent().getExpanded().get()) { + activeCategory.setValue(current); + break; + } + }; + } + public void selectBatchMode(StoreSection section) { var wrapper = section.getWrapper(); if (wrapper != null && wrapper.getEntry().getValidity() == DataStoreEntry.Validity.LOAD_FAILED) { @@ -380,6 +394,10 @@ public class StoreViewState { }); } + getActiveCategory().addListener((observable, oldValue, newValue) -> { + refreshActiveCategory(); + }); + // Watch out for synchronizing all calls to the entries and categories list! DataStorage.get().addListener(new StorageListener() { diff --git a/app/src/main/java/io/xpipe/app/process/ScriptHelper.java b/app/src/main/java/io/xpipe/app/process/ScriptHelper.java index adaf32ae4..b0b86dbcd 100644 --- a/app/src/main/java/io/xpipe/app/process/ScriptHelper.java +++ b/app/src/main/java/io/xpipe/app/process/ScriptHelper.java @@ -41,13 +41,16 @@ public class ScriptHelper { @SneakyThrows public static FilePath createExecScriptRaw(ShellControl processControl, FilePath file, String content, boolean log) { - if (processControl.view().fileExists(file)) { + var exists = processControl.view().fileExists(file); + + if (log) { + TrackEvent.withTrace("Creating exec script").tag("file", file).tag("exists", exists).tag("content", content).handle(); + } + + if (exists) { return file; } - if (log) { - TrackEvent.withTrace("Writing exec script").tag("file", file).tag("content", content).handle(); - } processControl.view().writeScriptFile(file, content); return file; } diff --git a/app/src/main/java/io/xpipe/app/process/ShellDialect.java b/app/src/main/java/io/xpipe/app/process/ShellDialect.java index da2c8c70a..56946e739 100644 --- a/app/src/main/java/io/xpipe/app/process/ShellDialect.java +++ b/app/src/main/java/io/xpipe/app/process/ShellDialect.java @@ -147,6 +147,8 @@ public interface ShellDialect { String runScriptCommand(ShellControl parent, String file); + String runScriptInOtherDialectCommand(ShellControl parent, String file); + String sourceScriptCommand(ShellControl sc, String file); String executeCommandWithShell(String cmd); diff --git a/dist/changelog/22.0.md b/dist/changelog/22.0.md index 2e013f5a2..9e7f1067e 100644 --- a/dist/changelog/22.0.md +++ b/dist/changelog/22.0.md @@ -57,3 +57,4 @@ Furthermore, the container restart action will now properly restart any systemd - Improve timeout handling for shells to allow for a quicker shell init - Fix Keeper issues on macOS and add support for Keeper App Store installations - Fix SSH being broken when a custom alias to a modified ssh command was set in a shell rc file +- Fix shell scripts for mixed environments, e.g. a powershell script in cmd environment, not properly running diff --git a/ext/base/src/main/java/io/xpipe/ext/base/script/ScriptCollectionSourceImportDialog.java b/ext/base/src/main/java/io/xpipe/ext/base/script/ScriptCollectionSourceImportDialog.java index 9cdcdacab..4359d3b91 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/script/ScriptCollectionSourceImportDialog.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/script/ScriptCollectionSourceImportDialog.java @@ -102,7 +102,7 @@ public class ScriptCollectionSourceImportDialog { stack.prefWidth(600); stack.prefHeight(650); - var catChoice = new DataStoreCategoryChoiceComp( + var catChoice = new StoreCategoryChoiceComp( StoreViewState.get().getAllScriptsCategory(), StoreViewState.get().getActiveCategory(), targetCategory, diff --git a/ext/base/src/main/java/io/xpipe/ext/base/script/ScriptStore.java b/ext/base/src/main/java/io/xpipe/ext/base/script/ScriptStore.java index e22b1718b..f99d610a9 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/script/ScriptStore.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/script/ScriptStore.java @@ -77,7 +77,7 @@ public class ScriptStore implements SelfReferentialStore, StatefulDataStore