Wayland compositor (wlroots)
git clone https://git.lucas.co/cce-compositor.git
Support nested key_bindings inside input node in config.kdl, and other updates
scenefx/render/fx_renderer/fx_pass.c | 15 ++++---
scenefx/types/scene/wlr_scene.c | 2 +-
src/server/config.rs | 28 ++++++++++++
src/server/layer_shell.rs | 22 ++++++++--
src/server/output.rs | 6 ++-
src/server/server.rs | 12 ++++-
src/server/window.rs | 85 +++++++++++++++++++++++++++---------
src/server/wlroots_log_wrapper.c | 22 +++++++++-
src/server/xdg_toplevel.rs | 63 ++++++++++++++++++++++++--
9 files changed, 215 insertions(+), 40 deletions(-)
diff --git a/scenefx/render/fx_renderer/fx_pass.c b/scenefx/render/fx_renderer/fx_pass.c
index d7d0f4c..578ba67 100644
--- a/scenefx/render/fx_renderer/fx_pass.c
+++ b/scenefx/render/fx_renderer/fx_pass.c
@@ -1112,6 +1112,11 @@ void fx_render_pass_add_blur(struct fx_gles_render_pass *pass,
TRACY_BOTH_ZONES_START(renderer);
push_fx_debug(renderer);
+ wlr_log(WLR_INFO, "[scenefx] add_blur dst_box: %dx%d at (%d, %d), optimized: %d strength: %f",
+ tex_options->base.dst_box.width, tex_options->base.dst_box.height,
+ tex_options->base.dst_box.x, tex_options->base.dst_box.y,
+ fx_options->use_optimized_blur, fx_options->blur_strength);
+
const bool has_strength = fx_options->blur_strength < 1.0;
struct fx_framebuffer *buffer = pass->fx_offscreen_buffers->optimized_blur_buffer;
TRACY_ZONE_TEXT_f("Use Optimized Blur: %d", fx_options->use_optimized_blur);
@@ -1216,6 +1221,9 @@ bool fx_render_pass_add_optimized_blur(struct fx_gles_render_pass *pass,
TRACY_ZONE_TEXT_f("\tSaturation: %f", fx_options->blur_data->saturation);
push_fx_debug(renderer);
+ wlr_log(WLR_INFO, "[scenefx] add_optimized_blur dst_box: %dx%d at (%d, %d)",
+ dst_box.width, dst_box.height, dst_box.x, dst_box.y);
+
pixman_region32_t clip;
pixman_region32_init_rect(&clip,
dst_box.x, dst_box.y, dst_box.width, dst_box.height);
@@ -1260,11 +1268,6 @@ void fx_render_pass_read_to_buffer(struct fx_gles_render_pass *pass,
goto done;
}
- float saved_projection_matrix[9];
- memcpy(saved_projection_matrix, pass->projection_matrix, sizeof(saved_projection_matrix));
- matrix_projection(pass->projection_matrix, dst_buffer->buffer->width, dst_buffer->buffer->height,
- WL_OUTPUT_TRANSFORM_NORMAL);
-
// Draw onto the dst_buffer
fx_framebuffer_bind(dst_buffer);
wlr_render_pass_add_texture(&pass->base, &(struct wlr_render_texture_options) {
@@ -1287,8 +1290,6 @@ void fx_render_pass_read_to_buffer(struct fx_gles_render_pass *pass,
});
wlr_texture_destroy(src_tex);
- memcpy(pass->projection_matrix, saved_projection_matrix, sizeof(saved_projection_matrix));
-
// Bind back to the main WLR buffer
fx_framebuffer_bind(pass->buffer);
diff --git a/scenefx/types/scene/wlr_scene.c b/scenefx/types/scene/wlr_scene.c
index 641d93f..dc8252b 100644
--- a/scenefx/types/scene/wlr_scene.c
+++ b/scenefx/types/scene/wlr_scene.c
@@ -1227,9 +1227,9 @@ void wlr_scene_blur_set_transparency_mask_source(struct wlr_scene_blur *blur,
}
linked_node_destroy(&blur->transparency_mask_source);
- linked_node_destroy(&source->blur);
if (source != NULL) {
+ linked_node_destroy(&source->blur);
linked_node_init_link(&blur->transparency_mask_source, &source->blur);
}
diff --git a/src/server/config.rs b/src/server/config.rs
index 580c7c2..e271cf3 100644
--- a/src/server/config.rs
+++ b/src/server/config.rs
@@ -1048,6 +1048,34 @@ fn parse_kdl_config(content: &str) -> Result<Config, String> {
}
}
+ if key_bindings.is_empty() {
+ if let Some(input_node) = doc.nodes().iter().find(|n| n.name().value() == "input") {
+ if let Some(children) = input_node.children() {
+ for child_node in children.nodes() {
+ if child_node.name().value() == "key_bindings" {
+ if let Some(bind_children) = child_node.children() {
+ for child in bind_children.nodes() {
+ if child.name().value() == "bind" {
+ let mods = get_prop_string(child, "mods", "");
+ let key = get_prop_string(child, "key", "");
+ let action = get_prop_string(child, "action", "");
+ let command = get_prop_string_opt(child, "command");
+ key_bindings.push(KeybindConfig { mods, key, action, command });
+ }
+ }
+ } else {
+ let mods = get_prop_string(child_node, "mods", "");
+ let key = get_prop_string(child_node, "key", "");
+ let action = get_prop_string(child_node, "action", "");
+ let command = get_prop_string_opt(child_node, "command");
+ key_bindings.push(KeybindConfig { mods, key, action, command });
+ }
+ }
+ }
+ }
+ }
+ }
+
// 4. output
let mut output = None;
let mut display = HashMap::new();
diff --git a/src/server/layer_shell.rs b/src/server/layer_shell.rs
index acd75b5..90e7dfa 100644
--- a/src/server/layer_shell.rs
+++ b/src/server/layer_shell.rs
@@ -584,24 +584,38 @@ unsafe extern "C" fn handle_layer_surface_commit(listener: *mut ffi::wl_listener
if (*wlr_layer_surface).current.layer != ffi::zwlr_layer_shell_v1_layer_ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND {
let server = (*layer_surface).server;
- let mut blur_enabled = true;
+ let mut blur_enabled = (*server).wm.layout.window_blur;
let mut ignore_transparent = (*server).wm.layout.window_backdrop_blur_ignore_transparent;
+ let mut is_status = false;
if !(*wlr_layer_surface).namespace.is_null() {
let ns = std::ffi::CStr::from_ptr((*wlr_layer_surface).namespace).to_string_lossy();
if ns == "cce-status" {
blur_enabled = (*server).wm.layout.status_background_blur > 0.001;
ignore_transparent = (*server).wm.layout.status_backdrop_blur_ignore_transparent;
+ is_status = true;
}
}
+ let use_optimized = if is_status { false } else { (*server).wm.layout.scenefx_optimized_blur };
+ let wlr_surface = (*wlr_layer_surface).surface;
+ let geom_w = if !wlr_surface.is_null() {
+ ffi::river_wlr_surface_get_width(wlr_surface)
+ } else {
+ (*wlr_layer_surface).current.actual_width as i32
+ };
+ let geom_h = if !wlr_surface.is_null() {
+ ffi::river_wlr_surface_get_height(wlr_surface)
+ } else {
+ (*wlr_layer_surface).current.actual_height as i32
+ };
ffi::river_scene_node_enable_blur(
(*(*layer_surface).scene_layer_surface).tree as *mut ffi::wlr_scene_node,
blur_enabled,
- (*server).wm.layout.scenefx_optimized_blur,
+ use_optimized,
ignore_transparent,
0,
0,
- 0,
- 0,
+ geom_w,
+ geom_h,
);
}
diff --git a/src/server/output.rs b/src/server/output.rs
index d3d844f..dc4b418 100644
--- a/src/server/output.rs
+++ b/src/server/output.rs
@@ -752,6 +752,11 @@ unsafe extern "C" fn handle_destroy(listener: *mut ffi::wl_listener, _data: *mut
wl_listener_remove(&mut (*output).frame);
wl_listener_remove(&mut (*output).present);
+ if !(*output).scene_output.is_null() {
+ ffi::wlr_scene_output_destroy((*output).scene_output);
+ (*output).scene_output = std::ptr::null_mut();
+ }
+
if !(*output).background_rect.is_null() {
ffi::wlr_scene_node_destroy((*output).background_rect as *mut ffi::wlr_scene_node);
(*output).background_rect = std::ptr::null_mut();
@@ -767,7 +772,6 @@ unsafe extern "C" fn handle_destroy(listener: *mut ffi::wl_listener, _data: *mut
}
(*output).wlr_output = std::ptr::null_mut();
- (*output).scene_output = std::ptr::null_mut();
(*output).scheduled.mode = OutputMode::None;
(*output).sent.mode = OutputMode::None;
(*output).current.mode = OutputMode::None;
diff --git a/src/server/server.rs b/src/server/server.rs
index fd13441..f7f831f 100644
--- a/src/server/server.rs
+++ b/src/server/server.rs
@@ -194,8 +194,12 @@ pub unsafe fn wl_list_insert(list: *mut WlList, elm: *mut WlList) {
pub unsafe fn wl_list_remove(elm: *mut WlList) {
(*(*elm).next).prev = (*elm).prev;
(*(*elm).prev).next = (*elm).next;
- (*elm).next = std::ptr::null_mut();
- (*elm).prev = std::ptr::null_mut();
+}
+
+pub unsafe fn wl_list_remove_and_reinit(elm: *mut WlList) {
+ wl_list_remove(elm);
+ (*elm).prev = elm;
+ (*elm).next = elm;
}
pub unsafe fn wl_signal_add(signal: *mut ffi::wl_signal, listener: *mut ffi::wl_listener) {
@@ -805,6 +809,10 @@ impl Server {
// 5. Destroy wlroots core hardware interfaces
log::info!("[deinit] destroying backend");
ffi::wlr_backend_destroy(self.backend);
+ if !self.session.is_null() {
+ log::info!("[deinit] destroying session");
+ ffi::wlr_session_destroy(self.session);
+ }
log::info!("[deinit] destroying renderer");
ffi::wlr_renderer_destroy(self.renderer);
log::info!("[deinit] destroying allocator");
diff --git a/src/server/window.rs b/src/server/window.rs
index 9bc1d1f..38192bb 100644
--- a/src/server/window.rs
+++ b/src/server/window.rs
@@ -2,7 +2,7 @@
// SPDX-License-Identifier: GPL-3.0-only
use crate::ffi;
-use crate::server::{Server, WlList, wl_list_insert, wl_list_remove, WlListener, wl_signal_add};
+use crate::server::{Server, WlList, wl_list_insert, wl_list_remove, wl_list_remove_and_reinit, WlListener, wl_signal_add};
use crate::wm_node::WmNode;
use crate::xdg_toplevel::ConfigureState;
@@ -278,6 +278,16 @@ impl Window {
self.get_app_id_string().as_deref() == Some("cce-wallpaper")
}
+ pub unsafe fn is_linked(&self) -> bool {
+ let prev = self.node.link.prev;
+ let next = self.node.link.next;
+ if prev.is_null() || next.is_null() {
+ return false;
+ }
+ let self_ptr = &self.node.link as *const ffi::wl_list as *mut ffi::wl_list;
+ prev != self_ptr
+ }
+
pub unsafe fn create(impl_type: WindowImpl, server: *mut Server) -> Result<*mut Self, &'static str> {
let hidden_tree = (*server).scene.hidden_tree;
@@ -743,18 +753,20 @@ impl Window {
pub unsafe fn set_closing(&mut self) {
if self.state != WindowState::Closing {
self.state = WindowState::Closing;
- wl_list_remove(&mut self.node.link as *mut ffi::wl_list as *mut WlList);
- self.node.link.prev = &mut self.node.link;
- self.node.link.next = &mut self.node.link;
+ if self.is_linked() {
+ wl_list_remove_and_reinit(&mut self.node.link as *mut ffi::wl_list as *mut WlList);
+ }
}
}
pub unsafe fn unmap(&mut self) {
log::debug!("window '{:?}' unmapped", self.get_title());
+ if self.state != WindowState::Mapped {
+ return;
+ }
wl_listener_remove_safe(&mut self.commit);
self.surfaces.save();
assert!(!matches!(self.impl_type, WindowImpl::Destroying));
- assert_eq!(self.state, WindowState::Mapped);
self.set_closing();
(*self.server).wm.dirty_windowing();
@@ -973,18 +985,20 @@ impl Window {
blur: false,
};
- wl_list_remove(&mut self.node.link as *mut ffi::wl_list as *mut WlList);
- self.node.link.prev = &mut self.node.link;
- self.node.link.next = &mut self.node.link;
+ if self.is_linked() {
+ wl_list_remove_and_reinit(&mut self.node.link as *mut ffi::wl_list as *mut WlList);
+ }
self.make_inert();
}
WindowState::Ready | WindowState::Initialized | WindowState::Mapped => {
let wm_v1 = (*self.server).wm.object;
if wm_v1.is_null() {
- let is_linked = self.node.link.prev as *const _ != &self.node.link as *const _;
+ let is_linked = self.is_linked();
if !is_linked {
- wl_list_remove(&mut self.node.link as *mut ffi::wl_list as *mut WlList);
+ if !self.node.link.prev.is_null() && !self.node.link.next.is_null() {
+ wl_list_remove_and_reinit(&mut self.node.link as *mut ffi::wl_list as *mut WlList);
+ }
let rendering_list = &mut (*self.server).wm.rendering_requested.list as *mut ffi::wl_list as *mut WlList;
wl_list_insert((*rendering_list).prev, &mut self.node.link as *mut ffi::wl_list as *mut WlList);
@@ -1041,8 +1055,16 @@ impl Window {
// Send window to manager
ffi::wl_resource_post_event(wm_v1, ffi::ZCCE_WINDOW_MANAGER_V1_WINDOW, res); // zcce_window_manager_v1.window
+ res
+ } else {
+ self.object
+ };
- wl_list_remove(&mut self.node.link as *mut ffi::wl_list as *mut WlList);
+ let is_linked = self.is_linked();
+ if !is_linked {
+ if !self.node.link.prev.is_null() && !self.node.link.next.is_null() {
+ wl_list_remove_and_reinit(&mut self.node.link as *mut ffi::wl_list as *mut WlList);
+ }
let rendering_list = &mut (*self.server).wm.rendering_requested.list as *mut ffi::wl_list as *mut WlList;
wl_list_insert((*rendering_list).prev, &mut self.node.link as *mut ffi::wl_list as *mut WlList);
@@ -1076,10 +1098,6 @@ impl Window {
}
}
}
-
- res
- } else {
- self.object
};
if new_resource {
@@ -1541,15 +1559,32 @@ impl Window {
let blur_enabled = requested.blur;
let app_id = self.get_app_id_string().unwrap_or_default();
let mut ignore_transparent = (*self.server).wm.layout.window_backdrop_blur_ignore_transparent;
- if app_id.starts_with("cce-status") {
+ let is_status = self.tiling_mode == crate::tiling::TilingMode::Status ||
+ app_id.starts_with("cce-status");
+ if is_status {
ignore_transparent = (*self.server).wm.layout.status_backdrop_blur_ignore_transparent;
}
- let width = (self.rendering_sent.width as f64 * self.scale) as i32;
- let height = (self.rendering_sent.height as f64 * self.scale) as i32;
+ let use_optimized = if is_status { false } else { (*self.server).wm.layout.scenefx_optimized_blur };
+ let toplevel_w = match self.impl_type {
+ WindowImpl::Toplevel(toplevel) => {
+ if toplevel.is_null() { 0 } else { (*toplevel).geometry.width }
+ }
+ _ => 0,
+ };
+ let toplevel_h = match self.impl_type {
+ WindowImpl::Toplevel(toplevel) => {
+ if toplevel.is_null() { 0 } else { (*toplevel).geometry.height }
+ }
+ _ => 0,
+ };
+ let actual_w = if self.rendering_sent.width > 0 { self.rendering_sent.width } else { toplevel_w as u32 };
+ let actual_h = if self.rendering_sent.height > 0 { self.rendering_sent.height } else { toplevel_h as u32 };
+ let width = (actual_w as f64 * self.scale) as i32;
+ let height = (actual_h as f64 * self.scale) as i32;
ffi::river_scene_node_enable_blur(
self.tree as *mut ffi::wlr_scene_node,
blur_enabled,
- (*self.server).wm.layout.scenefx_optimized_blur,
+ use_optimized,
ignore_transparent,
0,
0,
@@ -1652,8 +1687,12 @@ impl Window {
self.last_applied_scale = self.scale;
}
- self.box_geom.width = self.rendering_sent.width as i32;
- self.box_geom.height = self.rendering_sent.height as i32;
+ if self.rendering_sent.width > 0 {
+ self.box_geom.width = self.rendering_sent.width as i32;
+ }
+ if self.rendering_sent.height > 0 {
+ self.box_geom.height = self.rendering_sent.height as i32;
+ }
let mut clip = requested.clip;
let mut content_clip = requested.content_clip;
@@ -3113,5 +3152,9 @@ unsafe fn wl_listener_remove_safe(listener: *mut ffi::wl_listener) {
unsafe extern "C" fn handle_window_commit(listener: *mut ffi::wl_listener, _data: *mut std::ffi::c_void) {
let window = crate::container_of!(listener, Window, commit);
+ let was_status = (*window).is_status_bar();
(*window).render_finish();
+ if was_status {
+ (*(*window).server).wm.dirty_windowing();
+ }
}
diff --git a/src/server/wlroots_log_wrapper.c b/src/server/wlroots_log_wrapper.c
index 9ea316d..bb80fc6 100644
--- a/src/server/wlroots_log_wrapper.c
+++ b/src/server/wlroots_log_wrapper.c
@@ -680,8 +680,16 @@ static void get_size_iterator(struct wlr_scene_buffer *buffer, int sx, int sy, v
if (buffer->dst_height > size[1]) size[1] = buffer->dst_height;
}
+static void find_buffer_iterator(struct wlr_scene_buffer *buffer, int sx, int sy, void *user_data) {
+ (void)sx;
+ (void)sy;
+ struct wlr_scene_buffer **result = (struct wlr_scene_buffer **)user_data;
+ if (*result == NULL) {
+ *result = buffer;
+ }
+}
+
void river_scene_node_enable_blur(struct wlr_scene_node *node, bool enabled, bool optimized, bool ignore_transparent, int x, int y, int width, int height) {
- (void)ignore_transparent;
if (node->type != WLR_SCENE_NODE_TREE) {
return;
}
@@ -750,6 +758,11 @@ void river_scene_node_enable_blur(struct wlr_scene_node *node, bool enabled, boo
if (std_blur_node) {
wlr_scene_node_set_position(std_blur_node, x, y);
+ struct wlr_scene_buffer *source_buffer = NULL;
+ if (ignore_transparent) {
+ wlr_scene_node_for_each_buffer(node, find_buffer_iterator, &source_buffer);
+ }
+ wlr_scene_blur_set_transparency_mask_source((struct wlr_scene_blur *)std_blur_node, source_buffer);
}
// Ensure correct stack order (from back to front): opt_blur_node -> std_blur_node -> window content
@@ -772,6 +785,13 @@ static void set_opacity_iterator(struct wlr_scene_buffer *buffer, int sx, int sy
void river_scene_node_set_opacity(struct wlr_scene_node *node, float opacity) {
wlr_scene_node_for_each_buffer(node, set_opacity_iterator, &opacity);
+ if (node->type == WLR_SCENE_NODE_TREE) {
+ struct wlr_scene_tree *tree = wlr_scene_tree_from_node(node);
+ struct wlr_scene_node *blur_node = find_blur_node(tree);
+ if (blur_node && blur_node->type == WLR_SCENE_NODE_BLUR) {
+ wlr_scene_blur_set_alpha((struct wlr_scene_blur *)blur_node, opacity);
+ }
+ }
}
static void set_corner_radius_iterator(struct wlr_scene_buffer *buffer, int sx, int sy, void *user_data) {
diff --git a/src/server/xdg_toplevel.rs b/src/server/xdg_toplevel.rs
index 3fda19f..0a7ca16 100644
--- a/src/server/xdg_toplevel.rs
+++ b/src/server/xdg_toplevel.rs
@@ -361,6 +361,19 @@ unsafe extern "C" fn handle_map(listener: *mut ffi::wl_listener, _data: *mut std
log::error!("Window map failed: {}", e);
let client = ffi::wl_resource_get_client((*(*toplevel).wlr_toplevel).resource);
ffi::wl_client_post_no_memory(client);
+ return;
+ }
+
+ let base = ffi::river_wlr_xdg_toplevel_get_base((*toplevel).wlr_toplevel);
+ let mut new_geometry = std::mem::zeroed();
+ ffi::river_wlr_xdg_surface_get_geometry(base, &mut new_geometry);
+ (*toplevel).geometry = new_geometry;
+ let is_status = (*(*toplevel).window).tiling_mode == crate::tiling::TilingMode::Status ||
+ (*(*toplevel).window).get_app_id_string().map_or(false, |id| id.starts_with("cce-status"));
+ if is_status {
+ (*(*toplevel).window).box_geom.width = new_geometry.width;
+ (*(*toplevel).window).box_geom.height = new_geometry.height;
+ (*(*(*toplevel).window).server).wm.dirty_windowing();
}
}
@@ -401,12 +414,36 @@ unsafe extern "C" fn handle_ack_configure(
}
_ => {}
}
+
+ let base = ffi::river_wlr_xdg_toplevel_get_base((*toplevel).wlr_toplevel);
+ let mut new_geometry = std::mem::zeroed();
+ ffi::river_wlr_xdg_surface_get_geometry(base, &mut new_geometry);
+ (*toplevel).geometry = new_geometry;
+
+ let is_status = (*(*toplevel).window).tiling_mode == crate::tiling::TilingMode::Status ||
+ (*(*toplevel).window).get_app_id_string().map_or(false, |id| id.starts_with("cce-status"));
+ if is_status {
+ (*(*toplevel).window).box_geom.width = new_geometry.width;
+ (*(*toplevel).window).box_geom.height = new_geometry.height;
+ (*(*(*toplevel).window).server).wm.dirty_windowing();
+ }
}
unsafe extern "C" fn handle_commit(listener: *mut ffi::wl_listener, _data: *mut std::ffi::c_void) {
let toplevel = crate::container_of!(listener, XdgToplevel, commit);
let window = (*toplevel).window;
let base = ffi::river_wlr_xdg_toplevel_get_base((*toplevel).wlr_toplevel);
+ let surface = ffi::river_wlr_xdg_surface_get_surface(base);
+ let committed_w = ffi::river_wlr_surface_get_width(surface);
+ let committed_h = ffi::river_wlr_surface_get_height(surface);
+ if committed_w > 0 && committed_h > 0 {
+ (*toplevel).geometry.width = committed_w;
+ (*toplevel).geometry.height = committed_h;
+ } else {
+ let mut new_geometry = std::mem::zeroed();
+ ffi::river_wlr_xdg_surface_get_geometry(base, &mut new_geometry);
+ (*toplevel).geometry = new_geometry;
+ }
let app_id = (*window).get_app_id_string().unwrap_or_default();
let mut ignore_transparent = (*(*window).server).wm.layout.window_backdrop_blur_ignore_transparent;
@@ -414,12 +451,17 @@ unsafe extern "C" fn handle_commit(listener: *mut ffi::wl_listener, _data: *mut
ignore_transparent = (*(*window).server).wm.layout.status_backdrop_blur_ignore_transparent;
}
let scale = (*window).scale;
- let geom_w = ((*window).rendering_sent.width as f64 * scale) as i32;
- let geom_h = ((*window).rendering_sent.height as f64 * scale) as i32;
+ let actual_w = if (*window).rendering_sent.width > 0 { (*window).rendering_sent.width } else { (*toplevel).geometry.width as u32 };
+ let actual_h = if (*window).rendering_sent.height > 0 { (*window).rendering_sent.height } else { (*toplevel).geometry.height as u32 };
+ let geom_w = (actual_w as f64 * scale) as i32;
+ let geom_h = (actual_h as f64 * scale) as i32;
+ let is_status = (*window).tiling_mode == crate::tiling::TilingMode::Status ||
+ app_id.starts_with("cce-status");
+ let use_optimized = if is_status { false } else { (*(*window).server).wm.layout.scenefx_optimized_blur };
ffi::river_scene_node_enable_blur(
(*window).tree as *mut ffi::wlr_scene_node,
(*window).rendering_requested.blur,
- (*(*window).server).wm.layout.scenefx_optimized_blur,
+ use_optimized,
ignore_transparent,
0,
0,
@@ -448,6 +490,17 @@ unsafe extern "C" fn handle_commit(listener: *mut ffi::wl_listener, _data: *mut
if ffi::river_wlr_xdg_surface_get_initial_commit(base) {
assert!((*window).state != crate::window::WindowState::Ready);
(*window).state = crate::window::WindowState::Ready;
+ let mut new_geometry = std::mem::zeroed();
+ ffi::river_wlr_xdg_surface_get_geometry(base, &mut new_geometry);
+ (*toplevel).geometry = new_geometry;
+
+ let is_status = (*window).tiling_mode == crate::tiling::TilingMode::Status ||
+ (*window).get_app_id_string().map_or(false, |id| id.starts_with("cce-status"));
+ if is_status {
+ (*window).box_geom.width = new_geometry.width;
+ (*window).box_geom.height = new_geometry.height;
+ }
+
(*(*window).server).wm.dirty_windowing();
return;
}
@@ -477,6 +530,8 @@ unsafe extern "C" fn handle_commit(listener: *mut ffi::wl_listener, _data: *mut
(*window).configure_sent.width = Some(new_geometry.width as u32);
(*window).configure_sent.height = Some(new_geometry.height as u32);
if is_status {
+ (*window).box_geom.width = new_geometry.width;
+ (*window).box_geom.height = new_geometry.height;
(*(*window).server).wm.dirty_windowing();
}
} else {
@@ -502,6 +557,8 @@ unsafe extern "C" fn handle_commit(listener: *mut ffi::wl_listener, _data: *mut
if matches!((*window).tiling_mode, crate::tiling::TilingMode::Floating | crate::tiling::TilingMode::Popup) || is_status {
(*window).set_dimensions(new_geometry.width as u32, new_geometry.height as u32);
if is_status {
+ (*window).box_geom.width = new_geometry.width;
+ (*window).box_geom.height = new_geometry.height;
(*(*window).server).wm.dirty_windowing();
}
}