gioser

tawasuyu/brahman

Rust 582TOML 222Markdown 73JSON 198630 Definiciones

feat(mirada-compositor): centrar la ventana en su celda si el cliente no la llena

Un cliente que presenta una superficie más pequeña que su celda (p. ej.
un terminal que redondea a celdas de texto enteras) dejaba el hueco todo
a un lado. Ahora ManagedWindow recuerda el tamaño de la celda y
render_loc() centra la superficie en el sobrante. Lo usan los dos
backends (winit y DRM).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

5230d42b112a5fc846d3108275b38188bd28e1db · por sergio · (hace 5 meses) · padre c07356d8b · ver el árbol en este commit

Delta semántico · 6

crates/apps/mirada-compositor/src/drm_backend.rs

  • cambió por dentro fn render

crates/apps/mirada-compositor/src/main.rs

2 archivos · +26 −4

diff --git a/crates/apps/mirada-compositor/src/drm_backend.rs b/crates/apps/mirada-compositor/src/drm_backend.rs
index fdbd593..e0bc467 100644
--- a/crates/apps/mirada-compositor/src/drm_backend.rs
+++ b/crates/apps/mirada-compositor/src/drm_backend.rs
@@ -92,7 +92,7 @@ impl DrmState {
                     render_elements_from_surface_tree(
                         &mut self.renderer,
                         &w.surface,
-                        w.loc,
+                        crate::render_loc(w),
                         1.0,
                         1.0,
                         Kind::Unspecified,
diff --git a/crates/apps/mirada-compositor/src/main.rs b/crates/apps/mirada-compositor/src/main.rs
index 9340ea3..d2c11f1 100644
--- a/crates/apps/mirada-compositor/src/main.rs
+++ b/crates/apps/mirada-compositor/src/main.rs
@@ -26,7 +26,9 @@ use smithay::backend::renderer::element::surface::{
 };
 use smithay::backend::renderer::element::Kind;
 use smithay::backend::renderer::gles::GlesRenderer;
-use smithay::backend::renderer::utils::{draw_render_elements, on_commit_buffer_handler};
+use smithay::backend::renderer::utils::{
+    draw_render_elements, on_commit_buffer_handler, with_renderer_surface_state,
+};
 use smithay::backend::renderer::{Color32F, Frame, Renderer};
 use smithay::backend::winit::{self, WinitEvent};
 use smithay::input::keyboard::{xkb, FilterResult, KeyboardHandle, Keysym, ModifiersState};
@@ -86,8 +88,11 @@ struct ManagedWindow {
     id: u64,
     toplevel: ToplevelSurface,
     surface: WlSurface,
-    /// Esquina superior-izquierda en píxeles, según el Cerebro.
+    /// Esquina superior-izquierda de la celda asignada, según el Cerebro.
     loc: (i32, i32),
+    /// Tamaño de la celda asignada — para centrar la ventana si el
+    /// cliente presenta una superficie más pequeña.
+    size: (i32, i32),
     visible: bool,
     /// `true` si flota: se compone por encima de las teseladas.
     floating: bool,
@@ -182,6 +187,7 @@ impl App {
             BodyOp::Configure { id, rect, visible, floating, fullscreen } => {
                 if let Some(w) = self.windows.iter_mut().find(|w| w.id == id) {
                     w.loc = (rect.x, rect.y);
+                    w.size = (rect.w, rect.h);
                     w.visible = visible;
                     w.floating = floating;
                     w.toplevel.with_pending_state(|s| {
@@ -258,6 +264,7 @@ impl App {
             toplevel,
             surface,
             loc: (0, 0),
+            size: (0, 0),
             visible: false,
             floating: false,
         });
@@ -512,6 +519,21 @@ fn send_frames_surface_tree(surface: &WlSurface, time: u32) {
 // Bucle principal
 // ---------------------------------------------------------------------
 
+/// Dónde pintar una ventana: su celda asignada, pero si el cliente
+/// presenta una superficie más pequeña que la celda (p. ej. un terminal
+/// que redondea su tamaño a celdas de texto enteras), se centra en el
+/// hueco sobrante en vez de dejarlo todo a un lado.
+fn render_loc(w: &ManagedWindow) -> (i32, i32) {
+    match with_renderer_surface_state(&w.surface, |s| s.surface_size()) {
+        Some(Some(size)) => {
+            let dx = ((w.size.0 - size.w) / 2).max(0);
+            let dy = ((w.size.1 - size.h) / 2).max(0);
+            (w.loc.0 + dx, w.loc.1 + dy)
+        }
+        _ => w.loc,
+    }
+}
+
 /// Carga las reglas de ventana del usuario, o ninguna si no hay archivo.
 fn load_user_rules() -> Rules {
     match Rules::default_path() {
@@ -815,7 +837,7 @@ fn run_winit() -> Result<(), Box<dyn std::error::Error>> {
                     render_elements_from_surface_tree(
                         renderer,
                         &w.surface,
-                        w.loc,
+                        render_loc(w),
                         1.0,
                         1.0,
                         Kind::Unspecified,