refactor: crate agnostic

BREAKING CHANGE:  renamed to `window-shadows`
BREAKING CHANGE: `set_shadow` method is now a function that accepts
`impl HasRawWindowHandle` to make it agnostic so it can work
with  winit, tauri, tao and any other crate
This commit is contained in:
amrbashir
2022-03-02 09:05:49 +02:00
parent fac6f42f1c
commit a2a40e33ce
33 changed files with 141 additions and 337 deletions

View File

@@ -25,43 +25,8 @@ jobs:
toolchain: stable
override: true
- name: Get current date
if: matrix.os == 'macos-latest'
run: echo "CURRENT_DATE=$(date +'%Y-%m-%d')" >> $GITHUB_ENV
- name: Get current date
if: matrix.os == 'windows-latest'
run: echo "CURRENT_DATE=$(Get-Date -Format "yyyy-MM-dd")" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
- name: Cache cargo registry
uses: actions/cache@v2
with:
path: ~/.cargo/registry
# Add date to the cache to keep it up to date
key: ${{ matrix.os }}-${{ matrix.rust }}-cargo-registry-${{ hashFiles('**/Cargo.toml') }}-${{ env.CURRENT_DATE }}
# Restore from outdated cache for speed
restore-keys: |
${{ matrix.os }}-${{ matrix.rust }}-cargo-registry-${{ hashFiles('**/Cargo.toml') }}
- name: Cache cargo index
uses: actions/cache@v2
with:
path: ~/.cargo/git
# Add date to the cache to keep it up to date
key: ${{ matrix.os }}-${{ matrix.rust }}-cargo-index-${{ hashFiles('**/Cargo.toml') }}-${{ env.CURRENT_DATE }}
# Restore from outdated cache for speed
restore-keys: |
${{ matrix.os }}-${{ matrix.rust }}-cargo-index-${{ hashFiles('**/Cargo.toml') }}
- name: Cache cargo target
uses: actions/cache@v2
with:
path: ${{ matrix.project}}/target
# Add date to the cache to keep it up to date
key: ${{ matrix.os }}-${{ matrix.rust }}-cargo-build-target-${{ hashFiles('**/Cargo.toml') }}-${{ env.CURRENT_DATE }}
# Restore from outdated cache for speed
restore-keys: |
${{ matrix.os }}-${{ matrix.rust }}-cargo-build-target-${{ hashFiles('**/Cargo.toml') }}
- name: Run tests
uses: actions-rs/cargo@v1
with:
command: test
args: --manifest-path=Cargo.toml --release
args: --manifest-path ./Cargo.toml --release

View File

@@ -1,42 +1,34 @@
[package]
name = "tauri-plugin-shadows"
name = "window-shadows"
description = "Add native shadows to your Tauri/TAO windows."
authors = [ "Tauri Programme within The Commons Conservancy" ]
version = "0.0.0"
edition = "2021"
rust-version = "1.56"
license = "Apache-2.0 OR MIT"
readme = "README.md"
repository = "https://github.com/tauri-apps/tauri-plugin-shadows"
documentation = "https://docs.rs/tauri-plugin-shadows"
keywords = [ "vibrancy", "acrylic", "blur", "tauri", "gui", "plugin", "tauri-plugin" ]
keywords = [ "shadows", "tauri", "windowing", "gui", "plugin", "tauri-plugin" ]
categories = [ "gui" ]
[dependencies]
tao = { version = "0.6", default-features = false, features = [], optional = true }
tauri = { version = "1.0.0-rc.3", default-features = false, features = [], optional = true }
raw-window-handle = "0.4"
[target."cfg(target_os = \"windows\")".dependencies.windows]
version = "0.32.0"
features = [
"Win32_Foundation",
"Win32_Graphics_Dwm",
"Win32_UI_Controls"
]
[dev-dependencies]
tao = "0.6"
winit = "0.26"
[target."cfg(target_os = \"windows\")".dependencies]
windows-sys = { version = "0.33.0", features = [
"Win32_Foundation",
"Win32_Graphics_Dwm",
"Win32_UI_Controls"
] }
[target."cfg(target_os = \"macos\")".dependencies]
cocoa = "0.24"
objc = "0.2"
[package.metadata.docs.rs]
features = ["tauri-impl", "tao-impl"]
default-target = "x86_64-pc-windows-msvc"
targets = ["x86_64-apple-darwin", "x86_64-pc-windows-msvc"]
[features]
tao-impl = ["tao"]
tauri-impl = ["tauri"]
[[example]]
name = "tao"
required-features = ["tao-impl"]
targets = [ "x86_64-apple-darwin", "x86_64-pc-windows-msvc" ]

View File

@@ -1,6 +1,6 @@
# tauri-plugin-shadows
# window-shadows
Add native shadows to your Tauri/TAO windows.
Add native shadows to your windows.
## Platform support
@@ -13,27 +13,34 @@ Add native shadows to your Tauri/TAO windows.
Add it as a dependncy in `Cargo.toml` of your Tao/Tauri project
```toml
[dependencies]
tauri-plugin-shadows = { git = "https://github.com/tauri-apps/tauri-plugin-shadows", features = ["tauri-impl"] } # or "tao-impl" for TAO projects.
window-shadows = { git = "https://github.com/tauri-apps/window-shadows" }
```
## Cargo Features:
## Examples
- `tauri-impl`: for Tauri projects.
- `tao-impl`: for TAO projects.
## Usage
Import the `Shadows` trait and use `set_shadow()` on your window type:
- Tauri:
- with `winit`:
```rs
use winit::{event_loop::EventLoop, window::WindowBuilder};
use window_shadows::set_shadow
let event_loop = EventLoop::new();
let window = WindowBuilder::new()
.with_decorations(false)
.with_transparent(true)
.build(&event_loop)
.unwrap();
#[cfg(any(target_os = "windows", target_os = "macos"))]
set_shadow(&window, true).unwrap();
```
- with `tauri`:
```rs
use window_shadows::set_shadow
let window = app.get_window("main").unwrap();
use tauri_plugin_shadows::Shadows;
window.set_shadow(true);
#[cfg(any(target_os = "windows", target_os = "macos"))]
set_shadow(&window, true).unwrap();
```
- Tao:
```rs
let window = WindowBuilder::new().with_transparent(true).build(&event_loop).unwrap();
use tauri_plugin_shadows::Shadows;
window.set_shadow(true);
```

View File

@@ -8,7 +8,7 @@ fn main() {
event_loop::{ControlFlow, EventLoop},
window::WindowBuilder,
};
use tauri_plugin_shadows::Shadows;
use window_shadows::set_shadow;
let event_loop = EventLoop::new();
@@ -18,7 +18,8 @@ fn main() {
.build(&event_loop)
.unwrap();
window.set_shadow(true);
#[cfg(any(target_os = "windows", target_os = "macos"))]
let _ = set_shadow(&window, true);
window.set_title("A fantastic window!");

View File

@@ -1,21 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Welcome to Tauri!</title>
</head>
<style>
html,
body {
background: transparent;
}
</style>
<body>
<h1>Welcome to Tauri!</h1>
</body>
</html>

View File

@@ -1,4 +0,0 @@
# Generated by Cargo
# will have compiled files and executables
/target/
WixTools

View File

@@ -1,24 +0,0 @@
[package]
name = "app"
version = "0.1.0"
description = "A Tauri App"
authors = ["you"]
license = ""
repository = ""
default-run = "app"
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[build-dependencies]
tauri-build = { git = "https://github.com/tauri-apps/tauri", branch = "next", features = [ ] }
[dependencies]
serde_json = "1.0"
serde = { version = "1.0", features = ["derive"] }
tauri = { git = "https://github.com/tauri-apps/tauri", branch = "next", features = ["api-all"] }
tauri-plugin-shadows = { path = "../../../", features = ["tauri-impl"] }
[features]
default = [ "custom-protocol" ]
custom-protocol = [ "tauri/custom-protocol" ]

View File

@@ -1,3 +0,0 @@
fn main() {
tauri_build::build()
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 974 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 903 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

View File

@@ -1,14 +0,0 @@
max_width = 100
hard_tabs = false
tab_spaces = 2
newline_style = "Auto"
use_small_heuristics = "Default"
reorder_imports = true
reorder_modules = true
remove_nested_parens = true
edition = "2018"
merge_derives = true
use_try_shorthand = false
use_field_init_shorthand = false
force_explicit_abi = true
imports_granularity = "Crate"

View File

@@ -1,18 +0,0 @@
#![cfg_attr(
all(not(debug_assertions), target_os = "windows"),
windows_subsystem = "windows"
)]
use tauri::Manager;
use tauri_plugin_shadows::Shadows;
fn main() {
tauri::Builder::default()
.setup(|app| {
let window = app.get_window("main").unwrap();
window.set_shadow(true);
Ok(())
})
.run(tauri::generate_context!())
.expect("error while running tauri application");
}

View File

@@ -1,69 +0,0 @@
{
"package": {
"productName": "helloworld",
"version": "0.1.0"
},
"build": {
"distDir": ["../index.html"],
"devPath": ["../index.html"],
"beforeDevCommand": "",
"beforeBuildCommand": ""
},
"tauri": {
"bundle": {
"active": true,
"targets": "all",
"identifier": "com.tauri.dev",
"icon": [
"icons/32x32.png",
"icons/128x128.png",
"icons/128x128@2x.png",
"icons/icon.icns",
"icons/icon.ico"
],
"resources": [],
"externalBin": [],
"copyright": "",
"category": "DeveloperTool",
"shortDescription": "",
"longDescription": "",
"deb": {
"depends": [],
"useBootstrapper": false
},
"macOS": {
"frameworks": [],
"minimumSystemVersion": "",
"useBootstrapper": false,
"exceptionDomain": "",
"signingIdentity": null,
"entitlements": null
},
"windows": {
"certificateThumbprint": null,
"digestAlgorithm": "sha256",
"timestampUrl": ""
}
},
"updater": {
"active": false
},
"allowlist": {
"all": true
},
"windows": [
{
"title": "helloworld",
"width": 800,
"height": 600,
"resizable": true,
"fullscreen": false,
"decorations": false,
"transparent": true
}
],
"security": {
"csp": "default-src blob: data: filesystem: ws: wss: http: https: tauri: 'unsafe-eval' 'unsafe-inline' 'self' img-src: 'self'"
}
}
}

37
examples/winit.rs Normal file
View File

@@ -0,0 +1,37 @@
// Copyright 2021 Tauri Programme within The Commons Conservancy
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT
fn main() {
use window_shadows::set_shadow;
use winit::{
event::{Event, WindowEvent},
event_loop::{ControlFlow, EventLoop},
window::WindowBuilder,
};
let event_loop = EventLoop::new();
let window = WindowBuilder::new()
.with_decorations(false)
.with_transparent(true)
.build(&event_loop)
.unwrap();
#[cfg(any(target_os = "windows", target_os = "macos"))]
let _ = set_shadow(&window, true);
window.set_title("A fantastic window!");
event_loop.run(move |event, _, control_flow| {
*control_flow = ControlFlow::Wait;
match event {
Event::WindowEvent {
event: WindowEvent::CloseRequested,
..
} => *control_flow = ControlFlow::Exit,
_ => (),
}
});
}

View File

@@ -1,5 +1,3 @@
{
"extends": [
"config:base"
]
"extends": ["config:base", ":disableDependencyDashboard"]
}

View File

@@ -2,7 +2,7 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT
//! Add native shadows to your Tauri/TAO windows.
//! Add native shadows to your windows.
//!
//! # Platform support:
//!
@@ -10,69 +10,71 @@
//! - **macOS:** Yes!
//! - **Linux:** No, shadows are controlled by the compositor installed on the user system and they can enable it for your app if they want.
//!
//! # Usage:
//! # Example with [`winit`](https://docs.rs/winit)
//!
//! Import the [`Shadows`] trait and use [`Shadows::set_shadow()`] on your window type:
//! - Tauri:
//! ```ignore
//! let window = app.get_window("main").unwrap();
//! use tauri_plugin_shadows::Shadows;
//! window.set_shadow(true);
//! ```
//! - Tao:
//! ```ignore
//! let window = WindowBuilder::new().with_transparent(true).build(&event_loop).unwrap();
//! use tauri_plugin_shadows::Shadows;
//! window.set_shadow(true);
//! ```
//! ```no_run
//! # use winit::{event_loop::EventLoop, window::WindowBuilder};
//! # use window_shadows::set_shadow;
//! let event_loop = EventLoop::new();
//!
//! let window = WindowBuilder::new()
//! .with_decorations(false)
//! .with_transparent(true)
//! .build(&event_loop)
//! .unwrap();
//!
//! #[cfg(any(target_os = "windows", target_os = "macos"))]
//! set_shadow(&window, true).unwrap();
//! ```
#![allow(unused)]
/// Enables or disables the shadows for a window.
pub fn set_shadow(
window: impl raw_window_handle::HasRawWindowHandle,
enable: bool,
) -> Result<(), Error> {
match window.raw_window_handle() {
#[cfg(target_os = "macos")]
raw_window_handle::RawWindowHandle::AppKit(handle) => {
use cocoa::{appkit::NSWindow, base::id};
use objc::runtime::{NO, YES};
mod platform;
unsafe {
handle
.ns_window
.setHasShadow_(if enable { YES } else { NO });
}
#[cfg(target_os = "macos")]
use crate::platform::macos;
#[cfg(target_os = "windows")]
use crate::platform::windows;
Ok(())
}
#[cfg(target_os = "windows")]
raw_window_handle::RawWindowHandle::Win32(handle) => {
use windows_sys::Win32::{
Graphics::Dwm::DwmExtendFrameIntoClientArea, UI::Controls::MARGINS,
};
#[cfg(feature = "tauri-impl")]
use tauri::{Runtime, Window as TauriWindow};
#[cfg(all(target_os = "macos", feature = "tao-impl"))]
use tao::platform::macos::WindowExtMacOS;
#[cfg(all(target_os = "windows", feature = "tao-impl"))]
use tao::platform::windows::WindowExtWindows;
#[cfg(feature = "tao-impl")]
use tao::window::Window as TaoWindow;
pub trait Shadows {
/// Sets the shadows on the window.
///
/// ## Platform-specific
///
/// - **Windows:** shadows can't be turned off on a regular(decorated) window.
fn set_shadow(&self, shadow: bool);
}
#[cfg(feature = "tauri-impl")]
impl<R> Shadows for TauriWindow<R>
where
R: Runtime,
{
fn set_shadow(&self, shadow: bool) {
#[cfg(all(target_os = "windows", feature = "tauri-impl"))]
windows::set_shadow(windows::HWND(self.hwnd().unwrap() as _), shadow);
#[cfg(all(target_os = "macos", feature = "tauri-impl"))]
macos::set_shadow(self.ns_window().unwrap() as _, shadow);
let m = if enable { 1 } else { 0 };
let margins = MARGINS {
cxLeftWidth: m,
cxRightWidth: m,
cyTopHeight: m,
cyBottomHeight: m,
};
unsafe {
DwmExtendFrameIntoClientArea(handle.hwnd as _, &margins);
};
Ok(())
}
_ => Err(Error::UnsupportedPlatform),
}
}
#[cfg(feature = "tao-impl")]
impl Shadows for TaoWindow {
fn set_shadow(&self, shadow: bool) {
#[cfg(all(target_os = "windows", feature = "tao-impl"))]
windows::set_shadow(windows::HWND(self.hwnd() as _), shadow);
#[cfg(all(target_os = "macos", feature = "tao-impl"))]
self.set_has_shadow(shadow);
#[derive(Debug)]
pub enum Error {
UnsupportedPlatform,
}
impl std::fmt::Display for Error {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "\"set_shadow()\" is only supported on Windows and macOS")
}
}

View File

@@ -1,14 +0,0 @@
// Copyright 2021 Tauri Programme within The Commons Conservancy
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT
#![cfg(target_os = "macos")]
use cocoa::{appkit::NSWindow, base::id};
use objc::runtime::{NO, YES};
pub fn set_shadow(window: id, shadow: bool) {
unsafe {
window.setHasShadow_(if shadow { YES } else { NO });
}
}

View File

@@ -1,9 +0,0 @@
// Copyright 2021 Tauri Programme within The Commons Conservancy
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT
#[cfg(target_os = "windows")]
pub mod windows;
#[cfg(target_os = "macos")]
pub mod macos;

View File

@@ -1,22 +0,0 @@
// Copyright 2021 Tauri Programme within The Commons Conservancy
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT
#![cfg(target_os = "windows")]
pub use windows::Win32::{
Foundation::HWND, Graphics::Dwm::DwmExtendFrameIntoClientArea, UI::Controls::MARGINS,
};
pub fn set_shadow(hwnd: HWND, shadow: bool) {
let m = if shadow { 1 } else { 0 };
let margins = MARGINS {
cxLeftWidth: m,
cxRightWidth: m,
cyTopHeight: m,
cyBottomHeight: m,
};
unsafe {
DwmExtendFrameIntoClientArea(hwnd, &margins);
}
}