mirror of
https://github.com/microsoft/terminal.git
synced 2026-09-25 08:24:54 +00:00
Incorrect display of characters written on top of the wide emojis #6123
Closed
opened 2026-01-31 00:30:22 +00:00 by claunia
·
44 comments
No Branch/Tag Specified
main
dev/duhowett/stop-using-projection-for-control-innards
dev/duhowett/fhl-2026/remove-paste-hairpin-handler
dev/duhowett/win7-wpf-termcontrol-squash
dev/lhecker/20226-present-leaks
dev/duhowett/wpf-1-autoscroll-to-interactivity
dev/duhowett/wpf-3-swapchain-handle
dev/duhowett/wpf-2-midi-audio-timer
dev/migrie/overview-for-pr
dev/migrie/b/markdown-paste
dev/duhowett/padding-in-atlas
fix/german-split-pane-tooltip
release-1.25
dev/cazamor/sui-rejuv/fix-spaces
dev/migrie/per-window-final
dev/cazamor/selfhost/2026-08-31
dev/migrie/b/independent-animations
dev/pabhoj/wtcli
dev/cazamor/conhost/bugfix-a11y-find
dev/cazamor/conhost/bugfix-a11y-find-1.24
dev/lhecker/theme-quality-test
dev/lhecker/theme-quality
dev/cazamor/selfhost/sui-rejuv
dev/cazamor/fix/search-selection-off-by-one
dev/duhowett/even-more-builtin-glyphs
dev/crutkas/kitty-pr1
dev/cazamor/toast/activity
release-1.24
users/GitHubPolicyService/d8615b98-f5fa-4462-bf7f-c44a1cc12096
dev/cazamor/selfhost/2026-06-18
dev/migrie/f/new-profile-subcommand
dev/cazamor/sui-rejuv/profiles-v2
dev/duhowett/asan-for-all
dev/cazamor/sui-rejuv/profiles-new
dev/cazamor/sui-rejuv/expander-groups-new
dev/cazamor/auto-save/refresh-settings
feature/llm
dev/cazamor/auto-save/model/json-manager
dev/cazamor/auto-save/settings-model
dev/migrie/s/snippet-params
users/merlinbot/1es-pt-auto-baselining-pr
niels9001/inactive-tab-foreground
dev/cazamor/selfhost/2026-05-20-home
dev/duhowett/fzf-vcxproj
dev/cazamor/selfhost/2026-05-20
dev/cazamor/selfhost/2026-05-19
dev/cazamor/selfhost/2026-05-18
niels9001/fontweight-fixes
niels9001/page-transitions
dev/duhowett/fhl-2026/rewrite-paste-and-dragdrop-handling-writeinputstring
dev/migrie/f/overview-view
dev/cazamor/selfhost/2026-05-13
dev/cazamor/selfhost/2026-05-13-sui
dev/yeelam/f/BuildTest
dev/duhowett/hax/our-own-tabview
dev/cazamor/bugfix/close-scratchpad
dev/cazamor/selfhost/2026-05-05
dev/cazamor/selfhost/2026-05-04-workspaces
dev/cazamor/selfhost/2026-05-04
dev/lhecker/20149-hotfix
dev/lhecker/osc-7-wsl
dev/migrie/workspaces-real
dev/migrie/fhl-spring-2026/quake-4
dev/lhecker/pwsh-5.1
dev/cazamor/sui/dropdown-page
dev/cazamor/selfhost/2026-04-08
dev/cazamor/selfhost/2026-04-06
dev/migrie/fhl-spring-2026/confirmCloseOn
dev/cazamor/confirmCloseOn/dont-ask-me-again
dev/lhecker/inproc-conpty
dev/duhowett/powershell-module-supercharger
dev/cazamor/a11y/vt-seq-prototype
dev/migrie/fhl-spring26/osc777-2
dev/migrie/fhl-spring26/2/notification-infrastructure
dev/migrie/fhl-spring-2026/side-tabs
dev/cazamor/copilot/playground
dev/migrie/fhl-spring-2026/quake-3.5
dev/migrie/fhl-spring26/osc777
dev/migrie/fhl-spring26/unpackaged-notify
dev/migrie/fhl-spring26/bellStyle-notification
dev/migrie/fhl-spring26/activity-notifications
dev/migrie/fhl-spring-2026/x-open
dev/migrie/fhl-spring-2026/quake-5
dev/migrie/fhl-spring26/nextTab-filter
dev/duhowett/atlas-draw-d2d-dots-curlies-consistently
dev/lhecker/14165-conhost-font-size
dev/lhecker/ottosson-by-default
dev/duhowett/hax/unix-pty
dev/duhowett/hax/cmake
dev/lhecker/generate-256-colors
dev/lhecker/dcs-perf
dev/lhecker/1410-large-scrollback
dev/cazamor/selfhost/2026-02-10
dev/lhecker/11509-kitty-keyboard-protocol-wip
dev/cazamor/selfhost/2026-01-29
dev/lhecker/benchcat-fix
dev/duhowett/eoy-25/allow-set-foreground
release-1.23
dev/cazamor/bot/deprecate-area-atlasengine
dev/cazamor/selfhost/2026-01-20
dev/cazamor/selfhost/2026-01-12
dev/cazamor/spec/auto-save
dev/duhowett/fhl-2024/asciicast-recorder
dev/duhowett/eoy-25/underline-colors-in-atlas-bug
dev/duhowett/hax/serial-port-support
dev/duhowett/connection-utf8
dev/lhecker/fused-event
dev/lhecker/18928-wip
dev/duhowett/fhl-2024/clang
dev/duhowett/vt-cache-changes
dev/cazamor/uia-leak
release-1.22
dev/cazamor/selfhost/11-18-v3
dev/cazamor/selfhost/11-18
dev/duhowett/fhl-2025/bitmap-fonts
dev/duhowett/server-2025-vms
dev/duhowett/cant-believe-gotta-do-this-shit
dev/lhecker/dark-mode
dev/cazamor/sui/invert-cursor-color
dev/duhowett/fhl-2025/wt-command-palette-cmdpal-integration
dev/duhowett/fhl-2025/wt-json-relative-icons
dev/lhecker/fucking-service-locator
dev/duhowett/unicode-17
dev/duhowett/multi-blern
dev/lhecker/wellp2-alt
dev/duhowett/wellp2
dev/lhecker/1860-horizontal-scrollbar
dev/lhecker/fix-window-count
dev/cazamor/sui/tab-color-old
dev/duhowett/hax/conhost-icon
dev/duhowett/hax/sui-color-chip-border
dev/duhowett/hax/terminalsettings-as-a-lib-/with-types-merged-into-tsm
dev/pabhoj/page_control_input_cleanup
dev/duhowett/padding-in-atlas-rebase-20250729
dev/lhecker/attach-thread-input
dev/duhowett/portable-shader-members
msbuildcache-reenable
dev/cazamor/selfhost/1.24-2025-06-10
dev/cazamor/upgrade-settings-containers
dev/cazamor/sui/ext-page/powershell-stub
dev/cazamor/selfhost/1.24-2025-05-15
dev/pabhoj/sui_action_overhaul
dev/cazamor/selfhost/1.24-2025-05-06
dev/cazamor/selfhost/1.24-2025-04-29
dev/cazamor/sui/ext-page/lazy-load-objects
dev/cazamor/sui/ext-page/badge
dev/cazamor/selfhost/1.24
dev/lhecker/sdk-26100
dev/duhowett/testing
dev/jadelaga/VS-Pty.Net-1.22
dev/duhowett/fhl-2025/what-if-no-content-ids
dev/lhecker/18584-part2
dev/lhecker/get-lang-id
dev/duhowett/hax/clogs
release-1.21
dev/pabhoj/featurellm_fix_paste
dev/lhecker/grapheme-backup
dev/jadelaga/VS-Pty.netFixes
dev/lhecker/atlas-engine-compute-shader
dev/migrie/s/ai-providers
dev/lhecker/animated-cursor-wip
dev/pabhoj/featurellm_timeout
dev/lhecker/dark-mode-alt
dev/duhowett/osc-strided-table
dev/lhecker/bugbash
dev/pabhoj/featurellm_improve_parsing
dev/duhowett/coast-to-coast
dev/lhecker/curly-improvements
dev/duhowett/net8
dev/duhowett/onebranch-custom-pool
dev/lhecker/renderer-overhaul-2nd-attempt
dev/lhecker/cleanup
dev/cazamor/sui/confirmation-announcements
dev/lhecker/winconpty-cleanup
dev/duhowett/learn/rewrite-highlights
dev/migrie/b/no-nesting-when-searching
release-1.20
dev/duhowett/sel-2-spans
dev/lhecker/7118-cursor-color
dev/lhecker/remove-glyph-width
dev/lhecker/igfw-scroll-region
dev/lhecker/17656-win32im-double-encoding
dev/duhowett/fhl-2024/merge-idls
dev/duhowett/feed-forward-variables
dev/lhecker/remove-chrome-math
dev/duhowett/copylink
dev/duhowett/applicableactions
gh-readonly-queue/main/pr-17566-de50310295b7d92ed3d51f07974a2a945776bf9d
dev/lhecker/atlas-engine-stride-copy
dev/migrie/b/bump-nuget-in-c
dev/migrie/f/992-redux-redux
dev/migrie/f/filter-weight-input-too
dev/migrie/f/disable-nesting
dev/migrie/f/local-snippets-cleaner
dev/migrie/s/1553-mouse-bindings
selfhost-1.22-bugbash-2024-06-04
selfhost/1.22-bugbash-2024-06-04
dev/lhecker/15689-tab-drag-crash-fix
dev/migrie/f/sxnui-font-size-change
dev/migrie/f/local-snippets-on-action-refactor
dev/migrie/f/just-local-snippets
dev/migrie/save-input-patches
dev/migrie/f/md-pane-official
dev/migrie/base-pane
dev/migrie/fhl/tasks-pane
release-1.19
dev/migrie/b/17130-clear-marks-2
dev/migrie/b/17075-its-me-the-killer
dev/duhowett/i-figured-out-why-sometimes-the-publish-build-failed
dev/duhowett/nuget-publication-with-aad-app-id
selfhost-1.20
dev/duhowett/graph
dev/migrie/b/15803-activate-dont-copypasta
dev/duhowett/is-pgo-broken-because-of-sui-being-slower
dev/migrie/b/remove-terminaltab
dev/migrie/fhl/md-pane
dev/migrie/fhl/local-tasks-2024
dev/migrie/fhl/2024-inline-notebook
dev/duhowett/interface-projects
dev/duhowett/dead-loc
release-1.18
dev/migrie/fhl/2024-spring-merge-base
dev/duhowett/hax/l9
inbox
dev/migrie/14073-on-main
dev/duhowett/hax/conhost_dump_replay
user/lhecker/atlas-engine-srgb
dev/migrie/fhl/sxnui-tooltips-3
dev/migrie/7718-notifications-experiments
dev/migrie/fhl/7718-notifications
dev/migrie/fhl/7718-notifications-reboot
dev/lhecker/remove-gsl
dev/lhecker/16575-TerminateProcess
dev/lhecker/window-thread-climate-control
dev/lhecker/client-context-input-output-mode
dev/lhecker/ring-buffer-input-buffer
release-1.17
dev/lhecker/propsheet-fontdlg-refactor
dev/lhecker/renderer-overhaul
dev/pabhoj/test
dev/duhowett/chop
dev/lhecker/til-ulong-cleanup
dev/lhecker/til-env-cleanup
dev/migrie/f/16005-a11y-pane
dev/cazamor/a11y/fastpass
dev/migrie/b/15487-push-cwd
dev/migrie/b/15536-or-15219-idk
dev/duhowett/move-timers-down-into-core-interactivity-etc
dev/migrie/b/15812-broadcast-paste-two
dev/migrie/fhl-fall-2023/11162-quake-III-arena
dev/migrie/fhl-fall-2023/1620-automatic-tab-progress
dev/migrie/fhl-fall-2023/9992-quake-II
dev/migrie/fhl-fall-2023/9992-default-quake-settings
dev/migrie/fhl-fall-2023/9992-window-name-settings
dev/migrie/fhl-fall-2023/oceans
dev/lhecker/ColorScheme-improvements
dev/migrie/search-v2-v3
dev/migrie/pr-15717/its-dangerous-to-go-alone
dev/migrie/f/4768-taskbar-icons
dev/migrie/f/3121-tooltips
dev/duhowett/sticky-control
dev/duhowett/fix-tracing-2
dev/migrie/b/add-support-for-vsc-marks
dev/migrie/f/1860-this-is-literally-what-less-is-for
dev/migrie/s/5916-draft
dev/lhecker/tracy
dev/migrie/s/north-star
dev/cazamor/tag-youre-it
dev/migrie/f/12336-let-it-mellow
dev/migrie/f/now-with-more-compat-settings
dev/migrie/f/compatibility-sui
dev/duhowett/hax/wpf-atlas
dev/duhowett/fgb
dev/migrie/b/15487-relative-paths-are-hard
dev/lhecker/colrv1
loc-update
dev/migrie/fhl/dyndep-csharp
dev/migrie/fhl/dyndep
dev/migrie/fhl-clickable-send-input
dev/migrie/f/cwd-hijinks-5506-15173
dev/lhecker/openconsole-async-start
1.17
dev/migrie/bump-scratch
dev/migrie/f/3726-restartConnection
dev/migrie/b/cxn-restarting-attempt-1-backport
dev/migrie/b/9053-part-3-the-actual-doing-of-the-thing
dev/migrie/b/13388-focus-logger
dev/migrie/b/9053-part-4-i-guess-defterm
dev/migrie/oop/3/of-the-silmarils
of-the-darkening-of-valinor
dev/migrie/fhl/notebook-proto-000
dev/migrie/f/narrator-buddy
dev/migrie/mux-2.8.2-march-2023
dev/migrie/f/roast-mutton
dev/migrie/f/12861-preview-input
dev/lhecker/clang-tidy
dev/migrie/f/3121-wE-dOnT-hAvE-dEv-DaYs
dev/duhowett/compiler-compliance
dev/duhowett/i-have-a-burning-hatred-for-ntstatus-of-later-so-why-not-fix-it
dev/duhowett/shorthand-namespaces
dev/duhowett/rename-all-dlls
dev/duhowett/errordialog
dev/lhecker/gsl-narrow
dev/migrie/b/11522-dumb-idea
release-1.16
dev/miniksa/env
dev/duhowett/hax/embed-everything
dev/migrie/b/13388-attempt-003
dev/migrie/b/14512-test-research
dev/migrie/b/13388-attempt-002
dev/migrie/b/14464-copyOnSelect-moving-text
dev/migrie/s/thema-schema-for-1.16
dev/migrie/s/theme-pair-schema
dev/migrie/b/13388-experiments-1
dev/cazamor/spec/a11y-vt-seq
dev/migrie/b/14557-empty-folder-dropdown
dev/cazamor/spec/a11y-vt-seq-v2
release-1.15
dev/migrie/f/process-model-v3-test-0
dev/lhecker/vsconfig
dev/migrie/s/5000-presentation
dev/lhecker/5907-startup-perf
dev/lhecker/winrt-file-api-benchmark
dev/duhowett/128-bit-compiler
dev/migrie/fhl/more-shell-integration
dev/migrie/b/13388-experiments-0
dev/lhecker/til-to-ulong-improvements
dev/migrie/s/markdown-notebooks
dev/cazamor/a11y/nav-by-page
dev/cazamor/a11y/system-menu-support
dev/duhowett/no-private-registry-keys
dev/cazamor/wpf/uia-expose-enable-events
dev/cazamor/wpf/uia-events
extendAISpec
dev/migrie/fhl/clickSendInput
dev/migrie/fhl/save-command
dev/migrie/b/theme.profile
dev/migrie/b/13943-a-test-for-this
dev/migrie/oop/2/endgame
dev/duhowett/hax/merge_idl
dev/migrie/oop/2/infinity-war
dev/migrie/spellbot-cve
dev/cazamor/a11y-sev3/new-profile-announcement
dev/migrie/fhl/upside-down-mode
release-1.14
dev/migrie/f/9458-startupInfoToTerminal
dev/migrie/fhl/5916-triggers
dev/migrie/b/13523-context-menu
dev/migrie/b/6523-endpaint-outside-lock
dev/migrie/b/12413-OnUnhandledException
dev/lhecker/render-snapshot
dev/cazamor/1.15/scroll-to-point
dev/migrie/mux-2.8-aug-2022
dev/lhecker/lock-console-guard
dev/migrie/f/1504-final
dev/pabhoj/sui_follow_ups
dev/migrie/f/til-winrt.h
dev/cazamor/color-picker-redesign
dev/migrie/fhl/vscode-autocomplete-prototype
dev/migrie/f/1504-prototype
dev/migrie/oop/2/loki
dev/migrie/oop/2/wandavision
dev/migrie/b/8698-YOURE-OUT-OF-ORDER
fabricbot-configuration-migration
dev/migrie/b/12788-did-it-work
dev/migrie/b/localtests-ci-2022
dev/cazamor/1.14/replace-compareInBounds
dev/pabhoj/preview_string
dev/cazamor/ks/switchSelectionEndpoint
dev/migrie/oop/2/COM-ISwapChainProvider-attempt-1
dev/migrie/b/dxd-marker
release-1.13
dev/migrie/b/13066-for-defterm
dev/cazamor/revert-dwm
dev/migrie/b/13066-sw_flash_repeatedly
dev/migrie/b/no-cloaky-cloak
dev/migrie/f/apples-to-oranges
dev/migrie/f/no-custom-caption-btns
dev/migrie/f/10509-mica-and-transparent-titlebars
dev/migrie/b/12911-wpf-focus-fg
dev/migrie/titebar-colors
dev/lhecker/4015-cursor
dev/migrie/fhl/rgb-rainbow-window-frame
dev/migrie/fhl/scroll-marks-prototype
release-1.12
dev/miniksa/compliance
dev/migrie/f/default-icons
dev/migrie/fhl/10175-web-search-for-text
dev/migrie/fhl/menu-complete-prototype
dev/migrie/b/2988-merged-prototypes
dev/migrie/b/2988-niksa-msgs-prototype
dev/migrie/fhl/9583-colorSelection
dev/migrie/b/10609-sui-leak
dev/migrie/b/32-attempt-3
dev/migrie/release-1.12-rejuv-attempt-2
dev/migrie/demo-for-presentation
dev/migrie/b/32-but-im-here-for-12567
dev/duhowett/conpty_first_frame_blug
dev/migrie/b/11092-unfocused-acrylic-settings
dev/migrie/localtests-in-ci
dev/migrie/b/12356-attempt-2
dev/migrie/b/12353-with-null
dev/migrie/b/12387-trim-spaces
dev/migrie/b/5033-bad-start
dev/lhecker/12351-broken-locales
dev/migrie/b/8663-input-to-oem-crash
dev/migrie/b/11743-win10-opacity-is-hard
dev/migrie/f/ctrl-click-elevate
dev/migrie/b/12196-shim-localization
dev/lhecker/issue-4015-til-rect
dev/cazamor/eim/mvvm
dev/migrie/f/--elevate
dev/migrie/b/11668-i-think
dev/migrie/b/11994-wsl-mangline
dev/migrie/eim/3475-action-xmacros
dev/migrie/eim/incremental-build-000
dev/cazamor/a11y/fake-uia-data
dev/migrie/f/non-terminal-content-elevation-warning
dev/migrie/f/632-on-warning-dialog
dev/lhecker/rgba
dev/migrie/b/8480-keybindings-in-tabs
release-1.11
dev/migrie/b/11561-dead-ends
dev/migrie/oct-21-roadmap-update
dev/migrie/fhl/adaptive-card-extension
dev/cazamor/test/11440
dev/migrie/f/warning-dlg-automation
dev/migrie/b/1.12-crash-on-exit
dev/migrie/b/11146-next-tab-in-cmdpal
release-1.10
dev/migrie/5ff9a24-and-75e2b5f
dev/duhowtt/hax/cpal-jumplist-async
dev/lelian/actionid/1
dev/migrie/f/just-elevated-state
dev/lhecker/terminal-settings-cleanup
dev/migrie/gh-10824
dev/pabhoj/cursor_light
dev/migrie/oop/wandavision
dev/migrie/oop/endgame
dev/migrie/oop/infinity-war
dev/lhecker/app-state-actually-hidden
dev/migrie/b/6160-dynamic-default-warning
dev/mgirie/b/more-nchhittest-ideas
dev/migrie/b/9320-interfacial-separation
cinnamon/fhl/find-contextmenu
dev/lhecker/wsl-distro-generator-cleanup
dev/migrie/b/10875-but-more-clever
dev/migrie/b/broken-globalsummon-overloading
dev/duhowett/hax/rle-row
dev/migrie/fhl-2021/cmdpal-select-list
dev/migrie/fhl-2021/differential-pixel-shading
dev/duhowett/hax/no-writable-glyphat
dev/migrie/fhl-2021/more-shader-variables
dev/migrie/titlebar-shenannigans
dev/miniksa/win10_font_matching
dev/lhecker/conhost-oom
dev/migrie/b/10332-less-snappy-scrolling
dev/migrie/b/7422-1px-top-border
release-1.9
dev/cazamor/move-scratch
release-1.8
dev/miniksa/manifest_2
release-1.6
release-1.7
dev/migrie/oop/the-whole-thing
dev/migrie/oop/connection-factory
dev/migrie/f/quake-dropdown-2
dev/miniksa/rle2
dev/migrie/f/quake-toCurrent-experiments-2
dev/migrie/f/quake-toCurrent-experiments
dev/migrie/f/quake-dropdown
dev/cazamor/actions-page/template
dev/duhowett/hax/cursor_stamp_foreground_background
dev/migrie/f/1860-hey-might-was-well-hack-during-a-hackathon
dev/migrie/oop-terminal.control-split-control
dev/duhowett/hax/build-with-wholearchive
dev/cazamor/spec/tsm-actions-temp
dev/migrie/oop-tear-apart-control
dev/migrie/oop-scratch-3
dev/cazamor/sui/bugfix-reload-crash
dev/migrie/f/xmacro
dev/cazamor/sui/proto/profile-nav-view
dev/migrie/f/name-windows
dev/migrie/dol/messing-with-shaders-take-1
release-1.5
dev/cazamor/sui/inheritance-hyperlinks-test
dev/migrie/r/commandline-lib-002
dev/migrie/f/com.fabrikam.toaster
dev/cazamor/adaptive-cards-prototype
dev/migrie/f/commandline-lib
dev/miniksa/zipzoom2
dev/migrie/f/remote-commandlines
dev/migrie/f/632-elevated-profiles
dev/migrie/oop-broker-000
dev/migrie/fix-pr-7015
dev/duhowett/clang
dev/miniksa/input_tests_2
dev/miniksa/input2
dev/migrie/oop-rpc-000
release-1.4
dev/migrie/oop-mixed-elevation-1
dev/migrie/oop-window-content-1
cinnamon/open-json
dev/miniksa/input_tests
dev/duhowett/hax/tsm-graphviz
dev/miniksa/input
dev/duhowett/hax/caption_buttons
release-1.3
dev/cazamor/a11y/expand-line-under-viewport
dev/cazamor/acc/ch/word-nav-perf
dev/cazamor/spec/settings-ui-architecture-draft
dev/duhowett/hax/tap_upgrade
dev/migrie/f/pane-exit-animation
release-1.2
dev/migrie/move-lib-up-and-dll-down
release-1.1
dev/migrie/f/branch-2-backup
dev/migrie/f/settings-getters-only
dev/duhowett/hax/command_palette_search
dev/migrie/f/6856-let-terminalpage-expandcommands
dev/migrie/f/theming-2020
dev/migrie/oop-scratch-4
dev/duhowett/hax/punchout
dev/migrie/s/action-ids
dev/migrie/f/lets-just-generate-these
dev/migrie/oop-scratch-2
dev/miniksa/dcomp
dev/miniksa/gotta_go_fast_spsc
dev/miniksa/gotta_go_fast
dev/miniksa/perf_skip_checks
dev/miniksa/perf_buffer_dig
dev/migrie/s/1203-cursorTextColor
dev/migrie/f/fix-intellisense-i-guess-backup
release-1.0
dev/migrie/f/execute-commandlines
dev/migrie/f/2046-Command-Palette-v2
dev/migrie/b/6421-passthrough-alt
dev/migrie/b/moving-focus-is-hard
dev/miniksa/set
dev/migrie/f/1203-phase-1
dev/migrie/f/get-localtests-in-ci
dev/cazamor/drag-panes
dev/cazamor/tile-background
release-0.11
dev/duhowett/dev/duhowett/hax/appstate_remember
dev/duhowett/hax/wpf_win_8_hax
dev/migrie/b/3088-weird-exact-wrap-resize
release-0.10
dev/migrie/b/4591-custom-scaling-bug
dev/duhowett/hax/attr_smuggling
dev/migrie/b/5161-mingw-vim-fix
dev/miniksa/dx_bitmap
dev/migrie/b/1503-try-messing-with-cooked-read
dev/duhowett/eyebeam
dev/migrie/b/5113-experiments
dev/duhowett/hax-selection-exclusive
dev/migrie/f/more-vt-renderer-tracing
dev/miniksa/bitmap
dev/duhowett/wprp
dev/miniksa/bitmap-mad-with-power
dev/migrie/f/resize-quirk
dev/migrie/f/reflow-buffer-on-resize-002
wpf-renderer-revert
dev/miniksa/draw
release-0.9
dev/miniksa/tabs-color-fix
dev/miniksa/4309
dev/migrie/f/just-wrapping
dev/migrie/b/3490-try-another-resize-algo
release-0.8
dev/migrie/b/3490-a-simpler-resize
dev/migrie/b/3490-resize-down
dev/miniksa/4254
dev/migrie/f/conpty-wrapped-lines-2
dev/migrie/b/be-better-at-hiding
dev/migrie/f/3327-xaml-theming-proto
dev/miniksa/gardening2
release-0.7
dev/duhowett/conpty-flags
dev/migrie/f/603-vintage-opacity
dev/migrie/PR#3181-comments
dev/duhowett/font-64
release-0.5
dev/migrie/b/663-paste-lf-always
dev/migrie/b/2011-reordered-fallthrough-strings
dev/migrie/b/411-init-tab-stops
dev/migrie/b/json-patching-is-hard
dev/migrie/b/2455-try-getting-tests-working
dev/migrie/b/1223-change-256-table
dev/migrie/f/2171-openterm.cmd
dev/migrie/f/drag-panes
dev/migrie/f/2046-command-palette
release-0.3
dev/miniksa/manager
dev/migrie/f/non-terminal-panes
dev/migrie/f/passthrough-2019
dev/miniksa/shared_pch
dev/migrie/f/1897-less-duplicated-work
release-0.2
dev/cazamor/mcs/viewport-selection
dev/duhowett/version_hack
v1.25.1912.0
v1.24.11911.0
v1.25.1322.0
v1.24.11321.0
v1.25.1241.0
v1.25.1171.0
v1.25.923.0
v1.24.10921.0
v1.25.622.0
v1.24.10621.0
v1.24.10212.0
v1.23.20211.0
v1.24.3504.0
v1.23.13503.0
v1.24.2812.0
v1.23.12811.0
v1.24.2682.0
v1.23.12681.0
v1.24.2372.0
v1.23.12371.0
v1.23.12102.0
v1.22.12111.0
v1.23.11752.0
v1.22.11751.0
v1.22.11141.0
v1.23.11132.0
v1.23.10732.0
v1.22.10731.0
v1.21.10351.0
v1.22.10352.0
v1.23.10353.0
v1.22.3232.0
v1.21.3231.0
v1.22.2912.0
v1.21.2911.0
v1.22.2702.0
v1.21.2701.0
v1.22.2362.0
v1.21.2361.0
v1.21.1772.0
v1.20.11781.0
v1.21.1382.0
v1.20.11381.0
v1.21.1272.0
v1.20.11271.0
v1.20.11215.0
v1.19.11213.0
v1.20.10822.0
v1.19.10821.0
v1.20.10572.0
v1.19.10573.0
v1.20.10303.0
v1.19.10302.0
v1.18.10301.0
v1.20.10293.0
v1.19.10292.0
v1.18.10291.0
v1.18.3181.0
v1.19.3172.0
v1.19.2831.0
v1.18.2822.0
v1.19.2682.0
v1.18.2681.0
v1.18.1462.0
v1.17.11461.0
v1.18.1421.0
v1.17.11391.0
v1.17.11043.0
v1.16.10261.0
v1.17.1023
v1.16.10231.0
v1.15.3465.0
v1.16.3463.0
v1.15.2712.0
v1.15.2874.0
v1.16.2641.0
v1.16.2523.0
v1.15.2524.0
v1.15.2282.0
v1.14.2281.0
v1.14.1962.0
v1.15.2002.0
v1.15.2001.0
v1.15.1862.0
v1.14.1861.0
v1.14.1451.0
v1.14.1432.0
v1.13.11431.0
v1.13.10983.0
v1.12.10982.0
v1.13.10733.0
v1.12.10732.0
v1.13.10395.0
v1.12.10393.0
v1.13.10336.0
v1.12.10334.0
v1.12.3472.0
v1.11.3471.0
v1.12.2931.0
v1.12.2922.0
v1.11.2921.0
v1.11.2731.0
v1.10.2714.0
v1.11.2421.0
v1.10.2383.0
v1.10.1933.0
v1.9.1942.0
v1.9.1523.0
v1.8.1521.0
v1.9.1445.0
v1.8.1444.0
v1.8.1092.0
v1.7.1091.0
v1.8.1032.0
v1.7.1033.0
v1.7.572.0
v1.6.10571.0
v1.5.10411.0
v1.6.10412.0
v1.6.10272.0
v1.5.10271.0
v1.5.3242.0
v1.4.3243.0
v1.5.3142.0
v1.4.3141.0
v1.4.2652.0
v1.3.2651.0
v1.3.2382.0
v1.2.2381.0
v1.1.2233.0
v1.2.2234.0
v1.1.2021.0
v1.2.2022.0
v1.1.1812.0
v1.0.1811.0
v1.1.1671.0
v1.0.1401.0
v0.11.1333.0
v0.11.1251.0
v0.11.1191.0
v0.11.1111.0
v0.11.1121.0
v0.10.781.0
v0.10.761.0
v0.9.433.0
v0.8.10261.0
v0.8.10091.0
v0.7.3451.0
v0.7.3382.0
v0.7.3291.0
v0.7.3252.0
v0.6.3181.0
v0.6.2951.0
v0.6.2911.0
v0.5.2762.0
v0.5.2761.0
v0.5.2681.0
v0.5.2661.0
v0.3.2321.0
v0.4.2342.0
v0.4.2382.0
v0.3.2171.0
v0.3.2142.0
v0.2.1831.0
v0.2.1715.0
v0.2.1703.0
v0.1.1621.0
v0.1.1581.0
v0.1.1502.0
v0.1.1431.0
v0.1.1361.0
v0.1.1093.0
v0.1.1161.0
v0.1.1204.0
experiment-master
v0.1.1025.0
experiment-OutsideBuild
broken-tabstops
RS2-final
v0.1.1002.0
experiment-rel-windows-inbox
experiment-f-ServerApp
v0.1.1211.0
1904.29002
1810.02002
1708.14008
Labels
Clear labels
⛺ Reserved
A11yCO
A11yMAS
A11ySev1
A11ySev2
A11ySev3
A11yTTValidated
A11yUsable
A11yVoiceAccess
A11yWCAG
Area-Accessibility
Area-AtlasEngine
Area-AzureShell
Area-Build
Area-Build
Area-Chat
Area-CmdPal
Area-CodeHealth
Area-Commandline
Area-CookedRead
Area-DefApp
Area-Extensibility
Area-Fonts
Area-GroupPolicy
Area-i18n
Area-Input
Area-Interaction
Area-Interop
Area-Localization
Area-Output
Area-Performance
Area-Portable
Area-Quality
Area-Remoting
Area-Rendering
Area-Schema
Area-Server
Area-Settings
Area-SettingsUI
Area-ShellExtension
Area-ShellExtension
Area-ShellExtension
Area-Suggestions
Area-Suggestions
Area-TerminalConnection
Area-TerminalControl
Area-Theming
Area-UserInterface
Area-VT
Area-Windowing
Area-WPFControl
AutoMerge
Blocking-Ingestion
Culprit-Centennial
Culprit-WinUI
Disability-All
Disability-Blind
Disability-LowVision
Disability-Mobility
External-Blocked-WinUI3
Fixed
Gathering-Data
good first issue
HCL-E+D
HCL-WindowsTerminal
Help Wanted
Impact-Compatibility
Impact-Compliance
Impact-Correctness
Impact-Visual
In-PR
InclusionBacklog
InclusionBacklog-Windows TerminalWin32
InclusionCommitted-202206
Issue-Bug
Issue-Docs
Issue-Feature
Issue-Feature
Issue-Question
Issue-Samples
Issue-Scenario
Issue-Task
Needs-Attention
Needs-Author-Feedback
Needs-Bisect
Needs-Discussion
Needs-Repro
Needs-Tag-Fix
Needs-Tag-Fix
Needs-Triage
No-Recent-Activity
Priority-0
Priority-1
Priority-2
Priority-3
Product-Cmd.exe
Product-Colortool
Product-Colortool
Product-Colortool
Product-Conhost
Product-Conpty
Product-Meta
Product-Powershell
Product-Terminal
Product-WSL
pull-request
Resolution-Answered
Resolution-By-Design
Resolution-Duplicate
Resolution-External
Resolution-Fix-Available
Resolution-Fix-Committed
Resolution-No-Repro
Resolution-Won't-Fix
Severity-Blocking
Severity-Crash
Severity-DataLoss
spam
this-will-be-a-breaking-change
Tracking-External
WindowsTerminal_Win32
Work-Item
zAskModeBug
zInbox-Bug
Mirrored from GitHub Pull Request
Milestone
No items
No Milestone
Projects
Clear projects
No project
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: starred/terminal#6123
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @o-sdn-o on GitHub (Jan 23, 2020).
Environment
Steps to reproduce
In PowerShell type two wide emojis, move the cursor back (eg: ESC[nD) to place it on top of or between emojis, and then type a narrow character over it
or
copy and paste the following:
Expected behavior
"X" is placed as expected:

Actual behavior
The letter "X" is displayed incorrectly, moreover, emojis are unexpectedly shifted:

@o-sdn-o commented on GitHub (Jan 23, 2020):
When this is fixed, it will become possible to correctly wrap the text line that contains wide chars
like this:
instead of:

@DHowett-MSFT commented on GitHub (Jan 24, 2020):
Emoji cannot be split in half. Can you point to an example of a terminal that handles emoji in the way your "expected behavior" image reports?
Thanks!
@o-sdn-o commented on GitHub (Jan 24, 2020):
Thank you for your attension!
I do not know any terminal emulator that would correctly display this case, but I believe that Windows Terminal should do this correctly, unlike others, and others will need to focus on it.
That is why I believe that it is "expected behavior":
When a user prints a regular character with preliminary indication of the coordinates for displaying in a terminal window, he expects to see it in the cell with these coordinates, and he cannot know in advance that a wide character is located at these coordinates and take this into account before displaying a regular character.
Also, taking this case into account when rendering the contents of its buffer is in the interests of the terminal emulator itself.
Since the width of the terminal window, as well as the cursor coordinates, is a multiple of the width of an narrow character, and not the width of a wide character, then only one cell can remain on the right border for displaying a wide character, and the terminal, in case of line wrapping, requires or a way to depict the presence of half of a wide character in this single cell, and display the second half on the next line.
The terminal displays a Unicode Replacement Character "�", when wide emoji, like 😋, wrapped to the next line, unlike CJK (which are also wide char) that are entirely placed to the next line.
There is no need to operate on the emoji halves separately, the halves are obtained in the output process only in certain cases, such as line wrapping or overlapping text of another high-level object, such as a frame with the message text over the already displayed text.

In the screen buffer, wide characters are usually represented by two adjacent cells, and if one of these two cells is overwritten with a narrow character (as it should happen when the text cursor is positioned manually and its new position falls just over the wide character), then the rendering subsystem should determine a separate way of rendering such a combination of cells.
For instance,
A wide character is represented in the buffer as:
👨 = [subcell1] [subcell2]
note, both subcells should have a reference to the whole grapheme cluster "👨" or be it with the exception of some attribute - the first part or second part, or they are entirely equal, but the first cell has a width=2 and the second cell has a width=0, to distinguish between them.
Narrow character:
X = [normcell]
Two cases of the cell combinations in the buffer:
[subcell1] [normcell]
[normcell] [subcell2]
first, the rendering procedure should draw a whole wide character in its two occupied cells, and then draw a narrow character on top of the wide one, given its position - left or right.
@o-sdn-o commented on GitHub (Jan 24, 2020):
that's how it looks now

@o-sdn-o commented on GitHub (Jan 24, 2020):
In addition, it seems to me that the features of using DECDWL / DECDHL and friends (#1884, Line Renditions, Double-Width, Double-Height Line https://vt100.net/docs/vt510-rm/DECDWL.html) lie in the same plane as visualization of wide characters, and causes the same rendering difficulties, but there may be other distortions of the visual representation during the flow of text.
These cases may be implemented with the same approach, as well as the visualization of wide characters on a cell-based coordinate grid.
@DHowett-MSFT commented on GitHub (Jan 24, 2020):
I believe that the only correct way to handle a partial destruction of a double-width character is to remove the remaining half. There is no way for us to properly cut an emoji, or a CJK symbol that spans two cells, in half. Its meaning will be lost, and half of a character is not a unit that is representable in any encoding scheme or language.
RXVT-Unicode, which I believe set the standard for unicode use in terminals, treats your reproduction case as follows:
It doesn't support Emoji, but it does support a double-width glyph. Printing X over half of the double-width glyph destroys it.
The Windows Terminal currently has a bug where it does not destroy the double-width glyph. That, we should fix. I think it's tracked elsewhere, though.
@DHowett-MSFT commented on GitHub (Jan 24, 2020):
The same applies to wrapping wide glyphs. They just cannot be broken in half.
@o-sdn-o commented on GitHub (Jan 24, 2020):
Do I understand correctly that is possible to divide a wide character only by doubling the amount of memory allocated for one cell?
In that case, then the memory consumption can be neglected for the consistent visualization of all types of characters, since memory is not such a big problem these days, for example, tens of gigabytes of memory are needed only to compile the Windows Terminal.
@DHowett-MSFT commented on GitHub (Jan 24, 2020):
I'm not concerned about storage or memory for wide characters. I'm concerned about how half-glyphs are incomprehensible and do not mean anything, and there is no prior art for cutting an emoji or an ideograph in half. 😄
@o-sdn-o commented on GitHub (Jan 24, 2020):
It would be great to become pioneers 🚀 in this matter, since this problem exists.
No one cares about half glyphs, but text-based user interfaces cannot be rendered correctly without them in any way, and Windows Terminal is not least intended to display text user interfaces.
@o-sdn-o commented on GitHub (Jan 24, 2020):
It is also possible that at some point when glyphs with a width of three cells (e.g.: 👨👩👦👦 Family: Man, Woman, Boy, Boy) are needed to support any specific scripts or complex grapheme clusters, the problem will become even more obvious.
@o-sdn-o commented on GitHub (Jan 24, 2020):
I see no reason why the wide character should be completely destroyed when another symbol hits it.
I understand that it must be destroyed when copying the contents of cells with this state to the clipboard (until an Unicode standard will allow to form half glyphs by attaching the corresponding modifying codepoint), but such half cells in the terminal have full right to be displayed as is.
@DHowett-MSFT commented on GitHub (Jan 25, 2020):
I'd like to understand this scenario a bit more.
Consider an application drawing a UI over top of a two-cell character.
Consider the case of an application wrapping a two-cell character at the edge of the screen.
At the right side of my screen, I see:
and on the left, I see
It does not seem trivial as a human to (mentally) reconstruct a symbol from an ideographic language split and moved to the other side of the screen. It's a readability disaster, and no other application anywhere (even complicated word processors!) implements wrapping that breaks a character in half. I'm sure there's a very good reason why.
I think we need to let UI libraries, ones that operate on pixel buffers instead of cellular text buffers, solve this problem for graphical UIs and not try to add single-cell occlusion to terminals to bring them closer to word processors.
@DHowett-MSFT commented on GitHub (Jan 25, 2020):
(Thank you for taking your time to explain this!)
@o-sdn-o commented on GitHub (Jan 25, 2020):
I do not agree with this, Unicode allows you to visualize UI elements as exquisitely as never before before the Unicode era. now a huge number of graphic elements are available in the form of separate codepoints, which would be a big mistake not to use this and not to do sophisticated programs in text-based mode.
@o-sdn-o commented on GitHub (Jan 25, 2020):
An application offering a user interface naturally has its own buffer, which contains a picture of the world, and this application must duplicate all transactions in the terminal into this buffer, and moreover, changes to the buffer must be recorded taking into account that the terminal may not support half-characters and other functionality, e.g.: even if the terminal does not correctly handle character widths, the application may always emit an ansi-sequence to correct cursor coordinates after the printing of each potentially wide characters, despite the awarnes of terminal capabilities.
@o-sdn-o commented on GitHub (Jan 25, 2020):
Thank you for your clarification and for your work on the Windows Terminal, and I hope that my thoughts were at least a little useful 🙏🏻
@egmontkob commented on GitHub (Jan 25, 2020):
I'm mostly with @DHowett-MSFT on this.
No terminal I'm aware of supports half of a double-width character (half-CJK or half-emoji). When one half is overwritten, I believe most terminals explicitly replace the other half with a space (whether retaining its previous background color, or taking the currently active one, I have no clue).
In addition to that, when the cursor is at the rightmost column (i.e. there's still room for a final single character in the row) and a double wide is printed, the new double-wide character is placed entirely in the next line, leaving an empty cell at the end of the previous. Ideally this empty cell doesn't get copy-pasted, and disappears at a rewrap-on-resize; and similarly, if the CJK would cross the line boundary after the rewrapped position then it's placed entirely in the next line. Just like with every decent piece of software. (On a side note, this is one of the reasons VTE forces a minimum size of 1 row, 2 columns.)
If there is a need for supporting half-CJKs and half-emojis (which I'm unsure about), the partial overwriting approach shown above is problematic for multiple reasons.
It assumes that the other (the one overwriting half of a CJK/emoji) is a single-width one, for which I don't see a guarantee. If there's a need to display half characters, the need for displaying two halves next to each other can arise very easily. There would also be a need to display a right half in the leftmost column, or a left half in the rightmost column, which would be impossible (and is a natural requirement for a text editor with non-folding lines and horizontal scrolling).
It doesn't allow flicker-free updates: in order to replace the half-emoji with another one, the other character might shortly be replaced by the undesired other half of the emoji.
It makes it necessary to come up with a logic that is very unlikely to be compatible with the current thinking and implementation of screen drawing libraries (e.g. ncurses, slang...). Not only would they also need to support storing half-emojis in their internal buffers, they'd also need to construct non-trivial ways of transmitting them to the terminal. E.g. if the right half of an emoji is visible, they'd need to reprint the entire emoji first, then move the cursor back, and then print whichever character hides its left half (which again might be the right half of an emoji, and then continue backtracking...).
This all falls apart uncontrollably.
If there's a need to display half-emojis, a new escape sequence should be invented which allows to place a half-emoji anywhere, without affecting any other cell. It could perhaps be a new mode to SAPV, or some brand new sequence. Once we have it (with agreement of a couple of leader terminals), it's perhaps okay to change the overwriting mechanism too as part of this story, to keep the other half present upon a partial overwrite.
There'd be a couple of other tricky questions. E.g. what to do on a copy-paste (do you just simply copy it? and how do you make sure not to copy it twice if the entire emoji is visible, maybe emitted by a screen drawing library as separate left + right halves?). Or what to do on rewrap-on-resize, how to decide whether an emoji (or a matching pair of two half-emojis) are allowed to be separated to different lines or not? Would the terminal need to store somehow whether the two halves are joined or not; what escape sequences and what other actions would modify this state, and last but not least, do we see a reasonable chance that various major terminals would come to a conclusion here? I'm afraid not.
It's an interesting and really hard technical challenge if and how this could be solved, in a way that's not specific to just a terminal or two, but is likely followed by the entire ecosystem (most terminals, screen drawing libraries, utilities). A proper solution is sure much-much harder than just coding in WT for a couple of hours to keep the other half there :)
@o-sdn-o commented on GitHub (Jan 26, 2020):
use private codepoint (from Unicode Private Use Areas):
GCLPART: grapheme cluster left partGCRPART: grapheme cluster right partas a modifier character
(VT sequences are not suitable for copy-paste)
@egmontkob commented on GitHub (Jan 26, 2020):
How would it work? Prefix for a single following character?
What kinds of problems would it use that it's not an escape sequence, but a regular character?
Or wait, you said "modifier character", like VS16 and friends, so would it come after the base character? Then what if there's a pause in the input stream after the base character? The terminal displays the entire glyph, potentially overwriting something, or overflowing to the next line, in turn potentially scrolling the entire contents, and then a bit later oops it should change its mind, undo these and place only half of it? Clearly cannot work, the special treatment has to be known in advance.
Also, private use means private use, up for you to use it in-house for whatever you want; not for Microsoft or any similar party to start assigning it a value (let alone a control instuction, rather than a glyph).
There's a whole lot more to the story, like how would it be compatible with wcwidth() and similar methods of determining a glyph's width in the terminal, etc.
Trust me please, it's not an area where you, or me, or anyone could such easily come up with a good solution.
@o-sdn-o commented on GitHub (Jan 26, 2020):
like VS16. I suppose
If such a modifier appears first in the input stream the terminal should be triggered to text reflowing as in the case of window resize.
@o-sdn-o commented on GitHub (Jan 26, 2020):
So they need to add these modifiers to the Unicode Standard.
@o-sdn-o commented on GitHub (Jan 26, 2020):
to support double-height (DECDHL, 2x2 cells) characters use
which are preserve cwidth value of the base character.
@egmontkob commented on GitHub (Jan 26, 2020):
That's sure one possible way, with a couple of problems:
It wouldn't solve the problem that Unicode appends modifiers (becase they assume the text is available in its entirety, or it's okay to reprocess it if it changes). This model isn't suitable for the terminal, a terminal potentially needs to apply it retroactively without the possibility of replaying the previous events. If Unicode adds it as a suffix character, it hardcodes that terminals won't be able to support it.
Unicode hardly cares about the width in terminal, only has some weak hint that is sometimes ambiguous, sometimes changes over Unicode versions. Unicode's width model is already incompatible with what terminals and terminal-based applications expect, namely that the width of an entire string is always the sum of the width of the individual codepoints, VS16 breaks this and terminals have not yet figured out how to handle this. Anyway, if Unicode added such "left half", "right half" modifiers, they'd sure apply to all the glyphs, not just the double wide ones. And then one asks for half of a narrow glyph in a terminal, what to do?
It doesn't answer the copy-paste problem; and in the mean time introduces another surface for homoglyph attacks, e.g. the URL you see as "microsoft.com" might actually be "[left half of m][right half of m]icrosoft.com"
This approach would create tons new of problems and wouldn't solve anything in the Unicode world, and would solve certain things and create new problems in the terminal world.
There's no problem with Unicode, there's a problem with terminals right now. Trying to solve it in Unicode is in my firm opinion necessarily the wrong approach. The problem needs to be solved wherever it is: in terminals. That is, the solution is not new codepoints, the solution is new escape sequences.
A new escape sequence could switch to a mode where the following single character, or the following characters until the mode is switched off, are forced to a single cell, displaying the given half in case of double characters (but this might need to be further generalized, see below).
DECDWL/DECDHL themselves apply to entire lines, and as such they are utterly broken by design and useless, see e.g. VTE 195.
If there's a need for double-height or double-width (as in stretched) characters, it needs to go per-character, according to your proposal (maybe using brand new GCNWPART etc. escape sequences).
As you can see in Tilix 1782, some Unicode modifiers increase the width of a character in a way that it can be 4 or even more cells wide. Yet another sign of Unicode not caring about terminals, and terminals having no idea how to follow the specs they come up with. Another similar case is if a fixed variant (i.e. per-character) of DECDWL is invented: a horizontally stretched character which is double-wide to begin with becomes quadruple-wide. And if we allow these (i.e. units that occupy more than 2 cells horizontally), you'll need a solution for displaying any of its cells and only those, e.g. third or fourth or three fourths of such a grapheme...
Backwards compatibility is another important issue. It's unclear to me how to design an escape sequence that doesn't break in non-supporting terminals. A supporting and a non-supporting terminal (assuming that non-supporting ones silently ignore the escape sequence) need to advance the cursor by the same amount, even in special cases where the cursor is near one of the margins, otherwise subsequently printed text won't be displayed at the same location in them. If an app cannot reliably print either a half-emoji in supporting terminals, or a space (or preferably: an app-specified single-wide fallback character) in non-supporting terminals, it even significantly decreases the chance of apps caring enough to bother.
Realistically, I'm afraid all this is just too much work to fix (including not just multiple terminals but also ncurses and friends, and apps building on top of them), for quite small benefits, that it's unlikely to happen. Probably the terminal is just going to remain a platform that can display entire glyphs, and if only half of a glyph would fit than that glyph is entirely gone. If you need partial glyphs, graphical applications can do that for you (and a whole bunch of other things that terminals can't and won't ever).
@o-sdn-o commented on GitHub (Jan 26, 2020):
Thank you for your thoughts, everything is very clear, but let's dream a little, it would certainly be very cool to use such things in the terminals 😊
Of course, I imagined it much cooler until I drew 🤔
@o-sdn-o commented on GitHub (Jan 26, 2020):
Why?
When the selected area is copyed from the terminal, each halfed-cell that does not have an adjacent neighbor is appended with a half-modifier, otherwise it is replaced by a single whole character.
Such adjacent user-perceived characters should be replaced by the application as a whole as soon as possible (immediately after input from outside and before output), in the case when the application shows the user single glyph while internally represents it as a combination of two halves should be treated as application security bug. If an application does not know about such a Unicode standard, then it can't show the halves as a single whole.
The copy-paste activity is an area that is outside of the terminals.
Escape sequences are useless outside the terminal, so they break the copy-paste mechanics, unlike codepoint modifiers.
@egmontkob commented on GitHub (Jan 26, 2020):
By "the application" you pretty much every application in the world that supports Unicode (not restricted to terminal based ones), which would then have to be updated to your behavior. Absolutely hopeless.
Sorry if I wasn't clear, this sentence wasn't supposed to focus on copy-pasting, which is just a tiny part of the entire story. I meant this sentence for our main problem: half-cut CJKs and emojis. They are not a problem anywhere else, only in terminals. Trying to address this problem anywhere else (e.g. in Unicode) would create a giant headache for magnitudes more people than those who are affected by the problem in terminals. It's a wrong approach. Half-cut CJKs are a problem of the terminal world; if it is worth addressing at all (which I don't think is) then it should be addressed here, in the terminal world, not in some "upper entity". No one outside terminals wants or needs these.
@o-sdn-o commented on GitHub (Jan 26, 2020):
There are many modifiers in Unicode today that can corrupt glyphs, but no one forces them to use and corrupt CJK. The application that will claim Unicode Standard compliance should ensure that the incorrect use of this technique does not go beyond the application.
Absolutely not, because at the moment there are successfully running applications that do not know anything about Unicode, or if they aware, but don’t know all aspects of its appliance.
This can be done with the optional behavior of whether or not to copy-paste halves when copying a selected area of text or not. Let users decide what types of characters they want deal with outside the terminal.
@egmontkob commented on GitHub (Jan 26, 2020):
So you imagine that thousands (millions?) of apps out there, which let's assume support a future Unicode version 15, will then suddenly no longer be fully compliant when version 16 comes out, or not fully compliant with whichever UAX or whatnot; and will have to be updated to at least prevent those homoglyph attacks, have reasonable copy-pasting, etc. All this for the sake of fixing a rare problem in terminals. Thousands of developers will thank you for that. (No.)
But let's also mention again that currently in Unicode all the modifiers are suffix characters, whereas in order to fix the problem in terminals we'd definitely need a prefix one, a suffix modifier that decreases the width literally cannot be reliably handled when the input slowly arrives over a stream. What do you think the chances are of Unicode accepting such a proposal? I believe it's pretty much zero.
On one hand I find the Unicode approach technicaly a bad choice, on the other hand, even if decided to go for it, I don't see a reasonable chance for getting buy-in from the Unicode folks.
Anyway, I believe we have to agree to disagree at this point. We've shared out thoughts with each other, and continuing this discussion doesn't seem to take us any further.
[Disclaimer: I'm not a WT developer and I'm not affiliated with Microsoft, not commenting on their behalf.]
@o-sdn-o commented on GitHub (Jan 26, 2020):
Thanks so much for the in-depth discussion. This is a lot of valuable information.
@o-sdn-o commented on GitHub (Jan 26, 2020):
Another idea how to solve the problem of the allowing the screen drawing libraries (e.g. ncurses, slang ...) to display half characters to users.
Allow the terminal leaves the surviving half visible after splitting it, but only on the screen and only until the next repainting of the terminal window is occurred (text reflowing on some event of something else), and be sure to inform the application that all halves are “flushed”, and the application is responsible to reprint them (or whole screen) if they intended to do so.
Or, the application, at startup, tells to the terminal that the application itself is responsible for repainting entire terminal window when it is needed (by printing all screen lines, for example).
Some type of screen submode of the alternative screen buffer mode (CSI?1049h).
In this special mode, the terminal is not responsible to select text with the mouse, but must forward all mouse events to the application so that it takes care of the selection of text and placing data on the clipboard if the application provides for this.
Terminal should be responsible to emit VT-sequences to the application about the following data:
In order to be able to display the right half of the wide character along the left edge of the screen, it should be permissible to place the text cursor one character to the left of the left edge of the screen, location [y; 0]:- CUP (HVP) y; 0- CHA 0- CUB 1 from [y, 1] positionTo optimize application performance, the terminal is required to perform the following requests from the application:
@o-sdn-o commented on GitHub (Jan 27, 2020):
Your arguments are very convincing, and I agree in the sense that the decision to use Unicode modifiers is like shooting a sparrow from a cannon, however, I can’t agree that it will do much harm to anyone.
One way or another, this solution is not feasible at a given time.
I consider the proposal to use a special terminal mode to provide a narrow circle of libraries using the terminal window for rendering the user interface more real and effortless, as well as the experience of using this terminal screen mode in the future will clearly show the need for standardization of half modifiers in Unicode, so I'm going to do make feature request this new terminal functionality.
@egmontkob commented on GitHub (Jan 27, 2020):
First of all, your proposal allows to place half glyphs with limitations. E.g. there'd be no way to place a left half of X, followed by the right half of Y. What if an app distinguishes UI elements by different background colors, without an explicit character (e.g. line drawing) as borders, and two such items happen to be next to each other? If you need support for half glyphs, you need support for this, too. Also, screen drawing libraries need to know what to do if you create such a layout in their in-memory representation.
Second, I must point out that your proposal breaks plenty of things in terminal emulation:
The emulation behavior is right now the same on the normal and the alternate screen, several apps even offer the users to pick one, expecting identical behavior. With your proposal, the behavior would be different, and those apps that don't switch to the alternate screen would have no chance of achieving your desired layout. You can't suddenly make the behavior different without potentially breaking things.
You can't just say that moving the cursor to column 0 will no longer clamp it to column 1 but will actually move it offscreen, without worrying about breaking plenty of apps. You can't just say the counterpart of this for the right margin, either.
You can't just say that all apps on full screen will have to from now on handle mouse themselves, and you can't forbid terminals from doing their own copy-pasting (e.g. for Shift+mouse).
You can't suddenly change the existing model of how resize events are delivered, or how an application knows which parts to repaint.
and so on... Unix terminals carry a legacy of maybe 50-ish years, and at every step we have to be careful not to break things that were developed in this time. WT developers are in an much even harder situation, as they have to merge two different worlds without breaking anything. We have to be extremely careful with every step.
I'm sorry but I failed to understand this sentence, and I'm not sure where you're about to request this. In Unicode? If I fail to convince you not to push for your broken attempts then at least I sincerely hope that you'll point them to this discussion, so that they have a chance to read our (Dustin's and my) comments.
One of your screenshots shows Midnight Commander, an application I used to develop. It can use either the popular ncurses or the not-so-popular slang screen drawing library. I've been remotely following the development of these two libraries. There's not much happening, and they are really slow in catching up with changes of the terminal world. Even if terminals supported half glyphs, these libraries may not catch up for years (if not decades), and may even need backwards incompatible changes, I'm not sure about that. And then whichever app (e.g. mc) would also need to add support, which, given how its development goes, is again extremely unlikely. Before going ahead, it wouldn't hurt to hear a buy-in from these involved people, which at the very least requires the feature to be implemented by several popular terminals, which, in turn, definitely needs the feature to be well designed. The terminal world has way more popular and technically way easier features that are still not supported by many terminals, as well as these libraries.
It's an enormous amount of work to fix half-emojis, with necessary buy-in and coordination among many parties. It's extremely unlikely to happen. And even if it happens, it won't happen the way you think should, but the way experienced developers of the ecosystem will together design it.
To begin with, from the terminal's point of view, N years of experience with developing a terminal as well as bits of the surrounding infrastucture, I can assert you that the only reasonable way to start is to forget about changing Unicode, and go for an escape sequence that does one and exactly one thing and nothing else: prints a half-character somewhere.
Let me also tell you that N years of developer experience tells me that the terminal ecosystem has way more important problems to fix than this one. Also, fixing this problem would require multiple parties to care as much as you do, which I firmly doubt will happen.
I've been keep an eye on the bugtracker of many terminals and some terminal-based apps, as well as various public forum for years. I haven't come across any report about half-CJKs. It's not something Chinese/Japanese/Korean folks really care about, or really wanted to fix (or maybe they do prefer to see a space rather than a half-glyph? could be, I don't know).
[And finally allow me one comment that is not professional but personal:
Widespread use of emojis made this technical problem more prominient for a much larger user base. For me, the terminal is a tool for getting work done. It's not for playing games, it's not for watching videos, it's not really for having fun, and (some might disagree with me) it's not really for browsing the web, handling e-mail etc. either. There are other great tools for those purposes. In order to get things done (i.e. typical developer and sysadmin tasks), I couldn't care less about emojis.]
@o-sdn-o commented on GitHub (Jan 27, 2020):
My point is that the moment has come when terminal emulators require a certain special mode of operation for the correct presentation of text user interfaces, this is primarily due to the fact that emojis, CJK and many other unicode ones came to the world of terminals. And these things are very difficult to push into the world of terminals, which was formed decades before.
GUIs are always haviest stuff, but TUIs are much lighter, and if the terminals would provide convinient functionality/framework for building TUIs on it, this will be a big leap forward in terms of user experience in cases where using the GUI is impossible or impractical for some reasons.
@egmontkob commented on GitHub (Jan 27, 2020):
I wouldn't call displaying a half emoji, when there's no room for the entire one, instead of showing a space, a "big leap". I'd call it perhaps a minor cosmetic improvement, maybe even a questionable one (some people might prefer not to see glyphs cut in half).
Pair it with up with the fact that it's an enormous task to fix it. It needs a technical solution which has to be discussed, evaluated wrt. backwards compatibility, feasibility of implementation and whatnot. And then it needs to be implemented in many terminals (of which most likely hardly any cares), couple of libraries (presumably none of which cares), followed by each and every single application that cares.
I'm not saying I don't want this to happen. I'm saying I'm pretty sure it won't happen. You're the first person I hear caring about this story. You might find this important, others probably don't.
@o-sdn-o commented on GitHub (Jan 27, 2020):
I don’t mean right now about half-characters, I mean, on the whole, the problem of displaying wide, complexly designed glyphs, working with the visible surface in the manner of graphic applications as a result of the possibilities of using true-color and various fonts at the same time. But all this graphic variety is strictly within the TUI.
@o-sdn-o commented on GitHub (Jan 28, 2020):
Character segmentation and scaling
This technique allows to work with characters ranging in size from 1 to 4 cells along both coordinate axes.
It doesn’t matter what size (cwidth) the character has, it allows put a wide character to a single cell if you want.
It is also possible with this technique to print out mathematical expressions and multi-level formulas (monospaced text documents with formulas, CJK, wide emoji and so on - are the Unicode problems that outside terminal world).
@o-sdn-o commented on GitHub (Jan 29, 2020):
Discussion is moved to the Terminals Working Group\Specifications\Issues.
click to expand...
Character Segmentation and Scaling (Fractaling)
1. Abstract
This paper provides a general description of the solution to the problem of presenting and processing multi-sized (up to 4x4 cells) characters in a cell-based grid, where each cell one-to-one represents the visilbe part (fraction) of the character.
The following applications are related to multisize characters and character segmentation:
The solution allows to manipulate and store individual fractions of the whole character in a single cell for displaying them, as well as displaying multi-size characters in a cell-based grid and even allow their vertical splitting.
The solution also solves the problem of displaying wide characters in terminals by letting the terminal or the application running in it decide how wide the character will be, rather than relying on external data sources of these values that are subject to regular changes.
2. Solution
2.1 Definitions
Accordingly to the Unicode® Standard Annex #29, "UNICODE TEXT SEGMENTATION"
This paper defines a character as user-perceived character (or grapheme cluster).
2.2 Mathematical Presentation
To correctly display either a whole character of any size (up to 4x4 cells) or any selected character segment, only four numeric parameters
Ps=Dx,Nx,Dy,Nywith range values of each from 1 to 4 are required.Parameters
Dx- count of parts along X-axisNx- either width of the whole character or segment selector of theDxavailable parts from left to right along the X-axisDy- count of parts along Y-axisNy- either width of the whole character or segment selector of theDyavailable parts from top to bottom along the Y-axisInterpretation
There are several cases possible (for each axis accordingly)
D = 0N <= DNof the character fromDavailable parts and use it as a sinle-cell character (along the corresponding axis).N > D AND D = ANYNcells.2.3 Storing In Memory
Screen Buffer / Monospaced Text File
Each multisize character with a size of
n x mthat is greater than1x1is stored in the screen buffer (or monospaced text file)W x Has a matrix ofn x mExample:
3x2 stretched character
"A"is located atx=3, y=2in the screen buffer (of monospaced text file)Pscan be packed in one byte and overhead of screen buffer is 1 byte per cell:Also there are only 256 variants for the Unicode modifier character value 0 - 255.
Characters with parameters
N > Dare not allowed to be stored in a cell-based grid. When such a character is to be printed to the grid, it must be segmented for each grid cell, and the parameters are recalculated for each filled cell.2.4 Naming
2.4.1 VT-Sequence
Variants of the name for the VT-sequence
2.4.2 Unicode Standard
Name of the Unicode modifier letter
3. Usage
3.1 Unicode Standard
Latest Unicode Standard defines three types of variation sequences:
Only those three types of variation sequences are sanctioned for use by conformant implementations.
Accorginly to the Standardized variation sequences FAQ
Accodingly to the Section 23.4, Variation Selectors, UTR #25
Variation Sequence
Placement in the Text
If such a modifier appears the first in the input stream the terminal should be triggered to text reflowing as in the case of window resize.
3.2 VT-Sequence
XTerm Control Sequences, Functions using CSI
Assing VT-sequence as a CSI/SGR command, because it define characters rendition state and sets the appearance of the following characters.
n1,n2,n3,n4are from 0 to 4.n1 = Dx,n2 = Nx,n3 = Dy,n4 = Ny.P = (Nx-1) + (Dx-1) * 4 + (Ny-1) * 16 + (Dy-1) * 64from 0 to 255.110: missing numbers are treated as 1.111: missing number is treated as 0.ESC[m(all attributes off) also resets the scaling mode.110,111suggest...yours.4. Expected Behavior
It doesn’t matter what size (cwidth) the character has, it allows put a wide character to a single cell if you want.
4.1 Unicode Standard
4.2 VT-Sequence
4.2.1 Printing
Output examples (VT sequence <SCALE;;;>)
It is also possible with this technique to print out mathematical expressions and multi-level formulas (monospace textual documents with formulas, CJK, wide emoji and so on - are the Unicode problems that outside terminal world).
Line Wrap
Side effects
4.2.2 Capturing
5. Applications
5.1 Cost of Initial Implementation
6. Existed Infrastructure Compatibility
7. Security Issues
7.1 Unicode Security Considerations
Unicode Technical Report #36
This section describes some of the security considerations that programmers, system analysts, standards developers, and users should take into account.
For example, consider visual spoofing, where a similarity in visual appearance fools a user and causes him or her to take unsafe actions.
@jerch commented on GitHub (Jan 31, 2020):
@o-sdn-o Can you open an issue in terminal-wg? This way more terminals devs will see it and it can be dicussed more in detail.
Some early remarks from my side:
As @egmontkob already pointed out - we have several issues with newer unicode rules in general in the terminal. While up to unicode 8 the simple
wcwidthapproach worked for most things (minus BiDi), the newer unicode versions introduced several new rules, that are not quite terminal environment friendly:Among these issues the question whether a n-wide user percieved character can be split into n parts seems to be a minor detail. Until we have not fixed the basics it is hard to think about further extensions or alternate behavior.
Currently all terminals follow a common behavior here for n=2 (wider clusters were no issue until cluster rules took place) at the end of the row: if DECAWM (auto wrap) is set, the wide char would reflow to the next line early, otherwise it gets not printed (stays blank). Erasing an east asian wide char would actually clear two cells in most terminals.
Also note that your suggestion might not work with every terminal/render engine (not every terminal does the rendering on its own, technical level). Also to me it feels weird to be able to split those chars up (semantical level).
@DHowett-MSFT commented on GitHub (Jan 31, 2020):
Thank you all for the very lively and very interesting discussion. I think @jerch is correct: the right place to continue talking about this is the Terminal working group.
@magiblot commented on GitHub (Oct 28, 2021):
Excuse me for reviving this issue, but why all the fuss? The well-known Konsole terminal emulator has supported emoji left halfs for as long as I can remember, and I even took advantage of it in my Turbo Vision library:
https://user-images.githubusercontent.com/20713561/139157133-ce40a0fc-72c2-4166-bade-ca4d11c262ea.mp4
And unlike what has been said before, supporting this didn't require introducing a new escape sequence, extending the Unicode standard, buy-in and coordination among many parties, updating existing applications to prevent attacks or doing backwards incompatible changes (considering that the Turbo Vision API dates from the 90's). It was not an enormous task either, and it relies on whichever
wcwidthis available on your system.Of course, there are some edge cases that will never be supported this way: drawing a right half in the leftmost column, or a left half in the rightmost column, or a left half next to a right half, but none of these are necessary for what the OP initially suggested.
If Konsole supports left halfs, it is reasonable to request that Windows Terminal also does so. Not only that, but if left halfs are supported, support for right halfs is probably also feasible.
Note that while I think this, I also believe that Terminal's developers are free to decide they don't want to spend time on this and their decision shall be respected.
Cheers.
@o-sdn-o commented on GitHub (Oct 28, 2021):
If a certain terminal emulator is limited only by the functionality of a text file viewer, then it is enough just to be able to display the left half.
If the terminal emulator wants to support raster operations on cell-based canvas, then it is forced to store/input/output glyph fragments, since currently glyphs have an arbitrary size in cells, and it depends more on the font used than on any standard ... Hence, it makes sense to discuss the format for representing a glyph fragment. The ability to store fragments will allow you to set the width of the glyph in cells, this can be done in exactly the same way as setting the foreground/background color, for example. It also solves the problem of setting the width of glyphs of arbitrary width, such as the "Family" emoji or a four-cell wide Devanagari syllable.
@jerch commented on GitHub (Oct 28, 2021):
Then you rely on an implementation detail of
konsole, that will fail on most other TEs. The "fuss" is/was needed to clarify, if it makes sense to get TEs into strict cell by cell drawing with half glyph rendering. While I understand the reasoning behind this, I dont follow the idea on a semantic and technical level. For the latter - some TEs dont control glyph rendering themselves, thus have no saying in this regard, the font renderer would just do as it pleases. The semantics are tricky as well - making such a mode the default one would change a well-established behavior for wide chars at the right border, thus is a no-go. Only chance I see here is an opt-in, maybe via a separate sequence as indicated by @egmontkob.@o-sdn-o commented on GitHub (Jul 19, 2024):
For the record and if anyone else is interested in this. Built-in vtm terminal (
vtm -r term) as an example of such a GUI terminal.2x1 character samples:
3x1 character samples:
Special tailoring has been applied here (can be automated on the terminal side):
U+00002Grapheme cluster begin.U+D0138Characted matrix selector as a grapheme cluster end (matrix width=3 and height=1 cells).In general, table values of character matrix selectors are used (up to 16x4 cell matrix):
Characted matrix selector table:
https://github.com/directvt/vtm/blob/master/doc/images/vtm_character_geometry_modifiers_16x4.png
As a result, we get the following things in a text environment:
Complex scripts support, including RTL:

Various text transforms:
