Ver código fonte

Feat: `always_on_top` CLI Setting (#2715)

* feat: always_on_top cli setting

* revision: add user message for configuring settings
Miles Murgaw 11 meses atrás
pai
commit
810f8bbfb8

+ 20 - 0
packages/cli-config/src/config.rs

@@ -89,6 +89,9 @@ pub struct DioxusConfig {
     #[serde(default)]
     pub web: WebConfig,
 
+    #[serde(default)]
+    pub desktop: DesktopConfig,
+
     #[serde(default)]
     pub bundle: BundleConfig,
 }
@@ -129,6 +132,7 @@ impl Default for DioxusConfig {
                 pre_compress: true,
                 wasm_opt: Default::default(),
             },
+            desktop: DesktopConfig::default(),
             bundle: BundleConfig {
                 identifier: Some(format!("io.github.{name}")),
                 publisher: Some(name),
@@ -206,6 +210,22 @@ impl Default for WebConfig {
     }
 }
 
+/// Represents configuration items for the desktop platform.
+#[derive(Debug, Clone, Serialize, Deserialize)]
+pub struct DesktopConfig {
+    /// Describes whether a debug-mode desktop app should be always-on-top.
+    #[serde(default)]
+    pub always_on_top: bool,
+}
+
+impl Default for DesktopConfig {
+    fn default() -> Self {
+        Self {
+            always_on_top: true,
+        }
+    }
+}
+
 /// The wasm-opt configuration
 #[derive(Debug, Clone, Serialize, Deserialize, Default)]
 pub struct WasmOptConfig {

+ 26 - 2
packages/cli/src/cli/config.rs

@@ -30,21 +30,42 @@ pub enum Config {
     SetGlobal { setting: Setting, value: Value },
 }
 
-#[derive(Debug, Clone, Deserialize, clap::ValueEnum)]
+#[derive(Debug, Clone, Copy, Deserialize, clap::ValueEnum)]
 pub enum Setting {
     /// Set the value of the always-hot-reload setting.
     AlwaysHotReload,
     /// Set the value of the always-open-browser setting.
     AlwaysOpenBrowser,
+    /// Set the value of the always-on-top desktop setting.
+    AlwaysOnTop,
+}
+
+impl Display for Setting {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        match self {
+            Self::AlwaysHotReload => write!(f, "always_hot_reload"),
+            Self::AlwaysOpenBrowser => write!(f, "always_open_browser"),
+            Self::AlwaysOnTop => write!(f, "always_on_top"),
+        }
+    }
 }
 
 // NOTE: Unsure of an alternative to get the desired behavior with clap, if it exists.
-#[derive(Debug, Clone, Deserialize, clap::ValueEnum)]
+#[derive(Debug, Clone, Copy, Deserialize, clap::ValueEnum)]
 pub enum Value {
     True,
     False,
 }
 
+impl Display for Value {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        match self {
+            Self::True => write!(f, "true"),
+            Self::False => write!(f, "false"),
+        }
+    }
+}
+
 impl From<Value> for bool {
     fn from(value: Value) -> Self {
         match value {
@@ -90,11 +111,14 @@ impl Config {
                 file.write_all(content.as_bytes())?;
                 tracing::info!("🚩 Create custom html file done.");
             }
+            // Handle configuration of global CLI settings.
             Config::SetGlobal { setting, value } => {
                 CliSettings::modify_settings(|settings| match setting {
                     Setting::AlwaysHotReload => settings.always_hot_reload = Some(value.into()),
                     Setting::AlwaysOpenBrowser => settings.always_open_browser = Some(value.into()),
+                    Setting::AlwaysOnTop => settings.always_on_top = Some(value.into()),
                 })?;
+                tracing::info!("🚩 CLI setting `{setting}` has been set to `{value}`")
             }
         }
         Ok(())

+ 11 - 2
packages/cli/src/cli/serve.rs

@@ -16,14 +16,18 @@ pub struct ServeArguments {
     #[clap(flatten)]
     pub address: AddressArguments,
 
-    /// Open the app in the default browser [default: false - unless project or global settings are set]
+    /// Open the app in the default browser [default: true - unless cli settings are set]
     #[arg(long, default_missing_value="true", num_args=0..=1)]
     pub open: Option<bool>,
 
-    /// Enable full hot reloading for the app [default: true - unless project or global settings are set]
+    /// Enable full hot reloading for the app [default: true - unless cli settings are set]
     #[clap(long, group = "release-incompatible")]
     pub hot_reload: Option<bool>,
 
+    /// Configure always-on-top for desktop apps [default: true - unless cli settings are set]
+    #[clap(long, default_missing_value = "true")]
+    pub always_on_top: Option<bool>,
+
     /// Set cross-origin-policy to same-origin [default: false]
     #[clap(name = "cross-origin-policy")]
     #[clap(long)]
@@ -64,6 +68,11 @@ impl Serve {
         if self.server_arguments.open.is_none() {
             self.server_arguments.open = Some(settings.always_open_browser.unwrap_or_default());
         }
+        if self.server_arguments.always_on_top.is_none() {
+            self.server_arguments.always_on_top = Some(settings.always_on_top.unwrap_or(true))
+        }
+        crate_config.dioxus_config.desktop.always_on_top =
+            self.server_arguments.always_on_top.unwrap_or(true);
 
         // Resolve the build arguments
         self.build_arguments.resolve(crate_config)?;

+ 2 - 0
packages/cli/src/settings.rs

@@ -23,6 +23,8 @@ pub struct CliSettings {
     pub always_hot_reload: Option<bool>,
     /// Describes whether the CLI should always open the browser for Web targets.
     pub always_open_browser: Option<bool>,
+    /// Describes whether desktop apps in development will be pinned always-on-top.
+    pub always_on_top: Option<bool>,
 }
 
 impl CliSettings {

+ 15 - 9
packages/desktop/src/config.rs

@@ -49,15 +49,21 @@ impl Config {
     /// Initializes a new `WindowBuilder` with default values.
     #[inline]
     pub fn new() -> Self {
-        let window: WindowBuilder = WindowBuilder::new()
-            .with_title(
-                dioxus_cli_config::CURRENT_CONFIG
-                    .as_ref()
-                    .map(|c| c.application.name.clone())
-                    .unwrap_or("Dioxus App".to_string()),
-            )
-            // During development we want the window to be on top so we can see it while we work
-            .with_always_on_top(cfg!(debug_assertions));
+        let dioxus_config = dioxus_cli_config::CURRENT_CONFIG.as_ref();
+
+        let mut window: WindowBuilder = WindowBuilder::new().with_title(
+            dioxus_config
+                .map(|c| c.application.name.clone())
+                .unwrap_or("Dioxus App".to_string()),
+        );
+
+        // During development we want the window to be on top so we can see it while we work
+        let always_on_top = dioxus_config
+            .map(|c| c.desktop.always_on_top)
+            .unwrap_or(true);
+        if cfg!(debug_assertions) {
+            window = window.with_always_on_top(always_on_top);
+        }
 
         Self {
             window,