Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Changelog

## Unreleased

### Fixed
- A window dragged to another monitor now moves to that monitor's workspace. Before, Hyprland still filed it under the old monitor, so the controls were drawn off-screen and disappeared.

## 0.2.0

A rewrite of the plugin's internals. Every v0.1 feature is still there, and your existing `~/.config/omarchy/mouse-first.json` keeps working.
Expand Down
2 changes: 2 additions & 0 deletions src/DragController.qml
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,8 @@ Item {
} else if (root.rect) {
root.tracker.dispatch(Hypr.move(root.address, root.rect.x, root.rect.y))
}
// A window dropped on another monitor still belongs to the old one.
if (root.rect) root.tracker.evalLua(Hypr.evalAdopt(root.address, root.rect))
restoreAnimTimer.pendingAddress = root.address
restoreAnimTimer.restart()
}
Expand Down
5 changes: 5 additions & 0 deletions src/js/hypr.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,11 @@ function evalRestore(address, workspace) {
return a ? "MOUSE_FIRST.restore(" + luaString(a) + ", " + luaString(workspace || "") + ")" : ""
}

function evalAdopt(address, r) {
var a = normalizeAddress(address)
return a && r ? "MOUSE_FIRST.adopt(" + luaString(a) + ", " + int(r.x) + ", " + int(r.y) + ", " + int(r.w) + ", " + int(r.h) + ")" : ""
}

function evalFloatRule(enabled, center) {
return "MOUSE_FIRST.set_float_rule(" + (enabled ? "true" : "false") + ", " + (center ? "true" : "false") + ")"
}
Expand Down
26 changes: 26 additions & 0 deletions src/lua/mousefirst.lua
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,32 @@ function M.restore(address, workspace)
hl.dispatch(hl.dsp.focus({ window = "address:" .. address }))
end

-- The shell moves windows with absolute coordinates, which never changes the
-- monitor or workspace Hyprland files them under. After a drag drops a window
-- on another monitor, move it to that monitor's active workspace and put the
-- geometry back (the workspace move shifts floating windows on its own).
function M.adopt(address, x, y, w, h)
local win = hl.get_window("address:" .. address)
if not win then return end
local cx, cy = x + w / 2, y + math.min(h / 2, 8)
for _, m in ipairs(hl.get_monitors()) do
local scale = (m.scale and m.scale > 0) and m.scale or 1
local mw, mh = m.width / scale, m.height / scale
if (tonumber(m.transform) or 0) % 2 == 1 then mw, mh = mh, mw end
if cx >= m.x and cx < m.x + mw and cy >= m.y and cy < m.y + mh then
if win.monitor and win.monitor.name == m.name then return end
local ws = m.active_workspace
if not ws then return end
local target = "address:" .. address
hl.dispatch(hl.dsp.window.move({ workspace = tostring(ws.id), window = target, follow = true }))
hl.dispatch(hl.dsp.window.resize({ x = w, y = h, window = target }))
hl.dispatch(hl.dsp.window.move({ x = x, y = y, relative = false, window = target }))
hl.dispatch(hl.dsp.focus({ window = target }))
return
end
end
end

-- v0.1 parked windows on special:mf-minimized; move them to the shared one.
function M.migrate_legacy_minimized()
for _, w in ipairs(hl.get_windows() or {}) do
Expand Down