Various fixes

This commit is contained in:
crschnick 2024-04-12 14:32:29 +00:00
parent e1c2669349
commit a7efc737bb
6 changed files with 81 additions and 35 deletions

View file

@ -30,8 +30,15 @@ public class BrowserSessionComp extends SimpleComp {
@Override
protected Region createSimple() {
Predicate<StoreEntryWrapper> applicable = storeEntryWrapper -> {
return (storeEntryWrapper.getEntry().getStore() instanceof ShellStore)
&& storeEntryWrapper.getEntry().getValidity().isUsable();
if (!storeEntryWrapper.getEntry().getValidity().isUsable()) {
return false;
}
if (storeEntryWrapper.getEntry().getStore() instanceof ShellStore) {
return true;
}
return storeEntryWrapper.getEntry().getProvider().browserAction(model,storeEntryWrapper.getEntry(), null) != null;
};
BiConsumer<StoreEntryWrapper, BooleanProperty> action = (w, busy) -> {
ThreadHelper.runFailableAsync(() -> {
@ -43,6 +50,11 @@ public class BrowserSessionComp extends SimpleComp {
if (entry.getStore() instanceof ShellStore fileSystem) {
model.openFileSystemAsync(entry.ref(), null, busy);
}
var a = entry.getProvider().browserAction(model, entry, busy);
if (a != null) {
a.execute();
}
});
};

View file

@ -1,5 +1,6 @@
package io.xpipe.app.ext;
import io.xpipe.app.browser.session.BrowserSessionModel;
import io.xpipe.app.comp.base.MarkdownComp;
import io.xpipe.app.comp.store.StoreEntryComp;
import io.xpipe.app.comp.store.StoreEntryWrapper;
@ -15,6 +16,7 @@ import io.xpipe.core.dialog.Dialog;
import io.xpipe.core.store.DataStore;
import io.xpipe.core.util.JacksonizedValue;
import javafx.beans.binding.Bindings;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.Property;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.value.ObservableValue;
@ -44,6 +46,14 @@ public interface DataStoreProvider {
}
}
default ActionProvider.Action launchAction(DataStoreEntry store) {
return null;
}
default ActionProvider.Action browserAction(BrowserSessionModel sessionModel, DataStoreEntry store, BooleanProperty busy) {
return null;
}
default String browserDisplayName(DataStore store) {
var e = DataStorage.get().getStoreDisplayName(store);
return e.orElse("?");

View file

@ -1,6 +1,6 @@
.bookmark-list > .categories {
-fx-padding: 0.7em 1em 0.7em 1em;
-fx-padding: 1em;
-fx-background-color: -color-bg-subtle;
-fx-border-color: -color-border-default;
-fx-border-width: 0 0 1 0;

View file

@ -1,43 +1,59 @@
## Education professional licenses
There is now the possibility to use XPipe professional for free for students and faculty from accredited educational institutions (high schools, colleges, and universities). Just send an email to hello@xpipe.io with your official email address of your educational institution.
## Translations
A big new feature of XPipe 9 are translations. These were initially generated with DeepL and can be easily improved and corrected by anyone on GitHub. You can check them out in action and if there is any translation you don't like, submit a quick pull request to fix it. For instructions on how to do this, see https://github.com/xpipe-io/xpipe/lang.
You can change the language in the appearance settings.
## VNC support
This release comes with initial support for VNC. Any VNC connections are fully handled over automatic SSH tunnels and can therefore be established on top of any existing SSH connection you have in XPipe.
Note that this feature right now is in an early stage and open for feedback.
## RDP launcher
RDP is a much more complex protocol than VNC, so for now RDP support is not built-in. It is instead realized similar to the terminal support, i.e. by launching your preferred RDP client with the connection information.
Note that this feature right now is in an early stage and open for feedback.
## SSH connection improvements
- The custom SSH connections now properly apply all configuration options of your user configuration file
- The custom SSH connections now properly apply all configuration options of your user configuration file.
They also now support defining multiple host entries in place, which is useful for cases where you want to use ProxyJump hosts in place without having to define them elsewhere.
- There is now support defining multiple host entries in place in a custom SSH connection. This is useful for cases where you want to use ProxyJump hosts in place without having to define them elsewhere.
- The connection establishment has been reworked to reduce the amount of double prompts, e.g. for smartcards of 2FA, where user input is required twice.
- There's now an option to not let XPipe interact with the system. In case a system that does not run a known command shell, e.g. a router, link, or some IOT device, XPipe was previously unable to detect the shell type and errored out after some time. This option fixes this problem.
- Any value specified for the `RemoteCommand` config option will now be properly applied when launching a terminal.
## SSH X11 Forwarding
You can now enable X11 forwarding for an SSH connection.
XPipe allows you to use the WSL2 X11 capabilities for your SSH connection. The only thing you need for this is a [WSL2](https://learn.microsoft.com/en-us/windows/wsl/install) distribution installed on your local system. XPipe it will automatically choose a compatible installed distribution if possible, but you can also use another one in the settings menu.
XPipe allows you to use the WSL2 X11 capabilities on Windows for your SSH connection. The only thing you need for this is a [WSL2](https://learn.microsoft.com/en-us/windows/wsl/install) distribution installed on your local system. XPipe it will automatically choose a compatible installed distribution if possible, but you can also use another one in the settings menu.
This means that you don't need to install a separate X11 server on Windows. However, if you are using one anyway, XPipe will detect that and use the currently running X11 server.
## Keyboard control
It is a goal to be able to use XPipe only with a keyboard. This can be done either for productivity reasons or for accessibility reasons. XPipe 9 introduces improved keyboard support with new shortcuts and improved focus control for navigating with the arrow keys, tab, space, and enter.
## An improved logo
The application logo has been improved with of regards to contrast and visibility, which often was a problem on dark backgrounds. it should now stand out on any background color.
## Terminal improvements
The terminal integrations have been reworked across the board. To better show which terminals are well supported and which aren't, there is now a status indicator for every available terminal. This will show you how good the XPipe integration with each one is and which terminals are recommended to be used with XPipe.
- The kitty terminal is now fully supported with tabs on both Linux and macOS
Furthermore, the kitty terminal is now fully supported with tabs on both Linux and macOS.
## Improved keyboard control
It is a goal to be able to use XPipe only with a keyboard. This can be done either for productivity reasons or for accessibility reasons. XPipe 9 introduces improved keyboard support with new shortcuts and improved focus control for navigating with the arrow keys, tab, space, and enter.
## Improved logo
The application logo has been improved with of regards to contrast and visibility, which often was a problem on dark backgrounds. It should now stand out on any background color.
## Other changes
- Fix macOS app failing to automatically restart after update
- The window title will now reflect which edition you use
- On Windows, the window title bar will now respect the color theme
- Fix file names not being properly adjusted when transferred across file systems and some characters were not supported on the target system
- Fix macOS desktop shortcuts not having an icon associated with them
- Upgrade to GraalVM 22

View file

@ -6,6 +6,7 @@ import io.xpipe.app.storage.DataStorage;
import io.xpipe.app.storage.DataStoreEntry;
import io.xpipe.app.storage.DataStoreEntryRef;
import io.xpipe.app.util.TerminalLauncher;
import io.xpipe.core.store.DataStore;
import io.xpipe.core.store.LaunchableStore;
import io.xpipe.core.store.ShellStore;
import io.xpipe.ext.base.script.ScriptStore;
@ -21,7 +22,7 @@ public class LaunchAction implements ActionProvider {
@Override
public DataStoreCallSite<?> getDataStoreCallSite() {
return new DataStoreCallSite<LaunchableStore>() {
return new DataStoreCallSite<DataStore>() {
@Override
public boolean canLinkTo() {
@ -29,27 +30,28 @@ public class LaunchAction implements ActionProvider {
}
@Override
public ActionProvider.Action createAction(DataStoreEntryRef<LaunchableStore> store) {
public ActionProvider.Action createAction(DataStoreEntryRef<DataStore> store) {
return new Action(store.get());
}
@Override
public Class<LaunchableStore> getApplicableClass() {
return LaunchableStore.class;
public Class<DataStore> getApplicableClass() {
return DataStore.class;
}
@Override
public boolean isApplicable(DataStoreEntryRef<LaunchableStore> o) {
return o.get().getValidity().isUsable();
public boolean isApplicable(DataStoreEntryRef<DataStore> o) {
return o.get().getValidity().isUsable() && (
o.getStore() instanceof LaunchableStore || o.get().getProvider().launchAction(o.get()) != null);
}
@Override
public ObservableValue<String> getName(DataStoreEntryRef<LaunchableStore> store) {
public ObservableValue<String> getName(DataStoreEntryRef<DataStore> store) {
return AppI18n.observable("launch");
}
@Override
public String getIcon(DataStoreEntryRef<LaunchableStore> store) {
public String getIcon(DataStoreEntryRef<DataStore> store) {
return "mdi2p-play";
}
};
@ -57,21 +59,22 @@ public class LaunchAction implements ActionProvider {
@Override
public DefaultDataStoreCallSite<?> getDefaultDataStoreCallSite() {
return new DefaultDataStoreCallSite<LaunchableStore>() {
return new DefaultDataStoreCallSite<DataStore>() {
@Override
public ActionProvider.Action createAction(DataStoreEntryRef<LaunchableStore> store) {
public ActionProvider.Action createAction(DataStoreEntryRef<DataStore> store) {
return new Action(store.get());
}
@Override
public Class<LaunchableStore> getApplicableClass() {
return LaunchableStore.class;
public Class<DataStore> getApplicableClass() {
return DataStore.class;
}
@Override
public boolean isApplicable(DataStoreEntryRef<LaunchableStore> o) {
return o.get().getValidity().isUsable();
public boolean isApplicable(DataStoreEntryRef<DataStore> o) {
return o.get().getValidity().isUsable() && (
o.getStore() instanceof LaunchableStore || o.get().getProvider().launchAction(o.get()) != null);
}
};
}
@ -96,6 +99,11 @@ public class LaunchAction implements ActionProvider {
if (entry.getStore() instanceof LaunchableStore s) {
s.launch();
return;
}
if (entry.getProvider().launchAction(entry) != null) {
entry.getProvider().launchAction(entry).execute();
}
}
}

View file

@ -1 +1 @@
8.6
9.0