Skip to content

Commit 6fb524e

Browse files
committed
wip
1 parent 6dad07d commit 6fb524e

3 files changed

Lines changed: 84 additions & 81 deletions

File tree

src/platform/x11/error.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use crate::platform::x11::xcb_connection::GetPropertyError;
33
use crate::tracing::warn;
44
use crate::wrappers::xlib::{DisplayOpenFailedError, InitThreadsFailedError};
55
use crate::HandlerError;
6+
use std::sync::mpsc::RecvError;
67
use x11_dl::error::OpenError;
78
use x11rb::connection::RequestConnection;
89
use x11rb::cookie::{Cookie, VoidCookie};
@@ -11,6 +12,7 @@ use x11rb::x11_utils::{TryParse, X11Error};
1112

1213
#[derive(Debug)]
1314
pub enum Error {
15+
CreationFailed(String),
1416
Io(std::io::Error),
1517
DylibOpen(OpenError),
1618
InitThreadsFailed(InitThreadsFailedError),
@@ -22,6 +24,7 @@ pub enum Error {
2224
Connect(ConnectError),
2325
DisplayOpenFailed(DisplayOpenFailedError),
2426
Handler(HandlerError),
27+
ChannelError(RecvError),
2528
#[cfg(feature = "opengl")]
2629
XLib(crate::wrappers::xlib::XLibError),
2730
#[cfg(feature = "opengl")]

src/platform/x11/event_loop.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,20 +29,24 @@ pub(crate) struct EventLoop {
2929
impl EventLoop {
3030
pub fn new(
3131
window: Rc<WindowInner>, handler: Box<dyn WindowHandler>,
32-
parent_handle: Option<ParentHandle>, xkb_state: Option<XkbcommonState>,
32+
parent_handle: Option<ParentHandle>,
3333
) -> Self {
3434
Self {
35+
xkb_state: XkbcommonState::new(&window.connection),
3536
window,
3637
handler,
3738
parent_handle,
3839
frame_interval: Duration::from_millis(15),
3940
event_loop_running: false,
4041
new_physical_size: None,
4142
drag_n_drop: DragNDropState::NoCurrentSession,
42-
xkb_state,
4343
}
4444
}
4545

46+
pub fn window_id(&self) -> NonZeroU32 {
47+
self.window.xcb_window.id()
48+
}
49+
4650
#[inline]
4751
fn drain_xcb_events(&mut self) -> core::result::Result<(), ConnectionError> {
4852
// the X server has a tendency to send spurious/extraneous configure notify events when a
@@ -66,7 +70,7 @@ impl EventLoop {
6670
}
6771

6872
// Event loop
69-
pub fn run(&mut self) -> Result<()> {
73+
pub fn run(mut self) {
7074
let connection = Rc::clone(&self.window.connection);
7175
let mut poller = ConnectionPoller::new(&connection.conn)?;
7276

@@ -112,8 +116,6 @@ impl EventLoop {
112116
}
113117

114118
poller.delete()?;
115-
116-
Ok(())
117119
}
118120

119121
fn handle_xcb_event(&mut self, event: XEvent) {

src/platform/x11/window.rs

Lines changed: 74 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ use crate::handler::WindowHandlerBuilder;
1212
use crate::platform::x11::window_shared::WindowInner;
1313
use crate::platform::x11::xcb_window::XcbWindow;
1414
use crate::platform::Result;
15-
use crate::wrappers::xkbcommon::XkbcommonState;
1615
use crate::*;
1716

1817
pub struct WindowHandle {
@@ -28,13 +27,25 @@ impl WindowHandle {
2827
) -> Result<WindowHandle> {
2928
let (tx, rx) = mpsc::sync_channel::<WindowOpenResult>(1);
3029
let (parent_handle, mut window_handle) = ParentHandle::new();
31-
let join_handle = thread::spawn(move || {
32-
// TODO: properly handle crashes here
33-
Window::window_thread(options, handler, tx.clone(), Some(parent_handle)).unwrap();
34-
});
3530

36-
let raw_window_handle = rx.recv().unwrap()?;
37-
window_handle.window_id = Some(raw_window_handle);
31+
let join_handle =
32+
thread::spawn(move || match create_window(options, handler, Some(parent_handle)) {
33+
Ok(ev_loop) => {
34+
tx.send(Ok(ev_loop.window_id())).unwrap();
35+
ev_loop.run()
36+
}
37+
Err(e) => {
38+
tx.send(Err(format!("{}", e))).unwrap();
39+
}
40+
});
41+
42+
let id = match rx.recv() {
43+
Ok(Ok(id)) => id,
44+
Err(e) => return Err(super::Error::ChannelError(e)),
45+
Ok(Err(s)) => return Err(super::error::Error::CreationFailed(s)),
46+
};
47+
48+
window_handle.window_id = Some(id);
3849
window_handle.event_loop_handle = Some(join_handle).into();
3950
Ok(window_handle)
4051
}
@@ -91,87 +102,74 @@ impl Drop for ParentHandle {
91102
}
92103
}
93104

94-
pub struct Window;
105+
type WindowOpenResult = core::result::Result<NonZero<x11rb::protocol::xproto::Window>, String>;
95106

96-
type WindowOpenResult = Result<NonZero<x11rb::protocol::xproto::Window>>;
107+
fn create_window(
108+
options: WindowOpenOptions, build: WindowHandlerBuilder, parent_handle: Option<ParentHandle>,
109+
) -> Result<EventLoop> {
110+
// Connect to the X server
111+
let xcb_connection = X11Connection::new()?;
97112

98-
impl Window {
99-
fn window_thread(
100-
options: WindowOpenOptions, build: WindowHandlerBuilder,
101-
tx: mpsc::SyncSender<WindowOpenResult>, parent_handle: Option<ParentHandle>,
102-
) -> Result<()> {
103-
// Connect to the X server
104-
let xcb_connection = X11Connection::new()?;
113+
let scaling = match options.scale {
114+
WindowScalePolicy::SystemScaleFactor => xcb_connection.get_scaling(),
115+
WindowScalePolicy::ScaleFactor(scale) => scale,
116+
};
105117

106-
// Setup xkbcommon
107-
let xkb_state = XkbcommonState::new(&xcb_connection);
118+
let physical_size = options.size.to_physical(scaling);
108119

109-
let scaling = match options.scale {
110-
WindowScalePolicy::SystemScaleFactor => xcb_connection.get_scaling(),
111-
WindowScalePolicy::ScaleFactor(scale) => scale,
112-
};
120+
#[cfg(feature = "opengl")]
121+
let visual_info =
122+
WindowVisualConfig::find_best_visual_config_for_gl(&xcb_connection, options.gl_config)?;
113123

114-
let physical_size = options.size.to_physical(scaling);
124+
#[cfg(not(feature = "opengl"))]
125+
let visual_info = WindowVisualConfig::find_best_visual_config(&xcb_connection)?;
115126

116-
#[cfg(feature = "opengl")]
117-
let visual_info =
118-
WindowVisualConfig::find_best_visual_config_for_gl(&xcb_connection, options.gl_config)?;
119-
120-
#[cfg(not(feature = "opengl"))]
121-
let visual_info = WindowVisualConfig::find_best_visual_config(&xcb_connection)?;
122-
123-
let xcb_connection = Rc::new(xcb_connection);
124-
125-
let x_window = XcbWindow::new(
126-
Rc::clone(&xcb_connection),
127-
physical_size,
128-
&visual_info,
129-
options.parent.map(|p| p.window_id),
130-
)?;
131-
132-
let cookies = [
133-
x_window.map_window()?,
134-
x_window.set_title(&options.title)?,
135-
x_window.enable_wm_protocols()?,
136-
x_window.enable_dnd_protocols()?,
137-
];
138-
139-
for cookie in cookies {
140-
cookie.check()?;
141-
}
127+
let xcb_connection = Rc::new(xcb_connection);
142128

143-
#[cfg(feature = "opengl")]
144-
let gl_context = match visual_info.fb_config {
145-
None => None,
146-
Some(fb_config) => {
147-
// Because of the visual negotation we had to take some extra steps to create this context
148-
Some(super::gl::GlContextInner::create(
149-
&x_window,
150-
Rc::clone(&xcb_connection),
151-
fb_config,
152-
)?)
153-
}
154-
};
129+
let x_window = XcbWindow::new(
130+
Rc::clone(&xcb_connection),
131+
physical_size,
132+
&visual_info,
133+
options.parent.map(|p| p.window_id),
134+
)?;
155135

156-
let window_id = x_window.id();
157-
let inner = Rc::new(WindowInner::new(
158-
xcb_connection,
159-
x_window,
160-
physical_size,
161-
scaling,
162-
visual_info.visual_id,
163-
#[cfg(feature = "opengl")]
164-
gl_context,
165-
));
136+
let cookies = [
137+
x_window.map_window()?,
138+
x_window.set_title(&options.title)?,
139+
x_window.enable_wm_protocols()?,
140+
x_window.enable_dnd_protocols()?,
141+
];
166142

167-
let handler = build.build(WindowContext::new(Rc::clone(&inner)))?;
143+
for cookie in cookies {
144+
cookie.check()?;
145+
}
168146

169-
let _ = tx.send(Ok(window_id));
147+
#[cfg(feature = "opengl")]
148+
let gl_context = match visual_info.fb_config {
149+
None => None,
150+
Some(fb_config) => {
151+
// Because of the visual negotation we had to take some extra steps to create this context
152+
Some(super::gl::GlContextInner::create(
153+
&x_window,
154+
Rc::clone(&xcb_connection),
155+
fb_config,
156+
)?)
157+
}
158+
};
159+
160+
let inner = Rc::new(WindowInner::new(
161+
xcb_connection,
162+
x_window,
163+
physical_size,
164+
scaling,
165+
visual_info.visual_id,
166+
#[cfg(feature = "opengl")]
167+
gl_context,
168+
));
170169

171-
EventLoop::new(inner, handler, parent_handle, xkb_state).run()?;
170+
let handler = build.build(WindowContext::new(Rc::clone(&inner)))?;
172171

173-
Ok(())
174-
}
172+
Ok(EventLoop::new(inner, handler, parent_handle))
175173
}
176174

177175
pub fn copy_to_clipboard(_data: &str) {

0 commit comments

Comments
 (0)