From 24c1a0a4d4b1bf57f48850ee817f6caa850da37a Mon Sep 17 00:00:00 2001 From: Ivan Malison Date: Sat, 16 May 2026 12:32:50 -0700 Subject: [PATCH] hyprland: switch overview to patched hyprexpo --- dotfiles/config/hypr/hyprland/binds.lua | 17 +- dotfiles/config/hypr/hyprland/core.lua | 43 +---- dotfiles/config/hypr/hyprland/settings.lua | 7 - dotfiles/config/hypr/hyprland/state.lua | 18 -- dotfiles/lib/bin/hypr_plugin_dev_session | 9 +- nixos/flake.lock | 25 --- nixos/flake.nix | 8 - nixos/flake/per-system.nix | 8 +- nixos/hyprland.nix | 18 +- nixos/packages/hyprexpo-drag-windows.patch | 198 +++++++++++++++++++++ nixos/packages/hyprspace-lua-api.patch | 87 --------- 11 files changed, 217 insertions(+), 221 deletions(-) create mode 100644 nixos/packages/hyprexpo-drag-windows.patch delete mode 100644 nixos/packages/hyprspace-lua-api.patch diff --git a/dotfiles/config/hypr/hyprland/binds.lua b/dotfiles/config/hypr/hyprland/binds.lua index 67408fa2..13411bf8 100644 --- a/dotfiles/config/hypr/hyprland/binds.lua +++ b/dotfiles/config/hypr/hyprland/binds.lua @@ -89,7 +89,7 @@ function M.setup(ctx) local function setup_window_overview_bindings() bind(main_mod .. " + SHIFT + C", hl.dsp.window.close(), desc("Close active window")) bind(main_mod .. " + SHIFT + Q", hl.dsp.exit(), desc("Exit Hyprland")) - bind(main_mod .. " + Tab", hyprspace("toggle"), desc("Toggle Hyprspace workspace overview", overview_bind_opts)) + bind(main_mod .. " + Tab", hyprexpo("toggle"), desc("Toggle hyprexpo workspace overview", overview_bind_opts)) bind(main_mod .. " + SHIFT + Tab", hyprwinview({ action = "show", include_current_workspace = false, @@ -195,21 +195,6 @@ function M.setup(ctx) bind("catchall", hl.dsp.submap("reset"), desc("Exit window picker")) end) - hl.define_submap("hyprexpo", function() - bind("Up", hyprexpo_dispatch("kb_focus", "up"), desc("Focus workspace tile above")) - bind("Left", hyprexpo_dispatch("kb_focus", "left"), desc("Focus workspace tile to the left")) - bind("Down", hyprexpo_dispatch("kb_focus", "down"), desc("Focus workspace tile below")) - bind("Right", hyprexpo_dispatch("kb_focus", "right"), desc("Focus workspace tile to the right")) - bind("Return", hyprexpo_dispatch("kb_confirm"), desc("Select focused workspace tile")) - bind("Space", hyprexpo_dispatch("kb_confirm"), desc("Select focused workspace tile")) - - for _, token in ipairs({ "a", "s", "d", "f", "g", "q", "w", "e", "r", "t", "z", "x", "c", "v", "b" }) do - bind(string.upper(token), hyprexpo_dispatch("kb_select", token), desc("Select workspace tile " .. token)) - end - - bind("Escape", hyprexpo("off"), desc("Close workspace expo")) - bind("catchall", hyprexpo("off"), desc("Close workspace expo")) - end) end local function setup_window_resize_and_monitor_bindings() diff --git a/dotfiles/config/hypr/hyprland/core.lua b/dotfiles/config/hypr/hyprland/core.lua index b0454ed8..e1dea9ea 100644 --- a/dotfiles/config/hypr/hyprland/core.lua +++ b/dotfiles/config/hypr/hyprland/core.lua @@ -127,10 +127,6 @@ function M.setup(ctx) return hyprexpo_call("expo", action or "toggle") end - local function hyprexpo_dispatch(dispatcher, arg) - return hyprexpo_call(dispatcher, arg) - end - local function hyprwinview(action) return function() local label = "hyprwinview" @@ -175,33 +171,6 @@ function M.setup(ctx) end end - local function hyprspace(action) - return function() - local request = action - if type(request) == "table" then - request.action = request.action or "toggle" - if request.all == nil then - request.all = true - end - else - request = { action = action or "toggle", all = true } - end - - overview_trace("hyprspace " .. tostring(request.action)) - if hl.plugin and hl.plugin.hyprspace and hl.plugin.hyprspace.overview then - hl.plugin.hyprspace.overview(request) - else - hl.notification.create({ - text = "hyprspace is not loaded", - duration = 1800, - icon = notification_icons.warning, - color = "rgba(edb443ff)", - font_size = 13, - }) - end - end - end - local function apply_nstack_config() if verify_config or not enable_nstack or not configure_nstack_plugin_from_lua then return @@ -240,8 +209,9 @@ function M.setup(ctx) gap_size = 5, gap_size_outer = 0, bg_col = 0xff111111, - workspace_method = "center current", + workspace_method = "first 1", skip_empty = false, + max_workspace = max_workspace, gesture_distance = 200, keynav_wrap_h = 1, keynav_wrap_v = 1, @@ -258,12 +228,7 @@ function M.setup(ctx) label_position = "center", label_offset_x = 6, label_offset_y = 6, - selection_label_enable = 1, - selection_label_token_map = "a,s,d,f,g,q,w,e,r,t,z,x,c,v,b", - selection_label_position = "top-right", - selection_label_offset_x = 6, - selection_label_offset_y = 6, - selection_label_color = 0xffedb443, + selection_label_enable = 0, label_show = "always", label_color_default = 0xffffffff, label_color_hover = 0xffeeeeee, @@ -614,10 +579,8 @@ function M.setup(ctx) ctx.overview_trace = overview_trace ctx.window_selector = window_selector ctx.hyprexpo = hyprexpo - ctx.hyprexpo_dispatch = hyprexpo_dispatch ctx.hyprwinview = hyprwinview ctx.workspacehistory = workspacehistory - ctx.hyprspace = hyprspace ctx.apply_nstack_config = apply_nstack_config ctx.apply_hyprexpo_config = apply_hyprexpo_config ctx.apply_hyprwinview_config = apply_hyprwinview_config diff --git a/dotfiles/config/hypr/hyprland/settings.lua b/dotfiles/config/hypr/hyprland/settings.lua index 3ca602fa..678784c2 100644 --- a/dotfiles/config/hypr/hyprland/settings.lua +++ b/dotfiles/config/hypr/hyprland/settings.lua @@ -4,10 +4,6 @@ function M.setup(ctx) local _ENV = ctx local file_chooser_title_rule = "^(Open File|Open Files|Save File|Save Files|Save As|Select File|Select Files|Choose File|Choose Files|File Upload|Upload File|Upload Files|Select Folder|Choose Folder|Open Folder|Save Folder)$" - local function plugin_path(env_name, default) - return os.getenv(env_name) or default - end - local function lower_string(value) return string.lower(tostring(value or "")) end @@ -79,9 +75,6 @@ function M.setup(ctx) if enable_hyprexpo and not verify_config then hl.plugin.load("/run/current-system/sw/lib/libhyprexpo.so") end - if enable_hyprspace and not verify_config then - hl.plugin.load(plugin_path("HYPRLAND_HYPRSPACE_PLUGIN", "/run/current-system/sw/lib/libHyprspace.so")) - end if enable_hyprwinview and not verify_config then hl.plugin.load("/run/current-system/sw/lib/libhyprwinview.so") end diff --git a/dotfiles/config/hypr/hyprland/state.lua b/dotfiles/config/hypr/hyprland/state.lua index 1d723b07..f6e4213d 100644 --- a/dotfiles/config/hypr/hyprland/state.lua +++ b/dotfiles/config/hypr/hyprland/state.lua @@ -1,20 +1,3 @@ -local function env_bool(name, default) - local value = os.getenv(name) - if value == nil or value == "" then - return default - end - - value = value:lower() - if value == "1" or value == "true" or value == "yes" or value == "on" then - return true - end - if value == "0" or value == "false" or value == "no" or value == "off" then - return false - end - - return default -end - local shell_ui_command = "hypr_shell_ui" local columns_layout = "nStack" local large_main_layout = "master" @@ -63,7 +46,6 @@ return { current_layout = columns_layout, enable_nstack = true, enable_hyprexpo = true, - enable_hyprspace = env_bool("HYPRLAND_ENABLE_HYPRSPACE", true), enable_hyprwinview = true, enable_workspace_history = true, enable_hyprwobbly = true, diff --git a/dotfiles/lib/bin/hypr_plugin_dev_session b/dotfiles/lib/bin/hypr_plugin_dev_session index c64a97e9..8632545e 100755 --- a/dotfiles/lib/bin/hypr_plugin_dev_session +++ b/dotfiles/lib/bin/hypr_plugin_dev_session @@ -20,7 +20,6 @@ Options: --config PATH Run Hyprland with this config instead of a generated minimal config. --user-config Run the normal user Lua config. - --enable-hyprspace Set HYPRLAND_ENABLE_HYPRSPACE=1 for the nested config. --no-load Start the nested compositor but do not load a plugin. --detach Leave the nested compositor running and exit after setup. --keep-tmp Do not delete the generated config/log directory. @@ -33,7 +32,7 @@ Examples: hypr_plugin_dev_session hypr_plugin_dev_session --repo ~/Projects/hyprwobbly --attr .#hyprwobbly hypr_plugin_dev_session --plugin "$PWD/result/lib/libhyprwobbly.so" - hypr_plugin_dev_session --user-config --enable-hyprspace --no-load + hypr_plugin_dev_session --user-config --no-load EOF } @@ -51,7 +50,6 @@ hyprland_bin="" force_system_hyprland=0 load_plugin=1 config_arg="" -enable_hyprspace=0 detach=0 keep_tmp=0 size="1280x720" @@ -94,10 +92,6 @@ while [[ $# -gt 0 ]]; do config_arg="${XDG_CONFIG_HOME:-$HOME/.config}/hypr/hyprland.lua" shift ;; - --enable-hyprspace) - enable_hyprspace=1 - shift - ;; --no-load) load_plugin=0 shift @@ -347,7 +341,6 @@ setsid env \ WAYLAND_DISPLAY="$parent_wayland" \ XDG_SESSION_TYPE=wayland \ IMALISON_HYPRLAND_DEV_SESSION=1 \ - HYPRLAND_ENABLE_HYPRSPACE="$enable_hyprspace" \ bash -c 'trap "" HUP; exec "$1" --config "$2"' hyprland-launch "$hyprland_bin" "$config" >"$stdout_log" 2>&1 & pid=$! diff --git a/nixos/flake.lock b/nixos/flake.lock index faa597d4..4769a778 100644 --- a/nixos/flake.lock +++ b/nixos/flake.lock @@ -1,29 +1,5 @@ { "nodes": { - "Hyprspace": { - "inputs": { - "hyprland": [ - "hyprland" - ], - "systems": [ - "systems" - ] - }, - "locked": { - "lastModified": 1778832075, - "narHash": "sha256-q+5ETwj+oiZBT9j6/huwB8nwV4nbZdZmCrchL2E7tDQ=", - "owner": "colonelpanic8", - "repo": "Hyprspace", - "rev": "bf2ef21007e8963fcb0016ae26b6b21704946f80", - "type": "github" - }, - "original": { - "owner": "colonelpanic8", - "ref": "codex/defer-hyprspace-initial-reload", - "repo": "Hyprspace", - "type": "github" - } - }, "agenix": { "inputs": { "darwin": "darwin", @@ -1661,7 +1637,6 @@ }, "root": { "inputs": { - "Hyprspace": "Hyprspace", "agenix": "agenix", "aquamarine": [ "hyprland", diff --git a/nixos/flake.nix b/nixos/flake.nix index ba30893e..f1f133b8 100644 --- a/nixos/flake.nix +++ b/nixos/flake.nix @@ -125,14 +125,6 @@ inputs.hyprland.follows = "hyprland"; }; - Hyprspace = { - url = "github:colonelpanic8/Hyprspace/codex/defer-hyprspace-initial-reload"; - inputs = { - hyprland.follows = "hyprland"; - systems.follows = "systems"; - }; - }; - hyprwinview = { url = "github:colonelpanic8/hyprwinview"; inputs.hyprland.follows = "hyprland"; diff --git a/nixos/flake/per-system.nix b/nixos/flake/per-system.nix index ff00ef39..9639397b 100644 --- a/nixos/flake/per-system.nix +++ b/nixos/flake/per-system.nix @@ -26,7 +26,13 @@ hyprlang = inputs.hyprlang.packages.${system}.hyprlang; hyprutils = inputs.hyprutils.packages.${system}.hyprutils; }; - hyprexpo = inputs.hyprexpo.packages.${system}.hyprexpo; + hyprexpo = inputs.hyprexpo.packages.${system}.hyprexpo.overrideAttrs (old: { + patches = + (old.patches or []) + ++ [ + ../packages/hyprexpo-drag-windows.patch + ]; + }); tangledConfig = dotfilesOrgApi.org-agenda-custom-config; # Import container build logic diff --git a/nixos/hyprland.nix b/nixos/hyprland.nix index 362ba93a..9e263685 100644 --- a/nixos/hyprland.nix +++ b/nixos/hyprland.nix @@ -89,15 +89,6 @@ overrideAttrs = f: makeHyprlandLuaPackage (package.overrideAttrs f); }; hyprlandPackage = makeHyprlandLuaPackage baseHyprlandPackage; - hyprspace = inputs.Hyprspace.packages.${system}.Hyprspace.overrideAttrs (old: { - version = "${old.version}-pr231"; - __intentionallyOverridingVersion = true; - patches = - (old.patches or []) - ++ [ - ./packages/hyprspace-lua-api.patch - ]; - }); enableHyprglass = false; hyprglass = pkgs.callPackage ./packages/hyprglass { src = inputs.hyprglass; @@ -115,12 +106,17 @@ ./packages/hyprwobbly-safe-geometry-and-idle-timer.patch ]; }); - hyprexpo = inputs.hyprexpo.packages.${system}.hyprexpo; + hyprexpo = inputs.hyprexpo.packages.${system}.hyprexpo.overrideAttrs (old: { + patches = + (old.patches or []) + ++ [ + ./packages/hyprexpo-drag-windows.patch + ]; + }); hyprlandPluginPackages = [ inputs.hyprNStack.packages.${system}.hyprNStack hyprexpo - hyprspace inputs.hyprwinview.packages.${system}.hyprwinview inputs.hypr-workspace-history.packages.${system}.hypr-workspace-history hyprwobbly diff --git a/nixos/packages/hyprexpo-drag-windows.patch b/nixos/packages/hyprexpo-drag-windows.patch new file mode 100644 index 00000000..aa461192 --- /dev/null +++ b/nixos/packages/hyprexpo-drag-windows.patch @@ -0,0 +1,198 @@ +--- a/Overview.hpp ++++ b/Overview.hpp +@@ -80,6 +80,12 @@ + void updateHoveredFromMouse(); + bool isTileValid(int id) const; + void ensureKeyboardFocus(); ++ void beginWindowDrag(); ++ bool finishWindowDrag(); ++ void updateWindowDrag(); ++ PHLWINDOW windowAtTilePoint(int id, const Vector2D& localPoint) const; ++ Vector2D tilePointToWorkspacePoint(int id, const Vector2D& localPoint) const; ++ PHLWORKSPACE ensureWorkspaceForTile(int id); + + int SIDE_LENGTH = 3; + int GAP_WIDTH = 5; +@@ -94,6 +100,11 @@ + int hoveredID = -1; + int kbFocusID = -1; + ++ Vector2D dragStartLocal = Vector2D{}; ++ int dragSourceID = -1; ++ bool dragMoved = false; ++ PHLWINDOW dragWindow; ++ + std::vector images; + + PHLWORKSPACE startedOn; +--- a/Overview.cpp ++++ b/Overview.cpp +@@ -5,6 +5,7 @@ + #include + #include + #include ++#include + #define private public + #define protected public + #include +@@ -79,6 +80,10 @@ + return grad; + } + ++static bool windowVisibleOnWorkspace(const PHLWINDOW& window, const PHLWORKSPACE& workspace) { ++ return window && workspace && window->m_workspace == workspace && window->m_isMapped && !window->isHidden() && !window->m_pinned; ++} ++ + static void ensureFramebuffer(COverview::SWorkspaceImage& image, const CBox& monbox, uint32_t drmFormat) { + if (!image.fb) + image.fb = g_pHyprRenderer->createFB("hyprexpo"); +@@ -337,9 +342,29 @@ + info.cancelled = true; + lastMousePosLocal = g_pInputManager->getMouseCoordsInternal() - pMonitor->m_position; + updateHoveredFromMouse(); ++ updateWindowDrag(); ++ }; ++ ++ auto onCursorSelect = [this](IPointer::SButtonEvent event, Event::SCallbackInfo& info) { ++ if (closing) ++ return; ++ ++ info.cancelled = true; ++ ++ if (event.state == WL_POINTER_BUTTON_STATE_PRESSED) { ++ beginWindowDrag(); ++ return; ++ } ++ ++ if (finishWindowDrag()) ++ return; ++ ++ selectHoveredWorkspace(); ++ ++ close(); + }; + +- auto onCursorSelect = [this](Event::SCallbackInfo& info) { ++ auto onTouchSelect = [this](Event::SCallbackInfo& info) { + if (closing) + return; + +@@ -353,8 +378,107 @@ + mouseMoveHook = Event::bus()->m_events.input.mouse.move.listen([onCursorMove](Vector2D, Event::SCallbackInfo& info) { onCursorMove(info); }); + touchMoveHook = Event::bus()->m_events.input.touch.motion.listen([onCursorMove](ITouch::SMotionEvent, Event::SCallbackInfo& info) { onCursorMove(info); }); + +- mouseButtonHook = Event::bus()->m_events.input.mouse.button.listen([onCursorSelect](IPointer::SButtonEvent, Event::SCallbackInfo& info) { onCursorSelect(info); }); +- touchDownHook = Event::bus()->m_events.input.touch.down.listen([onCursorSelect](ITouch::SDownEvent, Event::SCallbackInfo& info) { onCursorSelect(info); }); ++ mouseButtonHook = Event::bus()->m_events.input.mouse.button.listen([onCursorSelect](IPointer::SButtonEvent event, Event::SCallbackInfo& info) { onCursorSelect(event, info); }); ++ touchDownHook = Event::bus()->m_events.input.touch.down.listen([onTouchSelect](ITouch::SDownEvent, Event::SCallbackInfo& info) { onTouchSelect(info); }); ++} ++ ++Vector2D COverview::tilePointToWorkspacePoint(int id, const Vector2D& localPoint) const { ++ const Vector2D tileSize = pMonitor->m_size / SIDE_LENGTH; ++ const Vector2D tilePos = tileSize * Vector2D{id % SIDE_LENGTH, id / SIDE_LENGTH}; ++ const Vector2D inTile = localPoint - tilePos; ++ ++ return pMonitor->m_position + Vector2D{std::clamp(inTile.x / tileSize.x, 0.0, 1.0) * pMonitor->m_size.x, std::clamp(inTile.y / tileSize.y, 0.0, 1.0) * pMonitor->m_size.y}; ++} ++ ++PHLWINDOW COverview::windowAtTilePoint(int id, const Vector2D& localPoint) const { ++ if (!isTileValid(id)) ++ return nullptr; ++ ++ const auto WORKSPACE = images[id].pWorkspace ? images[id].pWorkspace : g_pCompositor->getWorkspaceByID(images[id].workspaceID); ++ if (!WORKSPACE) ++ return nullptr; ++ ++ const auto POINT = tilePointToWorkspacePoint(id, localPoint); ++ for (auto it = g_pCompositor->m_windows.rbegin(); it != g_pCompositor->m_windows.rend(); ++it) { ++ const auto& window = *it; ++ if (!windowVisibleOnWorkspace(window, WORKSPACE)) ++ continue; ++ ++ if (window->getWindowMainSurfaceBox().containsPoint(POINT)) ++ return window; ++ } ++ ++ return nullptr; ++} ++ ++void COverview::beginWindowDrag() { ++ updateHoveredFromMouse(); ++ dragStartLocal = lastMousePosLocal; ++ dragSourceID = hoveredID; ++ dragMoved = false; ++ dragWindow = windowAtTilePoint(dragSourceID, dragStartLocal); ++} ++ ++void COverview::updateWindowDrag() { ++ if (!dragWindow || dragMoved) ++ return; ++ ++ const auto DX = lastMousePosLocal.x - dragStartLocal.x; ++ const auto DY = lastMousePosLocal.y - dragStartLocal.y; ++ if (std::hypot(DX, DY) < 12.0) ++ return; ++ ++ dragMoved = true; ++ damage(); ++} ++ ++PHLWORKSPACE COverview::ensureWorkspaceForTile(int id) { ++ if (!isTileValid(id)) ++ return nullptr; ++ ++ auto& image = images[id]; ++ if (image.pWorkspace) ++ return image.pWorkspace; ++ ++ auto workspace = g_pCompositor->getWorkspaceByID(image.workspaceID); ++ if (!workspace) ++ workspace = g_pCompositor->createNewWorkspace(image.workspaceID, pMonitor->m_id, std::to_string(image.workspaceID), false); ++ ++ image.pWorkspace = workspace; ++ return workspace; ++} ++ ++bool COverview::finishWindowDrag() { ++ const auto WINDOW = dragWindow; ++ const int SOURCE = dragSourceID; ++ const bool MOVED = dragMoved; ++ ++ dragWindow = nullptr; ++ dragSourceID = -1; ++ dragMoved = false; ++ ++ if (!WINDOW) ++ return false; ++ ++ if (!MOVED) ++ return false; ++ ++ updateHoveredFromMouse(); ++ ++ const int TARGET = hoveredID; ++ if (!isTileValid(SOURCE) || !isTileValid(TARGET) || SOURCE == TARGET) ++ return true; ++ ++ const auto SOURCEWS = images[SOURCE].pWorkspace; ++ const auto TARGETWS = ensureWorkspaceForTile(TARGET); ++ if (!windowVisibleOnWorkspace(WINDOW, SOURCEWS) || !TARGETWS || TARGETWS == SOURCEWS) ++ return true; ++ ++ g_pCompositor->moveWindowToWorkspaceSafe(WINDOW, TARGETWS); ++ redrawID(SOURCE); ++ redrawID(TARGET); ++ damage(); ++ return true; + } + + void COverview::selectHoveredWorkspace() { +@@ -954,6 +1078,8 @@ + drawBorder(openedID, *PBORDERCURRENT); + if (kbFocusID != -1) + drawBorder(kbFocusID, *PBORDERFOCUS); ++ if (dragMoved && dragSourceID != -1) ++ drawBorder(dragSourceID, *PBORDERFOCUS); + } + + static float lerp(const float& from, const float& to, const float perc) { diff --git a/nixos/packages/hyprspace-lua-api.patch b/nixos/packages/hyprspace-lua-api.patch deleted file mode 100644 index e1264e01..00000000 --- a/nixos/packages/hyprspace-lua-api.patch +++ /dev/null @@ -1,87 +0,0 @@ -diff --git a/src/main.cpp b/src/main.cpp -index 9dd0286..51fd8d7 100644 ---- a/src/main.cpp -+++ b/src/main.cpp -@@ -6,6 +6,7 @@ - #include - #include - #include -+#include - #include - #include - #include "Overview.hpp" -@@ -380,6 +381,65 @@ static SDispatchResult dispatchCloseOverview(std::string arg) { - return SDispatchResult{}; - } - -+static int luaOverview(lua_State* L) { -+ std::string action = "toggle"; -+ std::string arg; -+ -+ if (lua_gettop(L) >= 1 && !lua_isnil(L, 1)) { -+ if (lua_istable(L, 1)) { -+ lua_getfield(L, 1, "action"); -+ if (lua_isstring(L, -1)) -+ action = lua_tostring(L, -1); -+ else if (!lua_isnil(L, -1)) -+ return luaL_error(L, "hyprspace.overview: field \"action\" must be a string"); -+ lua_pop(L, 1); -+ -+ lua_getfield(L, 1, "all"); -+ if (lua_isboolean(L, -1) && lua_toboolean(L, -1)) -+ arg = "all"; -+ else if (!lua_isnil(L, -1) && !lua_isboolean(L, -1)) -+ return luaL_error(L, "hyprspace.overview: field \"all\" must be a boolean"); -+ lua_pop(L, 1); -+ } else if (lua_isstring(L, 1)) { -+ action = lua_tostring(L, 1); -+ } else { -+ return luaL_error(L, "hyprspace.overview: argument must be a string or table"); -+ } -+ } -+ -+ if (action == "toggle") { -+ dispatchToggleOverview(arg); -+ return 0; -+ } -+ -+ if (action == "open") { -+ dispatchOpenOverview(arg); -+ return 0; -+ } -+ -+ if (action == "close") { -+ dispatchCloseOverview(arg); -+ return 0; -+ } -+ -+ if (action == "toggle all") { -+ dispatchToggleOverview("all"); -+ return 0; -+ } -+ -+ if (action == "open all") { -+ dispatchOpenOverview("all"); -+ return 0; -+ } -+ -+ if (action == "close all") { -+ dispatchCloseOverview("all"); -+ return 0; -+ } -+ -+ return luaL_error(L, "hyprspace.overview: unknown action \"%s\"", action.c_str()); -+} -+ - void* findFunctionBySymbol(HANDLE inHandle, const std::string func, const std::string sym) { - // should return all functions - auto funcSearch = HyprlandAPI::findFunctionsByName(inHandle, func); -@@ -545,6 +605,8 @@ APICALL EXPORT PLUGIN_DESCRIPTION_INFO PLUGIN_INIT(HANDLE inHandle) { - HyprlandAPI::addDispatcherV2(pHandle, "overview:open", ::dispatchOpenOverview); - HyprlandAPI::addDispatcherV2(pHandle, "overview:close", ::dispatchCloseOverview); - -+ HyprlandAPI::addLuaFunction(pHandle, "hyprspace", "overview", ::luaOverview); -+ - g_pRenderHook = Event::bus()->m_events.render.stage.listen([](eRenderStage stage) { onRender(stage); }); - - // refresh on layer change