gpui: Decouple X11 logic from LinuxPlatform (#7598)
Release Notes: - Separated Linux platform and X11-specific code, so that we can add Wayland support now. --------- Co-authored-by: Mikayla <mikayla@zed.dev>
This commit is contained in:
parent
2e7db57e16
commit
266988adea
11 changed files with 337 additions and 215 deletions
|
@ -4,6 +4,7 @@
|
|||
//todo!(linux): remove
|
||||
#![allow(unused_variables)]
|
||||
|
||||
use crate::platform::linux::client_dispatcher::ClientDispatcher;
|
||||
use crate::{PlatformDispatcher, TaskLabel};
|
||||
use async_task::Runnable;
|
||||
use parking::{Parker, Unparker};
|
||||
|
@ -14,11 +15,9 @@ use std::{
|
|||
thread,
|
||||
time::{Duration, Instant},
|
||||
};
|
||||
use xcb::x;
|
||||
|
||||
pub(crate) struct LinuxDispatcher {
|
||||
xcb_connection: Arc<xcb::Connection>,
|
||||
x_listener_window: x::Window,
|
||||
client_dispatcher: Arc<dyn ClientDispatcher + Send + Sync>,
|
||||
parker: Mutex<Parker>,
|
||||
timed_tasks: Mutex<Vec<(Instant, Runnable)>>,
|
||||
main_sender: flume::Sender<Runnable>,
|
||||
|
@ -30,38 +29,16 @@ pub(crate) struct LinuxDispatcher {
|
|||
impl LinuxDispatcher {
|
||||
pub fn new(
|
||||
main_sender: flume::Sender<Runnable>,
|
||||
xcb_connection: &Arc<xcb::Connection>,
|
||||
x_root_index: i32,
|
||||
client_dispatcher: &Arc<dyn ClientDispatcher + Send + Sync>,
|
||||
) -> Self {
|
||||
let x_listener_window = xcb_connection.generate_id();
|
||||
let screen = xcb_connection
|
||||
.get_setup()
|
||||
.roots()
|
||||
.nth(x_root_index as usize)
|
||||
.unwrap();
|
||||
xcb_connection.send_request(&x::CreateWindow {
|
||||
depth: 0,
|
||||
wid: x_listener_window,
|
||||
parent: screen.root(),
|
||||
x: 0,
|
||||
y: 0,
|
||||
width: 1,
|
||||
height: 1,
|
||||
border_width: 0,
|
||||
class: x::WindowClass::InputOnly,
|
||||
visual: screen.root_visual(),
|
||||
value_list: &[],
|
||||
});
|
||||
|
||||
let (background_sender, background_receiver) = flume::unbounded::<Runnable>();
|
||||
let background_thread = thread::spawn(move || {
|
||||
for runnable in background_receiver {
|
||||
let _ignore_panic = panic::catch_unwind(|| runnable.run());
|
||||
}
|
||||
});
|
||||
LinuxDispatcher {
|
||||
xcb_connection: Arc::clone(xcb_connection),
|
||||
x_listener_window,
|
||||
Self {
|
||||
client_dispatcher: Arc::clone(client_dispatcher),
|
||||
parker: Mutex::new(Parker::new()),
|
||||
timed_tasks: Mutex::new(Vec::new()),
|
||||
main_sender,
|
||||
|
@ -72,14 +49,6 @@ impl LinuxDispatcher {
|
|||
}
|
||||
}
|
||||
|
||||
impl Drop for LinuxDispatcher {
|
||||
fn drop(&mut self) {
|
||||
self.xcb_connection.send_request(&x::DestroyWindow {
|
||||
window: self.x_listener_window,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
impl PlatformDispatcher for LinuxDispatcher {
|
||||
fn is_main_thread(&self) -> bool {
|
||||
thread::current().id() == self.main_thread_id
|
||||
|
@ -91,18 +60,7 @@ impl PlatformDispatcher for LinuxDispatcher {
|
|||
|
||||
fn dispatch_on_main_thread(&self, runnable: Runnable) {
|
||||
self.main_sender.send(runnable).unwrap();
|
||||
// Send a message to the invisible window, forcing
|
||||
// the main loop to wake up and dispatch the runnable.
|
||||
self.xcb_connection.send_request(&x::SendEvent {
|
||||
propagate: false,
|
||||
destination: x::SendEventDest::Window(self.x_listener_window),
|
||||
event_mask: x::EventMask::NO_EVENT,
|
||||
event: &x::VisibilityNotifyEvent::new(
|
||||
self.x_listener_window,
|
||||
x::Visibility::Unobscured,
|
||||
),
|
||||
});
|
||||
self.xcb_connection.flush().unwrap();
|
||||
self.client_dispatcher.dispatch_on_main_thread();
|
||||
}
|
||||
|
||||
fn dispatch_after(&self, duration: Duration, runnable: Runnable) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue