Skip to content
Merged
Show file tree
Hide file tree
Changes from 28 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
4ca1fd7
Save empty backend.
richard-uk1 Dec 29, 2020
fcfee87
implement druid-shell for wayland.
richard-uk1 Dec 29, 2020
32d1e6c
Reduce the number of warnings.
richard-uk1 Apr 6, 2021
d8413e9
log -> tracing
maan2003 Aug 17, 2021
91b71a8
simulate_input
maan2003 Aug 17, 2021
696ae7d
prepare paint
maan2003 Aug 17, 2021
81cf390
green CI
maan2003 Sep 27, 2021
0662630
wayland fixes and improvements
james-lawrence Oct 27, 2021
88cf58d
wayland: share xkb with x11 backend
maan2003 Aug 18, 2021
1194bbe
decouple buffers from surface. (#2032)
james-lawrence Nov 10, 2021
3500e1e
decouple window handles from wayland id. (#2033)
james-lawrence Nov 10, 2021
104579f
remove dead/unused code. (#2035)
james-lawrence Nov 19, 2021
ba5f362
update wayland dependencies
james-lawrence Nov 20, 2021
6a9b58d
expose api for display reinitialization support.
james-lawrence Nov 20, 2021
c800f00
handle output added/removed events on eventqueue.
james-lawrence Nov 20, 2021
a90667e
formatting
james-lawrence Nov 20, 2021
2a3ca49
implement locale detection for wayland. (#2059)
james-lawrence Nov 30, 2021
89412ba
enable buffer recreation to always be allowed. (#2070)
james-lawrence Dec 3, 2021
1186cff
implement repeating keys. (#2058)
james-lawrence Dec 4, 2021
7ad66e7
attempt to create a working clipboard (#2057)
james-lawrence Dec 4, 2021
41471d7
cleanup popup implementation. (#2071)
james-lawrence Dec 5, 2021
804040e
implement screen for wayland. (#2076)
james-lawrence Dec 6, 2021
e7d7d31
wayland: CI
maan2003 Dec 7, 2021
cff899a
xkb: only include xkbcommon-x11.h if x11 feature is enabled
maan2003 Dec 7, 2021
79a0c04
No ApplicationExt on wayland
maan2003 Dec 6, 2021
1b51ace
Clippy
maan2003 Dec 7, 2021
632c8c5
additional clippy fixes.
james-lawrence Dec 7, 2021
c803df8
test fixes
james-lawrence Dec 7, 2021
6e62f5e
cleanup the output detect code.
james-lawrence Dec 8, 2021
409981d
Merge pull request #1 from james-lawrence/wayland-display-refactor
james-lawrence Dec 11, 2021
2451da9
cargo fmt
james-lawrence Dec 11, 2021
bdf6792
peer review
james-lawrence Dec 31, 2021
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
43 changes: 43 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,49 @@ jobs:
args: --manifest-path=docs/book_examples/Cargo.toml
if: contains(matrix.os, 'mac')

# we test the wayland backend as a separate job
test-stable-wayland:
runs-on: ubuntu-latest
name: cargo clippy+test (wayland)
steps:
- uses: actions/checkout@v2

- name: install wayland
run: |
sudo apt update
sudo apt install libwayland-dev libpango1.0-dev libxkbcommon-dev

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

- name: restore cache
uses: Swatinem/rust-cache@v1

- name: cargo clippy druid-shell
uses: actions-rs/cargo@v1
with:
command: clippy
args: --manifest-path=druid-shell/Cargo.toml --all-targets --features wayland --no-default-features -- -D warnings

- name: cargo test druid-shell
uses: actions-rs/cargo@v1
with:
command: test
args: --manifest-path=druid-shell/Cargo.toml --features wayland --no-default-features

# We use --all-targets to skip doc tests; there are no wayland-specific
# doctests in the main druid crate anyway
- name: cargo test druid
uses: actions-rs/cargo@v1
with:
command: test
args: --manifest-path=druid/Cargo.toml --all-targets --features=svg,image,im --features wayland --no-default-features

# we test the gtk backend as a separate job because gtk install takes
# a long time.
test-stable-gtk:
Expand Down
21 changes: 21 additions & 0 deletions druid-shell/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,20 @@ default-target = "x86_64-pc-windows-msvc"
default = ["gtk"]
gtk = ["gdk-sys", "glib-sys", "gtk-sys", "gtk-rs"]
x11 = ["x11rb", "nix", "cairo-sys-rs", "bindgen", "pkg-config"]
wayland = [
"wayland-client",
"wayland-protocols/client",
"wayland-protocols/unstable_protocols",
"nix",
"cairo-sys-rs",
"rand",
"calloop",
"wayland-cursor",
"log",
"im",
"bindgen",
"pkg-config",
]
# Implement HasRawWindowHandle for WindowHandle
raw-win-handle = ["raw-window-handle"]

Expand Down Expand Up @@ -86,6 +100,13 @@ glib-sys = { version = "0.14.0", optional = true }
gtk-sys = { version = "0.14.0", optional = true }
nix = { version = "0.18.0", optional = true }
x11rb = { version = "0.8.0", features = ["allow-unsafe-code", "present", "render", "randr", "xfixes", "xkb", "resource_manager", "cursor"], optional = true }
wayland-client = { version = "0.29", optional = true }
wayland-protocols = { version = "0.29", optional = true }
wayland-cursor = { version = "0.29", optional = true }
rand = { version = "0.8.0", optional = true }
calloop = { version = "0.7.1", optional = true }
log = { version = "0.4.14", optional = true }
im = { version = "15.0.0", optional = true }

[target.'cfg(target_arch="wasm32")'.dependencies]
wasm-bindgen = "0.2.67"
Expand Down
26 changes: 16 additions & 10 deletions druid-shell/build.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#[cfg(not(feature = "x11"))]
#[cfg(not(any(feature = "x11", feature = "wayland")))]
fn main() {}

#[cfg(feature = "x11")]
#[cfg(any(feature = "x11", feature = "wayland"))]
fn main() {
use pkg_config::probe_library;
use std::env;
Expand All @@ -14,19 +14,25 @@ fn main() {
}

probe_library("xkbcommon").unwrap();

#[cfg(feature = "x11")]
probe_library("xkbcommon-x11").unwrap();

let mut header = "\
#include <xkbcommon/xkbcommon-compose.h>
#include <xkbcommon/xkbcommon-names.h>
#include <xkbcommon/xkbcommon.h>"
.to_string();

if cfg!(feature = "x11") {
header += "
#include <xkbcommon/xkbcommon-x11.h>";
}

let bindings = bindgen::Builder::default()
// The input header we would like to generate
// bindings for.
.header_contents(
"wrapper.h",
"\
#include <xkbcommon/xkbcommon-compose.h>
#include <xkbcommon/xkbcommon-names.h>
#include <xkbcommon/xkbcommon-x11.h>
#include <xkbcommon/xkbcommon.h>",
)
.header_contents("wrapper.h", &header)
// Tell cargo to invalidate the built crate whenever any of the
// included header files changed.
.parse_callbacks(Box::new(bindgen::CargoCallbacks))
Expand Down
136 changes: 136 additions & 0 deletions druid-shell/examples/empty_window.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
// Copyright 2018 The Druid 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.

/// An example that is as simple as possible (just throw up an empty window).
use std::any::Any;

use druid_shell::kurbo::{Point, Rect, Size};
use druid_shell::piet::{Color, FixedLinearGradient, GradientStop, RenderContext};

use druid_shell::{
Application, Cursor, FileDialogToken, FileInfo, KeyEvent, MouseEvent, Region, TimerToken,
WinHandler, WindowBuilder, WindowHandle,
};

#[derive(Default)]
struct HelloState {
size: Size,
handle: Option<WindowHandle>,
}

impl WinHandler for HelloState {
fn connect(&mut self, handle: &WindowHandle) {
self.handle = Some(handle.clone());
}

fn prepare_paint(&mut self) {
self.handle.as_mut().unwrap().invalidate();
}

fn paint(&mut self, piet: &mut piet_common::Piet, _: &Region) {
// draw a gradient so we can see what's going on.
let brush = piet
.gradient(FixedLinearGradient {
start: Point::ZERO,
end: self.size.to_vec2().to_point(),
stops: vec![
GradientStop {
pos: 0.0,
color: Color::RED,
},
GradientStop {
pos: 1.0,
color: Color::BLUE,
},
],
})
.unwrap();
piet.fill(Rect::ZERO.with_size(self.size), &brush);
}

fn command(&mut self, id: u32) {
println!("command id {}", id);
}

fn open_file(&mut self, _token: FileDialogToken, file_info: Option<FileInfo>) {
println!("open file result: {:?}", file_info);
}

fn key_down(&mut self, event: KeyEvent) -> bool {
println!("keydown: {:?}", event);
false
}

fn key_up(&mut self, event: KeyEvent) {
println!("keyup: {:?}", event);
}

fn wheel(&mut self, event: &MouseEvent) {
println!("mouse_wheel {:?}", event);
}

fn mouse_move(&mut self, event: &MouseEvent) {
self.handle.as_mut().unwrap().set_cursor(&Cursor::Arrow);
println!("mouse_move {:?}", event);
}

fn mouse_down(&mut self, event: &MouseEvent) {
println!("mouse_down {:?}", event);
}

fn mouse_up(&mut self, event: &MouseEvent) {
println!("mouse_up {:?}", event);
}

fn timer(&mut self, id: TimerToken) {
println!("timer fired: {:?}", id);
}

fn size(&mut self, size: Size) {
self.size = size;
}

fn got_focus(&mut self) {
println!("Got focus");
}

fn lost_focus(&mut self) {
println!("Lost focus");
}

fn request_close(&mut self) {
self.handle.as_ref().unwrap().close();
}

fn destroy(&mut self) {
Application::global().quit()
}

fn as_any(&mut self) -> &mut dyn Any {
self
}
}

fn main() {
tracing_subscriber::fmt::init();
let app = Application::new().unwrap();
let mut builder = WindowBuilder::new(app.clone());
builder.set_handler(Box::new(HelloState::default()));
builder.set_title("Hello example");

let window = builder.build().unwrap();
window.show();

app.run(None);
}
25 changes: 22 additions & 3 deletions druid-shell/src/backend/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,30 @@ pub use x11::*;
#[cfg(all(feature = "x11", any(target_os = "linux", target_os = "openbsd")))]
pub(crate) mod shared;

#[cfg(all(not(feature = "x11"), any(target_os = "linux", target_os = "openbsd")))]
#[cfg(all(feature = "wayland", target_os = "linux"))]
mod wayland;
#[cfg(all(feature = "wayland", target_os = "linux"))]
pub use wayland::*;
#[cfg(all(feature = "wayland", target_os = "linux"))]
pub(crate) mod shared;

#[cfg(all(
not(feature = "x11"),
not(feature = "wayland"),
any(target_os = "linux", target_os = "openbsd")
))]
mod gtk;
#[cfg(all(not(feature = "x11"), any(target_os = "linux", target_os = "openbsd")))]
#[cfg(all(
not(feature = "x11"),
not(feature = "wayland"),
any(target_os = "linux", target_os = "openbsd")
))]
pub use self::gtk::*;
#[cfg(all(not(feature = "x11"), any(target_os = "linux", target_os = "openbsd")))]
#[cfg(all(
not(feature = "x11"),
not(feature = "wayland"),
any(target_os = "linux", target_os = "openbsd")
))]
pub(crate) mod shared;

#[cfg(target_arch = "wasm32")]
Expand Down
1 change: 1 addition & 0 deletions druid-shell/src/backend/shared/keyboard.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ use keyboard_types::{Code, Location};

#[cfg(any(
all(feature = "x11", any(target_os = "linux", target_os = "openbsd")),
all(feature = "wayland", target_os = "linux"),
target_os = "macos"
))]
/// Map key code to location.
Expand Down
39 changes: 39 additions & 0 deletions druid-shell/src/backend/shared/linux/env.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
pub fn locale() -> String {
fn locale_env_var(var: &str) -> Option<String> {
match std::env::var(var) {
Ok(s) if s.is_empty() => {
tracing::debug!("locale: ignoring empty env var {}", var);
None
}
Ok(s) => {
tracing::debug!("locale: env var {} found: {:?}", var, &s);
Some(s)
}
Err(std::env::VarError::NotPresent) => {
tracing::debug!("locale: env var {} not found", var);
None
}
Err(std::env::VarError::NotUnicode(_)) => {
tracing::debug!("locale: ignoring invalid unicode env var {}", var);
None
}
}
}

// from gettext manual
// https://www.gnu.org/software/gettext/manual/html_node/Locale-Environment-Variables.html#Locale-Environment-Variables
let mut locale = locale_env_var("LANGUAGE")
// the LANGUAGE value is priority list seperated by :
// See: https://www.gnu.org/software/gettext/manual/html_node/The-LANGUAGE-variable.html#The-LANGUAGE-variable
.and_then(|locale| locale.split(':').next().map(String::from))
.or_else(|| locale_env_var("LC_ALL"))
.or_else(|| locale_env_var("LC_MESSAGES"))
.or_else(|| locale_env_var("LANG"))
.unwrap_or_else(|| "en-US".to_string());

// This is done because the locale parsing library we use expects an unicode locale, but these vars have an ISO locale
if let Some(idx) = locale.chars().position(|c| c == '.' || c == '@') {
locale.truncate(idx);
}
locale
}
2 changes: 2 additions & 0 deletions druid-shell/src/backend/shared/linux/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// environment based utilities
pub mod env;
8 changes: 8 additions & 0 deletions druid-shell/src/backend/shared/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,11 @@ cfg_if::cfg_if! {
pub use keyboard::*;
}
}
cfg_if::cfg_if! {
if #[cfg(all(target_os = "linux", any(feature = "x11", feature = "wayland")))] {
mod timer;
pub(crate) use timer::*;
pub(crate) mod xkb;
pub(crate) mod linux;
}
}
Loading