Skip to content
Draft
50 changes: 34 additions & 16 deletions TeXmacs/progs/texmacs/texmacs/tm-files.scm
Original file line number Diff line number Diff line change
Expand Up @@ -815,25 +815,43 @@
;; 这里只写入 init-env,避免触发文档重新解析;doc id 是否持久化到文件由
;; 用户后续保存动作决定。
(tm-define (auto-backup-ensure-buffer-doc-id! name)
(display "[1106-ab] enter name=")
(display name)
(newline)
(catch #t
(lambda ()
(and (auto-backup-buffer-eligible? name)
(with-buffer name
(let ((old-doc-id (auto-backup-buffer-doc-id name)))
(if (auto-backup-valid-doc-id? old-doc-id)
old-doc-id
(let ((doc-id (uuid4)))
;; 写入 init-env 即可绑定到当前会话,避免 buffer-set 触发
;; 文档重新解析。
(init-env "stem-doc-id" doc-id)
doc-id
) ;let
) ;if
) ;let
) ;with-buffer
) ;and
(let ((eligible (auto-backup-buffer-eligible? name)))
(display "[1106-ab] eligible=")
(display eligible)
(newline)
(and eligible
(with-buffer name
(let ((old-doc-id (auto-backup-buffer-doc-id name)))
(display "[1106-ab] old-doc-id=")
(display old-doc-id)
(newline)
(if (auto-backup-valid-doc-id? old-doc-id)
(begin
(display "[1106-ab] branch=keep-old")
(newline)
old-doc-id
) ;begin
(let ((doc-id (uuid4)))
(display "[1106-ab] branch=inject-new doc-id=")
(display doc-id)
(newline)
;; 写入 init-env 即可绑定到当前会话,避免 buffer-set 触发
;; 文档重新解析。
(init-env "stem-doc-id" doc-id)
doc-id
) ;let
) ;if
) ;let
) ;with-buffer
) ;and
) ;let
) ;lambda
(lambda args #f)
(lambda args (display "[1106-ab] exception=") (display args) (newline) #f)
) ;catch
) ;tm-define

Expand Down
125 changes: 125 additions & 0 deletions TeXmacs/tests/1106.scm
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; MODULE : 1106.scm
;; DESCRIPTION : GUI auto-reproduction for tab-switch dirty-state bug (1106)
;; COPYRIGHT : (C) 2026
;;
;; This software falls under the GNU general public license version 3 or later.
;; It comes WITHOUT ANY WARRANTY WHATSOEVER. For details, see the file LICENSE
;; in the root directory or <http://www.gnu.org/licenses/gpl-3.0.html>.
;;
;; PURPOSE
;; The bug reproduces in the real GUI just by opening two documents and
;; switching between their tabs. switch-to-buffer in headless does NOT
;; trigger it. This file drives the *same* code path that tabpage-menu.scm
;; uses when the user clicks a tab (window-set-view), in a real GUI process,
;; with a delay between steps so the Qt event loop has time to process tab
;; rebuild + paint. The [1106] buffer_modified and [1106-qt] applyDisplayTitle
;; debug logs can then be watched live in the terminal.
;;
;; Fixtures live under $TEXMACS_PATH/tests/tmu and are copied to /tmp at the
;; start of every run so save-buffer / edits never mutate the checked-in
;; copies.
;;
;; Because exec-delayed-at runs asynchronously, test_1106 schedules the
;; whole sequence as a chain of delayed tasks and lets the last task call
;; (quit-TeXmacs) itself; test_1106 returns immediately so the event loop
;; keeps running and the chain can fire.
;;
;; USAGE
;; xmake b stem
;; MOGAN_TEST_GUI=1 xmake r 1106
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(texmacs-module (texmacs tests 1106))

(define (fixture-name name)
(string-append "$TEXMACS_PATH/tests/tmu/" name)
) ;define

(define (tmp-name name)
(string->url (string-append "/tmp/" name))
) ;define

(define (refresh-fixture name)
(let ((src (string->url (fixture-name name))) (dst (tmp-name name)))
(when (url-exists? src)
(system-copy src dst)
) ;when
) ;let
) ;define

(define (view-for-buffer buf views)
(cond ((null? views) #f)
((== (view->buffer (car views)) buf) (car views))
(else (view-for-buffer buf (cdr views)))
) ;cond
) ;define

(define (switch-to buf)
(let* ((views (tabpage-list #t)) (v (view-for-buffer buf views)))
(when v
(let ((win (view->window-of-tabpage v)))
(window-set-view win v #t)
) ;let
) ;when
) ;let*
) ;define

(define step-delay-ms 5000)

(define (run-chain steps)
(let loop
((rest steps) (t (+ (texmacs-time) step-delay-ms)))
(when (pair? rest)
(let ((label (caar rest)) (act (cdar rest)))
(exec-delayed-at (lambda ()
(display "[1106-step] ")
(display label)
(newline)
(act)
(loop (cdr rest) (+ (texmacs-time) step-delay-ms))
) ;lambda
t
) ;exec-delayed-at
) ;let
) ;when
) ;let
) ;define

(tm-define (test_1106)
;; Refresh /tmp copies from $TEXMACS_PATH fixtures so the checked-in files
;; never get mutated by save-buffer during the run.
(refresh-fixture "1106_a.tmu")
(refresh-fixture "1106_b.tmu")
(let* ((path-a (tmp-name "1106_a.tmu")) (path-b (tmp-name "1106_b.tmu")))
(let ((steps (list (cons "load a" (lambda () (load-buffer path-a)))
(cons "load b" (lambda () (load-buffer path-b)))
) ;list
) ;steps
) ;
(let loop
((i 0) (acc steps))
(if (>= i 5)
(set! steps
(append acc (list (cons "all done; quitting" (lambda () (quit-TeXmacs)))))
) ;set!
(loop (+ i 1)
(append acc
(list (cons (string-append "round " (number->string i) ": switch a (std 2)")
(lambda () (switch-to-view-index 1))
) ;cons
(cons (string-append "round " (number->string i) ": switch b (std 3)")
(lambda () (switch-to-view-index 2))
) ;cons
) ;list
) ;append
) ;loop
) ;if
) ;let
(display "[1106-step] starting delayed chain\n")
(run-chain steps)
) ;let
) ;let*
) ;tm-define
15 changes: 15 additions & 0 deletions TeXmacs/tests/tmu/1106_a.tmu
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<TMU|<tuple|1.1.0|2026.2.6>>

<style|<tuple|generic|chinese|table-captions-above|number-europe|preview-ref>>

<\body>
1106_a
</body>

<\initial>
<\collection>
<associate|page-medium|paper>
<associate|page-screen-margin|false>
<associate|stem-doc-id|745D6745-9596-4000-8B80-3A32955ADF50>
</collection>
</initial>
15 changes: 15 additions & 0 deletions TeXmacs/tests/tmu/1106_b.tmu
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<TMU|<tuple|1.1.0|2026.2.6>>

<style|<tuple|generic|chinese|table-captions-above|number-europe|preview-ref>>

<\body>
1106_b
</body>

<\initial>
<\collection>
<associate|page-medium|paper>
<associate|page-screen-margin|false>
<associate|stem-doc-id|F7016320-2296-4340-802B-0E1BF65530C0>
</collection>
</initial>
Loading
Loading