half-baked re-implementation of the major parts of sdorfehs in Hammerspoon
at main 145 lines 3.6 kB view raw
1-- find a window table object from an hs.window object 2spoonfish.window_find_by_hswindow = function(win) 3 for _, w in pairs(spoonfish.windows) do 4 if w["win"] == win then 5 return w 6 end 7 end 8 9 return nil 10end 11 12-- find a window table object from its hs.window id 13spoonfish.window_find_by_id = function(id) 14 for _, w in pairs(spoonfish.windows) do 15 if w["win"]:id() == id then 16 return w 17 end 18 end 19 20 return nil 21end 22 23-- move a window to fit its frame, or hide it if in frame 0 24spoonfish.window_reframe = function(win) 25 if win == nil or win == {} then 26 error("bogus window passed") 27 return 28 end 29 30 if win["frame"] == 0 then 31 error("bogus frame for win " .. win["title"]) 32 return 33 end 34 35 local iframe = spoonfish.frame_rect_with_gap(win["space"], win["frame"]) 36 win["win"]:move(iframe, nil, true, 0) 37 38 if win["space"] == hs.spaces.activeSpaceOnScreen() then 39 spoonfish.window_reborder(win) 40 end 41end 42 43-- redraw a border and shadow on a window 44spoonfish.window_reborder = function(win) 45 if win == nil or win == {} then 46 error("bogus window passed") 47 return 48 end 49 50 if spoonfish.border_size == 0 then 51 return 52 end 53 54 for _, w in pairs({ "shadow", "border" }) do 55 local irect = spoonfish.frame_rect_with_gap(win["space"], win["frame"]) 56 irect = spoonfish.inset(irect, -(spoonfish.border_size)) 57 58 if w == "shadow" then 59 irect.x = irect.x + spoonfish.shadow_size 60 irect.y = irect.y + spoonfish.shadow_size 61 end 62 63 if win[w] == nil then 64 win[w] = hs.drawing.rectangle(irect) 65 else 66 win[w]:setFrame(irect) 67 end 68 win[w]:setLevel(hs.drawing.windowLevels.desktopIcon) 69 70 local color 71 if w == "border" then 72 color = spoonfish.border_color 73 elseif w == "shadow" then 74 color = spoonfish.shadow_color 75 end 76 win[w]:setStrokeColor({ ["hex"] = color }) 77 win[w]:setFill(true) 78 win[w]:setFillColor({ ["hex"] = color }) 79 win[w]:setRoundedRectRadii(14, 14) 80 win[w]:show() 81 end 82end 83 84-- remove a window from the stack and bring up a new window in the frame 85spoonfish.window_remove = function(win) 86 local frame_id = win["frame"] 87 if win["border"] ~= nil then 88 win["border"]:delete() 89 win["border"] = nil 90 end 91 if win["shadow"] ~= nil then 92 win["shadow"]:delete() 93 win["shadow"] = nil 94 end 95 spoonfish.window_restack(win, spoonfish.position.REMOVE) 96 if frame_id ~= 0 then 97 spoonfish.frame_cycle(win["space"], frame_id, false) 98 end 99end 100 101-- move a window to the front or back of the window stack (or remove it) 102spoonfish.window_restack = function(win, pos) 103 if pos == nil then 104 error("invalid position argument") 105 return 106 end 107 108 local new_stack = {} 109 for _, w in ipairs(spoonfish.windows) do 110 if w == win then 111 if pos == spoonfish.position.FRONT then 112 table.insert(new_stack, 1, w) 113 end 114 else 115 table.insert(new_stack, w) 116 end 117 end 118 if pos == spoonfish.position.BACK then 119 table.insert(new_stack, win) 120 end 121 spoonfish.windows = new_stack 122end 123 124-- restore a window but don't bother moving to its frame, window_reframe will 125spoonfish.window_show = function(win) 126 if win["win"]:isMinimized() then 127 win["win"]:unminimize() 128 end 129end 130 131-- return a table of windows not first in any frame 132spoonfish.windows_not_visible = function(space_id) 133 local wins = {} 134 local topwins = {} 135 for _, w in ipairs(spoonfish.windows) do 136 if w["space"] == space_id then 137 if topwins[w["frame"]] == nil then 138 topwins[w["frame"]] = w 139 else 140 table.insert(wins, w) 141 end 142 end 143 end 144 return wins 145end