mirror of
https://github.com/xpipe-io/xpipe.git
synced 2024-07-02 21:11:03 +12:00
Improve startup time and fix some small issues
This commit is contained in:
parent
f4c440fef1
commit
b889cd3fab
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue