Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

desktop: Move open URLs mode from launch options to preferences #18233

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
18 changes: 0 additions & 18 deletions core/src/backend/navigator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,24 +56,6 @@ pub enum SocketMode {
Ask,
}

/// The handling mode of links opening a new website.
#[cfg_attr(feature = "clap", derive(clap::ValueEnum))]
#[derive(Clone, Copy, Debug, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum OpenURLMode {
/// Allow all links to open a new website.
#[cfg_attr(feature = "serde", serde(rename = "allow"))]
Allow,

/// A confirmation dialog opens with every link trying to open a new website.
#[cfg_attr(feature = "serde", serde(rename = "confirm"))]
Confirm,

/// Deny all links to open a new website.
#[cfg_attr(feature = "serde", serde(rename = "deny"))]
Deny,
}

impl NavigationMethod {
/// Convert an SWF method enum into a NavigationMethod.
pub fn from_send_vars_method(s: SendVarsMethod) -> Option<Self> {
Expand Down
17 changes: 14 additions & 3 deletions desktop/src/backends/navigator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use tokio::sync::oneshot;
use url::Url;
use winit::event_loop::EventLoopProxy;

use crate::cli::FilesystemAccessMode;
use crate::cli::{FilesystemAccessMode, OpenUrlMode};
use crate::custom_event::RuffleEvent;
use crate::gui::dialogs::filesystem_access_dialog::{
FilesystemAccessDialogConfiguration, FilesystemAccessDialogResult,
Expand All @@ -18,6 +18,7 @@ use crate::gui::dialogs::network_access_dialog::{
NetworkAccessDialogConfiguration, NetworkAccessDialogResult,
};
use crate::gui::DialogDescriptor;
use crate::preferences::GlobalPreferences;
use crate::util::open_url;

// TODO Make this more generic, maybe a manager?
Expand Down Expand Up @@ -74,6 +75,8 @@ impl PathAllowList {

#[derive(Clone)]
pub struct DesktopNavigatorInterface {
preferences: GlobalPreferences,

// Arc + Mutex due to macOS
event_loop: Arc<Mutex<EventLoopProxy<RuffleEvent>>>,

Expand All @@ -84,11 +87,13 @@ pub struct DesktopNavigatorInterface {

impl DesktopNavigatorInterface {
pub fn new(
preferences: GlobalPreferences,
event_loop: EventLoopProxy<RuffleEvent>,
movie_path: Option<PathBuf>,
filesystem_access_mode: FilesystemAccessMode,
) -> Self {
Self {
preferences,
event_loop: Arc::new(Mutex::new(event_loop)),
allow_list: PathAllowList::new(movie_path),
filesystem_access_mode,
Expand All @@ -114,8 +119,14 @@ impl DesktopNavigatorInterface {
}

impl NavigatorInterface for DesktopNavigatorInterface {
fn navigate_to_website(&self, url: Url, ask: bool) {
if !ask {
fn navigate_to_website(&self, url: Url) {
let open_url_mode = self.preferences.open_url_mode();
if open_url_mode == OpenUrlMode::Deny {
tracing::warn!("SWF tried to open a website, but opening a website is not allowed");
return;
}

if open_url_mode == OpenUrlMode::Allow {
open_url(&url);
return;
}
Expand Down
10 changes: 4 additions & 6 deletions desktop/src/backends/ui.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::cli::OpenUrlMode;
use crate::custom_event::RuffleEvent;
use crate::gui::dialogs::message_dialog::MessageDialogConfiguration;
use crate::gui::{DialogDescriptor, FilePicker, LocalizableText};
Expand All @@ -9,7 +10,6 @@ use fontdb::Family;
use rfd::{
AsyncFileDialog, FileHandle, MessageButtons, MessageDialog, MessageDialogResult, MessageLevel,
};
use ruffle_core::backend::navigator::OpenURLMode;
use ruffle_core::backend::ui::{
DialogLoaderError, DialogResultFuture, FileDialogResult, FileFilter, FontDefinition,
FullscreenError, LanguageIdentifier, MouseCursor, UiBackend,
Expand Down Expand Up @@ -123,7 +123,6 @@ pub struct DesktopUiBackend {
clipboard: Clipboard,
preferences: GlobalPreferences,
preferred_cursor: MouseCursor,
open_url_mode: OpenURLMode,
font_database: Rc<fontdb::Database>,
file_picker: FilePicker,
}
Expand All @@ -132,7 +131,6 @@ impl DesktopUiBackend {
pub fn new(
window: Arc<Window>,
event_loop: EventLoopProxy<RuffleEvent>,
open_url_mode: OpenURLMode,
font_database: Rc<fontdb::Database>,
preferences: GlobalPreferences,
file_picker: FilePicker,
Expand All @@ -153,7 +151,6 @@ impl DesktopUiBackend {
clipboard,
preferences,
preferred_cursor: MouseCursor::Arrow,
open_url_mode,
font_database,
file_picker,
})
Expand Down Expand Up @@ -235,7 +232,8 @@ impl UiBackend for DesktopUiBackend {
return;
}

if self.open_url_mode == OpenURLMode::Confirm {
let open_url_mode = self.preferences.open_url_mode();
if open_url_mode == OpenUrlMode::Confirm {
let message = format!("The SWF file wants to open the website {}", url);
// TODO: Add a checkbox with a GUI toolkit
let confirm = MessageDialog::new()
Expand All @@ -249,7 +247,7 @@ impl UiBackend for DesktopUiBackend {
tracing::info!("SWF tried to open a website, but the user declined the request");
return;
}
} else if self.open_url_mode == OpenURLMode::Deny {
} else if open_url_mode == OpenUrlMode::Deny {
tracing::warn!("SWF tried to open a website, but opening a website is not allowed");
return;
}
Expand Down
36 changes: 33 additions & 3 deletions desktop/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use crate::preferences::storage::StorageBackend;
use crate::RUFFLE_VERSION;
use anyhow::{anyhow, Error};
use clap::{Parser, ValueEnum};
use ruffle_core::backend::navigator::{OpenURLMode, SocketMode};
use ruffle_core::backend::navigator::SocketMode;
use ruffle_core::config::Letterbox;
use ruffle_core::events::{GamepadButton, KeyCode};
use ruffle_core::{LoadBehavior, PlayerRuntime, StageAlign, StageScaleMode};
Expand Down Expand Up @@ -192,8 +192,8 @@ pub struct Opt {
pub frame_rate: Option<f64>,

/// The handling mode of links opening a new website.
#[clap(long, default_value = "allow")]
pub open_url_mode: OpenURLMode,
#[clap(long)]
pub open_url_mode: Option<OpenUrlMode>,

/// How to handle non-interactive filesystem access.
#[clap(long, default_value = "ask")]
Expand Down Expand Up @@ -342,6 +342,36 @@ impl FromStr for GameModePreference {
}
}

#[derive(Default, Debug, Copy, Clone, PartialEq, Eq, clap::ValueEnum)]
pub enum OpenUrlMode {
#[default]
Confirm,
Allow,
Deny,
}

impl OpenUrlMode {
pub fn as_str(&self) -> Option<&'static str> {
match self {
OpenUrlMode::Confirm => None,
OpenUrlMode::Allow => Some("allow"),
OpenUrlMode::Deny => Some("deny"),
}
}
}

impl FromStr for OpenUrlMode {
type Err = ();

fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"allow" => Ok(OpenUrlMode::Allow),
"deny" => Ok(OpenUrlMode::Deny),
_ => Err(()),
}
}
}

// TODO The following enum exists in order to preserve
// the behavior of mapping gamepad buttons,
// We should probably do something smarter here.
Expand Down
29 changes: 1 addition & 28 deletions desktop/src/gui/dialogs/open_dialog.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use crate::player::LaunchOptions;
use egui::{
emath, Align2, Button, Checkbox, ComboBox, Grid, Layout, Slider, TextEdit, Ui, Widget, Window,
};
use ruffle_core::backend::navigator::{OpenURLMode, SocketMode};
use ruffle_core::backend::navigator::SocketMode;
use ruffle_core::config::Letterbox;
use ruffle_core::{LoadBehavior, PlayerRuntime, StageAlign, StageScaleMode};
use ruffle_render::quality::StageQuality;
Expand Down Expand Up @@ -405,33 +405,6 @@ impl OpenDialog {
.ui(ui, &mut self.options.tcp_connections, locale);
ui.end_row();

// TODO: This should probably be a global setting somewhere, not per load
ui.label(text(locale, "open-url-mode"));
ComboBox::from_id_salt("open-file-advanced-options-open-url-mode")
.selected_text(match self.options.open_url_mode {
OpenURLMode::Allow => text(locale, "open-url-mode-allow"),
OpenURLMode::Confirm => text(locale, "open-url-mode-confirm"),
OpenURLMode::Deny => text(locale, "open-url-mode-deny"),
})
.show_ui(ui, |ui| {
ui.selectable_value(
&mut self.options.open_url_mode,
OpenURLMode::Allow,
text(locale, "open-url-mode-allow"),
);
ui.selectable_value(
&mut self.options.open_url_mode,
OpenURLMode::Confirm,
text(locale, "open-url-mode-confirm"),
);
ui.selectable_value(
&mut self.options.open_url_mode,
OpenURLMode::Deny,
text(locale, "open-url-mode-deny"),
);
});
ui.end_row();

ui.label(text(locale, "load-behavior"));
self.load_behavior
.ui(ui, &mut self.options.player.load_behavior, locale);
Expand Down
64 changes: 63 additions & 1 deletion desktop/src/gui/dialogs/preferences_dialog.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::cli::GameModePreference;
use crate::cli::{GameModePreference, OpenUrlMode};
use crate::gui::{available_languages, optional_text, text, ThemePreference};
use crate::log::FilenamePattern;
use crate::preferences::{storage::StorageBackend, GlobalPreferences};
Expand Down Expand Up @@ -47,6 +47,10 @@ pub struct PreferencesDialog {

theme_preference: ThemePreference,
theme_preference_changed: bool,

open_url_mode: OpenUrlMode,
open_url_mode_readonly: bool,
open_url_mode_changed: bool,
}

impl PreferencesDialog {
Expand Down Expand Up @@ -101,6 +105,10 @@ impl PreferencesDialog {
theme_preference: preferences.theme_preference(),
theme_preference_changed: false,

open_url_mode: preferences.open_url_mode(),
open_url_mode_readonly: preferences.cli.open_url_mode.is_some(),
open_url_mode_changed: false,

preferences,
}
}
Expand All @@ -127,6 +135,8 @@ impl PreferencesDialog {
self.show_gamemode_preferences(locale, &locked_text, ui);
}

self.show_open_url_mode_preferences(locale, &locked_text, ui);

self.show_language_preferences(locale, ui);

self.show_theme_preferences(locale, ui);
Expand Down Expand Up @@ -342,6 +352,44 @@ impl PreferencesDialog {
ui.end_row();
}

fn show_open_url_mode_preferences(
&mut self,
locale: &LanguageIdentifier,
locked_text: &str,
ui: &mut Ui,
) {
ui.label(text(locale, "open-url-mode"));
if self.open_url_mode_readonly {
ui.label(open_url_mode_preference_name(locale, self.open_url_mode))
.on_hover_text(locked_text);
} else {
let previous: OpenUrlMode = self.open_url_mode;
ComboBox::from_id_salt("open-url-mode")
.selected_text(open_url_mode_preference_name(locale, self.open_url_mode))
.show_ui(ui, |ui| {
ui.selectable_value(
&mut self.open_url_mode,
OpenUrlMode::Confirm,
open_url_mode_preference_name(locale, OpenUrlMode::Confirm),
);
ui.selectable_value(
&mut self.open_url_mode,
OpenUrlMode::Allow,
open_url_mode_preference_name(locale, OpenUrlMode::Allow),
);
ui.selectable_value(
&mut self.open_url_mode,
OpenUrlMode::Deny,
open_url_mode_preference_name(locale, OpenUrlMode::Deny),
);
});
if self.open_url_mode != previous {
self.open_url_mode_changed = true;
}
}
ui.end_row();
}

fn show_audio_preferences(&mut self, locale: &LanguageIdentifier, ui: &mut Ui) {
ui.label(text(locale, "audio-output-device"));

Expand Down Expand Up @@ -515,6 +563,9 @@ impl PreferencesDialog {
if self.gamemode_preference_changed {
preferences.set_gamemode_preference(self.gamemode_preference);
}
if self.open_url_mode_changed {
preferences.set_open_url_mode(self.open_url_mode);
}
}) {
// [NA] TODO: Better error handling... everywhere in desktop, really
tracing::error!("Could not save preferences: {e}");
Expand Down Expand Up @@ -577,6 +628,17 @@ fn gamemode_preference_tooltip(
})
}

fn open_url_mode_preference_name(
locale: &LanguageIdentifier,
open_url_mode: OpenUrlMode,
) -> Cow<str> {
match open_url_mode {
OpenUrlMode::Allow => text(locale, "open-url-mode-allow"),
OpenUrlMode::Confirm => text(locale, "open-url-mode-confirm"),
OpenUrlMode::Deny => text(locale, "open-url-mode-deny"),
}
}

fn filename_pattern_name(locale: &LanguageIdentifier, pattern: FilenamePattern) -> Cow<str> {
match pattern {
FilenamePattern::SingleFile => text(locale, "log-filename-pattern-single-file"),
Expand Down
Loading