Improve startup time and fix some small issues

This commit is contained in:
crschnick 2023-06-02 08:43:29 +00:00
parent f4c440fef1
commit b889cd3fab
7 changed files with 111 additions and 40 deletions

View file

@ -22,6 +22,7 @@ import lombok.SneakyThrows;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class AppLayoutComp extends Comp<CompStructure<BorderPane>> {
@ -71,26 +72,36 @@ public class AppLayoutComp extends Comp<CompStructure<BorderPane>> {
@Override
public CompStructure<BorderPane> createBase() {
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 sidebar = new SideMenuBarComp(selected, entries);
pane.setCenter(map.get(selected.getValue()));
pane.setCenter(getRegion(selected.getValue(), map));
pane.setRight(sidebar.createRegion());
selected.addListener((c, o, n) -> {
if (o != null && o.equals(entries.get(2))) {
AppPrefs.get().save();
}
pane.setCenter(map.get(n));
pane.setCenter(getRegion(n, map));
});
pane.setCenter(map.get(selected.getValue()));
pane.setPrefWidth(1280);
pane.setPrefHeight(720);
AppFont.normal(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() {
return entries;
}

View file

@ -80,15 +80,15 @@ public class App extends Application {
},
XPipeDistributionType.get().getUpdateHandler().getPreparedUpdate());
var appWindow = new AppMainWindow(stage);
var appWindow = AppMainWindow.init(stage);
appWindow.getStage().titleProperty().bind(PlatformThread.sync(titleBinding));
appWindow.initialize();
appWindow.show();
appWindow.setContent(content);
TrackEvent.info("Application window initialized");
stage.setOnShown(event -> {
focus();
});
appWindow.show();
// For demo purposes
// if (true) {

View file

@ -26,6 +26,7 @@ import java.time.temporal.ChronoField;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
public class AppLogs {
@ -362,10 +363,16 @@ public class AppLogs {
@Override
protected void handleNormalizedLoggingCall(
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()
.category(name)
.type(level.toString().toLowerCase())
.message(msg)
.message(formatted)
.build()
.handle();
}

View file

@ -11,9 +11,13 @@ import javafx.geometry.Rectangle2D;
import javafx.scene.Scene;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.Region;
import javafx.stage.Screen;
import javafx.stage.Stage;
import lombok.Builder;
import lombok.Getter;
import lombok.Value;
import lombok.extern.jackson.Jacksonized;
import java.time.Duration;
import java.time.Instant;
@ -25,6 +29,7 @@ public class AppMainWindow {
@Getter
private final Stage stage;
private final BooleanProperty windowActive = new SimpleBooleanProperty(false);
private Thread thread;
private volatile Instant lastUpdate;
@ -33,8 +38,12 @@ public class AppMainWindow {
this.stage = stage;
}
public static void init(Stage stage) {
public static AppMainWindow init(Stage 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() {
@ -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 -> {
saveState();
});
@ -136,7 +140,12 @@ public class AppMainWindow {
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();
e.consume();
});
TrackEvent.debug("Window listeners added");
@ -151,6 +160,9 @@ public class AppMainWindow {
// stage.setMaximized(state.maximized);
TrackEvent.debug("Window loaded saved bounds");
} else {
stage.setWidth(1280);
stage.setHeight(720);
}
}
@ -159,9 +171,13 @@ public class AppMainWindow {
return;
}
var newState = new WindowState(
stage.isMaximized(), (int) stage.getX(), (int) stage.getY(), (int) stage.getWidth(), (int)
stage.getHeight());
var newState = WindowState.builder()
.maximized(stage.isMaximized())
.windowX((int) stage.getX())
.windowY((int) stage.getY())
.windowWidth((int) stage.getWidth())
.windowHeight((int) stage.getHeight())
.build();
AppCache.update("windowState", newState);
}
@ -190,20 +206,6 @@ public class AppMainWindow {
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() {
initializeWindow();
setupListeners();
@ -217,18 +219,14 @@ public class AppMainWindow {
private void setupContent(Comp<?> content) {
var contentR = content.createRegion();
var scene = new Scene(contentR, -1, -1, false);
TrackEvent.debug("Created initial scene");
stage.setScene(scene);
contentR.requestFocus();
stage.getScene().setRoot(contentR);
TrackEvent.debug("Set content scene");
setupUndoRedo(scene);
scene.addEventHandler(KeyEvent.KEY_PRESSED, event -> {
stage.getScene().addEventHandler(KeyEvent.KEY_PRESSED, event -> {
if (AppProperties.get().isDeveloperMode() && event.getCode().equals(KeyCode.F6)) {
var newR = content.createRegion();
scene.setRoot(newR);
stage.getScene().setRoot(newR);
newR.requestFocus();
TrackEvent.debug("Rebuilt content");
@ -240,8 +238,16 @@ public class AppMainWindow {
public void setContent(Comp<?> 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;
}
}

View file

@ -20,6 +20,10 @@ import java.util.List;
public abstract class LauncherInput {
public static void handle(List<String> arguments) {
if (arguments.size() == 0) {
return;
}
TrackEvent.withDebug("launcher", "Handling arguments")
.elements(arguments)
.handle();

View file

@ -5,6 +5,7 @@ import io.xpipe.app.issue.ErrorEvent;
import io.xpipe.app.util.ApplicationHelper;
import io.xpipe.app.util.MacOsPermissions;
import io.xpipe.app.util.ScriptHelper;
import io.xpipe.app.util.WindowsRegistry;
import io.xpipe.core.impl.FileNames;
import io.xpipe.core.impl.LocalStore;
import io.xpipe.core.process.OsType;
@ -12,7 +13,10 @@ import io.xpipe.core.process.ShellControl;
import io.xpipe.core.process.ShellDialects;
import lombok.Getter;
import java.io.IOException;
import java.nio.file.Path;
import java.util.List;
import java.util.Optional;
import java.util.stream.Stream;
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 =
new SimpleType("app.gnomeTerminal", "gnome-terminal", "Gnome Terminal") {
@ -143,6 +185,7 @@ public interface ExternalTerminalType extends PrefsChoiceValue {
ExternalTerminalType CUSTOM = new CustomType();
List<ExternalTerminalType> ALL = Stream.of(
TABBY_WINDOWS,
WINDOWS_TERMINAL,
PWSH_WINDOWS,
POWERSHELL_WINDOWS,

View file

@ -28,7 +28,7 @@ deleteAlertTitle=Confirm deletion
deleteAlertHeader=Do you want to delete the ($COUNT$) selected elements?
selectedElements=Selected elements:
mustNotBeEmpty=$NAME$ must not be empty
download=Drop to transfer
download=Drop to download
dragFiles=Drag files from here
null=$VALUE$ must be not null
roots=Roots