layer-shell: implement exclusive zones
This commit is contained in:
parent
8dc31110b9
commit
8a91c070be
9 changed files with 300 additions and 90 deletions
|
|
@ -18,8 +18,8 @@ use {
|
|||
},
|
||||
wl_surface::{
|
||||
ext_session_lock_surface_v1::ExtSessionLockSurfaceV1,
|
||||
zwlr_layer_surface_v1::ZwlrLayerSurfaceV1, SurfaceSendPreferredScaleVisitor,
|
||||
SurfaceSendPreferredTransformVisitor,
|
||||
zwlr_layer_surface_v1::{ExclusiveSize, ZwlrLayerSurfaceV1},
|
||||
SurfaceSendPreferredScaleVisitor, SurfaceSendPreferredTransformVisitor,
|
||||
},
|
||||
zwlr_layer_shell_v1::{BACKGROUND, BOTTOM, OVERLAY, TOP},
|
||||
zwlr_screencopy_frame_v1::ZwlrScreencopyFrameV1,
|
||||
|
|
@ -47,7 +47,7 @@ use {
|
|||
std::{
|
||||
cell::{Cell, RefCell},
|
||||
fmt::{Debug, Formatter},
|
||||
ops::{Deref, Sub},
|
||||
ops::Deref,
|
||||
rc::Rc,
|
||||
},
|
||||
};
|
||||
|
|
@ -61,6 +61,10 @@ pub struct OutputNode {
|
|||
pub workspace: CloneCell<Option<Rc<WorkspaceNode>>>,
|
||||
pub seat_state: NodeSeatState,
|
||||
pub layers: [LinkedList<Rc<ZwlrLayerSurfaceV1>>; 4],
|
||||
pub exclusive_zones: Cell<ExclusiveSize>,
|
||||
pub workspace_rect: Cell<Rect>,
|
||||
pub non_exclusive_rect: Cell<Rect>,
|
||||
pub non_exclusive_rect_rel: Cell<Rect>,
|
||||
pub render_data: RefCell<OutputRenderData>,
|
||||
pub state: Rc<State>,
|
||||
pub is_dummy: bool,
|
||||
|
|
@ -94,6 +98,26 @@ pub async fn output_render_data(state: Rc<State>) {
|
|||
}
|
||||
|
||||
impl OutputNode {
|
||||
pub fn update_exclusive_zones(self: &Rc<Self>) {
|
||||
let mut exclusive = ExclusiveSize::default();
|
||||
for layer in &self.layers {
|
||||
for surface in layer.iter() {
|
||||
exclusive = exclusive.max(&surface.exclusive_size());
|
||||
}
|
||||
}
|
||||
if self.exclusive_zones.replace(exclusive) != exclusive {
|
||||
self.update_rects();
|
||||
for layer in &self.layers {
|
||||
for surface in layer.iter() {
|
||||
surface.exclusive_zones_changed();
|
||||
}
|
||||
}
|
||||
if let Some(c) = self.workspace.get() {
|
||||
c.change_extents(&self.workspace_rect.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_screencast(&self, sc: &Rc<JayScreencast>) {
|
||||
self.screencasts.set((sc.client.id, sc.id), sc.clone());
|
||||
self.screencast_changed();
|
||||
|
|
@ -222,9 +246,9 @@ impl OutputNode {
|
|||
}
|
||||
|
||||
pub fn on_spaces_changed(self: &Rc<Self>) {
|
||||
self.schedule_update_render_data();
|
||||
self.update_rects();
|
||||
if let Some(c) = self.workspace.get() {
|
||||
c.change_extents(&self.workspace_rect());
|
||||
c.change_extents(&self.workspace_rect.get());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -281,7 +305,7 @@ impl OutputNode {
|
|||
texture_height = (th as f64 * scale).round() as _;
|
||||
}
|
||||
let active_id = self.workspace.get().map(|w| w.id);
|
||||
let output_width = self.global.pos.get().width();
|
||||
let output_width = self.non_exclusive_rect.get().width();
|
||||
rd.underline = Rect::new_sized(0, th, output_width, 1).unwrap();
|
||||
for ws in self.workspaces.iter() {
|
||||
let old_tex = ws.title_texture.take();
|
||||
|
|
@ -430,7 +454,7 @@ impl OutputNode {
|
|||
if let Some(fs) = ws.fullscreen.get() {
|
||||
fs.tl_change_extents(&self.global.pos.get());
|
||||
}
|
||||
ws.change_extents(&self.workspace_rect());
|
||||
ws.change_extents(&self.workspace_rect.get());
|
||||
for seat in seats {
|
||||
ws.clone().node_do_focus(&seat, Direction::Unspecified);
|
||||
}
|
||||
|
|
@ -478,16 +502,29 @@ impl OutputNode {
|
|||
ws
|
||||
}
|
||||
|
||||
fn workspace_rect(&self) -> Rect {
|
||||
pub fn update_rects(self: &Rc<Self>) {
|
||||
let rect = self.global.pos.get();
|
||||
let th = self.state.theme.sizes.title_height.get();
|
||||
Rect::new_sized(
|
||||
rect.x1(),
|
||||
rect.y1() + th + 1,
|
||||
rect.width(),
|
||||
rect.height().sub(th + 1).max(0),
|
||||
)
|
||||
.unwrap()
|
||||
let exclusive = self.exclusive_zones.get();
|
||||
let y1 = rect.y1() + exclusive.top;
|
||||
let x2 = rect.x2() - exclusive.right;
|
||||
let y2 = rect.y2() - exclusive.bottom;
|
||||
let x1 = rect.x1() + exclusive.left;
|
||||
let width = (x2 - x1).max(0);
|
||||
let height = (y2 - y1).max(0);
|
||||
self.non_exclusive_rect
|
||||
.set(Rect::new_sized_unchecked(x1, y1, width, height));
|
||||
self.non_exclusive_rect_rel.set(Rect::new_sized_unchecked(
|
||||
exclusive.left,
|
||||
exclusive.top,
|
||||
width,
|
||||
height,
|
||||
));
|
||||
let y1 = y1 + th + 1;
|
||||
let height = (y2 - y1).max(0);
|
||||
self.workspace_rect
|
||||
.set(Rect::new_sized_unchecked(x1, y1, width, height));
|
||||
self.schedule_update_render_data();
|
||||
}
|
||||
|
||||
pub fn set_position(self: &Rc<Self>, x: i32, y: i32) {
|
||||
|
|
@ -546,7 +583,7 @@ impl OutputNode {
|
|||
self.global.persistent.pos.set((rect.x1(), rect.y1()));
|
||||
self.global.pos.set(*rect);
|
||||
self.state.root.update_extents();
|
||||
self.schedule_update_render_data();
|
||||
self.update_rects();
|
||||
if let Some(ls) = self.lock_surface.get() {
|
||||
ls.change_extents(*rect);
|
||||
}
|
||||
|
|
@ -554,7 +591,7 @@ impl OutputNode {
|
|||
if let Some(fs) = c.fullscreen.get() {
|
||||
fs.tl_change_extents(rect);
|
||||
}
|
||||
c.change_extents(&self.workspace_rect());
|
||||
c.change_extents(&self.workspace_rect.get());
|
||||
}
|
||||
for layer in &self.layers {
|
||||
for surface in layer.iter() {
|
||||
|
|
@ -657,6 +694,7 @@ impl OutputNode {
|
|||
Some(p) => p,
|
||||
_ => return,
|
||||
};
|
||||
let (x, y) = self.non_exclusive_rect_rel.get().translate(x, y);
|
||||
if y >= self.state.theme.sizes.title_height.get() {
|
||||
return;
|
||||
}
|
||||
|
|
@ -844,21 +882,25 @@ impl Node for OutputNode {
|
|||
fs.tl_as_node().node_find_tree_at(x, y, tree, usecase)
|
||||
} else {
|
||||
let mut search_layers = true;
|
||||
if y < bar_height {
|
||||
search_layers = false;
|
||||
} else {
|
||||
if let Some(ws) = self.workspace.get() {
|
||||
let y = y - bar_height;
|
||||
let len = tree.len();
|
||||
tree.push(FoundNode {
|
||||
node: ws.clone(),
|
||||
x,
|
||||
y,
|
||||
});
|
||||
match ws.node_find_tree_at(x, y, tree, usecase) {
|
||||
FindTreeResult::AcceptsInput => search_layers = false,
|
||||
FindTreeResult::Other => {
|
||||
tree.truncate(len);
|
||||
let non_exclusive_rect = self.non_exclusive_rect_rel.get();
|
||||
if non_exclusive_rect.contains(x, y) {
|
||||
let (x, y) = non_exclusive_rect.translate(x, y);
|
||||
if y < bar_height {
|
||||
search_layers = false;
|
||||
} else {
|
||||
if let Some(ws) = self.workspace.get() {
|
||||
let y = y - bar_height;
|
||||
let len = tree.len();
|
||||
tree.push(FoundNode {
|
||||
node: ws.clone(),
|
||||
x,
|
||||
y,
|
||||
});
|
||||
match ws.node_find_tree_at(x, y, tree, usecase) {
|
||||
FindTreeResult::AcceptsInput => search_layers = false,
|
||||
FindTreeResult::Other => {
|
||||
tree.truncate(len);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue