mirror of
https://github.com/xpipe-io/xpipe.git
synced 2024-10-04 03:53:59 +13:00
Improve startup time and fix some small issues
This commit is contained in:
parent
f4c440fef1
commit
b889cd3fab
7 changed files with 111 additions and 40 deletions
|
@ -22,6 +22,7 @@ import lombok.SneakyThrows;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
public class AppLayoutComp extends Comp<CompStructure<BorderPane>> {
|
public class AppLayoutComp extends Comp<CompStructure<BorderPane>> {
|
||||||
|
|
||||||
|
@ -71,26 +72,36 @@ public class AppLayoutComp extends Comp<CompStructure<BorderPane>> {
|
||||||
@Override
|
@Override
|
||||||
public CompStructure<BorderPane> createBase() {
|
public CompStructure<BorderPane> createBase() {
|
||||||
var map = new HashMap<SideMenuBarComp.Entry, Region>();
|
var map = new HashMap<SideMenuBarComp.Entry, Region>();
|
||||||
entries.forEach(entry -> map.put(entry, entry.comp().createRegion()));
|
getRegion(entries.get(0), map);
|
||||||
|
getRegion(entries.get(1), map);
|
||||||
|
|
||||||
var pane = new BorderPane();
|
var pane = new BorderPane();
|
||||||
var sidebar = new SideMenuBarComp(selected, entries);
|
var sidebar = new SideMenuBarComp(selected, entries);
|
||||||
pane.setCenter(map.get(selected.getValue()));
|
pane.setCenter(getRegion(selected.getValue(), map));
|
||||||
pane.setRight(sidebar.createRegion());
|
pane.setRight(sidebar.createRegion());
|
||||||
selected.addListener((c, o, n) -> {
|
selected.addListener((c, o, n) -> {
|
||||||
if (o != null && o.equals(entries.get(2))) {
|
if (o != null && o.equals(entries.get(2))) {
|
||||||
AppPrefs.get().save();
|
AppPrefs.get().save();
|
||||||
}
|
}
|
||||||
|
|
||||||
pane.setCenter(map.get(n));
|
pane.setCenter(getRegion(n, map));
|
||||||
});
|
});
|
||||||
pane.setCenter(map.get(selected.getValue()));
|
|
||||||
pane.setPrefWidth(1280);
|
pane.setPrefWidth(1280);
|
||||||
pane.setPrefHeight(720);
|
pane.setPrefHeight(720);
|
||||||
AppFont.normal(pane);
|
AppFont.normal(pane);
|
||||||
return new SimpleCompStructure<>(pane);
|
return new SimpleCompStructure<>(pane);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Region getRegion(SideMenuBarComp.Entry entry, Map<SideMenuBarComp.Entry, Region> map) {
|
||||||
|
if (map.containsKey(entry)) {
|
||||||
|
return map.get(entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
Region r = entry.comp().createRegion();
|
||||||
|
map.put(entry, r);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
public List<SideMenuBarComp.Entry> getEntries() {
|
public List<SideMenuBarComp.Entry> getEntries() {
|
||||||
return entries;
|
return entries;
|
||||||
}
|
}
|
||||||
|
|
|
@ -80,15 +80,15 @@ public class App extends Application {
|
||||||
},
|
},
|
||||||
XPipeDistributionType.get().getUpdateHandler().getPreparedUpdate());
|
XPipeDistributionType.get().getUpdateHandler().getPreparedUpdate());
|
||||||
|
|
||||||
var appWindow = new AppMainWindow(stage);
|
var appWindow = AppMainWindow.init(stage);
|
||||||
appWindow.getStage().titleProperty().bind(PlatformThread.sync(titleBinding));
|
appWindow.getStage().titleProperty().bind(PlatformThread.sync(titleBinding));
|
||||||
appWindow.initialize();
|
appWindow.initialize();
|
||||||
|
appWindow.show();
|
||||||
appWindow.setContent(content);
|
appWindow.setContent(content);
|
||||||
TrackEvent.info("Application window initialized");
|
TrackEvent.info("Application window initialized");
|
||||||
stage.setOnShown(event -> {
|
stage.setOnShown(event -> {
|
||||||
focus();
|
focus();
|
||||||
});
|
});
|
||||||
appWindow.show();
|
|
||||||
|
|
||||||
// For demo purposes
|
// For demo purposes
|
||||||
// if (true) {
|
// if (true) {
|
||||||
|
|
|
@ -26,6 +26,7 @@ import java.time.temporal.ChronoField;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
public class AppLogs {
|
public class AppLogs {
|
||||||
|
@ -362,10 +363,16 @@ public class AppLogs {
|
||||||
@Override
|
@Override
|
||||||
protected void handleNormalizedLoggingCall(
|
protected void handleNormalizedLoggingCall(
|
||||||
Level level, Marker marker, String msg, Object[] arguments, Throwable throwable) {
|
Level level, Marker marker, String msg, Object[] arguments, Throwable throwable) {
|
||||||
|
var formatted = msg;
|
||||||
|
if (arguments != null) {
|
||||||
|
for (var arg : arguments) {
|
||||||
|
msg = msg.replaceFirst("\\{}", Objects.toString(arg));
|
||||||
|
}
|
||||||
|
}
|
||||||
TrackEvent.builder()
|
TrackEvent.builder()
|
||||||
.category(name)
|
.category(name)
|
||||||
.type(level.toString().toLowerCase())
|
.type(level.toString().toLowerCase())
|
||||||
.message(msg)
|
.message(formatted)
|
||||||
.build()
|
.build()
|
||||||
.handle();
|
.handle();
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,9 +11,13 @@ import javafx.geometry.Rectangle2D;
|
||||||
import javafx.scene.Scene;
|
import javafx.scene.Scene;
|
||||||
import javafx.scene.input.KeyCode;
|
import javafx.scene.input.KeyCode;
|
||||||
import javafx.scene.input.KeyEvent;
|
import javafx.scene.input.KeyEvent;
|
||||||
|
import javafx.scene.layout.Region;
|
||||||
import javafx.stage.Screen;
|
import javafx.stage.Screen;
|
||||||
import javafx.stage.Stage;
|
import javafx.stage.Stage;
|
||||||
|
import lombok.Builder;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
import lombok.Value;
|
||||||
|
import lombok.extern.jackson.Jacksonized;
|
||||||
|
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
|
@ -25,6 +29,7 @@ public class AppMainWindow {
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
private final Stage stage;
|
private final Stage stage;
|
||||||
|
|
||||||
private final BooleanProperty windowActive = new SimpleBooleanProperty(false);
|
private final BooleanProperty windowActive = new SimpleBooleanProperty(false);
|
||||||
private Thread thread;
|
private Thread thread;
|
||||||
private volatile Instant lastUpdate;
|
private volatile Instant lastUpdate;
|
||||||
|
@ -33,8 +38,12 @@ public class AppMainWindow {
|
||||||
this.stage = stage;
|
this.stage = stage;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void init(Stage stage) {
|
public static AppMainWindow init(Stage stage) {
|
||||||
INSTANCE = new AppMainWindow(stage);
|
INSTANCE = new AppMainWindow(stage);
|
||||||
|
var scene = new Scene(new Region(), -1, -1, false);
|
||||||
|
stage.setScene(scene);
|
||||||
|
AppWindowHelper.setupStylesheets(stage.getScene());
|
||||||
|
return INSTANCE;
|
||||||
}
|
}
|
||||||
|
|
||||||
private synchronized void onChange() {
|
private synchronized void onChange() {
|
||||||
|
@ -117,11 +126,6 @@ public class AppMainWindow {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
stage.setOnCloseRequest(event -> {
|
|
||||||
// Close other windows
|
|
||||||
Stage.getWindows().stream().filter(w -> !w.equals(stage)).toList().forEach(w -> w.fireEvent(event));
|
|
||||||
});
|
|
||||||
|
|
||||||
stage.setOnHiding(e -> {
|
stage.setOnHiding(e -> {
|
||||||
saveState();
|
saveState();
|
||||||
});
|
});
|
||||||
|
@ -136,7 +140,12 @@ public class AppMainWindow {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Close other windows
|
||||||
|
Stage.getWindows().stream().filter(w -> !w.equals(stage)).toList().forEach(w -> w.fireEvent(e));
|
||||||
|
stage.close();
|
||||||
|
|
||||||
AppPrefs.get().closeBehaviour().getValue().getExit().run();
|
AppPrefs.get().closeBehaviour().getValue().getExit().run();
|
||||||
|
e.consume();
|
||||||
});
|
});
|
||||||
|
|
||||||
TrackEvent.debug("Window listeners added");
|
TrackEvent.debug("Window listeners added");
|
||||||
|
@ -151,6 +160,9 @@ public class AppMainWindow {
|
||||||
// stage.setMaximized(state.maximized);
|
// stage.setMaximized(state.maximized);
|
||||||
|
|
||||||
TrackEvent.debug("Window loaded saved bounds");
|
TrackEvent.debug("Window loaded saved bounds");
|
||||||
|
} else {
|
||||||
|
stage.setWidth(1280);
|
||||||
|
stage.setHeight(720);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -159,9 +171,13 @@ public class AppMainWindow {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var newState = new WindowState(
|
var newState = WindowState.builder()
|
||||||
stage.isMaximized(), (int) stage.getX(), (int) stage.getY(), (int) stage.getWidth(), (int)
|
.maximized(stage.isMaximized())
|
||||||
stage.getHeight());
|
.windowX((int) stage.getX())
|
||||||
|
.windowY((int) stage.getY())
|
||||||
|
.windowWidth((int) stage.getWidth())
|
||||||
|
.windowHeight((int) stage.getHeight())
|
||||||
|
.build();
|
||||||
AppCache.update("windowState", newState);
|
AppCache.update("windowState", newState);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -190,20 +206,6 @@ public class AppMainWindow {
|
||||||
return inBounds ? state : null;
|
return inBounds ? state : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setupUndoRedo(Scene scene) {
|
|
||||||
scene.addEventHandler(KeyEvent.KEY_PRESSED, event -> {
|
|
||||||
if ((event.isControlDown() && event.getCode().equals(KeyCode.Y))
|
|
||||||
|| (event.isControlDown()
|
|
||||||
&& event.isShiftDown()
|
|
||||||
&& event.getCode().equals(KeyCode.Z))) {
|
|
||||||
event.consume();
|
|
||||||
} else if (event.isControlDown() && event.getCode().equals(KeyCode.Z)) {
|
|
||||||
event.consume();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
TrackEvent.debug("Set undo/redo handler");
|
|
||||||
}
|
|
||||||
|
|
||||||
public void initialize() {
|
public void initialize() {
|
||||||
initializeWindow();
|
initializeWindow();
|
||||||
setupListeners();
|
setupListeners();
|
||||||
|
@ -217,18 +219,14 @@ public class AppMainWindow {
|
||||||
|
|
||||||
private void setupContent(Comp<?> content) {
|
private void setupContent(Comp<?> content) {
|
||||||
var contentR = content.createRegion();
|
var contentR = content.createRegion();
|
||||||
var scene = new Scene(contentR, -1, -1, false);
|
|
||||||
TrackEvent.debug("Created initial scene");
|
|
||||||
stage.setScene(scene);
|
|
||||||
contentR.requestFocus();
|
contentR.requestFocus();
|
||||||
|
stage.getScene().setRoot(contentR);
|
||||||
TrackEvent.debug("Set content scene");
|
TrackEvent.debug("Set content scene");
|
||||||
|
|
||||||
setupUndoRedo(scene);
|
stage.getScene().addEventHandler(KeyEvent.KEY_PRESSED, event -> {
|
||||||
|
|
||||||
scene.addEventHandler(KeyEvent.KEY_PRESSED, event -> {
|
|
||||||
if (AppProperties.get().isDeveloperMode() && event.getCode().equals(KeyCode.F6)) {
|
if (AppProperties.get().isDeveloperMode() && event.getCode().equals(KeyCode.F6)) {
|
||||||
var newR = content.createRegion();
|
var newR = content.createRegion();
|
||||||
scene.setRoot(newR);
|
stage.getScene().setRoot(newR);
|
||||||
newR.requestFocus();
|
newR.requestFocus();
|
||||||
|
|
||||||
TrackEvent.debug("Rebuilt content");
|
TrackEvent.debug("Rebuilt content");
|
||||||
|
@ -240,8 +238,16 @@ public class AppMainWindow {
|
||||||
|
|
||||||
public void setContent(Comp<?> content) {
|
public void setContent(Comp<?> content) {
|
||||||
setupContent(content);
|
setupContent(content);
|
||||||
AppWindowHelper.setupStylesheets(stage.getScene());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static record WindowState(boolean maximized, int windowX, int windowY, int windowWidth, int windowHeight) {}
|
@Builder
|
||||||
|
@Jacksonized
|
||||||
|
@Value
|
||||||
|
private static class WindowState {
|
||||||
|
boolean maximized;
|
||||||
|
int windowX;
|
||||||
|
int windowY;
|
||||||
|
int windowWidth;
|
||||||
|
int windowHeight;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,10 @@ import java.util.List;
|
||||||
public abstract class LauncherInput {
|
public abstract class LauncherInput {
|
||||||
|
|
||||||
public static void handle(List<String> arguments) {
|
public static void handle(List<String> arguments) {
|
||||||
|
if (arguments.size() == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
TrackEvent.withDebug("launcher", "Handling arguments")
|
TrackEvent.withDebug("launcher", "Handling arguments")
|
||||||
.elements(arguments)
|
.elements(arguments)
|
||||||
.handle();
|
.handle();
|
||||||
|
|
|
@ -5,6 +5,7 @@ import io.xpipe.app.issue.ErrorEvent;
|
||||||
import io.xpipe.app.util.ApplicationHelper;
|
import io.xpipe.app.util.ApplicationHelper;
|
||||||
import io.xpipe.app.util.MacOsPermissions;
|
import io.xpipe.app.util.MacOsPermissions;
|
||||||
import io.xpipe.app.util.ScriptHelper;
|
import io.xpipe.app.util.ScriptHelper;
|
||||||
|
import io.xpipe.app.util.WindowsRegistry;
|
||||||
import io.xpipe.core.impl.FileNames;
|
import io.xpipe.core.impl.FileNames;
|
||||||
import io.xpipe.core.impl.LocalStore;
|
import io.xpipe.core.impl.LocalStore;
|
||||||
import io.xpipe.core.process.OsType;
|
import io.xpipe.core.process.OsType;
|
||||||
|
@ -12,7 +13,10 @@ import io.xpipe.core.process.ShellControl;
|
||||||
import io.xpipe.core.process.ShellDialects;
|
import io.xpipe.core.process.ShellDialects;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Path;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
public interface ExternalTerminalType extends PrefsChoiceValue {
|
public interface ExternalTerminalType extends PrefsChoiceValue {
|
||||||
|
@ -77,6 +81,44 @@ public interface ExternalTerminalType extends PrefsChoiceValue {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
public abstract static class WindowsFullPathType extends ExternalApplicationType.WindowsFullPathType
|
||||||
|
implements ExternalTerminalType {
|
||||||
|
|
||||||
|
public WindowsFullPathType(String id) {
|
||||||
|
super(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void launch(String name, String file, boolean elevated) throws Exception {
|
||||||
|
var path = determinePath();
|
||||||
|
if (path.isEmpty()) {
|
||||||
|
throw new IOException("Unable to find installation of " + getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
ApplicationHelper.executeLocalApplication(
|
||||||
|
sc -> createCommand(sc, name, path.get().toString(), file), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract String createCommand(ShellControl shellControl, String name, String path, String file);
|
||||||
|
}
|
||||||
|
|
||||||
|
ExternalTerminalType TABBY_WINDOWS = new WindowsFullPathType("app.tabbyWindows") {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String createCommand(ShellControl shellControl, String name, String path, String file) {
|
||||||
|
return shellControl.getShellDialect().fileArgument(path) + " run " + shellControl.getShellDialect().fileArgument(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Optional<Path> determinePath() {
|
||||||
|
Optional<String> launcherDir;
|
||||||
|
launcherDir = WindowsRegistry.readString(WindowsRegistry.HKEY_CURRENT_USER, "SOFTWARE\\71445fac-d6ef-5436-9da7-5a323762d7f5", "InstallLocation")
|
||||||
|
.map(p -> p + "\\Tabby.exe");
|
||||||
|
return launcherDir.map(Path::of);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
ExternalTerminalType GNOME_TERMINAL =
|
ExternalTerminalType GNOME_TERMINAL =
|
||||||
new SimpleType("app.gnomeTerminal", "gnome-terminal", "Gnome Terminal") {
|
new SimpleType("app.gnomeTerminal", "gnome-terminal", "Gnome Terminal") {
|
||||||
|
|
||||||
|
@ -143,6 +185,7 @@ public interface ExternalTerminalType extends PrefsChoiceValue {
|
||||||
ExternalTerminalType CUSTOM = new CustomType();
|
ExternalTerminalType CUSTOM = new CustomType();
|
||||||
|
|
||||||
List<ExternalTerminalType> ALL = Stream.of(
|
List<ExternalTerminalType> ALL = Stream.of(
|
||||||
|
TABBY_WINDOWS,
|
||||||
WINDOWS_TERMINAL,
|
WINDOWS_TERMINAL,
|
||||||
PWSH_WINDOWS,
|
PWSH_WINDOWS,
|
||||||
POWERSHELL_WINDOWS,
|
POWERSHELL_WINDOWS,
|
||||||
|
|
|
@ -28,7 +28,7 @@ deleteAlertTitle=Confirm deletion
|
||||||
deleteAlertHeader=Do you want to delete the ($COUNT$) selected elements?
|
deleteAlertHeader=Do you want to delete the ($COUNT$) selected elements?
|
||||||
selectedElements=Selected elements:
|
selectedElements=Selected elements:
|
||||||
mustNotBeEmpty=$NAME$ must not be empty
|
mustNotBeEmpty=$NAME$ must not be empty
|
||||||
download=Drop to transfer
|
download=Drop to download
|
||||||
dragFiles=Drag files from here
|
dragFiles=Drag files from here
|
||||||
null=$VALUE$ must be not null
|
null=$VALUE$ must be not null
|
||||||
roots=Roots
|
roots=Roots
|
||||||
|
|
Loading…
Reference in a new issue