Skip to content

Commit a8d062a

Browse files
crsaraccoperlindgrencmyr
authored
X11 implementation of druid-shell (#599)
* Skeleton X11 backend; everything is unimplemented!() * Compiles and runs, but does nothing. * Huge hacks to try to get X11 window painting working * It draws stuff! * Schedule redraws by sleeping (TODO: fix later) * Make menu functions no-ops so the 'shello' example doesn't crash * Make TODOs easier to grep * Knock out a bunch of the easier 'initial_pr' TODOs * implement WindowHandle::close and WindowHandle::bring_to_front_and_focus * Run github workflows for druid_shell_x11 branch; fix workflow errors * keycodes * mouse down * review updates * Quick cleanup of X11 platform code before PR * [ci] Run x11 backend in ci This also includes some general ci tweaks to make things a bit more sensible, optimistically. * Post merge fixes * s/use_x11/x11 * Fix X11 hackery in examples * Update copyright year in druid-shell/src/platform/x11 files * Delete runloop.rs * Turn all unimplemented!() calls into log::warn!() calls * Return unknown keycode directly instead of using unreachable!() * Update visibility on XWindow to pub(crate) instead of pub * Fix clippy warnings for X11 implementation * Small PR review cleanups * update README with X11 info * Re-create X11 piet context every redraw * Communicate window size back to Druid * handle mouse_up and mouse_move * Make X11 window respond to window resize events. * Flush XCB event queue when requesting redraw * Code review fixes Co-authored-by: Per Lindgren <[email protected]> Co-authored-by: Per <Per Lindgren> Co-authored-by: Colin Rofls <[email protected]>
1 parent d6b5b84 commit a8d062a

20 files changed

+1321
-16
lines changed

.github/workflows/ci.yml

Lines changed: 64 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -78,40 +78,47 @@ jobs:
7878
profile: minimal
7979
override: true
8080

81-
- name: cargo clippy (no-svg)
81+
- name: cargo clippy (druid)
8282
uses: actions-rs/cargo@v1
8383
with:
8484
command: clippy
85-
args: --all -- -D warnings
86-
if: contains(matrix.os, 'ubuntu') != true
85+
args: --manifest-path=druid/Cargo.toml --features=svg,image -- -D warnings
8786

88-
- name: cargo clippy (svg)
87+
- name: cargo clippy (druid-shell)
8988
uses: actions-rs/cargo@v1
9089
with:
9190
command: clippy
92-
args: --all --all-features -- -D warnings
93-
if: contains(matrix.os, 'ubuntu')
91+
args: --manifest-path=druid-shell/Cargo.toml -- -D warnings
9492

93+
- name: cargo clippy (druid-derive)
94+
uses: actions-rs/cargo@v1
95+
with:
96+
command: clippy
97+
args: --manifest-path=druid-derive/Cargo.toml -- -D warnings
9598

96-
- name: cargo test --all
99+
- name: cargo test (druid)
97100
uses: actions-rs/cargo@v1
98101
with:
99102
command: test
100-
args: --all
101-
if: contains(matrix.os, 'ubuntu') != true
103+
args: --manifest-path=druid/Cargo.toml --features=svg,image
102104

103-
- name: cargo test --all --all-features
105+
- name: cargo test (druid-shell)
104106
uses: actions-rs/cargo@v1
105107
with:
106108
command: test
107-
args: --all --all-features
108-
if: contains(matrix.os, 'ubuntu')
109+
args: --manifest-path=druid-shell/Cargo.toml
110+
111+
- name: cargo test (druid-derive)
112+
uses: actions-rs/cargo@v1
113+
with:
114+
command: test
115+
args: --manifest-path=druid-shell/Cargo.toml
109116

110117
- name: Run rustc -D warnings in druid/
111118
uses: actions-rs/cargo@v1
112119
with:
113120
command: rustc
114-
args: --manifest-path=druid/Cargo.toml -- -D warnings
121+
args: --manifest-path=druid/Cargo.toml --features=svg,image -- -D warnings
115122

116123
- name: Run rustc -d warnings in druid/druid-shell
117124
uses: actions-rs/cargo@v1
@@ -188,3 +195,47 @@ jobs:
188195
with:
189196
command: doc
190197
args: --document-private-items
198+
199+
# by default on linux we test gtk; to test x11 we need a separate job.
200+
test-stable-x11:
201+
runs-on: ubuntu-latest
202+
name: cargo test stable (x11)
203+
steps:
204+
- uses: actions/checkout@v1
205+
206+
- name: install deps
207+
run: |
208+
sudo apt update
209+
sudo apt install libx11-dev libgtk-3-dev
210+
211+
- name: install stable toolchain
212+
uses: actions-rs/toolchain@v1
213+
with:
214+
toolchain: stable
215+
components: clippy
216+
profile: minimal
217+
override: true
218+
219+
- name: cargo clippy (x11)
220+
uses: actions-rs/cargo@v1
221+
with:
222+
command: clippy
223+
args: --manifest-path=druid-shell/Cargo.toml --features=x11 -- -D warnings
224+
225+
- name: cargo test druid-shell
226+
uses: actions-rs/cargo@v1
227+
with:
228+
command: test
229+
args: --manifest-path=druid-shell/Cargo.toml --features=x11
230+
231+
- name: cargo test druid
232+
uses: actions-rs/cargo@v1
233+
with:
234+
command: test
235+
args: --manifest-path=druid/Cargo.toml --features=x11
236+
237+
- name: Run rustc -d warnings in druid/druid-shell
238+
uses: actions-rs/cargo@v1
239+
with:
240+
command: rustc
241+
args: --manifest-path=druid-shell/Cargo.toml --features=x11 -- -D warnings

Cargo.lock

Lines changed: 23 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,10 @@ should be sufficient. Removing this dependency is on the roadmap.
246246
On Linux, druid requires gtk+3; see [gtk-rs dependencies] for installation
247247
instructions.
248248

249+
Alternatively, there is an X11 backend available, although it is currently
250+
[missing quite a few features](https://github.com/xi-editor/druid/issues/475).
251+
You can try it out with `--features=x11`.
252+
249253
## Alternatives
250254

251255
Druid is only one of many ongoing [Rust-native GUI experiments]. To mention a

druid-shell/Cargo.toml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ edition = "2018"
1111

1212
[features]
1313
use_gtk = ["gtk", "gtk-sys", "gio", "gdk", "gdk-sys", "glib", "glib-sys", "cairo-rs"]
14+
x11 = ["xcb", "cairo-sys-rs"]
1415

1516
[package.metadata.docs.rs]
1617
default-target = "x86_64-pc-windows-msvc"
@@ -25,13 +26,15 @@ cfg-if = "0.1.10"
2526
kurbo = "0.5.11"
2627

2728
cairo-rs = { version = "0.8.1", default_features = false, optional = true }
29+
cairo-sys-rs = { version = "0.9.2", default_features = false, optional = true }
2830
gio = { version = "0.8.1", optional = true }
2931
gdk = { version = "0.12.1", optional = true }
3032
gdk-sys = { version = "0.9.0", optional = true }
3133
gtk = { version = "0.8.1", optional = true }
3234
glib = { version = "0.9.3", optional = true }
3335
glib-sys = { version = "0.9.0", optional = true }
3436
gtk-sys = { version = "0.9.0", optional = true }
37+
xcb = { version = "0.9.0", features = ["thread", "xlib_xcb", "randr"], optional = true }
3538

3639
[target.'cfg(target_os="windows")'.dependencies]
3740
wio = "0.2"
@@ -45,8 +48,9 @@ cocoa = "0.20.0"
4548
objc = "0.2.5"
4649
cairo-rs = { version = "0.8.1", default_features = false }
4750

51+
# TODO(x11/dependencies): only use feature "xcb" if using XCB
4852
[target.'cfg(target_os="linux")'.dependencies]
49-
cairo-rs = { version = "0.8.1", default_features = false }
53+
cairo-rs = { version = "0.8.1", default_features = false, features = ["xcb"] }
5054
gio = "0.8.1"
5155
gdk = "0.12.1"
5256
gdk-sys = "0.9.0"

druid-shell/examples/perftest.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,5 +121,6 @@ fn main() {
121121

122122
let window = builder.build().unwrap();
123123
window.show();
124+
124125
app.run();
125126
}

druid-shell/examples/shello.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ impl WinHandler for HelloState {
6767
let deadline = std::time::Instant::now() + std::time::Duration::from_millis(500);
6868
let id = self.handle.request_timer(deadline);
6969
println!("keydown: {:?}, timer id = {:?}", event, id);
70+
7071
false
7172
}
7273

@@ -133,8 +134,9 @@ fn main() {
133134
builder.set_handler(Box::new(HelloState::default()));
134135
builder.set_title("Hello example");
135136
builder.set_menu(menubar);
136-
let window = builder.build().unwrap();
137137

138+
let window = builder.build().unwrap();
138139
window.show();
140+
139141
app.run();
140142
}

druid-shell/src/common_util.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ use std::sync::atomic::{AtomicU64, Ordering};
2121
/// Strip the access keys from the menu string.
2222
///
2323
/// Changes "E&xit" to "Exit". Actual ampersands are escaped as "&&".
24+
#[cfg(not(feature = "x11"))]
2425
#[cfg(any(target_os = "macos", target_os = "linux"))]
2526
pub fn strip_access_key(raw_menu_text: &str) -> String {
2627
let mut saw_ampersand = false;

druid-shell/src/dialog.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ pub struct FileInfo {
2323
}
2424

2525
/// Type of file dialog.
26+
#[cfg(not(feature = "x11"))]
2627
pub enum FileDialogType {
2728
/// File open dialog.
2829
Open,

druid-shell/src/lib.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,10 @@ extern crate objc;
3636
#[macro_use]
3737
extern crate lazy_static;
3838

39+
#[cfg(all(target_os = "linux", feature = "x11"))]
40+
#[macro_use]
41+
extern crate lazy_static;
42+
3943
mod application;
4044
mod clipboard;
4145
mod common_util;

druid-shell/src/platform/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ cfg_if::cfg_if! {
2121
} else if #[cfg(all(target_os = "macos", not(feature = "use_gtk")))] {
2222
mod mac;
2323
pub use mac::*;
24+
} else if #[cfg(all(feature = "x11", target_os = "linux"))] {
25+
mod x11;
26+
pub use x11::*;
2427
} else if #[cfg(any(feature = "use_gtk", target_os = "linux"))] {
2528
mod gtk;
2629
pub use self::gtk::*;

0 commit comments

Comments
 (0)