From 1227ede560f6068ed405242c5bb5e285b69b9f3a Mon Sep 17 00:00:00 2001 From: Julian Orth Date: Wed, 20 Apr 2022 17:28:17 +0200 Subject: [PATCH] autocommit 2022-04-20 17:28:17 CEST --- src/ifs/wl_surface.rs | 5 ++- .../wl_surface/xdg_surface/xdg_toplevel.rs | 14 +++--- src/render/renderer/renderer.rs | 16 ++++++- src/render/renderer/texture.rs | 4 ++ src/state.rs | 5 +-- src/tree/container.rs | 41 +++++++++++++++--- src/tree/fullscreen.rs | 18 +++++--- src/tree/placeholder.rs | 43 +++++++++++++++++++ src/tree/workspace.rs | 16 ++++++- 9 files changed, 137 insertions(+), 25 deletions(-) diff --git a/src/ifs/wl_surface.rs b/src/ifs/wl_surface.rs index 75d0c83e..9ea07b58 100644 --- a/src/ifs/wl_surface.rs +++ b/src/ifs/wl_surface.rs @@ -899,7 +899,10 @@ impl SizedNode for WlSurface { } fn fullscreen(&self) -> bool { - self.toplevel.get().map(|tl| tl.fullscreen()).unwrap_or(false) + self.toplevel + .get() + .map(|tl| tl.fullscreen()) + .unwrap_or(false) } } diff --git a/src/ifs/wl_surface/xdg_surface/xdg_toplevel.rs b/src/ifs/wl_surface/xdg_surface/xdg_toplevel.rs index 09869e33..e058bd81 100644 --- a/src/ifs/wl_surface/xdg_surface/xdg_toplevel.rs +++ b/src/ifs/wl_surface/xdg_surface/xdg_toplevel.rs @@ -16,6 +16,7 @@ use { object::Object, rect::Rect, render::Renderer, + state::State, tree::{ FindTreeResult, FoundNode, FullscreenData, Node, NodeId, NodeVisitor, SizedFullscreenNode, SizedNode, SizedToplevelNode, ToplevelData, ToplevelNodeId, @@ -39,7 +40,6 @@ use { }, thiserror::Error, }; -use crate::state::State; #[derive(Copy, Clone, Debug, FromPrimitive)] pub enum ResizeEdge { @@ -313,7 +313,8 @@ impl XdgToplevel { } else { break 'set_fullscreen; }; - self.fullscreen_data.set_fullscreen(&client.state, self.clone(), &output); + self.fullscreen_data + .set_fullscreen(&client.state, self.clone(), &output); } self.send_current_configure(); Ok(()) @@ -325,7 +326,8 @@ impl XdgToplevel { ) -> Result<(), UnsetFullscreenError> { let _req: UnsetFullscreen = self.xdg.surface.client.parse(self.deref(), parser)?; self.states.borrow_mut().remove(&STATE_FULLSCREEN); - self.fullscreen_data.unset_fullscreen(&self.state, self.clone()); + self.fullscreen_data + .unset_fullscreen(&self.state, self.clone()); self.send_current_configure(); Ok(()) } @@ -352,7 +354,8 @@ impl XdgToplevel { fn map_floating(self: &Rc, workspace: &Rc) { let (width, height) = self.toplevel_data.float_size(workspace); - self.state.map_floating(self.clone(), width, height, workspace); + self.state + .map_floating(self.clone(), width, height, workspace); } fn map_child(self: &Rc, parent: &XdgToplevel) { @@ -563,7 +566,8 @@ impl SizedToplevelNode for XdgToplevel { let state = &self.state; if fullscreen { if let Some(ws) = self.xdg.workspace.get() { - self.fullscreen_data.set_fullscreen(state, self.clone(), &ws.output.get()); + self.fullscreen_data + .set_fullscreen(state, self.clone(), &ws.output.get()); } } else { self.fullscreen_data.unset_fullscreen(state, self.clone()); diff --git a/src/render/renderer/renderer.rs b/src/render/renderer/renderer.rs index 35baafe8..ce372ffe 100644 --- a/src/render/renderer/renderer.rs +++ b/src/render/renderer/renderer.rs @@ -25,7 +25,7 @@ use { }, state::State, theme::Color, - tree::{ContainerNode, DisplayNode, FloatNode, OutputNode, WorkspaceNode}, + tree::{ContainerNode, DisplayNode, FloatNode, OutputNode, PlaceholderNode, WorkspaceNode}, utils::rc_eq::rc_eq, }, std::{ops::Deref, rc::Rc, slice}, @@ -168,6 +168,20 @@ impl Renderer<'_> { } } + pub fn render_placeholder(&mut self, placeholder: &PlaceholderNode, x: i32, y: i32) { + let pos = placeholder.position(); + self.fill_boxes( + std::slice::from_ref(&pos.at_point(x, y)), + &Color::from_rgba(20, 20, 20, 255), + ); + if let Some(tex) = placeholder.texture() { + let x = x + (pos.width() - tex.width()) / 2; + let y = y + (pos.height() - tex.height()) / 2; + log::info!("render at {}x{}", x, y); + self.render_texture(&tex, x, y, &ARGB8888); + } + } + pub fn render_container(&mut self, container: &ContainerNode, x: i32, y: i32) { { let rd = container.render_data.borrow_mut(); diff --git a/src/render/renderer/texture.rs b/src/render/renderer/texture.rs index 9bdae5ea..beb55252 100644 --- a/src/render/renderer/texture.rs +++ b/src/render/renderer/texture.rs @@ -12,4 +12,8 @@ impl Texture { pub fn width(&self) -> i32 { self.gl.width } + + pub fn height(&self) -> i32 { + self.gl.height + } } diff --git a/src/state.rs b/src/state.rs index 22a85125..07ccf685 100644 --- a/src/state.rs +++ b/src/state.rs @@ -25,9 +25,8 @@ use { render::RenderContext, theme::Theme, tree::{ - ContainerNode, ContainerSplit, DisplayNode, FloatNode, - Node, NodeIds, NodeVisitorBase, OutputNode, - SizedNode, WorkspaceNode, + ContainerNode, ContainerSplit, DisplayNode, FloatNode, Node, NodeIds, NodeVisitorBase, + OutputNode, SizedNode, WorkspaceNode, }, utils::{ asyncevent::AsyncEvent, clonecell::CloneCell, copyhashmap::CopyHashMap, diff --git a/src/tree/container.rs b/src/tree/container.rs index 3076e30e..c408088a 100644 --- a/src/tree/container.rs +++ b/src/tree/container.rs @@ -14,7 +14,8 @@ use { text, theme::Color, tree::{ - walker::NodeVisitor, FindTreeResult, FoundNode, Node, NodeId, SizedNode, WorkspaceNode, + walker::NodeVisitor, FindTreeResult, FoundNode, FullscreenData, Node, NodeId, + SizedFullscreenNode, SizedNode, WorkspaceNode, }, utils::{ clonecell::CloneCell, @@ -117,6 +118,7 @@ pub struct ContainerNode { pub render_data: RefCell, visible: Cell, scroll: Cell, + fullscreen_data: FullscreenData, } impl Debug for ContainerNode { @@ -216,6 +218,7 @@ impl ContainerNode { render_data: Default::default(), visible: Cell::new(false), scroll: Cell::new(0.0), + fullscreen_data: Default::default(), }); child.node_set_parent(slf.clone()); slf @@ -602,6 +605,7 @@ impl ContainerNode { } title.push_str("]"); self.parent.get().node_child_title_changed(&**self, &title); + self.fullscreen_data.set_title(&title); } pub fn schedule_compute_render_data(self: &Rc) { @@ -747,6 +751,7 @@ impl SizedNode for ContainerNode { } fn destroy_node(&self, detach: bool) { + self.fullscreen_data.destroy_node(); if detach { self.parent.get().node_remove_child(self); } @@ -1257,8 +1262,7 @@ impl SizedNode for ContainerNode { }; let num_children = self.num_children.fetch_sub(1) - 1; if num_children == 0 { - self.seats.borrow_mut().clear(); - self.parent.get().node_remove_child(self.deref()); + self.destroy_node(true); return; } self.update_content_size(); @@ -1411,12 +1415,35 @@ impl SizedNode for ContainerNode { .node_child_title_changed(self.deref(), self.title.borrow_mut().deref()); } - fn set_fullscreen(self: &Rc, _fullscreen: bool) { - // todo + fn fullscreen(&self) -> bool { + self.fullscreen_data.is_fullscreen.get() } - fn fullscreen(&self) -> bool { - false + fn set_fullscreen(self: &Rc, fullscreen: bool) { + if fullscreen { + self.fullscreen_data.set_fullscreen( + &self.state, + self.clone(), + &self.workspace.get().output.get().clone(), + ); + } else { + self.fullscreen_data + .unset_fullscreen(&self.state, self.clone()); + } + } +} + +impl SizedFullscreenNode for ContainerNode { + fn on_set_fullscreen(&self, _workspace: &Rc) { + // nothing + } + + fn on_unset_fullscreen(&self) { + // nothing + } + + fn title(&self) -> String { + self.title.borrow_mut().clone() } } diff --git a/src/tree/fullscreen.rs b/src/tree/fullscreen.rs index 51f77cdb..8ece509c 100644 --- a/src/tree/fullscreen.rs +++ b/src/tree/fullscreen.rs @@ -1,15 +1,16 @@ use { - crate::tree::{Node, PlaceholderNode, SizedNode, WorkspaceNode}, + crate::{ + ifs::wl_seat::collect_kb_foci, + state::State, + tree::{Node, OutputNode, PlaceholderNode, SizedNode, WorkspaceNode}, + }, + jay_config::Direction, std::{ cell::{Cell, RefCell}, ops::Deref, rc::Rc, }, }; -use jay_config::Direction; -use crate::ifs::wl_seat::collect_kb_foci; -use crate::state::State; -use crate::tree::OutputNode; pub trait SizedFullscreenNode: SizedNode { fn on_set_fullscreen(&self, workspace: &Rc); @@ -76,7 +77,12 @@ impl FullscreenData { } impl FullscreenData { - pub fn set_fullscreen(&self, state: &Rc, node: Rc, output: &Rc) { + pub fn set_fullscreen( + &self, + state: &Rc, + node: Rc, + output: &Rc, + ) { let ws = output.ensure_workspace(); if ws.fullscreen.get().is_some() { log::info!("Cannot fullscreen a node on a workspace that already has a fullscreen node attached"); diff --git a/src/tree/placeholder.rs b/src/tree/placeholder.rs index dad47fd4..e9f7f2de 100644 --- a/src/tree/placeholder.rs +++ b/src/tree/placeholder.rs @@ -8,7 +8,10 @@ use { wl_surface::WlSurface, }, rect::Rect, + render::{Renderer, Texture}, state::State, + text, + theme::Color, tree::{ FindTreeResult, FoundNode, FullscreenNode, Node, NodeId, NodeVisitor, SizedNode, SizedToplevelNode, ToplevelData, WorkspaceNode, @@ -22,6 +25,7 @@ use { rc::Rc, }, }; +use crate::utils::errorfmt::ErrorFmt; tree_id!(DetachedNodeId); pub struct PlaceholderNode { @@ -37,6 +41,7 @@ pub struct PlaceholderNode { toplevel: ToplevelData, active: Cell, destroyed: Cell, + texture: CloneCell>>, } impl PlaceholderNode { @@ -54,9 +59,14 @@ impl PlaceholderNode { toplevel: Default::default(), active: Default::default(), destroyed: Default::default(), + texture: Default::default(), } } + pub fn texture(&self) -> Option> { + self.texture.get() + } + pub fn set_title(&self, title: &str) { *self.title.borrow_mut() = title.to_string(); if let Some(parent) = self.parent.get() { @@ -67,6 +77,10 @@ impl PlaceholderNode { pub fn is_destroyed(&self) -> bool { self.destroyed.get() } + + pub fn position(&self) -> Rect { + self.pos.get() + } } impl SizedNode for PlaceholderNode { @@ -146,7 +160,32 @@ impl SizedNode for PlaceholderNode { } fn change_extents(self: &Rc, rect: &Rect) { + log::info!("{:?}", rect); self.pos.set(*rect); + if let Some(p) = self.parent.get() { + p.node_child_size_changed(self.deref(), rect.width(), rect.height()); + } + self.texture.set(None); + if let Some(ctx) = self.state.render_ctx.get() { + if rect.width() != 0 && rect.height() != 0 { + let font = format!("monospace {}", rect.width() / 10); + match text::render_fitting( + &ctx, + rect.height(), + &font, + "Fullscreen", + Color::GREY, + false, + ) { + Ok(t) => { + self.texture.set(Some(t)); + }, + Err(e) => { + log::warn!("Could not render fullscreen texture: {}", ErrorFmt(e)); + } + } + } + } } fn set_workspace(self: &Rc, ws: &Rc) { @@ -161,6 +200,10 @@ impl SizedNode for PlaceholderNode { fn client(&self) -> Option> { self.client.clone() } + + fn render(&self, renderer: &mut Renderer, x: i32, y: i32) { + renderer.render_placeholder(self, x, y); + } } impl SizedToplevelNode for PlaceholderNode { diff --git a/src/tree/workspace.rs b/src/tree/workspace.rs index 864657fa..e3db6a63 100644 --- a/src/tree/workspace.rs +++ b/src/tree/workspace.rs @@ -120,8 +120,20 @@ impl SizedNode for WorkspaceNode { FindTreeResult::AcceptsInput } - fn remove_child2(self: &Rc, _child: &dyn Node, _preserve_focus: bool) { - self.container.set(None); + fn remove_child2(self: &Rc, child: &dyn Node, _preserve_focus: bool) { + if let Some(container) = self.container.get() { + if container.node_id() == child.node_id() { + self.container.set(None); + return; + } + } + if let Some(fs) = self.fullscreen.get() { + if fs.as_node().node_id() == child.node_id() { + self.fullscreen.set(None); + return; + } + } + log::error!("Trying to remove child that's not a child"); } fn pointer_focus(&self, seat: &Rc) {