]> git.proxmox.com Git - mirror_xterm.js.git/commitdiff
Set xterm-color for cursor element
authorthomas <thomas@kreativkonzentrat.de>
Tue, 11 Jul 2017 19:15:33 +0000 (21:15 +0200)
committermofux <t.zilz@mofux.org>
Wed, 2 Aug 2017 13:41:18 +0000 (15:41 +0200)
Prevent focus from getting lost when in vt mouse mode
Fix: cursor style not applied on init, set a class for block cursor
Make all cursors work under all conditions (focused, unfocused, blink)
Unify cursor rendering with normal rendering code
Make sure underline AND blink can be used in co-existence
Always show outlined block cursor in unfocused state

src/Renderer.ts
src/xterm.css
src/xterm.js

index db4d6a63b5cd4502fa6e8b226b95f15d8004e2ca..165594fd25f6d165c116d89e209f0f529db98362 100644 (file)
@@ -170,16 +170,13 @@ export class Renderer {
         let data: any = line[i][0];
         const ch = line[i][1];
         const ch_width: any = line[i][2];
+        const isCursor: boolean = i === x;
         if (!ch_width) {
           continue;
         }
 
-        if (i === x) {
-          data = -1;
-        }
-
-        if (data !== attr) {
-          if (attr !== this._terminal.defAttr) {
+        if (data !== attr || isCursor) {
+          if (attr !== this._terminal.defAttr && !isCursor) {
             if (innerHTML) {
               currentElement.innerHTML = innerHTML;
               innerHTML = '';
@@ -187,7 +184,7 @@ export class Renderer {
             documentFragment.appendChild(currentElement);
             currentElement = null;
           }
-          if (data !== this._terminal.defAttr) {
+          if (data !== this._terminal.defAttr || isCursor) {
             if (innerHTML && !currentElement) {
               currentElement = this._spanElementObjectPool.acquire();
             }
@@ -199,71 +196,73 @@ export class Renderer {
               documentFragment.appendChild(currentElement);
             }
             currentElement = this._spanElementObjectPool.acquire();
-            if (data === -1) {
+
+            let bg = data & 0x1ff;
+            let fg = (data >> 9) & 0x1ff;
+            let flags = data >> 18;
+
+            if (isCursor) {
               currentElement.classList.add('reverse-video');
               currentElement.classList.add('terminal-cursor');
-            } else {
-              let bg = data & 0x1ff;
-              let fg = (data >> 9) & 0x1ff;
-              let flags = data >> 18;
-
-              if (flags & FLAGS.BOLD) {
-                if (!brokenBold) {
-                  currentElement.classList.add('xterm-bold');
-                }
-                // See: XTerm*boldColors
-                if (fg < 8) {
-                  fg += 8;
-                }
-              }
+            }
 
-              if (flags & FLAGS.UNDERLINE) {
-                currentElement.classList.add('xterm-underline');
+            if (flags & FLAGS.BOLD) {
+              if (!brokenBold) {
+                currentElement.classList.add('xterm-bold');
               }
-
-              if (flags & FLAGS.BLINK) {
-                currentElement.classList.add('xterm-blink');
+              // See: XTerm*boldColors
+              if (fg < 8) {
+                fg += 8;
               }
+            }
 
-              // If inverse flag is on, then swap the foreground and background variables.
-              if (flags & FLAGS.INVERSE) {
-                let temp = bg;
-                bg = fg;
-                fg = temp;
-                // Should inverse just be before the above boldColors effect instead?
-                if ((flags & 1) && fg < 8) {
-                  fg += 8;
-                }
-              }
+            if (flags & FLAGS.UNDERLINE) {
+              currentElement.classList.add('xterm-underline');
+            }
 
-              if (flags & FLAGS.INVISIBLE) {
-                currentElement.classList.add('xterm-hidden');
-              }
+            if (flags & FLAGS.BLINK) {
+              currentElement.classList.add('xterm-blink');
+            }
 
-              /**
-               * Weird situation: Invert flag used black foreground and white background results
-               * in invalid background color, positioned at the 256 index of the 256 terminal
-               * color map. Pin the colors manually in such a case.
-               *
-               * Source: https://github.com/sourcelair/xterm.js/issues/57
-               */
-              if (flags & FLAGS.INVERSE) {
-                if (bg === 257) {
-                  bg = 15;
-                }
-                if (fg === 256) {
-                  fg = 0;
-                }
+            // If inverse flag is on, then swap the foreground and background variables.
+            if (flags & FLAGS.INVERSE) {
+              let temp = bg;
+              bg = fg;
+              fg = temp;
+              // Should inverse just be before the above boldColors effect instead?
+              if ((flags & 1) && fg < 8) {
+                fg += 8;
               }
+            }
 
-              if (bg < 256) {
-                currentElement.classList.add(`xterm-bg-color-${bg}`);
-              }
+            if (flags & FLAGS.INVISIBLE && !isCursor) {
+              currentElement.classList.add('xterm-hidden');
+            }
 
-              if (fg < 256) {
-                currentElement.classList.add(`xterm-color-${fg}`);
+            /**
+             * Weird situation: Invert flag used black foreground and white background results
+             * in invalid background color, positioned at the 256 index of the 256 terminal
+             * color map. Pin the colors manually in such a case.
+             *
+             * Source: https://github.com/sourcelair/xterm.js/issues/57
+             */
+            if (flags & FLAGS.INVERSE) {
+              if (bg === 257) {
+                bg = 15;
+              }
+              if (fg === 256) {
+                fg = 0;
               }
             }
+
+            if (bg < 256) {
+              currentElement.classList.add(`xterm-bg-color-${bg}`);
+            }
+
+            if (fg < 256) {
+              currentElement.classList.add(`xterm-color-${fg}`);
+            }
+
           }
         }
 
@@ -295,7 +294,10 @@ export class Renderer {
           }
         }
 
-        attr = data;
+        // The cursor needs its own element, therefore we set attr to -1
+        // which will cause the next character to be rendered in a new element
+        attr = isCursor ? -1 : data;
+
       }
 
       if (innerHTML && !currentElement) {
index 6d6f48fadc9fed00907e37441a1260a261ac7bf0..89daf9e3e1a4b3bf8ba0d17b92fcc5798caa017b 100644 (file)
     text-decoration: none;
 }
 
-.terminal.focus:not(.xterm-cursor-style-underline):not(.xterm-cursor-style-bar) .terminal-cursor {
-    background-color: #fff;
-    color: #000;
+.terminal .terminal-cursor {
+    position: relative;
 }
 
 .terminal:not(.focus) .terminal-cursor {
     outline: 1px solid #fff;
     outline-offset: -1px;
-    background-color: transparent;
 }
 
-.terminal:not(.xterm-cursor-style-underline):not(.xterm-cursor-style-bar).focus.xterm-cursor-blink-on .terminal-cursor {
-    background-color: transparent;
-    color: inherit;
+.terminal.xterm-cursor-style-block.focus:not(.xterm-cursor-blink-on) .terminal-cursor {
+    background-color: #fff;
+    color: #000;
 }
 
-.terminal.xterm-cursor-style-bar .terminal-cursor,
-.terminal.xterm-cursor-style-underline .terminal-cursor {
-    position: relative;
-}
-.terminal.xterm-cursor-style-bar .terminal-cursor::before,
-.terminal.xterm-cursor-style-underline .terminal-cursor::before {
-    content: "";
-    display: block;
+.terminal.focus.xterm-cursor-style-bar:not(.xterm-cursor-blink-on) .terminal-cursor::before,
+.terminal.focus.xterm-cursor-style-underline:not(.xterm-cursor-blink-on) .terminal-cursor::before {
+    content: '';
     position: absolute;
     background-color: #fff;
 }
-.terminal.xterm-cursor-style-bar .terminal-cursor::before {
+
+.terminal.focus.xterm-cursor-style-bar:not(.xterm-cursor-blink-on) .terminal-cursor::before {
     top: 0;
-    bottom: 0;
     left: 0;
+    bottom: 0;
     width: 1px;
 }
-.terminal.xterm-cursor-style-underline .terminal-cursor::before {
+
+.terminal.focus.xterm-cursor-style-underline:not(.xterm-cursor-blink-on) .terminal-cursor::before {
     bottom: 0;
     left: 0;
     right: 0;
     height: 1px;
 }
-.terminal.xterm-cursor-style-bar.focus.xterm-cursor-blink.xterm-cursor-blink-on .terminal-cursor::before,
-.terminal.xterm-cursor-style-underline.focus.xterm-cursor-blink.xterm-cursor-blink-on .terminal-cursor::before {
-    background-color: transparent;
-}
-.terminal.xterm-cursor-style-bar.focus.xterm-cursor-blink .terminal-cursor::before,
-.terminal.xterm-cursor-style-underline.focus.xterm-cursor-blink .terminal-cursor::before {
-    background-color: #fff;
-}
 
 .terminal .composition-view {
     background: #000;
     text-decoration: blink;
 }
 
+.terminal .xterm-blink.xterm-underline {
+    text-decoration: blink underline;
+}
+
 .terminal .xterm-hidden {
     visibility: hidden;
 }
index a3f425d1aa797ced5bff82f4d4184f091b7c3c26..1bb44a9a3e214bf1ba78d50b9ed04f10c129eb05 100644 (file)
@@ -429,7 +429,7 @@ Terminal.prototype.setOption = function(key, value) {
   switch (key) {
     case 'cursorBlink': this.setCursorBlinking(value); break;
     case 'cursorStyle':
-      // Style 'block' applies with no class
+      this.element.classList.toggle(`xterm-cursor-style-block`, value === 'block');
       this.element.classList.toggle(`xterm-cursor-style-underline`, value === 'underline');
       this.element.classList.toggle(`xterm-cursor-style-bar`, value === 'bar');
       break;
@@ -639,6 +639,7 @@ Terminal.prototype.open = function(parent, focus) {
   this.element.classList.add('terminal');
   this.element.classList.add('xterm');
   this.element.classList.add('xterm-theme-' + this.theme);
+  this.element.classList.add(`xterm-cursor-style-${this.options.cursorStyle}`);
   this.setCursorBlinking(this.options.cursorBlink);
 
   this.element.setAttribute('tabindex', 0);
@@ -1025,6 +1026,9 @@ Terminal.prototype.bindMouse = function() {
   }
 
   on(el, 'mousedown', function(ev) {
+    // prevent the focus on the textarea from getting lost
+    ev.preventDefault();
+
     if (!self.mouseEvents) return;
 
     // send the button