diff --git a/CMakeLists.txt b/CMakeLists.txt
index 290d950..abb71f0 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -75,6 +75,7 @@ add_library(miracle-wm-implementation
src/minimal_window_manager.cpp src/minimal_window_manager.h
src/config_error_handler.cpp src/config_error_handler.h
src/scratchpad.h src/scratchpad.cpp
+ src/compositor_state.h src/compositor_state.cpp
)
add_executable(miracle-wm
diff --git a/src/compositor_state.cpp b/src/compositor_state.cpp
new file mode 100644
index 0000000..1d4bf58
--- /dev/null
+++ b/src/compositor_state.cpp
@@ -0,0 +1,75 @@
+/**
+Copyright (C) 2024 Matthew Kosarek
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
+**/
+
+#include "compositor_state.h"
+
+using namespace miracle;
+
+[[nodiscard]] std::shared_ptr CompositorState::active() const
+{
+ if (!focused.expired())
+ return focused.lock();
+
+ return nullptr;
+}
+
+void CompositorState::focus(std::shared_ptr const& container)
+{
+ auto it = std::find_if(focus_order.begin(), focus_order.end(), [&](auto const& element)
+ {
+ return !element.expired() && element.lock() == container;
+ });
+
+ if (it != focus_order.end())
+ {
+ std::rotate(focus_order.begin(), it, it + 1);
+ focused = container;
+ }
+}
+
+void CompositorState::unfocus(std::shared_ptr const& container)
+{
+ if (!focused.expired())
+ {
+ if (focused.lock() == container)
+ focused.reset();
+ }
+}
+
+void CompositorState::add(std::shared_ptr const& container)
+{
+ CompositorState::focus_order.push_back(container);
+}
+
+void CompositorState::remove(std::shared_ptr const& container)
+{
+ focus_order.erase(std::remove_if(focus_order.begin(), focus_order.end(), [&](auto const& element)
+ {
+ return !element.expired() && element.lock() == container;
+ }));
+}
+
+std::shared_ptr CompositorState::get_first_with_type(ContainerType type) const
+{
+ for (auto const& container : focus_order)
+ {
+ if (!container.expired() && container.lock()->get_type() == type)
+ return container.lock();
+ }
+
+ return nullptr;
+}
\ No newline at end of file
diff --git a/src/compositor_state.h b/src/compositor_state.h
index eda327d..d39a0f0 100644
--- a/src/compositor_state.h
+++ b/src/compositor_state.h
@@ -18,12 +18,15 @@ along with this program. If not, see .
#ifndef MIRACLE_WM_COMPOSITOR_STATE_H
#define MIRACLE_WM_COMPOSITOR_STATE_H
+#include "container.h"
+
+#include
#include
#include
+#include
namespace miracle
{
-class Container;
class Output;
enum class WindowManagerMode
@@ -40,14 +43,26 @@ enum class WindowManagerMode
selecting
};
-struct CompositorState
+class CompositorState
{
+public:
WindowManagerMode mode = WindowManagerMode::normal;
- std::shared_ptr