patch 9.1.1060: Vim always enables 'termguicolors' in a terminal

Problem:  Vim always enables 'termguicolors' in a terminal, even
          when not wanted (after v9.1.1054)
Solution: Respect `:set notermguicolors` in vimrc file

fixes: #16538
fixes: #16539
closes: #16540

Signed-off-by: Christian Brabandt <cb@256bit.org>
diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt
index 648b18c..e6decee 100644
--- a/runtime/doc/options.txt
+++ b/runtime/doc/options.txt
@@ -1,4 +1,4 @@
-*options.txt*	For Vim version 9.1.  Last change: 2025 Jan 29
+*options.txt*	For Vim version 9.1.  Last change: 2025 Jan 31
 
 
 		  VIM REFERENCE MANUAL	  by Bram Moolenaar
@@ -8500,7 +8500,8 @@
 <	You need to do this when your system has no locale support for UTF-8.
 
 		*'termguicolors'* *'tgc'* *'notermguicolors'* *'notgc'* *E954*
-'termguicolors' 'tgc'	boolean (default off)
+'termguicolors' 'tgc'	boolean (default off unless Vim detects that it runs
+				in a capable terminal)
 			global
 			{not available when compiled without the
 			|+termguicolors| feature}
@@ -8510,7 +8511,11 @@
 	Will automatically be enabled, if Vim detects that it runs in a
 	capable terminal (when the terminal supports the RGB terminfo
 	capability or when the number of colors |t_Co| supported by the
-	terminal is 0x1000000, e.g. with $TERM=xterm-direct).
+	terminal is 0x1000000, e.g. with $TERM=xterm-direct). Due to the async
+	nature of querying the terminal, enabling this automatically is
+	noticable. Use >
+		set notermguicolors
+<	to explicitly disable.
 
 	Requires a ISO-8613-3 compatible terminal.  If setting this option
 	does not work (produces a colorless UI) reading |xterm-true-color|
diff --git a/src/globals.h b/src/globals.h
index e3b1e27f..3827c1a 100644
--- a/src/globals.h
+++ b/src/globals.h
@@ -2043,3 +2043,7 @@
 // 'showcmd' buffer shared between normal.c and statusline code
 #define SHOWCMD_BUFLEN (SHOWCMD_COLS + 1 + 30)
 EXTERN char_u showcmd_buf[SHOWCMD_BUFLEN];
+
+#ifdef FEAT_TERMGUICOLORS
+EXTERN int	p_tgc_set INIT(= FALSE);
+#endif
diff --git a/src/option.c b/src/option.c
index 653b87c..3753c4a 100644
--- a/src/option.c
+++ b/src/option.c
@@ -4296,6 +4296,7 @@
 #  endif
 	    !has_vtp_working())
     {
+	p_tgc_set = TRUE;
 	p_tgc = 0;
 	return e_24_bit_colors_are_not_supported_on_this_environment;
     }
@@ -4320,6 +4321,7 @@
     term_update_palette_all();
     term_update_wincolor_all();
 # endif
+    p_tgc_set = TRUE;
 
     return NULL;
 }
diff --git a/src/term.c b/src/term.c
index 103ec96..1991342 100644
--- a/src/term.c
+++ b/src/term.c
@@ -1662,8 +1662,8 @@
     else
 	*nr_colors = NUL;
 #ifdef FEAT_TERMGUICOLORS
-    // xterm-direct, enable termguicolors
-    if (t_colors == 0x1000000 && !p_tgc)
+    // xterm-direct, enable termguicolors, when it wasn't set yet
+    if (t_colors == 0x1000000 && !p_tgc_set)
 	set_option_value((char_u *)"termguicolors", 1L, NULL, 0);
 #endif
     set_string_option_direct((char_u *)"t_Co", -1, nr_colors, OPT_FREE, 0);
@@ -7199,8 +7199,9 @@
 	    else if (name[0] == 'R' && name[1] == 'G' && name[2] == 'B' && code[9] == '=')
 	    {
 		int val = atoi((char *)str);
-		// 8 bits per color channel
-		if (val == 8)
+		// only enable it, if termguicolors hasn't been set yet and
+		// there are 8 bits per color channel
+		if (val == 8 && !p_tgc_set)
 		{
 #ifdef FEAT_EVAL
 		    ch_log(NULL, "got_code_from_term(RGB): xterm-direct colors detected");
diff --git a/src/testdir/test_termcodes.vim b/src/testdir/test_termcodes.vim
index 098fdb3..db98a70 100644
--- a/src/testdir/test_termcodes.vim
+++ b/src/testdir/test_termcodes.vim
@@ -10,6 +10,24 @@
 source view_util.vim
 source term_util.vim
 
+func s:TermGuiColorsTest()
+  CheckNotMSWindows
+  if !CanRunVimInTerminal()
+    throw 'Skipped: cannot make screendumps'
+  endif
+  if !executable('tput')
+    throw "Skipped: tput not executable!"
+  endif
+  if has("gui_running")
+    throw "Skipped: does not work in GUI mode"
+  endif
+  call system('tput -Txterm-direct RGB 2>/dev/null')
+  if v:shell_error
+    throw "Skipped: xterm-direct $TERM has no RGB capability"
+  endif
+endfunc
+
+
 func Test_term_mouse_left_click()
   new
   let save_mouse = &mouse
@@ -2740,21 +2758,8 @@
 endfunc
 
 func Test_xterm_direct_enables_termguicolors()
+  call s:TermGuiColorsTest()
   " TERM=xterm-direct enables termguicolors
-  CheckNotMSWindows
-  if !CanRunVimInTerminal()
-    throw 'Skipped: cannot make screendumps'
-  endif
-  if !executable('tput')
-    throw "Skipped: tput not executable!"
-  endif
-  if has("gui_running")
-    throw "Skipped: does not work in GUI mode"
-  endif
-  call system('tput -Txterm-direct RGB 2>/dev/null')
-  if v:shell_error
-    throw "Skipped: xterm-direct $TERM has no RGB capability"
-  endif
   let colors  = systemlist('tput -Txterm-direct colors')[0]
   defer delete('XTerm-direct.txt')
 
@@ -2773,6 +2778,33 @@
   call assert_equal(['', 'TERM: xterm-direct', 'Termguicolors: 1'], result)
   " cleanup
   bw!
+  close
+endfunc
+
+func Test_xterm_direct_no_termguicolors()
+  " unfortunately doesn't work with libvterm
+  call s:TermGuiColorsTest()
+
+  let lines =<< trim END
+      set notermguicolors noswapfile
+      set t_Co=16777216
+  END
+  call writefile(lines, 'XtermDirect', 'D')
+  defer delete('XTerm-direct2.txt')
+
+  let buf = RunVimInTerminal('-S XtermDirect --clean XTerm-direct2.txt',
+        \  {'rows': 10, 'env': {'TERM': 'xterm-direct'}})
+  call TermWait(buf)
+  call term_sendkeys(buf, ":$put ='TERM: ' .. &term\<cr>")
+  call term_sendkeys(buf, ":$put ='Termguicolors: ' .. &tgc\<cr>")
+  call term_sendkeys(buf, ":wq\<cr>")
+  call TermWait(buf)
+
+  let result=readfile('XTerm-direct2.txt')
+  call assert_equal(['', 'TERM: xterm-direct', 'Termguicolors: 0'], result)
+  " cleanup
+  bw!
+  close
 endfunc
 
 " vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/version.c b/src/version.c
index 209baf1..1e0d3cd 100644
--- a/src/version.c
+++ b/src/version.c
@@ -705,6 +705,8 @@
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    1060,
+/**/
     1059,
 /**/
     1058,