summaryrefslogtreecommitdiff
path: root/src/config/lua/objects
diff options
context:
space:
mode:
authorImperishableSecret <57067794+imperishableSecret@users.noreply.github.com>2026-04-30 02:43:15 +0530
committerGitHub <noreply@github.com>2026-04-29 22:13:15 +0100
commit56d7a43102b53f79a2311662783d5dd94cb2f1a5 (patch)
tree1c1c0427245abdca295801803329fa716952ca37 /src/config/lua/objects
parent31e025dbe04dbe1836ea759f6b6e2ea09591fb23 (diff)
config/lua: expand properties in the workspace object (#14194)
Diffstat (limited to 'src/config/lua/objects')
-rw-r--r--src/config/lua/objects/LuaGroup.cpp83
-rw-r--r--src/config/lua/objects/LuaGroup.hpp14
-rw-r--r--src/config/lua/objects/LuaWindow.cpp34
-rw-r--r--src/config/lua/objects/LuaWorkspace.cpp87
4 files changed, 186 insertions, 32 deletions
diff --git a/src/config/lua/objects/LuaGroup.cpp b/src/config/lua/objects/LuaGroup.cpp
new file mode 100644
index 00000000..551f8a91
--- /dev/null
+++ b/src/config/lua/objects/LuaGroup.cpp
@@ -0,0 +1,83 @@
+#include "LuaGroup.hpp"
+#include "LuaWindow.hpp"
+#include "LuaObjectHelpers.hpp"
+
+#include "../../../desktop/view/Group.hpp"
+
+#include <string_view>
+
+using namespace Config::Lua;
+
+static constexpr const char* MT = "HL.Group";
+
+static int groupEq(lua_State* L) {
+ const auto* lhs = sc<WP<Desktop::View::CGroup>*>(luaL_checkudata(L, 1, MT));
+ const auto* rhs = sc<WP<Desktop::View::CGroup>*>(luaL_checkudata(L, 2, MT));
+
+ lua_pushboolean(L, lhs->lock() == rhs->lock());
+ return 1;
+}
+
+static int groupToString(lua_State* L) {
+ const auto* ref = sc<WP<Desktop::View::CGroup>*>(luaL_checkudata(L, 1, MT));
+ const auto group = ref->lock();
+
+ if (!group)
+ lua_pushstring(L, "HL.Group(expired)");
+ else
+ lua_pushfstring(L, "HL.Group(%p)", group.get());
+
+ return 1;
+}
+
+static int groupIndex(lua_State* L) {
+ auto* ref = sc<WP<Desktop::View::CGroup>*>(luaL_checkudata(L, 1, MT));
+ const auto group = ref->lock();
+ if (!group) {
+ Log::logger->log(Log::DEBUG, "[lua] Tried to access an expired object");
+ lua_pushnil(L);
+ return 1;
+ }
+
+ const std::string_view key = luaL_checkstring(L, 2);
+
+ if (key == "locked")
+ lua_pushboolean(L, group->locked());
+ else if (key == "denied")
+ lua_pushboolean(L, group->denied());
+ else if (key == "size")
+ lua_pushinteger(L, sc<lua_Integer>(group->size()));
+ else if (key == "current_index")
+ lua_pushinteger(L, sc<lua_Integer>(group->getCurrentIdx()) + 1);
+ else if (key == "current") {
+ const auto current = group->current();
+ if (current)
+ Objects::CLuaWindow::push(L, current);
+ else
+ lua_pushnil(L);
+ } else if (key == "members") {
+ lua_newtable(L);
+ int i = 1;
+ for (const auto& grouped : group->windows()) {
+ const auto groupedWindow = grouped.lock();
+ if (!groupedWindow)
+ continue;
+
+ Objects::CLuaWindow::push(L, groupedWindow);
+ lua_rawseti(L, -2, i++);
+ }
+ } else
+ lua_pushnil(L);
+
+ return 1;
+}
+
+void Objects::CLuaGroup::setup(lua_State* L) {
+ registerMetatable(L, MT, groupIndex, gcRef<WP<Desktop::View::CGroup>>, groupEq, groupToString);
+}
+
+void Objects::CLuaGroup::push(lua_State* L, SP<Desktop::View::CGroup> group) {
+ new (lua_newuserdata(L, sizeof(WP<Desktop::View::CGroup>))) WP<Desktop::View::CGroup>(group);
+ luaL_getmetatable(L, MT);
+ lua_setmetatable(L, -2);
+}
diff --git a/src/config/lua/objects/LuaGroup.hpp b/src/config/lua/objects/LuaGroup.hpp
new file mode 100644
index 00000000..b7d638c6
--- /dev/null
+++ b/src/config/lua/objects/LuaGroup.hpp
@@ -0,0 +1,14 @@
+#pragma once
+
+#include <hyprutils/memory/WeakPtr.hpp>
+#include <lua.hpp>
+
+#include "../../../desktop/view/Group.hpp"
+
+namespace Config::Lua::Objects {
+ class CLuaGroup {
+ public:
+ static void setup(lua_State* L);
+ static void push(lua_State* L, SP<Desktop::View::CGroup> group);
+ };
+};
diff --git a/src/config/lua/objects/LuaWindow.cpp b/src/config/lua/objects/LuaWindow.cpp
index 1d933462..7fe87334 100644
--- a/src/config/lua/objects/LuaWindow.cpp
+++ b/src/config/lua/objects/LuaWindow.cpp
@@ -1,6 +1,7 @@
#include "LuaWindow.hpp"
#include "LuaWorkspace.hpp"
#include "LuaMonitor.hpp"
+#include "LuaGroup.hpp"
#include "LuaObjectHelpers.hpp"
#include "../../../desktop/view/Window.hpp"
@@ -126,38 +127,7 @@ static int windowIndex(lua_State* L) {
return 1;
}
- lua_newtable(L);
-
- lua_pushboolean(L, w->m_group->locked());
- lua_setfield(L, -2, "locked");
-
- lua_pushboolean(L, w->m_group->denied());
- lua_setfield(L, -2, "denied");
-
- lua_pushinteger(L, sc<lua_Integer>(w->m_group->size()));
- lua_setfield(L, -2, "size");
-
- lua_pushinteger(L, sc<lua_Integer>(w->m_group->getCurrentIdx()) + 1);
- lua_setfield(L, -2, "current_index");
-
- const auto current = w->m_group->current();
- if (current)
- Objects::CLuaWindow::push(L, current);
- else
- lua_pushnil(L);
- lua_setfield(L, -2, "current");
-
- lua_newtable(L);
- int i = 1;
- for (const auto& grouped : w->m_group->windows()) {
- const auto groupedWindow = grouped.lock();
- if (!groupedWindow)
- continue;
-
- Objects::CLuaWindow::push(L, groupedWindow);
- lua_rawseti(L, -2, i++);
- }
- lua_setfield(L, -2, "members");
+ Objects::CLuaGroup::push(L, w->m_group);
} else if (key == "tags") {
lua_newtable(L);
diff --git a/src/config/lua/objects/LuaWorkspace.cpp b/src/config/lua/objects/LuaWorkspace.cpp
index 84e4df0b..3f89b41a 100644
--- a/src/config/lua/objects/LuaWorkspace.cpp
+++ b/src/config/lua/objects/LuaWorkspace.cpp
@@ -1,10 +1,19 @@
#include "LuaWorkspace.hpp"
#include "LuaMonitor.hpp"
+#include "LuaWindow.hpp"
+#include "LuaGroup.hpp"
#include "LuaObjectHelpers.hpp"
#include "../../../desktop/Workspace.hpp"
+#include "../../../desktop/view/Group.hpp"
#include "../../../helpers/Monitor.hpp"
+#include "../../../layout/space/Space.hpp"
+#include "../../../layout/algorithm/Algorithm.hpp"
+#include "../../../layout/algorithm/TiledAlgorithm.hpp"
+#include "../../../layout/supplementary/WorkspaceAlgoMatcher.hpp"
+#include "../../../Compositor.hpp"
+#include <algorithm>
#include <string_view>
using namespace Config::Lua;
@@ -32,6 +41,55 @@ static int workspaceToString(lua_State* L) {
return 1;
}
+static int workspaceGetWindows(lua_State* L) {
+ auto* ref = sc<PHLWORKSPACEREF*>(luaL_checkudata(L, 1, MT));
+ const auto ws = ref->lock();
+ if (!ws || ws->inert()) {
+ lua_newtable(L);
+ return 1;
+ }
+
+ lua_newtable(L);
+ int idx = 1;
+ for (auto const& w : g_pCompositor->m_windows) {
+ if (w->m_workspace == ws) {
+ Objects::CLuaWindow::push(L, w);
+ lua_rawseti(L, -2, idx++);
+ }
+ }
+ return 1;
+}
+
+static int workspaceGetGroups(lua_State* L) {
+ auto* ref = sc<PHLWORKSPACEREF*>(luaL_checkudata(L, 1, MT));
+ const auto ws = ref->lock();
+ if (!ws || ws->inert()) {
+ lua_newtable(L);
+ return 1;
+ }
+
+ lua_newtable(L);
+ int idx = 1;
+
+ std::vector<Desktop::View::CGroup*> pushedGroups;
+
+ for (auto const& w : g_pCompositor->m_windows) {
+ if (w->m_workspace != ws || !w->m_group)
+ continue;
+
+ if (std::ranges::find(pushedGroups, w->m_group.get()) != pushedGroups.end())
+ continue;
+
+ pushedGroups.push_back(w->m_group.get());
+
+ Objects::CLuaGroup::push(L, w->m_group);
+
+ lua_rawseti(L, -2, idx++);
+ }
+
+ return 1;
+}
+
static int workspaceIndex(lua_State* L) {
auto* ref = sc<PHLWORKSPACEREF*>(luaL_checkudata(L, 1, MT));
const auto ws = ref->lock();
@@ -70,6 +128,35 @@ static int workspaceIndex(lua_State* L) {
lua_pushboolean(L, ws->m_hasFullscreenWindow);
else if (key == "is_persistent")
lua_pushboolean(L, ws->isPersistent());
+ else if (key == "is_empty")
+ lua_pushboolean(L, ws->getWindows() == 0);
+ else if (key == "config_name")
+ lua_pushstring(L, ws->getConfigName().c_str());
+ else if (key == "tiled_layout") {
+ std::string layoutName = "unknown";
+ if (ws->m_space && ws->m_space->algorithm() && ws->m_space->algorithm()->tiledAlgo()) {
+ const auto& TILED_ALGO = ws->m_space->algorithm()->tiledAlgo();
+ layoutName = Layout::Supplementary::algoMatcher()->getNameForTiledAlgo(&typeid(*TILED_ALGO.get()));
+ }
+ lua_pushstring(L, layoutName.c_str());
+ } else if (key == "last_window") {
+ const auto lastWindow = ws->m_lastFocusedWindow.lock();
+ if (lastWindow)
+ Objects::CLuaWindow::push(L, lastWindow);
+ else
+ lua_pushnil(L);
+ } else if (key == "fullscreen_window") {
+ const auto fsWindow = ws->getFullscreenWindow();
+ if (fsWindow)
+ Objects::CLuaWindow::push(L, fsWindow);
+ else
+ lua_pushnil(L);
+ } else if (key == "get_windows")
+ lua_pushcfunction(L, workspaceGetWindows);
+ else if (key == "get_groups")
+ lua_pushcfunction(L, workspaceGetGroups);
+ else if (key == "groups")
+ lua_pushinteger(L, sc<lua_Integer>(ws->getGroups()));
else
lua_pushnil(L);