Fix or promote leftover TODOs and GPUI APIs (#12514)

fixes https://github.com/zed-industries/zed/issues/11966

Release Notes:

- N/A
This commit is contained in:
Mikayla Maki 2024-05-31 18:36:15 -07:00 committed by GitHub
parent a6e0c8aca1
commit 94c3101fb0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
27 changed files with 581 additions and 441 deletions

View file

@ -2,7 +2,6 @@ use std::cell::RefCell;
use std::ffi::OsString;
use std::ops::Deref;
use std::rc::{Rc, Weak};
use std::sync::OnceLock;
use std::time::{Duration, Instant};
use calloop::generic::{FdWrapper, Generic};
@ -11,30 +10,29 @@ use calloop::{channel, EventLoop, LoopHandle, RegistrationToken};
use collections::HashMap;
use copypasta::x11_clipboard::{Clipboard, Primary, X11ClipboardContext};
use copypasta::ClipboardProvider;
use parking_lot::Mutex;
use util::ResultExt;
use x11rb::connection::{Connection, RequestConnection};
use x11rb::cursor;
use x11rb::errors::ConnectionError;
use x11rb::protocol::randr::ConnectionExt as _;
use x11rb::protocol::xinput::{ConnectionExt, ScrollClass};
use x11rb::protocol::xinput::ConnectionExt;
use x11rb::protocol::xkb::ConnectionExt as _;
use x11rb::protocol::xproto::{ChangeWindowAttributesAux, ConnectionExt as _};
use x11rb::protocol::{randr, render, xinput, xkb, xproto, Event};
use x11rb::resource_manager::Database;
use x11rb::xcb_ffi::XCBConnection;
use xim::{x11rb::X11rbClient, Client};
use xim::{AHashMap, AttributeName, ClientHandler, InputStyle};
use xim::{AttributeName, InputStyle};
use xkbc::x11::ffi::{XKB_X11_MIN_MAJOR_XKB_VERSION, XKB_X11_MIN_MINOR_XKB_VERSION};
use xkbcommon::xkb as xkbc;
use crate::platform::linux::LinuxClient;
use crate::platform::{LinuxCommon, PlatformWindow, WaylandClientState};
use crate::platform::{LinuxCommon, PlatformWindow};
use crate::{
modifiers_from_xinput_info, point, px, AnyWindowHandle, Bounds, CursorStyle, DisplayId,
ForegroundExecutor, Keystroke, Modifiers, ModifiersChangedEvent, Pixels, PlatformDisplay,
PlatformInput, Point, ScrollDelta, Size, TouchPhase, WindowAppearance, WindowParams, X11Window,
Keystroke, Modifiers, ModifiersChangedEvent, Pixels, PlatformDisplay, PlatformInput, Point,
ScrollDelta, Size, TouchPhase, WindowParams, X11Window,
};
use super::{
@ -54,6 +52,12 @@ pub(crate) struct WindowRef {
refresh_event_token: RegistrationToken,
}
impl WindowRef {
pub fn handle(&self) -> AnyWindowHandle {
self.window.state.borrow().handle
}
}
impl Deref for WindowRef {
type Target = X11WindowStatePtr;
@ -104,13 +108,14 @@ pub struct X11ClientState {
pub(crate) xcb_connection: Rc<XCBConnection>,
pub(crate) x_root_index: usize,
pub(crate) resource_database: Database,
pub(crate) _resource_database: Database,
pub(crate) atoms: XcbAtoms,
pub(crate) windows: HashMap<xproto::Window, WindowRef>,
pub(crate) focused_window: Option<xproto::Window>,
pub(crate) xkb: xkbc::State,
pub(crate) ximc: Option<X11rbClient<Rc<XCBConnection>>>,
pub(crate) xim_handler: Option<XimHandler>,
pub modifiers: Modifiers,
pub(crate) compose_state: xkbc::compose::State,
pub(crate) pre_edit_text: Option<String>,
@ -159,11 +164,13 @@ impl X11Client {
let handle = event_loop.handle();
handle.insert_source(main_receiver, |event, _, _: &mut X11Client| {
if let calloop::channel::Event::Msg(runnable) = event {
runnable.run();
}
});
handle
.insert_source(main_receiver, |event, _, _: &mut X11Client| {
if let calloop::channel::Event::Msg(runnable) = event {
runnable.run();
}
})
.unwrap();
let (xcb_connection, x_root_index) = XCBConnection::connect(None).unwrap();
xcb_connection
@ -248,23 +255,7 @@ impl X11Client {
xkbc::compose::State::new(&table, xkbc::compose::STATE_NO_FLAGS)
};
let screen = xcb_connection.setup().roots.get(x_root_index).unwrap();
// Values from `Database::GET_RESOURCE_DATABASE`
let resource_manager = xcb_connection
.get_property(
false,
screen.root,
xproto::AtomEnum::RESOURCE_MANAGER,
xproto::AtomEnum::STRING,
0,
100_000_000,
)
.unwrap();
let resource_manager = resource_manager.reply().unwrap();
// todo(linux): read hostname
let resource_database = Database::new_from_default(&resource_manager, "HOSTNAME".into());
let resource_database = x11rb::resource_manager::new_from_default(&xcb_connection).unwrap();
let scale_factor = resource_database
.get_value("Xft.dpi", "Xft.dpi")
@ -345,7 +336,7 @@ impl X11Client {
.insert_source(xim_rx, {
move |chan_event, _, client| match chan_event {
channel::Event::Msg(xim_event) => {
match (xim_event) {
match xim_event {
XimCallbackEvent::XimXEvent(event) => {
client.handle_event(event);
}
@ -363,18 +354,21 @@ impl X11Client {
}
})
.expect("Failed to initialize XIM event source");
handle.insert_source(XDPEventSource::new(&common.background_executor), {
move |event, _, client| match event {
XDPEvent::WindowAppearance(appearance) => {
client.with_common(|common| common.appearance = appearance);
for (_, window) in &mut client.0.borrow_mut().windows {
window.window.set_appearance(appearance);
handle
.insert_source(XDPEventSource::new(&common.background_executor), {
move |event, _, client| match event {
XDPEvent::WindowAppearance(appearance) => {
client.with_common(|common| common.appearance = appearance);
for (_, window) in &mut client.0.borrow_mut().windows {
window.window.set_appearance(appearance);
}
}
}
}
});
})
.unwrap();
X11Client(Rc::new(RefCell::new(X11ClientState {
modifiers: Modifiers::default(),
event_loop: Some(event_loop),
loop_handle: handle,
common,
@ -385,7 +379,7 @@ impl X11Client {
xcb_connection,
x_root_index,
resource_database,
_resource_database: resource_database,
atoms,
windows: HashMap::default(),
focused_window: None,
@ -446,7 +440,8 @@ impl X11Client {
});
}
}
ximc.create_ic(xim_handler.im_id, ic_attributes.build());
ximc.create_ic(xim_handler.im_id, ic_attributes.build())
.ok();
state = self.0.borrow_mut();
state.xim_handler = Some(xim_handler);
state.ximc = Some(ximc);
@ -457,7 +452,7 @@ impl X11Client {
state.composing = false;
if let Some(mut ximc) = state.ximc.take() {
let xim_handler = state.xim_handler.as_ref().unwrap();
ximc.destroy_ic(xim_handler.im_id, xim_handler.ic_id);
ximc.destroy_ic(xim_handler.im_id, xim_handler.ic_id).ok();
state.ximc = Some(ximc);
}
}
@ -535,6 +530,7 @@ impl X11Client {
);
let modifiers = Modifiers::from_xkb(&state.xkb);
let focused_window_id = state.focused_window?;
state.modifiers = modifiers;
drop(state);
let focused_window = self.get_window(focused_window_id)?;
@ -547,6 +543,8 @@ impl X11Client {
let mut state = self.0.borrow_mut();
let modifiers = modifiers_from_state(event.state);
state.modifiers = modifiers;
let keystroke = {
let code = event.detail.into();
let mut keystroke = crate::Keystroke::from_xkb(&state.xkb, modifiers, code);
@ -600,6 +598,8 @@ impl X11Client {
let mut state = self.0.borrow_mut();
let modifiers = modifiers_from_state(event.state);
state.modifiers = modifiers;
let keystroke = {
let code = event.detail.into();
let keystroke = crate::Keystroke::from_xkb(&state.xkb, modifiers, code);
@ -618,6 +618,8 @@ impl X11Client {
let mut state = self.0.borrow_mut();
let modifiers = modifiers_from_xinput_info(event.mods);
state.modifiers = modifiers;
let position = point(
px(event.event_x as f32 / u16::MAX as f32 / state.scale_factor),
px(event.event_y as f32 / u16::MAX as f32 / state.scale_factor),
@ -664,8 +666,10 @@ impl X11Client {
}
Event::XinputButtonRelease(event) => {
let window = self.get_window(event.event)?;
let state = self.0.borrow();
let mut state = self.0.borrow_mut();
let modifiers = modifiers_from_xinput_info(event.mods);
state.modifiers = modifiers;
let position = point(
px(event.event_x as f32 / u16::MAX as f32 / state.scale_factor),
px(event.event_y as f32 / u16::MAX as f32 / state.scale_factor),
@ -683,14 +687,15 @@ impl X11Client {
}
Event::XinputMotion(event) => {
let window = self.get_window(event.event)?;
let state = self.0.borrow();
let mut state = self.0.borrow_mut();
let pressed_button = pressed_button_from_mask(event.button_mask[0]);
let position = point(
px(event.event_x as f32 / u16::MAX as f32 / state.scale_factor),
px(event.event_y as f32 / u16::MAX as f32 / state.scale_factor),
);
drop(state);
let modifiers = modifiers_from_xinput_info(event.mods);
state.modifiers = modifiers;
drop(state);
let axisvalues = event
.axisvalues
@ -766,13 +771,14 @@ impl X11Client {
self.0.borrow_mut().scroll_y = None;
let window = self.get_window(event.event)?;
let state = self.0.borrow();
let mut state = self.0.borrow_mut();
let pressed_button = pressed_button_from_mask(event.buttons[0]);
let position = point(
px(event.event_x as f32 / u16::MAX as f32 / state.scale_factor),
px(event.event_y as f32 / u16::MAX as f32 / state.scale_factor),
);
let modifiers = modifiers_from_xinput_info(event.mods);
state.modifiers = modifiers;
drop(state);
window.handle_input(PlatformInput::MouseExited(crate::MouseExitEvent {
@ -855,7 +861,8 @@ impl X11Client {
);
})
.build();
ximc.set_ic_values(xim_handler.im_id, xim_handler.ic_id, ic_attributes);
ximc.set_ic_values(xim_handler.im_id, xim_handler.ic_id, ic_attributes)
.ok();
}
let mut state = self.0.borrow_mut();
state.ximc = Some(ximc);
@ -904,13 +911,14 @@ impl LinuxClient for X11Client {
fn open_window(
&self,
_handle: AnyWindowHandle,
handle: AnyWindowHandle,
params: WindowParams,
) -> Box<dyn PlatformWindow> {
let mut state = self.0.borrow_mut();
let x_window = state.xcb_connection.generate_id().unwrap();
let window = X11Window::new(
handle,
X11ClientStatePtr(Rc::downgrade(&self.0)),
state.common.foreground_executor.clone(),
params,
@ -1034,11 +1042,11 @@ impl LinuxClient for X11Client {
}
fn write_to_primary(&self, item: crate::ClipboardItem) {
self.0.borrow_mut().primary.set_contents(item.text);
self.0.borrow_mut().primary.set_contents(item.text).ok();
}
fn write_to_clipboard(&self, item: crate::ClipboardItem) {
self.0.borrow_mut().clipboard.set_contents(item.text);
self.0.borrow_mut().clipboard.set_contents(item.text).ok();
}
fn read_from_primary(&self) -> Option<crate::ClipboardItem> {
@ -1075,6 +1083,16 @@ impl LinuxClient for X11Client {
event_loop.run(None, &mut self.clone(), |_| {}).log_err();
}
fn active_window(&self) -> Option<AnyWindowHandle> {
let state = self.0.borrow();
state.focused_window.and_then(|focused_window| {
state
.windows
.get(&focused_window)
.map(|window| window.handle())
})
}
}
// Adatpted from: