diff --git a/app/src/main/java/io/xpipe/app/browser/file/BrowserFileListComp.java b/app/src/main/java/io/xpipe/app/browser/file/BrowserFileListComp.java index 8c9c52c6f..b22d5b373 100644 --- a/app/src/main/java/io/xpipe/app/browser/file/BrowserFileListComp.java +++ b/app/src/main/java/io/xpipe/app/browser/file/BrowserFileListComp.java @@ -31,9 +31,7 @@ import javafx.scene.Node; import javafx.scene.control.*; import javafx.scene.control.skin.TableViewSkin; import javafx.scene.control.skin.VirtualFlow; -import javafx.scene.input.DragEvent; -import javafx.scene.input.MouseButton; -import javafx.scene.input.MouseEvent; +import javafx.scene.input.*; import javafx.scene.layout.HBox; import javafx.scene.layout.Priority; import javafx.scene.layout.Region; @@ -79,7 +77,7 @@ public final class BrowserFileListComp extends SimpleComp { : null)); filenameCol.setComparator(Comparator.comparing(String::toLowerCase)); filenameCol.setSortType(ASCENDING); - filenameCol.setCellFactory(col -> new FilenameCell(fileList.getEditing())); + filenameCol.setCellFactory(col -> new FilenameCell(fileList.getEditing(), col.getTableView())); var sizeCol = new TableColumn(); sizeCol.textProperty().bind(AppI18n.observable("size")); @@ -170,8 +168,8 @@ public final class BrowserFileListComp extends SimpleComp { ThreadHelper.runFailableAsync(() -> { browserAction.execute(fileList.getFileSystemModel(), selected); }); + event.consume(); }); - event.consume(); }); } @@ -318,12 +316,10 @@ public final class BrowserFileListComp extends SimpleComp { TableColumn modeCol) { var lastDir = new SimpleObjectProperty(); Runnable updateHandler = () -> { - PlatformThread.runLaterIfNeeded(() -> { + Platform.runLater(() -> { var newItems = new ArrayList<>(fileList.getShown().getValue()); - var hasModifiedDate = newItems.size() == 0 - || newItems.stream() - .anyMatch(entry -> entry.getRawFileEntry().getDate() != null); + var hasModifiedDate = newItems.size() == 0 || newItems.stream().anyMatch(entry -> entry.getRawFileEntry().getDate() != null); if (!hasModifiedDate) { table.getColumns().remove(mtimeCol); } else { @@ -333,10 +329,7 @@ public final class BrowserFileListComp extends SimpleComp { } if (fileList.getFileSystemModel().getFileSystem() != null) { - var shell = fileList.getFileSystemModel() - .getFileSystem() - .getShell() - .orElseThrow(); + var shell = fileList.getFileSystemModel().getFileSystem().getShell().orElseThrow(); var hasAttributes = !OsType.WINDOWS.equals(shell.getOsType()); if (!hasAttributes) { table.getColumns().remove(modeCol); @@ -358,10 +351,8 @@ public final class BrowserFileListComp extends SimpleComp { if (!Objects.equals(lastDir.get(), currentDirectory)) { TableViewSkin skin = (TableViewSkin) table.getSkin(); if (skin != null) { - VirtualFlow flow = - (VirtualFlow) skin.getChildren().get(1); - ScrollBar vbar = - (ScrollBar) flow.getChildrenUnmodifiable().get(2); + VirtualFlow flow = (VirtualFlow) skin.getChildren().get(1); + ScrollBar vbar = (ScrollBar) flow.getChildrenUnmodifiable().get(2); if (vbar.getValue() != 0.0) { table.scrollTo(0); } @@ -466,7 +457,7 @@ public final class BrowserFileListComp extends SimpleComp { private final BooleanProperty updating = new SimpleBooleanProperty(); - public FilenameCell(Property editing) { + public FilenameCell(Property editing, TableView tableView) { accessibleTextProperty() .bind(Bindings.createStringBinding( () -> { @@ -496,6 +487,10 @@ public final class BrowserFileListComp extends SimpleComp { itemProperty()) .not() .not()) + .focusTraversable(false) + .apply(struc -> struc.get().focusedProperty().addListener((observable, oldValue, newValue) -> { + getTableRow().requestFocus(); + })) .createRegion(); editing.addListener((observable, oldValue, newValue) -> { @@ -524,6 +519,16 @@ public final class BrowserFileListComp extends SimpleComp { HBox.setHgrow(textField, Priority.ALWAYS); graphic.setAlignment(Pos.CENTER_LEFT); setGraphic(graphic); + + tableView.addEventFilter(KeyEvent.KEY_PRESSED, event -> { + if (event.getCode() == KeyCode.RIGHT) { + var selected = fileList.getSelection(); + if (selected.size() == 1 && selected.getFirst() == getTableRow().getItem()) { + ((ButtonBase) quickAccess).fire(); + event.consume(); + } + } + }); } @Override diff --git a/app/src/main/java/io/xpipe/app/browser/file/BrowserFileListCompEntry.java b/app/src/main/java/io/xpipe/app/browser/file/BrowserFileListCompEntry.java index 6e3682b9f..d14e6a06d 100644 --- a/app/src/main/java/io/xpipe/app/browser/file/BrowserFileListCompEntry.java +++ b/app/src/main/java/io/xpipe/app/browser/file/BrowserFileListCompEntry.java @@ -42,11 +42,13 @@ public class BrowserFileListCompEntry { // Only clear for normal clicks if (t.isStillSincePress()) { model.getSelection().clear(); + tv.requestFocus(); } t.consume(); return; } + row.requestFocus(); if (t.getClickCount() == 2 && t.getButton() == MouseButton.PRIMARY) { model.onDoubleClick(item); t.consume(); @@ -56,7 +58,7 @@ public class BrowserFileListCompEntry { } public void onMouseShiftClick(MouseEvent t) { - if (isSynthetic()) { + if (t.getButton() != MouseButton.PRIMARY) { return; } @@ -85,11 +87,6 @@ public class BrowserFileListCompEntry { t.consume(); } - public boolean isSynthetic() { - return item != null - && item.getRawFileEntry().equals(model.getFileSystemModel().getCurrentParentDirectory()); - } - private boolean acceptsDrop(DragEvent event) { // Accept drops from outside the app window if (event.getGestureSource() == null) { @@ -121,7 +118,7 @@ public class BrowserFileListCompEntry { } // Prevent dropping items onto themselves - if (item != null && cb.getEntries().contains(item.getRawFileEntry())) { + if (item != null && cb.getEntries().contains(item)) { return false; } @@ -172,11 +169,10 @@ public class BrowserFileListCompEntry { public void startDrag(MouseEvent event) { if (item == null) { - row.startFullDrag(); return; } - if (isSynthetic()) { + if (event.getButton() != MouseButton.PRIMARY) { return; } @@ -222,7 +218,7 @@ public class BrowserFileListCompEntry { model.getFileSystemModel().cdAsync(item.getRawFileEntry().getPath()); } }; - DROP_TIMER.schedule(activeTask, 1000); + DROP_TIMER.schedule(activeTask, 1200); } public void onDragEntered(DragEvent event) { diff --git a/app/src/main/java/io/xpipe/app/storage/DataStorage.java b/app/src/main/java/io/xpipe/app/storage/DataStorage.java index 7f813ea78..922d5b962 100644 --- a/app/src/main/java/io/xpipe/app/storage/DataStorage.java +++ b/app/src/main/java/io/xpipe/app/storage/DataStorage.java @@ -120,7 +120,6 @@ public abstract class DataStorage { } private synchronized void dispose() { - onReset(); save(true); } @@ -183,8 +182,6 @@ public abstract class DataStorage { }); } - protected void onReset() {} - protected Path getStoresDir() { return dir.resolve("stores"); } diff --git a/build.gradle b/build.gradle index c5aa3a2d0..bbd9f50da 100644 --- a/build.gradle +++ b/build.gradle @@ -103,7 +103,6 @@ project.ext { authors = 'Christopher Schnick' javafxVersion = '22.0.1' platformName = getPlatformName() - artifactChecksums = new HashMap() languages = ["en", "nl", "es", "fr", "de", "it", "pt", "ru", "ja", "zh", "tr", "da"] jvmRunArgs = [ "--add-opens", "java.base/java.lang=io.xpipe.app",