Skip to content

Commit

Permalink
🪟🫷Raw Window Handle Support
Browse files Browse the repository at this point in the history
  • Loading branch information
nickhudkins committed Sep 12, 2024
1 parent 872011e commit a844057
Show file tree
Hide file tree
Showing 7 changed files with 152 additions and 14 deletions.
121 changes: 108 additions & 13 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,12 @@ notan_text = { workspace = true, optional = true }
notan_audio = { workspace = true, optional = true }
notan_extra = { workspace = true, optional = true }
notan_random = { workspace = true, optional = true }
raw-window-handle = "0.5.2"

[target.'cfg(target_os = "macos")'.dependencies]
cocoa = "0.26.0"
objc = "0.2.7"


[features]
default = ["backend", "log", "draw", "random", "glsl-to-spirv"]
Expand Down
1 change: 1 addition & 0 deletions crates/notan_app/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ serde = { workspace = true, optional = true }
downcast-rs = "1.2.0"
indexmap = "2.0.2"
futures = "0.3.28"
raw-window-handle = "0.5.2"

[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
platter2 = "0.1.6"
Expand Down
3 changes: 3 additions & 0 deletions crates/notan_app/src/backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use downcast_rs::{impl_downcast, Downcast};
use futures::prelude::*;
use futures::Future;
use notan_graphics::DeviceBackend;
use raw_window_handle::RawWindowHandle;

#[cfg(feature = "audio")]
use notan_audio::AudioBackend;
Expand Down Expand Up @@ -213,4 +214,6 @@ pub trait WindowBackend {

/// Returns if touch as mouse is enabled
fn touch_as_mouse(&self) -> bool;

fn raw_window_handle(&self) -> Option<RawWindowHandle>;
}
5 changes: 5 additions & 0 deletions crates/notan_app/src/empty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use crate::{
App, Backend, BackendSystem, CursorIcon, EventIterator, FrameState, InitializeFn, WindowBackend,
};
use notan_graphics::prelude::*;
use raw_window_handle::RawWindowHandle;
use std::any::Any;

#[cfg(feature = "audio")]
Expand Down Expand Up @@ -137,6 +138,10 @@ impl WindowBackend for EmptyWindowBackend {
fn touch_as_mouse(&self) -> bool {
self.touch_as_mouse
}

fn raw_window_handle(&self) -> Option<RawWindowHandle> {
None
}
}

#[derive(Default)]
Expand Down
6 changes: 6 additions & 0 deletions crates/notan_winit/src/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use std::path::PathBuf;
use crate::gl_manager::GlManager;
use notan_app::WindowConfig;
use notan_app::{CursorIcon, WindowBackend};
use raw_window_handle::{HasRawWindowHandle, RawWindowHandle};
use winit::dpi::{LogicalPosition, LogicalSize, PhysicalPosition};
use winit::event_loop::EventLoop;
use winit::window::Fullscreen::Borderless;
Expand All @@ -26,6 +27,11 @@ pub struct WinitWindowBackend {
}

impl WindowBackend for WinitWindowBackend {

fn raw_window_handle(&self) -> Option<RawWindowHandle> {
Some(self.window().raw_window_handle())
}

fn capture_cursor(&self) -> bool {
self.captured
}
Expand Down
24 changes: 23 additions & 1 deletion examples/window_transparent.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,30 @@ fn main() -> Result<(), String> {
.build()
}

fn draw(gfx: &mut Graphics) {
fn draw(app: &mut App, gfx: &mut Graphics) {
let mut draw = gfx.create_draw();
let raw_window_handle = app.window().raw_window_handle().unwrap();

#[cfg(target_os = "macos")]
unsafe {
use cocoa::appkit::NSWindow;
use cocoa::base::NO;
use objc::runtime::Object;
use objc::{msg_send, sel, sel_impl};
use raw_window_handle::{AppKitWindowHandle, RawWindowHandle};

match raw_window_handle {
RawWindowHandle::AppKit(AppKitWindowHandle { ns_view, .. }) => {
// I told you it was unsafe.
let ns_view: *mut Object = ns_view as *mut Object;
let ns_window: *mut Object = msg_send![ns_view, window];

// NOTE: remove shadow to stop artifacts in transparent window
ns_window.setHasShadow_(NO);
}
_ => (),
}
}
draw.clear(Color::TRANSPARENT);
draw.triangle((400.0, 100.0), (100.0, 500.0), (700.0, 500.0))
.color(Color::MAGENTA);
Expand Down

0 comments on commit a844057

Please sign in to comment.