Procházet zdrojové kódy

Merge pull request #1925 from tauri-apps/feat/new-tao-apis

Lucas Fernandes Nogueira před 4 roky
rodič
revize
cb6c807ac8

+ 5 - 0
.changes/api-focus.md

@@ -0,0 +1,5 @@
+---
+"api": patch
+---
+
+Adds `focus?: boolean` to the WindowOptions interface.

+ 5 - 0
.changes/api-is-decorated.md

@@ -0,0 +1,5 @@
+---
+"api": patch
+---
+
+Adds `isDecorated` getter on the window API.

+ 5 - 0
.changes/api-is-resizable.md

@@ -0,0 +1,5 @@
+---
+"api": patch
+---
+
+Adds `isResizable` getter on the window API.

+ 5 - 0
.changes/api-is-visible.md

@@ -0,0 +1,5 @@
+---
+"api": patch
+---
+
+Adds `isVisible` getter on the window API.

+ 5 - 0
.changes/api-set-focus.md

@@ -0,0 +1,5 @@
+---
+"api": patch
+---
+
+Adds `setFocus` to the window API.

+ 5 - 0
.changes/api-set-skip-taskbar.md

@@ -0,0 +1,5 @@
+---
+"api": patch
+---
+
+Adds `setSkipTaskbar` to the window API.

+ 5 - 0
.changes/api-skip-taskbar.md

@@ -0,0 +1,5 @@
+---
+"api": patch
+---
+
+Adds `skipTaskbar?: boolean` to the WindowOptions interface.

+ 7 - 0
.changes/focus.md

@@ -0,0 +1,7 @@
+---
+"tauri": patch
+"tauri-runtime": patch
+"tauri-runtime-wry": patch
+---
+
+Adds `focus` API to the WindowBuilder.

+ 7 - 0
.changes/is-decorated.md

@@ -0,0 +1,7 @@
+---
+"tauri": patch
+"tauri-runtime": patch
+"tauri-runtime-wry": patch
+---
+
+Adds `is_decorated` getter on Window.

+ 7 - 0
.changes/is-resizable.md

@@ -0,0 +1,7 @@
+---
+"tauri": patch
+"tauri-runtime": patch
+"tauri-runtime-wry": patch
+---
+
+Adds `is_resizable` getter on Window.

+ 7 - 0
.changes/is-visible.md

@@ -0,0 +1,7 @@
+---
+"tauri": patch
+"tauri-runtime": patch
+"tauri-runtime-wry": patch
+---
+
+Adds `is_visible` getter on Window.

+ 7 - 0
.changes/set-focus.md

@@ -0,0 +1,7 @@
+---
+"tauri": patch
+"tauri-runtime": patch
+"tauri-runtime-wry": patch
+---
+
+Adds `set_focus` API on Window.

+ 7 - 0
.changes/set-skip-taskbar.md

@@ -0,0 +1,7 @@
+---
+"tauri": patch
+"tauri-runtime": patch
+"tauri-runtime-wry": patch
+---
+
+Adds `set_skip_taskbar` API on Window.

+ 7 - 0
.changes/skip-taskbar.md

@@ -0,0 +1,7 @@
+---
+"tauri": patch
+"tauri-runtime": patch
+"tauri-runtime-wry": patch
+---
+
+Adds `skip_taskbar` API to the WindowBuilder.

+ 3 - 0
Cargo.toml

@@ -22,6 +22,9 @@ members = [
   "examples/updater/src-tauri",
 ]
 
+[patch.crates-io]
+tao = { git = "https://github.com/tauri-apps/tao", rev = "a3f533232df25dc30998809094ed5431b449489c" }
+
 # default to small, optimized workspace release binaries
 [profile.release]
 panic = "abort"

+ 61 - 1
core/tauri-runtime-wry/src/lib.rs

@@ -248,7 +248,8 @@ impl WindowBuilder for WindowBuilderWrapper {
       .maximized(config.maximized)
       .fullscreen(config.fullscreen)
       .transparent(config.transparent)
-      .always_on_top(config.always_on_top);
+      .always_on_top(config.always_on_top)
+      .skip_taskbar(config.skip_taskbar);
 
     if let (Some(min_width), Some(min_height)) = (config.min_width, config.min_height) {
       window = window.min_inner_size(min_width, min_height);
@@ -260,6 +261,10 @@ impl WindowBuilder for WindowBuilderWrapper {
       window = window.position(x, y);
     }
 
+    if config.focus {
+      window = window.focus();
+    }
+
     window
   }
 
@@ -315,6 +320,10 @@ impl WindowBuilder for WindowBuilderWrapper {
     }
   }
 
+  fn focus(self) -> Self {
+    Self(self.0.with_focus())
+  }
+
   fn maximized(self, maximized: bool) -> Self {
     Self(self.0.with_maximized(maximized))
   }
@@ -351,6 +360,10 @@ impl WindowBuilder for WindowBuilderWrapper {
     ))
   }
 
+  fn skip_taskbar(self, skip: bool) -> Self {
+    Self(self.0.with_skip_taskbar(skip))
+  }
+
   fn has_icon(&self) -> bool {
     self.0.window.window_icon.is_some()
   }
@@ -399,6 +412,9 @@ enum WindowMessage {
   OuterSize(Sender<PhysicalSize<u32>>),
   IsFullscreen(Sender<bool>),
   IsMaximized(Sender<bool>),
+  IsDecorated(Sender<bool>),
+  IsResizable(Sender<bool>),
+  IsVisible(Sender<bool>),
   CurrentMonitor(Sender<Option<MonitorHandle>>),
   PrimaryMonitor(Sender<Option<MonitorHandle>>),
   AvailableMonitors(Sender<Vec<MonitorHandle>>),
@@ -421,7 +437,9 @@ enum WindowMessage {
   SetMaxSize(Option<Size>),
   SetPosition(Position),
   SetFullscreen(bool),
+  SetFocus,
   SetIcon(WindowIcon),
+  SetSkipTaskbar(bool),
   DragWindow,
 }
 
@@ -531,6 +549,20 @@ impl Dispatch for WryDispatcher {
     Ok(dispatcher_getter!(self, WindowMessage::IsMaximized))
   }
 
+  /// Gets the window’s current decoration state.
+  fn is_decorated(&self) -> Result<bool> {
+    Ok(dispatcher_getter!(self, WindowMessage::IsDecorated))
+  }
+
+  /// Gets the window’s current resizable state.
+  fn is_resizable(&self) -> Result<bool> {
+    Ok(dispatcher_getter!(self, WindowMessage::IsResizable))
+  }
+
+  fn is_visible(&self) -> Result<bool> {
+    Ok(dispatcher_getter!(self, WindowMessage::IsVisible))
+  }
+
   fn current_monitor(&self) -> Result<Option<Monitor>> {
     Ok(
       dispatcher_getter!(self, WindowMessage::CurrentMonitor)
@@ -751,6 +783,14 @@ impl Dispatch for WryDispatcher {
       .map_err(|_| Error::FailedToSendMessage)
   }
 
+  fn set_focus(&self) -> Result<()> {
+    self
+      .context
+      .proxy
+      .send_event(Message::Window(self.window_id, WindowMessage::SetFocus))
+      .map_err(|_| Error::FailedToSendMessage)
+  }
+
   fn set_icon(&self, icon: Icon) -> Result<()> {
     self
       .context
@@ -762,6 +802,17 @@ impl Dispatch for WryDispatcher {
       .map_err(|_| Error::FailedToSendMessage)
   }
 
+  fn set_skip_taskbar(&self, skip: bool) -> Result<()> {
+    self
+      .context
+      .proxy
+      .send_event(Message::Window(
+        self.window_id,
+        WindowMessage::SetSkipTaskbar(skip),
+      ))
+      .map_err(|_| Error::FailedToSendMessage)
+  }
+
   fn start_dragging(&self) -> Result<()> {
     self
       .context
@@ -1133,6 +1184,9 @@ fn handle_event_loop(
               .unwrap(),
             WindowMessage::IsFullscreen(tx) => tx.send(window.fullscreen().is_some()).unwrap(),
             WindowMessage::IsMaximized(tx) => tx.send(window.is_maximized()).unwrap(),
+            WindowMessage::IsDecorated(tx) => tx.send(window.is_decorated()).unwrap(),
+            WindowMessage::IsResizable(tx) => tx.send(window.is_resizable()).unwrap(),
+            WindowMessage::IsVisible(tx) => tx.send(window.is_visible()).unwrap(),
             WindowMessage::CurrentMonitor(tx) => tx.send(window.current_monitor()).unwrap(),
             WindowMessage::PrimaryMonitor(tx) => tx.send(window.primary_monitor()).unwrap(),
             WindowMessage::AvailableMonitors(tx) => {
@@ -1179,9 +1233,15 @@ fn handle_event_loop(
                 window.set_fullscreen(None)
               }
             }
+            WindowMessage::SetFocus => {
+              window.set_focus();
+            }
             WindowMessage::SetIcon(icon) => {
               window.set_window_icon(Some(icon));
             }
+            WindowMessage::SetSkipTaskbar(skip) => {
+              window.set_skip_taskbar(skip);
+            }
             WindowMessage::DragWindow => {
               let _ = window.drag_window();
             }

+ 15 - 0
core/tauri-runtime/src/lib.rs

@@ -207,6 +207,15 @@ pub trait Dispatch: Clone + Send + Sized + 'static {
   /// Gets the window's current maximized state.
   fn is_maximized(&self) -> crate::Result<bool>;
 
+  /// Gets the window’s current decoration state.
+  fn is_decorated(&self) -> crate::Result<bool>;
+
+  /// Gets the window’s current resizable state.
+  fn is_resizable(&self) -> crate::Result<bool>;
+
+  /// Gets the window's current vibility state.
+  fn is_visible(&self) -> crate::Result<bool>;
+
   /// Returns the monitor on which the window currently resides.
   ///
   /// Returns None if current monitor can't be detected.
@@ -283,9 +292,15 @@ pub trait Dispatch: Clone + Send + Sized + 'static {
   /// Updates the window fullscreen state.
   fn set_fullscreen(&self, fullscreen: bool) -> crate::Result<()>;
 
+  /// Bring the window to front and focus.
+  fn set_focus(&self) -> crate::Result<()>;
+
   /// Updates the window icon.
   fn set_icon(&self, icon: Icon) -> crate::Result<()>;
 
+  /// Whether to show the window icon in the task bar or not.
+  fn set_skip_taskbar(&self, skip: bool) -> crate::Result<()>;
+
   /// Starts dragging the window.
   fn start_dragging(&self) -> crate::Result<()>;
 

+ 6 - 0
core/tauri-runtime/src/webview.rs

@@ -124,6 +124,9 @@ pub trait WindowBuilder: WindowBuilderBase {
   /// Whether to start the window in fullscreen or not.
   fn fullscreen(self, fullscreen: bool) -> Self;
 
+  /// Whether the window will be initially hidden or focused.
+  fn focus(self) -> Self;
+
   /// Whether the window should be maximized upon creation.
   fn maximized(self, maximized: bool) -> Self;
 
@@ -143,6 +146,9 @@ pub trait WindowBuilder: WindowBuilderBase {
   /// Sets the window icon.
   fn icon(self, icon: Icon) -> crate::Result<Self>;
 
+  /// Sets whether or not the window icon should be added to the taskbar.
+  fn skip_taskbar(self, skip: bool) -> Self;
+
   /// Sets a parent to the window to be created.
   ///
   /// A child window has the WS_CHILD style and is confined to the client area of its parent window.

+ 15 - 1
core/tauri-utils/src/config.rs

@@ -69,6 +69,9 @@ pub struct WindowConfig {
   /// Whether the window starts as fullscreen or not.
   #[serde(default)]
   pub fullscreen: bool,
+  /// Whether the window will be initially hidden or focused.
+  #[serde(default)]
+  pub focus: bool,
   /// Whether the window is transparent or not.
   #[serde(default)]
   pub transparent: bool,
@@ -84,6 +87,9 @@ pub struct WindowConfig {
   /// Whether the window should always be on top of other windows.
   #[serde(default)]
   pub always_on_top: bool,
+  /// Whether or not the window icon should be added to the taskbar.
+  #[serde(default)]
+  pub skip_taskbar: bool,
 }
 
 fn default_window_label() -> String {
@@ -130,11 +136,13 @@ impl Default for WindowConfig {
       resizable: default_resizable(),
       title: default_title(),
       fullscreen: false,
+      focus: false,
       transparent: false,
       maximized: false,
       visible: default_visible(),
       decorations: default_decorations(),
       always_on_top: false,
+      skip_taskbar: false,
     }
   }
 }
@@ -630,11 +638,13 @@ mod build {
       let resizable = self.resizable;
       let title = str_lit(&self.title);
       let fullscreen = self.fullscreen;
+      let focus = self.focus;
       let transparent = self.transparent;
       let maximized = self.maximized;
       let visible = self.visible;
       let decorations = self.decorations;
       let always_on_top = self.always_on_top;
+      let skip_taskbar = self.skip_taskbar;
 
       literal_struct!(
         tokens,
@@ -652,11 +662,13 @@ mod build {
         resizable,
         title,
         fullscreen,
+        focus,
         transparent,
         maximized,
         visible,
         decorations,
-        always_on_top
+        always_on_top,
+        skip_taskbar
       );
     }
   }
@@ -899,11 +911,13 @@ mod test {
         resizable: true,
         title: String::from("Tauri App"),
         fullscreen: false,
+        focus: false,
         transparent: false,
         maximized: false,
         visible: true,
         decorations: true,
         always_on_top: false,
+        skip_taskbar: false,
       }],
       bundle: BundleConfig {
         identifier: String::from(""),

Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 0 - 0
core/tauri/scripts/bundle.js


+ 10 - 0
core/tauri/src/endpoints/window.rs

@@ -46,6 +46,9 @@ pub enum Cmd {
   OuterSize,
   IsFullscreen,
   IsMaximized,
+  IsDecorated,
+  IsResizable,
+  IsVisible,
   CurrentMonitor,
   PrimaryMonitor,
   AvailableMonitors,
@@ -67,9 +70,11 @@ pub enum Cmd {
   SetMaxSize(Option<Size>),
   SetPosition(Position),
   SetFullscreen(bool),
+  SetFocus,
   SetIcon {
     icon: IconDto,
   },
+  SetSkipTaskbar(bool),
   StartDragging,
   Print,
 }
@@ -129,6 +134,9 @@ impl Cmd {
         Self::OuterSize => return Ok(window.outer_size()?.into()),
         Self::IsFullscreen => return Ok(window.is_fullscreen()?.into()),
         Self::IsMaximized => return Ok(window.is_maximized()?.into()),
+        Self::IsDecorated => return Ok(window.is_decorated()?.into()),
+        Self::IsResizable => return Ok(window.is_resizable()?.into()),
+        Self::IsVisible => return Ok(window.is_visible()?.into()),
         Self::CurrentMonitor => return Ok(window.current_monitor()?.into()),
         Self::PrimaryMonitor => return Ok(window.primary_monitor()?.into()),
         Self::AvailableMonitors => return Ok(window.available_monitors()?.into()),
@@ -149,7 +157,9 @@ impl Cmd {
         Self::SetMaxSize(size) => window.set_max_size(size)?,
         Self::SetPosition(position) => window.set_position(position)?,
         Self::SetFullscreen(fullscreen) => window.set_fullscreen(fullscreen)?,
+        Self::SetFocus => window.set_focus()?,
         Self::SetIcon { icon } => window.set_icon(icon.into())?,
+        Self::SetSkipTaskbar(skip) => window.set_skip_taskbar(skip)?,
         Self::StartDragging => window.start_dragging()?,
         Self::Print => window.print()?,
       }

+ 29 - 0
core/tauri/src/window.rs

@@ -351,6 +351,21 @@ impl<P: Params> Window<P> {
     self.window.dispatcher.is_maximized().map_err(Into::into)
   }
 
+  /// Gets the window’s current decoration state.
+  pub fn is_decorated(&self) -> crate::Result<bool> {
+    self.window.dispatcher.is_decorated().map_err(Into::into)
+  }
+
+  /// Gets the window’s current resizable state.
+  pub fn is_resizable(&self) -> crate::Result<bool> {
+    self.window.dispatcher.is_resizable().map_err(Into::into)
+  }
+
+  /// Gets the window's current vibility state.
+  pub fn is_visible(&self) -> crate::Result<bool> {
+    self.window.dispatcher.is_visible().map_err(Into::into)
+  }
+
   /// Returns the monitor on which the window currently resides.
   ///
   /// Returns None if current monitor can't be detected.
@@ -518,11 +533,25 @@ impl<P: Params> Window<P> {
       .map_err(Into::into)
   }
 
+  /// Bring the window to front and focus.
+  pub fn set_focus(&self) -> crate::Result<()> {
+    self.window.dispatcher.set_focus().map_err(Into::into)
+  }
+
   /// Sets this window' icon.
   pub fn set_icon(&self, icon: Icon) -> crate::Result<()> {
     self.window.dispatcher.set_icon(icon).map_err(Into::into)
   }
 
+  /// Whether to show the window icon in the task bar or not.
+  pub fn set_skip_taskbar(&self, skip: bool) -> crate::Result<()> {
+    self
+      .window
+      .dispatcher
+      .set_skip_taskbar(skip)
+      .map_err(Into::into)
+  }
+
   /// Starts dragging the window.
   pub fn start_dragging(&self) -> crate::Result<()> {
     self.window.dispatcher.start_dragging().map_err(Into::into)

+ 14 - 15
examples/api/src-tauri/src/main.rs

@@ -41,24 +41,23 @@ fn main() {
       SystemTrayMenuItem::Custom(CustomMenuItem::new("toggle".into(), "Toggle")),
       SystemTrayMenuItem::Custom(CustomMenuItem::new("new".into(), "New window")),
     ])
-    .on_system_tray_event(|app, event| {
-      match event.menu_item_id().as_str() {
-        "toggle" => {
-          let window = app.get_window("main").unwrap();
-          // TODO: window.is_visible API
+    .on_system_tray_event(|app, event| match event.menu_item_id().as_str() {
+      "toggle" => {
+        let window = app.get_window("main").unwrap();
+        if window.is_visible().unwrap() {
           window.hide().unwrap();
+        } else {
+          window.show().unwrap();
         }
-        "new" => app
-          .create_window(
-            "new".into(),
-            WindowUrl::App("index.html".into()),
-            |window_builder, webview_attributes| {
-              (window_builder.title("Tauri"), webview_attributes)
-            },
-          )
-          .unwrap(),
-        _ => {}
       }
+      "new" => app
+        .create_window(
+          "new".into(),
+          WindowUrl::App("index.html".into()),
+          |window_builder, webview_attributes| (window_builder.title("Tauri"), webview_attributes),
+        )
+        .unwrap(),
+      _ => {}
     })
     .invoke_handler(tauri::generate_handler![
       cmd::log_operation,

+ 64 - 0
tooling/api/src/window.ts

@@ -362,6 +362,36 @@ class WindowManager {
     })
   }
 
+  /** Gets the window's current decorated state. */
+  async isDecorated(): Promise<boolean> {
+    return invokeTauriCommand({
+      __tauriModule: 'Window',
+      message: {
+        cmd: 'isDecorated'
+      }
+    })
+  }
+
+  /** Gets the window's current resizable state. */
+  async isResizable(): Promise<boolean> {
+    return invokeTauriCommand({
+      __tauriModule: 'Window',
+      message: {
+        cmd: 'isResizable'
+      }
+    })
+  }
+
+  /** Gets the window's current visible state. */
+  async isVisible(): Promise<boolean> {
+    return invokeTauriCommand({
+      __tauriModule: 'Window',
+      message: {
+        cmd: 'isVisible'
+      }
+    })
+  }
+
   // Setters
 
   /**
@@ -683,6 +713,20 @@ class WindowManager {
     })
   }
 
+  /**
+   * Bring the window to front and focus.
+   *
+   * @returns A promise indicating the success or failure of the operation.
+   */
+  async setFocus(): Promise<void> {
+    return invokeTauriCommand({
+      __tauriModule: 'Window',
+      message: {
+        cmd: 'setFocus'
+      }
+    })
+  }
+
   /**
    * Sets the window icon.
    *
@@ -701,6 +745,22 @@ class WindowManager {
     })
   }
 
+  /**
+   * Whether to show the window icon in the task bar or not.
+   *
+   * @param skip true to hide window icon, false to show it.
+   * @returns A promise indicating the success or failure of the operation.
+   */
+  async setSkipTaskbar(skip: boolean): Promise<void> {
+    return invokeTauriCommand({
+      __tauriModule: 'Window',
+      message: {
+        cmd: 'setSkipTaskbar',
+        data: skip
+      }
+    })
+  }
+
   /**
    * Starts dragging the window.
    *
@@ -747,6 +807,8 @@ interface WindowOptions {
   title?: string
   /** Whether the window is in fullscreen mode or not. */
   fullscreen?: boolean
+  /** Whether the window will be initially hidden or focused. */
+  focus?: boolean
   /** Whether the window is transparent or not. */
   transparent?: boolean
   /** Whether the window should be maximized upon creation or not. */
@@ -757,6 +819,8 @@ interface WindowOptions {
   decorations?: boolean
   /** Whether the window should always be on top of other windows or not. */
   alwaysOnTop?: boolean
+  /** Whether or not the window icon should be added to the taskbar. */
+  skipTaskbar?: boolean
 }
 
 /**

Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 140 - 480
tooling/api/yarn.lock


+ 4 - 1
tooling/cli.js/test/jest/__tests__/template.spec.js

@@ -25,7 +25,10 @@ describe('[CLI] cli.js template', () => {
 
     const manifestPath = resolve(tauriFixturePath, 'Cargo.toml')
     const manifestFile = readFileSync(manifestPath).toString()
-    writeFileSync(manifestPath, `workspace = { }\n\n${manifestFile}`)
+    writeFileSync(
+      manifestPath,
+      `workspace = { }\n[patch.crates-io]\ntao = { git = "https://github.com/tauri-apps/tao", rev = "a3f533232df25dc30998809094ed5431b449489c" }\n\n${manifestFile}`
+    )
 
     const { promise: buildPromise } = await build({
       config: {

+ 4 - 18
tooling/cli.rs/Cargo.lock

@@ -629,20 +629,6 @@ version = "0.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
 
-[[package]]
-name = "handlebars"
-version = "3.5.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4498fc115fa7d34de968184e473529abb40eeb6be8bc5f7faba3d08c316cb3e3"
-dependencies = [
- "log",
- "pest",
- "pest_derive",
- "quick-error",
- "serde",
- "serde_json",
-]
-
 [[package]]
 name = "handlebars"
 version = "4.0.0"
@@ -1904,7 +1890,7 @@ dependencies = [
  "chrono",
  "dirs-next",
  "glob",
- "handlebars 3.5.5",
+ "handlebars",
  "hex",
  "icns",
  "image",
@@ -1935,7 +1921,7 @@ dependencies = [
  "clap",
  "colored",
  "encode_unicode",
- "handlebars 4.0.0",
+ "handlebars",
  "heck",
  "include_dir",
  "json-patch",
@@ -2419,9 +2405,9 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
 
 [[package]]
 name = "winreg"
-version = "0.8.0"
+version = "0.9.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d107f8c6e916235c4c01cabb3e8acf7bea8ef6a63ca2e7fa0527c049badfc48c"
+checksum = "16cdb3898397cf7f624c294948669beafaeebc5577d5ec53d0afb76633593597"
 dependencies = [
  "winapi 0.3.9",
 ]

Některé soubory nejsou zobrazeny, neboť je v těchto rozdílových datech změněno mnoho souborů