git.lucas.co / cce-compositor
Wayland compositor (wlroots)
git clone https://git.lucas.co/cce-compositor.git

commitc975f53550ffa6d171264b6cb6983e8d471d87b3
parent8648f4fc57
authorLucas Galante <[email protected]>
date2026-06-24 21:35
window_manager: improve focus-window IPC to use weighted scoring instead of first match

 src/server/window_manager.rs | 32 ++++++++++++++++++++++----------
 1 file changed, 22 insertions(+), 10 deletions(-)

diff --git a/src/server/window_manager.rs b/src/server/window_manager.rs
index ecbff8e..8f43b69 100644
--- a/src/server/window_manager.rs
+++ b/src/server/window_manager.rs
@@ -1833,28 +1833,40 @@ fn get_closest_tag(x: f64, y: f64) -> i32 {
                 if parts.len() < 2 { return "error: missing app_id or title\n".to_string(); }
                 let query = parts[1..].join(" ").to_lowercase();
                 if let Some(seat) = self.first_seat() {
-                    let mut target: *mut Window = std::ptr::null_mut();
+                    let mut best_target: *mut Window = std::ptr::null_mut();
+                    let mut best_score = 0;
                     for &w in self.windows.iter() {
                         if !w.is_null() && !(*w).closed && !(*w).minimized && matches!((*w).state, crate::window::WindowState::Mapped) {
                             let aid = (*w).get_app_id_string();
                             let title = (*w).get_title_string();
 
-                            let mut match_found = false;
+                            let mut score = 0;
                             if let Some(ref aid_str) = aid {
-                                if aid_str.to_lowercase().contains(&query) { match_found = true; }
+                                let aid_lower = aid_str.to_lowercase();
+                                if aid_lower == query {
+                                    score = score.max(100);
+                                } else if aid_lower.contains(&query) {
+                                    score = score.max(50);
+                                }
                             }
                             if let Some(ref title_str) = title {
-                                if title_str.to_lowercase().contains(&query) { match_found = true; }
+                                let title_lower = title_str.to_lowercase();
+                                if title_lower == query {
+                                    score = score.max(80);
+                                } else if title_lower.contains(&query) {
+                                    score = score.max(30);
+                                }
                             }
-                            if match_found {
-                                target = w;
-                                break;
+
+                            if score > best_score {
+                                best_score = score;
+                                best_target = w;
                             }
                         }
                     }
-                    if !target.is_null() {
-                        (*seat).focus(crate::seat::Focus::Window(target));
-                        self.raise_window(target);
+                    if !best_target.is_null() {
+                        (*seat).focus(crate::seat::Focus::Window(best_target));
+                        self.raise_window(best_target);
                         self.dirty_windowing();
                         "ok\n".to_string()
                     } else {