From d3b4fcbf18ce71731bdf06fd59055c1d8ebf3b89 Mon Sep 17 00:00:00 2001
From: Janis <janis@nirgendwo.xyz>
Date: Sun, 28 Nov 2021 21:15:51 +0100
Subject: [PATCH] added a way to add already existing windows to wm

---
 src/backends/traits.rs   |  2 +-
 src/backends/xlib/mod.rs | 28 ++++++++++++++++++++++++++--
 src/main.rs              |  2 --
 src/state.rs             |  7 +++++++
 4 files changed, 34 insertions(+), 5 deletions(-)

diff --git a/src/backends/traits.rs b/src/backends/traits.rs
index 9ff085f..c8e8494 100644
--- a/src/backends/traits.rs
+++ b/src/backends/traits.rs
@@ -38,7 +38,7 @@ pub trait WindowServerBackend {
     fn ungrab_cursor(&self);
     fn move_cursor(&self, window: Option<Self::Window>, position: Point<i32>);
 
-    fn all_windows(&self) -> Vec<Self::Window>;
+    fn all_windows(&self) -> Option<Vec<Self::Window>>;
 
     fn resize_window(&self, window: Self::Window, new_size: Point<i32>) {
         self.configure_window(window, Some(new_size), None, None);
diff --git a/src/backends/xlib/mod.rs b/src/backends/xlib/mod.rs
index 7c3c3a7..2f50b6c 100644
--- a/src/backends/xlib/mod.rs
+++ b/src/backends/xlib/mod.rs
@@ -858,8 +858,32 @@ impl WindowServerBackend for XLib {
         }
     }
 
-    fn all_windows(&self) -> Vec<Self::Window> {
-        todo!()
+    fn all_windows(&self) -> Option<Vec<Self::Window>> {
+        let mut parent = 0;
+        let mut root = 0;
+        let mut children = std::ptr::null_mut();
+        let mut num_children = 0;
+
+        unsafe {
+            xlib::XQueryTree(
+                self.dpy(),
+                self.root,
+                &mut root,
+                &mut parent,
+                &mut children,
+                &mut num_children,
+            ) != 0
+        }
+        .then(|| {
+            let windows = unsafe {
+                std::slice::from_raw_parts(children, num_children as usize)
+                    .to_vec()
+            };
+
+            unsafe { xlib::XFree(children as *mut _) };
+
+            windows
+        })
     }
 }
 
diff --git a/src/main.rs b/src/main.rs
index 198e686..c290067 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -11,10 +11,8 @@ use state::WMConfig;
 
 mod backends;
 mod clients;
-//mod clients2;
 mod state;
 mod util;
-mod xlib;
 
 pub mod error {
     use thiserror::Error;
diff --git a/src/state.rs b/src/state.rs
index 357ebd1..91927f0 100644
--- a/src/state.rs
+++ b/src/state.rs
@@ -253,6 +253,13 @@ where
 
         self.add_vs_switch_keybinds();
 
+        // add all already existing windows to the WM
+        if let Some(windows) = self.backend.all_windows() {
+            windows
+                .into_iter()
+                .for_each(|window| self.new_client(window));
+        }
+
         self
     }