Skip to content

Commit 61f80e0

Browse files
committed
Squashed:
Port X11 backend to x11rb Fix macOS build Win32 refactor Make the added with_scale_factor fn pub(crate) for now Remove unneeded internal HasRawWindowHandle implementation Simplify everything by making the public Window/GlContext types hold the Weak themselves Remove lifetime from Window type, refactor and split X11 backend Added functional open_parented example
1 parent 085ae2a commit 61f80e0

21 files changed

+1774
-1562
lines changed

examples/open_parented.rs

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@ struct ParentWindowHandler {
1414
}
1515

1616
impl ParentWindowHandler {
17-
pub fn new(window: &mut Window) -> Self {
18-
let ctx = unsafe { softbuffer::Context::new(window) }.unwrap();
19-
let mut surface = unsafe { softbuffer::Surface::new(&ctx, window) }.unwrap();
17+
pub fn new(window: Window) -> Self {
18+
let ctx = unsafe { softbuffer::Context::new(&window) }.unwrap();
19+
let mut surface = unsafe { softbuffer::Surface::new(&ctx, &window) }.unwrap();
2020
surface.resize(NonZeroU32::new(512).unwrap(), NonZeroU32::new(512).unwrap()).unwrap();
2121

2222
let window_open_options = baseview::WindowOpenOptions {
@@ -28,8 +28,9 @@ impl ParentWindowHandler {
2828
#[cfg(feature = "opengl")]
2929
gl_config: None,
3030
};
31+
3132
let child_window =
32-
Window::open_parented(window, window_open_options, ChildWindowHandler::new);
33+
Window::open_parented(&window, window_open_options, ChildWindowHandler::new);
3334

3435
// TODO: no way to query physical size initially?
3536
Self {
@@ -43,7 +44,7 @@ impl ParentWindowHandler {
4344
}
4445

4546
impl WindowHandler for ParentWindowHandler {
46-
fn on_frame(&mut self, _window: &mut Window) {
47+
fn on_frame(&mut self) {
4748
let mut buf = self.surface.buffer_mut().unwrap();
4849
if self.damaged {
4950
buf.fill(0xFFAAAAAA);
@@ -52,7 +53,7 @@ impl WindowHandler for ParentWindowHandler {
5253
buf.present().unwrap();
5354
}
5455

55-
fn on_event(&mut self, _window: &mut Window, event: Event) -> EventStatus {
56+
fn on_event(&mut self, event: Event) -> EventStatus {
5657
match event {
5758
Event::Window(WindowEvent::Resized(info)) => {
5859
println!("Parent Resized: {:?}", info);
@@ -83,9 +84,9 @@ struct ChildWindowHandler {
8384
}
8485

8586
impl ChildWindowHandler {
86-
pub fn new(window: &mut Window) -> Self {
87-
let ctx = unsafe { softbuffer::Context::new(window) }.unwrap();
88-
let mut surface = unsafe { softbuffer::Surface::new(&ctx, window) }.unwrap();
87+
pub fn new(window: Window) -> Self {
88+
let ctx = unsafe { softbuffer::Context::new(&window) }.unwrap();
89+
let mut surface = unsafe { softbuffer::Surface::new(&ctx, &window) }.unwrap();
8990
surface.resize(NonZeroU32::new(512).unwrap(), NonZeroU32::new(512).unwrap()).unwrap();
9091

9192
// TODO: no way to query physical size initially?
@@ -94,7 +95,7 @@ impl ChildWindowHandler {
9495
}
9596

9697
impl WindowHandler for ChildWindowHandler {
97-
fn on_frame(&mut self, _window: &mut Window) {
98+
fn on_frame(&mut self) {
9899
let mut buf = self.surface.buffer_mut().unwrap();
99100
if self.damaged {
100101
buf.fill(0xFFAA0000);
@@ -103,7 +104,7 @@ impl WindowHandler for ChildWindowHandler {
103104
buf.present().unwrap();
104105
}
105106

106-
fn on_event(&mut self, _window: &mut Window, event: Event) -> EventStatus {
107+
fn on_event(&mut self, event: Event) -> EventStatus {
107108
match event {
108109
Event::Window(WindowEvent::Resized(info)) => {
109110
println!("Child Resized: {:?}", info);

examples/open_window.rs

Lines changed: 38 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
1+
use std::num::NonZeroU32;
12
use std::time::Duration;
23

34
use rtrb::{Consumer, RingBuffer};
45

56
#[cfg(target_os = "macos")]
67
use baseview::copy_to_clipboard;
7-
use baseview::{Event, EventStatus, MouseEvent, Window, WindowHandler, WindowScalePolicy};
8+
use baseview::{
9+
Event, EventStatus, MouseEvent, PhySize, Window, WindowEvent, WindowHandler, WindowScalePolicy,
10+
};
811

912
#[derive(Debug, Clone)]
1013
enum Message {
@@ -13,28 +16,50 @@ enum Message {
1316

1417
struct OpenWindowExample {
1518
rx: Consumer<Message>,
19+
20+
ctx: softbuffer::Context,
21+
surface: softbuffer::Surface,
22+
current_size: PhySize,
23+
damaged: bool,
1624
}
1725

1826
impl WindowHandler for OpenWindowExample {
19-
fn on_frame(&mut self, _window: &mut Window) {
27+
fn on_frame(&mut self) {
28+
let mut buf = self.surface.buffer_mut().unwrap();
29+
if self.damaged {
30+
buf.fill(0xFFAAAAAA);
31+
self.damaged = false;
32+
}
33+
buf.present().unwrap();
34+
2035
while let Ok(message) = self.rx.pop() {
2136
println!("Message: {:?}", message);
2237
}
2338
}
2439

25-
fn on_event(&mut self, _window: &mut Window, event: Event) -> EventStatus {
40+
fn on_event(&mut self, event: Event) -> EventStatus {
2641
match event {
2742
Event::Mouse(e) => {
2843
println!("Mouse event: {:?}", e);
2944

3045
#[cfg(target_os = "macos")]
3146
match e {
32-
MouseEvent::ButtonPressed { .. } => {
33-
copy_to_clipboard(&"This is a test!")
34-
}
47+
MouseEvent::ButtonPressed { .. } => copy_to_clipboard(&"This is a test!"),
3548
_ => (),
3649
}
3750
}
51+
Event::Window(WindowEvent::Resized(info)) => {
52+
println!("Resized: {:?}", info);
53+
let new_size = info.physical_size();
54+
self.current_size = new_size;
55+
56+
if let (Some(width), Some(height)) =
57+
(NonZeroU32::new(new_size.width), NonZeroU32::new(new_size.height))
58+
{
59+
self.surface.resize(width, height).unwrap();
60+
self.damaged = true;
61+
}
62+
}
3863
Event::Keyboard(e) => println!("Keyboard event: {:?}", e),
3964
Event::Window(e) => println!("Window event: {:?}", e),
4065
}
@@ -64,5 +89,11 @@ fn main() {
6489
}
6590
});
6691

67-
Window::open_blocking(window_open_options, |_| OpenWindowExample { rx });
92+
Window::open_blocking(window_open_options, |window| {
93+
let ctx = unsafe { softbuffer::Context::new(&window) }.unwrap();
94+
let mut surface = unsafe { softbuffer::Surface::new(&ctx, &window) }.unwrap();
95+
surface.resize(NonZeroU32::new(512).unwrap(), NonZeroU32::new(512).unwrap()).unwrap();
96+
97+
OpenWindowExample { ctx, surface, rx, current_size: PhySize::new(512, 512), damaged: true }
98+
});
6899
}

src/gl/mod.rs

Lines changed: 16 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,20 @@
11
use std::ffi::c_void;
2-
use std::marker::PhantomData;
3-
4-
// On X11 creating the context is a two step process
5-
#[cfg(not(target_os = "linux"))]
6-
use raw_window_handle::RawWindowHandle;
2+
use std::rc::{Rc, Weak};
73

84
#[cfg(target_os = "windows")]
9-
mod win;
5+
pub(crate) mod win;
106
#[cfg(target_os = "windows")]
11-
use win as platform;
7+
pub(crate) use win as platform;
128

13-
// We need to use this directly within the X11 window creation to negotiate the correct visual
149
#[cfg(target_os = "linux")]
1510
pub(crate) mod x11;
1611
#[cfg(target_os = "linux")]
17-
pub(crate) use self::x11 as platform;
12+
pub(crate) use x11 as platform;
1813

1914
#[cfg(target_os = "macos")]
20-
mod macos;
15+
pub(crate) mod macos;
2116
#[cfg(target_os = "macos")]
22-
use macos as platform;
17+
pub(crate) use macos as platform;
2318

2419
#[derive(Clone, Debug)]
2520
pub struct GlConfig {
@@ -70,46 +65,37 @@ pub enum GlError {
7065
}
7166

7267
pub struct GlContext {
73-
context: platform::GlContext,
74-
phantom: PhantomData<*mut ()>,
68+
context: Weak<platform::GlContext>,
7569
}
7670

7771
impl GlContext {
78-
#[cfg(not(target_os = "linux"))]
79-
pub(crate) unsafe fn create(
80-
parent: &RawWindowHandle, config: GlConfig,
81-
) -> Result<GlContext, GlError> {
82-
platform::GlContext::create(parent, config)
83-
.map(|context| GlContext { context, phantom: PhantomData })
72+
pub(crate) fn new(context: Weak<platform::GlContext>) -> GlContext {
73+
GlContext { context }
8474
}
8575

86-
/// The X11 version needs to be set up in a different way compared to the Windows and macOS
87-
/// versions. So the platform-specific versions should be used to construct the context within
88-
/// baseview, and then this object can be passed to the user.
89-
#[cfg(target_os = "linux")]
90-
pub(crate) fn new(context: platform::GlContext) -> GlContext {
91-
GlContext { context, phantom: PhantomData }
76+
fn context(&self) -> Rc<platform::GlContext> {
77+
self.context.upgrade().expect("GL context has been destroyed")
9278
}
9379

9480
pub unsafe fn make_current(&self) {
95-
self.context.make_current();
81+
self.context().make_current();
9682
}
9783

9884
pub unsafe fn make_not_current(&self) {
99-
self.context.make_not_current();
85+
self.context().make_not_current();
10086
}
10187

10288
pub fn get_proc_address(&self, symbol: &str) -> *const c_void {
103-
self.context.get_proc_address(symbol)
89+
self.context().get_proc_address(symbol)
10490
}
10591

10692
pub fn swap_buffers(&self) {
107-
self.context.swap_buffers();
93+
self.context().swap_buffers();
10894
}
10995

11096
/// On macOS the `NSOpenGLView` needs to be resized separtely from our main view.
11197
#[cfg(target_os = "macos")]
11298
pub(crate) fn resize(&self, size: cocoa::foundation::NSSize) {
113-
self.context.resize(size);
99+
self.context().resize(size);
114100
}
115101
}

0 commit comments

Comments
 (0)