wayland: surface: add show/hide functionality
While the keyboard is running, it may want to automatically show or hide itself depending on whether a text input is active. Add functions to show and hide the surface by destroying and re-creating it. Phosh's compositor, phoc, does not emit configure events in reaction to a surface being committed with no buffer attached. The complicated surface creation/destruction process is for compatibility with phoc.
This commit is contained in:
parent
53f4daedc0
commit
b5d09e655b
3 changed files with 96 additions and 35 deletions
|
|
@ -145,14 +145,17 @@ impl<T: Dispatch<WlShmPool, u32>
|
||||||
ImgRef::new(ptr, self.width as usize, self.height as usize)
|
ImgRef::new(ptr, self.width as usize, self.height as usize)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn consume(&mut self, surface: &WlSurface) -> Option<ImgRefMut<BGRA<u8>>>
|
pub fn consume(&mut self, surface: Option<&WlSurface>) -> Option<ImgRefMut<BGRA<u8>>>
|
||||||
{
|
{
|
||||||
if self.used {
|
if self.used {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.used = true;
|
self.used = true;
|
||||||
|
|
||||||
|
if let Some(surface) = surface {
|
||||||
surface.attach(Some(&self.buf), 0, 0);
|
surface.attach(Some(&self.buf), 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
// The ARGB format is in little endian.
|
// The ARGB format is in little endian.
|
||||||
let ptr = self.map.as_mut().as_bgra_mut();
|
let ptr = self.map.as_mut().as_bgra_mut();
|
||||||
|
|
|
||||||
|
|
@ -68,7 +68,7 @@ impl Dispatcher {
|
||||||
};
|
};
|
||||||
|
|
||||||
let disp = Surface::new(queue.clone(),
|
let disp = Surface::new(queue.clone(),
|
||||||
&shm, &compositor, &layer_shell,
|
&shm, compositor, layer_shell,
|
||||||
frac_scale_man, vper, 185)?;
|
frac_scale_man, vper, 185)?;
|
||||||
let gfx = Graphics::new(disp);
|
let gfx = Graphics::new(disp);
|
||||||
let gfx = Mutex::new(gfx);
|
let gfx = Mutex::new(gfx);
|
||||||
|
|
|
||||||
|
|
@ -24,13 +24,21 @@ use wayland::viewporter::wp_viewport::WpViewport;
|
||||||
|
|
||||||
pub struct Surface<T> {
|
pub struct Surface<T> {
|
||||||
bufs: [Buffer<T>; 2],
|
bufs: [Buffer<T>; 2],
|
||||||
surface: WlSurface,
|
|
||||||
layer_surf: zwlr_layer_surface_v1::ZwlrLayerSurfaceV1,
|
queue: QueueHandle<T>,
|
||||||
|
comp: WlCompositor,
|
||||||
|
layer_shell: zwlr_layer_shell_v1::ZwlrLayerShellV1,
|
||||||
|
vper: Option<WpViewporter>,
|
||||||
|
fsm: Option<WpFractionalScaleManagerV1>,
|
||||||
|
|
||||||
|
surface: Option<WlSurface>,
|
||||||
|
layer_surf: Option<zwlr_layer_surface_v1::ZwlrLayerSurfaceV1>,
|
||||||
vp: Option<WpViewport>,
|
vp: Option<WpViewport>,
|
||||||
|
|
||||||
used_buf: usize,
|
used_buf: usize,
|
||||||
configured: bool,
|
configured: bool,
|
||||||
scale: u32,
|
scale: u32,
|
||||||
|
height: i32,
|
||||||
}
|
}
|
||||||
|
|
||||||
const LAYER_ANCHOR: zwlr_layer_surface_v1::Anchor
|
const LAYER_ANCHOR: zwlr_layer_surface_v1::Anchor
|
||||||
|
|
@ -46,42 +54,38 @@ impl<T: Dispatch<WlBuffer, u32>
|
||||||
+ Dispatch<WpFractionalScaleV1, ()>
|
+ Dispatch<WpFractionalScaleV1, ()>
|
||||||
+ Dispatch<WpViewport, ()>
|
+ Dispatch<WpViewport, ()>
|
||||||
+ 'static> Surface<T> {
|
+ 'static> Surface<T> {
|
||||||
pub fn new(queue: QueueHandle<T>, shm: &WlShm, comp: &WlCompositor,
|
pub fn new(queue: QueueHandle<T>, shm: &WlShm, comp: WlCompositor,
|
||||||
layer_shell: &zwlr_layer_shell_v1::ZwlrLayerShellV1,
|
layer_shell: zwlr_layer_shell_v1::ZwlrLayerShellV1,
|
||||||
frac_scale_man: Option<WpFractionalScaleManagerV1>,
|
fsm: Option<WpFractionalScaleManagerV1>,
|
||||||
vper: Option<WpViewporter>,
|
vper: Option<WpViewporter>,
|
||||||
size: i32)
|
height: i32)
|
||||||
-> Result<Surface<T>, Error>
|
-> Result<Surface<T>, Error>
|
||||||
{
|
{
|
||||||
let buf1 = Buffer::new(queue.clone(), shm, 0)?;
|
let buf1 = Buffer::new(queue.clone(), shm, 0)?;
|
||||||
let buf2 = Buffer::new(queue.clone(), shm, 1)?;
|
let buf2 = Buffer::new(queue.clone(), shm, 1)?;
|
||||||
|
|
||||||
let surface = comp.create_surface(&queue, ());
|
let mut surf = Surface {
|
||||||
|
|
||||||
let layer_surf = layer_shell.get_layer_surface(&surface, None,
|
|
||||||
zwlr_layer_shell_v1::Layer::Top,
|
|
||||||
String::from("osk-ufkbd"),
|
|
||||||
&queue, ());
|
|
||||||
|
|
||||||
frac_scale_man.map(|fsm| fsm.get_fractional_scale(&surface, &queue, ()));
|
|
||||||
|
|
||||||
let vp = vper.map(|vper| vper.get_viewport(&surface, &queue, ()));
|
|
||||||
|
|
||||||
layer_surf.set_size(0, size as u32);
|
|
||||||
layer_surf.set_exclusive_zone(size);
|
|
||||||
layer_surf.set_anchor(LAYER_ANCHOR);
|
|
||||||
|
|
||||||
surface.commit();
|
|
||||||
|
|
||||||
Ok(Surface {
|
|
||||||
bufs: [buf1, buf2],
|
bufs: [buf1, buf2],
|
||||||
surface,
|
|
||||||
layer_surf,
|
queue: queue.clone(),
|
||||||
vp,
|
comp,
|
||||||
|
layer_shell,
|
||||||
|
vper,
|
||||||
|
fsm,
|
||||||
|
|
||||||
|
surface: None,
|
||||||
|
layer_surf: None,
|
||||||
|
vp: None,
|
||||||
|
|
||||||
used_buf: 1,
|
used_buf: 1,
|
||||||
configured: false,
|
configured: false,
|
||||||
scale: 120,
|
scale: 120,
|
||||||
})
|
height,
|
||||||
|
};
|
||||||
|
|
||||||
|
surf.show();
|
||||||
|
|
||||||
|
Ok(surf)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn configured(&self) -> bool
|
pub fn configured(&self) -> bool
|
||||||
|
|
@ -92,7 +96,7 @@ impl<T: Dispatch<WlBuffer, u32>
|
||||||
pub fn ack_configure(&mut self, serial: u32)
|
pub fn ack_configure(&mut self, serial: u32)
|
||||||
{
|
{
|
||||||
self.configured = true;
|
self.configured = true;
|
||||||
self.layer_surf.ack_configure(serial);
|
self.layer_surf.as_ref().unwrap().ack_configure(serial);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn scale(&self) -> u32
|
pub fn scale(&self) -> u32
|
||||||
|
|
@ -104,6 +108,58 @@ impl<T: Dispatch<WlBuffer, u32>
|
||||||
{
|
{
|
||||||
self.scale = scale;
|
self.scale = scale;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn hide(&mut self)
|
||||||
|
{
|
||||||
|
self.configured = false;
|
||||||
|
|
||||||
|
if let Some(vp) = &self.vp {
|
||||||
|
vp.destroy();
|
||||||
|
self.vp = None;
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(ls) = &self.layer_surf {
|
||||||
|
ls.destroy();
|
||||||
|
self.layer_surf = None;
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(s) = &self.surface {
|
||||||
|
s.destroy();
|
||||||
|
self.surface = None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn show(&mut self)
|
||||||
|
{
|
||||||
|
if self.layer_surf.is_some() || self.surface.is_some() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let surface = self.comp.create_surface(&self.queue, ());
|
||||||
|
|
||||||
|
let layer_surf = self.layer_shell.get_layer_surface(&surface, None,
|
||||||
|
zwlr_layer_shell_v1::Layer::Top,
|
||||||
|
String::from("osk"),
|
||||||
|
&self.queue, ());
|
||||||
|
|
||||||
|
self.fsm.as_ref().map(|fsm| {
|
||||||
|
fsm.get_fractional_scale(&surface, &self.queue, ())
|
||||||
|
});
|
||||||
|
|
||||||
|
let vp = self.vper.as_ref().map(|vper| {
|
||||||
|
vper.get_viewport(&surface, &self.queue, ())
|
||||||
|
});
|
||||||
|
|
||||||
|
layer_surf.set_size(0, self.height as u32);
|
||||||
|
layer_surf.set_exclusive_zone(self.height);
|
||||||
|
layer_surf.set_anchor(LAYER_ANCHOR);
|
||||||
|
|
||||||
|
surface.commit();
|
||||||
|
|
||||||
|
self.surface = Some(surface);
|
||||||
|
self.layer_surf = Some(layer_surf);
|
||||||
|
self.vp = vp;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Dispatch<WlBuffer, u32>
|
impl<T: Dispatch<WlBuffer, u32>
|
||||||
|
|
@ -123,7 +179,7 @@ impl<T: Dispatch<WlBuffer, u32>
|
||||||
fn begin(&mut self) -> ImgRefMut<BGRA<u8>>
|
fn begin(&mut self) -> ImgRefMut<BGRA<u8>>
|
||||||
{
|
{
|
||||||
for (id, buf) in self.bufs.iter_mut().enumerate() {
|
for (id, buf) in self.bufs.iter_mut().enumerate() {
|
||||||
if let Some(img) = buf.consume(&self.surface) {
|
if let Some(img) = buf.consume(self.surface.as_ref()) {
|
||||||
self.used_buf = id;
|
self.used_buf = id;
|
||||||
return img;
|
return img;
|
||||||
}
|
}
|
||||||
|
|
@ -149,8 +205,10 @@ impl<T: Dispatch<WlBuffer, u32>
|
||||||
|
|
||||||
fn end(&mut self, x: u32, y: u32, width: u32, height: u32)
|
fn end(&mut self, x: u32, y: u32, width: u32, height: u32)
|
||||||
{
|
{
|
||||||
self.surface.damage_buffer(x as i32, y as i32, width as i32, height as i32);
|
if let Some(surface) = &self.surface {
|
||||||
self.surface.commit();
|
surface.damage_buffer(x as i32, y as i32, width as i32, height as i32);
|
||||||
|
surface.commit();
|
||||||
|
}
|
||||||
|
|
||||||
for (id, buf) in self.bufs.iter_mut().enumerate() {
|
for (id, buf) in self.bufs.iter_mut().enumerate() {
|
||||||
if id != self.used_buf {
|
if id != self.used_buf {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue