Various fixes

This commit is contained in:
crschnick 2024-11-13 15:00:49 +00:00
parent 1483439345
commit eaf8d075fa
18 changed files with 62 additions and 49 deletions

View file

@ -263,26 +263,32 @@ public class BrowserSessionTabsComp extends SimpleComp {
var cm = ContextMenuHelper.create();
if (tabModel.isCloseable()) {
var unsplit = ContextMenuHelper.item(LabelGraphic.none(), AppI18n.get("unpinTab"));
unsplit.visibleProperty()
var unpin = ContextMenuHelper.item(LabelGraphic.none(), AppI18n.get("unpinTab"));
unpin.visibleProperty()
.bind(PlatformThread.sync(Bindings.createBooleanBinding(
() -> {
return model.getGlobalPinnedTab().getValue() != null
&& model.getGlobalPinnedTab().getValue().equals(tabModel);
},
model.getGlobalPinnedTab())));
unsplit.setOnAction(event -> {
unpin.setOnAction(event -> {
model.unpinTab(tabModel);
event.consume();
});
cm.getItems().add(unsplit);
cm.getItems().add(unpin);
var split = ContextMenuHelper.item(LabelGraphic.none(), AppI18n.get("pinTab"));
split.setOnAction(event -> {
var pin = ContextMenuHelper.item(LabelGraphic.none(), AppI18n.get("pinTab"));
pin.visibleProperty()
.bind(PlatformThread.sync(Bindings.createBooleanBinding(
() -> {
return model.getGlobalPinnedTab().getValue() == null;
},
model.getGlobalPinnedTab())));
pin.setOnAction(event -> {
model.pinTab(tabModel);
event.consume();
});
cm.getItems().add(split);
cm.getItems().add(pin);
}
var select = ContextMenuHelper.item(LabelGraphic.none(), AppI18n.get("selectTab"));
@ -364,7 +370,9 @@ public class BrowserSessionTabsComp extends SimpleComp {
private Tab createTab(TabPane tabs, BrowserSessionTab tabModel) {
var tab = new Tab();
tab.setContextMenu(createContextMenu(tabs, tab, tabModel));
if (tabModel.isCloseable()) {
tab.setContextMenu(createContextMenu(tabs, tab, tabModel));
}
tab.setClosable(tabModel.isCloseable());
// Prevent closing while busy

View file

@ -88,7 +88,7 @@ public class ModifiedStage extends Stage {
NativeWinWindowControl.DmwaWindowAttribute.DWMWA_USE_IMMERSIVE_DARK_MODE.get(),
AppPrefs.get().theme.getValue().isDark());
boolean seamlessFrame;
if (AppPrefs.get().performanceMode().get() || !mergeFrame()) {
if (AppPrefs.get().performanceMode().get() || !mergeFrame() || AppMainWindow.getInstance() == null || stage != AppMainWindow.getInstance().getStage()) {
seamlessFrame = false;
} else {
seamlessFrame = ctrl.setWindowBackdrop(NativeWinWindowControl.DwmSystemBackDropType.MICA_ALT);

View file

@ -60,6 +60,6 @@ public class ShellSession extends Session {
}
public void stop() throws Exception {
shellControl.close();
shellControl.shutdown();
}
}

View file

@ -77,7 +77,7 @@ public class TerminalErrorHandler extends GuiErrorHandlerBase implements ErrorHa
var rel = XPipeDistributionType.get()
.getUpdateHandler()
.refreshUpdateCheck(
false, !AppPrefs.get().automaticallyUpdate().get());
false, false);
if (rel != null && rel.isUpdate()) {
var update = AppWindowHelper.showBlockingAlert(alert -> {
alert.setAlertType(Alert.AlertType.INFORMATION);

View file

@ -16,9 +16,10 @@ public class WorkspacesCategory extends AppPrefsCategory {
@Override
protected Comp<?> create() {
return new OptionsBuilder()
.addTitle(LicenseProvider.get().getFeature("workspaces").suffixObservable("manageWorkspaces"))
.addTitle("manageWorkspaces")
.sub(new OptionsBuilder()
.nameAndDescription("workspaceAdd")
.licenseRequirement("workspaces")
.addComp(new ButtonComp(AppI18n.observable("addWorkspace"), WorkspaceCreationAlert::showAsync)))
.disable(!LicenseProvider.get().getFeature("workspaces").isSupported())
.buildComp();

View file

@ -154,7 +154,6 @@ public class TerminalDockModel {
}
this.viewBounds = new Rect(x, y, w, h);
TrackEvent.withTrace("Terminal view resized").tag("rect", viewBounds).handle();
updatePositions();
}

View file

@ -41,7 +41,8 @@ public class GitHubUpdater extends UpdateHandler {
lastUpdateCheckResult.getValue().getReleaseUrl(),
downloadFile.get(),
changelog,
lastUpdateCheckResult.getValue().getAssetType());
lastUpdateCheckResult.getValue().getAssetType(),
lastUpdateCheckResult.getValue().isSecurityOnly());
preparedUpdate.setValue(rel);
}
@ -93,7 +94,8 @@ public class GitHubUpdater extends UpdateHandler {
ghAsset.get().getBrowserDownloadUrl(),
assetType,
Instant.now(),
isUpdate));
isUpdate,
securityOnly));
return lastUpdateCheckResult.getValue();
}
}

View file

@ -48,7 +48,8 @@ public class PortableUpdater extends UpdateHandler {
null,
null,
Instant.now(),
isUpdate));
isUpdate,
securityOnly));
return lastUpdateCheckResult.getValue();
}
}

View file

@ -23,7 +23,7 @@ public class UpdateAvailableAlert {
}
// Check whether we still have the latest version prepared
uh.refreshUpdateCheckSilent(false, !AppPrefs.get().automaticallyUpdate().get());
uh.refreshUpdateCheckSilent(false, uh.getPreparedUpdate().getValue().isSecurityOnly());
if (uh.getPreparedUpdate().getValue() == null) {
return;
}

View file

@ -191,7 +191,8 @@ public abstract class UpdateHandler {
lastUpdateCheckResult.getValue().getReleaseUrl(),
null,
changelog,
lastUpdateCheckResult.getValue().getAssetType());
lastUpdateCheckResult.getValue().getAssetType(),
lastUpdateCheckResult.getValue().isSecurityOnly());
preparedUpdate.setValue(rel);
}
@ -214,7 +215,7 @@ public abstract class UpdateHandler {
var available = XPipeDistributionType.get()
.getUpdateHandler()
.refreshUpdateCheckSilent(
false, !AppPrefs.get().automaticallyUpdate().get());
false, preparedUpdate.getValue().isSecurityOnly());
if (preparedUpdate.getValue() == null) {
return;
}
@ -267,6 +268,7 @@ public abstract class UpdateHandler {
AppInstaller.InstallerAssetType assetType;
Instant checkTime;
boolean isUpdate;
boolean securityOnly;
}
@Value
@ -280,5 +282,6 @@ public abstract class UpdateHandler {
Path file;
String body;
AppInstaller.InstallerAssetType assetType;
boolean securityOnly;
}
}

View file

@ -4,6 +4,8 @@ import io.xpipe.app.issue.ErrorEvent;
import io.xpipe.app.prefs.AppPrefs;
import io.xpipe.core.process.CommandBuilder;
import io.xpipe.core.process.OsType;
import io.xpipe.core.process.ShellDialect;
import io.xpipe.core.process.ShellDialects;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
@ -56,7 +58,11 @@ public class FileOpener {
public static void openInDefaultApplication(String localFile) {
try (var pc = LocalShell.getShell().start()) {
if (pc.getOsType().equals(OsType.WINDOWS)) {
pc.executeSimpleCommand("start \"\" \"" + localFile + "\"");
if (pc.getShellDialect() == ShellDialects.POWERSHELL) {
pc.command(CommandBuilder.of().add("Invoke-Item").addFile(localFile)).execute();
} else {
pc.executeSimpleCommand("start \"\" \"" + localFile + "\"");
}
} else if (pc.getOsType().equals(OsType.LINUX)) {
pc.executeSimpleCommand("xdg-open \"" + localFile + "\"");
} else {

View file

@ -6,19 +6,17 @@ public class Hyperlinks {
public static final String DOUBLE_PROMPT = "https://docs.xpipe.io/two-step-connections";
public static final String AGENT_SETUP = "https://docs.xpipe.io/ssh-agent-socket";
public static final String GITHUB = "https://github.com/xpipe-io/xpipe";
public static final String GITHUB_PTB = "https://github.com/xpipe-io/xpipe-ptb";
public static final String GITHUB = "https://github.com/xpipe-io/xpipe?ref=xpipe.app";
public static final String GITHUB_PTB = "https://github.com/xpipe-io/xpipe-ptb?ref=xpipe.app";
public static final String PRIVACY = "https://docs.xpipe.io/privacy-policy";
public static final String EULA = "https://docs.xpipe.io/end-user-license-agreement";
public static final String SECURITY = "https://docs.xpipe.io/security";
public static final String TRANSLATE = "https://github.com/xpipe-io/xpipe/tree/master/lang";
public static final String TRANSLATE = "https://github.com/xpipe-io/xpipe/tree/master/lang?ref=xpipe.app";
public static final String DISCORD = "https://discord.gg/8y89vS8cRb";
public static final String GITHUB_WEBTOP = "https://github.com/xpipe-io/xpipe-webtop";
public static final String SELFHST_ICONS = "https://github.com/selfhst/icons";
public static final String GITHUB_WEBTOP = "https://github.com/xpipe-io/xpipe-webtop?ref=xpipe.app";
public static final String SELFHST_ICONS = "https://github.com/selfhst/icons?ref=xpipe.app";
public static final String SLACK =
"https://join.slack.com/t/XPipe/shared_invite/zt-1awjq0t5j-5i4UjNJfNe1VN4b_auu6Cg";
public static final String PRODUCT_HUNT =
"https://www.producthunt.com/posts/xpipe?embed=true&utm_source=badge-featured&utm_medium=badge&utm_souce=badge-xpipe";
static final String[] browsers = {
"xdg-open", "google-chrome", "firefox", "opera", "konqueror", "mozilla", "gnome-open", "open"

View file

@ -2,6 +2,7 @@ package io.xpipe.app.util;
import io.xpipe.app.core.AppI18n;
import javafx.beans.binding.Bindings;
import javafx.beans.value.ObservableValue;
import java.util.Optional;
@ -10,15 +11,10 @@ public interface LicensedFeature {
Optional<String> getDescriptionSuffix();
public default ObservableValue<String> suffixObservable(ObservableValue<String> s) {
return s.map(s2 ->
getDescriptionSuffix().map(suffix -> s2 + " (" + suffix + "+)").orElse(s2));
}
ObservableValue<String> suffixObservable(ObservableValue<String> s);
public default ObservableValue<String> suffixObservable(String key) {
return AppI18n.observable(key).map(s -> getDescriptionSuffix()
.map(suffix -> s + " (" + suffix + "+)")
.orElse(s));
return suffixObservable(AppI18n.observable(key));
}
public default String suffix(String s) {

View file

@ -143,7 +143,7 @@ public class OptionsBuilder {
null,
null,
null,
Comp.of(() -> new Label(title.getValue())).styleClass("title-header")));
new LabelComp(title).styleClass("title-header")));
return this;
}

View file

@ -16,6 +16,6 @@
.dialog-comp .buttons {
-fx-padding: 10;
-fx-border-color: -color-border-default;
-fx-background-color: -color-bg-inset;
-fx-background-color: -color-bg-overlay;
-fx-border-width: 1 0 0 0;
}

View file

@ -14,7 +14,7 @@
}
.prefs-container > .title-header {
-fx-padding: 2em 0 -1em 0;
-fx-padding: 4em 0 -1em 0;
-fx-font-weight: BOLD;
-fx-font-size: 1.5em;
}

View file

@ -112,7 +112,7 @@
-fx-font-size: 14px;
}
.root { -color-bg-default-transparent: #0d1117d2; }
.root { -color-bg-default-transparent: #10141ad2; }
.root .table-view {
-color-cell-bg-odd: derive(-color-bg-subtle, -35%);

View file

@ -1,9 +1,8 @@
## VMs
- There is now support for KVM/QEMU virtual machines that can be accessed via the libvirt CLI tools `virsh`. This includes support for other driver URLs as well aside from KVM and QEMU.
- You can now override a VM IP if you're using an advanced networking setup where the default IP detection is not suitable.
- There is now support for KVM/QEMU virtual machines that can be accessed via the libvirt CLI tools `virsh`. This includes support for other driver URLs as well aside from KVM and QEMU. This integration is available starting from the homelab plan
- You can now override a VM IP if you're using an advanced networking setup where the default IP detection is not suitable
- Fix remote VM SSH connections not being able to use the keys and identities from the local system
- VM states are now properly updated and shown
- There is now a new restart button for containers and VMs
## File browser
@ -13,18 +12,18 @@
- The previous system history tab is now always shown
- You can now change the default download location for the move to downloads button
## Terminal tacking
## Shell sessions
Many improvements have been implemented for reusability of shell sessions running in the background. Whenever you access a system or a parent system, XPipe will connect to it just as before but keep this session open in the background for some time, under the assumption that you will typically perform multiple actions shortly afterward. This will improve the speed of many actions and also results in less authentication prompts when you are using something like 2FA.
## Terminals
- Closing a terminal tab/window while the session is loading will now cancel the loading process in XPipe as well
- A newly opened terminal will now regain focus after any password prompt was entered in xpipe
## Shell session caching
There were made improvements for reusability of shell sessions running in the background. Whenever you access a system or a parent system, XPipe will connect to it just as before but keep this session open in the background for some time, under the assumption that users will typically perform multiple actions afterward. This will improve the speed of many actions and also results in less authentication prompts when you are using something like 2FA.
## Security updates
There's now a new mechanism in place for checking for security updates separately from the normal update check. This is important going forward, to be able to act quickly when any security patch is published, so that all users have the possibility to get notified even if they don't follow announcements on the GitHub repo or on Discord. You can also disable this functionality if you want.
There's now a new mechanism in place for checking for security updates separately from the normal update check. This is important going forward, to be able to act quickly when any security patch is published, so that all users have the possibility to get notified even if they don't follow announcements on the GitHub repo or on Discord. You can also disable this functionality in the settings if you want.
## Other
@ -36,12 +35,12 @@ There's now a new mechanism in place for checking for security updates separatel
## Fixes
- Fix Proxmox detection not working when not logging in as root
- Fix tunnels not closing properly when having to be closed forcefully
- Fix vmware integration failing when files other than .vmx were in the VM directories
- Fix Tabby not launching properly on Windows
- Fix SSH and docker issues with home assistant systems
- Fix Proxmox detection not working when not logging in as root
- Fix system dark mode changes not being applied if they were changed while XPipe was not running
- Fix git readme not showing connections in nested children categories
- Fix style issues with the mocha theme
- Fix color contrast for some themes
- Fix system dark mode changes not being applied if they were changed while XPipe was not running