Analysis
For me your script kinda works in tmux in konsole (I just needed to remove the last echo from the function to make the whole box stay visible). The script does not work in the way (I think) you think it works though.
Contrary to what one of the comments states, trap SCREEN SIGWINCH is a good command. Portably it should be trap SCREEN WINCH, but for trapin BashSIGWINCH is as good as WINCH.
[[ SIGWINCH == "true" ]] returns exit status 1 (failure) because the string SIGWINCH is not equal to the string true. In effect sleep 1 and SCREEN (that appear after then) never run. Your while loop only invokes true and compares two different fixed strings again and again.
When SIGWINCH comes, the trap works and SCREEN gets executed. In my tests the script reacts to changes of the size of its "window" (a tmux pane in my case).
Your while loop does nothing by itself, but if not the loop, the script would exit after setting up the trap in vain.
Improvements
This is a modified script that implements the logic I think you wanted:
#!/bin/bashSCREEN () { clear for (( i = 1; i <= "$LINES"; i++ )); do for (( j = 1; j <= "$COLUMNS"; j++ )); do if (( 1 == i || "$LINES" == i || 1 == j || "$COLUMNS" == j )); then echo -n "*" else echo -n " " fi done done}trap SCREEN WINCHSCREEN # to draw the first boxwhile true; do sleep 1doneNote I removed your calls to tput. By default bash sets LINES and COLUMNS after each external (non-builtin) command. In our case clear is the external command that makes the shell update the variables and there is no need to query tput.
If you want your script to do something outside of the trap, put it before (or instead of) the while loop. Keep in mind the trap (in general: a trap) cannot run when the shell awaits exit of a synchronous command. In our case the trap can run after true or after sleep 1, but not during; this is why the script does not always immediately redraws the box, there is usually a delay because the shell waits for sleep 1 to finish. If you introduce a long-running synchronous command then it will similarly make the script stop updating the box until the command finishes. A solution is to run the command asynchronously and wait for it. The point is a signal can interrupt wait.
The following example script will react to changes of the size of its window virtually immediately:
#!/bin/bashSCREEN () { clear for (( i = 1; i <= "$LINES"; i++ )); do for (( j = 1; j <= "$COLUMNS"; j++ )); do if (( 1 == i || "$LINES" == i || 1 == j || "$COLUMNS" == j )); then echo -n "*" else echo -n " " fi done done}trap SCREEN WINCHSCREEN # to draw the first boxwhile true; do sleep 10 & waitdoneI could use tail -f /dev/null & before the loop (this command shall never end by itself) and wait inside the loop, but in some circumstances tail could survive termination of the script and we don't want to let this happen. sleep 10 has to keep being renewed in the loop, but each instance will exit eventually no matter what. On the other hand a SIGWINCH that interrupts wait won't kill any background sleep, so if the signals come frequently then the number of background sleep processes will increase up to the value of about "number of signals per 10 seconds". In practice SIGWINCH happens occasionally, not all the time, so the problem is negligible.