Release Vulpes OS 2.7-preview.24

This commit is contained in:
OverSu 2026-11-04 12:52:20 +01:00
commit 97ef99f827
135 changed files with 7717 additions and 2524 deletions

View file

@ -17,7 +17,7 @@ public final class MainActivity extends Activity {
void updateTrackingProtection(boolean enabled) {
if (gaia != null) gaia.getSettings().setUseTrackingProtection(enabled);
if (web != null) web.getSettings().setUseTrackingProtection(enabled);
for (GeckoSession session : webTabs) session.getSettings().setUseTrackingProtection(enabled);
}
private VulpesApplication app;
@ -26,8 +26,12 @@ public final class MainActivity extends Activity {
private LinearLayout root, webPanel;
private TextView notice;
private EditText address;
private Button tabsButton;
private Button home;
private boolean webBack;
private final java.util.List<GeckoSession> webTabs = new ArrayList<>();
private final java.util.List<String> webUrls = new ArrayList<>();
private final java.util.List<Boolean> webCanGoBack = new ArrayList<>();
private boolean resumed, recoverGaia, recoverWeb;
private long lastCrash;
private int crashCount;
@ -95,6 +99,13 @@ public final class MainActivity extends Activity {
address.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_URI);
address.setTextSize(14);
nav.addView(address, new LinearLayout.LayoutParams(0, -1, 1));
tabsButton = new Button(this);
tabsButton.setText("▢ 0");
tabsButton.setContentDescription("Onglets");
tabsButton.setMinWidth(0);
tabsButton.setPadding(dp(8), 0, dp(8), 0);
nav.addView(tabsButton, new LinearLayout.LayoutParams(dp(64), -1));
tabsButton.setOnClickListener(v -> showBrowserTabs());
address.setOnEditorActionListener((v, id, event) -> {
String url = address.getText().toString().trim();
openBrowser(url.contains("://") ? url : "https://" + url);
@ -221,56 +232,99 @@ public final class MainActivity extends Activity {
} catch (Exception e) {
return;
}
if (web == null) {
web = new GeckoSession(new GeckoSessionSettings.Builder()
.useTrackingProtection(app.trackingProtection).build());
web.setContentDelegate(content);
web.setPromptDelegate(prompts);
web.setPermissionDelegate(permissions);
web.setNavigationDelegate(
new GeckoSession.NavigationDelegate() {
@Override
public void onCanGoBack(GeckoSession s, boolean can) {
webBack = can;
}
@Override
public void onLocationChange(
GeckoSession s,
String url,
java.util.List<GeckoSession.PermissionDelegate.ContentPermission> permissions,
Boolean gesture
) {
address.setText(url);
}
@Override
public GeckoResult<AllowOrDeny> onLoadRequest(GeckoSession s, LoadRequest r) {
return GeckoResult.fromValue(
(r.uri.startsWith("https://") || r.uri.startsWith("http://")) && !isGaia(r.uri)
? AllowOrDeny.ALLOW
: AllowOrDeny.DENY
);
}
@Override
public GeckoResult<GeckoSession> onNewSession(GeckoSession s, String uri) {
openBrowser(uri);
return GeckoResult.fromValue(null);
}
}
);
web.open(app.runtime);
webView.setSession(web);
if (web == null) newBrowserTab(url);
else {
int index = webTabs.indexOf(web);
if (index >= 0) webUrls.set(index, url);
web.loadUri(url);
updateTabsButton();
}
gaiaView.setVisibility(View.GONE);
webPanel.setVisibility(View.VISIBLE);
setHomeSurface(false);
address.setText(url);
web.loadUri(url);
syncActive();
}
private GeckoSession createBrowserSession() {
GeckoSession session = new GeckoSession(new GeckoSessionSettings.Builder()
.useTrackingProtection(app.trackingProtection).build());
session.setContentDelegate(content);
session.setPromptDelegate(prompts);
session.setPermissionDelegate(permissions);
session.setNavigationDelegate(new GeckoSession.NavigationDelegate() {
@Override public void onCanGoBack(GeckoSession s, boolean can) {
int index = webTabs.indexOf(s);
if (index < 0) return;
webCanGoBack.set(index, can);
if (s == web) webBack = can;
}
@Override public void onLocationChange(GeckoSession s, String url,
java.util.List<GeckoSession.PermissionDelegate.ContentPermission> permissions,
Boolean gesture) {
int index = webTabs.indexOf(s);
if (index >= 0) webUrls.set(index, url);
if (s == web) address.setText(url);
updateTabsButton();
}
@Override public GeckoResult<AllowOrDeny> onLoadRequest(GeckoSession s, LoadRequest r) {
return GeckoResult.fromValue(
(r.uri.startsWith("https://") || r.uri.startsWith("http://")) && !isGaia(r.uri)
? AllowOrDeny.ALLOW : AllowOrDeny.DENY);
}
@Override public GeckoResult<GeckoSession> onNewSession(GeckoSession s, String uri) {
newBrowserTab(uri);
return GeckoResult.fromValue(null);
}
});
session.open(app.runtime);
return session;
}
private void newBrowserTab(String url) {
if (web != null) web.setActive(false);
web = createBrowserSession();
webTabs.add(web);
webUrls.add(url);
webCanGoBack.add(false);
webView.setSession(web);
webBack = false;
address.setText(url);
web.loadUri(url);
updateTabsButton();
syncActive();
}
private void showBrowserTabs() {
java.util.List<String> choices = new ArrayList<>();
choices.add("+ Nouvel onglet");
for (int i = 0; i < webUrls.size(); i++) {
String url = webUrls.get(i);
choices.add((webTabs.get(i) == web ? "✓ " : "") +
(url == null || url.isEmpty() ? "Nouvel onglet" : url));
}
new AlertDialog.Builder(this).setTitle("Onglets")
.setItems(choices.toArray(new String[0]), (dialog, which) -> {
if (which == 0) newBrowserTab("https://duckduckgo.com/");
else selectBrowserTab(which - 1);
}).setNegativeButton("Fermer", null).show();
}
private void selectBrowserTab(int index) {
if (index < 0 || index >= webTabs.size()) return;
if (web != null) web.setActive(false);
web = webTabs.get(index);
webView.setSession(web);
webBack = webCanGoBack.get(index);
address.setText(webUrls.get(index));
updateTabsButton();
syncActive();
}
private void updateTabsButton() {
if (tabsButton != null) tabsButton.setText("▢ " + webTabs.size());
}
void setHomeSurface(boolean visible) {
runOnUiThread(() -> {
boolean overlay = visible && webPanel.getVisibility() != View.VISIBLE;
@ -334,7 +388,8 @@ public final class MainActivity extends Activity {
private void syncActive() {
boolean browsing = webPanel != null && webPanel.getVisibility() == View.VISIBLE;
if (gaia != null && gaia.isOpen()) gaia.setActive(resumed && !browsing);
if (web != null && web.isOpen()) web.setActive(resumed && browsing);
for (GeckoSession session : webTabs)
if (session.isOpen()) session.setActive(resumed && browsing && session == web);
}
private void recover(GeckoSession session, boolean crashed) {
@ -442,7 +497,7 @@ public final class MainActivity extends Activity {
app.gaiaSession = null;
}
}
if (web != null) web.close();
for (GeckoSession session : webTabs) session.close();
if (fileResult != null) {
fileResult.complete(filePrompt.dismiss());
fileResult = null;