mirror of
https://github.com/xpipe-io/xpipe.git
synced 2024-11-21 23:20:23 +00:00
Browser fixes
This commit is contained in:
parent
ddfa70d68b
commit
ff36cfb12a
17 changed files with 163 additions and 134 deletions
|
@ -27,7 +27,7 @@ You should therefore always check out the matching version tag for your local re
|
|||
You can find the available version tags at https://github.com/xpipe-io/xpipe/tags.
|
||||
So for example if you currently have XPipe `11.3` installed, you should run `git reset --hard 11.3` first to properly compile against it.
|
||||
|
||||
You need to have JDK for Java 21 installed to compile the project.
|
||||
You need to have JDK for Java 22 installed to compile the project.
|
||||
If you are on Linux or macOS, you can easily accomplish that by running
|
||||
```bash
|
||||
curl -s "https://get.sdkman.io" | bash
|
||||
|
@ -57,7 +57,7 @@ to connect to that debugger through [AttachMe](https://plugins.jetbrains.com/plu
|
|||
|
||||
## Modularity and IDEs
|
||||
|
||||
All XPipe components target [Java 21](https://openjdk.java.net/projects/jdk/21/) and make full use of the Java Module System (JPMS).
|
||||
All XPipe components target [Java 22](https://openjdk.java.net/projects/jdk/22/) and make full use of the Java Module System (JPMS).
|
||||
All components are modularized, including all their dependencies.
|
||||
In case a dependency is (sadly) not modularized yet, module information is manually added using [extra-java-module-info](https://github.com/gradlex-org/extra-java-module-info).
|
||||
Further, note that as this is a pretty complicated Java project that fully utilizes modularity,
|
||||
|
@ -65,7 +65,7 @@ many IDEs still have problems building this project properly.
|
|||
|
||||
For example, you can't build this project in eclipse or vscode as it will complain about missing modules.
|
||||
The tested and recommended IDE is IntelliJ.
|
||||
When setting up the project in IntelliJ, make sure that the correct JDK (Java 21)
|
||||
When setting up the project in IntelliJ, make sure that the correct JDK (Java 22)
|
||||
is selected both for the project and for gradle itself.
|
||||
|
||||
## Contributing guide
|
||||
|
|
|
@ -10,7 +10,7 @@ import io.xpipe.app.storage.DataColor;
|
|||
public final class BrowserHomeTabModel extends BrowserSessionTab {
|
||||
|
||||
public BrowserHomeTabModel(BrowserAbstractSessionModel<?> browserModel) {
|
||||
super(browserModel, AppI18n.get("overview"), null);
|
||||
super(browserModel, AppI18n.get("overview"));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -11,6 +11,9 @@ import io.xpipe.app.terminal.TerminalDockComp;
|
|||
import io.xpipe.app.terminal.TerminalDockModel;
|
||||
import io.xpipe.app.terminal.TerminalView;
|
||||
import io.xpipe.app.terminal.TerminalViewInstance;
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.beans.value.ObservableBooleanValue;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
|
||||
|
@ -23,9 +26,10 @@ public final class BrowserTerminalDockTabModel extends BrowserSessionTab {
|
|||
private final ObservableList<UUID> terminalRequests;
|
||||
private final TerminalDockModel dockModel = new TerminalDockModel();
|
||||
private TerminalView.Listener listener;
|
||||
private ObservableBooleanValue viewActive;
|
||||
|
||||
public BrowserTerminalDockTabModel(BrowserAbstractSessionModel<?> browserModel, BrowserSessionTab origin, ObservableList<UUID> terminalRequests) {
|
||||
super(browserModel, AppI18n.get("terminal"), null);
|
||||
super(browserModel, AppI18n.get("terminal"));
|
||||
this.origin = origin;
|
||||
this.terminalRequests = terminalRequests;
|
||||
}
|
||||
|
@ -84,11 +88,14 @@ public final class BrowserTerminalDockTabModel extends BrowserSessionTab {
|
|||
}
|
||||
};
|
||||
TerminalView.get().addListener(listener);
|
||||
this.browserModel.getSelectedEntry().addListener((observable, oldValue, newValue) -> {
|
||||
dockModel.toggleView(newValue == origin);
|
||||
});
|
||||
AppLayoutModel.get().getSelected().addListener((observable, oldValue, newValue) -> {
|
||||
dockModel.toggleView(AppLayoutModel.get().getEntries().indexOf(newValue) == 1);
|
||||
|
||||
viewActive = Bindings.createBooleanBinding(() -> {
|
||||
return this.browserModel.getSelectedEntry().getValue() == origin && AppLayoutModel.get().getEntries().indexOf(AppLayoutModel.get().getSelected().getValue()) == 1;
|
||||
}, this.browserModel.getSelectedEntry(), AppLayoutModel.get().getSelected());
|
||||
viewActive.subscribe(aBoolean -> {
|
||||
Platform.runLater(() -> {
|
||||
dockModel.toggleView(aBoolean);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -24,11 +24,6 @@ public interface LeafAction extends BrowserAction {
|
|||
default Button toButton(Region root, OpenFileSystemModel model, List<BrowserEntry> selected) {
|
||||
var b = new Button();
|
||||
b.setOnAction(event -> {
|
||||
// Only accept shortcut actions in the current tab
|
||||
if (!model.equals(model.getBrowserModel().getSelectedEntry().getValue())) {
|
||||
return;
|
||||
}
|
||||
|
||||
ThreadHelper.runFailableAsync(() -> {
|
||||
BooleanScope.executeExclusive(model.getBusy(), () -> {
|
||||
if (model.getFileSystem() == null) {
|
||||
|
|
|
@ -40,6 +40,7 @@ import java.time.Duration;
|
|||
import java.time.Instant;
|
||||
import java.time.ZoneId;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
@ -274,8 +275,15 @@ public final class BrowserFileListComp extends SimpleComp {
|
|||
}
|
||||
table.getSelectionModel().setCellSelectionEnabled(false);
|
||||
|
||||
var updateFromModel = new BooleanScope(new SimpleBooleanProperty());
|
||||
table.getSelectionModel().getSelectedItems().addListener((ListChangeListener<? super BrowserEntry>) c -> {
|
||||
fileList.getSelection().setAll(c.getList());
|
||||
if (updateFromModel.get()) {
|
||||
return;
|
||||
}
|
||||
|
||||
try (var ignored = updateFromModel) {
|
||||
fileList.getSelection().setAll(c.getList());
|
||||
}
|
||||
});
|
||||
|
||||
fileList.getSelection().addListener((ListChangeListener<? super BrowserEntry>) c -> {
|
||||
|
@ -284,16 +292,27 @@ public final class BrowserFileListComp extends SimpleComp {
|
|||
}
|
||||
|
||||
Platform.runLater(() -> {
|
||||
if (c.getList().isEmpty()) {
|
||||
var tableIndices = table.getSelectionModel().getSelectedItems().stream()
|
||||
.mapToInt(entry -> table.getItems().indexOf(entry))
|
||||
.toArray();
|
||||
var indices = c.getList().stream()
|
||||
.mapToInt(entry -> table.getItems().indexOf(entry))
|
||||
.toArray();
|
||||
if (Arrays.equals(indices, tableIndices)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (indices.length == 0) {
|
||||
table.getSelectionModel().clearSelection();
|
||||
return;
|
||||
}
|
||||
|
||||
var indices = c.getList().stream()
|
||||
.mapToInt(entry -> table.getItems().indexOf(entry))
|
||||
.toArray();
|
||||
table.getSelectionModel()
|
||||
.selectIndices(table.getItems().indexOf(c.getList().getFirst()), indices);
|
||||
if (indices.length == 1) {
|
||||
table.getSelectionModel().clearAndSelect(indices[0]);
|
||||
} else {
|
||||
table.getSelectionModel().clearSelection();
|
||||
table.getSelectionModel().selectIndices(indices[0], indices);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -9,9 +9,9 @@ import io.xpipe.app.comp.store.StoreEntryWrapper;
|
|||
import io.xpipe.app.core.AppLayoutModel;
|
||||
import io.xpipe.app.ext.ShellStore;
|
||||
import io.xpipe.app.fxcomps.Comp;
|
||||
import io.xpipe.app.fxcomps.CompStructure;
|
||||
import io.xpipe.app.fxcomps.SimpleComp;
|
||||
import io.xpipe.app.fxcomps.impl.AnchorComp;
|
||||
import io.xpipe.app.fxcomps.impl.LabelComp;
|
||||
import io.xpipe.app.fxcomps.impl.StackComp;
|
||||
import io.xpipe.app.fxcomps.impl.VerticalComp;
|
||||
import io.xpipe.app.fxcomps.util.BindingsHelper;
|
||||
|
@ -25,8 +25,10 @@ import javafx.beans.property.SimpleDoubleProperty;
|
|||
import javafx.geometry.Insets;
|
||||
import javafx.scene.layout.AnchorPane;
|
||||
import javafx.scene.layout.Region;
|
||||
import javafx.scene.layout.VBox;
|
||||
import javafx.scene.shape.Rectangle;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Predicate;
|
||||
|
@ -41,6 +43,66 @@ public class BrowserSessionComp extends SimpleComp {
|
|||
|
||||
@Override
|
||||
protected Region createSimple() {
|
||||
var vertical = createLeftSide();
|
||||
|
||||
var leftSplit = new SimpleDoubleProperty();
|
||||
var rightSplit = new SimpleDoubleProperty();
|
||||
var tabs = new BrowserSessionTabsComp(model, leftSplit, rightSplit);
|
||||
tabs.apply(struc -> {
|
||||
struc.get().setViewOrder(1);
|
||||
struc.get().setPickOnBounds(false);
|
||||
AnchorPane.setTopAnchor(struc.get(), 0.0);
|
||||
AnchorPane.setBottomAnchor(struc.get(), 0.0);
|
||||
AnchorPane.setLeftAnchor(struc.get(), 0.0);
|
||||
AnchorPane.setRightAnchor(struc.get(), 0.0);
|
||||
});
|
||||
|
||||
vertical.apply(struc -> {
|
||||
struc.get()
|
||||
.paddingProperty()
|
||||
.bind(Bindings.createObjectBinding(
|
||||
() -> new Insets(tabs.getHeaderHeight().get(), 0, 0, 0), tabs.getHeaderHeight()));
|
||||
});
|
||||
var loadingIndicator = LoadingOverlayComp.noProgress(Comp.empty(), model.getBusy())
|
||||
.apply(struc -> {
|
||||
AnchorPane.setTopAnchor(struc.get(), 3.0);
|
||||
AnchorPane.setRightAnchor(struc.get(), 0.0);
|
||||
})
|
||||
.styleClass("tab-loading-indicator");
|
||||
|
||||
var pinnedStack = createSplitStack(rightSplit, tabs);
|
||||
|
||||
var loadingStack = new AnchorComp(List.of(tabs, pinnedStack, loadingIndicator));
|
||||
var splitPane = new LeftSplitPaneComp(vertical, loadingStack)
|
||||
.withInitialWidth(AppLayoutModel.get().getSavedState().getBrowserConnectionsWidth())
|
||||
.withOnDividerChange(d -> {
|
||||
AppLayoutModel.get().getSavedState().setBrowserConnectionsWidth(d);
|
||||
leftSplit.set(d);
|
||||
});
|
||||
splitPane.apply(struc -> {
|
||||
struc.getLeft().setMinWidth(200);
|
||||
struc.getLeft().setMaxWidth(500);
|
||||
struc.get().setPickOnBounds(false);
|
||||
});
|
||||
|
||||
splitPane.apply(struc -> {
|
||||
struc.get().skinProperty().subscribe(newValue -> {
|
||||
if (newValue != null) {
|
||||
Platform.runLater(() -> {
|
||||
struc.get().getChildrenUnmodifiable().forEach(node -> {
|
||||
node.setClip(null);
|
||||
node.setPickOnBounds(false);
|
||||
});
|
||||
struc.get().lookupAll(".split-pane-divider").forEach(node -> node.setViewOrder(1));
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
splitPane.styleClass("browser");
|
||||
return splitPane.createRegion();
|
||||
}
|
||||
|
||||
private Comp<CompStructure<VBox>> createLeftSide() {
|
||||
Predicate<StoreEntryWrapper> applicable = storeEntryWrapper -> {
|
||||
if (!storeEntryWrapper.getEntry().getValidity().isUsable()) {
|
||||
return false;
|
||||
|
@ -104,42 +166,30 @@ public class BrowserSessionComp extends SimpleComp {
|
|||
localDownloadStage.maxHeight(200);
|
||||
var vertical =
|
||||
new VerticalComp(List.of(bookmarkTopBar, bookmarksContainer, localDownloadStage)).styleClass("left");
|
||||
return vertical;
|
||||
}
|
||||
|
||||
var leftSplit = new SimpleDoubleProperty();
|
||||
var rightSplit = new SimpleDoubleProperty();
|
||||
var tabs = new BrowserSessionTabsComp(model, leftSplit, rightSplit);
|
||||
tabs.apply(struc -> {
|
||||
struc.get().setViewOrder(1);
|
||||
struc.get().setPickOnBounds(false);
|
||||
AnchorPane.setTopAnchor(struc.get(), 0.0);
|
||||
AnchorPane.setBottomAnchor(struc.get(), 0.0);
|
||||
AnchorPane.setLeftAnchor(struc.get(), 0.0);
|
||||
AnchorPane.setRightAnchor(struc.get(), 0.0);
|
||||
});
|
||||
|
||||
vertical.apply(struc -> {
|
||||
struc.get()
|
||||
.paddingProperty()
|
||||
.bind(Bindings.createObjectBinding(
|
||||
() -> new Insets(tabs.getHeaderHeight().get(), 0, 0, 0), tabs.getHeaderHeight()));
|
||||
});
|
||||
var loadingIndicator = LoadingOverlayComp.noProgress(Comp.empty(), model.getBusy())
|
||||
.apply(struc -> {
|
||||
AnchorPane.setTopAnchor(struc.get(), 3.0);
|
||||
AnchorPane.setRightAnchor(struc.get(), 0.0);
|
||||
})
|
||||
.styleClass("tab-loading-indicator");
|
||||
|
||||
var pinnedStack = new StackComp(List.of(new LabelComp("a")));
|
||||
private StackComp createSplitStack(SimpleDoubleProperty rightSplit, BrowserSessionTabsComp tabs) {
|
||||
var cache = new HashMap<BrowserSessionTab, Region>();
|
||||
var pinnedStack = new StackComp(List.of());
|
||||
pinnedStack.apply(struc -> {
|
||||
model.getEffectiveRightTab().subscribe( (newValue) -> {
|
||||
PlatformThread.runLaterIfNeeded(() -> {
|
||||
if (newValue != null) {
|
||||
var r = newValue.comp().createRegion();
|
||||
struc.get().getChildren().add(r);
|
||||
} else {
|
||||
var all = model.getAllTabs();
|
||||
cache.keySet().removeIf(browserSessionTab -> !all.contains(browserSessionTab));
|
||||
|
||||
if (newValue == null) {
|
||||
struc.get().getChildren().clear();
|
||||
return;
|
||||
}
|
||||
|
||||
var cached = cache.containsKey(newValue);
|
||||
if (!cached) {
|
||||
cache.put(newValue, newValue.comp().createRegion());
|
||||
}
|
||||
var r = cache.get(newValue);
|
||||
struc.get().getChildren().clear();
|
||||
struc.get().getChildren().add(r);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -154,35 +204,6 @@ public class BrowserSessionComp extends SimpleComp {
|
|||
tabs.getHeaderHeight().subscribe(number -> {
|
||||
AnchorPane.setTopAnchor(struc.get(), number.doubleValue());
|
||||
});
|
||||
});
|
||||
|
||||
var loadingStack = new AnchorComp(List.of(tabs, pinnedStack, loadingIndicator));
|
||||
var splitPane = new LeftSplitPaneComp(vertical, loadingStack)
|
||||
.withInitialWidth(AppLayoutModel.get().getSavedState().getBrowserConnectionsWidth())
|
||||
.withOnDividerChange(d -> {
|
||||
AppLayoutModel.get().getSavedState().setBrowserConnectionsWidth(d);
|
||||
leftSplit.set(d);
|
||||
});
|
||||
splitPane.apply(struc -> {
|
||||
struc.getLeft().setMinWidth(200);
|
||||
struc.getLeft().setMaxWidth(500);
|
||||
struc.get().setPickOnBounds(false);
|
||||
});
|
||||
|
||||
splitPane.apply(struc -> {
|
||||
struc.get().skinProperty().subscribe(newValue -> {
|
||||
if (newValue != null) {
|
||||
Platform.runLater(() -> {
|
||||
struc.get().getChildrenUnmodifiable().forEach(node -> {
|
||||
node.setClip(null);
|
||||
node.setPickOnBounds(false);
|
||||
});
|
||||
struc.get().lookupAll(".split-pane-divider").forEach(node -> node.setViewOrder(1));
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
splitPane.styleClass("browser");
|
||||
return splitPane.createRegion();
|
||||
}); return pinnedStack;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,9 +24,7 @@ import javafx.collections.ListChangeListener;
|
|||
import javafx.collections.ObservableMap;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
|
||||
@Getter
|
||||
public class BrowserSessionModel extends BrowserAbstractSessionModel<BrowserSessionTab> {
|
||||
|
@ -79,6 +77,16 @@ public class BrowserSessionModel extends BrowserAbstractSessionModel<BrowserSess
|
|||
});
|
||||
}
|
||||
|
||||
public Set<BrowserSessionTab> getAllTabs() {
|
||||
var set = new HashSet<BrowserSessionTab>();
|
||||
set.addAll(sessionEntries);
|
||||
set.addAll(splits.values());
|
||||
if (globalPinnedTab.getValue() != null) {
|
||||
set.add(globalPinnedTab.getValue());
|
||||
}
|
||||
return set;
|
||||
}
|
||||
|
||||
public void splitTab(BrowserSessionTab tab, BrowserSessionTab split) {
|
||||
if (splits.containsKey(tab)) {
|
||||
return;
|
||||
|
@ -98,7 +106,6 @@ public class BrowserSessionModel extends BrowserAbstractSessionModel<BrowserSess
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
public void pinTab(BrowserSessionTab tab) {
|
||||
if (tab.equals(globalPinnedTab.getValue())) {
|
||||
return;
|
||||
|
|
|
@ -18,13 +18,11 @@ public abstract class BrowserSessionTab {
|
|||
protected final BooleanProperty busy = new SimpleBooleanProperty();
|
||||
protected final BrowserAbstractSessionModel<?> browserModel;
|
||||
protected final String name;
|
||||
protected final String tooltip;
|
||||
protected final Property<BrowserSessionTab> splitTab = new SimpleObjectProperty<>();
|
||||
|
||||
public BrowserSessionTab(BrowserAbstractSessionModel<?> browserModel, String name, String tooltip) {
|
||||
public BrowserSessionTab(BrowserAbstractSessionModel<?> browserModel, String name) {
|
||||
this.browserModel = browserModel;
|
||||
this.name = name;
|
||||
this.tooltip = tooltip;
|
||||
}
|
||||
|
||||
public abstract Comp<?> comp();
|
||||
|
|
|
@ -426,28 +426,6 @@ public class BrowserSessionTabsComp extends SimpleComp {
|
|||
});
|
||||
tab.setContent(split);
|
||||
|
||||
// var lastSplitRegion = new AtomicReference<Region>();
|
||||
// model.getGlobalPinnedTab().subscribe( (newValue) -> {
|
||||
// PlatformThread.runLaterIfNeeded(() -> {
|
||||
// if (newValue != null) {
|
||||
// var r = newValue.comp().createRegion();
|
||||
// split.getItems().add(r);
|
||||
// lastSplitRegion.set(r);
|
||||
// } else if (split.getItems().size() > 1) {
|
||||
// split.getItems().removeLast();
|
||||
// }
|
||||
// });
|
||||
// });
|
||||
// model.getSelectedEntry().addListener((observable, oldValue, newValue) -> {
|
||||
// PlatformThread.runLaterIfNeeded(() -> {
|
||||
// if (newValue != null && newValue.equals(model.getGlobalPinnedTab().getValue()) && split.getItems().size() > 1) {
|
||||
// split.getItems().remove(lastSplitRegion.get());
|
||||
// } else if (split.getItems().size() > 1 && !split.getItems().contains(lastSplitRegion.get())) {
|
||||
// split.getItems().add(lastSplitRegion.get());
|
||||
// }
|
||||
// });
|
||||
// });
|
||||
|
||||
var id = UUID.randomUUID().toString();
|
||||
tab.setId(id);
|
||||
|
||||
|
@ -471,7 +449,6 @@ public class BrowserSessionTabsComp extends SimpleComp {
|
|||
if (color != null) {
|
||||
c.getStyleClass().add(color.getId());
|
||||
}
|
||||
new TooltipAugment<>(new SimpleStringProperty(tabModel.getTooltip()), null).augment(c);
|
||||
c.addEventHandler(
|
||||
DragEvent.DRAG_ENTERED,
|
||||
mouseEvent -> Platform.runLater(
|
||||
|
|
|
@ -16,8 +16,7 @@ public abstract class BrowserStoreSessionTab<T extends DataStore> extends Browse
|
|||
public BrowserStoreSessionTab(BrowserAbstractSessionModel<?> browserModel, DataStoreEntryRef<? extends T> entry) {
|
||||
super(
|
||||
browserModel,
|
||||
DataStorage.get().getStoreEntryDisplayName(entry.get()),
|
||||
DataStorage.get().getStorePath(entry.getEntry()).toString());
|
||||
DataStorage.get().getStoreEntryDisplayName(entry.get()));
|
||||
this.entry = entry;
|
||||
}
|
||||
|
||||
|
|
|
@ -69,18 +69,7 @@ public class StoreEntryListOverviewComp extends SimpleComp {
|
|||
.getValue()
|
||||
.getRoot()
|
||||
.equals(rootCategory);
|
||||
// Sadly the all binding does not update when the individual visibility of entries changes
|
||||
// But it is good enough.
|
||||
var showProvider = true;
|
||||
try {
|
||||
showProvider = storeEntryWrapper.getEntry().getProvider() == null
|
||||
|| storeEntryWrapper
|
||||
.getEntry()
|
||||
.getProvider()
|
||||
.shouldShow(storeEntryWrapper);
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
return inRootCategory && showProvider;
|
||||
return inRootCategory;
|
||||
},
|
||||
StoreViewState.get().getActiveCategory());
|
||||
var count = new CountComp<>(all.getList(), all.getList());
|
||||
|
|
|
@ -60,7 +60,11 @@ public class TerminalDockComp extends SimpleComp {
|
|||
model.onClose();
|
||||
});
|
||||
s.focusedProperty().addListener((observable, oldValue, newValue) -> {
|
||||
|
||||
if (newValue) {
|
||||
model.onFocusGain();
|
||||
} else {
|
||||
model.onFocusLost();
|
||||
}
|
||||
});
|
||||
stack.setOnMouseClicked(event -> {
|
||||
model.clickView();
|
||||
|
|
|
@ -29,7 +29,9 @@ public class TerminalDockModel {
|
|||
public synchronized void trackTerminal(TerminalViewInstance terminal) {
|
||||
terminalInstances.add(terminal);
|
||||
terminal.alwaysInFront();
|
||||
terminal.updatePosition(viewBounds);
|
||||
if (viewBounds != null) {
|
||||
terminal.updatePosition(viewBounds);
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void closeTerminal(TerminalViewInstance terminal) {
|
||||
|
|
|
@ -30,7 +30,7 @@ public final class WindowsTerminalViewInstance extends TerminalViewInstance {
|
|||
@Override
|
||||
public void alwaysInFront() {
|
||||
this.control.alwaysInFront();
|
||||
this.control.removeBorders();
|
||||
// this.control.removeBorders();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -13,6 +13,10 @@ public class BooleanScope implements AutoCloseable {
|
|||
this.prop = prop;
|
||||
}
|
||||
|
||||
public boolean get() {
|
||||
return prop.get();
|
||||
}
|
||||
|
||||
public static <E extends Throwable> void executeExclusive(BooleanProperty prop, FailableRunnable<E> r) throws E {
|
||||
try (var ignored = new BooleanScope(prop).exclusive().start()) {
|
||||
r.run();
|
||||
|
|
|
@ -99,12 +99,13 @@ public class DesktopShortcuts {
|
|||
}
|
||||
|
||||
public static Path create(String executable, String args, String name) throws Exception {
|
||||
var compat = OsType.getLocal().makeFileSystemCompatible(name);
|
||||
if (OsType.getLocal().equals(OsType.WINDOWS)) {
|
||||
return createWindowsShortcut(executable, args, name);
|
||||
return createWindowsShortcut(executable, args, compat);
|
||||
} else if (OsType.getLocal().equals(OsType.LINUX)) {
|
||||
return createLinuxShortcut(executable, args, name);
|
||||
return createLinuxShortcut(executable, args, compat);
|
||||
} else {
|
||||
return createMacOSShortcut(executable, args, name);
|
||||
return createMacOSShortcut(executable, args, compat);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,7 +35,13 @@ public class OpenTerminalAction implements LeafAction {
|
|||
}
|
||||
|
||||
if (AppPrefs.get().enableTerminalDocking().get() && model.getBrowserModel() instanceof BrowserSessionModel sessionModel) {
|
||||
sessionModel.splitTab(model,new BrowserTerminalDockTabModel(sessionModel, model, model.getTerminalRequests()));
|
||||
// Check if the right side is already occupied
|
||||
var existingSplit = sessionModel.getSplits().get(model);
|
||||
if (existingSplit != null && !(existingSplit instanceof BrowserTerminalDockTabModel)) {
|
||||
return;
|
||||
}
|
||||
|
||||
sessionModel.splitTab(model, new BrowserTerminalDockTabModel(sessionModel, model, model.getTerminalRequests()));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue