summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/test.yml2
-rw-r--r--examples/integration_wgpu/.gitignore2
-rw-r--r--examples/integration_wgpu/Cargo.toml13
-rw-r--r--examples/integration_wgpu/README.md17
-rw-r--r--examples/integration_wgpu/index.html21
-rw-r--r--examples/integration_wgpu/src/controls.rs19
-rw-r--r--examples/integration_wgpu/src/main.rs94
-rw-r--r--examples/integration_wgpu/src/scene.rs23
-rw-r--r--examples/integration_wgpu/src/shader/frag.spvbin352 -> 0 bytes
-rw-r--r--examples/integration_wgpu/src/shader/frag.wgsl4
-rw-r--r--examples/integration_wgpu/src/shader/vert.spvbin904 -> 0 bytes
-rw-r--r--examples/integration_wgpu/src/shader/vert.wgsl6
-rw-r--r--futures/src/runtime.rs49
-rw-r--r--futures/src/subscription/tracker.rs52
-rw-r--r--glow/src/text.rs12
-rw-r--r--native/src/subscription.rs42
-rw-r--r--wgpu/Cargo.toml1
-rw-r--r--wgpu/src/text.rs10
-rw-r--r--winit/Cargo.toml4
-rw-r--r--winit/src/application.rs106
-rw-r--r--winit/src/clipboard.rs25
21 files changed, 415 insertions, 87 deletions
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 0450f13d..433afadc 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -37,3 +37,5 @@ jobs:
run: cargo build --package tour --target wasm32-unknown-unknown
- name: Check compilation of `todos` example
run: cargo build --package todos --target wasm32-unknown-unknown
+ - name: Check compilation of `integration_wgpu` example
+ run: cargo build --package integration_wgpu --target wasm32-unknown-unknown
diff --git a/examples/integration_wgpu/.gitignore b/examples/integration_wgpu/.gitignore
new file mode 100644
index 00000000..e188dc28
--- /dev/null
+++ b/examples/integration_wgpu/.gitignore
@@ -0,0 +1,2 @@
+*.wasm
+*.js
diff --git a/examples/integration_wgpu/Cargo.toml b/examples/integration_wgpu/Cargo.toml
index a088dd1b..0ded1a56 100644
--- a/examples/integration_wgpu/Cargo.toml
+++ b/examples/integration_wgpu/Cargo.toml
@@ -7,5 +7,16 @@ publish = false
[dependencies]
iced_winit = { path = "../../winit" }
-iced_wgpu = { path = "../../wgpu", features = ["spirv"] }
+iced_wgpu = { path = "../../wgpu", features = ["webgl"] }
env_logger = "0.8"
+
+[target.'cfg(target_arch = "wasm32")'.dependencies]
+console_error_panic_hook = "0.1.7"
+console_log = "0.2.0"
+log = "0.4"
+wasm-bindgen = "0.2"
+web-sys = { version = "0.3", features = ["Element", "HtmlCanvasElement", "Window", "Document"] }
+# This dependency a little bit quirky, it is deep in the tree and without `js` feature it
+# refuses to work with `wasm32-unknown-unknown target`. Unfortunately, we need this patch
+# to make it work
+getrandom = { version = "0.2", features = ["js"] }
diff --git a/examples/integration_wgpu/README.md b/examples/integration_wgpu/README.md
index c51c2c65..faefa153 100644
--- a/examples/integration_wgpu/README.md
+++ b/examples/integration_wgpu/README.md
@@ -15,5 +15,22 @@ You can run it with `cargo run`:
cargo run --package integration
```
+### How to run this example with WebGL backend
+NOTE: Currently, WebGL backend is is still experimental, so expect bugs.
+
+```sh
+# 0. Install prerequisites
+cargo install wasm-bindgen-cli https
+# 1. cd to the current folder
+# 2. Compile wasm module
+cargo build -p integration_wgpu --target wasm32-unknown-unknown
+# 3. Invoke wasm-bindgen
+wasm-bindgen ../../target/wasm32-unknown-unknown/debug/integration_wgpu.wasm --out-dir . --target web --no-typescript
+# 4. run http server
+http
+# 5. Open 127.0.0.1:8000 in browser
+```
+
+
[`main`]: src/main.rs
[`wgpu`]: https://github.com/gfx-rs/wgpu
diff --git a/examples/integration_wgpu/index.html b/examples/integration_wgpu/index.html
new file mode 100644
index 00000000..461e67a4
--- /dev/null
+++ b/examples/integration_wgpu/index.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+ <title>Iced - wgpu + WebGL integration</title>
+ </head>
+ <body>
+ <h1>integration_wgpu</h1>
+ <canvas id="iced_canvas"></canvas>
+ <script type="module">
+ import init from "./integration_wgpu.js";
+ init('./integration_wgpu_bg.wasm');
+ </script>
+ <style>
+ body {
+ width: 100%;
+ text-align: center;
+ }
+ </style>
+ </body>
+</html>
diff --git a/examples/integration_wgpu/src/controls.rs b/examples/integration_wgpu/src/controls.rs
index 4f110bd2..9bca40eb 100644
--- a/examples/integration_wgpu/src/controls.rs
+++ b/examples/integration_wgpu/src/controls.rs
@@ -1,23 +1,29 @@
use iced_wgpu::Renderer;
use iced_winit::widget::slider::{self, Slider};
+use iced_winit::widget::text_input::{self, TextInput};
use iced_winit::widget::{Column, Row, Text};
use iced_winit::{Alignment, Color, Command, Element, Length, Program};
pub struct Controls {
background_color: Color,
+ text: String,
sliders: [slider::State; 3],
+ text_input: text_input::State,
}
#[derive(Debug, Clone)]
pub enum Message {
BackgroundColorChanged(Color),
+ TextChanged(String),
}
impl Controls {
pub fn new() -> Controls {
Controls {
background_color: Color::BLACK,
+ text: Default::default(),
sliders: Default::default(),
+ text_input: Default::default(),
}
}
@@ -35,6 +41,9 @@ impl Program for Controls {
Message::BackgroundColorChanged(color) => {
self.background_color = color;
}
+ Message::TextChanged(text) => {
+ self.text = text;
+ }
}
Command::none()
@@ -42,7 +51,9 @@ impl Program for Controls {
fn view(&mut self) -> Element<Message, Renderer> {
let [r, g, b] = &mut self.sliders;
+ let t = &mut self.text_input;
let background_color = self.background_color;
+ let text = &self.text;
let sliders = Row::new()
.width(Length::Units(500))
@@ -96,7 +107,13 @@ impl Program for Controls {
Text::new(format!("{:?}", background_color))
.size(14)
.color(Color::WHITE),
- ),
+ )
+ .push(TextInput::new(
+ t,
+ "Placeholder",
+ text,
+ move |text| Message::TextChanged(text),
+ )),
),
)
.into()
diff --git a/examples/integration_wgpu/src/main.rs b/examples/integration_wgpu/src/main.rs
index 35a69a7d..045ee0d3 100644
--- a/examples/integration_wgpu/src/main.rs
+++ b/examples/integration_wgpu/src/main.rs
@@ -14,11 +14,39 @@ use winit::{
event_loop::{ControlFlow, EventLoop},
};
+#[cfg(target_arch = "wasm32")]
+use wasm_bindgen::JsCast;
+#[cfg(target_arch = "wasm32")]
+use web_sys::HtmlCanvasElement;
+#[cfg(target_arch = "wasm32")]
+use winit::platform::web::WindowBuilderExtWebSys;
+
pub fn main() {
+ #[cfg(target_arch = "wasm32")]
+ let canvas_element = {
+ console_log::init_with_level(log::Level::Debug)
+ .expect("could not initialize logger");
+ std::panic::set_hook(Box::new(console_error_panic_hook::hook));
+
+ web_sys::window()
+ .and_then(|win| win.document())
+ .and_then(|doc| doc.get_element_by_id("iced_canvas"))
+ .and_then(|element| element.dyn_into::<HtmlCanvasElement>().ok())
+ .expect("Canvas with id `iced_canvas` is missing")
+ };
+ #[cfg(not(target_arch = "wasm32"))]
env_logger::init();
// Initialize winit
let event_loop = EventLoop::new();
+
+ #[cfg(target_arch = "wasm32")]
+ let window = winit::window::WindowBuilder::new()
+ .with_canvas(Some(canvas_element))
+ .build(&event_loop)
+ .expect("Failed to build winit window");
+
+ #[cfg(not(target_arch = "wasm32"))]
let window = winit::window::Window::new(&event_loop).unwrap();
let physical_size = window.inner_size();
@@ -31,18 +59,35 @@ pub fn main() {
let mut clipboard = Clipboard::connect(&window);
// Initialize wgpu
- let instance = wgpu::Instance::new(wgpu::Backends::PRIMARY);
+
+ #[cfg(target_arch = "wasm32")]
+ let default_backend = wgpu::Backends::GL;
+ #[cfg(not(target_arch = "wasm32"))]
+ let default_backend = wgpu::Backends::PRIMARY;
+
+ let backend =
+ wgpu::util::backend_bits_from_env().unwrap_or(default_backend);
+
+ let instance = wgpu::Instance::new(backend);
let surface = unsafe { instance.create_surface(&window) };
let (format, (mut device, queue)) = futures::executor::block_on(async {
- let adapter = instance
- .request_adapter(&wgpu::RequestAdapterOptions {
- power_preference: wgpu::PowerPreference::HighPerformance,
- compatible_surface: Some(&surface),
- force_fallback_adapter: false,
- })
- .await
- .expect("Request adapter");
+ let adapter = wgpu::util::initialize_adapter_from_env_or_default(
+ &instance,
+ backend,
+ Some(&surface),
+ )
+ .await
+ .expect("No suitable GPU adapters found on the system!");
+
+ let adapter_features = adapter.features();
+
+ #[cfg(target_arch = "wasm32")]
+ let needed_limits = wgpu::Limits::downlevel_webgl2_defaults()
+ .using_resolution(adapter.limits());
+
+ #[cfg(not(target_arch = "wasm32"))]
+ let needed_limits = wgpu::Limits::default();
(
surface
@@ -52,8 +97,8 @@ pub fn main() {
.request_device(
&wgpu::DeviceDescriptor {
label: None,
- features: wgpu::Features::empty(),
- limits: wgpu::Limits::default(),
+ features: adapter_features & wgpu::Features::default(),
+ limits: needed_limits,
},
None,
)
@@ -62,20 +107,17 @@ pub fn main() {
)
});
- {
- let size = window.inner_size();
-
- surface.configure(
- &device,
- &wgpu::SurfaceConfiguration {
- usage: wgpu::TextureUsages::RENDER_ATTACHMENT,
- format,
- width: size.width,
- height: size.height,
- present_mode: wgpu::PresentMode::Mailbox,
- },
- )
- };
+ surface.configure(
+ &device,
+ &wgpu::SurfaceConfiguration {
+ usage: wgpu::TextureUsages::RENDER_ATTACHMENT,
+ format,
+ width: physical_size.width,
+ height: physical_size.height,
+ present_mode: wgpu::PresentMode::Mailbox,
+ },
+ );
+
let mut resized = false;
// Initialize staging belt and local pool
@@ -83,7 +125,7 @@ pub fn main() {
let mut local_pool = futures::executor::LocalPool::new();
// Initialize scene and GUI controls
- let scene = Scene::new(&mut device);
+ let scene = Scene::new(&mut device, format);
let controls = Controls::new();
// Initialize iced
diff --git a/examples/integration_wgpu/src/scene.rs b/examples/integration_wgpu/src/scene.rs
index 910d8d8c..fbda1326 100644
--- a/examples/integration_wgpu/src/scene.rs
+++ b/examples/integration_wgpu/src/scene.rs
@@ -6,8 +6,11 @@ pub struct Scene {
}
impl Scene {
- pub fn new(device: &wgpu::Device) -> Scene {
- let pipeline = build_pipeline(device);
+ pub fn new(
+ device: &wgpu::Device,
+ texture_format: wgpu::TextureFormat,
+ ) -> Scene {
+ let pipeline = build_pipeline(device, texture_format);
Scene { pipeline }
}
@@ -47,12 +50,14 @@ impl Scene {
}
}
-fn build_pipeline(device: &wgpu::Device) -> wgpu::RenderPipeline {
- let vs_module =
- device.create_shader_module(&wgpu::include_spirv!("shader/vert.spv"));
-
- let fs_module =
- device.create_shader_module(&wgpu::include_spirv!("shader/frag.spv"));
+fn build_pipeline(
+ device: &wgpu::Device,
+ texture_format: wgpu::TextureFormat,
+) -> wgpu::RenderPipeline {
+ let (vs_module, fs_module) = (
+ device.create_shader_module(&wgpu::include_wgsl!("shader/vert.wgsl")),
+ device.create_shader_module(&wgpu::include_wgsl!("shader/frag.wgsl")),
+ );
let pipeline_layout =
device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
@@ -74,7 +79,7 @@ fn build_pipeline(device: &wgpu::Device) -> wgpu::RenderPipeline {
module: &fs_module,
entry_point: "main",
targets: &[wgpu::ColorTargetState {
- format: wgpu::TextureFormat::Bgra8UnormSrgb,
+ format: texture_format,
blend: Some(wgpu::BlendState {
color: wgpu::BlendComponent::REPLACE,
alpha: wgpu::BlendComponent::REPLACE,
diff --git a/examples/integration_wgpu/src/shader/frag.spv b/examples/integration_wgpu/src/shader/frag.spv
deleted file mode 100644
index 9d6807c9..00000000
--- a/examples/integration_wgpu/src/shader/frag.spv
+++ /dev/null
Binary files differ
diff --git a/examples/integration_wgpu/src/shader/frag.wgsl b/examples/integration_wgpu/src/shader/frag.wgsl
new file mode 100644
index 00000000..a6f61336
--- /dev/null
+++ b/examples/integration_wgpu/src/shader/frag.wgsl
@@ -0,0 +1,4 @@
+[[stage(fragment)]]
+fn main() -> [[location(0)]] vec4<f32> {
+ return vec4<f32>(1.0, 0.0, 0.0, 1.0);
+}
diff --git a/examples/integration_wgpu/src/shader/vert.spv b/examples/integration_wgpu/src/shader/vert.spv
deleted file mode 100644
index 0cabc9c0..00000000
--- a/examples/integration_wgpu/src/shader/vert.spv
+++ /dev/null
Binary files differ
diff --git a/examples/integration_wgpu/src/shader/vert.wgsl b/examples/integration_wgpu/src/shader/vert.wgsl
new file mode 100644
index 00000000..7ef47fb2
--- /dev/null
+++ b/examples/integration_wgpu/src/shader/vert.wgsl
@@ -0,0 +1,6 @@
+[[stage(vertex)]]
+fn main([[builtin(vertex_index)]] in_vertex_index: u32) -> [[builtin(position)]] vec4<f32> {
+ let x = f32(1 - i32(in_vertex_index)) * 0.5;
+ let y = f32(1 - i32(in_vertex_index & 1u) * 2) * 0.5;
+ return vec4<f32>(x, y, 0.0, 1.0);
+}
diff --git a/futures/src/runtime.rs b/futures/src/runtime.rs
index 7779e235..96104cd9 100644
--- a/futures/src/runtime.rs
+++ b/futures/src/runtime.rs
@@ -5,6 +5,50 @@ use crate::{subscription, Executor, Subscription};
use futures::{channel::mpsc, Sink};
use std::marker::PhantomData;
+#[cfg(not(target_arch = "wasm32"))]
+mod trait_aliases {
+ use super::*;
+
+ pub trait RuntimeMessage: Send + 'static {}
+
+ impl<T> RuntimeMessage for T where T: Send + 'static {}
+
+ pub trait RuntimeMessageSender<Message: RuntimeMessage>:
+ Sink<Message, Error = mpsc::SendError> + Unpin + Send + Clone + 'static
+ {
+ }
+
+ impl<Message: RuntimeMessage, T> RuntimeMessageSender<Message> for T where
+ T: Sink<Message, Error = mpsc::SendError>
+ + Unpin
+ + Send
+ + Clone
+ + 'static
+ {
+ }
+}
+
+#[cfg(target_arch = "wasm32")]
+mod trait_aliases {
+ use super::*;
+
+ pub trait RuntimeMessage: 'static {}
+
+ impl<T> RuntimeMessage for T where T: 'static {}
+
+ pub trait RuntimeMessageSender<Message: RuntimeMessage>:
+ Sink<Message, Error = mpsc::SendError> + Unpin + Clone + 'static
+ {
+ }
+
+ impl<Message: RuntimeMessage, T> RuntimeMessageSender<Message> for T where
+ T: Sink<Message, Error = mpsc::SendError> + Unpin + Clone + 'static
+ {
+ }
+}
+
+pub use trait_aliases::{RuntimeMessage, RuntimeMessageSender};
+
/// A batteries-included runtime of commands and subscriptions.
///
/// If you have an [`Executor`], a [`Runtime`] can be leveraged to run any
@@ -23,9 +67,8 @@ where
Hasher: std::hash::Hasher + Default,
Event: Send + Clone + 'static,
Executor: self::Executor,
- Sender:
- Sink<Message, Error = mpsc::SendError> + Unpin + Send + Clone + 'static,
- Message: Send + 'static,
+ Sender: RuntimeMessageSender<Message>,
+ Message: RuntimeMessage,
{
/// Creates a new empty [`Runtime`].
///
diff --git a/futures/src/subscription/tracker.rs b/futures/src/subscription/tracker.rs
index 3a8d4a87..01e0c105 100644
--- a/futures/src/subscription/tracker.rs
+++ b/futures/src/subscription/tracker.rs
@@ -3,6 +3,50 @@ use crate::{BoxFuture, Subscription};
use futures::{channel::mpsc, sink::Sink};
use std::{collections::HashMap, marker::PhantomData};
+#[cfg(not(target_arch = "wasm32"))]
+mod trait_aliases {
+ use super::*;
+
+ pub trait TrackerMessage: Send + 'static {}
+
+ impl<T> TrackerMessage for T where T: Send + 'static {}
+
+ pub trait TrackerMessageReceiver<Message: TrackerMessage>:
+ Sink<Message, Error = mpsc::SendError> + Unpin + Send + Clone + 'static
+ {
+ }
+
+ impl<Message: TrackerMessage, T> TrackerMessageReceiver<Message> for T where
+ T: Sink<Message, Error = mpsc::SendError>
+ + Unpin
+ + Send
+ + Clone
+ + 'static
+ {
+ }
+}
+
+#[cfg(target_arch = "wasm32")]
+mod trait_aliases {
+ use super::*;
+
+ pub trait TrackerMessage: 'static {}
+
+ impl<T> TrackerMessage for T where T: 'static {}
+
+ pub trait TrackerMessageReceiver<Message: TrackerMessage>:
+ Sink<Message, Error = mpsc::SendError> + Unpin + Clone + 'static
+ {
+ }
+
+ impl<Message: TrackerMessage, T> TrackerMessageReceiver<Message> for T where
+ T: Sink<Message, Error = mpsc::SendError> + Unpin + Clone + 'static
+ {
+ }
+}
+
+pub use trait_aliases::{TrackerMessage, TrackerMessageReceiver};
+
/// A registry of subscription streams.
///
/// If you have an application that continuously returns a [`Subscription`],
@@ -57,12 +101,8 @@ where
receiver: Receiver,
) -> Vec<BoxFuture<()>>
where
- Message: 'static + Send,
- Receiver: 'static
- + Sink<Message, Error = mpsc::SendError>
- + Unpin
- + Send
- + Clone,
+ Message: TrackerMessage,
+ Receiver: TrackerMessageReceiver<Message>,
{
use futures::{future::FutureExt, stream::StreamExt};
diff --git a/glow/src/text.rs b/glow/src/text.rs
index 3b6f3bf5..834e7902 100644
--- a/glow/src/text.rs
+++ b/glow/src/text.rs
@@ -46,11 +46,15 @@ impl Pipeline {
.expect("Load fallback font")
});
- let draw_brush =
- glow_glyph::GlyphBrushBuilder::using_font(font.clone())
+ let draw_brush_builder =
+ wgpu_glyph::GlyphBrushBuilder::using_font(font.clone())
.initial_cache_size((2048, 2048))
- .draw_cache_multithread(multithreading)
- .build(&gl);
+ .draw_cache_multithread(multithreading);
+
+ #[cfg(target_arch = "wasm32")]
+ let draw_brush_builder = draw_brush_builder.draw_cache_align_4x4(true);
+
+ let draw_brush = draw_brush_builder.build(&gl);
let measure_brush =
glyph_brush::GlyphBrushBuilder::using_font(font).build();
diff --git a/native/src/subscription.rs b/native/src/subscription.rs
index 63834654..4fb7e760 100644
--- a/native/src/subscription.rs
+++ b/native/src/subscription.rs
@@ -7,6 +7,37 @@ use iced_futures::BoxStream;
use std::hash::Hash;
+#[cfg(not(target_arch = "wasm32"))]
+mod trait_aliases {
+ use super::*;
+
+ /// Wrapper type
+ pub trait RunnerStream<Message>:
+ Stream<Item = Message> + Send + 'static
+ {
+ }
+
+ impl<T, Message> RunnerStream<Message> for T where
+ T: Stream<Item = Message> + Send + 'static
+ {
+ }
+}
+
+#[cfg(target_arch = "wasm32")]
+mod trait_aliases {
+ use super::*;
+
+ /// Wrapper type
+ pub trait RunnerStream<Message>: Stream<Item = Message> + 'static {}
+
+ impl<T, Message> RunnerStream<Message> for T where
+ T: Stream<Item = Message> + 'static
+ {
+ }
+}
+
+pub use trait_aliases::RunnerStream;
+
/// A request to listen to external events.
///
/// Besides performing async actions on demand with [`Command`], most
@@ -191,7 +222,7 @@ impl<I, S, F, Message> Recipe<Hasher, (Event, event::Status)>
where
I: Hash + 'static,
F: FnOnce(EventStream) -> S,
- S: Stream<Item = Message> + Send + 'static,
+ S: RunnerStream<Message>,
{
type Output = Message;
@@ -203,6 +234,13 @@ where
fn stream(self: Box<Self>, input: EventStream) -> BoxStream<Self::Output> {
use futures::stream::StreamExt;
- (self.spawn)(input).boxed()
+ #[cfg(target_arch = "wasm32")]
+ {
+ (self.spawn)(input).boxed_local()
+ }
+ #[cfg(not(target_arch = "wasm32"))]
+ {
+ (self.spawn)(input).boxed()
+ }
}
}
diff --git a/wgpu/Cargo.toml b/wgpu/Cargo.toml
index f4c4fa2c..46012ea7 100644
--- a/wgpu/Cargo.toml
+++ b/wgpu/Cargo.toml
@@ -25,6 +25,7 @@ canvas = ["iced_graphics/canvas"]
qr_code = ["iced_graphics/qr_code"]
default_system_font = ["iced_graphics/font-source"]
spirv = ["wgpu/spirv"]
+webgl = ["wgpu/webgl"]
[dependencies]
wgpu = "0.12"
diff --git a/wgpu/src/text.rs b/wgpu/src/text.rs
index 336696ee..45f1f2de 100644
--- a/wgpu/src/text.rs
+++ b/wgpu/src/text.rs
@@ -48,11 +48,15 @@ impl Pipeline {
.expect("Load fallback font")
});
- let draw_brush =
+ let draw_brush_builder =
wgpu_glyph::GlyphBrushBuilder::using_font(font.clone())
.initial_cache_size((2048, 2048))
- .draw_cache_multithread(multithreading)
- .build(device, format);
+ .draw_cache_multithread(multithreading);
+
+ #[cfg(target_arch = "wasm32")]
+ let draw_brush_builder = draw_brush_builder.draw_cache_align_4x4(true);
+
+ let draw_brush = draw_brush_builder.build(device, format);
let measure_brush =
glyph_brush::GlyphBrushBuilder::using_font(font).build();
diff --git a/winit/Cargo.toml b/winit/Cargo.toml
index bfcfacbc..e0581b00 100644
--- a/winit/Cargo.toml
+++ b/winit/Cargo.toml
@@ -14,7 +14,6 @@ categories = ["gui"]
debug = ["iced_native/debug"]
[dependencies]
-window_clipboard = "0.2"
log = "0.4"
thiserror = "1.0"
@@ -37,3 +36,6 @@ path = "../futures"
[target.'cfg(target_os = "windows")'.dependencies.winapi]
version = "0.3.6"
+
+[target.'cfg(not(target_arch = "wasm32"))'.dependencies.window_clipboard]
+version = "0.2"
diff --git a/winit/src/application.rs b/winit/src/application.rs
index e9212b5e..a3715b04 100644
--- a/winit/src/application.rs
+++ b/winit/src/application.rs
@@ -115,12 +115,16 @@ where
use futures::task;
use futures::Future;
use winit::event_loop::EventLoop;
+ #[cfg(not(target_arch = "wasm32"))]
use winit::platform::run_return::EventLoopExtRunReturn;
let mut debug = Debug::new();
debug.startup_started();
+ #[cfg(not(target_arch = "wasm32"))]
let mut event_loop = EventLoop::with_user_event();
+ #[cfg(target_arch = "wasm32")]
+ let event_loop = EventLoop::with_user_event();
let mut proxy = event_loop.create_proxy();
let mut runtime = {
@@ -179,41 +183,81 @@ where
let mut context = task::Context::from_waker(task::noop_waker_ref());
- event_loop.run_return(move |event, _, control_flow| {
- use winit::event_loop::ControlFlow;
+ #[cfg(not(target_arch = "wasm32"))]
+ {
+ event_loop.run_return(move |event, _, control_flow| {
+ use winit::event_loop::ControlFlow;
- if let ControlFlow::Exit = control_flow {
- return;
- }
+ if let ControlFlow::Exit = control_flow {
+ return;
+ }
- let event = match event {
- winit::event::Event::WindowEvent {
- event:
- winit::event::WindowEvent::ScaleFactorChanged {
- new_inner_size,
- ..
- },
- window_id,
- } => Some(winit::event::Event::WindowEvent {
- event: winit::event::WindowEvent::Resized(*new_inner_size),
- window_id,
- }),
- _ => event.to_static(),
- };
-
- if let Some(event) = event {
- sender.start_send(event).expect("Send event");
-
- let poll = instance.as_mut().poll(&mut context);
-
- *control_flow = match poll {
- task::Poll::Pending => ControlFlow::Wait,
- task::Poll::Ready(_) => ControlFlow::Exit,
+ let event = match event {
+ winit::event::Event::WindowEvent {
+ event:
+ winit::event::WindowEvent::ScaleFactorChanged {
+ new_inner_size,
+ ..
+ },
+ window_id,
+ } => Some(winit::event::Event::WindowEvent {
+ event: winit::event::WindowEvent::Resized(*new_inner_size),
+ window_id,
+ }),
+ _ => event.to_static(),
};
- }
- });
- Ok(())
+ if let Some(event) = event {
+ sender.start_send(event).expect("Send event");
+
+ let poll = instance.as_mut().poll(&mut context);
+
+ *control_flow = match poll {
+ task::Poll::Pending => ControlFlow::Wait,
+ task::Poll::Ready(_) => ControlFlow::Exit,
+ };
+ }
+ });
+
+ Ok(())
+ }
+
+ #[cfg(target_arch = "wasm32")]
+ {
+ event_loop.run(move |event, _, control_flow| {
+ use winit::event_loop::ControlFlow;
+
+ if let ControlFlow::Exit = control_flow {
+ return;
+ }
+
+ let event = match event {
+ winit::event::Event::WindowEvent {
+ event:
+ winit::event::WindowEvent::ScaleFactorChanged {
+ new_inner_size,
+ ..
+ },
+ window_id,
+ } => Some(winit::event::Event::WindowEvent {
+ event: winit::event::WindowEvent::Resized(*new_inner_size),
+ window_id,
+ }),
+ _ => event.to_static(),
+ };
+
+ if let Some(event) = event {
+ sender.start_send(event).expect("Send event");
+
+ let poll = instance.as_mut().poll(&mut context);
+
+ *control_flow = match poll {
+ task::Poll::Pending => ControlFlow::Wait,
+ task::Poll::Ready(_) => ControlFlow::Exit,
+ };
+ }
+ });
+ }
}
async fn run_instance<A, E, C>(
diff --git a/winit/src/clipboard.rs b/winit/src/clipboard.rs
index 1b92b28d..197d32b3 100644
--- a/winit/src/clipboard.rs
+++ b/winit/src/clipboard.rs
@@ -6,15 +6,40 @@ use crate::command::{self, Command};
/// A buffer for short-term storage and transfer within and between
/// applications.
#[allow(missing_debug_implementations)]
+#[cfg(target_arch = "wasm32")]
+pub struct Clipboard;
+
+#[cfg(target_arch = "wasm32")]
+impl Clipboard {
+ /// Creates a new [`Clipboard`] for the given window.
+ pub fn connect(_window: &winit::window::Window) -> Clipboard {
+ Clipboard
+ }
+
+ /// Reads the current content of the [`Clipboard`] as text.
+ pub fn read(&self) -> Option<String> {
+ None
+ }
+
+ /// Writes the given text contents to the [`Clipboard`].
+ pub fn write(&mut self, _contents: String) {}
+}
+
+/// A buffer for short-term storage and transfer within and between
+/// applications.
+#[allow(missing_debug_implementations)]
+#[cfg(not(target_arch = "wasm32"))]
pub struct Clipboard {
state: State,
}
+#[cfg(not(target_arch = "wasm32"))]
enum State {
Connected(window_clipboard::Clipboard),
Unavailable,
}
+#[cfg(not(target_arch = "wasm32"))]
impl Clipboard {
/// Creates a new [`Clipboard`] for the given window.
pub fn connect(window: &winit::window::Window) -> Clipboard {