Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wasm support #759

Merged
merged 45 commits into from
Apr 15, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
19c186f
Add wasm backend + fix std::time dep
elrnv Mar 25, 2020
30d66ba
Disable simple logger on wasm
elrnv Mar 25, 2020
cfb3627
Fix resizing in wasm backends
elrnv Mar 25, 2020
fbce712
Added scrolling support + fixed hidpi handling
elrnv Mar 25, 2020
999ef45
Use explicit lifetime in StrOrChar
elrnv Mar 26, 2020
8ee237f
Added keyboard support on wasm
elrnv Mar 26, 2020
659e136
Fix browser zooming issue for web backend
elrnv Mar 26, 2020
4658a17
Fix a typo causing the web build to break
elrnv Mar 27, 2020
439b319
Format with cargo fmt
elrnv Mar 27, 2020
85f400b
Prevent the browser from going back on backspace
elrnv Mar 28, 2020
3316120
Fix key text + require console_log + adjust style
elrnv Apr 3, 2020
e2d8e00
Run rustfmt on stepper.rs
elrnv Apr 3, 2020
204230c
Fix up console_log dependency
elrnv Apr 4, 2020
c191012
Add wasm build to ci
elrnv Apr 5, 2020
844cbc2
Update ci by running wasm-pack explicitly
elrnv Apr 5, 2020
a37c3b4
Add druid/examples/wasm to workspace toml
elrnv Apr 5, 2020
2d67cd7
Address format and clippy warnings
elrnv Apr 5, 2020
481b796
Add wasm32 tests for druid & druid-shell in ci.yml
elrnv Apr 5, 2020
9b2a3d8
Fix build.rs in druid-wasm-examples
elrnv Apr 5, 2020
fbd6073
Fix windows build for druid-wasm-examples
elrnv Apr 5, 2020
23424af
Added simple_logger dep for wasm
elrnv Apr 5, 2020
510a60a
Remove invald cfg feature guard
elrnv Apr 5, 2020
e7e257c
Unwrap from examples that return result
elrnv Apr 5, 2020
cfe5153
Run rustfmt on build.rs for druid-wasm-examples
elrnv Apr 5, 2020
4b6150d
Address clippy concerns in druid examples
elrnv Apr 5, 2020
5609e38
Fix the build script for wasm examples
elrnv Apr 5, 2020
5ed32cb
Add .gitignore to wasm examples + fix clippy bugs
elrnv Apr 5, 2020
ad3c7e8
Update README.md formatting in druid wasm examples
elrnv Apr 5, 2020
d101869
Revert accidental change to build.rs
elrnv Apr 5, 2020
8d05b09
Fix examples for wasm
elrnv Apr 10, 2020
ea81ffe
Fix x11 keycodes StrOrChar conversion
elrnv Apr 10, 2020
78b4631
Rustfmt on recent changes to examples
elrnv Apr 10, 2020
3cd4144
Fix clippy warnings -- small structs passed by ref
elrnv Apr 12, 2020
1dbb4e9
Fix wasm build for multiwin example
elrnv Apr 12, 2020
2102f82
Add --no-run to `cargo test` for wasm targets
elrnv Apr 12, 2020
5021017
Do not build the unit test module for wasm32
elrnv Apr 12, 2020
a143692
Install necessary deps in wasm CI for macos/ubuntu
elrnv Apr 12, 2020
e0949ff
Add warnings for unimplemented file ops in web backend
elrnv Apr 13, 2020
0df38af
Remove windows specific comment from web/window.rs
elrnv Apr 13, 2020
5f64d4b
Ignore automatically generated html files in wasm example
elrnv Apr 13, 2020
ee88c7f
Remove unused dialog module from web backend
elrnv Apr 13, 2020
ea79c84
Remove TODO for adding to app state in web backend
elrnv Apr 13, 2020
e072555
Rework the generated examples in the wasm example
elrnv Apr 13, 2020
d0bc9df
Update Cargo.lock
elrnv Apr 13, 2020
3a528fa
Rename switch example js entry point for wasm build
elrnv Apr 14, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 59 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -239,3 +239,62 @@ jobs:
with:
command: rustc
args: --manifest-path=druid-shell/Cargo.toml --features=x11 -- -D warnings

test-stable-wasm:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [macOS-latest, windows-2019, ubuntu-latest]

name: cargo test stable (wasm32)
steps:
- uses: actions/checkout@v2

- name: install cairo
run: brew install cairo
if: contains(matrix.os, 'mac')

- name: install libgtk-dev
run: |
sudo apt update
sudo apt install libgtk-3-dev
if: contains(matrix.os, 'ubuntu')

- name: install deps
run: cargo install wasm-pack

- name: install stable toolchain
uses: actions-rs/toolchain@v1
with:
toolchain: stable
target: wasm32-unknown-unknown
components: clippy
profile: minimal
override: true

- name: cargo clippy (wasm32)
uses: actions-rs/cargo@v1
with:
command: clippy
args: --all --target wasm32-unknown-unknown -- -D warnings

- name: cargo test compile druid-shell (wasm32)
uses: actions-rs/cargo@v1
with:
command: test
args: --manifest-path=druid-shell/Cargo.toml --no-run --target wasm32-unknown-unknown

- name: cargo test compile druid (wasm32)
uses: actions-rs/cargo@v1
with:
command: test
args: --manifest-path=druid/Cargo.toml --no-run --target wasm32-unknown-unknown

- name: wasm-pack build examples
run: wasm-pack build --target web druid/examples/wasm

- name: Run rustc -D warnings in druid/examples/wasm
uses: actions-rs/cargo@v1
with:
command: rustc
args: --manifest-path=druid/examples/wasm/Cargo.toml -- -D warnings
101 changes: 74 additions & 27 deletions Cargo.lock

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ members = [
"druid-shell",
"druid-derive",
"docs/book_examples",
"druid/examples/wasm",
]
7 changes: 7 additions & 0 deletions druid-shell/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ time = "0.2.7"
cfg-if = "0.1.10"
# NOTE: if changing, ensure version is compatible with the version in piet
kurbo = "0.5.11"
# NOTE: This defaults to mimicking std::time on non-wasm targets
instant = { version = "0.1", features = [ "wasm-bindgen" ] }

cairo-rs = { version = "0.8.1", default_features = false, optional = true }
cairo-sys-rs = { version = "0.9.2", default_features = false, optional = true }
Expand Down Expand Up @@ -61,3 +63,8 @@ gtk-sys = "0.9.0"
[target.'cfg(target_os="linux")'.dependencies.gtk]
version = "0.8.1"
features = ["v3_20"]

[target.'cfg(target_arch="wasm32")'.dependencies]
wasm-bindgen = "0.2.59"
js-sys = "0.3.36"
web-sys = { version = "0.3.36", features = ["Window", "MouseEvent", "CssStyleDeclaration", "WheelEvent", "KeyEvent", "KeyboardEvent"] }
2 changes: 1 addition & 1 deletion druid-shell/examples/shello.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ impl WinHandler for HelloState {
}

fn key_down(&mut self, event: KeyEvent) -> bool {
let deadline = std::time::Instant::now() + std::time::Duration::from_millis(500);
let deadline = instant::Instant::now() + std::time::Duration::from_millis(500);
let id = self.handle.request_timer(deadline);
println!("keydown: {:?}, timer id = {:?}", event, id);

Expand Down
22 changes: 11 additions & 11 deletions druid-shell/src/keyboard.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,12 @@ pub struct KeyEvent {
impl KeyEvent {
/// Create a new `KeyEvent` struct. This accepts either &str or char for the last
/// two arguments.
pub(crate) fn new(
pub(crate) fn new<'a>(
key_code: impl Into<KeyCode>,
is_repeat: bool,
mods: KeyModifiers,
text: impl Into<StrOrChar>,
unmodified_text: impl Into<StrOrChar>,
text: impl Into<StrOrChar<'a>>,
unmodified_text: impl Into<StrOrChar<'a>>,
) -> Self {
let text = match text.into() {
StrOrChar::Char(c) => c.into(),
Expand Down Expand Up @@ -176,25 +176,25 @@ impl From<char> for TinyStr {

/// A type we use in the constructor of `KeyEvent`, specifically to avoid exposing
/// internals.
pub enum StrOrChar {
pub enum StrOrChar<'a> {
Char(char),
Str(&'static str),
Str(&'a str),
}

impl From<&'static str> for StrOrChar {
fn from(src: &'static str) -> Self {
impl<'a> From<&'a str> for StrOrChar<'a> {
fn from(src: &'a str) -> Self {
StrOrChar::Str(src)
}
}

impl From<char> for StrOrChar {
fn from(src: char) -> StrOrChar {
impl From<char> for StrOrChar<'static> {
fn from(src: char) -> StrOrChar<'static> {
StrOrChar::Char(src)
}
}

impl From<Option<char>> for StrOrChar {
fn from(src: Option<char>) -> StrOrChar {
impl From<Option<char>> for StrOrChar<'static> {
fn from(src: Option<char>) -> StrOrChar<'static> {
match src {
Some(c) => StrOrChar::Char(c),
None => StrOrChar::Str(""),
Expand Down
3 changes: 3 additions & 0 deletions druid-shell/src/platform/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,8 @@ cfg_if::cfg_if! {
} else if #[cfg(any(feature = "use_gtk", target_os = "linux"))] {
mod gtk;
pub use self::gtk::*;
} else if #[cfg(target_arch = "wasm32")] {
mod web;
pub use web::*;
}
}
39 changes: 39 additions & 0 deletions druid-shell/src/platform/web/application.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// Copyright 2020 The xi-editor Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! Web implementation of features at the application scope.

use super::clipboard::Clipboard;
use crate::application::AppHandler;

pub struct Application;

impl Application {
pub fn new(_handler: Option<Box<dyn AppHandler>>) -> Application {
Application
}

pub fn run(&mut self) {}

pub fn quit() {}

pub fn clipboard() -> Clipboard {
Clipboard
}

pub fn get_locale() -> String {
//TODO ahem
"en-US".into()
}
}
60 changes: 60 additions & 0 deletions druid-shell/src/platform/web/clipboard.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// Copyright 2020 The xi-editor Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! Interactions with the browser pasteboard.

use crate::clipboard::{ClipboardFormat, FormatId};

/// The browser clipboard.
#[derive(Debug, Clone, Default)]
pub struct Clipboard;

impl Clipboard {
/// Put a string onto the system clipboard.
pub fn put_string(&mut self, _s: impl AsRef<str>) {
log::warn!("unimplemented");
}

/// Put multi-format data on the system clipboard.
pub fn put_formats(&mut self, _formats: &[ClipboardFormat]) {
log::warn!("unimplemented");
}

/// Get a string from the system clipboard, if one is available.
pub fn get_string(&self) -> Option<String> {
log::warn!("unimplemented");
None
}

/// Given a list of supported clipboard types, returns the supported type which has
/// highest priority on the system clipboard, or `None` if no types are supported.
pub fn preferred_format(&self, _formats: &[FormatId]) -> Option<FormatId> {
log::warn!("unimplemented");
None
}

/// Return data in a given format, if available.
///
/// It is recommended that the `fmt` argument be a format returned by
/// [`Clipboard::preferred_format`]
pub fn get_format(&self, _format: FormatId) -> Option<Vec<u8>> {
log::warn!("unimplemented");
None
}

pub fn available_type_names(&self) -> Vec<String> {
log::warn!("unimplemented");
Vec::new()
}
}
50 changes: 50 additions & 0 deletions druid-shell/src/platform/web/error.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// Copyright 2020 The xi-editor Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! Web platform errors.

use wasm_bindgen::JsValue;

#[derive(Debug, Clone)]
pub enum Error {
NoWindow,
NoDocument,
Js(JsValue),
JsCast,
NoElementById(String),
NoContext,
Unimplemented,
}

impl std::fmt::Display for Error {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match self {
Error::NoWindow => write!(f, "No global window found"),
Error::NoDocument => write!(f, "No global document found"),
Error::Js(err) => write!(f, "JavaScript error: {:?}", err.as_string()),
Error::JsCast => write!(f, "JavaScript cast error"),
Error::NoElementById(err) => write!(f, "get_element_by_id error: {}", err),
Error::NoContext => write!(f, "Failed to get a draw context"),
Error::Unimplemented => write!(f, "Requested an unimplemented feature"),
}
}
}

impl From<JsValue> for Error {
fn from(js: JsValue) -> Error {
Error::Js(js)
}
}

impl std::error::Error for Error {}
Loading