Remove unused synchronization

co-authored-by: julia <julia@zed.dev>
This commit is contained in:
Mikayla Maki 2024-02-28 13:40:36 -08:00
parent 2d1602322e
commit b7d6d5281e
2 changed files with 115 additions and 111 deletions

View file

@ -1,8 +1,8 @@
use std::sync::atomic::{AtomicU32, AtomicU64, Ordering};
use std::borrow::Borrow;
use std::cell::{Cell, RefCell};
use std::time::Duration;
use std::{rc::Rc, sync::Arc};
use std::rc::Rc;
use parking_lot::Mutex;
use xcb::{x, Xid as _};
use xkbcommon::xkb;
@ -26,11 +26,11 @@ pub(crate) struct X11ClientState {
pub(crate) struct X11Client {
platform_inner: Rc<LinuxPlatformInner>,
xcb_connection: Arc<xcb::Connection>,
xcb_connection: Rc<xcb::Connection>,
x_root_index: i32,
atoms: XcbAtoms,
refresh_millis: AtomicU64,
state: Mutex<X11ClientState>,
refresh_millis: Cell<u64>,
state: RefCell<X11ClientState>,
}
impl X11Client {
@ -55,7 +55,7 @@ impl X11Client {
assert!(xkb_ver.supported());
let atoms = XcbAtoms::intern_all(&xcb_connection).unwrap();
let xcb_connection = Arc::new(xcb_connection);
let xcb_connection = Rc::new(xcb_connection);
let xkb_context = xkb::Context::new(xkb::CONTEXT_NO_FLAGS);
let xkb_device_id = xkb::x11::get_core_keyboard_device_id(&xcb_connection);
let xkb_keymap = xkb::x11::keymap_new_from_device(
@ -69,12 +69,12 @@ impl X11Client {
xkb::x11::state_new_from_device(&xkb_keymap, &xcb_connection, xkb_device_id);
let client: Rc<X11Client> = Rc::new(Self {
platform_inner: Rc::clone(&inner),
xcb_connection: Arc::clone(&xcb_connection),
platform_inner: inner.clone(),
xcb_connection: xcb_connection.clone(),
x_root_index,
atoms,
refresh_millis: AtomicU64::new(8),
state: Mutex::new(X11ClientState {
refresh_millis: Cell::new(16),
state: RefCell::new(X11ClientState {
windows: HashMap::default(),
windows_to_refresh: HashSet::default(),
xkb: xkb_state,
@ -82,7 +82,7 @@ impl X11Client {
});
// Safety: Safe if xcb::Connection always returns a valid fd
let fd = unsafe { FdWrapper::new(Arc::clone(&xcb_connection)) };
let fd = unsafe { FdWrapper::new(xcb_connection.clone()) };
inner
.loop_handle
@ -93,7 +93,7 @@ impl X11Client {
calloop::Mode::Level,
),
{
let client = Rc::clone(&client);
let client = client.clone();
move |readiness, _, _| {
if readiness.readable || readiness.error {
while let Some(event) = xcb_connection.poll_for_event()? {
@ -110,14 +110,14 @@ impl X11Client {
.loop_handle
.insert_source(
calloop::timer::Timer::from_duration(Duration::from_millis(
client.refresh_millis.load(Ordering::Relaxed),
client.refresh_millis.get(),
)),
{
let client = client.clone();
move |_, _, _| {
client.present();
calloop::timer::TimeoutAction::ToDuration(Duration::from_millis(
client.refresh_millis.load(Ordering::Relaxed),
client.refresh_millis.get(),
))
}
},
@ -127,62 +127,70 @@ impl X11Client {
client
}
fn get_window(&self, win: x::Window) -> Rc<X11WindowState> {
let state = self.state.lock();
// todo!(linux): This might be called when the windows are empty.
Rc::clone(&state.windows[&win])
fn get_window(&self, win: x::Window) -> Option<Rc<X11WindowState>> {
let state = self.state.borrow();
state.windows.get(&win).cloned()
}
fn present(&self) {
let state = self.state.lock();
let state = self.state.borrow_mut();
for window_state in state.windows.values() {
window_state.refresh();
}
}
fn handle_event(&self, event: xcb::Event) {
fn handle_event(&self, event: xcb::Event) -> Option<()> {
match event {
xcb::Event::X(x::Event::ClientMessage(ev)) => {
if let x::ClientMessageData::Data32([atom, ..]) = ev.data() {
xcb::Event::X(x::Event::ClientMessage(event)) => {
if let x::ClientMessageData::Data32([atom, ..]) = event.data() {
if atom == self.atoms.wm_del_window.resource_id() {
self.state.lock().windows_to_refresh.remove(&ev.window());
self.state
.borrow_mut()
.windows_to_refresh
.remove(&event.window());
// window "x" button clicked by user, we gracefully exit
let window = self.state.lock().windows.remove(&ev.window()).unwrap();
let window = self
.state
.borrow_mut()
.windows
.remove(&event.window())
.unwrap();
window.destroy();
let state = self.state.lock();
let state = self.state.borrow();
if state.windows.is_empty() {
self.platform_inner.loop_signal.stop();
}
}
}
}
xcb::Event::X(x::Event::ConfigureNotify(ev)) => {
xcb::Event::X(x::Event::ConfigureNotify(event)) => {
let bounds = Bounds {
origin: Point {
x: ev.x().into(),
y: ev.y().into(),
x: event.x().into(),
y: event.y().into(),
},
size: Size {
width: ev.width().into(),
height: ev.height().into(),
width: event.width().into(),
height: event.height().into(),
},
};
self.get_window(ev.window()).configure(bounds)
let window = self.get_window(event.window())?;
window.configure(bounds);
}
xcb::Event::X(x::Event::FocusIn(ev)) => {
let window = self.get_window(ev.event());
xcb::Event::X(x::Event::FocusIn(event)) => {
let window = self.get_window(event.event())?;
window.set_focused(true);
}
xcb::Event::X(x::Event::FocusOut(ev)) => {
let window = self.get_window(ev.event());
xcb::Event::X(x::Event::FocusOut(event)) => {
let window = self.get_window(event.event())?;
window.set_focused(false);
}
xcb::Event::X(x::Event::KeyPress(ev)) => {
let window = self.get_window(ev.event());
let modifiers = super::modifiers_from_state(ev.state());
xcb::Event::X(x::Event::KeyPress(event)) => {
let window = self.get_window(event.event())?;
let modifiers = super::modifiers_from_state(event.state());
let keystroke = {
let code = ev.detail().into();
let mut state = self.state.lock();
let code = event.detail().into();
let mut state = self.state.borrow_mut();
let keystroke = crate::Keystroke::from_xkb(&state.xkb, modifiers, code);
state.xkb.update_key(code, xkb::KeyDirection::Down);
keystroke
@ -193,12 +201,12 @@ impl X11Client {
is_held: false,
}));
}
xcb::Event::X(x::Event::KeyRelease(ev)) => {
let window = self.get_window(ev.event());
let modifiers = super::modifiers_from_state(ev.state());
xcb::Event::X(x::Event::KeyRelease(event)) => {
let window = self.get_window(event.event())?;
let modifiers = super::modifiers_from_state(event.state());
let keystroke = {
let code = ev.detail().into();
let mut state = self.state.lock();
let code = event.detail().into();
let mut state = self.state.borrow_mut();
let keystroke = crate::Keystroke::from_xkb(&state.xkb, modifiers, code);
state.xkb.update_key(code, xkb::KeyDirection::Up);
keystroke
@ -206,21 +214,21 @@ impl X11Client {
window.handle_input(PlatformInput::KeyUp(crate::KeyUpEvent { keystroke }));
}
xcb::Event::X(x::Event::ButtonPress(ev)) => {
let window = self.get_window(ev.event());
let modifiers = super::modifiers_from_state(ev.state());
xcb::Event::X(x::Event::ButtonPress(event)) => {
let window = self.get_window(event.event())?;
let modifiers = super::modifiers_from_state(event.state());
let position =
Point::new((ev.event_x() as f32).into(), (ev.event_y() as f32).into());
if let Some(button) = super::button_of_key(ev.detail()) {
Point::new((event.event_x() as f32).into(), (event.event_y() as f32).into());
if let Some(button) = super::button_of_key(event.detail()) {
window.handle_input(PlatformInput::MouseDown(crate::MouseDownEvent {
button,
position,
modifiers,
click_count: 1,
}));
} else if ev.detail() >= 4 && ev.detail() <= 5 {
} else if event.detail() >= 4 && event.detail() <= 5 {
// https://stackoverflow.com/questions/15510472/scrollwheel-event-in-x11
let delta_x = if ev.detail() == 4 { 1.0 } else { -1.0 };
let delta_x = if event.detail() == 4 { 1.0 } else { -1.0 };
window.handle_input(PlatformInput::ScrollWheel(crate::ScrollWheelEvent {
position,
delta: ScrollDelta::Lines(Point::new(0.0, delta_x)),
@ -228,15 +236,15 @@ impl X11Client {
touch_phase: TouchPhase::default(),
}));
} else {
log::warn!("Unknown button press: {ev:?}");
log::warn!("Unknown button press: {event:?}");
}
}
xcb::Event::X(x::Event::ButtonRelease(ev)) => {
let window = self.get_window(ev.event());
let modifiers = super::modifiers_from_state(ev.state());
xcb::Event::X(x::Event::ButtonRelease(event)) => {
let window = self.get_window(event.event())?;
let modifiers = super::modifiers_from_state(event.state());
let position =
Point::new((ev.event_x() as f32).into(), (ev.event_y() as f32).into());
if let Some(button) = super::button_of_key(ev.detail()) {
Point::new((event.event_x() as f32).into(), (event.event_y() as f32).into());
if let Some(button) = super::button_of_key(event.detail()) {
window.handle_input(PlatformInput::MouseUp(crate::MouseUpEvent {
button,
position,
@ -245,24 +253,24 @@ impl X11Client {
}));
}
}
xcb::Event::X(x::Event::MotionNotify(ev)) => {
let window = self.get_window(ev.event());
let pressed_button = super::button_from_state(ev.state());
xcb::Event::X(x::Event::MotionNotify(event)) => {
let window = self.get_window(event.event())?;
let pressed_button = super::button_from_state(event.state());
let position =
Point::new((ev.event_x() as f32).into(), (ev.event_y() as f32).into());
let modifiers = super::modifiers_from_state(ev.state());
Point::new((event.event_x() as f32).into(), (event.event_y() as f32).into());
let modifiers = super::modifiers_from_state(event.state());
window.handle_input(PlatformInput::MouseMove(crate::MouseMoveEvent {
pressed_button,
position,
modifiers,
}));
}
xcb::Event::X(x::Event::LeaveNotify(ev)) => {
let window = self.get_window(ev.event());
let pressed_button = super::button_from_state(ev.state());
xcb::Event::X(x::Event::LeaveNotify(event)) => {
let window = self.get_window(event.event())?;
let pressed_button = super::button_from_state(event.state());
let position =
Point::new((ev.event_x() as f32).into(), (ev.event_y() as f32).into());
let modifiers = super::modifiers_from_state(ev.state());
Point::new((event.event_x() as f32).into(), (event.event_y() as f32).into());
let modifiers = super::modifiers_from_state(event.state());
window.handle_input(PlatformInput::MouseExited(crate::MouseExitEvent {
pressed_button,
position,
@ -270,7 +278,9 @@ impl X11Client {
}));
}
_ => {}
}
};
Some(())
}
}
@ -328,11 +338,10 @@ impl Client for X11Client {
let refresh_millies = mode_refresh_rate_millis(mode).expect("Please just work");
self.refresh_millis
.store(refresh_millies as u64, Ordering::Relaxed);
self.refresh_millis.set(refresh_millies as u64);
self.state
.lock()
.borrow_mut()
.windows
.insert(x_window, Rc::clone(&window_ptr));
Box::new(X11Window(window_ptr))

View file

@ -16,12 +16,7 @@ use xcb::{
};
use std::{
ffi::c_void,
mem,
num::NonZeroU32,
ptr::NonNull,
rc::Rc,
sync::{self, Arc},
cell::RefCell, ffi::c_void, mem, num::NonZeroU32, ptr::NonNull, rc::Rc, sync::{self, Arc}
};
use super::X11Display;
@ -87,12 +82,12 @@ struct RawWindow {
}
pub(crate) struct X11WindowState {
xcb_connection: Arc<xcb::Connection>,
xcb_connection: Rc<xcb::Connection>,
display: Rc<dyn PlatformDisplay>,
raw: RawWindow,
x_window: x::Window,
callbacks: Mutex<Callbacks>,
inner: Mutex<LinuxWindowInner>,
callbacks: RefCell<Callbacks>,
inner: RefCell<LinuxWindowInner>,
}
#[derive(Clone)]
@ -138,7 +133,7 @@ impl rwh::HasDisplayHandle for X11Window {
impl X11WindowState {
pub fn new(
options: WindowOptions,
xcb_connection: &Arc<xcb::Connection>,
xcb_connection: &Rc<xcb::Connection>,
x_main_screen_index: i32,
x_window: x::Window,
atoms: &XcbAtoms,
@ -255,12 +250,12 @@ impl X11WindowState {
let gpu_extent = query_render_extent(xcb_connection, x_window);
Self {
xcb_connection: Arc::clone(xcb_connection),
xcb_connection: xcb_connection.clone(),
display: Rc::new(X11Display::new(xcb_connection, x_screen_index)),
raw,
x_window,
callbacks: Mutex::new(Callbacks::default()),
inner: Mutex::new(LinuxWindowInner {
callbacks: RefCell::new(Callbacks::default()),
inner: RefCell ::new(LinuxWindowInner {
bounds,
scale_factor: 1.0,
renderer: BladeRenderer::new(gpu, gpu_extent),
@ -270,25 +265,25 @@ impl X11WindowState {
}
pub fn destroy(&self) {
self.inner.lock().renderer.destroy();
self.inner.borrow_mut().renderer.destroy();
self.xcb_connection.send_request(&x::UnmapWindow {
window: self.x_window,
});
self.xcb_connection.send_request(&x::DestroyWindow {
window: self.x_window,
});
if let Some(fun) = self.callbacks.lock().close.take() {
if let Some(fun) = self.callbacks.borrow_mut().close.take() {
fun();
}
self.xcb_connection.flush().unwrap();
}
pub fn refresh(&self) {
let mut cb = self.callbacks.lock();
let mut cb = self.callbacks.borrow_mut();
if let Some(mut fun) = cb.request_frame.take() {
drop(cb);
fun();
let mut cb = self.callbacks.lock();
let mut cb = self.callbacks.borrow_mut();
cb.request_frame = Some(fun);
}
}
@ -297,7 +292,7 @@ impl X11WindowState {
let mut resize_args = None;
let do_move;
{
let mut inner = self.inner.lock();
let mut inner = self.inner.borrow_mut();
let old_bounds = mem::replace(&mut inner.bounds, bounds);
do_move = old_bounds.origin != bounds.origin;
//todo!(linux): use normal GPUI types here, refactor out the double
@ -311,7 +306,7 @@ impl X11WindowState {
}
}
let mut callbacks = self.callbacks.lock();
let mut callbacks = self.callbacks.borrow_mut();
if let Some((content_size, scale_factor)) = resize_args {
if let Some(ref mut fun) = callbacks.resize {
fun(content_size, scale_factor)
@ -335,13 +330,13 @@ impl X11WindowState {
}
pub fn handle_input(&self, input: PlatformInput) {
if let Some(ref mut fun) = self.callbacks.lock().input {
if let Some(ref mut fun) = self.callbacks.borrow_mut().input {
if fun(input.clone()) {
return;
}
}
if let PlatformInput::KeyDown(event) = input {
let mut inner = self.inner.lock();
let mut inner = self.inner.borrow_mut();
if let Some(ref mut input_handler) = inner.input_handler {
if let Some(ime_key) = &event.keystroke.ime_key {
input_handler.replace_text_in_range(None, ime_key);
@ -351,7 +346,7 @@ impl X11WindowState {
}
pub fn set_focused(&self, focus: bool) {
if let Some(ref mut fun) = self.callbacks.lock().active_status_change {
if let Some(ref mut fun) = self.callbacks.borrow_mut().active_status_change {
fun(focus);
}
}
@ -359,15 +354,15 @@ impl X11WindowState {
impl PlatformWindow for X11Window {
fn bounds(&self) -> WindowBounds {
WindowBounds::Fixed(self.0.inner.lock().bounds.map(|v| GlobalPixels(v as f32)))
WindowBounds::Fixed(self.0.inner.borrow_mut().bounds.map(|v| GlobalPixels(v as f32)))
}
fn content_size(&self) -> Size<Pixels> {
self.0.inner.lock().content_size()
self.0.inner.borrow_mut().content_size()
}
fn scale_factor(&self) -> f32 {
self.0.inner.lock().scale_factor
self.0.inner.borrow_mut().scale_factor
}
//todo!(linux)
@ -405,11 +400,11 @@ impl PlatformWindow for X11Window {
}
fn set_input_handler(&mut self, input_handler: PlatformInputHandler) {
self.0.inner.lock().input_handler = Some(input_handler);
self.0.inner.borrow_mut().input_handler = Some(input_handler);
}
fn take_input_handler(&mut self) -> Option<PlatformInputHandler> {
self.0.inner.lock().input_handler.take()
self.0.inner.borrow_mut().input_handler.take()
}
//todo!(linux)
@ -469,39 +464,39 @@ impl PlatformWindow for X11Window {
}
fn on_request_frame(&self, callback: Box<dyn FnMut()>) {
self.0.callbacks.lock().request_frame = Some(callback);
self.0.callbacks.borrow_mut().request_frame = Some(callback);
}
fn on_input(&self, callback: Box<dyn FnMut(PlatformInput) -> bool>) {
self.0.callbacks.lock().input = Some(callback);
self.0.callbacks.borrow_mut().input = Some(callback);
}
fn on_active_status_change(&self, callback: Box<dyn FnMut(bool)>) {
self.0.callbacks.lock().active_status_change = Some(callback);
self.0.callbacks.borrow_mut().active_status_change = Some(callback);
}
fn on_resize(&self, callback: Box<dyn FnMut(Size<Pixels>, f32)>) {
self.0.callbacks.lock().resize = Some(callback);
self.0.callbacks.borrow_mut().resize = Some(callback);
}
fn on_fullscreen(&self, callback: Box<dyn FnMut(bool)>) {
self.0.callbacks.lock().fullscreen = Some(callback);
self.0.callbacks.borrow_mut().fullscreen = Some(callback);
}
fn on_moved(&self, callback: Box<dyn FnMut()>) {
self.0.callbacks.lock().moved = Some(callback);
self.0.callbacks.borrow_mut().moved = Some(callback);
}
fn on_should_close(&self, callback: Box<dyn FnMut() -> bool>) {
self.0.callbacks.lock().should_close = Some(callback);
self.0.callbacks.borrow_mut().should_close = Some(callback);
}
fn on_close(&self, callback: Box<dyn FnOnce()>) {
self.0.callbacks.lock().close = Some(callback);
self.0.callbacks.borrow_mut().close = Some(callback);
}
fn on_appearance_changed(&self, callback: Box<dyn FnMut()>) {
self.0.callbacks.lock().appearance_changed = Some(callback);
self.0.callbacks.borrow_mut().appearance_changed = Some(callback);
}
//todo!(linux)
@ -510,12 +505,12 @@ impl PlatformWindow for X11Window {
}
fn draw(&self, scene: &Scene) {
let mut inner = self.0.inner.lock();
let mut inner = self.0.inner.borrow_mut();
inner.renderer.draw(scene);
}
fn sprite_atlas(&self) -> sync::Arc<dyn PlatformAtlas> {
let inner = self.0.inner.lock();
let inner = self.0.inner.borrow_mut();
inner.renderer.sprite_atlas().clone()
}