anvil: store buffer dimensions separately
Before this change, the texture size was used for the dimensions. However, the texture is not created until the next rendered frame, which means that frequently size was returned as zero, resulting in pointer focus artifacts. With this change, the dimensions are retrieved immediately on surface commit.
This commit is contained in:
parent
825995687a
commit
a224f774ee
|
@ -28,7 +28,10 @@ use smithay::{
|
|||
},
|
||||
};
|
||||
|
||||
use crate::window_map::{Kind as SurfaceKind, WindowMap};
|
||||
use crate::{
|
||||
buffer_utils::BufferUtils,
|
||||
window_map::{Kind as SurfaceKind, WindowMap},
|
||||
};
|
||||
|
||||
define_roles!(Roles =>
|
||||
[ XdgSurface, XdgSurfaceRole ]
|
||||
|
@ -47,6 +50,7 @@ pub type MyCompositorToken = CompositorToken<Roles>;
|
|||
|
||||
pub fn init_shell(
|
||||
display: &mut Display,
|
||||
buffer_utils: BufferUtils,
|
||||
log: ::slog::Logger,
|
||||
) -> (
|
||||
CompositorToken<Roles>,
|
||||
|
@ -58,7 +62,7 @@ pub fn init_shell(
|
|||
let (compositor_token, _, _) = compositor_init(
|
||||
display,
|
||||
move |request, surface, ctoken| match request {
|
||||
SurfaceEvent::Commit => surface_commit(&surface, ctoken),
|
||||
SurfaceEvent::Commit => surface_commit(&surface, ctoken, &buffer_utils),
|
||||
SurfaceEvent::Frame { callback } => callback
|
||||
.implement_closure(|_, _| unreachable!(), None::<fn(_)>, ())
|
||||
.done(0),
|
||||
|
@ -138,10 +142,15 @@ pub fn init_shell(
|
|||
pub struct SurfaceData {
|
||||
pub buffer: Option<wl_buffer::WlBuffer>,
|
||||
pub texture: Option<crate::glium_drawer::TextureMetadata>,
|
||||
pub dimensions: Option<(i32, i32)>,
|
||||
pub input_region: Option<RegionAttributes>,
|
||||
}
|
||||
|
||||
fn surface_commit(surface: &wl_surface::WlSurface, token: CompositorToken<Roles>) {
|
||||
fn surface_commit(
|
||||
surface: &wl_surface::WlSurface,
|
||||
token: CompositorToken<Roles>,
|
||||
buffer_utils: &BufferUtils,
|
||||
) {
|
||||
token.with_surface_data(surface, |attributes| {
|
||||
attributes.user_data.insert_if_missing(SurfaceData::default);
|
||||
let data = attributes.user_data.get_mut::<SurfaceData>().unwrap();
|
||||
|
@ -157,6 +166,8 @@ fn surface_commit(surface: &wl_surface::WlSurface, token: CompositorToken<Roles>
|
|||
old_buffer.release();
|
||||
}
|
||||
data.texture = None;
|
||||
// If this fails, the buffer will be discarded later by the drawing code.
|
||||
data.dimensions = buffer_utils.dimensions(data.buffer.as_ref().unwrap());
|
||||
}
|
||||
Some(None) => {
|
||||
// erase the contents
|
||||
|
@ -164,6 +175,7 @@ fn surface_commit(surface: &wl_surface::WlSurface, token: CompositorToken<Roles>
|
|||
old_buffer.release();
|
||||
}
|
||||
data.texture = None;
|
||||
data.dimensions = None;
|
||||
}
|
||||
None => {}
|
||||
}
|
||||
|
@ -171,12 +183,10 @@ fn surface_commit(surface: &wl_surface::WlSurface, token: CompositorToken<Roles>
|
|||
}
|
||||
|
||||
fn get_size(attrs: &SurfaceAttributes) -> Option<(i32, i32)> {
|
||||
attrs.user_data.get::<SurfaceData>().and_then(|data| {
|
||||
data.texture
|
||||
.as_ref()
|
||||
.map(|ref meta| meta.dimensions)
|
||||
.map(|(x, y)| (x as i32, y as i32))
|
||||
})
|
||||
attrs
|
||||
.user_data
|
||||
.get::<SurfaceData>()
|
||||
.and_then(|data| data.dimensions)
|
||||
}
|
||||
|
||||
fn contains_point(attrs: &SurfaceAttributes, point: (f64, f64)) -> bool {
|
||||
|
|
|
@ -61,6 +61,7 @@ use smithay::{
|
|||
},
|
||||
};
|
||||
|
||||
use crate::buffer_utils::BufferUtils;
|
||||
use crate::glium_drawer::GliumDrawer;
|
||||
use crate::input_handler::AnvilInputHandler;
|
||||
use crate::shell::{init_shell, MyWindowMap, Roles};
|
||||
|
@ -85,6 +86,11 @@ pub fn run_udev(mut display: Display, mut event_loop: EventLoop<()>, log: Logger
|
|||
#[cfg(feature = "egl")]
|
||||
let active_egl_context = Rc::new(RefCell::new(None));
|
||||
|
||||
#[cfg(feature = "egl")]
|
||||
let buffer_utils = BufferUtils::new(active_egl_context.clone(), log.clone());
|
||||
#[cfg(not(feature = "egl"))]
|
||||
let buffer_utils = BufferUtils::new(log.clone());
|
||||
|
||||
let display = Rc::new(RefCell::new(display));
|
||||
|
||||
/*
|
||||
|
@ -92,7 +98,8 @@ pub fn run_udev(mut display: Display, mut event_loop: EventLoop<()>, log: Logger
|
|||
*/
|
||||
init_shm_global(&mut display.borrow_mut(), vec![], log.clone());
|
||||
|
||||
let (compositor_token, _, _, window_map) = init_shell(&mut display.borrow_mut(), log.clone());
|
||||
let (compositor_token, _, _, window_map) =
|
||||
init_shell(&mut display.borrow_mut(), buffer_utils, log.clone());
|
||||
|
||||
/*
|
||||
* Initialize session
|
||||
|
|
|
@ -23,6 +23,7 @@ use smithay::{
|
|||
|
||||
use slog::Logger;
|
||||
|
||||
use crate::buffer_utils::BufferUtils;
|
||||
use crate::glium_drawer::GliumDrawer;
|
||||
use crate::input_handler::AnvilInputHandler;
|
||||
use crate::shell::init_shell;
|
||||
|
@ -42,10 +43,15 @@ pub fn run_winit(display: &mut Display, event_loop: &mut EventLoop<()>, log: Log
|
|||
|
||||
let (w, h) = renderer.get_framebuffer_dimensions();
|
||||
#[cfg(feature = "egl")]
|
||||
let drawer = GliumDrawer::init(renderer, egl_display, log.clone());
|
||||
let drawer = GliumDrawer::init(renderer, egl_display.clone(), log.clone());
|
||||
#[cfg(not(feature = "egl"))]
|
||||
let drawer = GliumDrawer::init(renderer, log.clone());
|
||||
|
||||
#[cfg(feature = "egl")]
|
||||
let buffer_utils = BufferUtils::new(egl_display, log.clone());
|
||||
#[cfg(not(feature = "egl"))]
|
||||
let buffer_utils = BufferUtils::new(log.clone());
|
||||
|
||||
let name = display.add_socket_auto().unwrap().into_string().unwrap();
|
||||
info!(log, "Listening on wayland socket"; "name" => name.clone());
|
||||
::std::env::set_var("WAYLAND_DISPLAY", name);
|
||||
|
@ -58,7 +64,7 @@ pub fn run_winit(display: &mut Display, event_loop: &mut EventLoop<()>, log: Log
|
|||
|
||||
init_shm_global(display, vec![], log.clone());
|
||||
|
||||
let (compositor_token, _, _, window_map) = init_shell(display, log.clone());
|
||||
let (compositor_token, _, _, window_map) = init_shell(display, buffer_utils, log.clone());
|
||||
|
||||
let dnd_icon = Arc::new(Mutex::new(None));
|
||||
|
||||
|
|
Loading…
Reference in New Issue