hammerspoon icon indicating copy to clipboard operation
hammerspoon copied to clipboard

hs.alert: Add atWindowEdge=0/1/2 to place hs.alert on currently focused window

Open kiryph opened this issue 3 years ago • 0 comments

diff --git a/Users/kiryph/.hammerspoon/hs/alert-orig.lua b/Users/kiryph/.hammerspoon/hs/alert.lua
index 7de26d4..208285a 100644
--- a/Users/kiryph/.hammerspoon/hs/alert-orig.lua
+++ b/Users/kiryph/.hammerspoon/hs/alert.lua
@@ -5,6 +5,7 @@ local module = {}
 --- Simple on-screen alerts

 local drawing = require("hs.drawing")
+local window  = require("hs.window")
 local timer   = require("hs.timer")
 local screen  = require("hs.screen")
 local uuid    = require"hs.host".uuid
@@ -32,6 +33,7 @@ module._visibleAlerts = {}
 ---    * textStyle   - an optional table, defaults to `nil`, specifying that a string message should be converted to an `hs.styledtext` object using the style elements specified in this table.  This table should conform to the key-value pairs as described in the documentation for the `hs.styledtext` module.  If this table does not contain a `font` key-value pair, one will be constructed from the `textFont` and `textSize` keys (or their defaults); likewise, if this table does not contain a `color` key-value pair, one will be constructed from the `textColor` key (or its default).
 ---    * padding     - the number of pixels to reserve around each side of the text and/or image, defaults to textSize/2
 ---    * atScreenEdge   - 0: screen center (default); 1: top edge; 2: bottom edge . Note when atScreenEdge>0, the latest alert will overlay above the previous ones if multiple alerts visible on same edge; and when atScreenEdge=0, latest alert will show below previous visible ones without overlap.
+---    * atWindowEdge   - if -1 use atScreenEdge, otherwise 0: window center; 1: top edge; 2: bottom edge . Note when atScreenEdge>0, the latest alert will overlay above the previous ones if multiple alerts visible on same edge; and when atScreenEdge=0, latest alert will show below previous visible ones without overlap.
 ---    * fadeInDuration  - a number in seconds specifying the fade in duration of the alert, defaults to 0.15
 ---    * fadeOutDuration - a number in seconds specifying the fade out duration of the alert, defaults to 0.15
 ---
@@ -45,6 +47,7 @@ module.defaultStyle = {
     textSize  = 27,
     radius = 27,
     atScreenEdge = 0,
+    atWindowEdge = -1,
     fadeInDuration = 0.15,
     fadeOutDuration = 0.15,
     padding = nil,
@@ -105,6 +108,12 @@ local showAlert = function(message, image, style, screenObj, duration)
     local absoluteTop = screenFrame.y + (screenFrame.h * (1 - 1 / 1.55) + 55) -- mimic module behavior for inverted rect
     if thisAlertStyle.atScreenEdge > 0 then
         absoluteTop = screenFrame.y -- this is for atScreenEdge = 1, and atScreenEdge = 2 case will be handled later
+    elseif thisAlertStyle.atWindowEdge == 0 then -- window center
+        win = window.focusedWindow()
+        absoluteTop = win:frame().y + (win:frame().h * (1 - 1 / 1.55) + 55)
+    elseif thisAlertStyle.atWindowEdge > 0 then -- window top or bottom
+        win = window.focusedWindow()
+        absoluteTop = win:frame().y -- this is for atScreenEdge = 1, and atScreenEdge = 2 case will be handled later
     else
         if #module._visibleAlerts > 0 then
             -- we're looking for the latest on the same screen
@@ -158,9 +167,16 @@ local showAlert = function(message, image, style, screenObj, duration)

     -- Use the size to set the position
     drawingFrame.x = screenFrame.x + (screenFrame.w - drawingFrame.w) / 2
+    if thisAlertStyle.atWindowEdge ~= -1 then
+        win = window.focusedWindow()
+        drawingFrame.x = win:frame().x + (win:frame().w - drawingFrame.w) / 2
+    end

     if thisAlertStyle.atScreenEdge == 2 then
         drawingFrame.y = screenFrame.y + screenFrame.h - drawingFrame.h
+    elseif thisAlertStyle.atWindowEdge == 2 then -- bottom edge
+        win = window.focusedWindow()
+        drawingFrame.y = win:frame().y + win:frame().h - drawingFrame.h
     else
         drawingFrame.y = absoluteTop
     end

kiryph avatar Jul 22 '22 15:07 kiryph