@kecan0406/ttheme 1.2.4 → 1.2.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.2.4",
2
+ "version": "1.2.5",
3
3
  "gate": [
4
4
  {
5
5
  "rule": "foreground",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kecan0406/ttheme",
3
- "version": "1.2.4",
3
+ "version": "1.2.5",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "ttheme": "bin/ttheme.js"
@@ -45,8 +45,19 @@ __tt_repaint() {
45
45
 
46
46
  __tt_apply() { __tt_osc_apply "$@" }
47
47
 
48
+ __tt_wear() {
49
+ local REPLY=$2 name
50
+ [[ -n $REPLY ]] || __tt_name_of "$1"
51
+ name=$REPLY
52
+ TTHEME_SPEC=$1
53
+ __tt_apply "$1"
54
+ [[ -n ${TTHEME_PALETTE[$name]} ]] && __tt_shown "$name" $3 && __tt_reload
55
+ }
56
+
48
57
  __tt_pv_paint() { __tt_apply "$1" && painted=$1 }
49
58
 
59
+ __tt_pv_claim() { : }
60
+
50
61
  __tt_shown() { return 1 }
51
62
 
52
63
  __tt_unshown() { : }
@@ -1,4 +1,5 @@
1
1
  typeset -g TTHEME_GHOSTTY_PID=""
2
+ typeset -gi TTHEME_GHOSTTY_SENT=0
2
3
 
3
4
  __tt_reload() {
4
5
  local wired
@@ -39,8 +40,8 @@ __tt_reload_ghostty() {
39
40
  __tt_ghostty_owner $PPID
40
41
  owner=$REPLY TTHEME_GHOSTTY_PID=$REPLY
41
42
  fi
42
- (( owner )) && kill -USR2 $owner 2>/dev/null && return
43
- pkill -USR2 -x ghostty 2>/dev/null
43
+ (( owner )) && kill -USR2 $owner 2>/dev/null && { TTHEME_GHOSTTY_SENT=1; return 0 }
44
+ pkill -USR2 -x ghostty 2>/dev/null && TTHEME_GHOSTTY_SENT=1
44
45
  }
45
46
 
46
47
  __tt_ghostty_shown() {
@@ -1,10 +1,11 @@
1
1
  source $TTHEME_HOME/adapters/_bg.zsh
2
2
 
3
- typeset -g TTHEME_GHOSTTY_TABS=$TTHEME_STATE_DIR/ghostty TTHEME_GHOSTTY_FRONT="" TTHEME_GHOSTTY_BLUR=""
4
- typeset -gF TTHEME_GHOSTTY_ASKED=0 TTHEME_GHOSTTY_WANT=0 TTHEME_GHOSTTY_HUSH=0
5
- typeset -gi TTHEME_GHOSTTY_IDLE=1 TTHEME_GHOSTTY_TICK=0 TTHEME_GHOSTTY_NONE=0 TTHEME_GHOSTTY_FOLLOWS=-1
3
+ typeset -g TTHEME_GHOSTTY_TABS=$TTHEME_STATE_DIR/ghostty TTHEME_GHOSTTY_FRONT="" TTHEME_GHOSTTY_BLUR="" TTHEME_GHOSTTY_HEARD="" TTHEME_GHOSTTY_CODE=""
4
+ typeset -gF TTHEME_GHOSTTY_ASKED=0 TTHEME_GHOSTTY_WANT=0 TTHEME_GHOSTTY_HUSH=0 TTHEME_GHOSTTY_TOLD=0 TTHEME_GHOSTTY_NONE_AT=0
5
+ typeset -gi TTHEME_GHOSTTY_IDLE=1 TTHEME_GHOSTTY_TICK=0 TTHEME_GHOSTTY_NONE=0 TTHEME_GHOSTTY_FOLLOWS=-1 TTHEME_GHOSTTY_WFD=0 TTHEME_GHOSTTY_WATCHER=0
6
6
  typeset -gA TTHEME_GHOSTTY_SEEN=() TTHEME_GHOSTTY_RUN=()
7
- typeset -g TTHEME_GHOSTTY_JS='ObjC.import("AppKit");function run(v){var p=+v[0],E=$.NSAppleEventDescriptor,G="com.mitchellh.ghostty",f=function(s){return(s.charCodeAt(0)<<24)|(s.charCodeAt(1)<<16)|(s.charCodeAt(2)<<8)|s.charCodeAt(3)},a=p?$.NSRunningApplication.runningApplicationWithProcessIdentifier(p):$.NSRunningApplication.runningApplicationsWithBundleIdentifier(G).firstObject;if(!a||a.isNil())return"none";var s=$.NSString.stringWithContentsOfFileEncodingError(a.bundleURL.path.js+"/Contents/Resources/Ghostty.sdef",4,null);if(s.isNil()||s.js.indexOf("code=\"Gtty\"")<0)return"blind";var t=E.descriptorWithProcessIdentifier(a.processIdentifier);function q(c,o){var d=E.recordDescriptor;d.setDescriptorForKeyword(E.descriptorWithTypeCode(f("prop")),f("want"));d.setDescriptorForKeyword(o,f("from"));d.setDescriptorForKeyword(E.descriptorWithEnumCode(f("prop")),f("form"));d.setDescriptorForKeyword(E.descriptorWithTypeCode(f(c)),f("seld"));return d.coerceToDescriptorType(f("obj "))}function g(o){var e=E.appleEventWithEventClassEventIDTargetDescriptorReturnIDTransactionID(f("core"),f("getd"),t,-1,0);e.setParamDescriptorForKeyword(o,f("----"));var r=e.sendEventWithOptionsTimeoutError(3,5,null);return!r||r.isNil()||!r.paramDescriptorForKeyword(f("errn")).isNil()?null:r.paramDescriptorForKeyword(f("----"))}var n=E.nullDescriptor,m=q("GTfT",q("GWsT",q("GFWn",n))),w=g(q("pisf",n)),y=g(q("Gtty",m)),i=g(q("Gpid",m));if(!w||!y||!i||w.isNil()||y.isNil()||i.isNil())return"none";return(w.booleanValue?1:0)+" "+y.stringValue.js+" "+i.int32Value}'
7
+ typeset -g TTHEME_GHOSTTY_JS='ObjC.import("AppKit");function run(v){var p=+v[0],E=$.NSAppleEventDescriptor,G="com.mitchellh.ghostty",f=function(s){return(s.charCodeAt(0)<<24)|(s.charCodeAt(1)<<16)|(s.charCodeAt(2)<<8)|s.charCodeAt(3)},a=p?$.NSRunningApplication.runningApplicationWithProcessIdentifier(p):$.NSRunningApplication.runningApplicationsWithBundleIdentifier(G).firstObject;if(!a||a.isNil())return p?"gone":"none";var s=$.NSString.stringWithContentsOfFileEncodingError(a.bundleURL.path.js+"/Contents/Resources/Ghostty.sdef",4,null);if(s.isNil()||s.js.indexOf("code=\"Gtty\"")<0)return"blind";var t=E.descriptorWithProcessIdentifier(a.processIdentifier);function q(c,o){var d=E.recordDescriptor;d.setDescriptorForKeyword(E.descriptorWithTypeCode(f("prop")),f("want"));d.setDescriptorForKeyword(o,f("from"));d.setDescriptorForKeyword(E.descriptorWithEnumCode(f("prop")),f("form"));d.setDescriptorForKeyword(E.descriptorWithTypeCode(f(c)),f("seld"));return d.coerceToDescriptorType(f("obj "))}function g(o){var e=E.appleEventWithEventClassEventIDTargetDescriptorReturnIDTransactionID(f("core"),f("getd"),t,-1,0);e.setParamDescriptorForKeyword(o,f("----"));var r=e.sendEventWithOptionsTimeoutError(3,5,null);return!r||r.isNil()||!r.paramDescriptorForKeyword(f("errn")).isNil()?null:r.paramDescriptorForKeyword(f("----"))}var n=E.nullDescriptor,m=q("GTfT",q("GWsT",q("GFWn",n))),w=g(q("pisf",n)),y=g(q("Gtty",m)),i=g(q("Gpid",m));if(!w||!y||!i||w.isNil()||y.isNil()||i.isNil())return"none";return(w.booleanValue?1:0)+" "+y.stringValue.js+" "+i.int32Value}'
8
+ typeset -g TTHEME_GHOSTTY_WATCH='ObjC.import("AppKit");ObjC.import("CoreGraphics");ObjC.import("unistd");function run(v){var p=+v[0],u=$.getppid(),E=$.NSAppleEventDescriptor,W=$.NSWorkspace.sharedWorkspace,L=$.NSRunLoop.currentRunLoop,o=$.NSFileHandle.fileHandleWithStandardOutput,a=$.NSRunningApplication.runningApplicationWithProcessIdentifier(p),f=function(s){return(s.charCodeAt(0)<<24)|(s.charCodeAt(1)<<16)|(s.charCodeAt(2)<<8)|s.charCodeAt(3)},S=$.kCGWindowListOptionOnScreenOnly|$.kCGWindowListExcludeDesktopElements,A=$.kCGWindowListOptionOnScreenAboveWindow,w=0,b=-1,h=false,z=0,k=0,c={};if(!a||a.isNil())return;var t=E.descriptorWithProcessIdentifier(p);function q(y,x){var d=E.recordDescriptor;d.setDescriptorForKeyword(E.descriptorWithTypeCode(f("prop")),f("want"));d.setDescriptorForKeyword(x,f("from"));d.setDescriptorForKeyword(E.descriptorWithEnumCode(f("prop")),f("form"));d.setDescriptorForKeyword(E.descriptorWithTypeCode(f(y)),f("seld"));return d.coerceToDescriptorType(f("obj "))}function g(x){var e=E.appleEventWithEventClassEventIDTargetDescriptorReturnIDTransactionID(f("core"),f("getd"),t,-1,0);e.setParamDescriptorForKeyword(x,f("----"));var r=e.sendEventWithOptionsTimeoutError(3,5,null);return!r||r.isNil()||!r.paramDescriptorForKeyword(f("errn")).isNil()?null:r.paramDescriptorForKeyword(f("----"))}var m=q("GTfT",q("GWsT",q("GFWn",E.nullDescriptor)));function mine(d){return d.objectForKey("kCGWindowOwnerPID").intValue===p&&d.objectForKey("kCGWindowLayer").intValue===0}function top(){var l=ObjC.castRefToObject($.CGWindowListCopyWindowInfo(S,0));for(var j=0;j<+l.count;j++){var d=l.objectAtIndex(j);if(mine(d))return d.objectForKey("kCGWindowNumber").intValue}return 0}function n(k,x){return+$.CFArrayGetCount($.CGWindowListCreate(k,x))}function idle(){return Math.min($.CGEventSourceSecondsSinceLastEventType(0,1),$.CGEventSourceSecondsSinceLastEventType(0,10),$.CGEventSourceSecondsSinceLastEventType(0,12))}function now(){return $.NSDate.date.timeIntervalSince1970.toFixed(6)}function say(s){o.writeData($(s+"\n").dataUsingEncoding(4))}while(!a.terminated&&$.getppid()===u){var x=w?n(A,w):-2,v=!w||x!==b||!n($.kCGWindowListOptionIncludingWindow,w);if(v||z++%40===0){L.runUntilDate($.NSDate.date);h=W.frontmostApplication.processIdentifier===p;var e=top();w=e;b=e?n(A,e):-1;if(!e){var d=$.NSRunningApplication.runningApplicationWithProcessIdentifier(p);if(!d||d.isNil())break}if(h&&e&&e!==k){k=e;var at=now();if(c[e])say("1 "+c[e]+" "+at);var y=g(q("Gtty",m)),i=g(q("Gpid",m));if(y&&i&&!y.isNil()&&!i.isNil()){var r=y.stringValue.js+" "+i.int32Value;if(r!==c[e])say("1 "+r+" "+now());if(top()===e)c[e]=r}}}if(!h)k=0;delay(!w?1:!h?0.25:idle()<1.5?0.05:0.15)}}'
8
9
 
9
10
  __tt_follows_focus() { return 0 }
10
11
 
@@ -95,8 +96,8 @@ __tt_ghostty_ask() {
95
96
  }
96
97
 
97
98
  __tt_ghostty_check() {
98
- local REPLY shown key pal conf=${TTHEME_CONFIG:h}/backgrounds/shown.conf
99
- local -a at ans rec
99
+ local REPLY shown conf=${TTHEME_CONFIG:h}/backgrounds/shown.conf
100
+ local -a at
100
101
  integer n
101
102
  __tt_ghostty_modules
102
103
  for (( n = 0; n < 3; n++ )); do
@@ -108,17 +109,35 @@ __tt_ghostty_check() {
108
109
  zstat -F %s.%N -A at +mtime -- $conf 2>/dev/null
109
110
  [[ $at[1] == "$shown" ]] && break
110
111
  done
111
- if [[ $REPLY == blind ]] || { [[ $REPLY == none ]] && (( ++TTHEME_GHOSTTY_NONE >= 5 )) }; then
112
+ __tt_ghostty_take "$REPLY"
113
+ }
114
+
115
+ __tt_ghostty_take() {
116
+ local REPLY key pal
117
+ local -a ans rec at
118
+ local -F now=$EPOCHREALTIME
119
+ [[ $1 == gone ]] && return 1
120
+ if [[ $1 == none ]]; then
121
+ (( TTHEME_GHOSTTY_PID )) && ! kill -0 $TTHEME_GHOSTTY_PID 2>/dev/null && return 1
122
+ (( TTHEME_GHOSTTY_NONE )) || TTHEME_GHOSTTY_NONE_AT=$now
123
+ (( ++TTHEME_GHOSTTY_NONE ))
124
+ fi
125
+ if [[ $1 == blind ]] || { [[ $1 == none ]] && (( TTHEME_GHOSTTY_NONE >= 5 && now - TTHEME_GHOSTTY_NONE_AT >= 30 )) }; then
112
126
  __tt_put $TTHEME_GHOSTTY_TABS/.blind "${TERM_PROGRAM_VERSION:--}" 2>/dev/null
113
127
  return 1
114
128
  fi
115
- [[ $REPLY == none ]] && return 0
129
+ [[ $1 == none ]] && return 0
116
130
  TTHEME_GHOSTTY_NONE=0
117
- ans=(${=REPLY})
131
+ ans=(${=1})
118
132
  if [[ $ans[1] != 1 || -z $ans[2] ]]; then
119
133
  TTHEME_GHOSTTY_FRONT=""
120
134
  return 0
121
135
  fi
136
+ if [[ -n $ans[4] ]]; then
137
+ at=("")
138
+ zstat -F %s.%N -A at +mtime -- ${TTHEME_CONFIG:h}/backgrounds/shown.conf 2>/dev/null
139
+ [[ -n $at[1] ]] && (( at[1] > ans[4] )) && return 0
140
+ fi
122
141
  __tt_ghostty_key $ans[2]
123
142
  key=$REPLY
124
143
  TTHEME_GHOSTTY_FRONT=$key TTHEME_GHOSTTY_IDLE=1
@@ -137,9 +156,10 @@ __tt_ghostty_tick() {
137
156
  local -a at rec
138
157
  local -F now=$EPOCHREALTIME
139
158
  integer seen
159
+ [[ -n $TTHEME_GHOSTTY_CODE ]] && zstat -F %s.%N -A at +mtime -- $TTHEME_HOME/adapters/ghostty.zsh 2>/dev/null && [[ $at[1] != "$TTHEME_GHOSTTY_CODE" ]] && return 1
140
160
  zstat -F %s.%N -A at +mtime -- $TTHEME_HOME/palettes.zsh 2>/dev/null && [[ $at[1] != "$TTHEME_PALETTES_AT" ]] && __tt_palettes_load
141
161
  if zstat -F %s.%N -A at +mtime -- $TTHEME_GHOSTTY_TABS/.blur 2>/dev/null && [[ $at[1] != "$TTHEME_GHOSTTY_BLUR" ]]; then
142
- [[ -n $TTHEME_GHOSTTY_BLUR ]] && TTHEME_GHOSTTY_WANT=$now
162
+ [[ -n $TTHEME_GHOSTTY_BLUR ]] && (( now - TTHEME_GHOSTTY_TOLD >= 1 )) && TTHEME_GHOSTTY_WANT=$now
143
163
  TTHEME_GHOSTTY_BLUR=$at[1]
144
164
  fi
145
165
  for f in $TTHEME_GHOSTTY_TABS/[^.]*(N); do
@@ -155,14 +175,14 @@ __tt_ghostty_tick() {
155
175
  (( seen )) || continue
156
176
  if [[ $key == "$TTHEME_GHOSTTY_FRONT" ]]; then
157
177
  TTHEME_GHOSTTY_HUSH=$now
158
- elif (( ++TTHEME_GHOSTTY_RUN[$key] < 5 )); then
178
+ elif (( ++TTHEME_GHOSTTY_RUN[$key] < 5 && now - TTHEME_GHOSTTY_TOLD >= 1 )); then
159
179
  TTHEME_GHOSTTY_WANT=$now
160
180
  fi
161
181
  done
162
- if (( TTHEME_GHOSTTY_HUSH && now - TTHEME_GHOSTTY_HUSH >= 0.3 && now - TTHEME_GHOSTTY_ASKED >= (TTHEME_GHOSTTY_IDLE ? 10 : 2) )); then
182
+ if (( ! TTHEME_GHOSTTY_WFD && TTHEME_GHOSTTY_HUSH && now - TTHEME_GHOSTTY_HUSH >= 0.3 && now - TTHEME_GHOSTTY_ASKED >= (TTHEME_GHOSTTY_IDLE ? 10 : 2) )); then
163
183
  TTHEME_GHOSTTY_HUSH=0 TTHEME_GHOSTTY_WANT=$now
164
184
  fi
165
- (( TTHEME_GHOSTTY_WANT && now - TTHEME_GHOSTTY_ASKED >= 0.2 )) || return 0
185
+ (( TTHEME_GHOSTTY_WANT && now - TTHEME_GHOSTTY_ASKED >= 0.2 && ( ! TTHEME_GHOSTTY_WFD || now - TTHEME_GHOSTTY_WANT >= 0.4 ) )) || return 0
166
186
  TTHEME_GHOSTTY_WANT=0
167
187
  __tt_ghostty_check
168
188
  }
@@ -183,20 +203,56 @@ __tt_ghostty_live() {
183
203
  (( live ))
184
204
  }
185
205
 
206
+ __tt_ghostty_watch() {
207
+ (( TTHEME_GHOSTTY_PID )) || return 0
208
+ coproc osascript -l JavaScript -e $TTHEME_GHOSTTY_WATCH $TTHEME_GHOSTTY_PID 2>/dev/null
209
+ TTHEME_GHOSTTY_WATCHER=$!
210
+ exec {TTHEME_GHOSTTY_WFD}<&p
211
+ }
212
+
213
+ __tt_ghostty_heard() {
214
+ local chunk line
215
+ integer rc
216
+ sysread -t 0 -i $TTHEME_GHOSTTY_WFD chunk 2>/dev/null
217
+ rc=$?
218
+ if (( rc == 2 || rc == 5 )); then
219
+ exec {TTHEME_GHOSTTY_WFD}<&-
220
+ TTHEME_GHOSTTY_WFD=0 TTHEME_GHOSTTY_HEARD=""
221
+ return 0
222
+ fi
223
+ TTHEME_GHOSTTY_HEARD+=$chunk
224
+ while [[ $TTHEME_GHOSTTY_HEARD == *$'\n'* ]]; do
225
+ line=${TTHEME_GHOSTTY_HEARD%%$'\n'*}
226
+ TTHEME_GHOSTTY_HEARD=${TTHEME_GHOSTTY_HEARD#*$'\n'}
227
+ TTHEME_GHOSTTY_TOLD=$EPOCHREALTIME TTHEME_GHOSTTY_WANT=0
228
+ __tt_ghostty_take "$line" || return 1
229
+ done
230
+ return 0
231
+ }
232
+
186
233
  __tt_ghostty_follower() {
187
234
  emulate -L zsh
188
235
  local fd REPLY
236
+ local -a at
189
237
  __tt_ghostty_modules
190
238
  zsystem flock -t 0 -f fd $TTHEME_GHOSTTY_TABS/.follow 2>/dev/null || return 0
191
239
  trap '' HUP
240
+ zstat -F %s.%N -A at +mtime -- $TTHEME_HOME/adapters/ghostty.zsh 2>/dev/null && TTHEME_GHOSTTY_CODE=$at[1]
192
241
  __tt_ghostty_owner $PPID
193
242
  TTHEME_GHOSTTY_PID=$REPLY
194
243
  __tt_ghostty_check || return 0
244
+ __tt_ghostty_watch
195
245
  while [[ -e $TTHEME_HOME/palettes.zsh ]]; do
196
246
  __tt_ghostty_tick || break
197
247
  (( ++TTHEME_GHOSTTY_TICK % 50 )) || __tt_ghostty_live || break
198
- zselect -t 10
248
+ if (( TTHEME_GHOSTTY_WFD )); then
249
+ zselect -t 50 -r $TTHEME_GHOSTTY_WFD && { __tt_ghostty_heard || break }
250
+ else
251
+ zselect -t 10
252
+ fi
199
253
  done
254
+ (( TTHEME_GHOSTTY_WATCHER )) && kill $TTHEME_GHOSTTY_WATCHER 2>/dev/null
255
+ return 0
200
256
  }
201
257
 
202
258
  __tt_reset_reloaded() {
@@ -224,6 +280,41 @@ __tt_shown() {
224
280
  __tt_put $dir/shown.conf "config-file = ?${${1/@/--}/\//--}.conf"
225
281
  }
226
282
 
283
+ __tt_ghostty_took() {
284
+ local f=${TTHEME_CONFIG:h}/backgrounds/shown.conf
285
+ local -A st
286
+ local -F t
287
+ zmodload -F zsh/datetime p:EPOCHREALTIME 2>/dev/null
288
+ t=$EPOCHREALTIME
289
+ while zstat -H st -F %s.%N -- $f 2>/dev/null && [[ ! $st[atime] > $st[mtime] ]]; do
290
+ (( EPOCHREALTIME - t < 0.1 )) || return 0
291
+ done
292
+ t=$EPOCHREALTIME
293
+ while (( EPOCHREALTIME - t < 0.003 )); do :; done
294
+ }
295
+
296
+ __tt_wear() {
297
+ local REPLY=$2 name
298
+ [[ -n $REPLY ]] || __tt_name_of "$1"
299
+ name=$REPLY
300
+ TTHEME_SPEC=$1
301
+ if [[ -n ${TTHEME_PALETTE[$name]} ]] && __tt_shown "$name" $3; then
302
+ TTHEME_GHOSTTY_SENT=0
303
+ __tt_reload
304
+ (( TTHEME_GHOSTTY_SENT )) && __tt_ghostty_took
305
+ __tt_apply "$1"
306
+ return 0
307
+ fi
308
+ __tt_apply "$1"
309
+ return 1
310
+ }
311
+
312
+ __tt_pv_claim() {
313
+ TTHEME_GHOSTTY_SENT=0
314
+ __tt_shown "$1" force && __tt_reload && (( TTHEME_GHOSTTY_SENT )) && __tt_ghostty_took
315
+ return 0
316
+ }
317
+
227
318
  __tt_bg_cells() {
228
319
  local REPLY resp line v f
229
320
  local -i px=2 py=2 fs=0 sc=2
package/shell/ttheme.zsh CHANGED
@@ -326,9 +326,8 @@ __tt_dir_sync() {
326
326
  fi
327
327
  TTHEME_PIN=$REPLY TTHEME_PIN_SPEC=$spec
328
328
  [[ -n $spec && $spec != "$TTHEME_SPEC" ]] || return 0
329
- __tt_apply "$spec"
330
- TTHEME_SPEC=$spec
331
- __tt_sync
329
+ __tt_wear "$spec"
330
+ return 0
332
331
  }
333
332
 
334
333
  __tt_chpwd() {
@@ -520,11 +519,11 @@ __tt_pin_save() {
520
519
  fi
521
520
  if [[ $spec != "$TTHEME_SPEC" ]]; then
522
521
  if [[ -n $spec ]]; then
523
- __tt_apply "$spec"
522
+ __tt_wear "$spec"
524
523
  else
525
524
  __tt_osc_reset
525
+ TTHEME_SPEC=
526
526
  fi
527
- TTHEME_SPEC=$spec
528
527
  fi
529
528
  __tt_dir_label "$base"
530
529
  k=$REPLY
@@ -1227,7 +1226,6 @@ __tt_catalog() {
1227
1226
  }
1228
1227
 
1229
1228
  __tt_switch() {
1230
- local spec
1231
1229
  __tt_cli "$@" || return
1232
1230
  [[ -r $TTHEME_HOME/palettes.zsh ]] && __tt_palettes_load && __tt_reloaded
1233
1231
  if ! __tt_active; then
@@ -1237,11 +1235,7 @@ __tt_switch() {
1237
1235
  if [[ $1 == off ]]; then
1238
1236
  __tt_off_here reload
1239
1237
  elif [[ -n $TTHEME_STARTUP ]]; then
1240
- spec=${TTHEME_PALETTE[$TTHEME_STARTUP]}
1241
- __tt_apply "$spec"
1242
- TTHEME_SPEC=$spec
1243
- __tt_shown "$TTHEME_STARTUP" force
1244
- __tt_reload
1238
+ __tt_wear "${TTHEME_PALETTE[$TTHEME_STARTUP]}" "$TTHEME_STARTUP" force || __tt_reload
1245
1239
  fi
1246
1240
  }
1247
1241
 
@@ -1343,9 +1337,7 @@ __tt_next() {
1343
1337
  __tt_rotate() {
1344
1338
  local REPLY
1345
1339
  __tt_next
1346
- __tt_apply "$REPLY"
1347
- TTHEME_SPEC=$REPLY
1348
- __tt_worn_shown force && __tt_reload
1340
+ __tt_wear "$REPLY" "" force
1349
1341
  __tt_announce
1350
1342
  }
1351
1343
 
@@ -2710,6 +2702,7 @@ __tt_preview() {
2710
2702
  done
2711
2703
  } always {
2712
2704
  local spec=${sel:+${TTHEME_PALETTE[$sel]}}
2705
+ [[ -n $spec && $mode != pin ]] && (( ! ${#bgedit} && ! ${#bgswap} )) && __tt_pv_claim "$sel"
2713
2706
  printf '\e[?2026h'
2714
2707
  __tt_pv_bg_close
2715
2708
  if [[ -n $spec ]]; then
@@ -2786,14 +2779,11 @@ ttheme() {
2786
2779
  [[ $1 == config ]] && { __tt_config; return }
2787
2780
  (( ${#TTHEME_PALETTE} )) || { __tt_empty; return }
2788
2781
 
2789
- local REPLY spec
2782
+ local REPLY
2790
2783
  case $1 in
2791
2784
  use)
2792
2785
  __tt_resolve "$2" || return 1
2793
- spec=${TTHEME_PALETTE[$REPLY]}
2794
- __tt_apply "$spec"
2795
- TTHEME_SPEC=$spec
2796
- __tt_shown "$REPLY" force && __tt_reload
2786
+ __tt_wear "${TTHEME_PALETTE[$REPLY]}" "$REPLY" force
2797
2787
  __tt_announce ;;
2798
2788
  next) __tt_rotate ;;
2799
2789
  default)