mirror of
https://github.com/xpipe-io/xpipe.git
synced 2024-10-04 03:53:59 +13:00
Browser fixes
This commit is contained in:
parent
fab1d75f45
commit
7ca4d64e2d
6 changed files with 85 additions and 62 deletions
|
@ -2,9 +2,10 @@
|
||||||
|
|
||||||
package io.xpipe.app.browser;
|
package io.xpipe.app.browser;
|
||||||
|
|
||||||
import io.xpipe.app.issue.ErrorEvent;
|
|
||||||
import io.xpipe.app.util.ExternalEditor;
|
import io.xpipe.app.util.ExternalEditor;
|
||||||
|
import io.xpipe.app.util.ScriptHelper;
|
||||||
import io.xpipe.app.util.TerminalHelper;
|
import io.xpipe.app.util.TerminalHelper;
|
||||||
|
import io.xpipe.app.util.ThreadHelper;
|
||||||
import io.xpipe.core.process.OsType;
|
import io.xpipe.core.process.OsType;
|
||||||
import io.xpipe.core.process.ShellProcessControl;
|
import io.xpipe.core.process.ShellProcessControl;
|
||||||
import io.xpipe.core.store.FileSystem;
|
import io.xpipe.core.store.FileSystem;
|
||||||
|
@ -36,6 +37,10 @@ final class FileContextMenu extends ContextMenu {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (List.of("sh", "command").contains(ending)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,6 +57,61 @@ final class FileContextMenu extends ContextMenu {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createMenu() {
|
private void createMenu() {
|
||||||
|
if (entry.isDirectory()) {
|
||||||
|
var terminal = new MenuItem("Open terminal");
|
||||||
|
terminal.setOnAction(event -> {
|
||||||
|
event.consume();
|
||||||
|
model.openTerminalAsync(entry.getPath());
|
||||||
|
});
|
||||||
|
getItems().add(terminal);
|
||||||
|
} else {
|
||||||
|
if (isScript(entry)) {
|
||||||
|
var execute = new MenuItem("Run in terminal");
|
||||||
|
execute.setOnAction(event -> {
|
||||||
|
ThreadHelper.runFailableAsync(() -> {
|
||||||
|
ShellProcessControl pc =
|
||||||
|
model.getFileSystem().getShell().orElseThrow();
|
||||||
|
pc.executeSimpleCommand(pc.getShellDialect().getMakeExecutableCommand(entry.getPath()));
|
||||||
|
var cmd = pc.command("\"" + entry.getPath() + "\"").prepareTerminalOpen();
|
||||||
|
TerminalHelper.open(FilenameUtils.getBaseName(entry.getPath()), cmd);
|
||||||
|
});
|
||||||
|
event.consume();
|
||||||
|
});
|
||||||
|
getItems().add(execute);
|
||||||
|
|
||||||
|
var executeInBackground = new MenuItem("Run in background");
|
||||||
|
executeInBackground.setOnAction(event -> {
|
||||||
|
ThreadHelper.runFailableAsync(() -> {
|
||||||
|
ShellProcessControl pc =
|
||||||
|
model.getFileSystem().getShell().orElseThrow();
|
||||||
|
pc.executeSimpleCommand(pc.getShellDialect().getMakeExecutableCommand(entry.getPath()));
|
||||||
|
var cmd = ScriptHelper.createDetachCommand(pc, "\"" + entry.getPath() + "\"");
|
||||||
|
pc.executeBooleanSimpleCommand(cmd);
|
||||||
|
});
|
||||||
|
event.consume();
|
||||||
|
});
|
||||||
|
getItems().add(executeInBackground);
|
||||||
|
}
|
||||||
|
|
||||||
|
var open = new MenuItem("Open default");
|
||||||
|
open.setOnAction(event -> {
|
||||||
|
ThreadHelper.runFailableAsync(() -> {
|
||||||
|
ShellProcessControl pc = model.getFileSystem().getShell().orElseThrow();
|
||||||
|
var cmd = "\"" + entry.getPath() + "\"";
|
||||||
|
pc.executeBooleanSimpleCommand(cmd);
|
||||||
|
});
|
||||||
|
event.consume();
|
||||||
|
});
|
||||||
|
getItems().add(open);
|
||||||
|
|
||||||
|
var edit = new MenuItem("Edit");
|
||||||
|
edit.setOnAction(event -> {
|
||||||
|
event.consume();
|
||||||
|
ExternalEditor.get().openInEditor(model.getFileSystem(), entry.getPath());
|
||||||
|
});
|
||||||
|
getItems().add(edit);
|
||||||
|
}
|
||||||
|
|
||||||
var cut = new MenuItem("Delete");
|
var cut = new MenuItem("Delete");
|
||||||
cut.setOnAction(event -> {
|
cut.setOnAction(event -> {
|
||||||
event.consume();
|
event.consume();
|
||||||
|
@ -66,56 +126,6 @@ final class FileContextMenu extends ContextMenu {
|
||||||
});
|
});
|
||||||
rename.setAccelerator(new KeyCodeCombination(KeyCode.F2));
|
rename.setAccelerator(new KeyCodeCombination(KeyCode.F2));
|
||||||
|
|
||||||
getItems().setAll(
|
getItems().addAll(new SeparatorMenuItem(), cut, rename);
|
||||||
new SeparatorMenuItem(),
|
|
||||||
cut,
|
|
||||||
rename
|
|
||||||
);
|
|
||||||
|
|
||||||
if (entry.isDirectory()) {
|
|
||||||
var terminal = new MenuItem("Terminal");
|
|
||||||
terminal.setOnAction(event -> {
|
|
||||||
event.consume();
|
|
||||||
model.openTerminalAsync(entry.getPath());
|
|
||||||
});
|
|
||||||
getItems().add(0, terminal);
|
|
||||||
} else {
|
|
||||||
var open = new MenuItem("Open");
|
|
||||||
open.setOnAction(event -> {
|
|
||||||
event.consume();
|
|
||||||
ExternalEditor.get().openInEditor(model.getFileSystem(), entry.getPath());
|
|
||||||
});
|
|
||||||
getItems().add(0, open);
|
|
||||||
|
|
||||||
if (isScript(entry)) {
|
|
||||||
var executeInBackground = new MenuItem("Run in background");
|
|
||||||
executeInBackground.setOnAction(event -> {
|
|
||||||
event.consume();
|
|
||||||
ExternalEditor.get().openInEditor(model.getFileSystem(), entry.getPath());
|
|
||||||
});
|
|
||||||
getItems().add(0, executeInBackground);
|
|
||||||
|
|
||||||
var execute = new MenuItem("Run in terminal");
|
|
||||||
execute.setOnAction(event -> {
|
|
||||||
event.consume();
|
|
||||||
try {
|
|
||||||
ShellProcessControl pc = model.getFileSystem().getShell().orElseThrow();
|
|
||||||
pc.executeSimpleCommand(pc.getShellDialect().getMakeExecutableCommand(entry.getPath()));
|
|
||||||
var cmd = pc.command(entry.getPath()).prepareTerminalOpen();
|
|
||||||
TerminalHelper.open(FilenameUtils.getName(entry.getPath()), cmd);
|
|
||||||
} catch (Exception e) {
|
|
||||||
ErrorEvent.fromThrowable(e).handle();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
getItems().add(0, execute);
|
|
||||||
}
|
|
||||||
|
|
||||||
var edit = new MenuItem("Edit");
|
|
||||||
edit.setOnAction(event -> {
|
|
||||||
event.consume();
|
|
||||||
ExternalEditor.get().openInEditor(model.getFileSystem(), entry.getPath());
|
|
||||||
});
|
|
||||||
getItems().add(0, edit);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,7 +66,7 @@ public class App extends Application {
|
||||||
var content = new AppLayoutComp();
|
var content = new AppLayoutComp();
|
||||||
content.apply(struc -> {
|
content.apply(struc -> {
|
||||||
struc.get().addEventFilter(MouseEvent.MOUSE_CLICKED, event -> {
|
struc.get().addEventFilter(MouseEvent.MOUSE_CLICKED, event -> {
|
||||||
AppActionLinkDetector.detectOnFocus();
|
// AppActionLinkDetector.detectOnFocus();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
var title =
|
var title =
|
||||||
|
|
|
@ -4,7 +4,6 @@ import io.xpipe.app.core.AppImages;
|
||||||
import io.xpipe.app.fxcomps.SimpleComp;
|
import io.xpipe.app.fxcomps.SimpleComp;
|
||||||
import io.xpipe.app.fxcomps.util.PlatformThread;
|
import io.xpipe.app.fxcomps.util.PlatformThread;
|
||||||
import io.xpipe.app.fxcomps.util.SimpleChangeListener;
|
import io.xpipe.app.fxcomps.util.SimpleChangeListener;
|
||||||
import io.xpipe.app.util.XPipeDaemon;
|
|
||||||
import javafx.beans.binding.Bindings;
|
import javafx.beans.binding.Bindings;
|
||||||
import javafx.beans.property.SimpleDoubleProperty;
|
import javafx.beans.property.SimpleDoubleProperty;
|
||||||
import javafx.beans.property.SimpleObjectProperty;
|
import javafx.beans.property.SimpleObjectProperty;
|
||||||
|
@ -73,7 +72,7 @@ public class PrettyImageComp extends SimpleComp {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return XPipeDaemon.getInstance().svgImage(value.getValue());
|
return AppImages.svgImage(value.getValue());
|
||||||
}, value));
|
}, value));
|
||||||
var ar = Bindings.createDoubleBinding(
|
var ar = Bindings.createDoubleBinding(
|
||||||
() -> {
|
() -> {
|
||||||
|
@ -101,7 +100,7 @@ public class PrettyImageComp extends SimpleComp {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return XPipeDaemon.getInstance().image(value.getValue());
|
return AppImages.image(value.getValue());
|
||||||
},
|
},
|
||||||
PlatformThread.sync(value)));
|
PlatformThread.sync(value)));
|
||||||
var ar = Bindings.createDoubleBinding(
|
var ar = Bindings.createDoubleBinding(
|
||||||
|
|
|
@ -37,10 +37,7 @@ public class ErrorHandlerComp extends SimpleComp {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void showAndWait(ErrorEvent event) {
|
public static void showAndWait(ErrorEvent event) {
|
||||||
// Always run later to prevent any issues when an exception
|
PlatformThread.runLaterIfNeededBlocking(() -> {
|
||||||
// is thrown within an animation or layout processing task
|
|
||||||
// Otherwise, the show and wait method might fail
|
|
||||||
PlatformThread.alwaysRunLaterBlocking(() -> {
|
|
||||||
synchronized (showing) {
|
synchronized (showing) {
|
||||||
if (!showing.get()) {
|
if (!showing.get()) {
|
||||||
showing.set(true);
|
showing.set(true);
|
||||||
|
@ -49,7 +46,15 @@ public class ErrorHandlerComp extends SimpleComp {
|
||||||
window.setOnHidden(e -> {
|
window.setOnHidden(e -> {
|
||||||
showing.set(false);
|
showing.set(false);
|
||||||
});
|
});
|
||||||
window.showAndWait();
|
|
||||||
|
// An exception is thrown when show and wait is called
|
||||||
|
// within an animation or layout processing task
|
||||||
|
try {
|
||||||
|
window.showAndWait();
|
||||||
|
} catch (Throwable t) {
|
||||||
|
window.show();
|
||||||
|
t.printStackTrace();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -2,6 +2,7 @@ package io.xpipe.app.util;
|
||||||
|
|
||||||
import io.xpipe.app.issue.TrackEvent;
|
import io.xpipe.app.issue.TrackEvent;
|
||||||
import io.xpipe.core.impl.FileNames;
|
import io.xpipe.core.impl.FileNames;
|
||||||
|
import io.xpipe.core.process.OsType;
|
||||||
import io.xpipe.core.process.ShellProcessControl;
|
import io.xpipe.core.process.ShellProcessControl;
|
||||||
import io.xpipe.core.process.ShellDialect;
|
import io.xpipe.core.process.ShellDialect;
|
||||||
import io.xpipe.core.process.ShellDialects;
|
import io.xpipe.core.process.ShellDialects;
|
||||||
|
@ -14,6 +15,14 @@ import java.util.Random;
|
||||||
|
|
||||||
public class ScriptHelper {
|
public class ScriptHelper {
|
||||||
|
|
||||||
|
public static String createDetachCommand(ShellProcessControl pc, String command) {
|
||||||
|
if (pc.getOsType().equals(OsType.WINDOWS)) {
|
||||||
|
return "start \"\" " + command;
|
||||||
|
} else {
|
||||||
|
return "nohup " + command + " </dev/null &>/dev/null & disown";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static int getScriptId() {
|
public static int getScriptId() {
|
||||||
// A deterministic approach can cause permission problems when two different users execute the same command on a
|
// A deterministic approach can cause permission problems when two different users execute the same command on a
|
||||||
// system
|
// system
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
.bar {
|
.bar {
|
||||||
-fx-padding: 0.8em 1.0em 0.8em 1.0em;
|
-fx-padding: 0.8em 1.0em 0.8em 1.0em;
|
||||||
-fx-background-color: -color-neutral-subtle;
|
-fx-background-color: -color-neutral-subtle;
|
||||||
-fx-border-color: -color-border-default;
|
-fx-border-color: -color-neutral-emphasis;
|
||||||
}
|
}
|
||||||
|
|
||||||
.store-header-bar {
|
.store-header-bar {
|
||||||
|
|
Loading…
Reference in a new issue