wlr-layer-shell support
This commit is contained in:
Generated
+14
@@ -1489,6 +1489,19 @@ dependencies = [
|
|||||||
"wayland-scanner",
|
"wayland-scanner",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wayland-protocols-wlr"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fce991093320e4a6a525876e6b629ab24da25f9baef0c2e0080ad173ec89588a"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags",
|
||||||
|
"wayland-backend",
|
||||||
|
"wayland-client",
|
||||||
|
"wayland-protocols",
|
||||||
|
"wayland-scanner",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wayland-scanner"
|
name = "wayland-scanner"
|
||||||
version = "0.30.0"
|
version = "0.30.0"
|
||||||
@@ -1630,6 +1643,7 @@ dependencies = [
|
|||||||
"walkdir",
|
"walkdir",
|
||||||
"wayland-client",
|
"wayland-client",
|
||||||
"wayland-protocols",
|
"wayland-protocols",
|
||||||
|
"wayland-protocols-wlr",
|
||||||
"xkbcommon",
|
"xkbcommon",
|
||||||
"zbus",
|
"zbus",
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ fontloading = ["fontconfig"]
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
wayland-client = { version = "0.30", features = ["calloop", "log"] }
|
wayland-client = { version = "0.30", features = ["calloop", "log"] }
|
||||||
wayland-protocols = { version = "0.30", features = ["client", "unstable", "staging"] }
|
wayland-protocols = { version = "0.30", features = ["client", "unstable", "staging"] }
|
||||||
|
wayland-protocols-wlr = { version = "0.1", features = ["client"] }
|
||||||
nix = "0.26"
|
nix = "0.26"
|
||||||
memmap = "0.7"
|
memmap = "0.7"
|
||||||
fontconfig = { version = "0.6.0", optional = true }
|
fontconfig = { version = "0.6.0", optional = true }
|
||||||
|
|||||||
+5
-4
@@ -19,7 +19,7 @@ use chrono::{Duration, Local, Timelike};
|
|||||||
use buffer::BufferView;
|
use buffer::BufferView;
|
||||||
use color::Color;
|
use color::Color;
|
||||||
use fonts::{FontMap, MaybeFontMap};
|
use fonts::{FontMap, MaybeFontMap};
|
||||||
use state::State;
|
use state::{State, OperationMode};
|
||||||
use event::{Event, Events};
|
use event::{Event, Events};
|
||||||
use widgets::{
|
use widgets::{
|
||||||
Audio, Backlight, Battery, Calendar, Clock, Date, Geometry, HorizontalLayout, IndexedLayout,
|
Audio, Backlight, Battery, Calendar, Clock, Date, Geometry, HorizontalLayout, IndexedLayout,
|
||||||
@@ -157,7 +157,7 @@ fn main() {
|
|||||||
fm
|
fm
|
||||||
}).unwrap();
|
}).unwrap();
|
||||||
|
|
||||||
let mut state = State::new(widgets, layout, MaybeFontMap::Waiting(font_thread), events);
|
let mut state = State::new(OperationMode::XdgToplevel, widgets, layout, MaybeFontMap::Waiting(font_thread), events);
|
||||||
|
|
||||||
let mut damage = Vec::new();
|
let mut damage = Vec::new();
|
||||||
for _ in 0..state.widgets.len() {
|
for _ in 0..state.widgets.len() {
|
||||||
@@ -199,8 +199,9 @@ fn main() {
|
|||||||
|
|
||||||
let surface = state.base_surface.as_ref().unwrap().clone();
|
let surface = state.base_surface.as_ref().unwrap().clone();
|
||||||
if force {
|
if force {
|
||||||
// Other compositors probably need this.
|
if state.needs_memset {
|
||||||
//bufview.memset(Color::BLACK);
|
bufview.memset(Color::BLACK);
|
||||||
|
}
|
||||||
for (idx, widget) in state.widgets.iter_mut().enumerate() {
|
for (idx, widget) in state.widgets.iter_mut().enumerate() {
|
||||||
if force || widget.get_dirty() {
|
if force || widget.get_dirty() {
|
||||||
let geo = widget.geometry();
|
let geo = widget.geometry();
|
||||||
|
|||||||
+111
-16
@@ -18,6 +18,10 @@ use wayland_protocols::xdg::{
|
|||||||
shell::client::{xdg_surface, xdg_toplevel, xdg_wm_base},
|
shell::client::{xdg_surface, xdg_toplevel, xdg_wm_base},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use wayland_protocols_wlr::layer_shell::v1::client::{
|
||||||
|
zwlr_layer_shell_v1, zwlr_layer_surface_v1,
|
||||||
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
buffer::BufferManager,
|
buffer::BufferManager,
|
||||||
fonts::{FontMap, MaybeFontMap},
|
fonts::{FontMap, MaybeFontMap},
|
||||||
@@ -26,11 +30,20 @@ use crate::{
|
|||||||
event::{Event, Events, PointerEvent, PointerButton},
|
event::{Event, Events, PointerEvent, PointerButton},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub enum OperationMode {
|
||||||
|
LayerSurface((u32, u32)),
|
||||||
|
XdgToplevel,
|
||||||
|
}
|
||||||
|
|
||||||
pub struct State {
|
pub struct State {
|
||||||
|
mode: OperationMode,
|
||||||
pub running: bool,
|
pub running: bool,
|
||||||
pub dirty: bool,
|
pub dirty: bool,
|
||||||
activated: bool,
|
activated: bool,
|
||||||
|
pub needs_memset: bool,
|
||||||
pub base_surface: Option<wl_surface::WlSurface>,
|
pub base_surface: Option<wl_surface::WlSurface>,
|
||||||
|
layer_shell: Option<zwlr_layer_shell_v1::ZwlrLayerShellV1>,
|
||||||
|
layer_surface: Option<zwlr_layer_surface_v1::ZwlrLayerSurfaceV1>,
|
||||||
wm_base: Option<xdg_wm_base::XdgWmBase>,
|
wm_base: Option<xdg_wm_base::XdgWmBase>,
|
||||||
xdg_surface: Option<(xdg_surface::XdgSurface, xdg_toplevel::XdgToplevel)>,
|
xdg_surface: Option<(xdg_surface::XdgSurface, xdg_toplevel::XdgToplevel)>,
|
||||||
wl_shm: Option<wl_shm::WlShm>,
|
wl_shm: Option<wl_shm::WlShm>,
|
||||||
@@ -48,6 +61,7 @@ pub struct State {
|
|||||||
|
|
||||||
impl State {
|
impl State {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
|
mode: OperationMode,
|
||||||
widgets: Vec<Box<dyn Widget>>,
|
widgets: Vec<Box<dyn Widget>>,
|
||||||
layout: Rc<Box<dyn Layout>>,
|
layout: Rc<Box<dyn Layout>>,
|
||||||
fonts: MaybeFontMap,
|
fonts: MaybeFontMap,
|
||||||
@@ -57,7 +71,10 @@ impl State {
|
|||||||
running: true,
|
running: true,
|
||||||
dirty: true,
|
dirty: true,
|
||||||
activated: false,
|
activated: false,
|
||||||
|
needs_memset: true,
|
||||||
base_surface: None,
|
base_surface: None,
|
||||||
|
layer_shell: None,
|
||||||
|
layer_surface: None,
|
||||||
wm_base: None,
|
wm_base: None,
|
||||||
xdg_surface: None,
|
xdg_surface: None,
|
||||||
wl_shm: None,
|
wl_shm: None,
|
||||||
@@ -67,6 +84,7 @@ impl State {
|
|||||||
bufmgr: BufferManager::new(),
|
bufmgr: BufferManager::new(),
|
||||||
keyboard: Keyboard::new(),
|
keyboard: Keyboard::new(),
|
||||||
pointer: None,
|
pointer: None,
|
||||||
|
mode,
|
||||||
widgets,
|
widgets,
|
||||||
fonts,
|
fonts,
|
||||||
events,
|
events,
|
||||||
@@ -97,6 +115,31 @@ impl State {
|
|||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn init_xdg_surface(&mut self, qh: &QueueHandle<State>) {
|
||||||
|
let wm_base = self.wm_base.as_ref().unwrap();
|
||||||
|
let base_surface = self.base_surface.as_ref().unwrap();
|
||||||
|
|
||||||
|
let xdg_surface = wm_base.get_xdg_surface(base_surface, qh, ());
|
||||||
|
let toplevel = xdg_surface.get_toplevel(qh, ());
|
||||||
|
toplevel.set_title("wldash".into());
|
||||||
|
|
||||||
|
base_surface.commit();
|
||||||
|
|
||||||
|
self.xdg_surface = Some((xdg_surface, toplevel));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn init_layer_surface(&mut self, qh: &QueueHandle<State>, size: (u32, u32)) {
|
||||||
|
let layer_shell = self.layer_shell.as_ref().unwrap();
|
||||||
|
let base_surface = self.base_surface.as_ref().unwrap();
|
||||||
|
|
||||||
|
let layer_surface = layer_shell.get_layer_surface(base_surface, None, zwlr_layer_shell_v1::Layer::Top, "launcher".to_string(), qh, ());
|
||||||
|
layer_surface.set_keyboard_interactivity(zwlr_layer_surface_v1::KeyboardInteractivity::Exclusive);
|
||||||
|
layer_surface.set_size(size.0, size.1);
|
||||||
|
|
||||||
|
base_surface.commit();
|
||||||
|
self.layer_surface = Some(layer_surface);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WidgetUpdater for State {
|
impl WidgetUpdater for State {
|
||||||
@@ -126,23 +169,26 @@ impl Dispatch<wl_registry::WlRegistry, ()> for State {
|
|||||||
match &interface[..] {
|
match &interface[..] {
|
||||||
"wl_compositor" => {
|
"wl_compositor" => {
|
||||||
let compositor =
|
let compositor =
|
||||||
registry.bind::<wl_compositor::WlCompositor, _, _>(name, 4, qh, ());
|
registry.bind::<wl_compositor::WlCompositor, _, _>(name, 5, qh, ());
|
||||||
let surface = compositor.create_surface(qh, ());
|
let surface = compositor.create_surface(qh, ());
|
||||||
state.base_surface = Some(surface);
|
state.base_surface = Some(surface);
|
||||||
state.activate(qh);
|
state.activate(qh);
|
||||||
|
|
||||||
if state.wm_base.is_some() && state.xdg_surface.is_none() {
|
if state.wm_base.is_some() && state.xdg_surface.is_none() && state.layer_surface.is_none() {
|
||||||
state.init_xdg_surface(qh);
|
match state.mode {
|
||||||
|
OperationMode::XdgToplevel => state.init_xdg_surface(qh),
|
||||||
|
OperationMode::LayerSurface(size) => state.init_layer_surface(qh, size),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"wl_shm" => {
|
"wl_shm" => {
|
||||||
state.wl_shm = Some(registry.bind::<wl_shm::WlShm, _, _>(name, 1, qh, ()));
|
state.wl_shm = Some(registry.bind::<wl_shm::WlShm, _, _>(name, 1, qh, ()));
|
||||||
}
|
}
|
||||||
"wl_seat" => {
|
"wl_seat" => {
|
||||||
registry.bind::<wl_seat::WlSeat, _, _>(name, 1, qh, ());
|
registry.bind::<wl_seat::WlSeat, _, _>(name, 8, qh, ());
|
||||||
}
|
}
|
||||||
"xdg_wm_base" => {
|
"xdg_wm_base" => if let OperationMode::XdgToplevel = state.mode {
|
||||||
let wm_base = registry.bind::<xdg_wm_base::XdgWmBase, _, _>(name, 1, qh, ());
|
let wm_base = registry.bind::<xdg_wm_base::XdgWmBase, _, _>(name, 2, qh, ());
|
||||||
state.wm_base = Some(wm_base);
|
state.wm_base = Some(wm_base);
|
||||||
|
|
||||||
if state.base_surface.is_some() && state.xdg_surface.is_none() {
|
if state.base_surface.is_some() && state.xdg_surface.is_none() {
|
||||||
@@ -155,6 +201,21 @@ impl Dispatch<wl_registry::WlRegistry, ()> for State {
|
|||||||
);
|
);
|
||||||
state.activate(qh);
|
state.activate(qh);
|
||||||
}
|
}
|
||||||
|
"zwlr_layer_shell_v1" => if let OperationMode::LayerSurface(size) = state.mode {
|
||||||
|
state.layer_shell = Some(
|
||||||
|
registry.bind::<zwlr_layer_shell_v1::ZwlrLayerShellV1, _, _>(name, 4, qh, ()),
|
||||||
|
);
|
||||||
|
if state.base_surface.is_some() && state.layer_surface.is_none() {
|
||||||
|
state.init_layer_surface(qh, size);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"clay_control_v1" => {
|
||||||
|
// Buffers are zeroed by default, which is equivalent to zero alpha black. This
|
||||||
|
// is not a particularly good background, but memsetting is slow. On clay,
|
||||||
|
// toplevels that adhere to their requested dimensions only have black behind
|
||||||
|
// them, so we can save the memset in this case, speeding things up.
|
||||||
|
state.needs_memset = false;
|
||||||
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -226,18 +287,52 @@ impl Dispatch<wl_buffer::WlBuffer, ()> for State {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl State {
|
impl Dispatch<zwlr_layer_shell_v1::ZwlrLayerShellV1, ()> for State {
|
||||||
fn init_xdg_surface(&mut self, qh: &QueueHandle<State>) {
|
fn event(
|
||||||
let wm_base = self.wm_base.as_ref().unwrap();
|
_: &mut Self,
|
||||||
let base_surface = self.base_surface.as_ref().unwrap();
|
_: &zwlr_layer_shell_v1::ZwlrLayerShellV1,
|
||||||
|
_: zwlr_layer_shell_v1::Event,
|
||||||
|
_: &(),
|
||||||
|
_: &Connection,
|
||||||
|
_: &QueueHandle<Self>,
|
||||||
|
) {}
|
||||||
|
}
|
||||||
|
|
||||||
let xdg_surface = wm_base.get_xdg_surface(base_surface, qh, ());
|
impl Dispatch<zwlr_layer_surface_v1::ZwlrLayerSurfaceV1, ()> for State {
|
||||||
let toplevel = xdg_surface.get_toplevel(qh, ());
|
fn event(
|
||||||
toplevel.set_title("wldash".into());
|
state: &mut Self,
|
||||||
|
layer_surface: &zwlr_layer_surface_v1::ZwlrLayerSurfaceV1,
|
||||||
|
event: zwlr_layer_surface_v1::Event,
|
||||||
|
_: &(),
|
||||||
|
_: &Connection,
|
||||||
|
_: &QueueHandle<Self>,
|
||||||
|
) {
|
||||||
|
if let zwlr_layer_surface_v1::Event::Configure { serial, width, height } = event {
|
||||||
|
if (width, height) == (0, 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
layer_surface.ack_configure(serial);
|
||||||
|
state.configured = true;
|
||||||
|
state.dirty = true;
|
||||||
|
|
||||||
base_surface.commit();
|
if state.dimensions != (width as i32, height as i32) {
|
||||||
|
state.bufmgr.clear_buffers();
|
||||||
self.xdg_surface = Some((xdg_surface, toplevel));
|
state.dimensions = (width as i32, height as i32);
|
||||||
|
state.fonts.resolve();
|
||||||
|
let fonts = state.fonts.unwrap();
|
||||||
|
let layout = state.layout.clone();
|
||||||
|
layout.geometry_update(
|
||||||
|
&mut fonts.borrow_mut(),
|
||||||
|
&Geometry {
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
width: width as u32,
|
||||||
|
height: height as u32,
|
||||||
|
},
|
||||||
|
state,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user