support resizing, start on layer shell support
This commit is contained in:
parent
9268cb0220
commit
eea1406bd4
5 changed files with 257 additions and 19 deletions
|
|
@ -1,4 +1,5 @@
|
||||||
mod compositor;
|
mod compositor;
|
||||||
|
mod wlr_layer_shell;
|
||||||
mod xdg_activation;
|
mod xdg_activation;
|
||||||
mod xdg_decoration;
|
mod xdg_decoration;
|
||||||
mod xdg_icon;
|
mod xdg_icon;
|
||||||
|
|
|
||||||
30
src/handlers/wlr_layer_shell.rs
Normal file
30
src/handlers/wlr_layer_shell.rs
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
use smithay::{
|
||||||
|
desktop::{layer_map_for_output, LayerSurface},
|
||||||
|
output::Output,
|
||||||
|
wayland::shell::wlr_layer::WlrLayerShellHandler,
|
||||||
|
};
|
||||||
|
use wayland_server::protocol::wl_output::WlOutput;
|
||||||
|
|
||||||
|
use crate::State;
|
||||||
|
|
||||||
|
impl WlrLayerShellHandler for State {
|
||||||
|
fn shell_state(&mut self) -> &mut smithay::wayland::shell::wlr_layer::WlrLayerShellState {
|
||||||
|
&mut self.wlr_layer_shell_state
|
||||||
|
}
|
||||||
|
|
||||||
|
fn new_layer_surface(
|
||||||
|
&mut self,
|
||||||
|
surface: smithay::wayland::shell::wlr_layer::LayerSurface,
|
||||||
|
output: Option<WlOutput>,
|
||||||
|
layer: smithay::wayland::shell::wlr_layer::Layer,
|
||||||
|
namespace: String,
|
||||||
|
) {
|
||||||
|
let output = output
|
||||||
|
.as_ref()
|
||||||
|
.and_then(Output::from_resource)
|
||||||
|
.unwrap_or_else(|| self.space.outputs().next().unwrap().clone());
|
||||||
|
let mut map = layer_map_for_output(&output);
|
||||||
|
map.map_layer(&LayerSurface::new(surface, namespace))
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
use smithay::utils::Point;
|
||||||
|
use smithay::wayland::seat::WaylandFocus;
|
||||||
use smithay::{
|
use smithay::{
|
||||||
desktop::{
|
desktop::{
|
||||||
find_popup_root_surface, get_popup_toplevel_coords, layer_map_for_output,
|
find_popup_root_surface, get_popup_toplevel_coords, layer_map_for_output,
|
||||||
|
|
@ -8,6 +10,7 @@ use smithay::{
|
||||||
pointer::{Focus, GrabStartData as PointerGrabStartData},
|
pointer::{Focus, GrabStartData as PointerGrabStartData},
|
||||||
Seat,
|
Seat,
|
||||||
},
|
},
|
||||||
|
output::Output,
|
||||||
reexports::{
|
reexports::{
|
||||||
wayland_protocols::xdg::shell::server::xdg_toplevel,
|
wayland_protocols::xdg::shell::server::xdg_toplevel,
|
||||||
wayland_server::{
|
wayland_server::{
|
||||||
|
|
@ -24,6 +27,7 @@ use smithay::{
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
use wayland_server::protocol::wl_output;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
grabs::{MoveSurfaceGrab, ResizeSurfaceGrab},
|
grabs::{MoveSurfaceGrab, ResizeSurfaceGrab},
|
||||||
|
|
@ -82,6 +86,11 @@ impl XdgShellHandler for State {
|
||||||
.find(|w| w.window.toplevel().unwrap().wl_surface() == wl_surface)
|
.find(|w| w.window.toplevel().unwrap().wl_surface() == wl_surface)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.clone();
|
.clone();
|
||||||
|
|
||||||
|
if window.is_fullscreen() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let initial_window_location = self.space.element_location(&window).unwrap();
|
let initial_window_location = self.space.element_location(&window).unwrap();
|
||||||
|
|
||||||
let grab = MoveSurfaceGrab {
|
let grab = MoveSurfaceGrab {
|
||||||
|
|
@ -115,6 +124,10 @@ impl XdgShellHandler for State {
|
||||||
.find(|w| w.window.toplevel().unwrap().wl_surface() == wl_surface)
|
.find(|w| w.window.toplevel().unwrap().wl_surface() == wl_surface)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.clone();
|
.clone();
|
||||||
|
|
||||||
|
if window.is_fullscreen() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
let initial_window_location = self.space.element_location(&window).unwrap();
|
let initial_window_location = self.space.element_location(&window).unwrap();
|
||||||
let initial_window_size = window.window.geometry().size;
|
let initial_window_size = window.window.geometry().size;
|
||||||
|
|
||||||
|
|
@ -169,12 +182,7 @@ impl XdgShellHandler for State {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn title_changed(&mut self, surface: ToplevelSurface) {
|
fn title_changed(&mut self, surface: ToplevelSurface) {
|
||||||
let window = self
|
let window = self.get_window_by_surface(&surface);
|
||||||
.space
|
|
||||||
.elements()
|
|
||||||
.filter(|w| w.window.toplevel().is_some())
|
|
||||||
.find(|w| *w.window.toplevel().unwrap() == surface)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
smithay::wayland::compositor::with_states(surface.wl_surface(), |states| {
|
smithay::wayland::compositor::with_states(surface.wl_surface(), |states| {
|
||||||
if let Some(data) = states.data_map.get::<XdgToplevelSurfaceData>() {
|
if let Some(data) = states.data_map.get::<XdgToplevelSurfaceData>() {
|
||||||
|
|
@ -184,6 +192,154 @@ impl XdgShellHandler for State {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// fn new_client(&mut self, client: smithay::wayland::shell::xdg::ShellClient) {}
|
||||||
|
|
||||||
|
// fn client_pong(&mut self, client: smithay::wayland::shell::xdg::ShellClient) {}
|
||||||
|
|
||||||
|
fn maximize_request(&mut self, surface: ToplevelSurface) {
|
||||||
|
{
|
||||||
|
let window = self.get_window_by_surface(&surface);
|
||||||
|
if let Some(loc) = self.space.element_location(&window) {
|
||||||
|
window.set_saved_location(loc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let window = self.get_window_by_surface(&surface).clone();
|
||||||
|
if let Some(loc) = self.space.element_location(&window) {
|
||||||
|
window.set_saved_location(loc);
|
||||||
|
}
|
||||||
|
self.space.relocate_element(&window, Point::new(0, 0));
|
||||||
|
|
||||||
|
if let Some(output) = window.output.lock().clone() {
|
||||||
|
let geom = self.space.output_geometry(&output).unwrap();
|
||||||
|
|
||||||
|
let xdg = window.window.toplevel().unwrap();
|
||||||
|
xdg.with_pending_state(|state| {
|
||||||
|
state.states.set(xdg_toplevel::State::Maximized);
|
||||||
|
state.size = Some(geom.size);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
surface.send_configure();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn unmaximize_request(&mut self, surface: ToplevelSurface) {
|
||||||
|
let window = self.get_window_by_surface(&surface).clone();
|
||||||
|
self.space
|
||||||
|
.relocate_element(&window, window.saved_location());
|
||||||
|
|
||||||
|
if let Some(output) = window.output.lock().clone() {
|
||||||
|
let xdg = window.window.toplevel().unwrap();
|
||||||
|
xdg.with_pending_state(|state| {
|
||||||
|
state.states.unset(xdg_toplevel::State::Maximized);
|
||||||
|
state.size = None;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
surface.send_configure();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn fullscreen_request(
|
||||||
|
&mut self,
|
||||||
|
surface: ToplevelSurface,
|
||||||
|
mut wl_output: Option<wl_output::WlOutput>,
|
||||||
|
) {
|
||||||
|
// NOTE: This is only one part of the solution. We can set the
|
||||||
|
// location and configure size here, but the surface should be rendered fullscreen
|
||||||
|
// independently from its buffer size
|
||||||
|
let wl_surface = surface.wl_surface();
|
||||||
|
let window = self.get_window_by_surface(&surface);
|
||||||
|
|
||||||
|
window.set_fullscreen(true);
|
||||||
|
|
||||||
|
let output_geometry = wl_output
|
||||||
|
.as_ref()
|
||||||
|
.and_then(Output::from_resource)
|
||||||
|
.or_else(|| {
|
||||||
|
let w = self.space.elements().find(|window| {
|
||||||
|
window
|
||||||
|
.window
|
||||||
|
.wl_surface()
|
||||||
|
.map(|s| &*s == wl_surface)
|
||||||
|
.unwrap_or(false)
|
||||||
|
});
|
||||||
|
w.and_then(|w| self.space.outputs_for_element(w).first().cloned())
|
||||||
|
})
|
||||||
|
.as_ref()
|
||||||
|
.and_then(|o| self.space.output_geometry(o));
|
||||||
|
|
||||||
|
if let Some(geometry) = output_geometry {
|
||||||
|
let output = wl_output
|
||||||
|
.as_ref()
|
||||||
|
.and_then(Output::from_resource)
|
||||||
|
.unwrap_or_else(|| self.space.outputs().next().unwrap().clone());
|
||||||
|
let client = match self.display_handle.get_client(wl_surface.id()) {
|
||||||
|
Ok(client) => client,
|
||||||
|
Err(_) => return,
|
||||||
|
};
|
||||||
|
for output in output.client_outputs(&client) {
|
||||||
|
wl_output = Some(output);
|
||||||
|
}
|
||||||
|
|
||||||
|
surface.with_pending_state(|state| {
|
||||||
|
state.states.set(xdg_toplevel::State::Fullscreen);
|
||||||
|
state.size = Some(geometry.size);
|
||||||
|
state.fullscreen_output = wl_output;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// The protocol demands us to always reply with a configure,
|
||||||
|
// regardless of we fulfilled the request or not
|
||||||
|
if surface.is_initial_configure_sent() {
|
||||||
|
surface.send_configure();
|
||||||
|
} else {
|
||||||
|
// Will be sent during initial configure
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn unfullscreen_request(&mut self, surface: ToplevelSurface) {
|
||||||
|
let window = self.get_window_by_surface(&surface);
|
||||||
|
|
||||||
|
window.set_fullscreen(false);
|
||||||
|
|
||||||
|
let xdg = window.window.toplevel().unwrap();
|
||||||
|
xdg.with_pending_state(|state| {
|
||||||
|
state.states.unset(xdg_toplevel::State::Fullscreen);
|
||||||
|
state.size = None;
|
||||||
|
state.fullscreen_output = None;
|
||||||
|
});
|
||||||
|
|
||||||
|
surface.send_configure();
|
||||||
|
}
|
||||||
|
|
||||||
|
// fn minimize_request(&mut self, surface: ToplevelSurface) {}
|
||||||
|
|
||||||
|
// fn show_window_menu(
|
||||||
|
// &mut self,
|
||||||
|
// surface: ToplevelSurface,
|
||||||
|
// seat: wl_seat::WlSeat,
|
||||||
|
// serial: Serial,
|
||||||
|
// location: smithay::utils::Point<i32, smithay::utils::Logical>,
|
||||||
|
// ) {
|
||||||
|
// }
|
||||||
|
|
||||||
|
// fn ack_configure(
|
||||||
|
// &mut self,
|
||||||
|
// surface: wl_surface::WlSurface,
|
||||||
|
// configure: smithay::wayland::shell::xdg::Configure,
|
||||||
|
// ) {
|
||||||
|
// }
|
||||||
|
|
||||||
|
// fn client_destroyed(&mut self, client: smithay::wayland::shell::xdg::ShellClient) {}
|
||||||
|
|
||||||
|
// fn toplevel_destroyed(&mut self, surface: ToplevelSurface) {}
|
||||||
|
|
||||||
|
// fn popup_destroyed(&mut self, surface: PopupSurface) {}
|
||||||
|
|
||||||
|
// fn app_id_changed(&mut self, surface: ToplevelSurface) {}
|
||||||
|
|
||||||
|
// fn parent_changed(&mut self, surface: ToplevelSurface) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_grab(
|
fn check_grab(
|
||||||
|
|
@ -277,4 +433,12 @@ impl State {
|
||||||
state.geometry = state.positioner.get_unconstrained_geometry(target);
|
state.geometry = state.positioner.get_unconstrained_geometry(target);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_window_by_surface(&self, surface: &ToplevelSurface) -> &DecoratedWindow {
|
||||||
|
self.space
|
||||||
|
.elements()
|
||||||
|
.filter(|w| w.window.toplevel().is_some())
|
||||||
|
.find(|w| *w.window.toplevel().unwrap() == *surface)
|
||||||
|
.unwrap()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,9 @@ use cairo::{Context, Format, ImageSurface};
|
||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
use smithay::backend::allocator::Fourcc;
|
use smithay::backend::allocator::Fourcc;
|
||||||
use smithay::backend::renderer::element::memory::MemoryRenderBuffer;
|
use smithay::backend::renderer::element::memory::MemoryRenderBuffer;
|
||||||
use smithay::utils::Transform;
|
use smithay::desktop::layer_map_for_output;
|
||||||
|
use smithay::utils::{Logical, Transform};
|
||||||
|
use smithay::wayland::commit_timing::CommitTimerBarrierStateUserData;
|
||||||
use smithay::{
|
use smithay::{
|
||||||
backend::renderer::{
|
backend::renderer::{
|
||||||
damage::OutputDamageTracker,
|
damage::OutputDamageTracker,
|
||||||
|
|
@ -36,7 +38,10 @@ const CSD_BORDER_FRAME_BOTTOM: f64 = 4.0;
|
||||||
pub struct DecoratedWindow {
|
pub struct DecoratedWindow {
|
||||||
pub window: Window,
|
pub window: Window,
|
||||||
title: Mutex<String>,
|
title: Mutex<String>,
|
||||||
decorations: bool,
|
pub output: Mutex<Option<Output>>,
|
||||||
|
decorations: Mutex<bool>,
|
||||||
|
fullscreen: Mutex<bool>,
|
||||||
|
saved_location: Mutex<Point<i32, Logical>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PartialEq for DecoratedWindow {
|
impl PartialEq for DecoratedWindow {
|
||||||
|
|
@ -49,10 +54,17 @@ impl Eq for DecoratedWindow {}
|
||||||
impl Clone for DecoratedWindow {
|
impl Clone for DecoratedWindow {
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
let title = self.title.lock().clone();
|
let title = self.title.lock().clone();
|
||||||
|
let output = self.output.lock().clone();
|
||||||
|
let decorations = self.decorations.lock().clone();
|
||||||
|
let fullscreen = self.fullscreen.lock().clone();
|
||||||
|
let saved_location = self.saved_location.lock().clone();
|
||||||
Self {
|
Self {
|
||||||
window: self.window.clone(),
|
window: self.window.clone(),
|
||||||
title: Mutex::new(title),
|
title: Mutex::new(title),
|
||||||
decorations: self.decorations,
|
output: Mutex::new(output),
|
||||||
|
decorations: Mutex::new(decorations),
|
||||||
|
fullscreen: Mutex::new(fullscreen),
|
||||||
|
saved_location: Mutex::new(saved_location),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -63,12 +75,35 @@ impl DecoratedWindow {
|
||||||
Self {
|
Self {
|
||||||
window,
|
window,
|
||||||
title: Mutex::new(String::new()),
|
title: Mutex::new(String::new()),
|
||||||
decorations,
|
output: Mutex::new(None),
|
||||||
|
decorations: Mutex::new(decorations),
|
||||||
|
fullscreen: Mutex::new(false),
|
||||||
|
saved_location: Mutex::new(Point::new(0, 0)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn saved_location(&self) -> Point<i32, Logical> {
|
||||||
|
self.saved_location.lock().clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_saved_location(&self, point: Point<i32, Logical>) {
|
||||||
|
*self.saved_location.lock() = point;
|
||||||
|
}
|
||||||
|
pub fn set_title(&self, title: String) {
|
||||||
|
*self.title.lock() = title;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_fullscreen(&self) -> bool {
|
||||||
|
return *self.fullscreen.lock();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_fullscreen(&self, fs: bool) {
|
||||||
|
// *self.decorations.lock() = !fs;
|
||||||
|
*self.fullscreen.lock() = fs;
|
||||||
|
}
|
||||||
|
|
||||||
fn decorated(&self) -> bool {
|
fn decorated(&self) -> bool {
|
||||||
let mut b = self.decorations;
|
let mut b = *self.decorations.lock();
|
||||||
if let Some(toplevel) = self.window.toplevel() {
|
if let Some(toplevel) = self.window.toplevel() {
|
||||||
toplevel.with_pending_state(|f| {
|
toplevel.with_pending_state(|f| {
|
||||||
if let Some(decor) = f.decoration_mode {
|
if let Some(decor) = f.decoration_mode {
|
||||||
|
|
@ -79,10 +114,6 @@ impl DecoratedWindow {
|
||||||
b
|
b
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_title(&self, title: String) {
|
|
||||||
*self.title.lock() = title;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn render_border(&self, width: i32, height: i32) -> (Vec<u8>, i32) {
|
fn render_border(&self, width: i32, height: i32) -> (Vec<u8>, i32) {
|
||||||
let mut surface = ImageSurface::create(Format::ARgb32, width, height).unwrap();
|
let mut surface = ImageSurface::create(Format::ARgb32, width, height).unwrap();
|
||||||
let stride = surface.stride();
|
let stride = surface.stride();
|
||||||
|
|
@ -285,10 +316,12 @@ impl SpaceElement for DecoratedWindow {
|
||||||
output: &Output,
|
output: &Output,
|
||||||
overlap: smithay::utils::Rectangle<i32, smithay::utils::Logical>,
|
overlap: smithay::utils::Rectangle<i32, smithay::utils::Logical>,
|
||||||
) {
|
) {
|
||||||
|
*self.output.lock() = Some(output.clone());
|
||||||
self.window.output_enter(output, overlap)
|
self.window.output_enter(output, overlap)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn output_leave(&self, output: &Output) {
|
fn output_leave(&self, output: &Output) {
|
||||||
|
*self.output.lock() = None;
|
||||||
self.window.output_leave(output)
|
self.window.output_leave(output)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -309,12 +342,17 @@ where
|
||||||
fn render_elements<C: From<Self::RenderElement>>(
|
fn render_elements<C: From<Self::RenderElement>>(
|
||||||
&self,
|
&self,
|
||||||
renderer: &mut R,
|
renderer: &mut R,
|
||||||
location: Point<i32, Physical>,
|
mut location: Point<i32, Physical>,
|
||||||
scale: Scale<f64>,
|
scale: Scale<f64>,
|
||||||
alpha: f32,
|
alpha: f32,
|
||||||
) -> Vec<C> {
|
) -> Vec<C> {
|
||||||
let mut elements: Vec<C> = Vec::new();
|
let mut elements: Vec<C> = Vec::new();
|
||||||
|
|
||||||
|
if self.is_fullscreen() {
|
||||||
|
location.x = 0;
|
||||||
|
location.y = 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Start with actual window elements */
|
/* Start with actual window elements */
|
||||||
elements.extend(
|
elements.extend(
|
||||||
self.window
|
self.window
|
||||||
|
|
@ -381,8 +419,6 @@ impl State {
|
||||||
framebuffer: &mut GlesTarget,
|
framebuffer: &mut GlesTarget,
|
||||||
damage_tracker: &mut OutputDamageTracker,
|
damage_tracker: &mut OutputDamageTracker,
|
||||||
) -> Result<(), Box<dyn std::error::Error>> {
|
) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
// let elem = DecorationElement::
|
|
||||||
|
|
||||||
smithay::desktop::space::render_output::<_, OutputElement<GlesRenderer>, _, _>(
|
smithay::desktop::space::render_output::<_, OutputElement<GlesRenderer>, _, _>(
|
||||||
output,
|
output,
|
||||||
renderer,
|
renderer,
|
||||||
|
|
@ -394,6 +430,7 @@ impl State {
|
||||||
damage_tracker,
|
damage_tracker,
|
||||||
[0.07, 0.16, 0.286, 1.0],
|
[0.07, 0.16, 0.286, 1.0],
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ use smithay::{
|
||||||
fixes::FixesState,
|
fixes::FixesState,
|
||||||
output::OutputManagerState,
|
output::OutputManagerState,
|
||||||
selection::data_device::DataDeviceState,
|
selection::data_device::DataDeviceState,
|
||||||
shell::xdg::{decoration::XdgDecorationState, XdgShellState},
|
shell::{wlr_layer::WlrLayerShellState, xdg::XdgShellState},
|
||||||
shm::ShmState,
|
shm::ShmState,
|
||||||
socket::ListeningSocketSource,
|
socket::ListeningSocketSource,
|
||||||
xdg_activation::XdgActivationState,
|
xdg_activation::XdgActivationState,
|
||||||
|
|
@ -59,6 +59,9 @@ pub struct State {
|
||||||
pub xdg_toplevel_tag_manager_state: XdgToplevelTagManager,
|
pub xdg_toplevel_tag_manager_state: XdgToplevelTagManager,
|
||||||
pub xdg_system_bell_state: XdgSystemBellState,
|
pub xdg_system_bell_state: XdgSystemBellState,
|
||||||
|
|
||||||
|
// the one wlroots protocol that everyone adopted
|
||||||
|
pub wlr_layer_shell_state: WlrLayerShellState,
|
||||||
|
|
||||||
pub output_manager_state: OutputManagerState,
|
pub output_manager_state: OutputManagerState,
|
||||||
|
|
||||||
pub xwayland_state: XWaylandState,
|
pub xwayland_state: XWaylandState,
|
||||||
|
|
@ -88,6 +91,8 @@ impl State {
|
||||||
let xdg_toplevel_tag_manager_state = XdgToplevelTagManager::new::<Self>(&dh);
|
let xdg_toplevel_tag_manager_state = XdgToplevelTagManager::new::<Self>(&dh);
|
||||||
let xdg_system_bell_state = XdgSystemBellState::new::<Self>(&dh);
|
let xdg_system_bell_state = XdgSystemBellState::new::<Self>(&dh);
|
||||||
|
|
||||||
|
let wlr_layer_shell_state = WlrLayerShellState::new::<Self>(&dh);
|
||||||
|
|
||||||
let shm_state = ShmState::new::<Self>(&dh, vec![]);
|
let shm_state = ShmState::new::<Self>(&dh, vec![]);
|
||||||
let popups = PopupManager::default();
|
let popups = PopupManager::default();
|
||||||
|
|
||||||
|
|
@ -149,6 +154,7 @@ impl State {
|
||||||
data_device_state,
|
data_device_state,
|
||||||
wl_fixes_state,
|
wl_fixes_state,
|
||||||
output_manager_state,
|
output_manager_state,
|
||||||
|
wlr_layer_shell_state,
|
||||||
|
|
||||||
// xdg_decoration_state,
|
// xdg_decoration_state,
|
||||||
xdg_activation_state,
|
xdg_activation_state,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue