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 =>
|
define_roles!(Roles =>
|
||||||
[ XdgSurface, XdgSurfaceRole ]
|
[ XdgSurface, XdgSurfaceRole ]
|
||||||
|
@ -47,6 +50,7 @@ pub type MyCompositorToken = CompositorToken<Roles>;
|
||||||
|
|
||||||
pub fn init_shell(
|
pub fn init_shell(
|
||||||
display: &mut Display,
|
display: &mut Display,
|
||||||
|
buffer_utils: BufferUtils,
|
||||||
log: ::slog::Logger,
|
log: ::slog::Logger,
|
||||||
) -> (
|
) -> (
|
||||||
CompositorToken<Roles>,
|
CompositorToken<Roles>,
|
||||||
|
@ -58,7 +62,7 @@ pub fn init_shell(
|
||||||
let (compositor_token, _, _) = compositor_init(
|
let (compositor_token, _, _) = compositor_init(
|
||||||
display,
|
display,
|
||||||
move |request, surface, ctoken| match request {
|
move |request, surface, ctoken| match request {
|
||||||
SurfaceEvent::Commit => surface_commit(&surface, ctoken),
|
SurfaceEvent::Commit => surface_commit(&surface, ctoken, &buffer_utils),
|
||||||
SurfaceEvent::Frame { callback } => callback
|
SurfaceEvent::Frame { callback } => callback
|
||||||
.implement_closure(|_, _| unreachable!(), None::<fn(_)>, ())
|
.implement_closure(|_, _| unreachable!(), None::<fn(_)>, ())
|
||||||
.done(0),
|
.done(0),
|
||||||
|
@ -138,10 +142,15 @@ pub fn init_shell(
|
||||||
pub struct SurfaceData {
|
pub struct SurfaceData {
|
||||||
pub buffer: Option<wl_buffer::WlBuffer>,
|
pub buffer: Option<wl_buffer::WlBuffer>,
|
||||||
pub texture: Option<crate::glium_drawer::TextureMetadata>,
|
pub texture: Option<crate::glium_drawer::TextureMetadata>,
|
||||||
|
pub dimensions: Option<(i32, i32)>,
|
||||||
pub input_region: Option<RegionAttributes>,
|
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| {
|
token.with_surface_data(surface, |attributes| {
|
||||||
attributes.user_data.insert_if_missing(SurfaceData::default);
|
attributes.user_data.insert_if_missing(SurfaceData::default);
|
||||||
let data = attributes.user_data.get_mut::<SurfaceData>().unwrap();
|
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();
|
old_buffer.release();
|
||||||
}
|
}
|
||||||
data.texture = None;
|
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) => {
|
Some(None) => {
|
||||||
// erase the contents
|
// erase the contents
|
||||||
|
@ -164,6 +175,7 @@ fn surface_commit(surface: &wl_surface::WlSurface, token: CompositorToken<Roles>
|
||||||
old_buffer.release();
|
old_buffer.release();
|
||||||
}
|
}
|
||||||
data.texture = None;
|
data.texture = None;
|
||||||
|
data.dimensions = None;
|
||||||
}
|
}
|
||||||
None => {}
|
None => {}
|
||||||
}
|
}
|
||||||
|
@ -171,12 +183,10 @@ fn surface_commit(surface: &wl_surface::WlSurface, token: CompositorToken<Roles>
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_size(attrs: &SurfaceAttributes) -> Option<(i32, i32)> {
|
fn get_size(attrs: &SurfaceAttributes) -> Option<(i32, i32)> {
|
||||||
attrs.user_data.get::<SurfaceData>().and_then(|data| {
|
attrs
|
||||||
data.texture
|
.user_data
|
||||||
.as_ref()
|
.get::<SurfaceData>()
|
||||||
.map(|ref meta| meta.dimensions)
|
.and_then(|data| data.dimensions)
|
||||||
.map(|(x, y)| (x as i32, y as i32))
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn contains_point(attrs: &SurfaceAttributes, point: (f64, f64)) -> bool {
|
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::glium_drawer::GliumDrawer;
|
||||||
use crate::input_handler::AnvilInputHandler;
|
use crate::input_handler::AnvilInputHandler;
|
||||||
use crate::shell::{init_shell, MyWindowMap, Roles};
|
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")]
|
#[cfg(feature = "egl")]
|
||||||
let active_egl_context = Rc::new(RefCell::new(None));
|
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));
|
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());
|
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
|
* Initialize session
|
||||||
|
|
|
@ -23,6 +23,7 @@ use smithay::{
|
||||||
|
|
||||||
use slog::Logger;
|
use slog::Logger;
|
||||||
|
|
||||||
|
use crate::buffer_utils::BufferUtils;
|
||||||
use crate::glium_drawer::GliumDrawer;
|
use crate::glium_drawer::GliumDrawer;
|
||||||
use crate::input_handler::AnvilInputHandler;
|
use crate::input_handler::AnvilInputHandler;
|
||||||
use crate::shell::init_shell;
|
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();
|
let (w, h) = renderer.get_framebuffer_dimensions();
|
||||||
#[cfg(feature = "egl")]
|
#[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"))]
|
#[cfg(not(feature = "egl"))]
|
||||||
let drawer = GliumDrawer::init(renderer, log.clone());
|
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();
|
let name = display.add_socket_auto().unwrap().into_string().unwrap();
|
||||||
info!(log, "Listening on wayland socket"; "name" => name.clone());
|
info!(log, "Listening on wayland socket"; "name" => name.clone());
|
||||||
::std::env::set_var("WAYLAND_DISPLAY", name);
|
::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());
|
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));
|
let dnd_icon = Arc::new(Mutex::new(None));
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue