Skip to content

Commit

Permalink
feat: add is_focused APIs, closes #6472
Browse files Browse the repository at this point in the history
  • Loading branch information
amrbashir committed Mar 22, 2023
1 parent 2f70d8d commit 0e26188
Show file tree
Hide file tree
Showing 14 changed files with 97 additions and 6 deletions.
5 changes: 5 additions & 0 deletions .changes/is_focused-api.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'api': 'minor'
---

Add `WebviewWindow.is_focused` and `WebviewWindow.getFocusedWindow` getters.
6 changes: 6 additions & 0 deletions .changes/is_focused-runtime.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'tauri-runtime': 'minor'
'tauri-runtime-wry': 'minor'
---

Add `Window::is_focused` getter.
5 changes: 5 additions & 0 deletions .changes/is_focused-tauri.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'tauri': 'minor'
---

Add `Window::is_focused` and `Manager::get_focused_window` getters.
6 changes: 6 additions & 0 deletions core/tauri-runtime-wry/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1053,6 +1053,7 @@ pub enum WindowMessage {
IsFullscreen(Sender<bool>),
IsMinimized(Sender<bool>),
IsMaximized(Sender<bool>),
IsFocused(Sender<bool>),
IsDecorated(Sender<bool>),
IsResizable(Sender<bool>),
IsVisible(Sender<bool>),
Expand Down Expand Up @@ -1283,6 +1284,10 @@ impl<T: UserEvent> Dispatch<T> for WryDispatcher<T> {
window_getter!(self, WindowMessage::IsMaximized)
}

fn is_focused(&self) -> Result<bool> {
window_getter!(self, WindowMessage::IsFocused)
}

/// Gets the window’s current decoration state.
fn is_decorated(&self) -> Result<bool> {
window_getter!(self, WindowMessage::IsDecorated)
Expand Down Expand Up @@ -2406,6 +2411,7 @@ fn handle_user_message<T: UserEvent>(
WindowMessage::IsFullscreen(tx) => tx.send(window.fullscreen().is_some()).unwrap(),
WindowMessage::IsMinimized(tx) => tx.send(window.is_minimized()).unwrap(),
WindowMessage::IsMaximized(tx) => tx.send(window.is_maximized()).unwrap(),
WindowMessage::IsFocused(tx) => tx.send(window.is_focused()).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(),
Expand Down
3 changes: 3 additions & 0 deletions core/tauri-runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -576,6 +576,9 @@ pub trait Dispatch<T: UserEvent>: Debug + Clone + Send + Sync + Sized + 'static
/// Gets the window's current maximized state.
fn is_maximized(&self) -> Result<bool>;

/// Gets the window's current focus state.
fn is_focused(&self) -> Result<bool>;

/// Gets the window’s current decoration state.
fn is_decorated(&self) -> Result<bool>;

Expand Down
8 changes: 4 additions & 4 deletions core/tauri/scripts/bundle.global.js

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions core/tauri/src/endpoints/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ pub enum WindowManagerCmd {
IsFullscreen,
IsMinimized,
IsMaximized,
IsFocused,
IsDecorated,
IsResizable,
IsVisible,
Expand Down Expand Up @@ -253,6 +254,7 @@ impl Cmd {
WindowManagerCmd::IsFullscreen => return Ok(window.is_fullscreen()?.into()),
WindowManagerCmd::IsMinimized => return Ok(window.is_minimized()?.into()),
WindowManagerCmd::IsMaximized => return Ok(window.is_maximized()?.into()),
WindowManagerCmd::IsFocused => return Ok(window.is_focused()?.into()),
WindowManagerCmd::IsDecorated => return Ok(window.is_decorated()?.into()),
WindowManagerCmd::IsResizable => return Ok(window.is_resizable()?.into()),
WindowManagerCmd::IsVisible => return Ok(window.is_visible()?.into()),
Expand Down
4 changes: 4 additions & 0 deletions core/tauri/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -639,6 +639,10 @@ pub trait Manager<R: Runtime>: sealed::ManagerBase<R> {
fn get_window(&self, label: &str) -> Option<Window<R>> {
self.manager().get_window(label)
}
/// Fetch the focused window. Returns `None` if there is not any focused window.
fn get_focused_window(&self) -> Option<Window<R>> {
self.manager().get_focused_window()
}

/// Fetch all managed windows.
fn windows(&self) -> HashMap<String, Window<R>> {
Expand Down
8 changes: 8 additions & 0 deletions core/tauri/src/manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1367,6 +1367,14 @@ impl<R: Runtime> WindowManager<R> {
self.windows_lock().get(label).cloned()
}

pub fn get_focused_window(&self) -> Option<Window<R>> {
self
.windows_lock()
.iter()
.find(|w| w.1.is_focused().unwrap_or(false))
.map(|w| w.1.clone())
}

pub fn windows(&self) -> HashMap<String, Window<R>> {
self.windows_lock().clone()
}
Expand Down
4 changes: 4 additions & 0 deletions core/tauri/src/test/mock_runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,10 @@ impl<T: UserEvent> Dispatch<T> for MockDispatcher {
Ok(false)
}

fn is_focused(&self) -> Result<bool> {
Ok(false)
}

fn is_decorated(&self) -> Result<bool> {
Ok(false)
}
Expand Down
5 changes: 5 additions & 0 deletions core/tauri/src/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1006,6 +1006,11 @@ impl<R: Runtime> Window<R> {
self.window.dispatcher.is_maximized().map_err(Into::into)
}

/// Gets the window's current focus state.
pub fn is_focused(&self) -> crate::Result<bool> {
self.window.dispatcher.is_focused().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)
Expand Down
2 changes: 1 addition & 1 deletion examples/api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"tauri": "node ../../tooling/cli/node/tauri.js"
},
"dependencies": {
"@tauri-apps/api": "../../tooling/api/dist",
"@tauri-apps/api": "link:../../tooling/api/dist",
"@zerodevx/svelte-json-view": "0.2.1"
},
"devDependencies": {
Expand Down
2 changes: 1 addition & 1 deletion tooling/api/docs/js-api.json

Large diffs are not rendered by default.

43 changes: 43 additions & 0 deletions tooling/api/src/window.ts
Original file line number Diff line number Diff line change
Expand Up @@ -633,6 +633,33 @@ class WindowManager extends WebviewWindowHandle {
})
}

/**
* Gets the window's current focus state.
* @example
* ```typescript
* import { appWindow } from '@tauri-apps/api/window';
* const focused = await appWindow.isFocused();
* ```
*
* @returns Whether the window is focused or not.
*
* @since 1.4
* */
async isFocused(): Promise<boolean> {
return invokeTauriCommand({
__tauriModule: 'Window',
message: {
cmd: 'manage',
data: {
label: this.label,
cmd: {
type: 'isFocused'
}
}
}
})
}

/**
* Gets the window's current decorated state.
* @example
Expand Down Expand Up @@ -2029,6 +2056,22 @@ class WebviewWindow extends WindowManager {
}
return null
}

/**
* Gets the focused window.
* @example
* ```typescript
* import { WebviewWindow } from '@tauri-apps/api/window';
* const focusedWindow = WebviewWindow.getFocusedWindow();
* ```
*
* @returns The WebviewWindow instance to communicate with the webview or `undefined` if there is not any focused window.
*
* @since 1.4
*/
static getFocusedWindow(): WebviewWindow | undefined {
return getAll().find((w) => w.isFocused())
}
}

/** The WebviewWindow for the current window. */
Expand Down

0 comments on commit 0e26188

Please sign in to comment.