This commit is contained in:
crschnick
2025-06-18 13:28:39 +00:00
parent ae8f7211a2
commit a459b236cf
42 changed files with 68 additions and 93 deletions

View File

@@ -82,9 +82,7 @@ public class ActionShortcutComp extends SimpleComp {
private Comp<?> createMacroComp() {
var button = new ButtonComp(
AppI18n.observable("createMacro"), new FontIcon("mdi2c-clipboard-multiple-outline"), () -> {
onCreateMacro.run();
});
AppI18n.observable("createMacro"), new FontIcon("mdi2c-clipboard-multiple-outline"), onCreateMacro);
return button;
}
}

View File

@@ -18,7 +18,7 @@ public class OpenDirectoryActionProvider implements BrowserActionProvider {
public static class Action extends BrowserAction {
@Override
public void executeImpl() throws Exception {
public void executeImpl() {
var first = getEntries().getFirst();
model.cdSync(first.getRawFileEntry().getPath().toString());
}

View File

@@ -19,7 +19,7 @@ public class OpenFileDefaultActionProvider implements BrowserActionProvider {
public static class Action extends BrowserAction {
@Override
public void executeImpl() throws Exception {
public void executeImpl() {
for (var entry : getEntries()) {
BrowserFileOpener.openInDefaultApplication(model, entry.getRawFileEntry());
}

View File

@@ -20,7 +20,7 @@ public class OpenFileWithActionProvider implements BrowserActionProvider {
public static class Action extends BrowserAction {
@Override
public void executeImpl() throws Exception {
public void executeImpl() {
for (var entry : getEntries()) {
BrowserFileOpener.openWithAnyApplication(model, entry.getRawFileEntry());
}

View File

@@ -30,7 +30,7 @@ public class RunCommandInBrowserActionProvider implements BrowserActionProvider
}
@Override
public void executeImpl() throws Exception {
public void executeImpl() {
var builder = CommandBuilder.of().addFile(command);
for (BrowserEntry entry : getEntries()) {
builder.addFile(entry.getRawFileEntry().getPath());

View File

@@ -8,7 +8,7 @@ import java.util.Optional;
public interface BrowserFileOutput {
public static BrowserFileOutput none() {
static BrowserFileOutput none() {
return new BrowserFileOutput() {
@Override
@@ -22,7 +22,7 @@ public interface BrowserFileOutput {
}
@Override
public OutputStream open() throws IOException {
public OutputStream open() {
return null;
}
};

View File

@@ -49,7 +49,6 @@ public final class BrowserFileSystemTabModel extends BrowserStoreSessionTab<File
private final ObservableList<UUID> terminalRequests = FXCollections.observableArrayList();
private final BooleanProperty transferCancelled = new SimpleBooleanProperty();
@NonNull
private FileSystem fileSystem;
private BrowserFileSystemSavedState savedState;
@@ -144,7 +143,6 @@ public final class BrowserFileSystemTabModel extends BrowserStoreSessionTab<File
}
private void startIfNeeded() throws Exception {
var s = fileSystem.getShell();
if (s.isPresent()) {
s.get().start();
@@ -152,7 +150,6 @@ public final class BrowserFileSystemTabModel extends BrowserStoreSessionTab<File
}
public void killTransfer() {
transferCancelled.set(true);
}
@@ -345,7 +342,7 @@ public final class BrowserFileSystemTabModel extends BrowserStoreSessionTab<File
}
if (!Objects.equals(path, resolvedPath.toString())) {
return Optional.ofNullable(resolvedPath.toString());
return Optional.of(resolvedPath.toString());
}
try {
@@ -359,7 +356,7 @@ public final class BrowserFileSystemTabModel extends BrowserStoreSessionTab<File
return Optional.empty();
}
private void cdSyncWithoutCheck(FilePath path) throws Exception {
private void cdSyncWithoutCheck(FilePath path) {
// Assume that the path is normalized to improve performance!
// path = FileSystemHelper.normalizeDirectoryPath(this, path);

View File

@@ -16,7 +16,7 @@ import java.util.List;
public class BackMenuProvider implements BrowserMenuLeafProvider {
@Override
public void execute(BrowserFileSystemTabModel model, List<BrowserEntry> entries) throws Exception {
public void execute(BrowserFileSystemTabModel model, List<BrowserEntry> entries) {
model.backSync(1);
}

View File

@@ -147,7 +147,7 @@ public class ChgrpMenuProvider implements BrowserMenuBranchProvider {
}
@Override
public void execute(BrowserFileSystemTabModel model, List<BrowserEntry> entries) throws Exception {
public void execute(BrowserFileSystemTabModel model, List<BrowserEntry> entries) {
var group = new SimpleStringProperty();
var modal = ModalOverlay.of(
"groupName",

View File

@@ -145,7 +145,7 @@ public class ChmodMenuProvider implements BrowserMenuBranchProvider {
}
@Override
public void execute(BrowserFileSystemTabModel model, List<BrowserEntry> entries) throws Exception {
public void execute(BrowserFileSystemTabModel model, List<BrowserEntry> entries) {
var permissions = new SimpleStringProperty();
var modal = ModalOverlay.of(
"chmodPermissions",

View File

@@ -146,7 +146,7 @@ public class ChownMenuProvider implements BrowserMenuBranchProvider {
}
@Override
public void execute(BrowserFileSystemTabModel model, List<BrowserEntry> entries) throws Exception {
public void execute(BrowserFileSystemTabModel model, List<BrowserEntry> entries) {
var user = new SimpleStringProperty();
var modal = ModalOverlay.of(
"userName",

View File

@@ -3,8 +3,6 @@ package io.xpipe.app.comp.base;
import io.xpipe.app.comp.Comp;
import io.xpipe.app.comp.SimpleComp;
import io.xpipe.app.core.*;
import io.xpipe.app.core.AppImages;
import io.xpipe.app.core.AppResources;
import io.xpipe.app.core.window.AppDialog;
import io.xpipe.app.core.window.AppMainWindow;
import io.xpipe.app.issue.TrackEvent;

View File

@@ -8,7 +8,6 @@ import io.xpipe.app.core.AppLogs;
import io.xpipe.app.util.PlatformThread;
import io.xpipe.core.process.OsType;
import javafx.animation.*;
import javafx.application.Platform;
import javafx.beans.binding.Bindings;
import javafx.beans.property.Property;

View File

@@ -5,6 +5,7 @@ import io.xpipe.core.util.JacksonMapper;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.Getter;
import lombok.NonNull;
import lombok.Setter;
import org.apache.commons.io.FileUtils;
@@ -72,7 +73,7 @@ public class AppCache {
FileUtils.deleteQuietly(path.toFile());
}
}
return notPresent != null ? notPresent.get() : null;
return notPresent.get();
}
public static boolean getBoolean(String key, boolean notPresent) {

View File

@@ -146,7 +146,7 @@ public class AppProperties {
// We require the user dir from here
AppUserDirectoryCheck.check(dataDir);
AppCache.setBasePath(dataDir.resolve("cache"));
UUID id = AppCache.getNonNull("uuid", UUID.class, null);
UUID id = AppCache.getNonNull("uuid", UUID.class, () -> null);
if (id == null) {
uuid = UUID.randomUUID();
AppCache.update("uuid", uuid);

View File

@@ -3,7 +3,6 @@ package io.xpipe.app.core.window;
import io.xpipe.app.comp.base.AppLayoutComp;
import io.xpipe.app.comp.base.AppMainWindowContentComp;
import io.xpipe.app.core.*;
import io.xpipe.app.core.AppImages;
import io.xpipe.app.core.mode.OperationMode;
import io.xpipe.app.issue.ErrorEventFactory;
import io.xpipe.app.issue.TrackEvent;

View File

@@ -1,8 +1,6 @@
package io.xpipe.app.core.window;
import io.xpipe.app.core.*;
import io.xpipe.app.core.AppImages;
import io.xpipe.app.core.AppResources;
import io.xpipe.app.issue.TrackEvent;
import io.xpipe.app.util.InputHelper;
import io.xpipe.app.util.PlatformInit;

View File

@@ -24,7 +24,7 @@ public interface BatchHubProvider<T extends DataStore> extends ActionProvider {
return true;
}
default void execute(List<DataStoreEntryRef<T>> refs) throws Exception {
default void execute(List<DataStoreEntryRef<T>> refs) {
createBatchAction(refs).executeAsync();
}

View File

@@ -19,7 +19,7 @@ import java.util.stream.Collectors;
@Getter
public final class BatchStoreAction<T extends DataStore> extends SerializableAction implements StoreContextAction {
protected final List<StoreAction<T>> actions;
private final List<StoreAction<T>> actions;
@Override
public void executeImpl() throws Exception {

View File

@@ -7,11 +7,7 @@ import io.xpipe.app.comp.SimpleCompStructure;
import io.xpipe.app.comp.augment.ContextMenuAugment;
import io.xpipe.app.comp.augment.GrowAugment;
import io.xpipe.app.comp.base.*;
import io.xpipe.app.comp.base.IconButtonComp;
import io.xpipe.app.comp.base.LazyTextFieldComp;
import io.xpipe.app.comp.base.LoadingOverlayComp;
import io.xpipe.app.core.*;
import io.xpipe.app.core.AppResources;
import io.xpipe.app.hub.action.HubBranchProvider;
import io.xpipe.app.hub.action.HubLeafProvider;
import io.xpipe.app.hub.action.HubMenuItemProvider;

View File

@@ -341,7 +341,7 @@ public class StoreEntryWrapper {
});
}
public void executeDefaultAction() throws Exception {
public void executeDefaultAction() {
if (entry.getValidity() == DataStoreEntry.Validity.LOAD_FAILED) {
return;
}

View File

@@ -177,11 +177,11 @@ public class StoreViewState {
}
private void initSortMode() {
String global = AppCache.getNonNull("globalSortMode", String.class, null);
String global = AppCache.getNonNull("globalSortMode", String.class, () -> null);
var globalMode = global != null ? StoreSectionSortMode.fromId(global).orElse(null) : null;
globalSortMode.setValue(globalMode != null ? globalMode : StoreSectionSortMode.INDEX_ASC);
String tie = AppCache.getNonNull("tieSortMode", String.class, null);
String tie = AppCache.getNonNull("tieSortMode", String.class, () -> null);
var tieMode = global != null ? StoreSectionSortMode.fromId(tie).orElse(null) : null;
tieSortMode.setValue(tieMode != null ? tieMode : StoreSectionSortMode.DATE_DESC);
}

View File

@@ -23,7 +23,7 @@ import javax.imageio.ImageIO;
public class SystemIconCache {
private static enum ImageColorScheme {
private enum ImageColorScheme {
TRANSPARENT,
MIXED,
LIGHT,

View File

@@ -7,10 +7,10 @@ import java.nio.file.Path;
@Value
public class SystemIconSourceFile {
public static enum ColorSchemeData {
public enum ColorSchemeData {
LIGHT,
DARK,
DEFAULT;
DEFAULT
}
SystemIconSource source;

View File

@@ -3,7 +3,6 @@ package io.xpipe.app.issue;
import io.xpipe.app.comp.Comp;
import io.xpipe.app.comp.base.*;
import io.xpipe.app.core.*;
import io.xpipe.app.core.AppResources;
import javafx.beans.property.*;
import javafx.collections.FXCollections;

View File

@@ -11,8 +11,6 @@ import javafx.geometry.Insets;
import javafx.scene.control.ScrollPane;
import javafx.scene.layout.*;
import lombok.val;
public class AppPrefsComp extends SimpleComp {
@Override

View File

@@ -17,9 +17,9 @@ import java.util.Optional;
public interface ExternalApplicationType extends PrefsValue {
public abstract boolean isAvailable();
boolean isAvailable();
public interface MacApplication extends ExternalApplicationType {
interface MacApplication extends ExternalApplicationType {
default CommandControl launchCommand(CommandBuilder builder, boolean args) {
if (args) {
@@ -84,7 +84,7 @@ public interface ExternalApplicationType extends PrefsValue {
}
}
public interface PathApplication extends ExternalApplicationType {
interface PathApplication extends ExternalApplicationType {
String getExecutable();
@@ -118,11 +118,11 @@ public interface ExternalApplicationType extends PrefsValue {
}
}
public interface InstallLocationType extends ExternalApplicationType {
interface InstallLocationType extends ExternalApplicationType {
String getExecutable();
public abstract Optional<Path> determineInstallation();
Optional<Path> determineInstallation();
default Optional<Path> determineFromPath() {
// Try to locate if it is in the Path
@@ -164,7 +164,7 @@ public interface ExternalApplicationType extends PrefsValue {
}
}
public interface WindowsType extends InstallLocationType {
interface WindowsType extends InstallLocationType {
boolean detach();

View File

@@ -28,7 +28,7 @@ import java.util.regex.Pattern;
* Client for communicating with KeePassXC using the native messaging protocol.
* This implementation communicates with the actual running KeePassXC-proxy process
* via stdin and stdout.
*
* <p>
* Native messaging uses length-prefixed JSON messages over stdin/stdout.
*/
public class KeePassXcProxyClient {
@@ -75,7 +75,6 @@ public class KeePassXcProxyClient {
* Connects to KeePassXC via the provided input and output streams.
* In a real application, these would be the streams connecting to KeePassXC.
*
* @return True if connection was successful, false otherwise
* @throws IOException If there's an error connecting to KeePassXC
*/
public void connect() throws IOException {
@@ -92,7 +91,6 @@ public class KeePassXcProxyClient {
/**
* Performs a key exchange with KeePassXC.
*
* @return True if the key exchange was successful, false otherwise
* @throws IOException If there's an error communicating with KeePassXC
*/
public void exchangeKeys() throws IOException {
@@ -162,7 +160,6 @@ public class KeePassXcProxyClient {
/**
* Tests the association with KeePassXC.
*
* @return True if associated, false otherwise
* @throws IOException If there's an error communicating with KeePassXC
*/
public void testAssociation() throws IOException {
@@ -437,7 +434,6 @@ public class KeePassXcProxyClient {
/**
* Associate with KeePassXC.
*
* @return True if successful, false otherwise
* @throws IOException If there's an error communicating with KeePassXC
*/
public void associate() throws IOException {

View File

@@ -32,7 +32,7 @@ public interface PasswordManager {
}
@Value
static class CredentialResult {
class CredentialResult {
String username;
SecretValue password;

View File

@@ -13,7 +13,7 @@ import java.util.Base64;
/**
* Cryptographic helper for KeePassXC communication.
*
* <p>
* This implementation properly mimics TweetNaCl.js behavior using BouncyCastle,
* implementing X25519 key exchange and XSalsa20-Poly1305 authenticated encryption
* which is what KeePassXC expects.
@@ -69,7 +69,7 @@ public class TweetNaClHelper {
/**
* Encrypt a message using NaCl box.
*
* <p>
* This uses X25519 for key exchange and XSalsa20-Poly1305 for authenticated encryption.
* Follows the TweetNaCl.js implementation exactly.
*/

View File

@@ -89,7 +89,6 @@ public interface AlacrittyTerminalType extends ExternalTerminalType, TrackableTe
.addQuoted(configuration.getCleanTitle())
.add("-e")
.addFile(configuration.getScriptFile());
;
launch(b);
}
}

View File

@@ -11,9 +11,9 @@ import java.nio.file.Path;
public interface WarpTerminalType extends ExternalTerminalType, TrackableTerminalType {
static WarpTerminalType WINDOWS = new Windows();
static WarpTerminalType LINUX = new Linux();
static WarpTerminalType MACOS = new MacOs();
WarpTerminalType WINDOWS = new Windows();
WarpTerminalType LINUX = new Linux();
WarpTerminalType MACOS = new MacOs();
class Windows implements WarpTerminalType {

View File

@@ -24,7 +24,7 @@ public class UpdateNagDialog {
return;
}
Instant lastCheck = AppCache.getNonNull("lastUpdateNag", Instant.class, null);
Instant lastCheck = AppCache.getNonNull("lastUpdateNag", Instant.class, () -> null);
if (lastCheck == null) {
AppCache.update("lastUpdateNag", Instant.now());
return;

View File

@@ -1,6 +1,5 @@
package io.xpipe.app.util;
import io.xpipe.app.action.*;
import io.xpipe.app.ext.LocalStore;
import io.xpipe.app.pwman.PasswordManager;
import io.xpipe.app.storage.*;

View File

@@ -10,7 +10,6 @@ import java.lang.ref.WeakReference;
import java.util.WeakHashMap;
import java.util.function.Function;
@SuppressWarnings("InfiniteLoopStatement")
public class BindingsHelper {
private static final WeakHashMap<Object, Object> REFERENCES = new WeakHashMap<>();

View File

@@ -25,17 +25,17 @@ import java.util.function.Function;
*/
public class Check {
private Map<String, ObservableValue<? extends Object>> dependencies = new HashMap<>(1);
private final Map<String, ObservableValue<?>> dependencies = new HashMap<>(1);
private Consumer<Context> checkMethod;
private ReadOnlyObjectWrapper<ValidationResult> validationResultProperty = new ReadOnlyObjectWrapper<>();
private final ReadOnlyObjectWrapper<ValidationResult> validationResultProperty = new ReadOnlyObjectWrapper<>();
private ValidationResult nextValidationResult = new ValidationResult();
@Getter
private List<Node> targets = new ArrayList<>(1);
private final List<Node> targets = new ArrayList<>(1);
private List<Decoration> decorations = new ArrayList<>();
private final List<Decoration> decorations = new ArrayList<>();
private Function<ValidationMessage, Decoration> decorationFactory;
private ChangeListener<? super Object> dependencyListener;
private final ChangeListener<? super Object> dependencyListener;
public class Context {
@@ -81,7 +81,7 @@ public class Check {
return this;
}
public Check dependsOn(String key, ObservableValue<? extends Object> dependency) {
public Check dependsOn(String key, ObservableValue<?> dependency) {
dependencies.put(key, dependency);
return this;
}
@@ -100,7 +100,7 @@ public class Check {
* This method must be called last.
*/
public Check immediate() {
for (ObservableValue<? extends Object> dependency : dependencies.values()) {
for (ObservableValue<?> dependency : dependencies.values()) {
dependency.addListener(dependencyListener);
}
Platform.runLater(this::recheck); // to circumvent problems with decoration pane vs. dialog

View File

@@ -134,7 +134,7 @@ public class FileOpener {
}
@Override
public OutputStream open() throws Exception {
public OutputStream open() {
return new ByteArrayOutputStream(s.length()) {
@Override
public void close() throws IOException {

View File

@@ -58,7 +58,6 @@ class ScanMultiDialogComp extends ModalOverlayContentComp {
.apply(struc -> {
VBox.setVgrow(struc.get().getChildren().getFirst(), ALWAYS);
});
;
return b.createRegion();
}
}

View File

@@ -1,3 +1,4 @@
XPipe 17 is a large-scale rework of many existing parts of XPipe. It focuses on fixing many longstanding issues and limitations, so that future updates can easily bring new integrations without having to deal with that baggage.
## File browser
@@ -15,22 +16,12 @@
## Connection hub
Proper functionality to organize a collection of hundreds of connections was always somewhat limited until now. There is now an additional index-based organization mechanism where you can assign and move indices of connections to have them listed at a certain place in relation to other connections. This can also be combined with the existing sorting methods like time and alphabetical sorting.
Furthermore, there are also more improvements in the connection hub:
- Renaming connection entries can now be done quickly without having to open the configuration dialog
- You can now set connection configurations to be frozen, meaning that the connection entry can't be modified or deleted. This is helpful for templating and team vault setups
- When editing an incomplete connection configuration, the focus will automatically jump to the first incomplete/invalid value. This makes keyboard usage easier
- Password managers now support retrieving both username and password of an entry. For that, you can now create password manager identities that automatically provide the username and password
## VNC
Up until now, the internal VNC implementation of XPipe did a somewhat acceptable job for most connections. However, it is not able to match dedicated VNC clients when it comes to more advanced features and authentication methods. There's simply not Le development capacity to maintain all of these additional VNC features. For this reason, there is now support to also use an external VNC client with XPipe, it just as with any other tool integrations.
The current integrations include:
- TigerVNC
- TightVNC
- RealVNC
- Remmina
- macOS screen sharing
- A custom command
## SSH
@@ -46,18 +37,27 @@ There is now a new action system, which maps most UI actions to fixed schemas. E
Furthermore, it is also now possible to control how all of these actions are run. For production systems, for example, you can configure that all actions that perform some kind of modification, like deleting a file, have to be confirmed first. This gives you an added layer of protection to double-check any operation before actually executing it.
## VNC
Up until now, the internal VNC implementation of XPipe did a somewhat acceptable job for most connections. However, it is not able to match dedicated VNC clients when it comes to more advanced features and authentication methods. There's simply not Le development capacity to maintain all of these additional VNC features. For this reason, there is now support to also use an external VNC client with XPipe, it just as with any other tool integrations.
The current integrations include:
- TigerVNC
- TightVNC
- RealVNC
- Remmina
- macOS screen sharing
- A custom command
## macOS 26 Tahoe
XPipe adopts many of the new features of macOS 26 right away. if you are using the macOS beta, you have access to these right away.
The application window now uses the new Liquid Glass theming. The application icon has also been reworked with Liquid Glass in mind. There's also support for the new apple containers framework, which has just been released. Searching for available connections on the local machine will make apple containers show up if you have installed the package.
## Connection organization
Proper functionality to organize a collection of hundreds of connections was always somewhat limited until now. There is now an additional index-based organization mechanism where you can assign and move indices of connections to have them listed at a certain place in relation to other connections. This can also be combined with the existing sorting methods like time and alphabetical sorting.
## Other
- Password managers now support retrieving both username and password of an entry. For that, you can now create password manager identities that automatically provide the username and password
- Terminal connections now enable truecolor mode if possible
- The option to open a connection in VSCode remote has been expanded to also support Cursor and Windsurf
- Implement various performance improvements

View File

@@ -119,7 +119,7 @@ public class PasswordManagerIdentityStore extends IdentityStore implements Inter
}
@Override
public void validate() throws Exception {
public void validate() {
retrieveCredentials();
}
}

View File

@@ -12,7 +12,7 @@ public interface UsernameStrategy {
String retrieveUsername() throws Exception;
static class None implements UsernameStrategy {
class None implements UsernameStrategy {
@Override
public boolean hasUser() {
@@ -30,7 +30,7 @@ public interface UsernameStrategy {
}
}
static class Fixed implements UsernameStrategy {
class Fixed implements UsernameStrategy {
private final String username;

View File

@@ -238,7 +238,7 @@ public class RunScriptActionProviderMenu implements HubBranchProvider<ShellStore
private static class NoScriptsActionProvider implements HubLeafProvider<ShellStore>, BatchHubProvider<ShellStore> {
@Override
public void execute(List<DataStoreEntryRef<ShellStore>> dataStoreEntryRefs) throws Exception {
public void execute(List<DataStoreEntryRef<ShellStore>> dataStoreEntryRefs) {
var cat = StoreViewState.get().getAllScriptsCategory();
cat.select();
}
@@ -284,7 +284,7 @@ public class RunScriptActionProviderMenu implements HubBranchProvider<ShellStore
implements HubLeafProvider<ShellStore>, BatchHubProvider<ShellStore> {
@Override
public void execute(List<DataStoreEntryRef<ShellStore>> dataStoreEntryRefs) throws Exception {
public void execute(List<DataStoreEntryRef<ShellStore>> dataStoreEntryRefs) {
var cat = StoreViewState.get()
.getCategoryWrapper(DataStorage.get()
.getStoreCategory(dataStoreEntryRefs.getFirst().get()));