I Might Check Out Scroll Instead

So, update: I will probably end up checking out Scroll instead of Niri. Scroll is a fork of Sway, with a scrolling layout and a Lua API. I was originally only interested because of the former, but over my little bit of investigation the latter has been extremely helpful.

For example: I wanted scratchpads to work the way I’m used to. In Sway (and i3, and Scroll) there is a single scratchpad, that windows can be sent to and pulled out of. What I’m used to is the dwm scratchpads patch, where you can have basically however many you want, with one window per scratchpad.

I thought I was going to be out of luck with getting my usual scratchpad workflow here (as I have 12 of them), but because of the Lua API I was able to make it work by having all of those windows be opened in the scratchpad, but whenever I open the binding it only pulls out the one I want, so it all just works from the user perspective. (If you are interested, I have the script below).

I currently intend to keep messing with it on one of my computers. The current plan is my desktop, but as that is where I play games, and KSP doesn’t react super well to it, that may change.

local args, _ = ...
local id = ""
local terminal = false
local command = nil

for i, arg in ipairs(args) do
  if i <= 1 then
    id = arg
    if #args == 1 then
      command = arg
    end
  elseif i == 2 then
    if (arg == "kitty") then
      terminal = true
    else
      command = arg
    end
  elseif i == 3 and (terminal == true) then
    command = arg
    break
  else
    command = command .. ' ' .. arg
  end
end

local function exists(id)
  local is_in_array = false
  local cons = scroll.scratchpad_get_containers()
  for _, con in ipairs(cons) do
    local views = scroll.container_get_views(con)
    for _, view in ipairs(views) do
      local app_id = scroll.view_get_app_id(view)
      if (app_id == id) then
        is_in_array = true
      end
    end
  end
  return is_in_array
end

local function is_focused(id)
  local view = scroll.focused_view()
  local app_id = scroll.view_get_app_id(view)
  return app_id == id
end

local function spawn(term, comm)
  if (term) then
    if (comm) then
      scroll.command(nil, "exec kitty --class " .. id .. " -e " .. comm)
    else
      scroll.command(nil, "exec kitty --class " .. id)
    end
  else
    scroll.command(nil, "exec " .. comm)
  end
end

if (not exists(id)) then
  spawn(terminal, command)
end
if (is_focused(id)) then
  scroll.command(nil, "scratchpad show")
else
  scroll.command(nil, "[app_id=\"" .. id .. "\"] scratchpad show")
end

2025-07-28