X11: Continuous Presentation (#7762)
Alternative to #7758, which doesn't involve adding a new trait method `request_draw`. Somehow, my whole screen goes blinking black with this when moving the window, so not ready for landing. Release Notes: - N/A --------- Co-authored-by: Mikayla Maki <mikayla@zed.dev>
This commit is contained in:
co-authored by
Mikayla Maki
parent
181f556269
commit
8f7a26f397
@@ -64,7 +64,9 @@ impl Default for LinuxPlatform {
|
||||
|
||||
impl LinuxPlatform {
|
||||
pub(crate) fn new() -> Self {
|
||||
let (xcb_connection, x_root_index) = xcb::Connection::connect(None).unwrap();
|
||||
let (xcb_connection, x_root_index) =
|
||||
xcb::Connection::connect_with_extensions(None, &[xcb::Extension::Present], &[])
|
||||
.unwrap();
|
||||
let atoms = XcbAtoms::intern_all(&xcb_connection).unwrap();
|
||||
|
||||
let xcb_connection = Arc::new(xcb_connection);
|
||||
|
||||
@@ -41,6 +41,11 @@ impl X11Client {
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
fn get_window(&self, win: x::Window) -> Rc<X11WindowState> {
|
||||
let state = self.state.lock();
|
||||
Rc::clone(&state.windows[&win])
|
||||
}
|
||||
}
|
||||
|
||||
impl Client for X11Client {
|
||||
@@ -58,18 +63,14 @@ impl Client for X11Client {
|
||||
// window "x" button clicked by user, we gracefully exit
|
||||
let window = self.state.lock().windows.remove(&ev.window()).unwrap();
|
||||
window.destroy();
|
||||
let mut state = self.state.lock();
|
||||
let state = self.state.lock();
|
||||
self.platform_inner.state.lock().quit_requested |=
|
||||
state.windows.is_empty();
|
||||
}
|
||||
}
|
||||
}
|
||||
xcb::Event::X(x::Event::Expose(ev)) => {
|
||||
let window = {
|
||||
let state = self.state.lock();
|
||||
Rc::clone(&state.windows[&ev.window()])
|
||||
};
|
||||
window.expose();
|
||||
self.get_window(ev.window()).refresh();
|
||||
}
|
||||
xcb::Event::X(x::Event::ConfigureNotify(ev)) => {
|
||||
let bounds = Bounds {
|
||||
@@ -82,12 +83,14 @@ impl Client for X11Client {
|
||||
height: ev.height().into(),
|
||||
},
|
||||
};
|
||||
let window = {
|
||||
let state = self.state.lock();
|
||||
Rc::clone(&state.windows[&ev.window()])
|
||||
};
|
||||
window.configure(bounds)
|
||||
self.get_window(ev.window()).configure(bounds)
|
||||
}
|
||||
xcb::Event::Present(xcb::present::Event::CompleteNotify(ev)) => {
|
||||
let window = self.get_window(ev.window());
|
||||
window.refresh();
|
||||
window.request_refresh();
|
||||
}
|
||||
xcb::Event::Present(xcb::present::Event::IdleNotify(_ev)) => {}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
@@ -117,7 +120,7 @@ impl Client for X11Client {
|
||||
|
||||
fn open_window(
|
||||
&self,
|
||||
handle: AnyWindowHandle,
|
||||
_handle: AnyWindowHandle,
|
||||
options: WindowOptions,
|
||||
) -> Box<dyn PlatformWindow> {
|
||||
let x_window = self.xcb_connection.generate_id();
|
||||
@@ -129,6 +132,7 @@ impl Client for X11Client {
|
||||
x_window,
|
||||
&self.atoms,
|
||||
));
|
||||
window_ptr.request_refresh();
|
||||
|
||||
self.state
|
||||
.lock()
|
||||
|
||||
@@ -202,6 +202,16 @@ impl X11WindowState {
|
||||
})
|
||||
.unwrap();
|
||||
|
||||
let fake_id = xcb_connection.generate_id();
|
||||
xcb_connection
|
||||
.send_and_check_request(&xcb::present::SelectInput {
|
||||
eid: fake_id,
|
||||
window: x_window,
|
||||
//Note: also consider `IDLE_NOTIFY`
|
||||
event_mask: xcb::present::EventMask::COMPLETE_NOTIFY,
|
||||
})
|
||||
.unwrap();
|
||||
|
||||
xcb_connection.send_request(&x::MapWindow { window: x_window });
|
||||
xcb_connection.flush().unwrap();
|
||||
|
||||
@@ -258,7 +268,7 @@ impl X11WindowState {
|
||||
self.xcb_connection.flush().unwrap();
|
||||
}
|
||||
|
||||
pub fn expose(&self) {
|
||||
pub fn refresh(&self) {
|
||||
let mut cb = self.callbacks.lock();
|
||||
if let Some(ref mut fun) = cb.request_frame {
|
||||
fun();
|
||||
@@ -291,6 +301,18 @@ impl X11WindowState {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn request_refresh(&self) {
|
||||
self.xcb_connection
|
||||
.send_and_check_request(&xcb::present::NotifyMsc {
|
||||
window: self.x_window,
|
||||
serial: 0,
|
||||
target_msc: 0,
|
||||
divisor: 1,
|
||||
remainder: 0,
|
||||
})
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
impl PlatformWindow for X11Window {
|
||||
|
||||
Reference in New Issue
Block a user