Compare commits

..

1276 Commits

Author SHA1 Message Date
Kovid Goyal
68cd863fe0 version 0.22.1 2021-07-31 12:03:42 +05:30
Kovid Goyal
65e5015d19 Allow linking to discussions in docs 2021-07-31 11:51:03 +05:30
Kovid Goyal
c26665ec4d Wayland: If the compositor turns off server side decorations after turning them on do not draw client side decorations
This matches the behavior of GNOME based clients and in any case sway
seems to get very confused if CSD is drawn.

Fixes #3888
2021-07-31 11:41:27 +05:30
Kovid Goyal
91d82ebf4b Remove unused import 2021-07-31 11:27:29 +05:30
Kovid Goyal
303e4baa58 Add GLFW API to set WM_COMMAND
Also have create_os_window take keyword arguments
2021-07-30 08:35:40 +05:30
Kovid Goyal
3c953d47ca Merge branch 'pr-fix-nix' of https://github.com/egnor/kitty 2021-07-29 14:23:08 +05:30
Kovid Goyal
5e629d5c09 Linux binary: Remove any RPATH build artifacts from bundled libraries
Thanks to Dan Egnor for pointing these out.
2021-07-29 13:12:49 +05:30
Kovid Goyal
c6ec2d4282 Update docs to reflect the fact that the shell is run with both --login and --interactive to read its env vars 2021-07-29 12:40:19 +05:30
Kovid Goyal
66b93a9af8 Merge branch 'pr-doc-editor-fix' of https://github.com/egnor/kitty 2021-07-29 12:24:17 +05:30
egnor
8d5479f55e minor tweaks to wording and formatting 2021-07-28 23:50:11 -07:00
egnor
96ce6c9504 Resolve some duplication in glossary.rst 2021-07-28 23:47:55 -07:00
egnor
0d55865545 more accurately describe editor behavior 2021-07-28 23:44:09 -07:00
Kovid Goyal
a1fc383e6f Cleanup the previous PR 2021-07-29 11:52:14 +05:30
Kovid Goyal
c3807e175d Merge branch 'pr-doc-editor' of https://github.com/egnor/kitty 2021-07-29 11:48:34 +05:30
Kovid Goyal
6f83f76d41 Make reading shell environment a bit more robust
Now ensure that --login flag is not duplicated. Also
run the shell in --interactive as well as --login mode.
2021-07-29 11:12:09 +05:30
egnor
9a56d619af clarify the text for the "editor" config variable slightly 2021-07-28 22:18:03 -07:00
Kovid Goyal
f692d586f7 Fix type checking in send_text 2021-07-29 09:04:07 +05:30
Kovid Goyal
d3d3e99979 broadcast kitten: Fix decoding of key events
No clue why mypy didnt catch this error
2021-07-29 08:55:34 +05:30
egnor
8e6a179efe fix shell.nix error with stdenv.lib.getLib 2021-07-28 17:16:52 -07:00
Kovid Goyal
17ff317d30 Allow specifying additional targets for detach_window 2021-07-28 21:50:09 +05:30
Kovid Goyal
faef9f0049 ... 2021-07-28 21:27:43 +05:30
Kovid Goyal
bb0c831601 Fix #3878 2021-07-28 18:22:08 +05:30
Kovid Goyal
9462654738 Update changelog 2021-07-28 15:52:54 +05:30
Kovid Goyal
e872169e4c Graphics protocol: Fix composing onto currently displayed frame not updating the frame on the GPU. Fixes #3874 2021-07-28 15:46:50 +05:30
Kovid Goyal
a22404abe6 Better names 2021-07-28 15:44:17 +05:30
Kovid Goyal
7c06313750 A couple more useful aliases 2021-07-28 15:40:48 +05:30
Kovid Goyal
6f265f448d DRYer 2021-07-28 15:39:21 +05:30
Kovid Goyal
acdc41bd03 Allow sending no payload 2021-07-28 13:39:15 +05:30
Kovid Goyal
bcff2a7fb6 Add aliases to GraphicsCommand to make it more useable 2021-07-28 13:28:21 +05:30
Kovid Goyal
94188fddce pep8-ify sample code 2021-07-28 11:13:29 +05:30
Kovid Goyal
3684e7f54a Merge branch 'cocoa-fix-m1' of https://github.com/horta/kitty 2021-07-28 07:45:50 +05:30
Danilo Horta
890181172f Fix "Cocoa: Failed to find service port...". 2021-07-28 00:39:50 +01:00
Kovid Goyal
9c9d68561e When calling the active tab idx setter do not re-record the current tab in the active tab history if the current tab will not actually change. Fixes #3871 2021-07-27 09:12:35 +05:30
Kovid Goyal
1bd39ff935 Use new URL scheme and define the kitty website centrally as much as possible 2021-07-27 09:03:11 +05:30
Kovid Goyal
17f3d2d581 DRYer 2021-07-27 08:44:50 +05:30
Kovid Goyal
55aa9e11db Dont use globals for role mapping 2021-07-27 08:39:04 +05:30
Kovid Goyal
bc895eacc5 Also prevent unknown roles from causing formatting to error 2021-07-27 08:07:11 +05:30
Kovid Goyal
6c8eb4a19a Fix #3869 2021-07-27 08:05:55 +05:30
Kovid Goyal
887347106d version 0.22.0 2021-07-26 13:57:09 +05:30
Kovid Goyal
419cf78984 A new remote control command to resize OS Windows 2021-07-25 22:57:00 +05:30
Kovid Goyal
aa339a8a9f Expose parameter in boss.py as well 2021-07-25 13:59:36 +05:30
Kovid Goyal
a2f7aedd9c Allow specifying which os window to toggle 2021-07-25 13:58:03 +05:30
Kovid Goyal
630379651e Use union instead of define for graphics commands aliases 2021-07-25 13:14:52 +05:30
Kovid Goyal
3d9b52fbc2 Functions to get and set OS Window size 2021-07-25 12:58:58 +05:30
Kovid Goyal
2e01c1f37e Wayland: Inform compositor of new window geometry when setting window size 2021-07-25 12:26:09 +05:30
Kovid Goyal
174abb352c Fix broken link 2021-07-24 08:29:25 +05:30
Kovid Goyal
85e028cab1 Add links to kitten source code 2021-07-24 08:15:52 +05:30
Kovid Goyal
ff191c9404 clipboard kitten: fix copies to clipboard not working without the --wait-for-completion option 2021-07-24 07:55:50 +05:30
Kovid Goyal
31da01d4df Add clipboard_control to query_terminal 2021-07-24 07:26:12 +05:30
Kovid Goyal
6d45a94125 Always ignore truncated OSC 52 2021-07-24 07:19:58 +05:30
Kovid Goyal
e7bfb04047 Fix mouse actions not working when caps lock or num lock are engaged
Fixes #3859
2021-07-24 07:06:46 +05:30
Kovid Goyal
b9033d721c print KeyPress on a new line 2021-07-24 07:02:52 +05:30
Kovid Goyal
41c0343d33 macOS: Fix automatic detection of bold/italic faces for fonts that use the family name as the full face name of the regular font not working
Fixes #3861
2021-07-23 23:06:42 +05:30
Kovid Goyal
aa8156a7fd Remove mentions of no-append 2021-07-23 22:28:34 +05:30
Kovid Goyal
e48adf7a07 Allow leading/trailing spaces in tab_activity_symbol 2021-07-23 22:26:10 +05:30
Kovid Goyal
8f214c51c0 Get rid of kitty's special OSC 52 protocol
A better solution from an ecosystem perspective is to just work with the
original protocol. I have modified kitty's escape parser to special case
OSC 52 handling without changing its max escape code size.

Basically, it works by splitting up OSC 52 escape codes longer than the
max size into a series of partial OSC 52 escape codes. These get
dispatched to the UI layer where it accumulates them upto the 8MB limit
and then sends to clipboard when the partial sequence ends.

See https://github.com/ranger/ranger/issues/1861
2021-07-23 22:18:02 +05:30
Kovid Goyal
096c4c78c7 Fix #3856 2021-07-23 08:13:47 +05:30
Kovid Goyal
257fce5a1b Merge branch 'dankamongmen/triangle-wrangle' of https://github.com/dankamongmen/kitty 2021-07-23 08:09:25 +05:30
nick black
182bc7b8f9 U+1fb3f: upper middle left to lower right 🭊🬿 2021-07-22 18:21:57 -04:00
Kovid Goyal
3c35999246 Fix code scanning warning 2021-07-22 22:08:55 +05:30
Kovid Goyal
340159b591 Graphics protocol: Support for frame composition
Fixes #3809
2021-07-22 18:58:59 +05:30
Kovid Goyal
075fb2eaf2 DRYer 2021-07-22 17:56:21 +05:30
Kovid Goyal
21a2768ec3 ... 2021-07-22 17:31:54 +05:30
Kovid Goyal
554c840d4e ssh kitten: exit with 255 for unknown arg to match ssh 2021-07-22 17:30:07 +05:30
Kovid Goyal
9c28a1ba31 ssh kitten: handle -- 2021-07-22 17:03:47 +05:30
Kovid Goyal
13fc921fa5 Dont hardcode the ignore path for sphinx-autobuild 2021-07-22 11:03:13 +05:30
Kovid Goyal
61f5d3972f Dont use scrollIntoView as it causes the main content to scroll as well 2021-07-21 16:39:57 +05:30
Kovid Goyal
5027bc743b Mark sidebar toc entry corresponding to current hash
Also scroll it to the top on initial page load
2021-07-21 14:41:01 +05:30
Kovid Goyal
9b8085220f ... 2021-07-21 14:16:53 +05:30
Kovid Goyal
54c04301cc Use html_css_files instead of add_css_file 2021-07-21 13:12:32 +05:30
Kovid Goyal
cfd3bc823c ... 2021-07-21 12:36:55 +05:30
Kovid Goyal
329d95fd3a Include all in page headings in the sidebar ToC
The furo theme tries to make this impossible, fortunately,
this being python, we dont care what it wants
2021-07-21 10:35:58 +05:30
Kovid Goyal
8dfef58f29 Use a glfw specific name for memfd_create 2021-07-20 21:49:11 +05:30
Kovid Goyal
eeb4d3fe55 Dont show individual tools in the page toc 2021-07-20 14:39:52 +05:30
Kovid Goyal
c6da4576b6 ... 2021-07-20 14:37:31 +05:30
Kovid Goyal
2417122ed3 Make the integration tools link targets 2021-07-20 14:28:44 +05:30
Kovid Goyal
e6c17e19d7 Turn on nitpicky in makefile rather than conf.py 2021-07-20 13:57:58 +05:30
Kovid Goyal
d98c2f89aa When redirecting preserve anchors 2021-07-20 13:51:50 +05:30
Kovid Goyal
624991b9b7 Use the builtin envvar role for env vars
Also fix some broken links
2021-07-20 13:29:39 +05:30
Kovid Goyal
c7ee776349 ... 2021-07-20 13:21:45 +05:30
Kovid Goyal
ffeacef394 Document the various env vars kitty uses/sets 2021-07-20 13:19:23 +05:30
Kovid Goyal
f4ebec6759 The graphics protocol spec should link to POSIX not the linux man page 2021-07-20 09:51:15 +05:30
Kovid Goyal
93e3e4d2b1 Also strip \r from marked text 2021-07-19 18:12:29 +05:30
Kovid Goyal
3633049ba5 Forgot to include \r in the url regex 2021-07-19 18:09:00 +05:30
Kovid Goyal
c566ed4643 hints kitten: Detect paths and hashes that appear over multiple lines
Fixes #3845
2021-07-19 17:35:48 +05:30
Kovid Goyal
af956f4d84 Fix debug print for long strings 2021-07-19 16:56:10 +05:30
Kovid Goyal
b70c72fc3b ... 2021-07-19 13:45:20 +05:30
Kovid Goyal
1f35694705 Render ┄ ┅ ┆ ┇ ┈ ┉ ┊ ┋ with spaces at the edges
Matches rendering in most other programs and allows long chains of them to look better

Fixes #3844
2021-07-19 13:42:59 +05:30
Kovid Goyal
d912d96f00 More docs cleanups 2021-07-19 09:08:55 +05:30
Kovid Goyal
94f8fb4a4b Cleanup up some doc formatting 2021-07-19 08:45:56 +05:30
Kovid Goyal
103744e2ca Note the changed docs build requirements 2021-07-19 08:32:39 +05:30
Kovid Goyal
fe18a5de92 Use a shorter title 2021-07-18 22:19:47 +05:30
Kovid Goyal
9b0394860d typo 2021-07-18 19:56:06 +05:30
Kovid Goyal
380c7628d8 Use tabs for C/Python code samples 2021-07-18 13:43:26 +05:30
Kovid Goyal
f787a377c3 A new theme for the kitty website
Supports dark mode. Also re-organize the documentation
a bit, making it more hierarchical.

Have a nicer landing page
2021-07-18 13:29:33 +05:30
Kovid Goyal
7c1b819728 Use nicer URLs without .html suffix on website
Also easier insertion of analytics tag for the website without
needing a custom template.

The old .html URLs are redirected via meta http-equiv refresh, which is
all gh-pages supports
2021-07-17 21:25:29 +05:30
Kovid Goyal
8e5175e56b Revert "icat: Use scandir for slightly better performance"
This reverts commit 2e893690bd.
scandir is not recursive
2021-07-17 09:51:06 +05:30
Kovid Goyal
9e9d1a4e96 Add a glossary to define some commonly used terms in kitty 2021-07-17 06:36:56 +05:30
Kovid Goyal
fd475423cf Fix reference to option in changelog docs 2021-07-17 06:30:48 +05:30
Kovid Goyal
070911d458 Wayland: Fix initial_window_size in cells on scale != 1 screens
Fixes #3834
2021-07-17 06:04:56 +05:30
Kovid Goyal
3b585e6dbb Fix #3840 2021-07-17 05:46:08 +05:30
Kovid Goyal
2e893690bd icat: Use scandir for slightly better performance 2021-07-16 21:55:15 +05:30
Kovid Goyal
d052b020fa Check for dirs when getting mimetypes in a couple more places 2021-07-16 21:49:02 +05:30
Kovid Goyal
ac6224563b Cleanup previous PR 2021-07-16 21:43:56 +05:30
Kovid Goyal
a9630890fd Merge branch 'folder-mime' of https://github.com/william-gooch/kitty 2021-07-16 21:40:14 +05:30
Kovid Goyal
4b889750db Add a new variable `{num_window_groups}` for tab_title_template
See #3837
2021-07-16 19:25:24 +05:30
William Gooch
308bd0d81d Directories should have mime-type inode/directory. 2021-07-16 13:40:00 +01:00
Kovid Goyal
d55a86e39b Cleanup icdir creation 2021-07-13 08:00:15 +05:30
Kovid Goyal
0c193c3ab7 Merge branch 'add-icons' of https://github.com/Artturin/kitty 2021-07-13 07:57:27 +05:30
Artturin
6f513f5706 linux: install a scalable icon 2021-07-13 05:10:15 +03:00
Kovid Goyal
368bc91eed macOS: Render colors in the sRGB colorspace to match other macOS terminal applications
Fixes #2249
2021-07-12 17:34:03 +05:30
Kovid Goyal
3a322c5c6e Fix warning from sphinx 2021-07-12 13:22:39 +05:30
Kovid Goyal
c5ee044343 Merge branch 'patch-1' of https://github.com/con-f-use/kitty 2021-07-12 13:21:08 +05:30
con-f-use
19b918e56f mention kitten_alias in hits documentation
No idea if I correctly referenced this url: https://sw.kovidgoyal.net/kitty/conf.html#opt-kitty.kitten_alias
2021-07-12 07:48:34 +02:00
Kovid Goyal
cf5ed54c84 Dont add formatting escape codes to completion descriptions in ZSH
ZSH gets confused by them, causes the text to move up a line when
completing after the first line
2021-07-11 21:46:17 +05:30
Kovid Goyal
b813e1f7ab ... 2021-07-11 21:39:54 +05:30
Kovid Goyal
cdd8e52116 DRYer 2021-07-11 21:39:08 +05:30
Kovid Goyal
6945eb4186 Better complete debug function 2021-07-11 21:33:19 +05:30
Kovid Goyal
1d9626d493 Graphics protocol: Fix image without placements being deleted when screen scrolls 2021-07-10 14:05:53 +05:30
Kovid Goyal
75b73f6821 Allow using neighboring window operations in the stack layout 2021-07-09 08:54:22 +05:30
Kovid Goyal
f62f94381e also forgot to list the a=a key 2021-07-08 09:17:42 +05:30
Kovid Goyal
cd6b3da665 Fix turning off cursor blink via escape codes not working
Also fix cursor blink stopping after terminal reset. The default cursor
state should be blinking.

Fixes #3808

...
2021-07-07 20:45:46 +05:30
Kovid Goyal
25fb5d0ee6 Forgot to list the f key for a 2021-07-07 18:26:06 +05:30
Kovid Goyal
65b2ca8f57 Fix a typo that broke addition of default mouse mappings in gen-config
Also update options/types.py with new action name
2021-07-07 18:06:39 +05:30
Kovid Goyal
1ec07eb17a diff kitten: Remove limit on max line length of 4096 characters
Fixes #3806
2021-07-07 07:27:42 +05:30
Kovid Goyal
46fbf78da5 Fix #3804 2021-07-06 15:34:02 +05:30
Kovid Goyal
cea8d4a87d ... 2021-07-06 09:05:50 +05:30
Kovid Goyal
e07ba2c53d Dont move back glyph on overflow in infinite ligatures 2021-07-05 14:47:01 +05:30
Kovid Goyal
0af3f102aa ... 2021-07-05 14:38:07 +05:30
Kovid Goyal
a5b293401d Add an action to restore move-end behavior when extending selections 2021-07-04 19:02:33 +05:30
Kovid Goyal
05d0bda044 Allow selecting blanks at the start of the top line 2021-07-04 18:49:17 +05:30
Kovid Goyal
3dee3aba59 Fix #3794 2021-07-04 18:05:54 +05:30
Kovid Goyal
e732df46b8 Have right clicking to extend selection operate on the nearest selection boundary instead of the selection end. This matches both vim and xterm 2021-07-04 18:00:41 +05:30
Kovid Goyal
86a8b231f4 ... 2021-07-04 07:15:15 +05:30
Kovid Goyal
10d359c222 Better error message for application escape mode
tmux apparently uses it
2021-07-03 12:24:51 +05:30
Kovid Goyal
1ef895e246 When dumping commands dump stop_pending_mode at the correct place 2021-07-03 12:07:46 +05:30
Kovid Goyal
38ae370202 Fix #3789 2021-07-03 10:12:44 +05:30
Kovid Goyal
610a09817f Fix incorrect Sync terminfo entry 2021-07-03 09:18:33 +05:30
Kovid Goyal
c6938c9039 Add some missed actions 2021-07-02 21:43:18 +05:30
Kovid Goyal
7a8fb8f430 Merge branch 'dankamongmen/the-vs-then' of https://github.com/dankamongmen/kitty 2021-07-01 20:17:03 +05:30
nick black
3495591c5f [trivial] s/the/then/ 2021-07-01 10:34:43 -04:00
Kovid Goyal
050c31094b toggle_layout action to zoom/unzoom active window 2021-07-01 17:57:00 +05:30
Kovid Goyal
6a4668974b Forgot to mark layout actions 2021-07-01 17:38:26 +05:30
Kovid Goyal
026d200add Fix a bug in the implementation of the synchronized updates escape code that could cause incorrect parsing if either the pending buffer capacity or the pending timeout were exceeded
Fixes #3779
2021-07-01 15:32:53 +05:30
Kovid Goyal
fe991ee767 DRYer 2021-07-01 08:53:11 +05:30
Kovid Goyal
b2a219f9d8 Add the Sync non-standard capability for synchronized updates to terminfo
Since the geniuses at terminal-wg are trying their best to create chaos
by retroactively changing the escape code used for this feature, it is
good to have a property for it in terminfo. Since tmux already uses Sync
for it, follow that in kitty's terminfo.
2021-07-01 08:48:59 +05:30
Kovid Goyal
64810e0e0b Add some missing blank lines before code blocks 2021-07-01 07:22:49 +05:30
Kovid Goyal
6e5ed38b76 Add syntax highlighting for mouse_map 2021-06-30 15:56:03 +05:30
Kovid Goyal
8d308ef2b8 Add a ref to vim-kitty for syntax highlighting kitty.conf 2021-06-30 15:50:43 +05:30
Kovid Goyal
ab76ae3778 Dont set the filetype in the default config file modeline
This enables people using custom syntax highlighting such as
https://github.com/fladson/vim-kitty
2021-06-30 15:36:33 +05:30
Kovid Goyal
222055fcff Add link to detailed cp buffers docs 2021-06-30 15:15:41 +05:30
Kovid Goyal
247d700c30 Fix docs build failure 2021-06-30 15:12:46 +05:30
Kovid Goyal
cf41d56c00 Clean docstrings when generating actions docs 2021-06-30 15:06:12 +05:30
Kovid Goyal
a8f7b1eb92 Disable text justification in website
Looks really bad in many places as there are quite a few non-breakbale
phrases.
2021-06-30 15:03:06 +05:30
Kovid Goyal
90d3ce4162 make target to publish website 2021-06-30 15:01:25 +05:30
Kovid Goyal
bc66b7f16e Fix a bunch of broken links 2021-06-30 14:59:54 +05:30
Kovid Goyal
606708a96e Cross reference builtin shortcuts from actions 2021-06-30 14:52:47 +05:30
Kovid Goyal
2ec0d94c31 Document all mappable actions 2021-06-30 14:33:28 +05:30
Kovid Goyal
e6a17f78b6 Use the main VT parser in pending mode as well
Should get much closer semantics in the two cases and its nice not to
have an extra mini VT parser for pending mode. There is a performance
hit in pending mode, since now the pending mode bytes are round tripped
via utf-8 decoding/encoding, but its worth it for the code
simplification.
2021-06-30 10:52:22 +05:30
Kovid Goyal
d6b6d3f59f Make dispatch_unicode_char re-useable 2021-06-30 08:29:40 +05:30
Kovid Goyal
5932ddb0fe DRYer 2021-06-30 07:57:21 +05:30
Kovid Goyal
d1e5c2f86f ... 2021-06-29 22:31:23 +05:30
Kovid Goyal
1f2f25f7a3 Mark the mouse actions 2021-06-29 22:27:31 +05:30
Kovid Goyal
b0edbf2857 Mark more actions 2021-06-29 22:21:01 +05:30
Kovid Goyal
91f0da9dcd Document actions in the tab object 2021-06-29 20:12:39 +05:30
Kovid Goyal
3d5d60bc5b ... 2021-06-29 16:37:29 +05:30
Kovid Goyal
5c5599592a abort CSI parsing on NUL or DEL 2021-06-29 12:37:34 +05:30
Kovid Goyal
c60d09f3b2 Mark combine as an action 2021-06-29 12:28:44 +05:30
Kovid Goyal
5768c54c5b Add support for pending mode via SM/RM 2026
Because, why the hell not, it's not like I have an actual life.
More seriously, terminal-wg (aka Bikeshedder's Anonymous) is
pushing for it so it's likely at least one poor application writer
will fall for their propaganda.
2021-06-29 12:24:34 +05:30
Kovid Goyal
6d413e2492 Start documenting mappable actions 2021-06-28 21:44:52 +05:30
Kovid Goyal
331675d413 Fix ResourceWarning 2021-06-28 20:40:10 +05:30
Kovid Goyal
2105940286 Better error message for +launch 2021-06-28 19:38:51 +05:30
Kovid Goyal
90164dfee7 make clean should not clean bypy build artifacts 2021-06-28 06:39:12 +05:30
Kovid Goyal
73f641cb66 version 0.21.2 2021-06-28 06:22:35 +05:30
Kovid Goyal
3d51835b9b Avoid unneccessary mallocs and copying when return code points for word 2021-06-28 05:56:49 +05:30
Kovid Goyal
f358d76409 Fix type sig 2021-06-28 05:51:49 +05:30
Kovid Goyal
ce486e9244 Move the if condition out of the inner loops 2021-06-27 21:09:06 +05:30
Kovid Goyal
691b7215a0 Unicode input kitten: Fix searching when a word has more than 1024 matches
Fixes #3773
2021-06-27 21:04:43 +05:30
Kovid Goyal
5be45d0ff2 Turn on all warnings when running test suite 2021-06-26 12:55:53 +05:30
Kovid Goyal
8a4b326127 Finish completion for ssh kitten
Fixes #3760
2021-06-26 12:28:12 +05:30
Kovid Goyal
051374cd55 Add support for comma separated completions 2021-06-26 10:52:14 +05:30
Kovid Goyal
71cd92da29 Store match group properties on the match group object 2021-06-26 09:47:21 +05:30
Kovid Goyal
c2d3a0c8b4 Completion for choice args 2021-06-26 09:18:36 +05:30
Kovid Goyal
fe8b151666 Complete option 2021-06-25 22:53:55 +05:30
Kovid Goyal
9e2d67f7a1 Show option descriptions when completing in ZSH 2021-06-25 19:13:16 +05:30
Kovid Goyal
23ea3745ca Make zsh completion headings bold 2021-06-25 18:05:18 +05:30
Kovid Goyal
d8d5a8fada More work on completion for the SSH kitten 2021-06-25 17:50:08 +05:30
Kovid Goyal
21ce0e90bf Code to get list of known host names 2021-06-25 15:04:17 +05:30
Kovid Goyal
ec420b8012 Start work on completion for ssh kitten 2021-06-25 15:04:17 +05:30
Kovid Goyal
bd67899943 Allow using super and sub scripts in tab titles
The syntax is

{sup.whatever}

works by translating enhlish letters/number to their unicode
equivalents.

Fixes #3763
2021-06-25 15:02:43 +05:30
Kovid Goyal
4b7600f3a5 Nicer error message on unknown entry point 2021-06-25 10:25:54 +05:30
Kovid Goyal
5eabd69659 ... 2021-06-25 08:03:20 +05:30
Kovid Goyal
e83be21756 Add a note about completions for the SSH kitten 2021-06-25 08:02:28 +05:30
Kovid Goyal
13c58536be Cleanup previous PR and add changelog entry 2021-06-24 21:27:15 +05:30
Kovid Goyal
512dccdbfa Merge branch 'ripgrep-context' of https://github.com/allemangD/kitty 2021-06-24 21:25:11 +05:30
David Allemang
bb3a8453e0 Make hyperlinked_grep kitten respect context
Fix regex so that context lines (from -C option) are still hyperlinked.

Also add a case so that any non-matching lines are still output raw.
2021-06-24 11:04:35 -04:00
Kovid Goyal
e337fcaadc query terminal kitten: Allow querying font face and size information
Fixes #3756
2021-06-24 13:31:50 +05:30
Kovid Goyal
890a149a5d Move generation of query responses into the query classes 2021-06-24 12:31:17 +05:30
Kovid Goyal
5b3ac259ce Fix a resource warning 2021-06-24 11:27:02 +05:30
Kovid Goyal
ce50043048 Add an issue reference to the changelog 2021-06-23 14:16:41 +05:30
Kovid Goyal
ebfbf6082f ... 2021-06-21 21:23:29 +05:30
Kovid Goyal
b44bec2207 Move processing of coca_pending_actions() into its own function
Makes process_global_state less crowded and easier to grok
2021-06-21 21:03:41 +05:30
Kovid Goyal
576ce21fc8 macOS: Fix shortcuts in the global menu bar responding slowly when cursor blink is disabled/timed out
The event loop needed to be forced to tick over immediately otherwise
the changes were not being rendered till some other event such as mouse
motion or key release was not delivered.

Fixes #3693
2021-06-21 20:58:44 +05:30
Kovid Goyal
2ba015d0be Add an issue reference to the changelog
Fixes #3405
2021-06-21 16:46:49 +05:30
Kovid Goyal
98ae2ac96a ssh kitten: Use sh rather than /bin/sh
It's not actually required that sh be in /bin.  The hope is that fewer
users alias sh to non POSIX things than put sh in places other than /bin
2021-06-21 16:43:59 +05:30
Kovid Goyal
1c25ed7666 ssh kitten: Fix "Connection closed" message being printed by ssh when running remote commands
Don't force allocate a tty when running remote commands. This
matches ssh behavior as well.
2021-06-21 16:40:07 +05:30
Kovid Goyal
fd4c7a4ed2 ssh kitten: Support system where the login shell is a non-POSIX shell
Now the kitten passes its script to /bin/sh and detects the login shell
using various strategies based on the value of $USER on the remote
machine. The strategies are tried one after another till one succeeds:

1) getent passwd $USER
2) id -P
3) python pwd module
4) parsing /etc/passwd

The hope is that these strategies will fail on fewer systems than
relying on the login shell being POSIX compliant.
2021-06-21 16:30:49 +05:30
Kovid Goyal
32d275c138 Document how to use the new config framework with external kittens 2021-06-21 05:31:17 +05:30
Kovid Goyal
f8924286ce gen-config for third party kittens 2021-06-21 05:11:46 +05:30
Kovid Goyal
6e77345263 Ensure sys.path is preserved even if there are errors importing a custom kitten 2021-06-21 04:35:10 +05:30
Kovid Goyal
1438c64b9e Move the config generation code into kitty proper 2021-06-21 04:25:04 +05:30
Kovid Goyal
2ff1256aef mouse_discard_event -> discard_event 2021-06-21 04:01:45 +05:30
Kovid Goyal
5d169854c4 Merge branch 'typo' of https://github.com/Luflosi/kitty 2021-06-18 20:21:08 +05:30
Luflosi
e61d328cb0 Fix typo in changelog 2021-06-18 16:36:27 +02:00
Kovid Goyal
0c196888fb Clarify meaning of grabbed/ungrabbed a bit more 2021-06-18 17:56:21 +05:30
Kovid Goyal
85efed8308 Fix #3743 2021-06-18 17:54:13 +05:30
Kovid Goyal
857c88a951 Add a note to the keyboard protocol elucidating the use of separate main and alternate screen mode stacks in more detail 2021-06-18 09:58:19 +05:30
Kovid Goyal
74b0a7f6f8 Make it clearer that there are separate keyboard mode stacks for main and alternate screens 2021-06-18 09:41:35 +05:30
Kovid Goyal
5da5d00aec text typos 2021-06-18 08:20:32 +05:30
Kovid Goyal
eb59fae9b0 ... 2021-06-18 08:20:04 +05:30
Kovid Goyal
b6b38d6f44 Linux: Fix emoji/bitmapped fonts not useable in symbol_map 2021-06-18 08:01:23 +05:30
Kovid Goyal
4f4d9e0ae3 ... 2021-06-17 21:34:26 +05:30
Kovid Goyal
43c1776594 Handle systems that use less -F as pagers
Fix #3740
2021-06-17 21:33:26 +05:30
Kovid Goyal
397638998b Dont use static memory for the list of chars options
Saves a couple of KB of RAM and is more flexible in terms
of max number of allowed chars, although for large numbers one really
needs a hash for fast lookups.
2021-06-17 13:27:11 +05:30
Kovid Goyal
6ddbda00df Clean up url excluded chars PR 2021-06-17 13:11:23 +05:30
Kovid Goyal
df0bf74bfe Merge branch 'url_excluded_characters' of https://github.com/rbutoi/kitty 2021-06-17 13:01:31 +05:30
Radu Butoi
5ee0651f56 Add url_excluded_characters option to exclude characters from URLs.
This option, like select_by_word_characters, is a set of characters, but
for which to *exclude* from URL parsing. See
https://github.com/kovidgoyal/kitty/issues/3688#issuecomment-862711148.
2021-06-17 01:55:21 -04:00
Kovid Goyal
9ec1c28b35 Merge branch 'cleanup-adjust-baseline' of https://github.com/ytang/kitty 2021-06-16 21:24:59 +05:30
Yang Tang
bfdbf06731 Remove redundant code 2021-06-16 11:44:27 -04:00
Kovid Goyal
ca58b30c47 Fix compiler warning 2021-06-16 20:51:47 +05:30
Kovid Goyal
0fb2f383ac Clean up the baseline adjustment PR 2021-06-16 20:39:00 +05:30
Kovid Goyal
5d0eb1d330 Merge branch 'adjust-baseline' of https://github.com/ytang/kitty 2021-06-16 20:04:15 +05:30
Kovid Goyal
ee77144e2b Make the sample script a little nicer 2021-06-16 18:51:21 +05:30
Kovid Goyal
9d3a2cc219 Fix space based ligatures not rendering correctly
The new infinite ligature cache needed to be keyed by total number of
cells as well as total number of glyphs, otherwise a space based
ligature which is the same glyph rendered in different numbers of cells
wold render incorrectly when present in multiple forms. Fixes #3729
2021-06-16 18:41:01 +05:30
Yang Tang
e964ac86d5 Allow specifying adjust_baseline as either pixels or percentage 2021-06-16 01:11:51 -04:00
Yang Tang
bb26b3d549 Add option adjust_baseline to adjust the baseline position on macOS 2021-06-15 14:52:43 -04:00
Kovid Goyal
71c8d82c33 Merge branch 'doc-harfbuzz' of https://github.com/The-Compiler/kitty 2021-06-15 21:52:39 +05:30
Florian Bruhin
9fffe0d710 doc: Link to harfbuzz font feature format 2021-06-15 17:36:12 +02:00
Kovid Goyal
51f8b22dfa macOS: Fix middle-click to paste from clipboard not working
Fixes #3730
2021-06-15 13:45:50 +05:30
Kovid Goyal
63a36a1054 Add Smulx to terminfo
A couple of other terminals use it for styled underlines, in
contravention of the spec. But, in the interests of wider
interoperability add it to kitty as well.

Fixes #3725
2021-06-14 11:58:52 +05:30
Kovid Goyal
057084a708 Add support for XTVERSION version reporting escape code 2021-06-14 10:20:50 +05:30
Kovid Goyal
79b130ed23 version 0.21.1 2021-06-14 07:47:32 +05:30
Kovid Goyal
75e8b16ea3 Dont limit the number of possible cocoa pending actions to the number of bits in an int 2021-06-14 07:34:28 +05:30
Kovid Goyal
1b35708d89 macOS: Fix a crash when rendering ligatures larger than 128 characters
Fixes #3724
2021-06-14 07:15:52 +05:30
Kovid Goyal
ebff343a55 macOS: Add reload config to kitty global menu 2021-06-13 20:34:27 +05:30
Kovid Goyal
c7b91e5f19 Cocoa grabs control+function key presses so use dedicated cmd based shortcuts for those on macOS 2021-06-13 18:20:14 +05:30
Kovid Goyal
b9d52dfaf7 Update Changelog 2021-06-13 10:01:38 +05:30
Kovid Goyal
2c8f66586f macOS: Fix a regression in the previous release that broke rendering of strikeout
The new cell height code forgot to adjust strikeout position.
Fixes #3717
2021-06-13 09:29:30 +05:30
Kovid Goyal
219bf564f7 Fix #3719 2021-06-13 09:07:08 +05:30
Kovid Goyal
291be6f5a6 Silence incorrect compiler warning on older gcc 2021-06-12 13:15:05 +05:30
Kovid Goyal
1da2344aa3 Fix a possible crash when handling mouse clicks 2021-06-12 13:03:47 +05:30
Kovid Goyal
750cf7ad20 version 0.21.0 2021-06-12 08:41:37 +05:30
Kovid Goyal
962acd1537 ssh kitten: Fix non-standard properties in terminfo such as the ones used for true color not being copied 2021-06-12 07:27:14 +05:30
Kovid Goyal
7a44765860 Remove unused pyc files from frozen bundles 2021-06-11 12:46:12 +05:30
Kovid Goyal
007be8e52c Add a note about matching source to binary versions 2021-06-11 09:14:05 +05:30
Kovid Goyal
5e4c98eae6 Remote control: Allow matching tabs by index number in currently active OS Window
Fixes #3708
2021-06-11 09:12:08 +05:30
Kovid Goyal
858a6dc27e Document KITTY_DEVELOP_FROM 2021-06-11 08:59:55 +05:30
Kovid Goyal
ad5d14c672 Fix #3703 2021-06-10 16:53:27 +05:30
Kovid Goyal
199685a25b Graphics protocol: Add support for shared memory on Windows 2021-06-10 12:44:50 +05:30
Kovid Goyal
d99e243f57 Respect --ignore-compiler-warnings when building the launcher 2021-06-10 07:48:52 +05:30
Kovid Goyal
64f1211cf8 Fix example in FAQ
Mapping wont work in kitty keyboard mode.
2021-06-09 20:46:36 +05:30
Kovid Goyal
9432f86e43 Remove no longer needed type: ignore
Looks like the type signature for runpy.run_path has finally been fixed
2021-06-09 08:30:22 +05:30
Kovid Goyal
fc99d4d757 Specify the type of files to make mypy happy (I hope) 2021-06-09 08:24:36 +05:30
Kovid Goyal
7fb2b21a22 Also needs types for docutils 2021-06-09 08:18:04 +05:30
Kovid Goyal
260b300da9 Now mypy wants types for requests installed 2021-06-09 08:14:02 +05:30
Kovid Goyal
f26d5b02cb ... 2021-06-09 08:01:46 +05:30
Kovid Goyal
c9ff061feb Merge branch 'leiserfg-doc-patch' of https://github.com/leiserfg/kitty 2021-06-08 08:11:51 +05:30
Leiser Fernández Gallo
86ad318e6c Fix Iosevka version in the docs
Iosevka with kitty support is already out, just waiting for kitty to be released too 🎉
2021-06-07 17:36:40 +02:00
Kovid Goyal
df05339d2a Allow reloading config by sending the SIGUSR1 signal 2021-06-07 20:51:45 +05:30
Kovid Goyal
ec1303a232 Fix some more warnings 2021-06-07 17:30:13 +05:30
Kovid Goyal
c1049734e6 Simpler implementation of scroll and clear screen 2021-06-07 17:13:39 +05:30
Kovid Goyal
99fa79caaf Fix warning 2021-06-07 17:12:53 +05:30
Kovid Goyal
761062a6d7 Discard press event for ctrl+shift+release open_url mapping as it can causes issues when delivered to the terminal program 2021-06-07 17:00:09 +05:30
Kovid Goyal
11227b3ee1 Fix motivation for ctrl+shift+release mapping 2021-06-07 16:36:39 +05:30
Kovid Goyal
8d63d50aea Sort imports 2021-06-07 15:01:30 +05:30
Kovid Goyal
3360aa6c33 Fix #3695 2021-06-07 14:57:38 +05:30
Kovid Goyal
bfffd98fd4 Add a changelog entry for config reloading
Fixes #1292
2021-06-07 09:38:41 +05:30
Kovid Goyal
9a86184a45 Add a note about binding ctrl+l to scroll and clear instead of just clear 2021-06-07 09:35:08 +05:30
Kovid Goyal
00828cb804 More reloading work for various options 2021-06-07 09:30:15 +05:30
Kovid Goyal
ec31a36fd9 Fix reloading of various settings 2021-06-07 08:27:58 +05:30
Kovid Goyal
9003c76261 Add a shortcut to reload the config file 2021-06-06 18:49:58 +05:30
Kovid Goyal
7148f262c0 Reload for keys, fonts and colors now working 2021-06-06 14:31:22 +05:30
Kovid Goyal
3ab417e291 Start work on config file reloading 2021-06-05 15:29:28 +05:30
Kovid Goyal
4ced7b7657 Missed one reference to --debug-config 2021-06-05 15:12:52 +05:30
Kovid Goyal
ad69143573 Improve config debug output for is_multiple variables 2021-06-05 14:39:43 +05:30
Kovid Goyal
4a71afaf96 Get rid of --debug-config
Instead have a keybind that shows the configuration used
by the currently running kitty instance
2021-06-05 14:27:24 +05:30
Kovid Goyal
a1b87f445b Store the paths from which config data is read on the created options object 2021-06-05 12:55:00 +05:30
Kovid Goyal
33e63f000a Make mouse mapping gen-config order stable 2021-06-05 12:22:54 +05:30
Kovid Goyal
1c8b7955eb Have gen-config output action names as comments 2021-06-05 12:20:43 +05:30
Kovid Goyal
0bade29c25 Fix a gen-config bug that was causing macos shortcuts to be defined on linux as well 2021-06-05 10:14:30 +05:30
Kovid Goyal
4cff3e51cb macOS: Add a global menu entry to reset the terminal 2021-06-05 10:12:44 +05:30
Kovid Goyal
d264c3d91e typo 2021-06-05 10:10:23 +05:30
Kovid Goyal
099fed07e9 Note that set-font-size --all changes configured size 2021-06-05 09:39:10 +05:30
Kovid Goyal
091fec0867 Add tab bar margin height to changelog
Fixes #3685
Fixes #3247
2021-06-05 09:18:52 +05:30
Kovid Goyal
a670268a6b Add blank rects for tab bar padding 2021-06-05 09:16:24 +05:30
Kovid Goyal
caa44b3d4a Position tab bar as per new margin options
Also mouse clicking anywhere in the tab bar margins should be the same
as clicking in the tab bar, for ease of use.
2021-06-05 09:02:01 +05:30
Kovid Goyal
f3977da8f3 Start work on options for tab bar vertical margins
Create the option, now need to implement it.
2021-06-05 09:01:57 +05:30
Kovid Goyal
7dc3184f31 ... 2021-06-04 22:00:15 +05:30
Kovid Goyal
d09c20aa01 Store the global font_size on the opts object where it belongs 2021-06-04 21:51:02 +05:30
Kovid Goyal
81411e6b54 Fix trailing parentheses in URLs not being detected
Also fix URLs starting near the end of the line not being detected.

Fixes #3688
2021-06-04 18:13:36 +05:30
Kovid Goyal
a8d1c73fec API to get text for currently marked URL 2021-06-04 14:35:22 +05:30
Kovid Goyal
1b3742efbb Add a link to Iosevka in the changelog 2021-06-04 12:20:27 +05:30
Kovid Goyal
e01bb09e8c Fix ligatures not working with the Iosevka font
Fixes #297
2021-06-04 12:18:17 +05:30
Kovid Goyal
2c9c0751a4 Speed up import of options.types
The color table attributes are never used in a type checked
environment, only via setattr/gettattr so dont create individual
get/setters for them. Reduaces the import time for this module from 2ms
to 0.7ms

Since attribute access is implemented via __getattr__ there should be no
performance implications for normal attribute access, as __getattr__ is
only called if normal attribute access fails. setattr becomes slightly
slower but that is done very rarely.
2021-06-04 06:01:55 +05:30
Kovid Goyal
e10a7579e8 Remove unreachable code 2021-06-04 05:40:27 +05:30
Kovid Goyal
c52a04c7d3 Use a tuple for clipboard control
Avoids churn in the generated options files as python randomized set
ordering
2021-06-04 05:36:05 +05:30
Kovid Goyal
79dd98b20e Use a more efficient representation of the color table on the Options object 2021-06-03 22:17:37 +05:30
Kovid Goyal
2e71429b03 Auto generate the boilerplate code to convert python opts to c opts 2021-06-03 18:30:13 +05:30
Kovid Goyal
4ab299d0af When reflowing the screen, also reflow the saved cursor position 2021-06-03 15:35:48 +05:30
Kovid Goyal
c60a941d1b Allow rewrap_inner to track multiple positions 2021-06-03 12:29:27 +05:30
Kovid Goyal
e2197c586b Forgot a brace 2021-06-03 12:11:31 +05:30
Kovid Goyal
93e9d3cb5f Fix a crash on exit on macOS
Calling Python API functions is not allowed in atexit handlers.

Fixes #3686
2021-06-03 11:54:55 +05:30
Kovid Goyal
2e7b68bf74 Move python to C converters into their own header 2021-06-01 21:18:39 +05:30
Kovid Goyal
6ffb198e9c DRYer 2021-06-01 21:15:36 +05:30
Kovid Goyal
604458810e Start work on autogenerating opts to c conversion boilerplate 2021-06-01 13:33:19 +05:30
Kovid Goyal
af5ed093b8 Fix test failing on macOS 2021-05-31 17:54:57 +05:30
Kovid Goyal
8f491e7dbb Add newslines at end of generated files and do imports in sorted order 2021-05-31 17:45:02 +05:30
Kovid Goyal
c1324da3fc missing newline in debug print 2021-05-31 17:42:10 +05:30
Kovid Goyal
0bbc4462fd Coalesce shortcuts as well 2021-05-31 17:40:49 +05:30
Kovid Goyal
e0261e925e DRYer 2021-05-31 17:40:49 +05:30
Kovid Goyal
46b3f71b8f Start work on porting docs generation 2021-05-31 17:40:49 +05:30
Kovid Goyal
3e598a17cf Add headers to options def files 2021-05-31 17:40:49 +05:30
Kovid Goyal
c1b13f2db2 DRYer 2021-05-31 17:40:49 +05:30
Kovid Goyal
a059e49579 Restore conf file generation in the new framework 2021-05-31 17:40:49 +05:30
Kovid Goyal
6d7df1c5e8 Refactor configuration file parsing
Now the time for importing the kitty.config module has been halved, from
16ms from 32ms on my machine. Also, the new architecture will eventually
allow for auto generating a bunch of python-to-C boilerplate code.
2021-05-31 17:40:49 +05:30
Kovid Goyal
dd5715ce79 Rename parsing placeholders for actions 2021-05-31 17:40:48 +05:30
Kovid Goyal
43acf3c5b1 name parser for deprecated send text appropriately 2021-05-31 17:40:48 +05:30
Kovid Goyal
f7db9e3527 Move deprecated parsers into utils 2021-05-31 17:40:48 +05:30
Kovid Goyal
1621a67f36 unused import 2021-05-31 17:40:48 +05:30
Kovid Goyal
248631a1a8 Add tests for conf parsing 2021-05-31 17:40:48 +05:30
Kovid Goyal
b4cb6e10ca Dont resolve kitty_mod in the defaults key definitions
Needed to allow multiple load_config calls
2021-05-31 17:40:48 +05:30
Kovid Goyal
5fa73e4413 Dont use a unneccessary global variable 2021-05-31 17:40:48 +05:30
Kovid Goyal
49c4b20113 Report bad choice values when parsing config 2021-05-31 17:40:48 +05:30
Kovid Goyal
43ece23b89 the args for KeyAction are not just strings 2021-05-31 17:40:48 +05:30
Kovid Goyal
f976851442 Make the repr for KeyAction more compact 2021-05-31 17:40:48 +05:30
Kovid Goyal
5470dd74bd Move options code into its own directory 2021-05-31 17:40:48 +05:30
Kovid Goyal
ddd178fa82 Move clear_all_shortcuts to options_types 2021-05-31 17:40:48 +05:30
Kovid Goyal
8d411cac5f ... 2021-05-31 17:40:48 +05:30
Kovid Goyal
bfbb85399e Move action parsing to option_types 2021-05-31 17:40:47 +05:30
Kovid Goyal
9f8a120664 Add __repr__ for action definitions 2021-05-31 17:40:47 +05:30
Kovid Goyal
e1cd6b6037 kitten_alias is also an is_multiple option 2021-05-31 17:40:47 +05:30
Kovid Goyal
2fd4487922 Better naming of action parsers 2021-05-31 17:40:47 +05:30
Kovid Goyal
27a459b0dd Refactor action parsers as generators 2021-05-31 17:40:47 +05:30
Kovid Goyal
6c344d4ae2 Move the action parsing code into options_types 2021-05-31 17:40:47 +05:30
Kovid Goyal
d7aa9952d8 Fix a regression that caused using the `title` command in session files to stop working
Fixes #3676
2021-05-31 09:31:29 +05:30
Kovid Goyal
09093c8f3e Cleanup PR 2021-05-30 12:47:00 +05:30
Kovid Goyal
222bf09df4 Merge branch 'libstartup-notification' of https://github.com/ctrlcctrlv/kitty 2021-05-30 12:45:13 +05:30
Fredrick Brennan
3041ff8d25 Downgrade libstartup-notification-1.so non-existence to warning
I'm not sure how common this library actually is. On my system, an Arch
Linux system with 2,170 packages installed, including KDE (Plasma), I
didn't have it.

It's downgraded to a warning instead of printing a traceback.
2021-05-30 03:05:42 -04:00
Kovid Goyal
bfe1952705 Merge branch 'less-contrast-for-powerline-alt-separator' of https://github.com/chipaca/kitty 2021-05-30 07:37:41 +05:30
John R. Lenton
97181a39da Use less contrasting color for powerline alt separator
This change makes it so that when using powerline-style tab bars, and
if the `tab_bar_background`, `inactive_tab_background` and
`inactive_tab_foreground` are all different, the separator between
inactive tabs uses the less contrasting color between the inactive
foreground, and the tab bar background.

This fixes #3664.
2021-05-29 16:54:51 +01:00
Kovid Goyal
39b3d3de0f macOS: Fix the baseline for text not matching other CoreText based applications for some fonts
Finally found an API to query CoreText for the adjusted baseline
position, so the baseline should now match up with other CoreText
based applications.

Fixes #2022
2021-05-29 14:19:20 +05:30
Kovid Goyal
056d16017f Fix #3660 2021-05-28 05:33:12 +05:30
Kovid Goyal
5cef0aef92 Update changelog for last PR 2021-05-25 18:19:34 +05:30
Kovid Goyal
f794de5b9b Merge branch 'new-menu-items' of https://github.com/Luflosi/kitty 2021-05-25 18:18:32 +05:30
Luflosi
4a67af9b90 macOS: add menu items for new_window and close_window 2021-05-25 13:54:02 +02:00
Kovid Goyal
f178dff4e0 Remove the special_types kludge for is_multiple options 2021-05-25 11:25:39 +05:30
Kovid Goyal
ba821cb02f DOnt be lazy about typing font features 2021-05-25 09:29:47 +05:30
Kovid Goyal
b169831810 remove unused import 2021-05-25 09:00:54 +05:30
Kovid Goyal
06b3c71304 Make is_multiple explicit 2021-05-25 08:46:26 +05:30
Kovid Goyal
fe94f4cbb4 Move type parsers for config into own module 2021-05-24 22:29:28 +05:30
Kovid Goyal
a4daa49f70 Micro-optimization 2021-05-24 17:11:20 +05:30
Kovid Goyal
3b1d534f6d The parser doesnt need the full defaults object 2021-05-24 14:01:50 +05:30
Kovid Goyal
c1777b1098 DRYer 2021-05-24 13:42:51 +05:30
Kovid Goyal
c827a29a7b Use the new get_options() function
Nicer than carrying around opts objects everywhere
2021-05-24 12:29:11 +05:30
Kovid Goyal
253b219d67 Store the options object globally 2021-05-24 11:50:03 +05:30
Kovid Goyal
b702f3daf1 In extend from point mode always restrict the top line to be from the point, even for multiline selections
Otherwise soft wrapped lines cause the full first line to be selected.
2021-05-23 15:52:48 +05:30
Kovid Goyal
76c9f46438 Disambiguate between click and doublepress
A doubleprpess should not generate a click event
2021-05-23 13:38:19 +05:30
Kovid Goyal
c6c203da43 Remove unused imports 2021-05-23 11:48:30 +05:30
Kovid Goyal
00302b74d1 Add a default mapping for line_from_point selection 2021-05-23 11:37:26 +05:30
Kovid Goyal
32f6f18527 DRYer 2021-05-23 11:22:29 +05:30
Kovid Goyal
4fd0446538 Merge branch 'new-menu-bar-item' of https://github.com/Luflosi/kitty 2021-05-22 06:03:32 +05:30
Luflosi
082ad61d14 macOS: move menu bar items for opening and closing OS windows and tabs to new menu
Most apps on macOS have the menu items for opening and closing tabs and windows in the "File" menu. Since this doesn't really apply to Terminal emulators, both Terminal.app and iTerm2 have them in the "Shell" menu instead.
This change makes the menu bar of kitty more consistent with these applications.
2021-05-21 18:21:31 +02:00
Kovid Goyal
0ca4faa25b New OS window -> New OS Window 2021-05-21 17:57:53 +05:30
Kovid Goyal
46a0566e2e Special handling for IOSevka's future ligatures
See https://github.com/be5invis/Iosevka/issues/1007
2021-05-21 17:53:49 +05:30
Kovid Goyal
97440d45d6 Add an example showing how to run things in scripts via launch 2021-05-21 16:02:05 +05:30
Kovid Goyal
c5afe4e745 Merge branch 'feat/undercurl-retina' of https://github.com/disrupted/kitty 2021-05-21 08:30:21 +05:30
Kovid Goyal
bc6e819396 typos in text 2021-05-19 20:35:43 +05:30
disrupted
d650a97dda Fix undercurl height & thickness on HiDPI screens
Update positioning
2021-05-18 19:00:46 +02:00
Kovid Goyal
cf88eb9d60 ssh kitten: Mimic behavior of ssh more closely
Execute any command specified on the command line via the users' shell
on the remote side just as ssh does

Fixes #3638
2021-05-18 15:12:57 +05:30
Kovid Goyal
0a742ea8d0 middle is more common than start or end 2021-05-18 09:55:00 +05:30
Kovid Goyal
cb8935746f Pass the font group to init_face
Allows using the DPI there if needed
2021-05-18 07:58:32 +05:30
Kovid Goyal
608ac953e5 Pass DPI through to special render function 2021-05-18 07:46:04 +05:30
Kovid Goyal
4d0d0b205d Improve parser error messages a bit 2021-05-17 21:29:54 +05:30
Kovid Goyal
07b643e24c Remove expected behavior section from issue template
Its largely redundant and a waste of time. Not to mention
no one likes being told what's expected of them :))
2021-05-17 18:38:46 +05:30
Kovid Goyal
02fb020dfd Better fix for minimal border layout issue
Keep _set_dimensions() private
2021-05-17 15:30:03 +05:30
Kovid Goyal
bac6ebdf95 Fix incorrect border drawing when multiple tabs and multiple OS Windows are present and some of the OS Windows have tab bars and some dont
Fixes #3634
2021-05-17 15:04:33 +05:30
Kovid Goyal
b7072d4097 Mention how to unmap mouse actions 2021-05-17 08:26:12 +05:30
Kovid Goyal
d7c7bb00b8 Merge branch 'master' of https://github.com/copy/kitty 2021-05-17 07:42:13 +05:30
Fabian
0485f0c7ed kitty @ get-text add an option to wrap long lines 2021-05-16 15:19:22 -05:00
Kovid Goyal
2ade6c0739 Update outdated info in build docs 2021-05-16 21:22:33 +05:30
Kovid Goyal
5eeb19871b Update dependency requirements for build from source 2021-05-16 21:20:11 +05:30
Kovid Goyal
083a0ae5fc ... 2021-05-16 09:33:06 +05:30
Kovid Goyal
ccc370e1c4 Dont initialize FontConfig when importing fast_data_types
This reduces the import time for fast_data_types by 12ms on my machine.
FontConfig initialization is very slow and it is only needed by the
main kitty program, however fast_data_types is imported in kittens and
remote control as well, where FontConfig is useless.
2021-05-15 10:41:54 +05:30
Kovid Goyal
23b8cafc41 Add layout name completion to @ goto-layout 2021-05-15 10:25:34 +05:30
Kovid Goyal
d7ab96856c ... 2021-05-15 09:42:52 +05:30
Kovid Goyal
3c77229f61 Add --no-response to set-background-image 2021-05-15 09:41:22 +05:30
Kovid Goyal
fcd206891f kitty @ get-text add an option to also get the current cursor position and state as ANSI escape codes
Fixes #3625
2021-05-15 09:27:28 +05:30
Kovid Goyal
3bf9130b0a Fix deleting windows that are not the last window via remote control leaving no window focused
Fixes #3619
2021-05-14 07:25:48 +05:30
Kovid Goyal
4125ac013f Validate command line args to @ goto-layout better 2021-05-13 20:46:37 +05:30
Kovid Goyal
e089e9c121 Clarify what --debug-config does 2021-05-13 20:19:34 +05:30
Kovid Goyal
81af379bbc correct spelling 2021-05-13 17:46:21 +05:30
Kovid Goyal
9b07aa6894 Simplify Quickstart section by delegating repo link to repology.org
Also add a warning about some Linux distros with outdated packages.
2021-05-13 17:42:29 +05:30
Kovid Goyal
a75140c6d7 Add a --working-directory alias for --directory as this is commonly used in many terminal emulators 2021-05-13 16:13:46 +05:30
Kovid Goyal
f3364cfdc0 Guard against invalid cache file in a couple more places 2021-05-13 09:51:57 +05:30
Kovid Goyal
f64b4e0e56 ... 2021-05-12 20:26:38 +05:30
Kovid Goyal
a1356d3bcf ... 2021-05-12 12:29:53 +05:30
Kovid Goyal
4c5a1ceefa Add a FAQ entry for why one should never output binary data into terminals 2021-05-12 12:24:29 +05:30
Kovid Goyal
e4b4a35375 macOS: Fix rendering getting stuck on some machines after sleep/screensaver
This is caused, as far as I can tell, by CVDisplayLink getting stuck.
Apple apparently are incapable of writing a simple timer robustly.
So if it remains stuck after a second delete and recreate it to force it
to restart.

Fixes #2016
2021-05-12 07:30:17 +05:30
Kovid Goyal
cc2afef390 Make the max number of unscrolled lines implementation defined 2021-05-11 14:55:14 +05:30
Kovid Goyal
7c5706ead9 Add the ability to unscroll the screen to the `kitty @ scroll-window` remote control command
Fixes #3604
2021-05-11 14:36:52 +05:30
Kovid Goyal
bcb739fcd2 Allow clicking URLs to open them without needing to also hold ctrl+shift 2021-05-11 14:20:12 +05:30
Kovid Goyal
85ef3724f1 Proper prefix when reporting Move events 2021-05-11 14:02:17 +05:30
Kovid Goyal
cb21422836 Add click and doubleclick events as well 2021-05-11 13:59:52 +05:30
Kovid Goyal
1c9674cec9 SPlit up add_click into two functions 2021-05-11 13:19:34 +05:30
Kovid Goyal
6dcc09a96f Port mouse selection tests to new framework 2021-05-11 11:49:44 +05:30
Kovid Goyal
0260c9d3fb Add a note about selection drag being auto-released 2021-05-11 11:18:10 +05:30
Kovid Goyal
80c03f28f8 Add a note about backward incompatibility 2021-05-11 10:36:48 +05:30
Kovid Goyal
eeaf67079a DRYer 2021-05-11 10:33:01 +05:30
Kovid Goyal
c50863c0d5 Add a note about --debug-input 2021-05-11 10:28:27 +05:30
Kovid Goyal
f4ab6542fa ... 2021-05-11 10:24:48 +05:30
Kovid Goyal
dfbe1bd234 Add debug prints for mouse events 2021-05-11 10:22:30 +05:30
Kovid Goyal
1e89cdc055 Get middle click paste working and dont trigger when mouse is grabbed 2021-05-11 09:20:27 +05:30
Kovid Goyal
7a40959f13 Add a configurable mouse action to select from the clicked point to the end of the line.
Fixes #3585
2021-05-11 09:01:52 +05:30
Kovid Goyal
2b4d55804c Document the mouse action mapping infrastructure 2021-05-11 08:39:13 +05:30
Kovid Goyal
858dac5601 Port mouse selection handling to the new generic mouse actions framework 2021-05-10 21:33:13 +05:30
Kovid Goyal
e944945b7a Implement URL clicking handler 2021-05-10 15:35:50 +05:30
Kovid Goyal
920151a460 Fix mouse event dispatch 2021-05-10 14:48:29 +05:30
Kovid Goyal
ac2a01fb09 Implement documentation generation and conf file generation for mouse actions 2021-05-10 14:27:45 +05:30
Kovid Goyal
a7933018cb Start work on intercepting mouse events 2021-05-10 07:16:43 +05:30
Kovid Goyal
5ee889eadd Dont carry around a bunch of definitions that were only needed during parsing on the opts object 2021-05-10 07:16:43 +05:30
Kovid Goyal
e811f03011 Match key names 2021-05-10 07:16:43 +05:30
Kovid Goyal
417c81de60 Implement parsing for mouse_map config 2021-05-10 07:16:43 +05:30
Kovid Goyal
212c653165 Maintain separate click queues for every button 2021-05-10 07:16:43 +05:30
Kovid Goyal
e36f11385f Convert mouse buttons to an enum 2021-05-10 07:16:43 +05:30
Kovid Goyal
abb05f4883 ... 2021-05-10 07:16:43 +05:30
Kovid Goyal
2973f33959 Start work on parsing mouse mappings 2021-05-10 07:16:43 +05:30
Kovid Goyal
053c2ed2b9 Make pow10_array const 2021-05-10 07:16:43 +05:30
Kovid Goyal
1865570390 Dont force dragging to be with left button 2021-05-10 07:16:43 +05:30
Kovid Goyal
ba1ee7e6cc Code to dispatch mouse events to python 2021-05-10 07:16:43 +05:30
Kovid Goyal
f6b0fcbc0f Add a link to patat 2021-05-10 07:12:31 +05:30
Kovid Goyal
a802058886 Add a link to hologram.nvim 2021-05-10 07:08:27 +05:30
Kovid Goyal
bbc1f68966 Add a link to euporie 2021-05-10 07:04:45 +05:30
Kovid Goyal
ca0b42c3bd oops 2021-05-10 06:28:03 +05:30
Kovid Goyal
9536a475ff Add changelog entry for last PR 2021-05-10 06:12:41 +05:30
Kovid Goyal
cfd731c376 Merge branch 'background-process-always-inherit-env' of https://github.com/trygveaa/kitty 2021-05-10 06:11:31 +05:30
Trygve Aaberge
de1015f6ac When running a background process, always inherit env
subprocess.Popen inherits the current environment if you pass env=None,
but only sets the environment you pass when you pass something else.
This causes an issue with using launch with --stdin-source and
--type=background, e.g. that DISPLAY is not set so you can't launch
graphical processes. Therefore, we have to include os.environ when we
pass an env to Popen.

Fixes #3602
2021-05-09 20:52:25 +02:00
Kovid Goyal
6c0730fef4 ... 2021-05-09 15:27:36 +05:30
Kovid Goyal
c73132610e Merge branch 'master' of https://github.com/jean/kitty 2021-05-09 15:26:56 +05:30
Jean Jordaan
77abaaf8b8 Oh yes, gather stow'd directories in one place for tidiness 2021-05-09 16:43:22 +07:00
Jean Jordaan
2787e86fd7 Shout-out to stow, it deserves to be used :-) 2021-05-09 16:38:49 +07:00
Kovid Goyal
355808b0f6 Fix dynamically changing the background color in a window causing rendering artifacts in the tab bar
Fixes #3595
2021-05-09 11:54:51 +05:30
Kovid Goyal
80c13fa75b Use same co-ord system for cursor as in KITTY_PIPE_DATA 2021-05-09 08:11:05 +05:30
Kovid Goyal
9a6c2aa1ea Add a few more special command line arguments for launch
Now all ``KITTY_PIPE_DATA`` is also available via command line argument substitution
Fixes #3593
2021-05-09 07:46:37 +05:30
Kovid Goyal
63d76ee837 macOS: When the Apple Color Emoji font lacks an emoji glyph search for it in other installed fonts
Fixes #3591
2021-05-09 07:17:32 +05:30
Kovid Goyal
7c48db7da8 Merge pull request #3592 from aaronjanse/allocation_typo
fix allocation typo
2021-05-08 15:10:10 +05:30
Aaron Janse
bd8d5f6288 fix allocation typo 2021-05-08 01:51:29 -07:00
Kovid Goyal
7413b7c4f6 Merge pull request #3590 from dankamongmen/master
graphics-protocol.rst: s/and/an/
2021-05-07 16:37:17 +05:30
nick black
80e3c871ce graphics-protocol.rst: s/and/an/ 2021-05-07 06:15:12 -04:00
Kovid Goyal
74c1e02274 Remove redundant F1-F4 defs in cursor key more 2021-05-07 15:20:26 +05:30
Kovid Goyal
efb0f6f24a Fix a regression in 0.20.0 that sent incorrect bytes for the F1-F4 keys in rmkx mode
Fixes #3586
2021-05-07 15:09:42 +05:30
Kovid Goyal
dbf8580dc3 Add issue reference for infinite length ligatures
Fixes #3504
2021-05-07 11:55:38 +05:30
Kovid Goyal
f110a01ffe Only use the last line of ssh hostname -f output incase the user has configured ssh to print random junk on login 2021-05-07 11:42:52 +05:30
Kovid Goyal
eced40a761 ... 2021-05-07 09:31:31 +05:30
Kovid Goyal
5ac315bc3a DRYer 2021-05-07 09:30:44 +05:30
Kovid Goyal
32df4daa63 Fix warning from CodeQL 2021-05-07 09:27:52 +05:30
Kovid Goyal
5836e456e5 Cleanup mouse features documentation 2021-05-07 09:19:17 +05:30
Kovid Goyal
dc6ab69387 Workaround spurious error reported by ASAN 2021-05-07 08:34:18 +05:30
Kovid Goyal
7301c56753 ... 2021-05-07 07:42:39 +05:30
Kovid Goyal
3b76d657bd Fix colored indication not being sent to GPU 2021-05-07 07:41:19 +05:30
Kovid Goyal
2adb6240e4 Reduce GPU memory for infinite length ligatures
An infinite length ligature (longer than 9 glyphs) that has long
sequences of a repeated glyph now does not store a separate sprite
for every repeat.

For example in the ligature ---------- even though there are 10 hyphen
glyphs only four will be stored on the GPU.
2021-05-07 06:59:30 +05:30
Kovid Goyal
e11af496da Remove incorrect cast 2021-05-07 06:59:30 +05:30
Kovid Goyal
f6e33406d7 Dont assume all sprites are rendered if the first one is 2021-05-07 06:59:30 +05:30
Kovid Goyal
6eab138d68 ... 2021-05-07 06:59:29 +05:30
Kovid Goyal
33287115de Support infinite length ligatures 2021-05-07 06:59:24 +05:30
Kovid Goyal
8e36056dd8 oops 2021-05-07 06:58:55 +05:30
Kovid Goyal
4a34f596a8 Remove MAX_EXTRA_GLYPHS_IN_GROUP 2021-05-07 06:58:55 +05:30
Kovid Goyal
7616a3e743 ... 2021-05-07 06:58:55 +05:30
Kovid Goyal
c64353c324 Dont make canvas dependent on max num of glyphs 2021-05-07 06:58:55 +05:30
Kovid Goyal
8eac22d37a typo 2021-05-07 06:58:55 +05:30
Kovid Goyal
35fab12330 Dont rely on max glyphs limit for scratch space 2021-05-07 06:58:55 +05:30
Kovid Goyal
a46988bc50 Simplify code by getting rid of ExtraGlyphs 2021-05-07 06:58:54 +05:30
Kovid Goyal
26e1d6fe5c Use uthash for glyph properties as well 2021-05-07 06:58:54 +05:30
Kovid Goyal
ec68739585 Make it harder to forget to redefine uthash_fatal 2021-05-07 06:58:54 +05:30
Kovid Goyal
33de0f821f Use uthash for the sprite position cache 2021-05-07 06:58:54 +05:30
Kovid Goyal
86ce11134a Unicode input kitten: Fix a regression in 0.20.0 that broke keyboard handling when the num lock or caps lock modifiers were engaged.
Fixes #3587
2021-05-07 06:55:25 +05:30
Kovid Goyal
bef4905416 Also remove -pedantic-errors when using --ignore-compiler-warnings
Fixes #3584
2021-05-07 06:26:00 +05:30
Kovid Goyal
baa8152248 Add link to changelog in github release notes
Fixes #3588
2021-05-07 06:18:42 +05:30
Kovid Goyal
34fe103c2b Prefix by GPG signature instead 2021-05-07 06:14:40 +05:30
Kovid Goyal
0d08014bd5 Dont append GPG signature twice to release file descs 2021-05-07 06:13:21 +05:30
Kovid Goyal
dd0130180b Use the kitty fatal function 2021-05-06 11:19:06 +05:30
Kovid Goyal
accdf9a6a8 DRYer 2021-05-06 08:57:38 +05:30
Kovid Goyal
c891432c9d version 0.20.3 2021-05-06 08:11:41 +05:30
Kovid Goyal
1a4efd9d81 Remove unused code 2021-05-06 07:46:31 +05:30
Kovid Goyal
bf462e535a Fix focus changes not being sent to windows when focused window changes because of the previously focused window being closed
Fixes #3571
2021-05-05 14:45:57 +05:30
Kovid Goyal
5cf228e362 Fix tab activity tracking not working unless there is some other activity in tab bar as well
Fixes #3571
2021-05-05 14:30:16 +05:30
Kovid Goyal
4dcccc553c ... 2021-05-05 14:02:58 +05:30
Kovid Goyal
7e53db8aac DRYer 2021-05-05 13:58:10 +05:30
Kovid Goyal
4a83584934 Fix #3576 2021-05-05 13:55:46 +05:30
Kovid Goyal
c735d1f6ac Merge branch 'master' of https://github.com/alexDarcy/kitty 2021-05-05 08:39:44 +05:30
Alexis Praga
7bd0fdf3da Freebsd: use gmake to build docs 2021-05-04 22:48:23 +02:00
Kovid Goyal
b570dfcd09 Move the inline ToC above quickstart
local doesnt work below quickstart and it also serves as a good overview
2021-05-04 11:31:34 +05:30
Kovid Goyal
2bc35539f0 Exclude document titles from local ToCs 2021-05-04 11:19:49 +05:30
Kovid Goyal
80e05319c6 ... 2021-05-04 11:08:04 +05:30
Kovid Goyal
49459b3774 Merge branch 'fix-help-menu-spotlight-search' of https://github.com/Luflosi/kitty 2021-05-04 08:20:58 +05:30
Luflosi
0788032003 macOS: fix spotlight search in help menu not working on some machines
The spotlight search in the "Help" menu of the menu bar did not appear when the system language is set to a language other than English. macOS magically adds the search box when the text in that menu matches the translation of "Help" in the system language. On my German system for example replacing "Help" with "Hilfe" will make the search box appear again. This is however not a good solution for kitty as it would require implementing localization support for all languages. Removing `CFBundleAllowMixedLocalizations=True` from `setup.py` also brings back the search box but that may break the locale again. The line was added in  8818b5d8df to fix an issue related to https://github.com/kovidgoyal/kitty/issues/1233.
Luckily I found a seemingly undocumented function that helps us out here, which does not rely the text comparison magic.
2021-05-02 22:21:09 +02:00
Kovid Goyal
d4c7c205cb Add a changelog entry for universal binaries 2021-05-02 07:35:59 +05:30
Kovid Goyal
96ce33792d Build kitty as a universal binary 2021-05-01 14:58:06 +05:30
Kovid Goyal
13bf8a20b0 Build universal binaries of all deps on macOS 2021-05-01 14:50:22 +05:30
Kovid Goyal
6b9b478492 Linux: Fix keyboard layout change keys defined via compose rules not being ignored 2021-05-01 08:09:26 +05:30
Kovid Goyal
c4e8bcb876 Merge branch 'add_attribution_logo' of https://github.com/MindTooth/kitty 2021-04-29 13:11:23 +05:30
Kovid Goyal
28b4fe5cb6 A new show_key kitten
Fixes #3556
2021-04-29 13:10:20 +05:30
Birger J. Nordølum
58b5e645c6 chore(logo): add missing attribution
The Big Sur template includes a CC BY 4.0 license, hence the attribution
with the details of the change.
2021-04-29 09:11:20 +02:00
Kovid Goyal
3e00ee4155 When releasing also upload GPG signatures
Fixes #3555
2021-04-29 08:08:35 +05:30
Kovid Goyal
d1169a0f37 Fix #3549 2021-04-28 19:46:56 +05:30
Kovid Goyal
c8c22d3dd2 Merge branch 'update_macos_icon' of https://github.com/MindTooth/kitty 2021-04-28 19:22:37 +05:30
Birger J. Nordølum
689fd03250 fix(logo): make the icon more inline with Big Sur
This tries to follow the Human Interface Guidelines
from Apple.
2021-04-28 15:37:13 +02:00
Kovid Goyal
56fe6480ce Merge branch 'patch-1' of https://github.com/kidonng/kitty 2021-04-28 16:00:49 +05:30
Kid
017d5f2991 Fix tasks shortcut on macOS 2021-04-28 16:59:39 +08:00
Kovid Goyal
ae43b1565e DRYer 2021-04-28 13:41:48 +05:30
Kovid Goyal
3206e1b12c ... 2021-04-28 13:11:59 +05:30
Kovid Goyal
93d4eca2d4 Fix kitty.conf man page being installed in incorrect location
Fixes #3543
2021-04-28 13:11:01 +05:30
Kovid Goyal
57b5e493a4 version 0.20.2 2021-04-28 10:50:34 +05:30
Kovid Goyal
fc184984a0 ... 2021-04-27 15:11:34 +05:30
Kovid Goyal
2178ff1c48 DRYer 2021-04-27 15:07:27 +05:30
Kovid Goyal
ae1df38c88 Fallback to mkostemp if O_TMPFILE fails 2021-04-27 12:03:24 +05:30
Kovid Goyal
162e498347 Fix @ set-colors for active_tab_foreground 2021-04-26 20:18:50 +05:30
Kovid Goyal
172023afca Forgot the double backslash in the docs 2021-04-26 17:31:43 +05:30
Kovid Goyal
18c7ea50b4 Cleanup text 2021-04-26 13:46:03 +05:30
Kovid Goyal
bdddb238f8 Also generate a man page for kitty.conf 2021-04-26 13:35:22 +05:30
Kovid Goyal
8d46237935 Add the most common keyboard shortcuts to the kitty man page 2021-04-26 12:39:25 +05:30
Kovid Goyal
3fcf83e685 Use a framed icon on macOS
Fits better with Apple's icon style
2021-04-26 12:07:35 +05:30
Kovid Goyal
d374af4341 Type check supersampled functions 2021-04-26 09:12:38 +05:30
Kovid Goyal
f32ad617a2 Special case rendering of the few remaining Powerline box drawing chars
Fixes #3535
2021-04-26 09:07:55 +05:30
Kovid Goyal
62656b24eb GNOME: Add a new option to control the color of the kitty window titlebar 2021-04-25 11:22:23 +05:30
Kovid Goyal
12763e19d8 Add a build argument to turn off -Werror
Fixes #3530
2021-04-24 18:32:57 +05:30
Kovid Goyal
89fd726e07 A new remote control command @env to change the default environment passed to newly created windows
Fixes #3529
2021-04-24 18:06:57 +05:30
Kovid Goyal
0b428987b1 ... 2021-04-24 18:02:16 +05:30
Kovid Goyal
1e29fad5f0 Typecheck @ls cli opts 2021-04-24 17:51:02 +05:30
Kovid Goyal
19524a4459 Update uthash 2021-04-24 09:47:40 +05:30
Kovid Goyal
7043d565c9 ... 2021-04-24 09:44:40 +05:30
Kovid Goyal
d6f856f2f2 Fix https://trac.macports.org/ticket/62732 2021-04-24 07:43:02 +05:30
Kovid Goyal
24f0451c10 Merge branch 'bug3514-fix' of https://github.com/orki/kitty 2021-04-23 21:27:31 +05:30
Ravi R Kiran
3c4460ca98 Give shift, control and caps lock precedence over other modifiers 2021-04-23 10:47:26 -05:00
Kovid Goyal
cbf33fa14b Fix #3523 2021-04-23 16:23:13 +05:30
Kovid Goyal
d782654819 Forgot to handle case of empty scrollback 2021-04-23 16:07:10 +05:30
Kovid Goyal
3c39cbf333 Add a note about over large scrollback fill 2021-04-23 15:54:21 +05:30
Kovid Goyal
bd746e5151 Add a note about what happens when no scrollback lines are present 2021-04-23 15:48:47 +05:30
Kovid Goyal
b32c346eed A new protocol extension to unscroll the screen
See https://gitlab.freedesktop.org/terminal-wg/specifications/-/issues/30
2021-04-23 15:44:38 +05:30
Kovid Goyal
77b8e204ad Fix graphics being cleared when switching to alt screen if the switch mode is to not clear the alt screen 2021-04-23 14:51:32 +05:30
Kovid Goyal
93dfe19c35 GNOME: Fix maximize state not being remembered when focus changes and window decorations are hidden
Apparently mutter needs window geometry set after the surface commit not
before, otherwise it doesnt "stick". When decorations are not hidden
there were other commits caused by the decorations, masking the issue.

Fixes #3507
2021-04-23 14:04:12 +05:30
Kovid Goyal
6dc8df5178 icat kitten: Respect EXIF orientation when displaying JPEG images
Fixes #3518
2021-04-23 07:31:37 +05:30
Kovid Goyal
237fd73702 Fix removal of inactive tab that is before the currently active tab causing the highlighted tab to be incorrect
Fixes #3516
2021-04-22 22:28:05 +05:30
Kovid Goyal
5f2d0142d1 Re-organize README a bit 2021-04-22 20:32:34 +05:30
Kovid Goyal
572d576d5b Merge branch 'fix-compilation-on-old-macos' of https://github.com/Luflosi/kitty 2021-04-22 14:30:38 +05:30
Luflosi
6606f51636 Fix compilation on macOS 10.12
The constants `NSControlStateValueOn`, `NSControlStateValueOff` and `NSControlStateValueMixed` are only available for macOS 10.13 or above according to https://developer.apple.com/documentation/appkit/nscontrolstatevalueon?language=objc.
Without this commit, compilation fails with this message:
```
glfw/cocoa_window.m:1537:28: error: use of undeclared identifier 'NSControlStateValueOn'
              item.state = NSControlStateValueOn;
                           ^
glfw/cocoa_window.m:1539:28: error: use of undeclared identifier 'NSControlStateValueMixed'
              item.state = NSControlStateValueMixed;
                           ^
glfw/cocoa_window.m:1542:47: error: use of undeclared identifier 'NSControlStateValueOn'
          item.state = controller.isDesired ? NSControlStateValueOn : NSControlStateValueOff;
                                              ^
glfw/cocoa_window.m:1542:71: error: use of undeclared identifier 'NSControlStateValueOff'
          item.state = controller.isDesired ? NSControlStateValueOn : NSControlStateValueOff;
                                                                      ^
```
To fix this, simply redefine the constants to use the old and now deprecated constants on older macOS versions.

The code that causes this was introduced in 98519bf326.
2021-04-22 10:53:34 +02:00
Kovid Goyal
36da65120a It's only alt and alt+shift that dont work in global menubar
alt in combination with ctrl/cmd works fine.
2021-04-22 10:50:43 +05:30
Kovid Goyal
b6c1e1a609 ... 2021-04-22 10:24:57 +05:30
Kovid Goyal
5d003ec772 Fix @close-tab not working with pipe based remote control
Fixes #3510
2021-04-22 10:23:04 +05:30
Kovid Goyal
b9210a2ba4 macOS: Prevent option based shortcuts for being used for global menu actions
Fixes #3515
2021-04-22 10:15:10 +05:30
Kovid Goyal
f3c559ea13 Cleanup secure keyboard entry logging 2021-04-22 09:41:01 +05:30
Kovid Goyal
6cee6b6429 More accurate ignoring message 2021-04-22 09:31:41 +05:30
Kovid Goyal
84f6aabf5b Clean up debug keyboard on macOS 2021-04-22 09:28:11 +05:30
Kovid Goyal
9ce947d6ea Ignore failure to read the readline init file on Linux as well
There are apparently people that like to break things randomly on their
systems by removing needed files. Fixes #3513
2021-04-22 08:13:57 +05:30
Kovid Goyal
0f23ad0d7e Merge branch 'u_int8_t' of https://github.com/sgn/kitty 2021-04-21 18:45:18 +05:30
Đoàn Trần Công Danh
1b760b6c53 freetype_render_ui_text: use uint8_t instead of u_int8_t
uint8_t is a standard type, while u_int8_t isn't. And we're assigning to
an uint8_t anyway.
2021-04-21 19:23:43 +07:00
Kovid Goyal
cdf64bf016 Linux: Fix binary kitty builds not able to load fonts in WOFF2 format
Fixes #3506
2021-04-20 17:07:47 +05:30
Kovid Goyal
f3726023c2 version 0.20.1 2021-04-19 21:45:08 +05:30
Kovid Goyal
cb41683f47 ... 2021-04-19 20:12:20 +05:30
Kovid Goyal
629a8ad055 Fix #3501 2021-04-19 19:58:02 +05:30
Kovid Goyal
4ba0fa00b4 Update changelog 2021-04-19 18:07:03 +05:30
Kovid Goyal
f1e73c015a Merge branch 'hyperlink_unbound_variable' of https://github.com/miseran/kitty 2021-04-19 18:03:18 +05:30
Reto Schnyder
926c3540ff Fix unbound variable in hyperlink handling 2021-04-19 14:19:13 +02:00
Kovid Goyal
1aebd83e45 A little clearer code 2021-04-19 17:42:15 +05:30
Kovid Goyal
8225351145 icat: When displaying an animated GIF image with no delays between frames, add a 100ms delay between every frame.
This allows some broken images tested with broken software *cough* browsers to work.
See #3498
2021-04-19 17:17:45 +05:30
Kovid Goyal
379add8d6f IntEnum was needed 2021-04-19 17:09:23 +05:30
Kovid Goyal
ea11ce8664 Use a normal enum for Dispose rather than an IntEnum 2021-04-19 16:57:43 +05:30
Kovid Goyal
82e9e96f0c Fix CodeQL warnings 2021-04-19 14:00:53 +05:30
Kovid Goyal
8c4e426534 Silence some unused parameter warnings 2021-04-19 13:53:27 +05:30
Kovid Goyal
636771e566 Fix test crashing on 32bit machines 2021-04-19 13:48:39 +05:30
Kovid Goyal
363b20bdd2 Add debug symbols when not stripping 2021-04-19 13:29:50 +05:30
Kovid Goyal
b16317e2ca Silence spurious compiler warning 2021-04-19 13:27:17 +05:30
Kovid Goyal
2c5c869228 Print command used to run tests 2021-04-19 13:14:25 +05:30
Kovid Goyal
3f5f218e0b Use correct printf codes 2021-04-19 13:00:48 +05:30
Kovid Goyal
c9cc425aad version 0.20.0
Fixes #3248
Fixes #3287
2021-04-19 10:14:00 +05:30
Kovid Goyal
9a2b0b6995 Wayland CSD: Double clicking on titlebar should toggle window maximize 2021-04-19 08:58:29 +05:30
Kovid Goyal
50f8aeeaf6 Dont output an error when none is used as a modifier 2021-04-18 18:11:56 +05:30
Kovid Goyal
fe291dd769 ... 2021-04-18 10:46:06 +05:30
Kovid Goyal
58850a0e14 Switch to ALE instead of syntastic 2021-04-17 16:53:48 +05:30
Kovid Goyal
518057489c Also output layout state in kitty @ ls 2021-04-17 12:11:56 +05:30
Kovid Goyal
cf0b2389a3 Also report window sizes in kitty @ ls 2021-04-17 11:49:57 +05:30
Kovid Goyal
6179cfc670 Abort parsing of APC and PM escape codes on 0x00 and 0x7f
Correct as per ECMA-48 section 8.3 and matches parsing of other escape
codes
2021-04-15 12:57:58 +05:30
Kovid Goyal
e6ccc2d178 Fix #3485 2021-04-15 08:57:47 +05:30
Kovid Goyal
db719eafac Remove num/caps locks from modifier processing in mouse events 2021-04-14 10:08:33 +05:30
Kovid Goyal
a4db27a807 Ignore the lock modifiers in legacy mode 2021-04-13 21:35:18 +05:30
Kovid Goyal
111c123435 X11: Fix resize_in_steps being applied even when window is maximized
Fixes #3473
2021-04-13 12:48:23 +05:30
Kovid Goyal
75d067e411 Merge branch 'fix-timg-link' of https://github.com/hzeller/kitty 2021-04-13 11:09:31 +05:30
Henner Zeller
fbeb991f7d Fix timg link (underscore was missing).
Signed-off-by: Henner Zeller <h.zeller@acm.org>
2021-04-12 22:27:32 -07:00
Kovid Goyal
ea2db51bbb Output all modifier indices in debug 2021-04-13 10:21:26 +05:30
Kovid Goyal
15f4c476c3 Ignore locked mods for legacy encoding in a few more places 2021-04-13 10:01:16 +05:30
Kovid Goyal
a7c5b8c634 Fix #3471 2021-04-13 09:53:57 +05:30
Kovid Goyal
1aeafcaebf Remove unused code 2021-04-13 09:02:30 +05:30
Kovid Goyal
8d743e9511 Fix is_self 2021-04-13 08:54:45 +05:30
Kovid Goyal
958d4d8a6a kitty @ ls: Show only environment variables that are different for each window, by default.
Makes the output much less noisy, and env vars that are common across
all windows are useless for selection/identification purposes.
2021-04-13 08:44:11 +05:30
Kovid Goyal
05fb09f56c Fix #3470 2021-04-13 08:23:15 +05:30
Kovid Goyal
cdcf8ed3bd Add some colors to keyboad debug output 2021-04-13 07:41:47 +05:30
Kovid Goyal
572466eed1 XKB: Honor numlock state when reporting keypad keys 2021-04-13 07:35:13 +05:30
Kovid Goyal
4c644b8556 Add NumLock and CapsLock reporting to the keyboard protocol 2021-04-13 07:10:00 +05:30
Kovid Goyal
c989a7198b Add support for the keypad Begin key
Fixes #3468
2021-04-11 07:58:27 +05:30
Kovid Goyal
084b028eac Merge branch 'macos-secure-keyboard-entry' of https://github.com/multi/kitty
This is the usual Apple security theatre. Prevent key loggers from
reading key events from the OS, but those same key events are written to
the unsecured tty device from where the keylogger could read them
anyway.

But, since I dont want to have to explain why this is simply security
theatre to every rando on the internet, merging anyway. It only costs
one line in the application menu and maybe it will make some people that
click on it *feel* more secure.
2021-04-10 14:41:54 +05:30
Kovid Goyal
699d88e393 ... 2021-04-10 14:36:31 +05:30
Kovid Goyal
8c6566580a ... 2021-04-10 14:32:13 +05:30
Kovid Goyal
effe30ad3f Add a FAQ entry about memory leaks 2021-04-10 14:23:28 +05:30
Kovid Goyal
e91b8d4556 ... 2021-04-10 14:08:03 +05:30
Kovid Goyal
76fca0641e Fix memory leak in utf_8_strndup test 2021-04-10 13:39:04 +05:30
Kovid Goyal
7ec803222f Fix a mem leak of the disk cache directory path 2021-04-10 13:21:58 +05:30
Kovid Goyal
03f0f065ee Use a single alloc per history buf segment 2021-04-10 13:18:27 +05:30
Kovid Goyal
63e5be6ff0 Dont use the python memory pool for the history buffer
It's not optimized for this use case
2021-04-10 12:11:05 +05:30
Kovid Goyal
4ccd2afd78 Free ChildMonitor at end of dealloc 2021-04-10 11:49:39 +05:30
Georgi Yonchev
98519bf326 [macos] - Add "Secure Keyboard Entry" menu item 2021-04-09 16:39:51 +03:00
Kovid Goyal
82d11b80dd Add a test for filling from scrollback with large continued line 2021-04-09 17:04:55 +05:30
Kovid Goyal
cf3662442f Fix #3460 2021-04-09 16:56:53 +05:30
Kovid Goyal
0be5347e6a Better error message when screen_resize() fails 2021-04-09 10:09:17 +05:30
Kovid Goyal
1b39c42e92 ... 2021-04-08 12:36:44 +05:30
Kovid Goyal
5b4f5a1e2a Add a link to the nb note taking application 2021-04-08 12:06:02 +05:30
Kovid Goyal
4eb8b1db01 Merge branch 'bug3446-fix' of https://github.com/orki/kitty 2021-04-08 08:37:55 +05:30
Ravi R Kiran
b5555b9a8d Handle multiple real modifiers mapping to the same virtual modifier 2021-04-07 21:36:11 -05:00
Kovid Goyal
67bb426eb2 Fix recent Wayland chagelog entries in the incorrect section 2021-04-08 07:59:34 +05:30
Kovid Goyal
cf3a088a53 Allow running under Wayland on GNOME by default 2021-04-08 07:52:28 +05:30
Kovid Goyal
a79d024c09 Accept window_id as an alias for id when matching 2021-04-08 07:19:45 +05:30
Kovid Goyal
253de1eeca Move the CSD metrics initialization into the CSD module 2021-04-07 22:28:04 +05:30
Kovid Goyal
4e6d5d3f1e Fix GNOME breaking when setting window geometry
The current version of GNOME has a regression that causes the compositor
to send incorrect geometry with the next configure event if the CSD
buffers are created after a call to set_window_geometry.

So call set_window_geometry last. And shake head sadly.
2021-04-07 22:14:09 +05:30
Kovid Goyal
82a5733ec5 _glfwPLatformSetWindowSize() should not be called when handling configure events as it does a bunch of work already done before 2021-04-07 19:55:15 +05:30
Kovid Goyal
4822fa989e Wayland: wire up live resize notification 2021-04-07 18:29:28 +05:30
Kovid Goyal
fe0e1adb2a DRYer 2021-04-07 15:26:30 +05:30
Kovid Goyal
850a8218db Allow toggling xdg configure debug output at runtime 2021-04-07 15:24:58 +05:30
Kovid Goyal
bf3fc5fb92 Also implement programmatic window resizing 2021-04-07 15:13:22 +05:30
Kovid Goyal
a19d1fc140 Restore size after all types of docking not just maximize/unmaximize
We make use of the fact that wayland tells us when the window is being
resized to track actual user requested sizes as opposed to compositor
requested ones.
2021-04-07 15:08:44 +05:30
Kovid Goyal
593eb1d952 Focus state needs to be updated always 2021-04-07 14:28:11 +05:30
Kovid Goyal
75ec801941 Get the window geometry with CSD fully correct (I think)
The co-ordinates are in the surface co-ordinate system. When the
compositor specifies sizes it apparently adds one subsurface size
in both x and y directions, not both. Possibly because the origin is
placed after the top and left subsurfaces. So modify it by adding
and extra subsurface size to that.
2021-04-07 14:21:43 +05:30
Kovid Goyal
5a1bd93518 Handle all known xdg top level states 2021-04-07 13:33:06 +05:30
Kovid Goyal
f849f383cb Use the proper number for wayland CSD vertical shadow geometry
Apparently set_wayland_geometry uses buffer co-ordinates not surface
co-ords so the numbers need to be multiplied by the scale
2021-04-06 22:19:17 +05:30
Kovid Goyal
ac3080f0e2 Fix #3446 (I hope) 2021-04-06 21:51:03 +05:30
Kovid Goyal
0935dd053c Modifier indices are unsigned 2021-04-06 21:45:02 +05:30
Kovid Goyal
7e78f30739 Wayland: Fix un-maximizing a window not restoring its size to what it was before being maximized 2021-04-05 13:47:50 +05:30
Kovid Goyal
d0f34e99a6 Fix fringing in shadow due to using integer operations 2021-04-05 11:09:34 +05:30
Kovid Goyal
c781825b00 Make setting sigma independent of kernel size 2021-04-05 10:55:30 +05:30
Kovid Goyal
7199c62b76 ... 2021-04-05 10:13:33 +05:30
Kovid Goyal
2074a0d958 Forgot that the top margin is scaled 2021-04-05 09:57:44 +05:30
Kovid Goyal
3e2b626107 Inform compositor of visible window geometry
The numbers dont make logical sense, but they do what is expected on
GNOME and since only GNOME is stupid enough to insist on CSD, that's
all we care about.
2021-04-05 09:10:47 +05:30
Kovid Goyal
abf515ece9 Mention that w3m now supports the kitty graphics protocol 2021-04-05 08:15:34 +05:30
Kovid Goyal
07de9c021d Decrease shadow intensity when un-focused 2021-04-04 23:04:12 +05:30
Kovid Goyal
ff420b6495 Render top CSD shadow 2021-04-04 22:49:07 +05:30
Kovid Goyal
78908e5b93 Finish rendering of side shadows for CSD 2021-04-04 20:16:13 +05:30
Kovid Goyal
bd6643a523 Use a tile to reduce startup CPU cost of shadows 2021-04-04 18:16:33 +05:30
Kovid Goyal
71fddeb1f5 Start work on shadow based CSD 2021-04-04 17:13:50 +05:30
Kovid Goyal
9f708be8fd Fix name of wttr -> wttr.in 2021-04-04 17:13:17 +05:30
Kovid Goyal
a13f815591 Fix index_selection() not updating empty selections
Newly created selections are empty but must still be indexed.
Fixes #3431
2021-04-03 10:48:43 +05:30
Kovid Goyal
b5ac06e652 Fix #3422 2021-04-03 06:48:10 +05:30
Kovid Goyal
e56d259b8e Also free() when loading fails 2021-04-03 06:41:11 +05:30
Kovid Goyal
11d13c406a Fix a memory leak when setting default window icon or background image 2021-04-03 06:37:57 +05:30
Kovid Goyal
d5448e6902 Add documentation and cleanup previous PR 2021-04-03 06:25:47 +05:30
Kovid Goyal
777b9eb68e Merge branch 'hyper' of https://github.com/orki/kitty 2021-04-03 06:15:55 +05:30
Kovid Goyal
ff1585acfe Unicode input: Make diamond a synonym for gem
Fixes #3437
2021-04-02 12:53:58 +05:30
Kovid Goyal
cb515157b3 Fix the selection getting changed if the screen contents scroll while the selection is in progress
When the selection object was refactored to track the input
co-ordinates, index_selection() was not updated accordingly.
Fixes #3431
2021-04-01 23:17:13 +05:30
Kovid Goyal
da39fb2880 Add a note about when the splits layout was added to kitty
Bloody Ubuntu/Debian and their absurd release policies.
2021-04-01 23:04:13 +05:30
Kovid Goyal
eb3a2126ee Changelog entry for CSD work
Bloody two days of my life I will never get back thanks to those
*&^(*&%*%*& at GNOME.
2021-04-01 22:57:19 +05:30
Kovid Goyal
9c1c399716 ... 2021-04-01 22:52:13 +05:30
Kovid Goyal
e209c3329b Allow specifying a right_margin that is not rendered for the CSD title
Can void double rendering if I ever decide to add button to the titlebar
2021-04-01 22:50:54 +05:30
Kovid Goyal
802147e255 More robust ellipsis width calculation 2021-04-01 22:18:13 +05:30
Kovid Goyal
1a7291276c Add a cat face emoji at the start of the CSD title 2021-04-01 22:07:37 +05:30
Kovid Goyal
6d6273af48 Properly scale emoji rendered in the CSD 2021-04-01 22:07:00 +05:30
Kovid Goyal
b7d967b6bc Dont offset title from left edge 2021-04-01 18:19:59 +05:30
Kovid Goyal
779a06fa72 DRYer 2021-04-01 13:54:20 +05:30
Kovid Goyal
0656a5079a CSD titles: Render ellipsis when too long 2021-04-01 13:48:58 +05:30
Kovid Goyal
a1669267b3 Fix hiding on window decorations not working with new CSD code 2021-04-01 12:32:48 +05:30
Kovid Goyal
bbb40f2a21 Use a little less contrast for CSD title 2021-04-01 12:20:53 +05:30
Kovid Goyal
c5b3e43b6c Use bold for CSD titles 2021-04-01 12:18:48 +05:30
Kovid Goyal
55dc354e68 Improve at exit cleanup functions
Now they are run in a defined order not based on
the order of initialization
2021-04-01 11:48:36 +05:30
Kovid Goyal
0ec7e6c36f Make the freetype text rendering code re-useable in multiple contexts 2021-04-01 11:28:23 +05:30
Kovid Goyal
b1da76eefa Set CSD color based on focus state 2021-04-01 10:54:22 +05:30
Kovid Goyal
5c6e55d37f Vertically center CSD title 2021-04-01 10:34:22 +05:30
Kovid Goyal
5d496216e0 Implement rendering of titles in CSD 2021-04-01 10:23:04 +05:30
Kovid Goyal
e92ed67021 Add a callback glfw can use to request text rendering 2021-04-01 08:22:06 +05:30
Ravi R Kiran
b074533b29 Fix regression 2021-03-31 08:54:10 -05:00
Kovid Goyal
f3665ddfab Cleanup some used memory 2021-03-31 15:29:28 +05:30
Kovid Goyal
dd2b6119b3 Implement rendering of emoji for CSD 2021-03-31 15:23:05 +05:30
Kovid Goyal
ada3f9e547 Add a wcswidth() implementation useable from C code 2021-03-31 15:19:39 +05:30
Kovid Goyal
0372242d12 Use an enum for UTF8 decoder state 2021-03-31 15:19:27 +05:30
Kovid Goyal
9838a336d5 Make wcwidth-std.h more generally includeable 2021-03-31 15:18:19 +05:30
Kovid Goyal
debd9fe419 Dont render glyphs that would overflow the canvas 2021-03-31 11:06:37 +05:30
Kovid Goyal
73a06b0e9e Text rendering for CSD now works 2021-03-31 11:02:35 +05:30
Ravi R Kiran
fdfba4ea04 Fix pyflakes failures 2021-03-30 14:57:41 -05:00
Ravi R Kiran
953253de99 Implementation of hyper and meta 2021-03-30 14:23:17 -05:00
Kovid Goyal
da0009a46b More work on CSD title rendering 2021-03-30 22:12:54 +05:30
Kovid Goyal
d7e1e53450 More work on text rendering for CSD 2021-03-30 08:25:01 +05:30
Kovid Goyal
4a3c57054f Function to get fallback font for a char 2021-03-29 15:35:38 +05:30
Kovid Goyal
41b9495588 More work on text rendering 2021-03-29 14:56:49 +05:30
Kovid Goyal
cdbc096990 Start work on rendering text for CSDs 2021-03-29 12:15:47 +05:30
Kovid Goyal
53f2df115e Hook up re-render of title bar when title changes 2021-03-29 12:15:47 +05:30
Kovid Goyal
0593158a86 Refactor CSD code to avoid un-needed rerenders and use a single shm pool for all CSD buffers 2021-03-29 12:15:47 +05:30
Kovid Goyal
c1f8372efc Hide edges when not focused 2021-03-29 12:15:47 +05:30
Kovid Goyal
6e3db0be3d Rename variable 2021-03-29 12:15:47 +05:30
Kovid Goyal
0f084faca5 Forgot to scale the title buffer 2021-03-29 12:15:47 +05:30
Kovid Goyal
c6829766bb Properly scale the decorations buffers 2021-03-29 12:15:47 +05:30
Kovid Goyal
e7931b0121 Get rid of the no longer needed viewporter protocol 2021-03-29 12:15:47 +05:30
Kovid Goyal
aeb82e7fb0 Refactor the rendering of CSD on Wayland 2021-03-29 12:15:47 +05:30
Kovid Goyal
1e6fe7785a Dont set the EDITOR env var in child processes
It isnt really needed, since the various kittens dont rely on it
anymore, instead calling get_editor() to get the path to the editor.
Has the nice side-effect of not needing to run the shell at startup
to read its environment. Now the shell is only run if the user calls
the edit config file kitten. Fixes #3426
2021-03-29 11:56:48 +05:30
Kovid Goyal
4edbe0ea4f Remove unnecessary opacity marking for decoration buffers 2021-03-25 16:28:49 +05:30
Kovid Goyal
0788b98ae4 Fix header comment 2021-03-25 16:05:14 +05:30
Kovid Goyal
8a267894f3 Make createShmBuffer re-useable 2021-03-25 16:04:12 +05:30
Kovid Goyal
0510cd47f4 Rename buffer -> edge_buffer 2021-03-25 15:19:11 +05:30
Kovid Goyal
5dbbed3dcc Ignore text input done if serial is incorrect 2021-03-25 15:05:48 +05:30
Kovid Goyal
7b130dc220 Double buffer pre-edit and commit events 2021-03-25 14:59:58 +05:30
Kovid Goyal
d28caf15b2 More glyph grouping fixes 2021-03-25 14:06:16 +05:30
Kovid Goyal
44df11c443 Move CSD metrics into the window object
Makes them potentially configurable
2021-03-25 12:52:09 +05:30
Kovid Goyal
63a50ec066 Use the correct mouse cursor theme on GNOME
Relies on a working desktop settings portal (xdg-desktop-portal-gtk)
2021-03-25 12:20:13 +05:30
Kovid Goyal
3d0cff1f47 Merge branch 'fix-rectircle-subpixel-rendering' of https://github.com/jesseleite/kitty 2021-03-25 09:55:05 +05:30
Jesse Leite
97a8b718dd Merge branch 'master' of https://github.com/kovidgoyal/kitty into fix-rectircle-subpixel-rendering 2021-03-25 00:17:47 -04:00
Kovid Goyal
fc8e147e4a Fix mouse handling when using client side decorations
The mouse co-ordinates used by glfw were all wrong.
2021-03-25 09:27:25 +05:30
Jesse Leite
af4083a8b7 Prevent subpixel rendering via floor/ceil on left/right side of box drawn corners. 2021-03-24 23:56:53 -04:00
Kovid Goyal
7c7933efa9 Fix #3416 2021-03-24 13:17:38 +05:30
Kovid Goyal
317ecbc9fa Wayland: Add support for the text input protocol
Fixes #3410
2021-03-24 11:24:37 +05:30
Kovid Goyal
67445a22d3 ... 2021-03-23 16:33:05 +05:30
Kovid Goyal
62997956a0 Start work on Wayland text input protocol support 2021-03-23 16:33:04 +05:30
Kovid Goyal
df7790fdfe ... 2021-03-23 16:31:25 +05:30
Kovid Goyal
34d06fa3e9 Use a struct for IME update events
Allows for easier extension in the future
2021-03-23 16:05:22 +05:30
Kovid Goyal
a981b46ec9 Use an enum for updateimestate as well 2021-03-23 10:52:11 +05:30
Kovid Goyal
84dcf8fd27 Use an enum for ime_state 2021-03-23 10:42:07 +05:30
Kovid Goyal
11268ffa16 Fix marking of text not working on lines that contain zero cells
Zero cells are passed to the regex engine as spaces, so they must
increment the match_pos counter. Fixes #3403
2021-03-23 10:04:58 +05:30
Kovid Goyal
c0ec60c113 Forgot to change a couple of usages of line_as_unicode 2021-03-23 09:56:58 +05:30
Kovid Goyal
ca7587c084 Allow skipping zero cells when converting a line to unicode 2021-03-23 09:53:22 +05:30
Kovid Goyal
33ecfc6f84 ... 2021-03-22 22:33:30 +05:30
Kovid Goyal
83bbcf0aa1 Graphics protocol: Add a control to allow clients to specify that the cursor should not move when displaying an image
Fixes #3411
2021-03-22 22:16:40 +05:30
Kovid Goyal
ba32e481ca ... 2021-03-22 10:46:41 +05:30
Kovid Goyal
af9da2e495 Make pt_to_px useable in state.c 2021-03-21 07:29:48 +05:30
Kovid Goyal
77f7672e98 ... 2021-03-20 13:19:11 +05:30
Kovid Goyal
9dd8185f37 rectciricle -> rectircle 2021-03-20 13:17:17 +05:30
Kovid Goyal
12f61fd24f super sample factor is included in height 2021-03-20 13:11:26 +05:30
Kovid Goyal
c9864c994f Improve rendering of rounded corners by using a rectcircle equation rather than a cubic bezier
Fixes #3409
2021-03-20 12:59:20 +05:30
Kovid Goyal
9e476127d3 macOS: Add native keyboard shortcut for unicode input
Fixes #3407
2021-03-19 14:44:38 +05:30
Kovid Goyal
fae99a24bf Merge branch 'installation-doc-bug' of https://github.com/Dsantra92/kitty 2021-03-18 18:17:14 +05:30
Deeptendu Santra
8d9ab15c40 Fix installation docs
Added `/` at the applications, otherwise applications may be considered a file if the directory is not present. The addition of `/` also ensures user knows that he/she needs to create new directory if it is not present.
2021-03-18 17:55:53 +05:30
Kovid Goyal
ccafdacc6f Ensure cursor position is correct when filling line buffer 2021-03-18 10:39:08 +05:30
Kovid Goyal
4a996c1f76 Use the final cursor position when calculating number of continued lines in resized buffer 2021-03-17 22:29:59 +05:30
Kovid Goyal
d743aff4bc Make the code to copy lines into linebufs general 2021-03-17 22:02:47 +05:30
Kovid Goyal
0f3ff4e2d9 Scrollback filling should happen after cursor position is finalized 2021-03-17 21:59:11 +05:30
Kovid Goyal
a4d9d948ab ... 2021-03-17 14:45:23 +05:30
Kovid Goyal
32e6c0c6a6 Add a security policy 2021-03-17 14:38:57 +05:30
Kovid Goyal
ba2efaacd8 Fix regression in launching executables as command line arguments without full paths 2021-03-17 14:32:43 +05:30
Kovid Goyal
37e3e29c8c Fix a crash on systems using musl as libc
Fixes #3395
2021-03-17 14:13:50 +05:30
Kovid Goyal
90722ecbe7 historybuf should be used only when current screen is the main linebuf 2021-03-17 13:51:30 +05:30
Kovid Goyal
5a2eaa24d0 Add changelog entry for last PR 2021-03-17 13:49:24 +05:30
Kovid Goyal
071986138b Cleanup previous merge 2021-03-17 13:43:26 +05:30
Kovid Goyal
d61c4a9569 Merge branch 'scrollback-fill-enlarged-window' of https://github.com/elebow/kitty 2021-03-17 12:22:12 +05:30
Eddie Lebow
9fff829ab4 Implement scrollback_fill_enlarged_window 2021-03-17 02:27:59 -04:00
Eddie Lebow
4682da83c1 Add linebuf_continued_lines_count() 2021-03-17 02:27:58 -04:00
Eddie Lebow
c93c87e8fe Add linebuf_add_line_to_top() 2021-03-17 00:09:03 -04:00
Kovid Goyal
f3e2a42c29 Fix #3400 2021-03-16 20:59:54 +05:30
Kovid Goyal
b063c8cda1 Fix inactive tab closing causing active tab to change
Fixes #3398
2021-03-16 18:06:01 +05:30
Kovid Goyal
d360d077d1 Handle the XTMODKEYS escape code
Treat the XTerm specific modifyOtherKeys escape codes as putting the
disambiguate mode on/off the stack. The escape code causes XTerm to use
a (broken, naturally) variant of CSI u encoding for many keys, so we
treat it as going into the disambiguate mode.
2021-03-16 17:46:11 +05:30
Kovid Goyal
a548c31d50 Add links to rasterm and notcurses in the graphics protocol docs 2021-03-16 17:11:01 +05:30
Eddie Lebow
6c44b4f451 Add historybuf_pop_line() 2021-03-15 23:59:26 -04:00
Eddie Lebow
b76491ba82 Add tests for scrollback_fill_enlarged_window 2021-03-15 23:58:11 -04:00
Eddie Lebow
e10919496f Add scrollback_fill_enlarged_window config option 2021-03-15 23:57:43 -04:00
Kovid Goyal
543b7dcf94 Increase the default set of recognized URL prefixes 2021-03-15 12:17:15 +05:30
Kovid Goyal
271c39cc9d Fix reading image index not working on older ImageMagick
Fixes #3384
2021-03-12 12:00:44 +05:30
Kovid Goyal
18186da90e Better error message for people running icat on systems with outdated/broken ImageMagick 2021-03-12 11:28:57 +05:30
Kovid Goyal
02d29d4816 Better error message when ImageMagick does not write correct output filenames 2021-03-12 11:07:42 +05:30
Kovid Goyal
82934b84d6 ... 2021-03-12 08:25:19 +05:30
Kovid Goyal
6177a7d71f Fix duplicated line in graphics protocol delete table
Fixes #3383
2021-03-12 08:06:13 +05:30
Kovid Goyal
1f4fdb174a Fix rendering of the new infinite length ligatures on CoreText
Apparently on CoreText, harfbuzz gives incorrect values for glyph
positions. So we use it only for selection and grouping of glyphs.
Actual positioning is done using CoreText. This means sophisticated
positioning using GPOS tables is probably broken, but that isn't really
useable in a character grid anyway.

Also remove the hack where glyph_centering was done for calt ligatures
as it seems to not be needed with modern FiraCode and CoreText
rendering. Fixes #3372
2021-03-11 20:11:40 +05:30
Kovid Goyal
a94b94cab0 Fix macos-freeze building everything twice 2021-03-11 13:03:45 +05:30
Kovid Goyal
399c700939 Prevent Cocoa from sending us open file events from command line args
We process command line args ourselves, thank you very much.
2021-03-11 10:59:03 +05:30
Kovid Goyal
077097c112 Also implement openFiles 2021-03-10 21:55:00 +05:30
Kovid Goyal
f70c9842f5 macOS: Allow opening script and command
Fixes #3366
2021-03-10 21:33:29 +05:30
Kovid Goyal
0f020d5b37 When passing a directory or a non-executable file as the program to run to kitty open it with the shell, instead of just failing.
Allows using kitty as the program to open directories or shell scripts
from desktop environments.
2021-03-10 14:27:07 +05:30
Kovid Goyal
2eccc81fee Show a message about how to exit --hold 2021-03-10 14:26:11 +05:30
Kovid Goyal
9fdaef1da6 Graphics protocol: Fix suppression of responses not working for chunked transmission
Now the starting escape codes q value is used unless the last escape
code specifies a non-zero q value of its own. Fixes #3375
2021-03-10 09:58:49 +05:30
Kovid Goyal
eb42edff09 Use builtin rfc linking 2021-03-10 08:30:13 +05:30
Kovid Goyal
07f27d0f54 Add a link to RFC 1950 2021-03-10 08:22:59 +05:30
Kovid Goyal
48d2aa14c8 Install libx11-xcb-dev on CI
Looks like it is no longer pre-installed
2021-03-10 08:20:35 +05:30
Kovid Goyal
3c1c8ecd20 Merge branch 'dankamongmen/deflate-docs' of https://github.com/dankamongmen/kitty 2021-03-10 08:07:32 +05:30
nick black
dcb8fcece4 Add some notes to graphics protocol docs
Clarify that RFC1950-style zlib-wrapped deflate (as opposed
to RFC1951-style raw deflate) payloads are sent in the
graphics protocol, and that base64 encoding follows
compression (implied by remarks elsewhere, but go ahead and
make it explicit here).
2021-03-09 18:25:18 -05:00
Kovid Goyal
958ccadc09 Also detect gemini:// URLs when hovering with the mouse
Fixes #3370
2021-03-06 11:12:45 +05:30
Kovid Goyal
c48a42bec5 Merge branch 'add-timg-to-graphics-docs' of https://github.com/hzeller/kitty 2021-03-06 10:48:54 +05:30
Henner Zeller
50858322d6 Add timg (http://timg.sh/) to graphics protocol users program list.
Signed-off-by: Henner Zeller <h.zeller@acm.org>
2021-03-05 20:45:32 -08:00
Kovid Goyal
62912a800a Ban a bunch of unsafe C functions from the codebase
List is taken from the git codebase
2021-03-05 08:26:05 +05:30
Kovid Goyal
1ded78a98c A new command to show the env vars of the kitty process 2021-03-03 16:04:08 +05:30
Kovid Goyal
90c6c2a366 ... 2021-03-03 15:11:05 +05:30
Kovid Goyal
fbe84698c4 Add a FAQ entry about env vars 2021-03-03 15:06:30 +05:30
Kovid Goyal
2c642406d8 Dont exclude glfw.c from LoC as it no longer is largely auto-generated 2021-03-01 10:59:57 +05:30
Kovid Goyal
b811976018 Ensure global shortcuts are never sent to children
This was happening with ctrl+tab and ctrl+shift+tab because cocoa eats
these and so glfw has a workaround to always send them. If they are
added as global shortcuts, for exmaple for next/previous tab they were
then being sent to children
2021-02-28 21:42:57 +05:30
Kovid Goyal
3ee7e5f800 Fix another use after free caused by a re-assigned pointer 2021-02-28 12:30:12 +05:30
Kovid Goyal
945cbca387 hints kitten: When using the linenumber action with a background action, preserve the working directory
Fixes #3352
2021-02-27 09:14:12 +05:30
Kovid Goyal
30c7ff341f DRYer 2021-02-27 09:10:16 +05:30
Kovid Goyal
12d7c7314a Only warn about Wayland's inadequacy once 2021-02-26 19:21:48 +05:30
Kovid Goyal
ce3cd691cc macOS: Add global menu action to detach current tab 2021-02-25 12:27:10 +05:30
Kovid Goyal
81f144df15 macOS: Add entries to global menu bar for creating and changing tabs 2021-02-25 11:54:53 +05:30
Kovid Goyal
78854d4a10 macOS: Disable cocoa tabs
kitty has its own tabs, and macOS inserts confusing menu entries for its
non-functional tabs into the global menu. So disable tabs. Fixes #3325
2021-02-25 11:26:55 +05:30
Kovid Goyal
dc3ad80d24 Window may not be in current os window if triggerred shortcut is detach_window 2021-02-25 07:20:07 +05:30
Kovid Goyal
ed1188dc61 Forgot modifier mask 2021-02-25 07:12:00 +05:30
Kovid Goyal
52347ced85 macOS: Make the global keybinding used for preferences also configurable 2021-02-25 06:58:20 +05:30
Kovid Goyal
5fd6c6b9a1 typos in docs 2021-02-24 14:17:28 +05:30
Kovid Goyal
9e7031f5d8 Dont call window_for_id() unnecessarily 2021-02-24 13:38:38 +05:30
Kovid Goyal
cca590c20a Fix a use-after-free introduced in the recent key handling refactor 2021-02-24 13:32:27 +05:30
Kovid Goyal
863fff8620 Cleanup previous PR 2021-02-24 12:32:26 +05:30
Kovid Goyal
18f42fe4c1 Merge branch 'tab_powerline' of https://github.com/slfotg/kitty 2021-02-24 12:23:11 +05:30
Sam Foster
2a3cc71641 Made powerline tab_bar_style have different display options 2021-02-24 00:14:00 -06:00
Kovid Goyal
bd67814485 Fix building with asan on macOS 2021-02-23 17:06:00 +05:30
Kovid Goyal
40dbf7f1c8 Use log_error instead of print 2021-02-22 08:33:26 +05:30
Kovid Goyal
42a7023203 Fix #3332 2021-02-21 13:18:48 +05:30
Kovid Goyal
14b33a845e Avoid compiler warning about using main as a variable name 2021-02-21 11:20:10 +05:30
Kovid Goyal
56fcbb95ab Key encoding: in legacy mode use legacy encoding for a few more combinations
Some legacy terminal applications get confused seeing CSI u escape
codes. Since it is relatively common to press ctrl or shift and
space/enter/tab/backspace, emit the same bytes as traditional terminals
do for these common keys.
2021-02-21 11:14:25 +05:30
Kovid Goyal
de100ac67c DRYer 2021-02-20 11:39:31 +05:30
Kovid Goyal
2a96d2621c Use cleanup in a few more places to simplify the code 2021-02-19 18:53:30 +05:30
Kovid Goyal
a097f5df23 Use the gcc cleanup attribute in launcher 2021-02-19 18:34:12 +05:30
Kovid Goyal
6a901ea048 Forgot that wayland is not built on CI 2021-02-19 18:09:12 +05:30
Kovid Goyal
dbc1ade5a9 Fallback to importlib_resources on python 3.6 2021-02-19 18:02:15 +05:30
Kovid Goyal
c2a924a5ea Run all tests on the full frozen build using the frozen launcher
Much more comprehensive test coverage at the cost of slightly increasing
the frozen build size.
2021-02-19 17:57:59 +05:30
Kovid Goyal
e06d40cb31 Fix test suite getting type checked accidentally 2021-02-19 15:19:04 +05:30
Kovid Goyal
45d89cfe55 Install importlib.resources on python 3.6 2021-02-19 15:08:47 +05:30
Kovid Goyal
d45a8309cb Dont use VLAs in launcher.c 2021-02-19 15:04:49 +05:30
Kovid Goyal
9cd8637e9c Remove another use of __file__ 2021-02-19 14:49:07 +05:30
Kovid Goyal
38992e25d7 Make the tests into a package
Useful to make the tests runnable in a frozen build.
2021-02-19 14:35:25 +05:30
Kovid Goyal
f25b3c2aee Canonicalize resource pathnames in the frozen build 2021-02-19 13:59:33 +05:30
Kovid Goyal
e3e2261005 Fix resources path in macOS bundle 2021-02-19 13:57:58 +05:30
Kovid Goyal
38a7e77058 Add build test for filesystem locations 2021-02-19 13:42:20 +05:30
Kovid Goyal
a920919b13 Workaround for bug in libxkbcommon/Debian/Ubuntu on en_IN locale
See https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=903373
2021-02-19 12:35:59 +05:30
Kovid Goyal
625f0f77bb Ensure disk cache is cleared 2021-02-19 09:43:57 +05:30
Kovid Goyal
12604072fc Allow querying number cached in ram from c code as well 2021-02-19 09:28:56 +05:30
Kovid Goyal
0341b64748 Allow caching of disk cache entries in RAM 2021-02-18 10:22:42 +05:30
Kovid Goyal
e0620fbb1d Also implement the bypy freeze on macOS 2021-02-17 22:01:09 +05:30
Kovid Goyal
9114bda24c Get the new bypy based freezing process working with linux builds 2021-02-17 15:50:53 +05:30
Kovid Goyal
4cf73204a2 Forgot to exclude modules 2021-02-16 13:57:23 +05:30
Kovid Goyal
55e7f69768 Use importlib.resources to enumerate kitten names 2021-02-16 13:48:02 +05:30
Kovid Goyal
d2a16bc8e8 ... 2021-02-16 13:14:36 +05:30
Kovid Goyal
5fdeb3b3b4 Use a temp dir as cache dir when running tests during freezing on linux 2021-02-16 13:07:45 +05:30
Kovid Goyal
9ad5ef8b2d Fix compilation on ancient Linux distros without sys/random.h 2021-02-16 12:39:18 +05:30
Kovid Goyal
c244bcd978 Allow overriding the location of the kitty base directory in frozen builds 2021-02-16 10:29:19 +05:30
Kovid Goyal
7eb8e1df79 Use importlib to load the shaders 2021-02-16 10:23:18 +05:30
Kovid Goyal
74c4e94c3d ... 2021-02-16 10:21:28 +05:30
Kovid Goyal
275b8ce2e7 Fix #3322 2021-02-15 21:27:52 +05:30
Kovid Goyal
ff1b0a7e1b Maybe it's uuid-dev instead 2021-02-15 16:44:59 +05:30
Kovid Goyal
39026bc45c Apparently fontconfig now depends on uuid 2021-02-15 16:39:07 +05:30
Kovid Goyal
3d9a95d0cd ... 2021-02-15 16:24:39 +05:30
Kovid Goyal
085bc09dfb Micro-optimization 2021-02-15 16:24:04 +05:30
Kovid Goyal
886309850f Dont add alpha when rendering alpha mask on canvas
Instead use the larger of the two alphas. This gives better results
for overlapping text, such as the infinite length ligature glyphs used
by FiraCode. I dont think adding ever gave better results anyway.
2021-02-15 16:08:06 +05:30
Kovid Goyal
ba005e991a Improve handling of infinite length ligatures in newer versions of FiraCode and CascadiaCode.
Now such ligatures are detected based on glyph naming convention.
This removes the gap in the ligatures at cell boundaries. However, at
least in Fira Code the infinite length ligature glyphs define a negative
left side bearing. This means they overlap when drawn consecutively,
leading to unsightly bumps at the joins.

Fixes #2695
2021-02-15 15:49:09 +05:30
Kovid Goyal
912c46fc57 Fix rendering of ligatures in the latest release of Cascadia code
For some reason it puts empty glyphs after the ligature glyph rather than before it.
There is a possibility this fix might break something else, we will see.
Fixes #3313
2021-02-15 11:57:57 +05:30
Kovid Goyal
5675944c0c Recognize remaining ASCII keys for legacy mode as well 2021-02-15 05:33:57 +05:30
Kovid Goyal
6b9c280214 Add a test for encoding of : as a legacy ascii key 2021-02-15 05:27:32 +05:30
Kovid Goyal
19b882a0bd Also handle : as a legacy ASCII key
Fixes #3315
2021-02-15 05:24:21 +05:30
Kovid Goyal
323d5dba7e SingleKey parsing requires ASCII lowercase 2021-02-15 04:55:51 +05:30
Kovid Goyal
cd9755ffb3 Sphinx: replace use of deprecated css_files 2021-02-15 04:35:24 +05:30
Kovid Goyal
fbcdf352ac Allow resizing of OS Window framebuffers to a single cell
This is much smaller than before and essentially works around the issue
of the text being scaled when the window is resized to small sizes. Also
has the nice side effect of making the code simpler for the panel
kitten. Fixes #3307
2021-02-14 22:17:41 +05:30
Kovid Goyal
015fe9054e Fix shifted keys not matching shortcuts in kittens
Broke after keyboard refactoring for new keyboard protocol. Now a key
event will match a shortcut specification if either the mods and key
match or mods without shift and shifted key match. Fixes #3314
2021-02-14 07:52:08 +05:30
Kovid Goyal
9a031c5b0c Bump versions for bundled deps 2021-02-12 12:29:38 +05:30
Kovid Goyal
de0f225c45 Fix #3299 2021-02-09 22:10:40 +05:30
Kovid Goyal
41533bffdd Merge branch 'build_doc' of https://github.com/spenczar/kitty 2021-02-09 07:45:25 +05:30
Spencer Nelson
cdf7c4bf97 Add two more build-time dependencies to the docs 2021-02-08 10:40:15 -08:00
Kovid Goyal
57db384953 Add packaging status to README 2021-02-06 12:10:30 +05:30
Kovid Goyal
9f0785a160 Add a link to the RFC 2021-02-05 11:36:03 +05:30
Kovid Goyal
4541cf8807 Another CodeQL warning 2021-02-05 10:41:35 +05:30
Kovid Goyal
fe07306ff1 Use a nicer decorator for functions that only need to be run once 2021-02-05 10:40:52 +05:30
Kovid Goyal
726d736aac Type check return value of cache_dir 2021-02-05 10:34:17 +05:30
Kovid Goyal
db0360dc81 Fix a bunch of CodeQL warnings 2021-02-05 10:05:54 +05:30
Kovid Goyal
4ba35d4a93 Clear cache_dir lru cache when testing 2021-02-05 09:56:17 +05:30
Kovid Goyal
1d51fca879 Python 3.6 compat 2021-02-05 09:49:46 +05:30
Kovid Goyal
67ca1902a0 Use a cache dir in the cwd on CI 2021-02-05 09:42:01 +05:30
Kovid Goyal
1ef326e220 Better error message 2021-02-05 09:29:56 +05:30
Kovid Goyal
0e483f81ac Compat for python < 3.8 2021-02-05 09:23:54 +05:30
Kovid Goyal
e969dea3b7 Remove unused function 2021-02-05 09:20:58 +05:30
Kovid Goyal
89b4f59efa Update changelog to note animation support 2021-02-05 09:20:02 +05:30
Kovid Goyal
95dc87cf04 Prevent stack overflows when recursing to coalesce frames 2021-02-05 09:12:08 +05:30
Kovid Goyal
3fc29e0d11 ... 2021-02-05 09:03:39 +05:30
Kovid Goyal
cc3b71154d Document the animation protocol 2021-02-05 09:00:19 +05:30
Kovid Goyal
e4e9e29949 Add a note about broadcast kitten to index 2021-02-05 06:33:48 +05:30
Kovid Goyal
7a1785e1e8 Get chunked loading working with frames 2021-02-04 21:04:44 +05:30
Kovid Goyal
5d2baaac38 ... 2021-02-04 17:52:18 +05:30
Kovid Goyal
b479510f6c Allow controlling the number of loops in icat 2021-02-04 17:47:53 +05:30
Kovid Goyal
8033e9fef5 Fix error checking when rendering single frame 2021-02-04 17:16:52 +05:30
Kovid Goyal
83b8c8ea12 Reduce frequency of key frames slightly 2021-02-04 17:08:06 +05:30
Kovid Goyal
a447ba7d76 Fix typo in coalesce function causing incorrect coalesce for more than one level of recursion 2021-02-04 16:50:13 +05:30
Kovid Goyal
450e1c2f95 Use key frames for performance 2021-02-04 16:20:30 +05:30
Kovid Goyal
cf3a01f502 Handle images whose first frame is smaller than the canvas 2021-02-04 15:57:49 +05:30
Kovid Goyal
3925e18964 Use rgba data for opaque animations that uses blended frames 2021-02-04 14:39:06 +05:30
Kovid Goyal
2650c7dd9e Avoid calculation when over px is transparent 2021-02-04 14:26:10 +05:30
Kovid Goyal
0f18fedf13 Add support for animations to icat 2021-02-04 14:18:47 +05:30
Kovid Goyal
f18a56682f Fix animations not resuming when OS window is hidden and then shown 2021-02-04 13:34:27 +05:30
Kovid Goyal
af94e07618 Cache exe lookups 2021-02-04 11:36:59 +05:30
Kovid Goyal
7eba3b6cbc Use the magick executable from IMv7 preferentially 2021-02-04 11:34:32 +05:30
Kovid Goyal
e5ef9d9062 Ensure IM outputs multiple images in rgba format 2021-02-04 11:23:54 +05:30
Kovid Goyal
b72dbc973d Allow controlling how many times an animation will loop 2021-02-03 20:54:43 +05:30
Kovid Goyal
55d0e23c38 ... 2021-02-03 19:29:46 +05:30
Kovid Goyal
d3489712a6 Store mode data per frame 2021-02-03 18:00:36 +05:30
Kovid Goyal
56193f6902 Handle resizing of animated images with blended frames correctly 2021-02-03 17:51:38 +05:30
Kovid Goyal
2dad179285 ... 2021-02-03 16:00:31 +05:30
Kovid Goyal
19f0e2303d Refactor to store frame deltas instead of fully coalesced frames
Trades CPU usage for cache/memory space
2021-02-03 15:49:33 +05:30
Kovid Goyal
c152624634 Rename state variable to be closer to its actual purpose 2021-02-02 09:00:28 +05:30
Kovid Goyal
212906cf7d gap should be gap to next frame not gap from previous frame
Matches usage in the GIF format and makes the concept of gapless
clearer.
2021-02-01 17:08:59 +05:30
Kovid Goyal
bb5c5a8e4f Allow gapless frames 2021-02-01 16:22:36 +05:30
Kovid Goyal
9cf5348c36 Modify ImageMagick wrapper to handle animated images 2021-02-01 14:12:26 +05:30
Kovid Goyal
edf4e14e4c Work on animation support for icat 2021-01-31 20:58:43 +05:30
Kovid Goyal
8fa737f01c Rescan for animated images on various events 2021-01-31 20:58:43 +05:30
Kovid Goyal
f16e22fbec Forgot to convert gaps to monotonic_t 2021-01-31 20:58:43 +05:30
Kovid Goyal
19e0406459 Wire up animation state tracking 2021-01-31 20:58:43 +05:30
Kovid Goyal
354d7c2740 ... 2021-01-31 20:58:42 +05:30
Kovid Goyal
00edb6058e Start work on implementing frame transitions
Also ensure that the correct OS Window is current when uploading images
to GPU.
2021-01-31 20:58:42 +05:30
Kovid Goyal
597267d1d0 root frame gap should be set to the gap of the first received frame 2021-01-31 20:58:42 +05:30
Kovid Goyal
ad4665e638 Add support for newer keys to GraphicsCommand serializer 2021-01-31 20:58:42 +05:30
Kovid Goyal
b21850dd15 Implement updating of current frame on GPU 2021-01-31 20:58:42 +05:30
Kovid Goyal
4098f2d383 Add quota enforcement testing 2021-01-31 20:58:42 +05:30
Kovid Goyal
5eba754c60 Implement animation control escape codes 2021-01-31 20:58:42 +05:30
Kovid Goyal
b35084062d Remove old data from cache when re-using image objects 2021-01-31 20:58:42 +05:30
Kovid Goyal
1d20472759 Avoid a cache move when deleting frames 2021-01-31 20:58:42 +05:30
Kovid Goyal
c0e336a971 DRYer 2021-01-31 20:58:42 +05:30
Kovid Goyal
d76e757d53 Implement delete for frames 2021-01-31 20:58:42 +05:30
Kovid Goyal
43ea58ef48 Start work on delete for frames 2021-01-31 20:58:42 +05:30
Kovid Goyal
17f485d614 Basic frame loading works 2021-01-31 20:58:41 +05:30
Kovid Goyal
35f3312a1e Use shorter cache keys 2021-01-31 20:58:41 +05:30
Kovid Goyal
ca3c49099f Start work on tests for frame loading 2021-01-31 20:58:41 +05:30
Kovid Goyal
6631bb0eac Make the image dict more complete 2021-01-31 20:58:41 +05:30
Kovid Goyal
0adbbc6d62 Implement loading of frame animation data 2021-01-31 20:58:41 +05:30
Kovid Goyal
cc4f9ddad8 More work an animation handling 2021-01-31 20:58:41 +05:30
Kovid Goyal
5a182d3d13 Store image data in a disk cache 2021-01-31 20:58:41 +05:30
Kovid Goyal
c60d3af60b Add links to locations for discussion to README
Proof of reddit account:
1e2b9113-2d30-48f0-8f2f-f7a2bcbd4895
2021-01-31 20:54:21 +05:30
Kovid Goyal
4e67a92ec4 DRYer 2021-01-31 12:26:54 +05:30
Kovid Goyal
e43c3118d4 ... 2021-01-31 12:14:36 +05:30
Kovid Goyal
ffc0919790 Allow setting colors when creating windows using the launch command. 2021-01-31 12:13:27 +05:30
Kovid Goyal
2af145879e Make color spec parsing re-useable 2021-01-31 12:10:45 +05:30
Kovid Goyal
35517d3e6f Allow using the full launch command in session files
Note this is slightly backward incompatible.
2021-01-31 11:37:00 +05:30
Kovid Goyal
e9e8ef7210 ssh kitten: Allow using python instead of the shell on the server 2021-01-31 09:04:46 +05:30
Kovid Goyal
ee198ca863 Add versionadded notes 2021-01-31 07:42:01 +05:30
Kovid Goyal
0681e6a9b6 ... 2021-01-31 07:35:58 +05:30
Kovid Goyal
965a6dfd30 Add some more kittens to the list 2021-01-31 07:18:27 +05:30
Kovid Goyal
d55fde9eea Use EINTR safe wrappers for open() and shm_open() 2021-01-31 07:02:11 +05:30
Kovid Goyal
231f054bc3 Merge branch 'master' of https://github.com/dlh/kitty 2021-01-31 06:47:01 +05:30
Daniel Lee Harple
43fafd85f8 Allow cancellation of "detach_window ask" 2021-01-30 19:21:11 -05:00
Kovid Goyal
8a5a7b8807 Merge branch 'master' of https://github.com/dlh/kitty 2021-01-30 10:07:16 +05:30
Daniel Lee Harple
2c24cc1341 Allow quoted args to toggle_marker 2021-01-29 17:52:24 -05:00
Kovid Goyal
0fc93118f2 Make the error message when failing to get monitor display name more informative 2021-01-29 12:45:22 +05:30
Kovid Goyal
ac2a33d09f Silence the errors about OSC 7
Up to now this poorly designed and completely unnecessary escape code
was relegated to only GNOME, however, off late Apple has started using
it as well, so silently ignore it, instead of spamming error messages
for it.
2021-01-29 12:43:41 +05:30
Kovid Goyal
68423b3603 Fix compiler warning on newer Xcode
Fixes #3271
2021-01-29 11:29:29 +05:30
Kovid Goyal
6d18223f17 Use an id for keyboard focus tracking as well 2021-01-29 11:22:39 +05:30
Kovid Goyal
0443e5ad7f Wayland: Use window ids rather than pointers to track windows for key repeat
Might fix #3266
2021-01-29 08:43:00 +05:30
Kovid Goyal
4619921780 Add a link to the thread with discussion on using vim as pager 2021-01-29 08:35:15 +05:30
Kovid Goyal
df89266c03 diff kitten: Implement recursive diff over SSH
Fixes #3268
2021-01-28 14:23:56 +05:30
Kovid Goyal
36ca3838a6 Fix #3265 2021-01-27 17:19:06 +05:30
davidak
60ce88cf25 Update Nix package link 2021-01-27 13:43:21 +05:30
Kovid Goyal
5a2f2767ad Fix window icon not working on X11 with 64bits
Apparently on X11 the maximum icon size is 128x128. 256x256 is too
large for the X11 protocol because the X server unserializes the icons
using "unsigned long" which is 64 bits on Linux. So we have to use
64bits per pixel instead of 32, with 32bits padded to 0.

While there I also got rid of the kitty.rgba file replacing it with a
128x128 PNG file.

Fixes #3260
2021-01-25 20:54:19 +05:30
Kovid Goyal
6e73d3fac8 Fix extra space at bottom of OS window when using the fat layout with the tab bar at the top
Fix #3258
2021-01-25 09:30:14 +05:30
Kovid Goyal
d08ae5466d Dont use a function 2021-01-24 12:57:39 +05:30
Kovid Goyal
fc175732e1 Fix CodeQL warning 2021-01-24 12:48:47 +05:30
Kovid Goyal
dfe41217f8 Start work on allowing images to have multiple frames 2021-01-24 12:37:21 +05:30
Kovid Goyal
4870d07cbb Refactor handle_add_command to make it more readable 2021-01-24 12:00:35 +05:30
Kovid Goyal
2dd9fd83a3 Add some text to the control reference 2021-01-23 13:44:10 +05:30
Kovid Goyal
0b93153656 Add the I key to the control data reference 2021-01-23 13:20:32 +05:30
Kovid Goyal
714d64c417 Get type checking working with mypy 0.80
Add workaround for https://github.com/python/typeshed/issues/4964
2021-01-23 09:25:31 +05:30
Kovid Goyal
b823af00ff Get rid of a bunch of noqas 2021-01-22 22:04:53 +05:30
Kovid Goyal
77f456bd9c Fix #3253 2021-01-22 21:06:58 +05:30
Kovid Goyal
874fe2ed72 ... 2021-01-22 20:36:39 +05:30
Kovid Goyal
786f8c7b1f macOS: Ensure font size is correct if the OS moves the newly created window to a different monitor after it is shown 2021-01-22 20:22:09 +05:30
Kovid Goyal
0c784346cc Update blurb 2021-01-21 12:14:44 +05:30
Kovid Goyal
2ab0ff74c6 ... 2021-01-21 11:34:21 +05:30
Kovid Goyal
22cb9b9798 Add a note about kbs = backspace 2021-01-21 11:29:01 +05:30
Kovid Goyal
2ee1a366fd Also assert non-negative params for SET_MODE 2021-01-21 07:21:23 +05:30
Kovid Goyal
f9844ba3b0 Allow negative numbers in CSI codes 2021-01-21 07:06:43 +05:30
Kovid Goyal
7cea233de3 - is not a CSI start modifier 2021-01-21 06:44:18 +05:30
Kovid Goyal
e4d8aac3d5 Make CSI parsing a bit more spec compliant
Now the full list of secondary characters (intermediate bytes) is used from ECMA 48
Also the codes that accept only one parameter now report errors when
multiple parameters are passed.
2021-01-21 06:41:27 +05:30
Kovid Goyal
354d381372 Oops forgot to regen glfw wrapper 2021-01-21 05:37:13 +05:30
Kovid Goyal
60e589f775 Recognize Hyper key
Also use only one implementation for detecting if a key is a modifier
key
2021-01-21 05:33:14 +05:30
Kovid Goyal
f6d4b8e0b0 typo 2021-01-20 18:30:22 +05:30
Kovid Goyal
5fafd70b0f Fix detection of ASCII control chars in key event text 2021-01-20 17:35:24 +05:30
Kovid Goyal
dcfeab8461 Remove un-needed code
Space is now handled as legacy ascii key
2021-01-20 16:08:15 +05:30
Kovid Goyal
2a8e8d4b38 Fix #3252 2021-01-20 16:02:28 +05:30
Kovid Goyal
e6644aebcb Add a test to ensure caps lock does not produce bytes in legacy mode 2021-01-19 09:19:34 +05:30
Kovid Goyal
654cd54363 Add the ISO level 3 and 5 shift keys to functional keys 2021-01-19 09:11:44 +05:30
Kovid Goyal
16005d43e8 Dont send unknown keys that dont generate text
Fixes #3249
2021-01-19 09:01:52 +05:30
Kovid Goyal
b08c93032b ... 2021-01-19 08:58:06 +05:30
Kovid Goyal
dd08896c70 Lock keys should not be sent to applications in legacy mode 2021-01-19 08:55:01 +05:30
Kovid Goyal
f0ae5dfc73 ... 2021-01-18 16:31:09 +05:30
Kovid Goyal
0adc7e4d4b fix typo 2021-01-18 16:30:02 +05:30
Kovid Goyal
5c2056a7cb Fix parsing of + as a shortcut 2021-01-17 19:56:32 +05:30
Kovid Goyal
f0e7d26409 Fix typo 2021-01-17 19:12:12 +05:30
Kovid Goyal
95ebeebb84 Mention alternate screen mode in the quickstart 2021-01-17 11:41:35 +05:30
Kovid Goyal
a88875f98e ... 2021-01-17 11:17:31 +05:30
Kovid Goyal
39da92d8ab Now that glfw reports shifted keys, use it when encoding key events 2021-01-17 11:14:44 +05:30
Kovid Goyal
089d358031 ... 2021-01-17 09:06:03 +05:30
Kovid Goyal
6a4885df17 Add changelog entries for the new keyboard features 2021-01-17 08:52:10 +05:30
Kovid Goyal
d45d553eaf When using a non-US keyboard layout and pressing ctrl+key when the key matches an English key in the default layout, send that to the program running in the terminal automatically
See #2000
2021-01-17 08:25:19 +05:30
Kovid Goyal
2cbbd84987 Clean up some formatting 2021-01-17 07:34:35 +05:30
Kovid Goyal
1016586611 Fix compiler warning 2021-01-17 07:28:22 +05:30
Kovid Goyal
6bbf014152 ... 2021-01-17 07:24:12 +05:30
Kovid Goyal
4fea7bd8ef Fix building on systems with xkbcommon < 1.0 2021-01-17 07:22:21 +05:30
Kovid Goyal
aa63bf71cf macOS: Add menu items to close the OS window and the current tab
Fixes #3246
2021-01-17 06:49:25 +05:30
Kovid Goyal
4c9bd368c6 Implement alternate keys on macOS 2021-01-16 20:52:16 +05:30
Kovid Goyal
b1c1c497e4 More character key name aliases 2021-01-16 20:52:16 +05:30
Kovid Goyal
86ce72e725 Port the Cocoa backend to use unicode key numbers 2021-01-16 20:52:16 +05:30
Kovid Goyal
ae37b4b09b Add more character key aliases 2021-01-16 20:52:15 +05:30
Kovid Goyal
5ffbee1e8c Use shifted keys to match shortcuts as well 2021-01-16 20:52:15 +05:30
Kovid Goyal
19a3635c64 Dont send release events for kitty shortcuts to children 2021-01-16 20:52:15 +05:30
Kovid Goyal
3c648c05ec Report shifted and alternate keys from the XKB backend 2021-01-16 20:52:15 +05:30
Kovid Goyal
5607a3c2ed ... 2021-01-16 20:52:15 +05:30
Kovid Goyal
cf04a5a036 Add tests for encode/decode roundtripping 2021-01-16 20:52:15 +05:30
Kovid Goyal
c12680895e Fix key state tracking regression 2021-01-16 20:52:15 +05:30
Kovid Goyal
0163bf3edb Fix enter/tab/backspace not being reported in all keys mode 2021-01-16 20:52:15 +05:30
Kovid Goyal
af0a24c702 Make key demo output prettier 2021-01-16 20:52:15 +05:30
Kovid Goyal
7ea1deba8f Clean up code tables 2021-01-16 20:52:15 +05:30
Kovid Goyal
b60c84ecdc Add note on detection of support 2021-01-16 20:52:15 +05:30
Kovid Goyal
e09ed038e2 Port key handling in more kittens
Also fix decoding of enter/f3 key events
2021-01-16 20:52:15 +05:30
Kovid Goyal
9c6ba213f9 Fix key handling in diff kitten 2021-01-16 20:52:14 +05:30
Kovid Goyal
66341111e6 keyboard mode change should happen only in alternate screen 2021-01-16 20:52:14 +05:30
Kovid Goyal
abc1e3f289 Remove the function used to init glfw key events
Instead use C99 struct initializers. Much less error prone.
2021-01-16 20:52:14 +05:30
Kovid Goyal
027c5a57f1 Work on porting kittens to use new key infrastructure
Also move type definitions into their own module
2021-01-16 20:52:14 +05:30
Kovid Goyal
0714fd376b Fix handling of ctrl key in legacy mode
Also change the glfw constants used for the modifiers to match those
used in the terminal encoding. Less likely to make mistakes translating
that way.
2021-01-16 20:52:14 +05:30
Kovid Goyal
39f41faf9f Dont send events for modifier keys unless in all key mode 2021-01-16 20:52:14 +05:30
Kovid Goyal
6b2ffc774f Port shortcut and sequence matching code 2021-01-16 20:52:14 +05:30
Kovid Goyal
f94a5f4e5c Add a Quickstart section to the protocol documentation 2021-01-16 20:52:14 +05:30
Kovid Goyal
c421fd56be Ensure typing in shell works in disambiguate mode 2021-01-16 20:52:14 +05:30
Kovid Goyal
11de87d9d9 It's ok that Enter and F3 share a number
Enter has u has trailer, F3 has either ~ or 1R
2021-01-16 20:52:14 +05:30
Kovid Goyal
8f5d42fa11 Python wrapper for key events from window system 2021-01-16 20:52:14 +05:30
Kovid Goyal
e14fcf5590 Clean up docs 2021-01-16 20:52:14 +05:30
Kovid Goyal
f5b81c7ed6 ... 2021-01-16 20:52:13 +05:30
Kovid Goyal
47a901385f Implement reporting of all keys as escape codes with text 2021-01-16 20:52:13 +05:30
Kovid Goyal
819bd5cd70 Tests for alternate key reporting 2021-01-16 20:52:13 +05:30
Kovid Goyal
753ad68ca9 Add tests for event type reporting 2021-01-16 20:52:13 +05:30
Kovid Goyal
5498f4e526 ... 2021-01-16 20:52:13 +05:30
Kovid Goyal
83a01b6bf4 Add tests for the disambiguate flag 2021-01-16 20:52:13 +05:30
Kovid Goyal
c519013b20 Add tests for legacy letter key encodings 2021-01-16 20:52:13 +05:30
Kovid Goyal
78d45eb161 Port another use of the old key API 2021-01-16 20:52:13 +05:30
Kovid Goyal
eeacac227a Add tests for functional KP keys 2021-01-16 20:52:13 +05:30
Kovid Goyal
529e9f83f7 Finish up functional key tests 2021-01-16 20:52:13 +05:30
Kovid Goyal
5297f7474d Remove another use of GLFW_KEY 2021-01-16 20:52:13 +05:30
Kovid Goyal
e06b48a344 Identify SS3 in the docs 2021-01-16 20:52:13 +05:30
Kovid Goyal
7ba57ebf62 esc also needs a low number 2021-01-16 20:52:12 +05:30
Kovid Goyal
1ec9a8b777 Fix parsing of shortcuts to support the new keys 2021-01-16 20:52:12 +05:30
Kovid Goyal
1690718710 More removal of GLFW_KEY_ constants 2021-01-16 20:52:12 +05:30
Kovid Goyal
774a6c8c8b Remove glfw key constants 2021-01-16 20:52:12 +05:30
Kovid Goyal
f06eee8fe1 Define special numbers in one place only 2021-01-16 20:52:12 +05:30
Kovid Goyal
2b12bcc07f Docs for legacy functional encoding 2021-01-16 20:52:12 +05:30
Kovid Goyal
a30ea2b7f8 Implement progressive enhancement of key event reporting 2021-01-16 20:52:12 +05:30
Kovid Goyal
295e8db04c remove unused code 2021-01-16 20:52:12 +05:30
Kovid Goyal
b63ae10a09 Start documenting new keyboard protocol 2021-01-16 20:52:12 +05:30
Kovid Goyal
c8a9336160 Code to encode key events 2021-01-16 20:52:12 +05:30
Kovid Goyal
c0b6078438 Add more keypad keys 2021-01-16 20:52:11 +05:30
Kovid Goyal
ccce8c32a3 Mapping to unicode and back for XKB keys 2021-01-16 20:52:11 +05:30
Kovid Goyal
8f8be9c2b1 Add notice to not edit generated code 2021-01-16 20:52:11 +05:30
Kovid Goyal
eb8e2225e5 Add some more functional keys
Also define aliases for XKB codes
2021-01-16 20:52:11 +05:30
Kovid Goyal
397d7d044b Change key data type in some functions 2021-01-16 20:52:11 +05:30
Kovid Goyal
a681162326 Start work on supporting arbitrary unicode keys 2021-01-16 20:52:11 +05:30
Kovid Goyal
f00ec0ff60 Merge branch 'm1-build-fix' of https://github.com/pjjw/kitty 2021-01-15 10:52:01 +05:30
Peter Woodman
35982a9e58 Make is_arm predicate work on macos 2021-01-15 00:09:24 -05:00
Kovid Goyal
cf0bdf4d59 Add another couple of integrations 2021-01-14 06:36:18 +05:30
Kovid Goyal
8a9d43e84d Changelog item for last PR 2021-01-13 06:58:01 +05:30
Kovid Goyal
578bf963e3 Merge branch 'master' of https://github.com/quentin-fox/kitty 2021-01-13 06:57:25 +05:30
Quentin Fox
292c4ce450 add menu item to close window 2021-01-12 19:55:51 -05:00
Kovid Goyal
8ea589e5a3 Change blurb wording slightly 2021-01-12 20:01:44 +05:30
Kovid Goyal
ad09ccb0f2 Panel kitten: Allow setting WM_CLASS
Fixes #3233
2021-01-12 04:49:45 +05:30
Kovid Goyal
edfc6903ce Remove unused code 2021-01-08 13:32:52 +05:30
Kovid Goyal
b94d2b27f4 Refactor single key config parsing to use a special type 2021-01-07 18:07:17 +05:30
Kovid Goyal
31cb68840a Merge branch 'bugfix-unicode-names-input' of https://github.com/purxiz/kitty
Fixes #3221
2021-01-07 14:18:24 +05:30
purxiz
89c62377da fix type error
I moved the location of the check for an overflowing index to avoid a type error that was revealed by mypy. I also think this is a better place to put it from a code standpoint in general...
2021-01-06 13:24:38 -06:00
purxiz
85afda8832 fixes incorrect hint base
The bases for the hint were being decoded as base 16, despite being displayed as base 36 (0-9, a-z). This fix makes it so typing 'search string .index' returns the unicode char at the expected index, based on what is displayed by the program.

It also slightly changes the behavior. Before, only the selected result would appear. For example, musical note `musical note .18` would only show a single result, since there was only a single result at index 18. Now, searching by index doesn't remove codepoints/results, it simply highlights the result at the correct index for you.
2021-01-06 13:07:41 -06:00
Kovid Goyal
5184e4bde3 Fix #3217 2021-01-06 22:31:09 +05:30
Kovid Goyal
133b580262 Avoid error prints when rendering the space glyph and freetype fails to load it
Also a micro-optimization, since there is no need to actually render the
space glyph
2021-01-05 12:21:06 +05:30
Kovid Goyal
3e76cf87ce Linux: Fix rendering of emoji followed by the graphics variation selector not being colored with some fonts
Harfbuzz, for some reason has started rendering variation selector
glyphs. These fail to load for some fonts. https://github.com/harfbuzz/harfbuzz/issues/2804

Fixes #3211
2021-01-05 09:35:21 +05:30
Kovid Goyal
f72ff73344 Correct return type 2021-01-05 09:17:17 +05:30
Kovid Goyal
9aae346ab5 Better error message when failing to load glyph 2021-01-05 09:10:35 +05:30
Kovid Goyal
ca65ad6fa3 Inline qsort
Cleaner, more local code and faster sorting by virtue of inlining the
comparisons. What's not to like.
2021-01-04 14:14:15 +05:30
Kovid Goyal
0f4156c564 ... 2021-01-04 13:15:29 +05:30
Kovid Goyal
3a0d3dc0b3 Slightly improved command line 2021-01-04 13:14:14 +05:30
Kovid Goyal
d68c338304 Wait for write and check data, fixes test failure 2021-01-04 12:27:26 +05:30
Kovid Goyal
82f8c59bc7 ... 2021-01-04 12:18:42 +05:30
Kovid Goyal
c55f485166 Add an example of using the remote control protocol from a shell script 2021-01-04 12:17:20 +05:30
Kovid Goyal
2762488c81 Remove double increment 2021-01-03 21:10:37 +05:30
Kovid Goyal
ac13ae727f Fix failing test
We cant know what the size of the disk cache file is,
since defragmentation occurs asynchronously
2021-01-03 21:05:08 +05:30
Kovid Goyal
1b59a1c421 Finish tests of disk cache 2021-01-03 17:36:40 +05:30
Kovid Goyal
df00e9545d Add some more ensure_state() 2021-01-03 12:13:08 +05:30
Kovid Goyal
d1496f1eb5 Use O_TMPFILE when available 2021-01-03 07:07:50 +05:30
Kovid Goyal
14d9bcb08a Go back to nanosleep since it is in POSIX 2021-01-03 06:45:53 +05:30
Kovid Goyal
c869774c58 More tests for the disk cache 2021-01-03 06:22:48 +05:30
Kovid Goyal
18679348b2 Use usleep rather than nanosleep 2021-01-03 05:00:40 +05:30
Kovid Goyal
b3ed4c3f40 Simplify implementation of REP
Also make it align more with the standard by using the actual last drawn
graphics character rather than the character before the cursor
2021-01-03 04:38:02 +05:30
Kovid Goyal
8f58140419 Start work on tests for disk cache 2021-01-03 04:28:48 +05:30
Kovid Goyal
bc8a351558 Add repeat character to client.py 2021-01-02 12:49:33 +05:30
Kovid Goyal
9ae198ef8f Double clicking on empty tab bar area now opens a new tab
Fixes #3201
2021-01-02 11:45:18 +05:30
Kovid Goyal
bc86bc91f7 Auto-defrag cache file 2021-01-02 11:32:38 +05:30
Kovid Goyal
a60f347648 Merge branch 'kitten-diff-select-fg-none' of https://github.com/tomaskrizek/kitty 2021-01-02 09:01:25 +05:30
Tomas Krizek
dbe44c9e4b kitten/diff: allow specifying none color for select_fg
Allow diff kitten to not override foreground color for selections.

Related #1358
2021-01-01 23:25:06 +01:00
Tomas Krizek
fb8b9b3933 kitty/config_data: remove duplicate function
selection_foreground() serves the exact same purpose as
to_color_or_none()
2021-01-01 23:23:47 +01:00
Kovid Goyal
56ebc9fa92 Add a link to ctx.graphics 2021-01-01 15:20:47 +05:30
Kovid Goyal
7f73609c77 Update total_size when removing cache items 2021-01-01 14:31:57 +05:30
Kovid Goyal
3ac70042c1 Expose grman disk cache to python 2021-01-01 14:19:10 +05:30
Kovid Goyal
61637a7a74 Simplified API t read from disk cache
Avoids the need to pass a custom allocator by using malloc
2021-01-01 14:16:26 +05:30
Kovid Goyal
49562e96cc Python wrappers for the disk cache methods 2021-01-01 14:08:23 +05:30
Kovid Goyal
58b1868536 When cache is emptied clear disk file to avoid fragmentation 2021-01-01 13:15:21 +05:30
Kovid Goyal
1cad40e977 ... 2021-01-01 12:03:09 +05:30
Kovid Goyal
9fbf23fdcc Implement simple defrag for on-disk cache 2021-01-01 11:54:13 +05:30
Kovid Goyal
55e53db184 ... 2020-12-31 15:38:57 +05:30
Kovid Goyal
f790e8bd47 DRYer 2020-12-31 15:33:04 +05:30
Kovid Goyal
54de2d177e Enforce max key size
Also allocate it dynamically
2020-12-31 15:30:55 +05:30
Kovid Goyal
ec96771e4c track total size and since each cache has its own writer thread store current key per thread 2020-12-31 15:24:25 +05:30
Kovid Goyal
99d2647335 Code to write to cache file 2020-12-31 15:18:30 +05:30
Kovid Goyal
c346cbc252 Use a single file for the disk cache
This has the advantage that on crash it is automatically cleaned
2020-12-31 13:54:33 +05:30
Kovid Goyal
3c77290c2c Code to get random bytes in C, cross-platform 2020-12-31 11:26:22 +05:30
Kovid Goyal
72d193e852 Fix python3.7 fork registration not working 2020-12-31 10:38:26 +05:30
Kovid Goyal
1f7499e841 Detect more types of BSD 2020-12-31 10:26:15 +05:30
Kovid Goyal
c486fbb7c3 Add some aliases for shift key shenanigans 2020-12-30 21:09:03 +05:30
Kovid Goyal
fe1050fc0e More work on disk cache 2020-12-30 14:26:38 +05:30
Kovid Goyal
3162d391cc Start work on disk cache 2020-12-29 19:16:21 +05:30
Kovid Goyal
e2d61ab5be Fix error handling for pthread create 2020-12-29 15:53:40 +05:30
Kovid Goyal
2a026de526 More sophisticated PATH resolution for the launch command 2020-12-29 11:51:17 +05:30
Kovid Goyal
c1b7023e3a Look in ~/.local/bin preferentially 2020-12-29 11:50:11 +05:30
Kovid Goyal
175ff4b955 DRYer 2020-12-29 11:36:30 +05:30
Kovid Goyal
65361d56c4 Use find_exe() for resolving editor as well
Avoids having to exec the shell in most cases
2020-12-29 11:33:42 +05:30
Kovid Goyal
08fae7a0ac Add sbin to default paths 2020-12-29 10:50:31 +05:30
Kovid Goyal
a7e9030c12 Make finding ImageMagick a bit more robust on macOS 2020-12-29 10:48:26 +05:30
Kovid Goyal
aa8282f8f2 Update actual terminfo files from last PR
Also add entry to changelog
2020-12-29 10:03:56 +05:30
Kovid Goyal
7155400eb5 Merge branch 'bawr/terminfo-u6789' of https://github.com/bawr/kitty 2020-12-29 10:02:17 +05:30
Kovid Goyal
6760e38d93 Callback to create tempdir in cache 2020-12-29 10:00:34 +05:30
Bartosz Wróblewski
6bbe995d64 Generate u[6789] with terminfo.py
Should not hurt anything, it's just documenting kitty's existing VT220 compatibility.
2020-12-28 14:05:25 -08:00
Kovid Goyal
85bc8b61df Make wm_class/wm_name available in @ ls output 2020-12-26 10:46:07 +05:30
Kovid Goyal
a235509fa1 Make aliasing ssh kitten more prominent 2020-12-24 13:56:17 +05:30
Kovid Goyal
2e5b595a82 Clarify color table docs 2020-12-24 13:54:09 +05:30
Kovid Goyal
5f8dee8384 Add support for the color settings stack that XTerm copied from us without acknowledgement and decided to use incompatible escape codes for.
Completely in keeping with that project's past behavior.
See https://github.com/kovidgoyal/kitty/issues/879

XTerm announcement:
https://www.mail-archive.com/xorg@lists.x.org/msg06419.html
2020-12-21 21:39:05 +05:30
Kovid Goyal
e97f1a4310 Have the save/restore colors escape codes also save restore the ANSI color table 2020-12-21 19:38:03 +05:30
Kovid Goyal
c3c5a5446f Add window_id and window_title fields to --match-tab 2020-12-20 19:39:09 +05:30
Kovid Goyal
3ce04c3e4b version 0.19.3 2020-12-19 08:19:34 +05:30
Kovid Goyal
3b5951eb2f Add a note about aliasing the SSH kitten 2020-12-18 16:59:42 +05:30
Kovid Goyal
aa8dd4ddf4 ... 2020-12-17 11:30:37 +05:30
Kovid Goyal
4cd14aee42 Add a changelog entry for the last merge
Also some misc code/docs cleanups for it.
2020-12-17 11:24:38 +05:30
Kovid Goyal
0b2726ec33 Cleanup fc_match_postscript_name 2020-12-17 11:16:51 +05:30
Kovid Goyal
bc7f689165 Clean up pattern_as_dict 2020-12-17 11:12:35 +05:30
Kovid Goyal
6681652c21 Merge branch 'master' of https://github.com/Diaoul/kitty 2020-12-17 11:02:26 +05:30
Kovid Goyal
ed4b5f179e Full screen kittens: Fix incorrect cursor position after kitten quits
DECOM should be reset only after entering alternate screen as it also
changes cursor position. Fixes #3176
2020-12-17 08:58:44 +05:30
Kovid Goyal
e48e166584 And another 2020-12-17 08:41:58 +05:30
Kovid Goyal
e7675e8bab Add some more commands to the client 2020-12-17 08:37:55 +05:30
Antoine Bertin
cf7eaea88c Add documentation 2020-12-16 18:01:14 +01:00
Antoine Bertin
3e0855ff45 Properly convert font_features to a list 2020-12-16 17:52:43 +01:00
Antoine Bertin
822c9367c6 Support default font_features from fontconfig 2020-12-16 14:58:38 +01:00
Kovid Goyal
0e46e2a6a7 Forgot to add new delete flags to reference table 2020-12-16 19:07:25 +05:30
Kovid Goyal
ade7ef19e7 Fix #3173 2020-12-16 19:00:31 +05:30
Kovid Goyal
e82a6dedd9 Fix deletion with image numbers 2020-12-16 18:57:46 +05:30
Kovid Goyal
2fd6bf7442 Fix failing test
Error responses must be sent for put commands that refer
non-existent images
2020-12-16 18:41:47 +05:30
Kovid Goyal
d10681f27f Send responses when only a number and no id is specified 2020-12-16 18:31:30 +05:30
Kovid Goyal
e96ff19a7a Graphics protocol: Add support for having the terminal emulator assign image ids
Useful when multiple non co-operating programs want to share the screen.
Fixes #3163
2020-12-16 17:31:15 +05:30
Kovid Goyal
09e75ea329 Add a note about cursor movement after placing an image. 2020-12-15 07:37:14 +05:30
Kovid Goyal
84b03e9f77 ... 2020-12-14 20:06:43 +05:30
Kovid Goyal
55597dcea5 Add the needed import to the example 2020-12-14 19:23:30 +05:30
Kovid Goyal
3290bf3c35 Merge branch 'patch-1' of https://github.com/ThatNerdyPikachu/kitty 2020-12-14 08:37:53 +05:30
Pika
6771429911 Update faq.rst 2020-12-13 19:04:14 -05:00
Kovid Goyal
e428858ad6 Micro-optimization 2020-12-12 17:43:33 +05:30
Kovid Goyal
3e73f860d1 Fix assert in ringbuf_memcpy_from 2020-12-11 21:38:58 +05:30
Kovid Goyal
4cf5bd8d70 Turn on the asserts in ringbuf for debug builds 2020-12-11 21:26:15 +05:30
Kovid Goyal
bffe0f4a6c Use a separate, re-useable ring-buffer implementation
Not only is it re-useable it also allows for easier debugging by
separating the ring buffer specific logic and the pager history logic.

Hopefully it fixes #3049
2020-12-11 21:17:38 +05:30
Kovid Goyal
3b8be26cc7 Workaround for Ubuntu as usual shipping with insanely outdated packages
Fixes #3160
2020-12-11 12:22:28 +05:30
Kovid Goyal
9e95939c47 Add wttr.in to integrations 2020-12-11 07:21:22 +05:30
Kovid Goyal
0af7af95cf Merge branch 'master' of https://github.com/molly-cactus/kitty 2020-12-09 08:17:22 +05:30
Margaret K. Geiger
2b3e2ea6f8 Add tab_switch_strategy option 'right' 2020-12-08 16:55:27 -08:00
Kovid Goyal
19870983ca Allow specifying text formatting in tab_title_template
Fixes #3146
2020-12-08 21:42:40 +05:30
Kovid Goyal
6e83b4c1bc Make it more prominent when you dont need allow_remote_control 2020-12-07 16:24:54 +05:30
Kovid Goyal
14f5e10fd6 Fix mapping of remote_control not working for actions that yield generators
Fixes #3147
2020-12-07 16:15:44 +05:30
Kovid Goyal
ed41e3cd25 Add mentions of glkitty to the docs
Fixes #3111
2020-12-06 08:23:25 +05:30
Kovid Goyal
4cc58e8535 Better fix for filtering out -march=native 2020-12-04 20:59:18 +05:30
Kovid Goyal
e1d9686eb5 Merge branch 'master' of https://github.com/runchard/kitty 2020-12-04 19:35:25 +05:30
Runchard
c5cb4f9e69 do not use clang option -march=native on Apple Silicon
Apple Silicon arm64-apple-darwin clang do not support `-march` option.
2020-12-04 21:07:19 +08:00
Kovid Goyal
4a60413e0b ... 2020-12-03 21:38:42 +05:30
Kovid Goyal
245f5d60b5 Add a test for image put + delete + put 2020-12-03 21:37:32 +05:30
Kovid Goyal
23420adfa6 Graphics protocol: Allow suppressing responses from the terminal to graphics commands 2020-12-03 20:42:03 +05:30
Kovid Goyal
c9828dfece Removed unused parameter 2020-12-03 20:02:16 +05:30
Kovid Goyal
f52c843fa2 Add support for placement id to GraphicsCommand 2020-12-02 05:35:57 +05:30
Kovid Goyal
b5e704a934 Graphics protocol: Add support for giving individual image placements their
Fixes #3133
2020-12-02 05:25:19 +05:30
Kovid Goyal
0173959e64 Make a note that images can be placed and such are known as placements 2020-12-01 21:21:24 +05:30
Kovid Goyal
b00cd5cbc3 Match save/restore cursor behavior of other terms
For the sake of interoperability. This means that doing a DECRC without
a prior DECSC is now undefined. However, one can now issue multiple
DECRC for a single DECSC. Fixes #1264
2020-12-01 17:55:17 +05:30
Kovid Goyal
00aba7c646 Add basic editing support for the broadcast kitten 2020-12-01 17:35:15 +05:30
Kovid Goyal
34db18ea0a Also transmit key events when broadcasting 2020-12-01 14:11:50 +05:30
Kovid Goyal
457c292d3c Fix one ANSI formatting escape code not being removed from the pager history buffer when piping it as plain text
Fixes #3132
2020-12-01 13:17:35 +05:30
Kovid Goyal
f481c17732 The broadcast kitten
Fixes #1569
2020-12-01 13:11:32 +05:30
Kovid Goyal
4a049b14ca Fix infinite loop in send-text when stdin is a tty 2020-12-01 12:29:03 +05:30
Kovid Goyal
ed2dae5884 Fix error when sending empty write buf 2020-12-01 12:25:09 +05:30
Kovid Goyal
df61ee4ac3 ... 2020-12-01 11:39:50 +05:30
Kovid Goyal
850bc12929 DRYer 2020-11-30 22:16:21 +05:30
Kovid Goyal
559e17eb13 Add a couple more useful options to control selected windows for @ send-text 2020-11-30 22:04:46 +05:30
Kovid Goyal
4c4f6983d1 Fix env LC_CTYPE=UTF-8 not working on macOS 2020-11-30 16:23:29 +05:30
Kovid Goyal
2dbeb151f3 Changelog entry for traditional fullscreen on Big Sur 2020-11-29 12:04:52 +05:30
Kovid Goyal
82c137878c Graphics protocol: Dont return filename in the error message when opening file fails, since filenames can contain control characters
Fixes #3128
2020-11-29 12:02:14 +05:30
Kovid Goyal
8845bd6ed3 ... 2020-11-27 15:28:16 +05:30
Kovid Goyal
c89d861c0e Add A FAQ entry about opening new windows with the cwd 2020-11-25 17:47:20 +05:30
Kovid Goyal
3ed536ace1 ... 2020-11-22 12:32:12 +05:30
Kovid Goyal
d13ad4ec4b Merge branch 'nohand' of https://github.com/derekschrock/kitty
Also add a changelog entry and some stylistic fixes
2020-11-22 12:31:28 +05:30
Kovid Goyal
cb5ac1fcf8 DRYer 2020-11-22 12:24:00 +05:30
Kovid Goyal
53797b9ead Wayland: Fix key repeat being stopped by the release of an unrelated key
Fixes #2191
2020-11-22 12:14:52 +05:30
Derek Schrock
cb164e5cac Add new option detect_urls to check for URLs under the mouse cursor
Enabled by default add new option `detect_urls` that will allow you
contorl if kitty should detect URLs under the mouse cursor.  If disabled
the URLs are still clickable with open_url_modifiers.
2020-11-22 00:58:26 -05:00
Kovid Goyal
c46ebebbb3 Override the min-width for body from the alabaster theme
For some reason it sets min width to 450px which is too wide
for some mobile screens. Fixes #3116
2020-11-22 09:14:17 +05:30
Kovid Goyal
ff96036f62 Better window title when choosing tabs/OS windows 2020-11-21 14:58:08 +05:30
Kovid Goyal
6409786f8d Add a new mappable select_tab action to choose a tab to switch to even when the tab bar is hidden
Fixes #3115
2020-11-21 14:52:18 +05:30
Kovid Goyal
05eb07caf5 Add to changelog for last merge
Also remove a spurious return that was disabling a test. Fixes #3113
2020-11-20 20:23:23 +05:30
Kovid Goyal
f5b2a60549 Merge branch 'scroll-region-scrollback' of https://github.com/romkatv/kitty 2020-11-20 20:20:53 +05:30
Roman Perepelitsa
620eaf1ada Change the flow of lines from the scroll region to the scrollback
There are two user-visible changes in here:

1. If a scroll region is set such that there is a bottom margin and no
   top margin, scrolling the region forward used to discard the top
   lines. Now those lines are appended to the scrollback.
   ```shell
   # Assuming a terminal window with 24 lines.
   printf '\033[H\033[J\033[3J\033[0;5r' && seq 100
   ```
   This command used to result in an empty scrollback. Now it contains
   the numbers 1-96.
2. If a scroll region is set such that there is a top margin and no bottom
   margin, scrolling the region forward used to append the top lines to
   the scrollback. Now these lines are discarded.
   ```shell
   # Assuming a terminal window with 24 lines.
   printf '\033[H\033[J\033[3J\033[2;24r' && seq 100
   ```
   This command used to populate scrollback with the numbers 2-78. Now
   the scrollback is empty. The numbers on the screen are the same as
   before: 1 and 79-100.

Related issue: #3113.
2020-11-20 15:41:57 +01:00
Kovid Goyal
9193a20b44 macOS: Fix minimize not working for chromeless windows
Fixes #3112
2020-11-20 07:30:46 +05:30
Kovid Goyal
bdcac9aed3 Partial fix for traditional full screen on Big Turd 2020-11-16 10:23:01 +05:30
Kovid Goyal
e9a28550cc explanatory note 2020-11-15 14:31:40 +05:30
Kovid Goyal
f3cd3e74ae ... 2020-11-15 10:17:32 +05:30
Kovid Goyal
b853fc30c0 Merge branch 'master' of https://github.com/dankamongmen/kitty 2020-11-15 10:13:00 +05:30
nick black
63e32a94c0 Sextants: fix arithmetic mistake that broke 🬓, 🬦, 🬧
The scheme used in draw_sextant works well enough, but the
feed was broken. 21 and 42 need to be skipped, not 20 and
40. Without this change, the following glyphs are broken:

U+1FB13 BLOCK SEXTANT-35 🬓 renders as LEFT HALF
U+1FB26 BLOCK SEXTANT-46 🬦 renders as SEXTANT-146
U+1FB27 BLOCK SEXTANT-146 🬧 renders as RIGHT HALF

With this change, the entirety of the sextant block works
correctly. Found debugging the Notcurses sextant blitter:

https://github.com/dankamongmen/notcurses/issues/1112
2020-11-14 23:30:25 -05:00
Kovid Goyal
ef596f6a8b Distribute extra pixels among all eight-blocks rather than adding them all to the last block
Makes one block stand out less, every block is now at most a pixel in
size different from every other block. Fixes #3097
2020-11-14 11:06:47 +05:30
Kovid Goyal
c830097511 Add a note about using hyperlinks with the hints kitten 2020-11-14 00:03:15 +05:30
Kovid Goyal
d8790a4628 Make the help text for --linenum-action less confusing 2020-11-13 23:53:26 +05:30
Kovid Goyal
e06ef732d8 version 0.19.2 2020-11-13 09:32:53 +05:30
Kovid Goyal
792a3e7db8 Dont mix the raw/non-raw malloc/free for pagerhist 2020-11-13 08:12:26 +05:30
Kovid Goyal
9b32842f66 Fix #3096 2020-11-13 07:47:40 +05:30
Kovid Goyal
9816979169 Don't restrict the DCH control code to only the current scroll region
Matches behavior of other terminal emulators.  Fixes #3090
2020-11-12 11:44:09 +05:30
Kovid Goyal
a74679dd95 Fix last character of URL not being detected if it is the only character on a new line
Fixes #3088
2020-11-11 14:00:33 +05:30
Kovid Goyal
a40059729e Fix the send_text action not working in URL handlers
send_text keeps its args as byte string, so variable expansion was not
working. Fixes #3081
2020-11-11 07:51:43 +05:30
Kovid Goyal
6bab967586 Merge branch 'memory-leak' of https://github.com/Luflosi/kitty 2020-11-05 18:15:44 +05:30
Luflosi
bb88b33469 Fix memory leak
Found with the Clang Static Analyzer.
2020-11-05 13:15:19 +01:00
Kovid Goyal
c440470276 Entry point to edit config file 2020-11-04 16:30:29 +05:30
Kovid Goyal
ef6164eecb Merge branch 'incorrect-reference-count-decrement' of https://github.com/Luflosi/kitty 2020-11-04 07:44:00 +05:30
Luflosi
7ad360d872 Fix incorrect decrement of the reference counts of objects
Found with the Clang Static Analyzer.
The function `schedule_notification()` for the new notification API also does not `release` similar objects.
2020-11-03 18:17:58 +01:00
Kovid Goyal
0870a33956 Merge branch 'memory-leak' of https://github.com/Luflosi/kitty 2020-11-01 18:47:31 +05:30
Luflosi
3ccc2f538d Fix memory leak in unlikely failure condition
Found with the Clang Static Analyzer.
2020-11-01 13:41:52 +01:00
Kovid Goyal
17375f0be2 Add a link to nix-shell 2020-10-31 09:10:50 +05:30
Kovid Goyal
5a987a162e Merge branch 'add-shell.nix' of https://github.com/Luflosi/kitty 2020-10-31 07:31:19 +05:30
Luflosi
5058fb9919 Add shell.nix
This makes it possible to execute `nix-shell` to create the correct environment to build kitty. Use `nix-shell --pure` to eliminate most of the influence of the outside system, e.g. globally installed packages.
This works on NixOS and any Linux or macOS system with the Nix package manager installed.
The build inputs are split into `buildInputs`, `nativeBuildInputs`, `propagatedBuildInputs` and `checkInputs` so it closely resembles 2bb3a9da24/pkgs/applications/terminal-emulators/kitty/default.nix. This makes it easy to port changes between the two files.
2020-10-31 01:44:33 +01:00
Luflosi
3335f8602b Allow reading some build system flags as environment variables 2020-10-29 12:20:11 +01:00
Kovid Goyal
87ab1bbe54 Add a changelog entry for previous merge 2020-10-29 07:20:45 +05:30
Kovid Goyal
f8d52b33f4 Merge branch 'wl_fix_destroy_csds' of https://github.com/LeonardKoenig/kitty 2020-10-29 07:19:57 +05:30
Leonard König
bc2dcdf9db wl: Fix destroying CSDs in correct order (#3051)
On Wayland, some compositors refuse to implement SSDs in which case we draw
primitive CSDs.  However, the destructors were called in the wrong order,
leading to a dereference of an already freed object.
2020-10-28 18:57:37 +01:00
Kovid Goyal
93d1aacfb6 macOS: Fix kitty not being added to PATH automatically
Fixes #3063. Apparently in newer Python, Py_Initialize() nukes
sys._xoptions when the isolate flag is set.
2020-10-27 10:38:33 +05:30
Kovid Goyal
3ddaa4aff9 Make it clear that remote control mappings dont need remote control enabled 2020-10-26 16:51:53 +05:30
Kovid Goyal
75488d568a Merge branch 'glfw_upstream' of https://github.com/Luflosi/kitty 2020-10-26 16:34:30 +05:30
Luflosi
3df80545bd Reduce the difference of GLFW to upstream 2020-10-26 11:02:55 +01:00
Kovid Goyal
c605fd9783 Merge branch 'remove-extra-space' of https://github.com/Luflosi/kitty 2020-10-26 15:03:25 +05:30
Luflosi
60719e7bff Remove extra space 2020-10-26 10:22:14 +01:00
Kovid Goyal
e9faa3277a Merge branch 'fix-memory-leak' of https://github.com/Luflosi/kitty 2020-10-26 07:33:06 +05:30
Luflosi
35f7388725 Fix memory leaks in coretext_all_fonts()
Found with the Clang Static Analyzer.
2020-10-25 17:40:51 +01:00
Kovid Goyal
ef1486a779 Add .js and .json to known extensions 2020-10-25 20:25:31 +05:30
Kovid Goyal
95c44165e9 Merge branch 'fix-clang-analyze-error' of https://github.com/Luflosi/kitty 2020-10-25 20:24:28 +05:30
Kovid Goyal
7b816bb96f Font independent rendering for braille characters, which ensures they are properly aligned at all font sizes. 2020-10-25 20:20:22 +05:30
Luflosi
d2ac51aa4a Fix Clang Static Analyzer complaining about Apple coding conventions
The error message was: "Method accepting NSError** should have a non-void return value to indicate whether or not an error occurred".
2020-10-25 15:47:43 +01:00
Kovid Goyal
26974b1f3a Dont ignore --title when using an empty session
Fixes #3055
2020-10-25 18:53:57 +05:30
Kovid Goyal
3960c6678d Override MIME for some types that are actually text 2020-10-25 15:11:44 +05:30
Kovid Goyal
30b8991a73 DRYer 2020-10-25 13:47:12 +05:30
Kovid Goyal
75a94bcd96 Improving MIME type detection for some common file types when they are missing from the system MIME database
Also allow the user to specify their own database via mime.types in the
kitty config directory. See #3056
2020-10-25 13:42:11 +05:30
Kovid Goyal
e160cbf32b ssh kitten: Fix parsing of combined single letter options to more closely match ssh. Fixes #3053 2020-10-23 16:55:53 +05:30
Kovid Goyal
2da2e63245 Add another integration 2020-10-23 09:36:35 +05:30
Kovid Goyal
f160ea6012 Fix #3048 2020-10-21 21:57:35 +05:30
Kovid Goyal
8057bc639d Add diff context parser defs 2020-10-20 11:37:48 +05:30
Kovid Goyal
6f5ec5aa03 Merge branch 'fix-mistake-in-previous-pr' of https://github.com/Luflosi/kitty into master 2020-10-19 16:41:01 +05:30
Luflosi
e343c9445c Creating a temporary directory is not actually required
While developing the previous PR (https://github.com/kovidgoyal/kitty/pull/3043), I was using more compiler command line arguments, one of which was `-MMD`. This caused the .d file to be created. Without this argument, there is no need to create a temporary directory.
2020-10-19 13:08:32 +02:00
Kovid Goyal
c73e374f1a Remove unneeded space 2020-10-19 16:02:49 +05:30
Kovid Goyal
d9b292f808 Merge branch 'fix-macos-notification-api-detection' of https://github.com/Luflosi/kitty into master 2020-10-19 16:00:38 +05:30
Luflosi
46ef2f313b macOS: Fix detection for notification API
For some reason it can happen that the `UserNotifications` framework exists but the `UserNotifications/UserNotifications.h` header doesn't.
Closes https://github.com/kovidgoyal/kitty/issues/3042.
2020-10-19 12:19:51 +02:00
Luflosi
92a705c79e Add language parameter to first_successful_compile() and test_compile()
This allows compiling Objective-C files.
The temporary directory is needed because clang would try to write to `/dev/null.d`, which would obviously fail.
2020-10-18 23:08:19 +02:00
Kovid Goyal
12ebdd2574 Add a changelog entry for the last PR 2020-10-18 08:48:07 +05:30
Kovid Goyal
ed2e951032 Merge branch 'pointer_shape_when_dragging' of https://github.com/jaeheum/kitty into master 2020-10-18 08:46:18 +05:30
Kovid Goyal
01a34a8846 Add links to viu that supports the graphics protocol 2020-10-18 08:42:59 +05:30
Jay Han
b13174cb9c pointer_shape_when_dragging option + set_mouse_cursor_when_dragging() 2020-10-17 09:52:44 -07:00
Jay Han
03ac6cab99 default_pointer_shape option 2020-10-17 09:28:04 -07:00
Kovid Goyal
532eebaefb Merge branch 'fix-garbage-pointer-dereference' of https://github.com/Luflosi/kitty into master 2020-10-16 07:35:31 +05:30
Luflosi
f825345b14 Fix potential garbage pointer dereference
`create_os_window()` calls `get_window_content_scale()` without initializing the `xscale` and `yscale` variables. Instead of initializing them everywhere, where this function is called, just do it once in the function itself.
Found with the Clang Static Analyzer.
2020-10-15 20:41:16 +02:00
Kovid Goyal
1409477ed7 Merge branch 'double-free' of https://github.com/Luflosi/kitty into master 2020-10-15 19:11:31 +05:30
Luflosi
d8e4294432 Fix double free and memory leak
Found with the Clang Static Analyzer.
This is a copy & paste error. This bug was introduced in 72e2307c16 in Jul 2018.
2020-10-15 15:29:44 +02:00
Kovid Goyal
5d13908776 github actions CI updated to python 3.9
Pillow wheel currently not available for python 3.9. So tries to install
from source and fails on missing zlib. So install zlib in brew and make
it available via PKG_CONFIG_PATH. Apparently, this wont be necessary
after Pillow 8, but who knows.
2020-10-14 19:13:46 +05:30
Luflosi
2832a73285 GLFW: Wayland: Assume 96 DPI if physical size is <= 0
From upstream: 0ef149c8f2.
2020-10-14 14:43:40 +02:00
Kovid Goyal
4152ed5809 Update changelog 2020-10-14 08:51:07 +05:30
Kovid Goyal
8a90ed70ee Merge branch 'fix-upwards-selection-clearing' of https://github.com/Luflosi/kitty into master 2020-10-14 05:31:08 +05:30
Luflosi
e2646c08a5 Fix upwards selection not being cleared when lines change
When selecting text by dragging upwards, the "end" of the selection is above the "start". This causes the `selection_has_screen_line()` to never return `true` in this case.
In practice this bug causes the selection to not be cleared when the screen contents under the selection change if it was made by dragging upwards.
2020-10-13 21:40:03 +02:00
Kovid Goyal
7122ba820f Fix eight bar unicode chars not being rendered at very small font sizes
Fixes #3025
2020-10-13 20:00:25 +05:30
Kovid Goyal
efca2658ea Fix typing issues pointed out by updated mypy 2020-10-12 23:03:07 +05:30
Kovid Goyal
91a714947c Fix encoding error when reporting capabilities for number of colors 2020-10-12 22:39:05 +05:30
Kovid Goyal
5d3ac649ba Fix #3017 2020-10-08 17:39:44 +05:30
Kovid Goyal
6443e726a6 Add a note about how the query_terminal kitten works 2020-10-08 07:42:47 +05:30
Kovid Goyal
6a755bda45 A new kitten to easily query kitty for config values 2020-10-07 13:35:16 +05:30
Kovid Goyal
dab555ea3b kittens: Dont discard pending input on startup
Fixes #3012
2020-10-06 16:39:00 +05:30
Kovid Goyal
a3bbad0060 Allow specifying the optional actions for tcsetattr 2020-10-06 16:30:23 +05:30
327 changed files with 48043 additions and 50476 deletions

9
.gitattributes vendored
View File

@@ -1,6 +1,5 @@
kitty/wcwidth-std.h linguist-generated=true
kitty/emoji.h linguist-generated=true
kitty/keys.h linguist-generated=true
kitty/charsets.c linguist-generated=true
kitty/key_encoding.py linguist-generated=true
kitty/unicode-data.c linguist-generated=true
@@ -8,6 +7,14 @@ kitty/rgb.py linguist-generated=true
kitty/gl-wrapper.* linguist-generated=true
kitty/glfw-wrapper.* linguist-generated=true
kitty/parse-graphics-command.h linguist-generated=true
kitty/options/types.py linguist-generated=true
kitty/options/parse.py linguist-generated=true
kitty/options/to-c-generated.h linguist-generated=true
kittens/diff/options/types.py linguist-generated=true
kittens/diff/options/parse.py linguist-generated=true
glfw/*.c linguist-vendored=true
glfw/*.h linguist-vendored=true
kittens/unicode_input/names.h linguist-generated=true
*.py text diff=python
*.m text diff=objc

View File

@@ -17,17 +17,15 @@ Steps to reproduce the behavior:
3. ZZZ
4. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Environment details**
OS: Name and version of operating system(s)
```
Output of kitty --debug-config
Press Ctrl+Shift+F6 (cmd+option+, on macOS) in kitty, to copy debug output about kitty and its
configuration to the clipboard and paste it here.
On older versions of kitty, run kitty --debug-config instead
```
**Additional context**

View File

@@ -35,12 +35,18 @@ def install_deps():
else:
run('sudo apt-get update')
run('sudo apt-get install -y libgl1-mesa-dev libxi-dev libxrandr-dev libxinerama-dev'
' libxcursor-dev libxcb-xkb-dev libdbus-1-dev libxkbcommon-dev libharfbuzz-dev'
' libpng-dev liblcms2-dev libfontconfig-dev libxkbcommon-x11-dev libcanberra-dev')
' libxcursor-dev libxcb-xkb-dev libdbus-1-dev libxkbcommon-dev libharfbuzz-dev libx11-xcb-dev'
' libpng-dev liblcms2-dev libfontconfig-dev libxkbcommon-x11-dev libcanberra-dev uuid-dev')
if is_bundle:
install_bundle()
else:
run('pip3 install Pillow pygments')
if is_macos:
# needed for zlib for pillow, should not be needed after pillow 8.0
os.environ['PKG_CONFIG_PATH'] = '/usr/local/opt/zlib/lib/pkgconfig'
cmd = 'pip3 install Pillow pygments'
if sys.version_info[:2] < (3, 7):
cmd += ' importlib-resources'
run(cmd)
def build_kitty():

View File

@@ -76,7 +76,7 @@ jobs:
python-version: 3.8
- name: Install build-only deps
run: pip install flake8 mypy sphinx
run: pip install -r docs/requirements.txt flake8 mypy types-requests types-docutils
- name: Run pyflakes
run: python -m flake8 --count .

View File

@@ -1,4 +1,5 @@
pkg-config
zlib
python
imagemagick
harfbuzz

View File

@@ -1 +1 @@
See https://sw.kovidgoyal.net/kitty/changelog.html
See https://sw.kovidgoyal.net/kitty/changelog/

View File

@@ -10,9 +10,9 @@ config to reproduce the issue with).
### Contributing code
Install [the dependencies](https://sw.kovidgoyal.net/kitty/build.html#dependencies)
Install [the dependencies](https://sw.kovidgoyal.net/kitty/build/#dependencies)
using your favorite package manager. Build and run kitty [from
source](https://sw.kovidgoyal.net/kitty/build.html#install-and-run-from-source).
source](https://sw.kovidgoyal.net/kitty/build/#install-and-run-from-source).
Make a fork, submit your Pull Request. If it's a large/controversial change, open an issue
beforehand to discuss it, so that you don't waste your time making a pull

View File

@@ -1,3 +1,3 @@
To build from source: <https://sw.kovidgoyal.net/kitty/build.html>
To build from source: <https://sw.kovidgoyal.net/kitty/build/>
Pre-built binaries: <https://sw.kovidgoyal.net/kitty/binary.html>
Pre-built binaries: <https://sw.kovidgoyal.net/kitty/binary/>

View File

@@ -40,4 +40,11 @@ html:
linkcheck:
$(MAKE) FAIL_WARN=$(FAIL_WARN) -C docs linkcheck
website:
./publish.py --only website
docs: man html
develop-docs:
$(MAKE) -C docs develop-docs

View File

@@ -1,5 +1,14 @@
= kitty - the fast, featureful, GPU based, terminal emulator
= kitty - the fast, feature-rich, cross-platform, GPU based terminal
See https://sw.kovidgoyal.net/kitty/
See https://sw.kovidgoyal.net/kitty/[the kitty website].
image:https://github.com/kovidgoyal/kitty/workflows/CI/badge.svg["Build status", link="https://github.com/kovidgoyal/kitty/actions?query=workflow%3ACI"]
https://sw.kovidgoyal.net/kitty/faq/[Frequently Asked Questions]
To ask other questions about kitty usage, use either the https://github.com/kovidgoyal/kitty/discussions/[discussions on GitHub] or the
https://www.reddit.com/r/KittyTerminal[Reddit community]
Packaging status in various repositories:
image:https://repology.org/badge/vertical-allrepos/kitty.svg[https://repology.org/project/kitty/versions]

12
SECURITY.md Normal file
View File

@@ -0,0 +1,12 @@
# Security Policy
## Supported Versions
There are no security specific releases of kitty. Security bugs are fixed
and released just like all other bugs.
## Reporting a vulnerability
Preferably send an email to kovid at kovidgoyal.net or open an issue in the
GitHub repository, though the latter means you are disclosing the vulnerability
publicly before it can be fixed.

View File

@@ -2,8 +2,8 @@
# vim:fileencoding=utf-8
# License: GPL v3 Copyright: 2015, Kovid Goyal <kovid at kovidgoyal.net>
import sys
import os
import sys
from typing import List
@@ -30,8 +30,14 @@ def runpy(args: List[str]) -> None:
def hold(args: List[str]) -> None:
import subprocess
import tty
from contextlib import suppress
ret = subprocess.Popen(args[1:]).wait()
sys.stdin.read()
with suppress(BaseException):
print('\n\x1b[1;32mPress any key to exit', end='', flush=True)
with suppress(BaseException):
tty.setraw(sys.stdin.fileno())
sys.stdin.buffer.read(1)
raise SystemExit(ret)
@@ -43,13 +49,22 @@ def complete(args: List[str]) -> None:
def launch(args: List[str]) -> None:
import runpy
sys.argv = args[1:]
exe = args[1]
try:
exe = args[1]
except IndexError:
raise SystemExit(
'usage: kitty +launch script.py [arguments to be passed to script.py ...]\n\n'
'script.py will be run with full access to kitty code. If script.py is '
'prefixed with a : it will be searched for in PATH'
)
if exe.startswith(':'):
import shutil
q = shutil.which(exe[1:])
if not q:
raise SystemExit('{} not found in PATH'.format(args[1][1:]))
raise SystemExit(f'{exe[1:]} not found in PATH')
exe = q
if not os.path.exists(exe):
raise SystemExit(f'{exe} does not exist')
runpy.run_path(exe, run_name='__main__')
@@ -65,9 +80,23 @@ def run_kitten(args: List[str]) -> None:
rk(kitten)
def edit_config_file(args: List[str]) -> None:
from kitty.cli import create_default_opts
from kitty.fast_data_types import set_options
from kitty.utils import edit_config_file as f
set_options(create_default_opts())
f()
def namespaced(args: List[str]) -> None:
func = namespaced_entry_points[args[1]]
func(args[1:])
try:
func = namespaced_entry_points[args[1]]
except KeyError:
pass
else:
func(args[1:])
return
raise SystemExit(f'{args[1]} is not a known entry point. Choices are: ' + ', '.join(namespaced_entry_points))
entry_points = {
@@ -77,6 +106,7 @@ entry_points = {
'runpy': runpy,
'launch': launch,
'kitten': run_kitten,
'edit-config': edit_config_file,
'@': remote_control,
'+': namespaced,

View File

@@ -4,15 +4,17 @@
import os
import re
import shlex
import shutil
import subprocess
import sys
import tempfile
from contextlib import suppress
from bypy.constants import (
LIBDIR, PREFIX, PYTHON, SRC as KITTY_DIR, ismacos, worker_env
)
from bypy.utils import run_shell
from bypy.utils import run_shell, walk
def read_src_file(name):
@@ -40,52 +42,69 @@ def run(*args, **extra_env):
if ismacos:
env['PKGCONFIG_EXE'] = os.path.join(PREFIX, 'bin', 'pkg-config')
cwd = env.pop('cwd', KITTY_DIR)
print(' '.join(map(shlex.quote, args)), flush=True)
return subprocess.call(list(args), env=env, cwd=cwd)
SETUP_CMD = [PYTHON, 'setup.py', '--build-universal-binary']
def build_frozen_launcher(extra_include_dirs):
inc_dirs = [f'--extra-include-dirs={x}' for x in extra_include_dirs]
cmd = SETUP_CMD + ['--prefix', build_frozen_launcher.prefix] + inc_dirs + ['build-frozen-launcher']
if run(*cmd, cwd=build_frozen_launcher.writeable_src_dir) != 0:
print('Building of frozen kitty launcher failed', file=sys.stderr)
os.chdir(KITTY_DIR)
run_shell()
raise SystemExit('Building of kitty launcher failed')
return build_frozen_launcher.writeable_src_dir
def run_tests(kitty_exe):
with tempfile.TemporaryDirectory() as tdir:
env = {
'KITTY_CONFIG_DIRECTORY': os.path.join(tdir, 'conf'),
'KITTY_CACHE_DIRECTORY': os.path.join(tdir, 'cache')
}
[os.mkdir(x) for x in env.values()]
cmd = [kitty_exe, '+runpy', 'from kitty_tests.main import run_tests; run_tests()']
print(*map(shlex.quote, cmd), flush=True)
if subprocess.call(cmd, env=env) != 0:
print('Checking of kitty build failed', file=sys.stderr)
os.chdir(os.path.dirname(kitty_exe))
run_shell()
raise SystemExit('Checking of kitty build failed')
def sanitize_source_folder(path: str) -> None:
for q in walk(path):
if os.path.splitext(q)[1] not in ('.py', '.glsl', '.ttf', '.otf'):
os.unlink(q)
def build_c_extensions(ext_dir, args):
writeable_src_dir = os.path.join(ext_dir, 'src')
build_frozen_launcher.writeable_src_dir = writeable_src_dir
shutil.copytree(
KITTY_DIR, writeable_src_dir, symlinks=True,
ignore=shutil.ignore_patterns('b', 'build', 'dist', '*_commands.json', '*.o'))
ignore=shutil.ignore_patterns('b', 'build', 'dist', '*_commands.json', '*.o', '*.so', '*.dylib', '*.pyd'))
# Build the launcher as it is needed for the spawn test
with suppress(FileNotFoundError):
os.remove(os.path.join(writeable_src_dir, 'kitty', 'launcher', 'kitty'))
if run(PYTHON, 'setup.py', 'build-launcher', cwd=writeable_src_dir) != 0:
print('Building of kitty launcher failed', file=sys.stderr)
os.chdir(KITTY_DIR)
run_shell()
raise SystemExit('Building of kitty launcher failed')
os.unlink(os.path.join(writeable_src_dir, 'kitty', 'launcher', 'kitty'))
cmd = [PYTHON, 'setup.py']
bundle = 'macos-freeze' if ismacos else 'linux-freeze'
cmd.append(bundle)
cmd = SETUP_CMD + ['macos-freeze' if ismacos else 'linux-freeze']
if args.dont_strip:
cmd.append('--debug')
dest = kitty_constants['appname'] + ('.app' if ismacos else '')
dest = os.path.join(ext_dir, dest)
cmd += ['--prefix', dest]
dest = build_frozen_launcher.prefix = os.path.join(ext_dir, dest)
cmd += ['--prefix', dest, '--full']
if run(*cmd, cwd=writeable_src_dir) != 0:
print('Building of kitty package failed', file=sys.stderr)
os.chdir(KITTY_DIR)
os.chdir(writeable_src_dir)
run_shell()
raise SystemExit('Building of kitty package failed')
return ext_dir
def run_tests(path_to_kitty, cwd_on_failure):
kw = {'cwd': cwd_on_failure}
if not ismacos:
# this is needed for the spawn test which starts an interpreter
# using the kitty launcher.
kw['PYTHONHOME'] = PREFIX
ret = run(PYTHON, 'test.py', **kw)
if ret != 0:
os.chdir(cwd_on_failure)
print(
'running kitty tests failed with return code:', ret, file=sys.stderr)
run_shell()
raise SystemExit('running kitty tests failed')
if __name__ == 'program':
kitty_constants = initialize_constants()

View File

@@ -13,12 +13,14 @@ import time
from bypy.constants import (
OUTPUT_DIR, PREFIX, is64bit, python_major_minor_version
)
from bypy.utils import get_dll_path, py_compile, walk
from bypy.freeze import (
extract_extension_modules, freeze_python, path_to_freeze_dir
)
from bypy.utils import get_dll_path, mkdtemp, py_compile, walk
j = os.path.join
self_dir = os.path.dirname(os.path.abspath(__file__))
arch = 'x86_64' if is64bit else 'i686'
self_dir = os.path.dirname(os.path.abspath(__file__))
py_ver = '.'.join(map(str, python_major_minor_version()))
iv = globals()['init_env']
kitty_constants = iv['kitty_constants']
@@ -26,14 +28,10 @@ kitty_constants = iv['kitty_constants']
def binary_includes():
return tuple(map(get_dll_path, (
'expat', 'sqlite3', 'ffi', 'z', 'lzma', 'png16', 'lcms2',
# dont include freetype because fontconfig is closely coupled to it
# and also distros often patch freetype
# 'iconv.so.2', 'pcre.so.1', 'graphite2.so.3', 'glib-2.0.so.0', 'freetype.so.6',
'expat', 'sqlite3', 'ffi', 'z', 'lzma', 'png16', 'lcms2', 'crypt',
'iconv', 'pcre', 'graphite2', 'glib-2.0', 'freetype',
'harfbuzz', 'xkbcommon', 'xkbcommon-x11',
'ncursesw', 'readline',
'ncursesw', 'readline', 'brotlicommon', 'brotlienc', 'brotlidec'
))) + (
get_dll_path('bz2', 2), get_dll_path('ssl', 2), get_dll_path('crypto', 2),
get_dll_path('python' + py_ver, 2),
@@ -48,6 +46,7 @@ class Env:
self.py_dir = j(self.lib_dir, 'python' + py_ver)
os.makedirs(self.py_dir)
self.bin_dir = j(self.base, 'bin')
self.obj_dir = mkdtemp('launchers-')
def ignore_in_lib(base, items, ignored_dirs=None):
@@ -75,7 +74,7 @@ def import_site_packages(srcdir, dest):
if ext in ('py', 'so'):
shutil.copy2(f, dest)
elif ext == 'pth' and x != 'setuptools.pth':
for line in open(f, 'rb').read().splitlines():
for line in open(f):
src = os.path.abspath(j(srcdir, line))
if os.path.exists(src) and os.path.isdir(src):
import_site_packages(src, dest)
@@ -89,6 +88,8 @@ def copy_libs(env):
for x in binary_includes():
dest = env.bin_dir if '/bin/' in x else env.lib_dir
shutil.copy2(x, dest)
dest = os.path.join(dest, os.path.basename(x))
subprocess.check_call(['chrpath', '-d', dest])
def copy_python(env):
@@ -105,10 +106,31 @@ def copy_python(env):
shutil.copy2(y, env.py_dir)
srcdir = j(srcdir, 'site-packages')
dest = j(env.py_dir, 'site-packages')
import_site_packages(srcdir, dest)
site_packages_dir = j(env.py_dir, 'site-packages')
import_site_packages(srcdir, site_packages_dir)
pdir = os.path.join(env.lib_dir, 'kitty-extensions')
os.makedirs(pdir, exist_ok=True)
kitty_dir = os.path.join(env.lib_dir, 'kitty')
bases = ('kitty', 'kittens', 'kitty_tests')
for x in bases:
dest = os.path.join(env.py_dir, x)
os.rename(os.path.join(kitty_dir, x), dest)
if x == 'kitty':
shutil.rmtree(os.path.join(dest, 'launcher'))
os.rename(os.path.join(kitty_dir, '__main__.py'), os.path.join(env.py_dir, 'kitty_main.py'))
shutil.rmtree(os.path.join(kitty_dir, '__pycache__'))
print('Extracting extension modules from', env.py_dir, 'to', pdir)
ext_map = extract_extension_modules(env.py_dir, pdir)
shutil.copy(os.path.join(os.path.dirname(self_dir), 'site.py'), os.path.join(env.py_dir, 'site.py'))
for x in bases:
iv['sanitize_source_folder'](os.path.join(env.py_dir, x))
py_compile(env.py_dir)
py_compile(os.path.join(env.base, 'lib', 'kitty'))
freeze_python(env.py_dir, pdir, env.obj_dir, ext_map, develop_mode_env_var='KITTY_DEVELOP_FROM', remove_pyc_files=True)
def build_launcher(env):
iv['build_frozen_launcher']([path_to_freeze_dir(), env.obj_dir])
def is_elf(path):
@@ -192,16 +214,16 @@ def create_tarfile(env, compression_level='9'):
def main():
args = globals()['args']
ext_dir = globals()['ext_dir']
if not args.skip_tests:
run_tests = iv['run_tests']
run_tests(None, os.path.join(ext_dir, 'src'))
env = Env(os.path.join(ext_dir, kitty_constants['appname']))
copy_libs(env)
copy_python(env)
build_launcher(env)
files = find_binaries(env)
fix_permissions(files)
if not args.dont_strip:
strip_binaries(files)
if not args.skip_tests:
iv['run_tests'](os.path.join(env.base, 'bin', 'kitty'))
create_tarfile(env, args.compression_level)

View File

@@ -1,6 +1,8 @@
# Requires installation of XCode 10.3 and Python 3 and
# python3 -m pip install certifi
vm_name 'macos-kitty-build'
vm_name 'macos-kitty'
root '/Users/Shared/kitty-build'
python '/usr/local/bin/python3'
universal 'true'
deploy_target '10.14'

View File

@@ -13,16 +13,23 @@ import tempfile
import zipfile
from bypy.constants import PREFIX, PYTHON, SW, python_major_minor_version
from bypy.freeze import (
extract_extension_modules, freeze_python, path_to_freeze_dir
)
from bypy.macos_sign import (
codesign, create_entitlements_file, make_certificate_useable, notarize_app,
verify_signature
)
from bypy.utils import current_dir, py_compile, run_shell, timeit, walk
from bypy.utils import (
current_dir, mkdtemp, py_compile, run_shell, timeit, walk
)
iv = globals()['init_env']
kitty_constants = iv['kitty_constants']
self_dir = os.path.dirname(os.path.abspath(__file__))
join = os.path.join
basename = os.path.basename
dirname = os.path.dirname
abspath = os.path.abspath
APPNAME = kitty_constants['appname']
VERSION = kitty_constants['version']
@@ -134,8 +141,9 @@ class Freeze(object):
FID = '@executable_path/../Frameworks'
def __init__(self, build_dir, dont_strip=False, sign_installers=False, notarize=False):
def __init__(self, build_dir, dont_strip=False, sign_installers=False, notarize=False, skip_tests=False):
self.build_dir = build_dir
self.skip_tests = skip_tests
self.sign_installers = sign_installers
self.notarize = notarize
self.dont_strip = dont_strip
@@ -147,6 +155,7 @@ class Freeze(object):
self.py_ver = py_ver
self.python_stdlib = join(self.resources_dir, 'Python', 'lib', 'python' + self.py_ver)
self.site_packages = self.python_stdlib # hack to avoid needing to add site-packages to path
self.obj_dir = mkdtemp('launchers-')
self.run()
@@ -160,10 +169,11 @@ class Freeze(object):
self.add_site_packages()
self.add_stdlib()
self.add_misc_libraries()
self.compile_py_modules()
self.fix_dependencies_in_kitty()
self.freeze_python()
if not self.dont_strip:
self.strip_files()
if not self.skip_tests:
self.run_tests()
# self.run_shell()
ret = self.makedmg(self.build_dir, APPNAME + '-' + VERSION)
@@ -175,6 +185,10 @@ class Freeze(object):
print('\nStripping files...')
strip_files(self.to_strip)
@flush
def run_tests(self):
iv['run_tests'](os.path.join(self.contents_dir, 'MacOS', 'kitty'))
@flush
def set_id(self, path_to_lib, new_id):
old_mode = flipwritable(path_to_lib)
@@ -239,7 +253,6 @@ class Freeze(object):
self.set_id(
join(currd, 'Python'),
self.FID + '/Python.framework/Versions/%s/Python' % basename(curr))
self.fix_dependencies_in_lib(join(self.contents_dir, 'MacOS', 'kitty'))
# The following is needed for codesign
with current_dir(x):
os.symlink(basename(curr), 'Versions/Current')
@@ -273,11 +286,6 @@ class Freeze(object):
dest = join(self.frameworks_dir, x)
self.set_id(dest, self.FID + '/' + x)
self.fix_dependencies_in_lib(dest)
base = join(self.frameworks_dir, 'kitty')
for lib in walk(base):
if lib.endswith('.so'):
self.set_id(lib, self.FID + '/' + os.path.relpath(lib, self.frameworks_dir))
self.fix_dependencies_in_lib(lib)
@flush
def add_package_dir(self, x, dest=None):
@@ -295,21 +303,10 @@ class Freeze(object):
dest = self.site_packages
dest = join(dest, basename(x))
shutil.copytree(x, dest, symlinks=True, ignore=ignore)
self.postprocess_package(x, dest)
for f in walk(dest):
if f.endswith('.so'):
self.fix_dependencies_in_lib(f)
@flush
def fix_dependencies_in_kitty(self):
for f in walk(join(self.resources_dir, 'kitty')):
if f.endswith('.so'):
self.fix_dependencies_in_lib(f)
@flush
def postprocess_package(self, src_path, dest_path):
pass
@flush
def add_stdlib(self):
print('\nAdding python stdlib')
@@ -331,6 +328,35 @@ class Freeze(object):
if dest2.endswith('.so'):
self.fix_dependencies_in_lib(dest2)
@flush
def freeze_python(self):
print('\nFreezing python')
kitty_dir = join(self.resources_dir, 'kitty')
bases = ('kitty', 'kittens', 'kitty_tests')
for x in bases:
dest = os.path.join(self.python_stdlib, x)
os.rename(os.path.join(kitty_dir, x), dest)
if x == 'kitty':
shutil.rmtree(os.path.join(dest, 'launcher'))
os.rename(os.path.join(kitty_dir, '__main__.py'), os.path.join(self.python_stdlib, 'kitty_main.py'))
shutil.rmtree(os.path.join(kitty_dir, '__pycache__'))
pdir = os.path.join(dirname(self.python_stdlib), 'kitty-extensions')
os.mkdir(pdir)
print('Extracting extension modules from', self.python_stdlib, 'to', pdir)
ext_map = extract_extension_modules(self.python_stdlib, pdir)
shutil.copy(os.path.join(os.path.dirname(self_dir), 'site.py'), os.path.join(self.python_stdlib, 'site.py'))
for x in bases:
iv['sanitize_source_folder'](os.path.join(self.python_stdlib, x))
self.compile_py_modules()
freeze_python(self.python_stdlib, pdir, self.obj_dir, ext_map, develop_mode_env_var='KITTY_DEVELOP_FROM', remove_pyc_files=True)
iv['build_frozen_launcher']([path_to_freeze_dir(), self.obj_dir])
os.rename(join(dirname(self.contents_dir), 'bin', 'kitty'), join(self.contents_dir, 'MacOS', 'kitty'))
shutil.rmtree(join(dirname(self.contents_dir), 'bin'))
self.fix_dependencies_in_lib(join(self.contents_dir, 'MacOS', 'kitty'))
for f in walk(pdir):
if f.endswith('.so') or f.endswith('.dylib'):
self.fix_dependencies_in_lib(f)
@flush
def add_site_packages(self):
print('\nAdding site-packages')
@@ -389,14 +415,11 @@ class Freeze(object):
@flush
def compile_py_modules(self):
print('\nCompiling Python modules')
self.remove_bytecode(join(self.resources_dir, 'Python'))
py_compile(join(self.resources_dir, 'Python'))
self.remove_bytecode(join(self.resources_dir, 'kitty'))
py_compile(join(self.resources_dir, 'kitty'))
@flush
def makedmg(self, d, volname, internet_enable=True, format='ULFO'):
def makedmg(self, d, volname, format='ULFO'):
''' Copy a directory d into a dmg named volname '''
print('\nMaking dmg...')
sys.stdout.flush()
@@ -432,9 +455,6 @@ class Freeze(object):
print('\nCreating dmg...')
with timeit() as times:
subprocess.check_call(cmd + [dmg])
if internet_enable:
subprocess.check_call(
['/usr/bin/hdiutil', 'internet-enable', '-yes', dmg])
print('dmg created in %d minutes and %d seconds' % tuple(times))
shutil.rmtree(tdir)
size = os.stat(dmg).st_size / (1024 * 1024.)
@@ -445,14 +465,12 @@ class Freeze(object):
def main():
args = globals()['args']
ext_dir = globals()['ext_dir']
if not args.skip_tests:
run_tests = iv['run_tests']
run_tests(None, os.path.join(ext_dir, 'src'))
Freeze(
os.path.join(ext_dir, kitty_constants['appname'] + '.app'),
dont_strip=args.dont_strip,
sign_installers=args.sign_installers,
notarize=args.notarize
notarize=args.notarize,
skip_tests=args.skip_tests
)

31
bypy/site.py Normal file
View File

@@ -0,0 +1,31 @@
#!/usr/bin/env python
# vim:fileencoding=utf-8
# License: GPLv3 Copyright: 2021, Kovid Goyal <kovid at kovidgoyal.net>
import builtins
import sys
import _sitebuiltins
def set_quit():
eof = 'Ctrl-D (i.e. EOF)'
builtins.quit = _sitebuiltins.Quitter('quit', eof)
builtins.exit = _sitebuiltins.Quitter('exit', eof)
def set_helper():
builtins.help = _sitebuiltins._Helper()
def main():
sys.argv[0] = sys.calibre_basename
set_helper()
set_quit()
mod = __import__(sys.calibre_module, fromlist=[1])
func = getattr(mod, sys.calibre_function)
return func()
if __name__ == '__main__':
main()

View File

@@ -28,13 +28,34 @@
}
},
{
"name": "cmake",
"os": "macos",
"unix": {
"filename": "cmake-3.19.4.tar.gz",
"hash": "sha256:7d0232b9f1c57e8de81f38071ef8203e6820fe7eec8ae46a1df125d88dbcc2e1",
"urls": ["https://cmake.org/files/v3.19/{filename}"]
}
},
{
"name": "expat",
"unix": {
"filename": "expat-2.2.6.tar.bz2",
"hash": "sha256:17b43c2716d521369f82fc2dc70f359860e90fa440bea65b3b85f0b246ea81f2",
"urls": ["https://github.com/libexpat/libexpat/releases/download/R_2_2_6/{filename}"]
"filename": "expat-2.2.10.tar.bz2",
"hash": "sha256:b2c160f1b60e92da69de8e12333096aeb0c3bf692d41c60794de278af72135a5",
"urls": ["https://github.com/libexpat/libexpat/releases/download/R_2_2_10/{filename}"]
}
},
{
"name": "libxml2",
"os": "linux",
"unix": {
"filename": "libxml2-2.9.10.tar.gz",
"hash": "sha256:aafee193ffb8fe0c82d4afef6ef91972cbaf5feea100edc2f262750611b4be1f",
"urls": ["ftp://xmlsoft.org/libxml2/{filename}"]
}
},
@@ -43,8 +64,8 @@
"name": "xkbcommon",
"os": "linux",
"unix": {
"filename": "libxkbcommon-0.10.0.tar.xz",
"hash": "sha256:57c3630cdc38fb4734cd57fa349e92244f5ae3862813e533cedbd86721a0b6f2",
"filename": "libxkbcommon-1.0.3.tar.xz",
"hash": "sha256:a2202f851e072b84e64a395212cbd976ee18a8ee602008b0bad02a13247dbc52",
"urls": ["http://xkbcommon.org/download/{filename}"]
}
},
@@ -52,27 +73,28 @@
{
"name": "sqlite",
"unix": {
"filename": "sqlite-autoconf-3310100.tar.gz",
"hash": "sha1:0c30f5b22152a8166aa3bebb0f4bc1f3e9cc508b",
"urls": ["https://www.sqlite.org/2020/{filename}"]
"filename": "sqlite-autoconf-3340100.tar.gz",
"hash": "sha256:2a3bca581117b3b88e5361d0ef3803ba6d8da604b1c1a47d902ef785c1b53e89",
"urls": ["https://www.sqlite.org/2021/{filename}"]
}
},
{
"name": "libffi",
"os": "linux",
"unix": {
"filename": "libffi-3.2.1.tar.gz",
"hash": "sha1:280c265b789e041c02e5c97815793dfc283fb1e6",
"urls": ["ftp://sourceware.org/pub/libffi/{filename}"]
"filename": "libffi-3.3.0.tar.gz",
"hash": "sha256:72fba7922703ddfa7a028d513ac15a85c8d54c8d67f55fa5a4802885dc652056",
"urls": ["https://github.com/libffi/libffi/releases/download/v3.3/libffi-3.3.tar.gz"]
}
},
{
"name": "openssl",
"unix": {
"filename": "openssl-1.1.1g.tar.gz",
"hash": "sha256:ddb04774f1e32f0c49751e21b67216ac87852ceb056b75209af2443400636d46",
"filename": "openssl-1.1.1i.tar.gz",
"hash": "sha256:e8be6a35fe41d10603c3cc635e93289ed00bf34b79671a3a4de64fcee00d5242",
"urls": ["https://www.openssl.org/source/{filename}"]
}
},
@@ -91,15 +113,14 @@
"name": "readline",
"os": "linux",
"unix": {
"filename": "readline-8.0.tar.gz",
"hash": "sha256:e339f51971478d369f8a053a330a190781acb9864cf4c541060f12078948e461",
"filename": "readline-8.1.tar.gz",
"hash": "sha256:f8ceb4ee131e3232226a17f51b164afc46cd0b9e6cef344be87c65962cb82b02",
"urls": ["http://ftp.gnu.org/gnu/readline/{filename}"]
}
},
{
"name": "xz",
"os": "macos,linux",
"unix": {
"filename": "xz-5.2.5.tar.gz",
"hash": "sha256:f6f4910fd033078738bd82bfba4f49219d03b17eb0794eb91efbae419f4aba10",
@@ -107,20 +128,30 @@
}
},
{
"name": "xcrypt",
"os": "linux",
"unix": {
"filename": "xcrypt-4.4.17.tar.gz",
"hash": "sha256:7665168d0409574a03f7b484682e68334764c29c21ca5df438955a381384ca07",
"urls": ["https://github.com/besser82/libxcrypt/archive/v4.4.17.tar.gz"]
}
},
{
"name": "python",
"unix": {
"filename": "Python-3.8.3.tar.xz",
"hash": "sha256:dfab5ec723c218082fe3d5d7ae17ecbdebffa9a1aea4d64aa3a2ecdd2e795864",
"urls": ["https://www.python.org/ftp/python/3.8.3/{filename}"]
"filename": "Python-3.9.4.tar.xz",
"hash": "sha256:4b0e6644a76f8df864ae24ac500a51bbf68bd098f6a173e27d3b61cdca9aa134",
"urls": ["https://www.python.org/ftp/python/3.9.4/{filename}"]
}
},
{
"name": "setuptools",
"unix": {
"filename": "setuptools-41.0.1.zip",
"hash": "sha256:a222d126f5471598053c9a77f4b5d4f26eaa1f150ad6e01dcf1a42e185d05613",
"filename": "setuptools-53.0.0.tar.gz",
"hash": "sha256:1b18ef17d74ba97ac9c0e4b4265f123f07a8ae85d9cd093949fa056d3eeeead5",
"urls": ["pypi"]
}
},
@@ -128,22 +159,12 @@
{
"name": "pygments",
"unix": {
"filename": "Pygments-2.6.1.tar.gz",
"hash": "sha256:647344a061c249a3b74e230c739f434d7ea4d8b1d5f3721bc0f3558049b38f44",
"filename": "Pygments-2.7.4.tar.gz",
"hash": "sha256:df49d09b498e83c1a73128295860250b0b7edd4c723a32e9bc0d295c7c2ec337",
"urls": ["pypi"]
}
},
{
"name": "cmake",
"os": "macos",
"unix": {
"filename": "cmake-3.6.0.tar.gz",
"hash": "sha1:6b0d2d7d93c2e74f8890c4b8b824deb3b36d24b6",
"urls": ["https://cmake.org/files/v3.6/{filename}"]
}
},
{
"name": "libpng",
"unix": {
@@ -156,9 +177,9 @@
{
"name": "lcms2",
"unix": {
"filename": "lcms2-2.11.tar.gz",
"hash": "sha256:478c9c3938d7a91b1171de4616f8b04308a8676d73eadc19505b7ace41327f28",
"urls": ["https://github.com/mm2/Little-CMS/archive/2.11/{filename}"]
"filename": "lcms2-2.12.tar.gz",
"hash": "sha256:e501f1482fc424550ef3abbf86bf1c66090e1661249e89552d39ed5bf935df66",
"urls": ["https://github.com/mm2/Little-CMS/archive/2.12/{filename}"]
}
},
@@ -166,8 +187,8 @@
"name": "graphite",
"os": "linux",
"unix": {
"filename": "graphite2-1.3.5.tgz",
"hash": "md5:5b8d22a8bbf031838e31432868c0109c",
"filename": "graphite2-1.3.14.tgz",
"hash": "sha256:f99d1c13aa5fa296898a181dff9b82fb25f6cc0933dbaa7a475d8109bd54209d",
"urls": ["http://downloads.sourceforge.net/silgraphite/{filename}"]
}
},
@@ -176,8 +197,8 @@
"name": "pcre",
"os": "linux",
"unix": {
"filename": "pcre-8.42.tar.bz2",
"hash": "md5:085b6aa253e0f91cae70b3cdbe8c1ac2",
"filename": "pcre-8.44.tar.bz2",
"hash": "sha256:19108658b23b3ec5058edc9f66ac545ea19f9537234be1ec62b714c84399366d",
"urls": ["https://ftp.pcre.org/pub/pcre/{filename}"]
}
},
@@ -196,9 +217,19 @@
"name": "glib",
"os": "linux",
"unix": {
"filename": "glib-2.65.1.tar.xz",
"hash": "sha256:bc63bf6c32713e0ee1dddc28e03f23b4a20c78bcb9a2c5b0f4eea41e46fb9cee",
"urls": ["https://ftp.gnome.org/pub/GNOME/sources/glib/2.65/{filename}"]
"filename": "glib-2.66.6.tar.xz",
"hash": "sha256:80fff9c63d2725834328071c42003c311f77f91caf2285195c587c62f5638329",
"urls": ["https://ftp.gnome.org/pub/GNOME/sources/glib/2.66/{filename}"]
}
},
{
"name": "brotli",
"os": "linux",
"unix": {
"filename": "brotli-1.0.9.tar.gz",
"hash": "sha256:f9e8d81d0405ba66d181529af42a3354f838c939095ff99930da6aa9cdf6fe46",
"urls": ["https://github.com/google/brotli/archive/v1.0.9/{filename}"]
}
},
@@ -206,8 +237,8 @@
"name": "freetype",
"os": "linux",
"unix": {
"filename": "freetype-2.9.1.tar.bz2",
"hash": "md5:60ef7d8160cd4bf8cb118ee9d65367ca",
"filename": "freetype-2.10.4.tar.xz",
"hash": "sha256:86a854d8905b19698bbc8f23b860bc104246ce4854dcea8e3b0fb21284f75784",
"urls": ["https://download.savannah.gnu.org/releases/freetype/{filename}"]
}
},
@@ -216,8 +247,8 @@
"name": "fontconfig",
"os": "linux",
"unix": {
"filename": "fontconfig-2.12.0.tar.bz2",
"hash": "sha256:b433e4efff1f68fdd8aac221ed1df3ff1e580ffedbada020a703fe64017d8224",
"filename": "fontconfig-2.13.1.tar.bz2",
"hash": "sha256:f655dd2a986d7aa97e052261b36aa67b0a64989496361eca8d604e6414006741",
"urls": ["http://www.fontconfig.org/release/{filename}"]
}
},
@@ -225,19 +256,9 @@
{
"name": "harfbuzz",
"unix": {
"filename": "harfbuzz-1.7.2.tar.bz2",
"hash": "sha256:a790585e35c1a87f0dcc23580c84b7cc2324e6f67a2946178d278c2a36c790cb",
"urls": ["https://www.freedesktop.org/software/harfbuzz/release/{filename}"]
}
},
{
"name": "libxml2",
"os": "linux",
"unix": {
"filename": "libxml2-2.9.4.tar.gz",
"hash": "sha1:958ae70baf186263a4bd801a81dd5d682aedd1db",
"urls": ["ftp://xmlsoft.org/libxml2/{filename}"]
"filename": "harfbuzz-2.7.4.tar.xz",
"hash": "sha256:6ad11d653347bd25d8317589df4e431a2de372c0cf9be3543368e07ec23bb8e7",
"urls": ["https://github.com/harfbuzz/harfbuzz/releases/download/2.7.4/{filename}"]
}
},
@@ -245,8 +266,8 @@
"name": "wayland",
"os": "linux",
"unix": {
"filename": "wayland-1.18.0.tar.xz",
"hash": "sha256:4675a79f091020817a98fd0484e7208c8762242266967f55a67776936c2e294d",
"filename": "wayland-1.19.0.tar.xz",
"hash": "sha256:baccd902300d354581cd5ad3cc49daa4921d55fb416a5883e218750fef166d15",
"urls": ["https://wayland.freedesktop.org/releases/{filename}"]
}
},

View File

@@ -4,8 +4,6 @@ import subprocess
files_to_exclude = '''\
kitty/wcwidth-std.h
kitty/glfw.c
kitty/keys.h
kitty/charsets.c
kitty/unicode-data.c
kitty/key_encoding.py
@@ -18,6 +16,11 @@ kitty/glfw-wrapper.c
kitty/emoji.h
kittens/unicode_input/names.h
kitty/parse-graphics-command.h
kitty/options/types.py
kitty/options/parse.py
kitty/options/to-c-generated.h
kittens/diff/options/types.py
kittens/diff/options/parse.py
'''
p = subprocess.Popen([

View File

@@ -2,7 +2,7 @@
#
# You can set these variables from the command line.
SPHINXOPTS = -j auto -T $(FAIL_WARN)
SPHINXOPTS = -n -q -j auto -T $(FAIL_WARN) $(OPTS)
SPHINXBUILD = sphinx-build
SPHINXPROJ = kitty
SOURCEDIR = .
@@ -18,3 +18,7 @@ help:
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
develop-docs:
sphinx-autobuild --ignore "$(abspath $(SOURCEDIR))/generated/*" --watch ../kitty --watch ../kittens -b dirhtml "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS)

View File

@@ -5,118 +5,15 @@
* Distributed under terms of the MIT license.
*/
.float-left-img {
float: left;
margin-right: 1em;
margin-bottom: 1em;
}
.float-right-img { float: right; margin-left: 1em; margin-bottom: 1em }
.half-with-img { max-width: 50% }
.fit-img { max-width: 95% }
div.body p, div.body dd, div.body li, div.body blockquote {
text-align: justify;
}
pre {
white-space: pre-wrap;
}
pre.pre {
white-space: pre;
}
a[href], input[type="submit"] { cursor: pointer; }
img[style] {
/* Used for :scale: images to have them render properly but still popup when clicked */
width: auto !important;
height: auto !important;
}
a {
text-decoration: none !important;
border-bottom: none !important;
}
body div.document {
margin-top: 1ex;
.sidebar-logo {
max-height: 128px;
}
.major-features li {
margin-top: 0.75ex;
margin-bottom: 0.75ex;
}
.support-form input[type=submit] {
border-radius: 6px;
box-shadow: rgb(255, 246, 175) 0px 1px 0px 0px;
background: linear-gradient(rgb(255, 236, 100) 5%, rgb(255, 171, 35) 100%) rgb(255, 236, 100);
border: 1px solid rgb(255, 170, 34);
display: inline-block;
color: rgb(51, 51, 51);
font-family: Arial;
font-size: 15px;
font-weight: bold;
padding: 6px 24px;
text-decoration: none;
text-shadow: rgb(255, 238, 102) 0px 1px 0px;
}
.support-form input[type=submit]:hover {
background: linear-gradient(rgb(255, 171, 35) 5%, rgb(255, 236, 100) 100%) rgb(255, 171, 35);
}
.support-form input[type=submit]:focus {
outline: 0;
}
div.sphinxsidebar {
font-size: inherit;
line-height: inherit;
max-height: 100%;
overflow-y: auto;
}
#sidebartoc li {
margin-top: 0.75ex;
margin-bottom: 0.75ex;
}
#sidebartoc ul {
list-style: none !important;
}
#sidebartoc a[href]:hover {
color: red;
}
.green {
color: green;
}
.cyan {
color: blue;
}
.env {
.sidebar-tree a.current {
font-style: italic;
}
.italic {
font-style: italic;
}
.bold {
font-weight: bold;
}
.title {
font-size: larger;
font-weight: bold
}

57
docs/_static/custom.js vendored Normal file
View File

@@ -0,0 +1,57 @@
/* vim:fileencoding=utf-8
*
* Copyright (C) 2021 Kovid Goyal <kovid at kovidgoyal.net>
*
* Distributed under terms of the GPLv3 license
*/
(function() {
"use strict";
function get_sidebar_tree() {
return document.querySelector('.sidebar-tree');
}
function scroll_sidebar_node_into_view(a) {
var ss = get_sidebar_tree().closest('.sidebar-scroll');
if (!ss || !a) return;
ss.style.position = 'relative';
var pos = 0;
while (true) {
pos += a.offsetTop;
a = a.offsetParent;
if (!a || a == ss) break;
}
ss.scrollTop = pos;
}
function mark_current_link(sidebar_tree, a, onload) {
var li = a.closest('li.has-children');
while (li) {
li.querySelector('input[type=checkbox]').setAttribute('checked', 'checked');
li = li.parentNode.closest('li.has-children');
}
sidebar_tree.querySelectorAll('.current').forEach(function (elem) {
elem.classList.remove('current');
});
if (onload) scroll_sidebar_node_into_view(a);
a.classList.add('current');
}
function show_hash_in_sidebar(onload) {
var sidebar_tree = document.querySelector('.sidebar-tree');
if (document.location.hash.length > 1) {
var a = sidebar_tree.querySelector('a[href="' + document.location.hash + '"]');
if (a) mark_current_link(sidebar_tree, a, onload);
} else {
if (onload) scroll_sidebar_node_into_view(sidebar_tree.querySelector('.current-page a'));
}
}
document.addEventListener("DOMContentLoaded", function() {
show_hash_in_sidebar(true);
window.addEventListener('hashchange', show_hash_in_sidebar.bind(null, false));
});
}());

22
docs/_templates/base.html vendored Normal file
View File

@@ -0,0 +1,22 @@
{% extends "!base.html" %}
{% block extrahead %}
{{ super() }}
{%- if analytics_id %}
<script type="text/javascript">
var _gaq = _gaq || [];
_gaq.push(['_setAccount', '{{ analytics_id }}']);
_gaq.push(['_setDomainName', 'none']);
_gaq.push(['_setAllowLinker', true]);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
</script>
{% endif -%}
{% endblock %}

View File

@@ -1,6 +0,0 @@
{% extends "!layout.html" %}
{%- block extrahead %}
<!-- kitty analytics placeholder -->
{{ super() }}
{% endblock %}

View File

@@ -1,6 +0,0 @@
{%- if display_toc %}
<div>&nbsp;</div>
<div id="sidebartoc">
{{ toc }}
</div>
{%- endif %}

View File

@@ -1,22 +0,0 @@
{#
basic/searchbox.html
~~~~~~~~~~~~~~~~~~~~
Sphinx sidebar template: quick search box.
:copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
#}
{%- if pagename != "search" and builder != "singlehtml" %}
<div id="searchbox" style="display: none" role="search">
<div class="searchformwrapper">
<form class="search" action="{{ pathto('search') }}" method="get">
<input type="text" name="q" placeholder="{{ _('Search') }}" />
<input type="submit" value="{{ _('Go') }}" style="cursor: pointer" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
{%- endif %}

View File

@@ -1,7 +0,0 @@
{% if pagename != "support" %}
<div id="support" style="text-align: center">
<form class="support-form" action="{{ pathto('support') }}" title="{{ _('Donate to support kitty development') }}">
<input type="submit" value="{{ _('Support kitty') }}">
</form>
</div>
{% endif %}

9
docs/actions.rst Normal file
View File

@@ -0,0 +1,9 @@
Mappable actions
-----------------------
.. highlight:: conf
The actions described below can be mapped to any key press or mouse action
using the ``map`` and ``mouse_map`` directives in :file:`kitty.conf`.
.. include:: /generated/actions.rst

135
docs/basic.rst Normal file
View File

@@ -0,0 +1,135 @@
Tabs and Windows
-------------------
|kitty| is capable of running multiple programs organized into tabs and
windows. The top level of organization is the *Tab*. Each tab consists
of one or more *windows*. The windows can be arranged in multiple
different layouts, like windows are organized in a tiling window
manager. The keyboard controls (which are all customizable) for tabs and
windows are:
Scrolling
~~~~~~~~~~~~~~
======================== =======================
Action Shortcut
======================== =======================
Scroll line up :sc:`scroll_line_up` (also :kbd:`⌥+⌘+⇞` and :kbd:`⌘+↑` on macOS)
Scroll line down :sc:`scroll_line_down` (also :kbd:`⌥+⌘+⇟` and :kbd:`⌘+↓` on macOS)
Scroll page up :sc:`scroll_page_up` (also :kbd:`⌘+⇞` on macOS)
Scroll page down :sc:`scroll_page_down` (also :kbd:`⌘+⇟` on macOS)
Scroll to top :sc:`scroll_home` (also :kbd:`⌘+↖` on macOS)
Scroll to bottom :sc:`scroll_end` (also :kbd:`⌘+↘` on macOS)
======================== =======================
Tabs
~~~~~~~~~~~
======================== =======================
Action Shortcut
======================== =======================
New tab :sc:`new_tab` (also :kbd:`⌘+t` on macOS)
Close tab :sc:`close_tab` (also :kbd:`⌘+w` on macOS)
Next tab :sc:`next_tab` (also :kbd:`^+⇥` and :kbd:`⇧+⌘+]` on macOS)
Previous tab :sc:`previous_tab` (also :kbd:`⇧+^+⇥` and :kbd:`⇧+⌘+[` on macOS)
Next layout :sc:`next_layout`
Move tab forward :sc:`move_tab_forward`
Move tab backward :sc:`move_tab_backward`
Set tab title :sc:`set_tab_title` (also :kbd:`⇧+⌘+i` on macOS)
======================== =======================
Windows
~~~~~~~~~~~~~~~~~~
======================== =======================
Action Shortcut
======================== =======================
New window :sc:`new_window` (also :kbd:`⌘+↩` on macOS)
New OS window :sc:`new_os_window` (also :kbd:`⌘+n` on macOS)
Close window :sc:`close_window` (also :kbd:`⇧+⌘+d` on macOS)
Next window :sc:`next_window`
Previous window :sc:`previous_window`
Move window forward :sc:`move_window_forward`
Move window backward :sc:`move_window_backward`
Move window to top :sc:`move_window_to_top`
Focus specific window :sc:`first_window`, :sc:`second_window` ... :sc:`tenth_window`
(also :kbd:`⌘+1`, :kbd:`⌘+2` ... :kbd:`⌘+9` on macOS)
(clockwise from the top-left)
======================== =======================
Additionally, you can define shortcuts in :file:`kitty.conf` to focus neighboring
windows and move windows around (similar to window movement in vim)::
map ctrl+left neighboring_window left
map shift+left move_window right
map ctrl+down neighboring_window down
map shift+down move_window up
...
You can also define a shortcut to switch to the previously active window::
map ctrl+p nth_window -1
``nth_window`` will focus the nth window for positive numbers and the
previously active windows for negative numbers.
.. _detach_window:
You can define shortcuts to detach the current window and
move it to another tab or another OS window::
# moves the window into a new OS window
map ctrl+f2 detach_window
# moves the window into a new Tab
map ctrl+f3 detach_window new-tab
# moves the window into the previously active tab
map ctrl+f3 detach_window tab-prev
# moves the window into the tab at the left of the active tab
map ctrl+f3 detach_window tab-left
# asks which tab to move the window into
map ctrl+f4 detach_window ask
Similarly, you can detach the current tab, with::
# moves the tab into a new OS window
map ctrl+f2 detach_tab
# asks which OS Window to move the tab into
map ctrl+f4 detach_tab ask
Finally, you can define a shortcut to close all windows in a tab other than
the currently active window::
map f9 close_other_windows_in_tab
Other keyboard shortcuts
----------------------------------
The full list of actions that can be mapped to key presses is available
:doc:`here </actions>`.
================================== =======================
Action Shortcut
================================== =======================
Copy to clipboard :sc:`copy_to_clipboard` (also :kbd:`⌘+c` on macOS)
Paste from clipboard :sc:`paste_from_clipboard` (also :kbd:`⌘+v` on macOS)
Paste from selection :sc:`paste_from_selection`
Increase font size :sc:`increase_font_size` (also :kbd:`⌘++` on macOS)
Decrease font size :sc:`decrease_font_size` (also :kbd:`⌘+-` on macOS)
Restore font size :sc:`reset_font_size` (also :kbd:`⌘+0` on macOS)
Toggle fullscreen :sc:`toggle_fullscreen` (also :kbd:`^+⌘+f` on macOS)
Toggle maximized :sc:`toggle_maximized`
Input unicode character :sc:`input_unicode_character` (also :kbd:`^+⌘+space` on macOS)
Click URL using the keyboard :sc:`open_url`
Reset the terminal :sc:`reset_terminal`
Reload :file:`kitty.conf` :sc:`reload_config_file` (also :kbd:`^+⌘+f5` on macOS)
Debug :file:`kitty.conf` :sc:`debug_config` (also :kbd:`⌘+option+f6` on macOS)
Pass current selection to program :sc:`pass_selection_to_program`
Edit |kitty| config file :sc:`edit_config_file`
Open a |kitty| shell :sc:`kitty_shell`
Increase background opacity :sc:`increase_background_opacity`
Decrease background opacity :sc:`decrease_background_opacity`
Full background opacity :sc:`full_background_opacity`
Reset background opacity :sc:`reset_background_opacity`
================================== =======================

View File

@@ -1,6 +1,9 @@
kitty - Binary install
Install kitty
========================
Binary install
----------------
.. |ins| replace:: curl -L :literal:`https://sw.kovidgoyal.net/kitty/installer.sh` | sh /dev/stdin
.. highlight:: sh
@@ -44,10 +47,17 @@ particular desktop, but it should work for most major desktop environments.
# your PATH)
ln -s ~/.local/kitty.app/bin/kitty ~/.local/bin/
# Place the kitty.desktop file somewhere it can be found by the OS
cp ~/.local/kitty.app/share/applications/kitty.desktop ~/.local/share/applications
cp ~/.local/kitty.app/share/applications/kitty.desktop ~/.local/share/applications/
# Update the path to the kitty icon in the kitty.desktop file
sed -i "s|Icon=kitty|Icon=/home/$USER/.local/kitty.app/share/icons/hicolor/256x256/apps/kitty.png|g" ~/.local/share/applications/kitty.desktop
.. note::
If you use the venerable `stow <https://www.gnu.org/software/stow/>`_
command to manage your manual installations, the following takes care of the
above for you (use with :file:`dest=~/.local/stow`)::
cd ~/.local/stow
stow -v kitty.app
Customizing the installation

View File

@@ -1,37 +1,51 @@
Building kitty from source
==============================
Build from source
==================
.. image:: https://github.com/kovidgoyal/kitty/workflows/CI/badge.svg
:alt: Build status
:target: https://github.com/kovidgoyal/kitty/actions?query=workflow%3ACI
|kitty| is designed to run from source, for easy hackability. Make sure
|kitty| is designed to run from source, for easy hack-ability. Make sure
the following dependencies are installed first.
.. note::
If you are making small changes only to the python parts of kitty, there is no need to
build kitty at all, instead, assuming you have installed the official kitty
binaries, you can simply set the KITTY_DEVELOP_FROM enviroment variable to
point to the directory into which you have checked out the kitty source
code. kitty will then load its python code from there. You should use a
version of the source that matches the binary version as closely as
possible, since the two are tightly coupled.
Dependencies
----------------
Run-time dependencies:
* python >= 3.5
* harfbuzz >= 1.5.0
* zlib
* libpng
* liblcms2
* freetype (not needed on macOS)
* fontconfig (not needed on macOS)
* libcanberra (not needed on macOS)
* ImageMagick (optional, needed to use the ``kitty icat`` tool to display images in the terminal)
* pygments (optional, need for syntax highlighting in ``kitty +kitten diff``)
* ``python`` >= 3.6
* ``harfbuzz`` >= 2.2.0
* ``zlib``
* ``libpng``
* ``liblcms2``
* ``freetype`` (not needed on macOS)
* ``fontconfig`` (not needed on macOS)
* ``libcanberra`` (not needed on macOS)
* ``ImageMagick`` (optional, needed to use the ``kitty +kitten icat`` tool to display images in the terminal)
* ``pygments`` (optional, needed for syntax highlighting in ``kitty +kitten diff``)
Build-time dependencies:
* gcc or clang
* pkg-config
* For building on Linux in addition to the above dependencies you might also need to install the ``-dev`` packages for:
``libdbus-1-dev``, ``libxcursor-dev``, ``libxrandr-dev``, ``libxi-dev``, ``libxinerama-dev``, ``libgl1-mesa-dev``, ``libxkbcommon-x11-dev``, ``libfontconfig-dev``, and ``libpython-dev``,
if they are not already installed by your distro.
* ``gcc`` or ``clang``
* ``pkg-config``
* For building on Linux in addition to the above dependencies you might also need to install the ``-dev`` packages for:
``libdbus-1-dev``, ``libxcursor-dev``, ``libxrandr-dev``, ``libxi-dev``, ``libxinerama-dev``,
``libgl1-mesa-dev``, ``libxkbcommon-x11-dev``, ``libfontconfig-dev``, ``libx11-xcb-dev``,
``liblcms2-dev``, and ``libpython3-dev``, if they are not already installed by your distro.
Install and run from source
------------------------------
@@ -67,9 +81,8 @@ you might have to rebuild the app.
.. note::
The released :file:`kitty.dmg` includes all dependencies, unlike the
:file:`kitty.app` built above and is built automatically by using the
:file:`kitty` branch of `build-calibre
<https://github.com/kovidgoyal/build-calibre>`_ however, that is designed to
run on Linux and is not for the faint of heart.
`bypy framework <https://github.com/kovidgoyal/bypy>`_ however, that is
designed to run on Linux and is not for the faint of heart.
.. note::
@@ -78,6 +91,19 @@ you might have to rebuild the app.
a self signed certificate, see for example, `here
<https://stackoverflow.com/questions/27474751/how-can-i-codesign-an-app-without-being-in-the-mac-developer-program/27474942>`_.
Build and run from source with Nix
-------------------------------------------
On NixOS or any other Linux or macOS system with the Nix package manager
installed, execute `nix-shell
<https://nixos.org/guides/nix-pills/developing-with-nix-shell.html>`_ to create
the correct environment to build kitty or use ``nix-shell --pure`` instead to
eliminate most of the influence of the outside system, e.g. globally installed
packages. ``nix-shell`` will automatically fetch all required dependencies and
make them available in the newly spawned shell.
Then proceed with ``make`` or ``make app`` according to the platform specific instructions above.
Note for Linux/macOS packagers
----------------------------------
@@ -105,18 +131,19 @@ This allows users to install the terminfo file on servers into which they ssh,
without needing to install all of |kitty|.
.. note::
You need a couple of extra dependencies to build linux-package.
:file:`tic` to compile terminfo files, usually found in the
development package of :file:`ncurses`. Also, if you are building from
a git checkout instead of the released source code tarball, you will
need :file:`sphinx-build` from the `Sphinx documentation generator
<https://www.sphinx-doc.org/>`_.
You need a couple of extra dependencies to build linux-package.
:file:`tic` to compile terminfo files, usually found in the
development package of :file:`ncurses`. Also, if you are building from
a git checkout instead of the released source code tarball, you will
need to install the dependencies from ``docs/requirements.txt`` to
build the kitty documentation. They can be installed most easily with
``python -m pip -r docs/requirements.txt``.
This applies to creating packages for |kitty| for macOS package managers such as
brew or MacPorts as well.
.. note::
|kitty| has its own update check mechanism, if you would like to turn
it off for your package, use
``python3 setup.py linux-package --update-check-interval=0``
|kitty| has its own update check mechanism, if you would like to turn
it off for your package, use
``python3 setup.py linux-package --update-check-interval=0``

View File

@@ -1,9 +1,554 @@
Changelog
==============
|kitty| is a feature full, cross-platform, *fast*, GPU based terminal emulator.
|kitty| is a feature-rich, cross-platform, *fast*, GPU based terminal.
To update |kitty|, :doc:`follow the instructions <binary>`.
0.22.1 [2021-07-31]
----------------------
- Fix a regression in the previous release that broke ``kitty --help`` (:iss:`3869`)
- Graphics protocol: Fix composing onto currently displayed frame not updating the frame on the GPU (:iss:`3874`)
- Fix switching to previously active tab after detaching a tab not working (:pull:`3871`)
- macOS: Fix an error on Apple silicon when enumerating monitors (:pull:`3875`)
- detach_window: Allow specifying the previously active tab or the tab to the left/right of
the active tab (:disc:`3877`)
- broadcast kitten: Fix a regression in ``0.20.0`` that broke sending of some
keys, such as backspace
- Linux binary: Remove any RPATH build artifacts from bundled libraries
- Wayland: If the compositor turns off server side decorations after turning
them on do not draw client side decorations (:iss:`3888`)
0.22.0 [2021-07-26]
----------------------
- Add a new :ref:`action-toggle_layout` action to easily zoom/unzoom a window
- When right clicking to extend a selection, move the nearest selection
boundary rather than the end of the selection. To restore previous behavior
use ``mouse_map right press ungrabbed mouse_selection move-end``.
- When opening hyperlinks, allow defining open actions for directories
(:pull:`3836`)
- When using the OSC 52 escape code to copy to clipboard allow large
copies (up to 8MB) without needing a kitty specific chunking protocol.
Note that if you used the chunking protocol in the past, it will no longer
work and you should switch to using the unmodified protocol which has the
advantage of working with all terminal emulators.
- Fix a bug in the implementation of the synchronized updates escape code that
could cause incorrect parsing if either the pending buffer capacity or the
pending timeout were exceeded (:iss:`3779`)
- A new remote control command to :program:`resize the OS Window <kitty @
resize-os-window>`
- Graphics protocol: Add support for composing rectangles from one animation
frame onto another (:iss:`3809`)
- diff kitten: Remove limit on max line length of 4096 characters (:iss:`3806`)
- Fix turning off cursor blink via escape codes not working (:iss:`3808`)
- Allow using neighboring window operations in the stack layout. The previous
window is considered the left and top neighbor and the next window is
considered the bottom and right neighbor (:iss:`3778`)
- macOS: Render colors in the sRGB colorspace to match other macOS terminal
applications (:iss:`2249`)
- Add a new variable ``{num_window_groups}`` for the :opt:`tab_title_template`
(:iss:`3837`)
- Wayland: Fix :opt:`initial_window_width/height <remember_window_size>` specified
in cells not working on High DPI screens (:iss:`3834`)
- A new theme for the kitty website with support for dark mode.
- Render ┄ ┅ ┆ ┇ ┈ ┉ ┊ ┋ with spaces at the edges. Matches rendering in
most other programs and allows long chains of them to look better
(:iss:`3844`)
- hints kitten: Detect paths and hashes that appear over multiple lines.
Note that this means that all line breaks in the text are no longer \n
soft breaks are instead \r. If you use a custom regular expression that
is meant to match over line breaks, you will need to match over both.
(:iss:`3845`)
- Allow leading or trailing spaces in :opt:`tab_activity_symbol`
- Fix mouse actions not working when caps lock or num lock are engaged
(:iss:`3859`)
- macOS: Fix automatic detection of bold/italic faces for fonts that
use the family name as the full face name of the regular font not working
(:iss:`3861`)
- clipboard kitten: fix copies to clipboard not working without the
:option:`kitty +kitten clipboard --wait-for-completion` option
0.21.2 [2021-06-28]
----------------------
- A new :opt:`adjust_baseline` option to adjust the vertical alignment of text
inside a line (:pull:`3734`)
- A new :opt:`url_excluded_characters` option to exclude additional characters
when detecting URLs under the mouse (:pull:`3738`)
- Fix a regression in 0.21.0 that broke rendering of private use Unicode symbols followed
by spaces, when they also exist not followed by spaces (:iss:`3729`)
- ssh kitten: Support systems where the login shell is a non-POSIX shell
(:iss:`3405`)
- ssh kitten: Add completion (:iss:`3760`)
- ssh kitten: Fix "Connection closed" message being printed by ssh when running
remote commands
- Add support for the XTVERSION escape code
- macOS: Fix a regression in 0.21.0 that broke middle-click to paste from clipboard (:iss:`3730`)
- macOS: Fix shortcuts in the global menu bar responding slowly when cursor blink
is disabled/timed out (:iss:`3693`)
- When displaying scrollback ensure that the window does not quit if the amount
of scrollback is less than a screen and the user has the ``--quit-if-one-screen``
option enabled for less (:iss:`3740`)
- Linux: Fix Emoji/bitmapped fonts not use able in symbol_map
- query terminal kitten: Allow querying font face and size information
(:iss:`3756`)
- hyperlinked grep kitten: Fix context options not generating contextual output (:iss:`3759`)
- Allow using superscripts in tab titles (:iss:`3763`)
- Unicode input kitten: Fix searching when a word has more than 1024 matches (:iss:`3773`)
0.21.1 [2021-06-14]
----------------------
- macOS: Fix a regression in the previous release that broke rendering of
strikeout (:iss:`3717`)
- macOS: Fix a crash when rendering ligatures larger than 128 characters
(:iss:`3724`)
- Fix a regression in the previous release that could cause a crash when
changing layouts and mousing (:iss:`3713`)
0.21.0 [2021-06-12]
----------------------
- Allow reloading the :file:`kitty.conf` config file by pressing
:sc:`reload_config_file`. (:iss:`1292`)
- Allow clicking URLs to open them without needing to also hold
:kbd:`ctrl+shift`
- Allow remapping all mouse button press/release events to perform arbitrary
actions. :ref:`See details <conf-kitty-mouse.mousemap>` (:iss:`1033`)
- Support infinite length ligatures (:iss:`3504`)
- **Backward incompatibility**: The options to control which modifiers keys to
press for various mouse actions have been removed, if you used these options,
you will need to replace them with configuration using the new
:ref:`mouse actions framework <conf-kitty-mouse.mousemap>` as they will be
ignored. The options were: ``terminal_select_modifiers``,
``rectangle_select_modifiers`` and ``open_url_modifiers``.
- Add a configurable mouse action (:kbd:`ctrl+alt+triplepress` to select from the
clicked point to the end of the line. (:iss:`3585`)
- Add the ability to un-scroll the screen to the ``kitty @ scroll-window``
remote control command (:iss:`3604`)
- A new option, :opt:`tab_bar_margin_height` to add margins around the
top and bottom edges of the tab bar (:iss:`3247`)
- Unicode input kitten: Fix a regression in 0.20.0 that broke keyboard handling
when the NumLock or CapsLock modifiers were engaged. (:iss:`3587`)
- Fix a regression in 0.20.0 that sent incorrect bytes for the :kbd:`F1-F4` keys
in rmkx mode (:iss:`3586`)
- macOS: When the Apple Color Emoji font lacks an emoji glyph search for it in other
installed fonts (:iss:`3591`)
- macOS: Fix rendering getting stuck on some machines after sleep/screensaver
(:iss:`2016`)
- macOS: Add a new ``Shell`` menu to the global menubar with some commonly used
actions (:pull:`3653`)
- macOS: Fix the baseline for text not matching other CoreText based
applications for some fonts (:iss:`2022`)
- Add a few more special commandline arguments for the launch command. Now all
``KITTY_PIPE_DATA`` is also available via command line argument substitution
(:iss:`3593`)
- Fix dynamically changing the background color in a window causing rendering
artifacts in the tab bar (:iss:`3595`)
- Fix passing STDIN to launched background processes causing them to not inherit
environment variables (:pull:`3603`)
- Fix deleting windows that are not the last window via remote control leaving
no window focused (:iss:`3619`)
- Add an option :option:`kitty @ get-text --add-cursor` to also get the current
cursor position and state as ANSI escape codes (:iss:`3625`)
- Add an option :option:`kitty @ get-text --add-wrap-markers` to add line wrap
markers to the output (:pull:`3633`)
- Improve rendering of curly underlines on HiDPI screens (:pull:`3637`)
- ssh kitten: Mimic behavior of ssh command line client more closely by
executing any command specified on the command line via the users' shell
just as ssh does (:iss:`3638`)
- Fix trailing parentheses in URLs not being detected (:iss:`3688`)
- Tab bar: Use a lower contrast color for tab separators (:pull:`3666`)
- Fix a regression that caused using the ``title`` command in session files
to stop working (:iss:`3676`)
- macOS: Fix a rare crash on exit (:iss:`3686`)
- Fix ligatures not working with the `Iosevka
<https://github.com/be5invis/Iosevka>`_ font (requires Iosevka >= 7.0.4)
(:iss:`297`)
- Remote control: Allow matching tabs by index number in currently active OS
Window (:iss:`3708`)
- ssh kitten: Fix non-standard properties in terminfo such as the ones used for
true color not being copied (:iss:`312`)
0.20.3 [2021-05-06]
----------------------
- macOS: Distribute universal binaries with both ARM and Intel architectures
- A new ``show_key`` kitten to easily see the bytes generated by the terminal
for key presses in the various keyboard modes (:pull:`3556`)
- Linux: Fix keyboard layout change keys defined via compose rules not being
ignored
- macOS: Fix Spotlight search of global menu not working in non-English locales
(:pull:`3567`)
- Fix tab activity symbol not appearing if no other changes happen in tab bar even when
there is activity in a tab (:iss:`3571`)
- Fix focus changes not being sent to windows when focused window changes
because of the previously focused window being closed (:iss:`3571`)
0.20.2 [2021-04-28]
----------------------
- A new protocol extension to :ref:`unscroll <unscroll>` text from the
scrollback buffer onto the screen. Useful, for example, to restore
the screen after showing completions below the shell prompt.
- A new remote control command :ref:`at_env` to change the default
environment passed to newly created windows (:iss:`3529`)
- Linux: Fix binary kitty builds not able to load fonts in WOFF2 format
(:iss:`3506`)
- macOS: Prevent :kbd:`option` based shortcuts for being used for global menu
actions (:iss:`3515`)
- Fix ``kitty @ close-tab`` not working with pipe based remote control
(:iss:`3510`)
- Fix removal of inactive tab that is before the currently active tab causing
the highlighted tab to be incorrect (:iss:`3516`)
- icat kitten: Respect EXIF orientation when displaying JPEG images
(:iss:`3518`)
- GNOME: Fix maximize state not being remembered when focus changes and window
decorations are hidden (:iss:`3507`)
- GNOME: Add a new :opt:`wayland_titlebar_color` option to control the color of the
kitty window title bar
- Fix reading :option:`kitty --session` from ``STDIN`` not working when the
:option:`kitty --detach` option is used (:iss:`3523`)
- Special case rendering of the few remaining Powerline box drawing chars
(:iss:`3535`)
- Fix ``kitty @ set-colors`` not working for the :opt:`active_tab_foreground`.
0.20.1 [2021-04-19]
----------------------
- icat: Fix some broken GIF images with no frame delays not being animated
(:iss:`3498`)
- hints kitten: Fix sending hyperlinks to their default handler not working
(:pull:`3500`)
- Wayland: Fix regression in previous release causing window decorations to
be drawn even when compositor supports server side decorations (:iss:`3501`)
0.20.0 [2021-04-19]
----------------------
- Support display of animated images ``kitty +kitten icat animation.gif``. See
:ref:`animation_protocol` for details on animation support in the kitty
graphics protocol.
- A new keyboard reporting protocol with various advanced features that can be
used by full screen terminal programs and even games, see
:doc:`keyboard-protocol` (:iss:`3248`)
- **Backward incompatibility**: Session files now use the full :doc:`launch <launch>`
command with all its capabilities. However, the syntax of the command is
slightly different from before. In particular watchers are now specified
directly on launch and environment variables are set using ``--env``.
- Allow setting colors when creating windows using the :doc:`launch <launch>` command.
- A new option :opt:`tab_powerline_style` to control the appearance of the tab
bar when using the powerline tab bar style.
- A new option :opt:`scrollback_fill_enlarged_window` to fill extra lines in
the window when the window is expanded with lines from the scrollback
(:pull:`3371`)
- diff kitten: Implement recursive diff over SSH (:iss:`3268`)
- ssh kitten: Allow using python instead of the shell on the server, useful if
the shell used is a non-POSIX compliant one, such as fish (:iss:`3277`)
- Add support for the color settings stack that XTerm copied from us without
acknowledgement and decided to use incompatible escape codes for.
- Add entries to the terminfo file for some user capabilities that are shared
with XTerm (:pull:`3193`)
- The launch command now does more sophisticated resolving of executables to
run. The system-wide PATH is used first, then system specific default paths,
and finally the PATH inside the shell.
- Double clicking on empty tab bar area now opens a new tab (:iss:`3201`)
- kitty @ ls: Show only environment variables that are different for each
window, by default.
- When passing a directory or a non-executable file as the program to run to
kitty opens it with the shell or by parsing the shebang, instead of just failing.
- Linux: Fix rendering of emoji followed by the graphics variation selector not
being colored with some fonts (:iss:`3211`)
- Unicode input: Fix using index in select by name mode not working for indices
larger than 16. Also using an index does not filter the list of matches. (:pull:`3219`)
- Wayland: Add support for the text input protocol (:iss:`3410`)
- Wayland: Fix mouse handling when using client side decorations
- Wayland: Fix un-maximizing a window not restoring its size to what it was
before being maximized
- GNOME/Wayland: Improve window decorations the titlebar now shows the window
title. Allow running under Wayland on GNOME by default. (:iss:`3284`)
- Panel kitten: Allow setting WM_CLASS (:iss:`3233`)
- macOS: Add menu items to close the OS window and the current tab (:pull:`3240`, :iss:`3246`)
- macOS: Allow opening script and command files with kitty (:iss:`3366`)
- Also detect ``gemini://`` URLs when hovering with the mouse (:iss:`3370`)
- When using a non-US keyboard layout and pressing :kbd:`ctrl+key` when
the key matches an English key, send that to the program running in the
terminal automatically (:iss:`2000`)
- When matching shortcuts, also match on shifted keys, so a shortcut defined as
:kbd:`ctrl+plus` will match a keyboard where you have to press
:kbd:`shift+equal` to get the plus key (:iss:`2000`)
- Fix extra space at bottom of OS window when using the fat layout with the tab bar at the
top (:iss:`3258`)
- Fix window icon not working on X11 with 64bits (:iss:`3260`)
- Fix OS window sizes under 100px resulting in scaled display (:iss:`3307`)
- Fix rendering of ligatures in the latest release of Cascadia code, which for
some reason puts empty glyphs after the ligature glyph rather than before it
(:iss:`3313`)
- Improve handling of infinite length ligatures in newer versions of FiraCode
and CascadiaCode. Now such ligatures are detected based on glyph naming
convention. This removes the gap in the ligatures at cell boundaries (:iss:`2695`)
- macOS: Disable the native operating system tabs as they are non-functional
and can be confusing (:iss:`3325`)
- hints kitten: When using the linenumber action with a background action,
preserve the working directory (:iss:`3352`)
- Graphics protocol: Fix suppression of responses not working for chunked
transmission (:iss:`3375`)
- Fix inactive tab closing causing active tab to change (:iss:`3398`)
- Fix a crash on systems using musl as libc (:iss:`3395`)
- Improve rendering of rounded corners by using a rectircle equation rather
than a cubic bezier (:iss:`3409`)
- Graphics protocol: Add a control to allow clients to specify that the cursor
should not move when displaying an image (:iss:`3411`)
- Fix marking of text not working on lines that contain zero cells
(:iss:`3403`)
- Fix the selection getting changed if the screen contents scroll while
the selection is in progress (:iss:`3431`)
- X11: Fix :opt:`resize_in_steps` being applied even when window is maximized
(:iss:`3473`)
0.19.3 [2020-12-19]
-------------------
- Happy holidays to all kitty users!
- A new :doc:`broadcast <kittens/broadcast>` kitten to type in all kitty windows
simultaneously (:iss:`1569`)
- Add a new mappable `select_tab` action to choose a tab to switch to even
when the tab bar is hidden (:iss:`3115`)
- Allow specifying text formatting in :opt:`tab_title_template` (:iss:`3146`)
- Linux: Read :opt:`font_features` from the FontConfig database as well, so
that they can be configured in a single, central location (:pull:`3174`)
- Graphics protocol: Add support for giving individual image placements their
own ids and for asking the terminal emulator to assign ids for images. Also
allow suppressing responses from the terminal to commands.
These are backwards compatible protocol extensions. (:iss:`3133`,
:iss:`3163`)
- Distribute extra pixels among all eight-blocks rather than adding them
all to the last block (:iss:`3097`)
- Fix drawing of a few sextant characters incorrect (:pull:`3105`)
- macOS: Fix minimize not working for chromeless windows (:iss:`3112`)
- Preserve lines in the scrollback if a scrolling region is defined that
is contiguous with the top of the screen (:iss:`3113`)
- Wayland: Fix key repeat being stopped by the release of an unrelated key
(:iss:`2191`)
- Add an option, :opt:`detect_urls` to control whether kitty will detect URLs
when the mouse moves over them (:pull:`3118`)
- Graphics protocol: Dont return filename in the error message when opening file
fails, since filenames can contain control characters (:iss:`3128`)
- macOS: Partial fix for traditional fullscreen not working on Big Sur
(:iss:`3100`)
- Fix one ANSI formatting escape code not being removed from the pager history
buffer when piping it as plain text (:iss:`3132`)
- Match the save/restore cursor behavior of other terminals, for the sake of
interoperability. This means that doing a DECRC without a prior DECSC is now
undefined (:iss:`1264`)
- Fix mapping ``remote_control send-text`` not working (:iss:`3147`)
- Add a ``right`` option for :opt:`tab_switch_strategy` (:pull:`3155`)
- Fix a regression in 0.19.0 that caused a rare crash when using the optional
:opt:`scrollback_pager_history_size` (:iss:`3049`)
- Full screen kittens: Fix incorrect cursor position after kitten quits
(:iss:`3176`)
0.19.2 [2020-11-13]
-------------------
- A new :doc:`kittens/query_terminal` kitten to easily query the running kitty
via escape codes to detect its version, and the values of
configuration options that enable or disable terminal features.
- Options to control mouse pointer shape, :opt:`default_pointer_shape`, and
:opt:`pointer_shape_when_dragging` (:pull:`3041`)
- Font independent rendering for braille characters, which ensures they are properly
aligned at all font sizes.
- Fix a regression in 0.19.0 that caused borders not to be drawn when setting
:opt:`window_margin_width` and keeping :opt:`draw_minimal_borders` on
(:iss:`3017`)
- Fix a regression in 0.19.0 that broke rendering of one-eight bar unicode
characters at very small font sizes (:iss:`3025`)
- Wayland: Fix a crash under GNOME when using multiple OS windows
(:pull:`3066`)
- Fix selections created by dragging upwards not being auto-cleared when
screen contents change (:pull:`3028`)
- macOS: Fix kitty not being added to PATH automatically when using pre-built
binaries (:iss:`3063`)
- Allow adding MIME definitions to kitty by placing a ``mime.types`` file in
the kitty config directory (:iss:`3056`)
- Dont ignore :option:`--title` when using a session file that defines no
windows (:iss:`3055`)
- Fix the send_text action not working in URL handlers (:iss:`3081`)
- Fix last character of URL not being detected if it is the only character on a
new line (:iss:`3088`)
- Don't restrict the ICH,DCH,REP control codes to only the current scroll region (:iss:`3090`, :iss:`3096`)
0.19.1 [2020-10-06]
-------------------
@@ -377,7 +922,7 @@ To update |kitty|, :doc:`follow the instructions <binary>`.
beam and underline cursors (:iss:`2337` and :pull:`2342`)
- When the application running in the terminal grabs the mouse, pass middle
clicks to the application unless :opt:`terminal_select_modifiers` are
clicks to the application unless `terminal_select_modifiers` are
pressed (:iss:`2368`)
- A new ``copy_and_clear_or_interrupt`` function (:iss:`2403`)
@@ -485,7 +1030,7 @@ To update |kitty|, :doc:`follow the instructions <binary>`.
- macOS: Add a :code:`titlebar-only` setting to
:opt:`hide_window_decorations` to only hide the title bar (:pull:`2286`)
- Fix a segfault when using :option:`kitty --debug-config` with maps (:iss:`2270`)
- Fix a segfault when using ``--debug-config`` with maps (:iss:`2270`)
- ``goto_tab`` now maps numbers larger than the last tab to the last tab
(:iss:`2291`)
@@ -657,7 +1202,7 @@ To update |kitty|, :doc:`follow the instructions <binary>`.
the mouse pointer shape when the terminal programs grabs the pointer
(:iss:`1808`)
- Add an option :opt:`terminal_select_modifiers` to control which modifiers
- Add an option `terminal_select_modifiers` to control which modifiers
are used to override mouse selection even when a terminal application has
grabbed the mouse (:iss:`1774`)
@@ -1230,8 +1775,7 @@ To update |kitty|, :doc:`follow the instructions <binary>`.
using standard keyboards) via `IBus
<https://github.com/ibus/ibus/wiki/ReadMe>`_ (:iss:`469`)
- Implement completion for the kitty command in bash and zsh. See
:ref:`completion`.
- Implement completion for the kitty command in bash and zsh
- Render the text under the cursor in a fixed color, configurable via
the option :opt:`cursor_text_color` (:iss:`126`)
@@ -1361,8 +1905,8 @@ To update |kitty|, :doc:`follow the instructions <binary>`.
- Support "-T" as an alias for "--title" (:pull:`659`)
- Fix a regression in the previous release that broke using :option:`kitty
--debug-config` with custom key mappings (:iss:`695`)
- Fix a regression in the previous release that broke using
``--debug-config`` with custom key mappings (:iss:`695`)
0.11.1 [2018-06-17]

26
docs/color-stack.rst Normal file
View File

@@ -0,0 +1,26 @@
Saving and restoring colors
==============================
It is often useful for a full screen application with its own color themes to
set the default foreground, background, selection and cursor colors and the
ANSI color table. This allows for various performance optimizations when
drawing the screen. The problem is that if the user previously used the escape
codes to change these colors herself, then running the full screen application
will lose her changes even after it exits. To avoid this, kitty introduces a
new pair of *OSC* escape codes to push and pop the current color values from a
stack::
<ESC>]30001<ESC>\ # push onto stack
<ESC>]30101<ESC>\ # pop from stack
These escape codes save/restore the colors, default
background, default foreground, selection background, selection foreground and
cursor color and the 256 colors of the ANSI color table.
.. note:: In July 2020, after several years, XTerm copied this protocol
extension, without acknowledgement, and using incompatible escape codes
(XTPUSHCOLORS, XTPOPCOLORS, XTREPORTCOLORS). And they decided to save not
just the dynamic colors but the entire ANSI color table. In the interests of
promoting interoperability, kitty added support for XTerm's escape codes as
well, and changed this extension to also save/restore the entire ANSI color
table.

View File

@@ -13,10 +13,7 @@ import subprocess
import sys
import time
from functools import partial
from typing import (
Any, Callable, Dict, Iterable, List, Match, Optional, Sequence, Tuple,
Union
)
from typing import Any, Callable, Dict, Iterable, List, Match, Optional, Tuple
from docutils import nodes
from docutils.parsers.rst.roles import set_classes
@@ -24,17 +21,15 @@ from pygments.lexer import RegexLexer, bygroups # type: ignore
from pygments.token import ( # type: ignore
Comment, Keyword, Literal, Name, Number, String, Whitespace
)
from sphinx import addnodes # type: ignore
from sphinx.environment.adapters.toctree import TocTree # type: ignore
from sphinx import addnodes, version_info # type: ignore
from sphinx.util.logging import getLogger # type: ignore
kitty_src = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
if kitty_src not in sys.path:
sys.path.insert(0, kitty_src)
from kitty.conf.definition import Option, Shortcut # noqa
from kitty.constants import str_version # noqa
from kitty.conf.types import Definition # noqa
from kitty.constants import str_version, website_url # noqa
# config {{{
# -- Project information -----------------------------------------------------
@@ -64,8 +59,14 @@ extensions = [
'sphinx.ext.ifconfig',
'sphinx.ext.viewcode',
'sphinx.ext.githubpages',
'sphinx_copybutton',
'sphinx_inline_tabs',
"sphinxext.opengraph",
]
# URL for OpenGraph tags
ogp_site_url = website_url()
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
@@ -89,13 +90,10 @@ language: Optional[str] = None
# directories to ignore when looking for source files.
# This pattern also affects html_static_path and html_extra_path .
exclude_patterns = [
'_build', 'Thumbs.db', '.DS_Store',
'generated/cli-*.rst', 'generated/conf-*.rst'
'_build', 'Thumbs.db', '.DS_Store', 'basic.rst',
'generated/cli-*.rst', 'generated/conf-*.rst', 'generated/actions.rst'
]
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx'
rst_prolog = '''
.. |kitty| replace:: *kitty*
.. |version| replace:: VERSION
@@ -105,7 +103,6 @@ rst_prolog = '''
.. role:: bold
.. role:: cyan
.. role:: title
.. role:: env
'''.replace('VERSION', str_version)
@@ -115,35 +112,26 @@ rst_prolog = '''
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
html_theme = 'alabaster'
html_theme = 'furo'
html_title = 'kitty'
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# documentation.
#
html_theme_options = {
'logo': 'kitty.png',
'show_powered_by': False,
'fixed_sidebar': True,
'sidebar_collapse': True,
'github_button': False,
'github_banner': True,
'github_user': 'kovidgoyal',
'github_repo': 'kitty',
# increase contrast of link color with text color
'link': '#00587d',
'link_hover': 'green',
html_theme_options: Dict[str, Any] = {
'sidebar_hide_name': True,
'navigation_with_keys': True,
}
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static', '../logo/kitty.png']
html_context = {
'css_files': ['_static/custom.css']
}
html_favicon = '../logo/kitty.png'
html_static_path = ['_static']
html_favicon = html_logo = '../logo/kitty.svg'
html_css_files = ['custom.css']
html_js_files = ['custom.js']
# Custom sidebar templates, must be a dictionary that maps document names
# to template names.
@@ -153,25 +141,17 @@ html_favicon = '../logo/kitty.png'
# default: ``['localtoc.html', 'relations.html', 'sourcelink.html',
# 'searchbox.html']``.
#
html_sidebars = {
'**': [
'about.html',
'support.html',
'searchbox.html',
'localtoc.html',
'relations.html',
]
}
html_show_sourcelink = False
html_show_sphinx = False
manpages_url = 'https://man7.org/linux/man-pages/man{section}/{page}.{section}.html'
# -- Options for manual page output ------------------------------------------
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
('invocation', 'kitty', 'kitty Documentation',
[author], 1)
('invocation', 'kitty', 'kitty Documentation', [author], 1),
('conf', 'kitty.conf', 'kitty.conf Documentation', [author], 5)
]
@@ -182,7 +162,7 @@ man_pages = [
# dir menu entry, description, category)
texinfo_documents = [
(master_doc, 'kitty', 'kitty Documentation',
author, 'kitty', 'A cross-platform, fast, feature full, GPU based terminal emulator',
author, 'kitty', 'Cross-platform, fast, feature-rich, GPU based terminal',
'Miscellaneous'),
]
# }}}
@@ -227,32 +207,10 @@ def commit_role(name: str, rawtext: str, text: str, lineno: int, inliner: Any, o
# }}}
# Sidebar ToC {{{
def create_toc(app: Any, pagename: str) -> Optional[Any]:
tt = TocTree(app.env)
toctree = tt.get_toc_for(pagename, app.builder)
if toctree is not None:
subtree = toctree[toctree.first_child_matching_class(nodes.list_item)]
bl = subtree.first_child_matching_class(nodes.bullet_list)
if bl is None:
return None # Empty ToC
subtree = subtree[bl]
# for li in subtree.traverse(nodes.list_item):
# modify_li(li)
# subtree['ids'] = [ID]
return app.builder.render_partial(subtree)['fragment']
def add_html_context(app: Any, pagename: str, templatename: str, context: Any, *args: Any) -> None:
if 'toc' in context:
context['toc'] = create_toc(app, pagename) or context['toc']
# }}}
# CLI docs {{{
def write_cli_docs(all_kitten_names: Iterable[str]) -> None:
from kitty.launch import options_spec as launch_options_spec
from kitty.cli import option_spec_as_rst
from kitty.launch import options_spec as launch_options_spec
with open('generated/launch.rst', 'w') as f:
f.write(option_spec_as_rst(
appname='launch', ospec=launch_options_spec, heading_char='_',
@@ -267,7 +225,7 @@ if you specify a program-to-run you can use the special placeholder
'kitty --to', 'kitty @ --to'))
as_rst = partial(option_spec_as_rst, heading_char='_')
from kitty.rc.base import all_command_names, command_for_name
from kitty.remote_control import global_options_spec, cli_msg
from kitty.remote_control import cli_msg, global_options_spec
with open('generated/cli-kitty-at.rst', 'w') as f:
p = partial(print, file=f)
p('kitty @\n' + '-' * 80)
@@ -288,6 +246,11 @@ if you specify a program-to-run you can use the special placeholder
with open(f'generated/cli-kitten-{kitten}.rst', 'w') as f:
p = partial(print, file=f)
p('.. program::', f'kitty +kitten {kitten}')
p(f'\nSource code for {kitten}')
p('-' * 72)
p(f'\nThe source code for this kitten is `available on GitHub <https://github.com/kovidgoyal/kitty/tree/master/kittens/{kitten}>`_.')
p('\nCommand Line Interface')
p('-' * 72, file=f)
p('\n\n' + option_spec_as_rst(
data['options'], message=data['help_text'], usage=data['usage'], appname=f'kitty +kitten {kitten}',
heading_char='^'))
@@ -296,7 +259,9 @@ if you specify a program-to-run you can use the special placeholder
def write_remote_control_protocol_docs() -> None: # {{{
from kitty.rc.base import all_command_names, command_for_name, RemoteCommand
from kitty.rc.base import (
RemoteCommand, all_command_names, command_for_name
)
field_pat = re.compile(r'\s*([a-zA-Z0-9_+]+)\s*:\s*(.+)')
def format_cmd(p: Callable, name: str, cmd: RemoteCommand) -> None:
@@ -352,6 +317,8 @@ class ConfLexer(RegexLexer):
(r'(include)(\s+)(.+?)$', bygroups(Comment.Preproc, Whitespace, Name.Namespace)),
(r'(map)(\s+)(\S+)(\s+)', bygroups(
Keyword.Declaration, Whitespace, String, Whitespace), 'action'),
(r'(mouse_map)(\s+)(\S+)(\s+)(\S+)(\s+)(\S+)(\s+)', bygroups(
Keyword.Declaration, Whitespace, String, Whitespace, Name.Variable, Whitespace, String, Whitespace), 'action'),
(r'(symbol_map)(\s+)(\S+)(\s+)(.+?)$', bygroups(
Keyword.Declaration, Whitespace, String, Whitespace, Literal)),
(r'([a-zA-Z_0-9]+)(\s+)', bygroups(
@@ -393,12 +360,14 @@ class SessionLexer(RegexLexer):
def link_role(name: str, rawtext: str, text: str, lineno: int, inliner: Any, options: Any = {}, content: Any = []) -> Tuple[List, List]:
text = text.replace('\n', ' ')
m = re.match(r'(.+)\s+<(.+?)>', text)
if m is None:
msg = inliner.reporter.error(f'link "{text}" not recognized', line=lineno)
prb = inliner.problematic(rawtext, rawtext, msg)
return [prb], [msg]
text, url = m.group(1, 2)
url = url.replace(' ', '')
set_classes(options)
node = nodes.reference(rawtext, text, refuri=url, **options)
return [node], []
@@ -450,87 +419,6 @@ def parse_shortcut_node(env: Any, sig: str, signode: Any) -> str:
return sig
def render_conf(conf_name: str, all_options: Iterable[Union['Option', Sequence['Shortcut']]]) -> str:
from kitty.conf.definition import merged_opts, Option, Group
ans = ['.. default-domain:: conf', '']
a = ans.append
current_group: Optional[Group] = None
all_options_ = list(all_options)
kitty_mod = 'kitty_mod'
def render_group(group: Group) -> None:
a('')
a(f'.. _conf-{conf_name}-{group.name}:')
a('')
a(group.short_text)
heading_level = '+' if '.' in group.name else '^'
a(heading_level * (len(group.short_text) + 20))
a('')
if group.start_text:
a(group.start_text)
a('')
def handle_group_end(group: Group) -> None:
if group.end_text:
assert current_group is not None
a(''), a(current_group.end_text)
def handle_group(new_group: Group, new_group_is_shortcut: bool = False) -> None:
nonlocal current_group
if new_group is not current_group:
if current_group:
handle_group_end(current_group)
current_group = new_group
render_group(current_group)
def handle_option(i: int, opt: Option) -> None:
nonlocal kitty_mod
if not opt.long_text or not opt.add_to_docs:
return
handle_group(opt.group)
if opt.name == 'kitty_mod':
kitty_mod = opt.defval_as_string
mopts = list(merged_opts(all_options_, opt, i))
a('.. opt:: ' + ', '.join(conf_name + '.' + mo.name for mo in mopts))
a('.. code-block:: conf')
a('')
sz = max(len(x.name) for x in mopts)
for mo in mopts:
a((' {:%ds} {}' % sz).format(mo.name, mo.defval_as_string))
a('')
if opt.long_text:
a(expand_opt_references(conf_name, opt.long_text))
a('')
def handle_shortcuts(shortcuts: Sequence[Shortcut]) -> None:
sc = shortcuts[0]
handle_group(sc.group, True)
sc_text = f'{conf_name}.{sc.short_text}'
a('.. shortcut:: ' + sc_text)
shortcuts = [s for s in shortcuts if s.add_to_default]
shortcut_slugs[f'{conf_name}.{sc.name}'] = (sc_text, sc.key.replace('kitty_mod', kitty_mod))
if shortcuts:
a('.. code-block:: conf')
a('')
for x in shortcuts:
if x.add_to_default:
a(' map {} {}'.format(x.key.replace('kitty_mod', kitty_mod), x.action_def))
a('')
if sc.long_text:
a(expand_opt_references(conf_name, sc.long_text))
a('')
for i, opt in enumerate(all_options_):
if isinstance(opt, Option):
handle_option(i, opt)
else:
handle_shortcuts(opt)
if current_group:
handle_group_end(current_group)
return '\n'.join(ans)
def process_opt_link(env: Any, refnode: Any, has_explicit_title: bool, title: str, target: str) -> Tuple[str, str]:
conf_name, opt = target.partition('.')[::2]
if not opt:
@@ -555,7 +443,7 @@ def process_shortcut_link(env: Any, refnode: Any, has_explicit_title: bool, titl
def write_conf_docs(app: Any, all_kitten_names: Iterable[str]) -> None:
app.add_lexer('conf', ConfLexer)
app.add_lexer('conf', ConfLexer() if version_info[0] < 3 else ConfLexer)
app.add_object_type(
'opt', 'opt',
indextemplate="pair: %s; Config Setting",
@@ -574,29 +462,47 @@ def write_conf_docs(app: Any, all_kitten_names: Iterable[str]) -> None:
sc_role = app.registry.domain_roles['std']['sc']
sc_role.warn_dangling = True
sc_role.process_link = process_shortcut_link
shortcut_slugs.clear()
def generate_default_config(all_options: Dict[str, Union[Option, Sequence[Shortcut]]], name: str) -> None:
from kitty.conf.definition import as_conf_file
def generate_default_config(definition: Definition, name: str) -> None:
with open(f'generated/conf-{name}.rst', 'w', encoding='utf-8') as f:
print('.. highlight:: conf\n', file=f)
f.write(render_conf(name, all_options.values()))
f.write('\n'.join(definition.as_rst(name, shortcut_slugs)))
conf_name = re.sub(r'^kitten-', '', name) + '.conf'
with open(f'generated/conf/{conf_name}', 'w', encoding='utf-8') as f:
text = '\n'.join(as_conf_file(all_options.values()))
text = '\n'.join(definition.as_conf())
print(text, file=f)
from kitty.config_data import all_options
generate_default_config(all_options, 'kitty')
from kitty.options.definition import definition
generate_default_config(definition, 'kitty')
from kittens.runner import get_kitten_conf_docs
for kitten in all_kitten_names:
all_options = get_kitten_conf_docs(kitten)
if all_options:
generate_default_config(all_options, f'kitten-{kitten}')
definition = get_kitten_conf_docs(kitten)
if definition:
generate_default_config(definition, f'kitten-{kitten}')
from kitty.actions import as_rst
with open('generated/actions.rst', 'w', encoding='utf-8') as f:
f.write(as_rst())
# }}}
def add_html_context(app: Any, pagename: str, templatename: str, context: Any, doctree: Any, *args: Any) -> None:
context['analytics_id'] = app.config.analytics_id
if 'toctree' in context:
# this is needed with furo to use all titles from pages
# in the sidebar (global) toc
original_toctee_function = context['toctree']
def include_sub_headings(**kwargs: Any) -> Any:
kwargs['titles_only'] = False
return original_toctee_function(**kwargs)
context['toctree'] = include_sub_headings
def setup(app: Any) -> None:
os.makedirs('generated/conf', exist_ok=True)
from kittens.runner import all_kitten_names
@@ -604,9 +510,11 @@ def setup(app: Any) -> None:
write_cli_docs(kn)
write_remote_control_protocol_docs()
write_conf_docs(app, kn)
app.add_lexer('session', SessionLexer)
app.add_config_value('analytics_id', '', 'env')
app.connect('html-page-context', add_html_context)
app.add_lexer('session', SessionLexer() if version_info[0] < 3 else SessionLexer)
app.add_role('link', link_role)
app.add_role('iss', partial(num_role, 'issues'))
app.add_role('pull', partial(num_role, 'pull'))
app.add_role('disc', partial(num_role, 'discussions'))
app.add_role('commit', commit_role)
app.connect('html-page-context', add_html_context)

View File

@@ -1,17 +1,16 @@
:tocdepth: 2
Configuring kitty
===============================
kitty.conf
-----------------------
.. highlight:: conf
|kitty| is highly customizable, everything from keyboard shortcuts, to painting
frames-per-second. See below for an overview of all customization
|kitty| is highly customizable, everything from keyboard shortcuts, to
rendering frames-per-second. See below for an overview of all customization
possibilities.
You can open the config file within kitty by pressing :sc:`edit_config_file`.
You can also display the current configuration by running ``kitty
--debug-config``.
You can reload the config file within kitty by pressing
:sc:`reload_config_file` or sending kitty the ``SIGUSR1`` signal. You can also
display the current configuration by pressing the :sc:`debug_config` key.
.. _confloc:
@@ -33,12 +32,37 @@ expanded, so :code:`${USER}.conf` becomes :file:`name.conf` if
include other.conf
.. note:: Syntax highlighting for :file:`kitty.conf` in vim is available via
`vim-kitty <https://github.com/fladson/vim-kitty>`_.
.. include:: /generated/conf-kitty.rst
Sample kitty.conf
^^^^^^^^^^^^^^^^^^^^^
--------------------
You can download a sample :file:`kitty.conf` file with all default settings and
comments describing each setting by clicking: :download:`sample kitty.conf
</generated/conf/kitty.conf>`.
.. only:: html
You can download a sample :file:`kitty.conf` file with all default settings and
comments describing each setting by clicking: :download:`sample kitty.conf
</generated/conf/kitty.conf>`.
.. only:: man
You can edit a fully commented sample kitty.conf by pressing the
:sc:`edit_config_file` shortcut in kitty. This will generate a config
file with full documentation and all settings commented out. If you
have a pre-existing kitty.conf, then that will be used instead, delete
it to see the sample file.
All mappable actions
------------------------
See the :doc:`list of all the things you can make kitty can do </actions>`.
.. toctree::
:hidden:
actions

21
docs/deccara.rst Normal file
View File

@@ -0,0 +1,21 @@
Setting text styles/colors in arbitrary regions of the screen
------------------------------------------------------------------
There already exists an escape code to set *some* text attributes in arbitrary
regions of the screen, `DECCARA
<https://vt100.net/docs/vt510-rm/DECCARA.html>`_. However, it is limited to
only a few attributes. |kitty| extends this to work with *all* SGR attributes.
So, for example, this can be used to set the background color in an arbitrary
region of the screen.
The motivation for this extension is the various problems with the existing
solution for erasing to background color, namely the *background color erase
(bce)* capability. See
`this discussion <https://github.com/kovidgoyal/kitty/issues/160#issuecomment-346470545>`_
and `this FAQ <https://invisible-island.net/ncurses/ncurses.faq.html#bce_mismatches>`_
for a summary of problems with *bce*.
For example, to set the background color to blue in a
rectangular region of the screen from (3, 4) to (10, 11), you use::
<ESC>[2*x<ESC>[4;3;11;10;44$r<ESC>[*x

View File

@@ -0,0 +1,122 @@
.. _desktop_notifications:
Desktop notifications
=======================
|kitty| implements an extensible escape code (OSC 99) to show desktop
notifications. It is easy to use from shell scripts and fully extensible to
show title and body. Clicking on the notification can optionally focus the
window it came from, and/or send an escape code back to the application running
in that window.
The design of the escape code is partially based on the discussion in
the defunct
`terminal-wg <https://gitlab.freedesktop.org/terminal-wg/specifications/-/issues/13>`_
The escape code has the form::
<OSC> 99 ; metadata ; payload <terminator>
Here ``<OSC>`` is :code:`<ESC>]` and ``<terminator>`` is
:code:`<ESC><backslash>`. The metadata is a section of colon separated
:code:`key=value` pairs. Every key must be a single character from the set
:code:`a-zA-Z` and every value must be a word consisting of characters from
the set :code:`a-zA-Z0-9-_/\+.,(){}[]*&^%$#@!`~`. The payload must be
interpreted based on the metadata section. The two semi-colons *must* always be
present even when no metadata is present.
Before going into details, lets see how one can display a simple, single line
notification from a shell script::
printf '\x1b]99;;Hello world\x1b\\'
To show a message with a title and a body::
printf '\x1b]99;i=1:d=0;Hello world\x1b\\'
printf '\x1b]99;i=1:d=1:p=body;This is cool\x1b\\'
The most important key in the metadata is the ``p`` key, it controls how the
payload is interpreted. A value of ``title`` means the payload is setting the
title for the notification. A value of ``body`` means it is setting the body,
and so on, see the table below for full details.
The design of the escape code is fundamentally chunked, this is because
different terminal emulators have different limits on how large a single escape
code can be. Chunking is accomplished by the ``i`` and ``d`` keys. The ``i``
key is the *notification id* which can be any string containing the characters
``[a-zA-Z0-9_-+.]``. The ``d`` key stands for *done* and
can only take the values ``0`` and ``1``. A value of ``0`` means the
notification is not yet done and the terminal emulator should hold off
displaying it. A value of ``1`` means the notification is done, and should be
displayed. You can specify the title or body multiple times and the terminal
emulator will concatenate them, thereby allowing arbitrarily long text
(terminal emulators are free to impose a sensible limit to avoid
Denial-of-Service attacks).
Both the ``title`` and ``body`` payloads must be either UTF-8 encoded plain
text with no embedded escape codes, or UTF-8 text that is base64 encoded, in
which case there must be an ``e=1`` key in the metadata to indicate the payload
is base64 encoded.
When the user clicks the notification, a couple of things can happen, the
terminal emulator can focus the window from which the notification came, and/or
it can send back an escape code to the application indicating the notification
was activated. This is controlled by the ``a`` key which takes a comma
separated set of values, ``report`` and ``focus``. The value ``focus`` means
focus the window from which the notification was issued and is the default.
``report`` means send an escape code back to the application. The format of the
returned escape code is::
<OSC> 99 ; i=identifier ; <terminator>
The value of ``identifier`` comes from the ``i`` key in the escape code sent by
the application. If the application sends no identifier, then the terminal
*must* use ``i=0``. Actions can be preceded by a negative sign to turn them
off, so for example if you do not want any action, turn off the default
``focus`` action with::
a=-focus
Complete specification of all the metadata keys is in the table below. If a
terminal emulator encounters a key in the metadata it does not understand,
the key *must* be ignored, to allow for future extensibility of this escape
code. Similarly if values for known keys are unknown, the terminal emulator
*should* either ignore the entire escape code or perform a best guess effort
to display it based on what it does understand.
.. note::
It is possible to extend this escape code to allow specifying an icon for
the notification, however, given that some platforms, such as macOS, dont
allow displaying custom icons on a notification, at all, it was decided to
leave it out of the spec for the time being.
Similarly, features such as scheduled notifications could be added in future
revisions.
======= ==================== ========= =================
Key Value Default Description
======= ==================== ========= =================
``a`` Comma separated list ``focus`` What action to perform when the
of ``report``, notification is clicked
``focus``, with
optional leading
``-``
``d`` ``0`` or ``1`` ``1`` Indicates if the notification is
complete or not.
``e`` ``0`` or ``1`` ``0`` If set to ``1`` means the payload is base64 encoded UTF-8,
otherwise it is plain UTF-8 text with no C0 control codes in it
``i`` ``[a-zA-Z0-9-_+.]`` ``0`` Identifier for the notification
``p`` One of ``title`` or ``title`` Whether the payload is the notification title or body. If a
``body``. notification has no title, the body will be used as title.
======= ==================== ========= =================
.. note::
|kitty| also supports the legacy OSC 9 protocol developed by iTerm2 for
desktop notifications.

View File

@@ -3,8 +3,6 @@ Frequently Asked Questions
.. highlight:: sh
.. contents::
Some special symbols are rendered small/truncated in kitty?
-----------------------------------------------------------
@@ -35,7 +33,7 @@ it by adding the following to your vimrc::
let &t_ut=''
See :ref:`here <ext_styles>` for why |kitty| does not support background color erase.
See :doc:`here <deccara>` for why |kitty| does not support background color erase.
I get errors about the terminal being unknown or opening the terminal failing when SSHing into a different computer?
@@ -47,12 +45,24 @@ terminfo files to the server::
kitty +kitten ssh myserver
This ssh kitten takes all the same command line arguments
as ssh, you can alias it to ssh in your shell's rc files to avoid having to
type it each time::
alias ssh="kitty +kitten ssh"
If for some reason that does not work (typically because the server is using a
non POSIX compliant shell), you can use the following one-liner instead (it
non POSIX compliant shell as ``/bin/sh``), you can try using it with ``python``
instead::
kitty +kitten ssh use-python myserver
If that also fails, perhaps because python is not installed on the remote
server, use the following one-liner instead (it
is slower as it needs to ssh into the server twice, but will work with most
servers)::
infocmp xterm-kitty | ssh myserver tic -x -o \~/.terminfo /dev/stdin
infocmp -a xterm-kitty | ssh myserver tic -x -o \~/.terminfo /dev/stdin
If you are behind a proxy (like Balabit) that prevents this, you must redirect the
1st command to a file, copy that to the server and run ``tic`` manually. If you
@@ -108,7 +118,7 @@ How do I change the colors in a running kitty instance?
------------------------------------------------------------
You can either use the
`OSC terminal escape codes <https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Operating-System-Commands>`_
`OSC terminal escape codes <https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Operating-System-Commands>`_
to set colors or you can define keyboard shortcuts to set colors, for example::
map f1 set_colors --configured /path/to/some/config/file/colors.conf
@@ -158,6 +168,19 @@ You can, of course, also run |kitty| from a terminal with command line options,
And within |kitty| itself, you can always run |kitty| using just `kitty` as it
cleverly adds itself to the ``PATH``.
I catted a binary file and now kitty is hung?
-----------------------------------------------
**Never** output unknown binary data directly into a terminal.
Terminals have a single channel for both data and control. Certain bytes
are control codes. Some of these control codes are of arbitrary length, so
if the binary data you output into the terminal happens to contain the starting
sequence for one of these control codes, the terminal will hang waiting for
the closing sequence. Press :kbd:`ctrl+shift+delete` to reset the terminal.
If you do want to cat unknown data, use ``cat -v``.
kitty is not able to use my favorite font?
---------------------------------------------
@@ -165,9 +188,12 @@ kitty is not able to use my favorite font?
|kitty| achieves its stellar performance by caching alpha masks of each rendered
character on the GPU, so that every character needs to be rendered only once.
This means it is a strictly character cell based display. As such it can use
only monospace fonts, since every cell in the grid has to be the same size. If
your font is not listed in ``kitty list-fonts`` it means that it is not
monospace. On Linux you can list all monospace fonts with::
only monospace fonts, since every cell in the grid has to be the same size.
Furthermore, it needs fonts to be freely resizable, so it does not support
bitmapped fonts.
If your font is not listed in ``kitty list-fonts`` it means that it is not
monospace or is a bitmapped font. On Linux you can list all monospace fonts with::
fc-list : family spacing outline scalable | grep -e spacing=100 -e spacing=90 | grep -e outline=True | grep -e scalable=True
@@ -179,7 +205,7 @@ following :file:`~/.config/fontconfig/fonts.conf`::
<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<fontconfig>
<match target="font">
<match target="scan">
<test name="family">
<string>Your Font Family Name</string>
</test>
@@ -212,26 +238,53 @@ How do I map key presses in kitty to different keys in the terminal program?
This is accomplished by using ``map`` with :sc:`send_text <send_text>` in :file:`kitty.conf`.
For example::
map alt+s send_text all \x13
map alt+s send_text normal,application \x13
This maps :kbd:`alt+s` to :kbd:`ctrl+s`. To figure out what bytes to use for
the :sc:`send_text <send_text>` you can use the ``showkey`` utility. Run::
the :sc:`send_text <send_text>` you can use the ``show_key`` kitten. Run::
showkey -a
kitty +kitten show_key
Then press the key you want to emulate. On macOS, this utility is currently not
available. The manual way to figure it out is:
Then press the key you want to emulate.
1. Look up your key's decimal value in the table at the bottom of `this
page <http://ascii-table.com/ansi-escape-sequences.php>`_ or any
ANSI escape sequence table. There are different modifiers for :kbd:`ctrl`,
:kbd:`alt`, etc. For e.g., for :kbd:`ctrl+s`, find the ``S`` row and look at
the third column value, ``19``.
How do I open a new window or tab with the same working directory as the current window?
--------------------------------------------------------------------------------------------
2. Convert the decimal value to hex with ``kitty +runpy "print(hex(19))"``.
This shows the hex value, ``13`` in this case.
In :file:`kitty.conf` add the following::
3. Use ``\x(hexval)`` in your ``send_text`` command in kitty. So in this example, ``\x13``
map f1 launch --cwd=current
map f2 launch --cwd=current --type=tab
Pressing :kbd:`F1` will open a new kitty window with the same working directory
as the current window. The :doc:`launch command <launch>` is very powerful,
explore :doc:`its documentation <launch>`.
Things behave differently when running kitty from system launcher vs. from another terminal?
-----------------------------------------------------------------------------------------------
This will be because of environment variables. When you run kitty from the
system launcher, it gets a default set of system environment variables. When
you run kitty from another terminal, you are actually running it from a shell,
and the shell's rc files will have setup a whole different set of environment
variables which kitty will now inherit.
You need to make sure that the environment variables you define in your shell's
rc files are either also defined system wide or via the :opt:`env` directive in
:file:`kitty.conf`. Common environment variables that cause issues are those
related to localization, such as ``LANG, LC_*`` and loading of configuration
files such as ``XDG_*, KITTY_CONFIG_DIRECTORY``.
To see the environment variables that kitty sees, you can add the following
mapping to :file:`kitty.conf`::
map f1 show_kitty_env_vars
then pressing :kbd:`F1` will show you the environment variables kitty sees.
This problem is most common on macOS, as Apple makes it exceedingly difficult to
setup environment variables system-wide, so people end up putting them in all
sorts of places where they may or may not work.
I am using tmux and have a problem
@@ -251,11 +304,44 @@ terminal and then switch to another and these terminals have different TERM
variables, tmux will break. You will need to restart it as tmux does not
support multiple terminfo definitions.
Copying to clipboard via OSC 52 will not work, because tmux does not support
the extended version of that protocol, you will need to add ``no-append`` to
:opt:`clipboard_control` in kitty.conf.
If you use any of the advanced features that kitty has innovated, such as
styled underlines, desktop notifications, extended keyboard support, etc.
they may or may not work, depending on the whims of tmux's maintainer, your
version of tmux, etc.
I opened and closed a lot of windows/tabs and top shows kitty's memory usage is very high?
-------------------------------------------------------------------------------------------
``top`` is not a good way to measure process memory usage. That is because on
modern systems, when allocating memory to a process, the C library functions
will typically allocate memory in large blocks, and give the process chunks of
these blocks. When the process frees a chunk, the C library will not
necessarily release the underlying block back to the OS. So even though the
application has released the memory, ``top`` will still claim the process is
using it.
To check for memory leaks, instead use a tool like ``valgrind``. Run::
PYTHONMALLOC=malloc valgrind --tool=massif kitty
Now open lots of tabs/windows, generate lots of output using tools like find/yes
etc. Then close all but one window. Do some random work for a few seconds in
that window, maybe run yes or find again. Then quit kitty and run::
massif-visualizer massif.out.*
You will see the allocations graph goes up when you opened the windows, then
goes back down when you closed them, indicating there were no memory leaks.
For those interested, you can get a similar profile out of ``valgrind`` as you get
with ``top`` by adding ``--pages-as-heap=yes`` then you will see that memory
allocated in malloc is not freed in free. This can be further refined if you
use `glibc`` as your C library by setting the environment variable
``MALLOC_MMAP_THRESHOLD_=64``. This will cause free to actually free memory
allocated in sizes of more than 64 bytes. With this set, memory usage will
climb high, then fall when closing windows, but not fall all the way back. The
remaining used memory can be investigated using valgrind again, and it will
come from arenas in the GPU drivers and the per thread arenas glibc's malloc
maintains. These too allocate memory in large blocks and dont release it back
to the OS immediately.

122
docs/glossary.rst Normal file
View File

@@ -0,0 +1,122 @@
:orphan:
Glossary
=========
.. glossary::
os_window
kitty has two kinds of windows. Operating System windows, refered to as :term:`OS
Window <os_window>`, and *kitty windows*. An OS Window consists of one or more kitty
:term:`tabs <tab>`. Each tab in turn consists of one or more *kitty
windows* organized in a :term:`layout`.
tab
A *tab* refers to a group of :term:`kitty windows <window>`, organized in
a :term:`layout`. Every :term:`OS Window <os_window>` contains one or more tabs.
layout
A *layout* is a system of organizing :term:`kitty windows <window>` in
groups inside a tab. The layout automatically maintains the size and
position of the windows, think of a layout as a tiling window manager for
the terminal. See :doc:`layouts` for details.
window
kitty has two kinds of windows. Operating System windows, refered to as :term:`OS
Window <os_window>`, and *kitty windows*. An OS Window consists of one or more kitty
:term:`tabs <tab>`. Each tab in turn consists of one or more *kitty
windows* organized in a :term:`layout`.
overlay
An *overlay window* is a :term:`kitty window <window>` that is placed on
top of an existing kitty window, entirely covering it. Overlays are used
throught kitty, for example, to display the :ref:`the scrollback buffer <scrollback>`,
to display :doc:`hints </kittens/hints>`, for :doc:`unicode input
</kittens/unicode-input>` etc.
hyperlinks
Terminals can have hyperlinks, just like the internet. In kitty you can
:doc:`control exactly what happens <open_actions>` when clicking on a
hyperlink, based on the type of link and its URL.
.. _env_vars:
Environment variables
------------------------
Variables that influence kitty behavior
.. envvar:: KITTY_CONFIG_DIRECTORY
Controls where kitty looks for :file:`kitty.conf` and other configuration
files. Defaults to :file:`~/.config/kitty`. For full details of the config
directory lookup mechanism see, :option:`kitty --config`.
.. envvar:: VISUAL
The terminal editor (such as ``vi`` or ``nano``) kitty uses, when, for
instance, opening :file:`kitty.conf` in response to :sc:`edit_config_file`.
.. envvar:: EDITOR
Same as :envvar:`VISUAL`. Used if :envvar:`VISUAL` is not set.
Variables that kitty sets when running child programs
.. envvar:: KITTY_WINDOW_ID
An integer that is the id for the kitty :term:`window` the program is running in.
Can be used with the :doc:`kitty remote control facility <remote-control>`.
.. envvar:: WINDOWID
The id for the :term:`OS Window <os_window>` the program is running in. Only available
on platforms that have ids for their windows, such as X11 and macOS.
.. envvar:: TERM
The name of the terminal, defaults to ``xterm-kitty``. See :opt:`term`.
.. envvar:: TERMINFO
Path to a directory containing the kitty terminfo database.
.. envvar:: COLORTERM
Set to the value ``truecolor`` to indicate that kitty supports 16 million
colors.
.. envvar:: KITTY_LISTEN_ON
Set when the :doc:`remote control <remote-control>` facility is enabled and
the a socket is used for control via :option:`kitty --listen-on` or :opt:`listen_on`.
Contains the path to the socket. Avoids needs to use :option:`kitty @ --to` when
issuing remote control commands.
.. envvar:: KITTY_PIPE_DATA
Set to data describing the layout of the screen when running child
programs using :option:`launch --stdin-source` with the contents of the
screen/scrollback piped to them.
.. envvar:: KITTY_CHILD_CMDLINE
Set to the command line of the child process running in the kitty
window when calling the notification callback program on terminal bell, see
:opt:`command_on_bell`.
.. envvar:: KITTY_COMMON_OPTS
Set with the values of some common kitty options when running
kittens, so kittens can use them without needing to load kitty.conf.

View File

@@ -1,18 +1,16 @@
:tocdepth: 3
The terminal graphics protocol
==================================
Terminal graphics protocol
=================================
The goal of this specification is to create a flexible and performant protocol
that allows the program running in the terminal, hereafter called the *client*,
to render arbitrary pixel (raster) graphics to the screen of the terminal
emulator. The major design goals are
emulator. The major design goals are:
* Should not require terminal emulators to understand image formats.
* Should allow specifying graphics to be drawn at individual pixel positions.
* The graphics should integrate with the text, in particular it should be possible to draw graphics
below as well as above the text, with alpha blending. The graphics should also scroll with the text, automatically.
* Should use optimizations when the client is running on the same computer as the terminal emulator.
* Should not require terminal emulators to understand image formats.
* Should allow specifying graphics to be drawn at individual pixel positions.
* The graphics should integrate with the text, in particular it should be possible to draw graphics
below as well as above the text, with alpha blending. The graphics should also scroll with the text, automatically.
* Should use optimizations when the client is running on the same computer as the terminal emulator.
For some discussion regarding the design choices, see `#33
<https://github.com/kovidgoyal/kitty/issues/33>`_.
@@ -28,18 +26,21 @@ alpha-blending and text over graphics.
:alt: Demo of graphics rendering in kitty
:align: center
Some programs that use the kitty graphics protocol:
Some programs and libraries that use the kitty graphics protocol:
* `termpdf.py <https://github.com/dsanson/termpdf.py>`_ - a terminal PDF/DJVU/CBR viewer
* `ranger <https://github.com/ranger/ranger>`_ - a terminal file manager, with
image previews, see this `PR <https://github.com/ranger/ranger/pull/1077>`_
* :doc:`kitty-diff <kittens/diff>` - a side-by-side terminal diff program with support for images
* `pixcat <https://github.com/mirukana/pixcat>`_ - a third party CLI and python library that wraps the graphics protocol
* `neofetch <https://github.com/dylanaraps/neofetch>`_ - A command line system
information tool
.. contents::
* `termpdf.py <https://github.com/dsanson/termpdf.py>`_ - a terminal PDF/DJVU/CBR viewer
* `ranger <https://github.com/ranger/ranger>`_ - a terminal file manager, with
image previews, see this `PR <https://github.com/ranger/ranger/pull/1077>`_
* :doc:`kitty-diff <kittens/diff>` - a side-by-side terminal diff program with support for images
* `pixcat <https://github.com/mirukana/pixcat>`_ - a third party CLI and python library that wraps the graphics protocol
* `neofetch <https://github.com/dylanaraps/neofetch>`_ - A command line system
information tool
* `viu <https://github.com/atanunq/viu>`_ - a terminal image viewer
* `glkitty <https://github.com/michaeljclark/glkitty>`_ - C library to draw OpenGL shaders in the terminal with a glgears demo
* `ctx.graphics <https://ctx.graphics/>`_ - Library for drawing graphics
* `timg <https://github.com/hzeller/timg>`_ - a terminal image and video viewer
* `notcurses <https://github.com/dankamongmen/notcurses>`_ - C library for terminal graphics with bindings for C++, Rust and Python
* `rasterm <https://github.com/BourgeoisBear/rasterm>`_ - Go library to display images in the the terminal
Getting the window size
@@ -50,28 +51,33 @@ client must be able to get the window size in pixels and the number of cells
per row and column. This can be done by using the ``TIOCGWINSZ`` ioctl. Some
code to demonstrate its use
In C:
.. tab:: C
.. code-block:: c
.. code-block:: c
#include <stdio.h>
#include <sys/ioctl.h>
#include <stdio.h>
#include <sys/ioctl.h>
int main(int argc, char **argv) {
struct winsize sz;
ioctl(0, TIOCGWINSZ, &sz);
printf("number of rows: %i, number of columns: %i, screen width: %i, screen height: %i\n", sz.ws_row, sz.ws_col, sz.ws_xpixel, sz.ws_ypixel);
return 0;
}
int main(int argc, char **argv) {
struct winsize sz;
ioctl(0, TIOCGWINSZ, &sz);
printf(
"number of rows: %i, number of columns: %i, screen width: %i, screen height: %i\n",
sz.ws_row, sz.ws_col, sz.ws_xpixel, sz.ws_ypixel);
return 0;
}
In Python:
.. code-block:: python
.. tab:: Python
import array, fcntl, sys, termios
buf = array.array('H', [0, 0, 0, 0])
fcntl.ioctl(sys.stdout, termios.TIOCGWINSZ, buf)
print('number of rows: {}, number of columns: {}, screen width: {}, screen height: {}'.format(*buf))
.. code-block:: python
import array, fcntl, sys, termios
buf = array.array('H', [0, 0, 0, 0])
fcntl.ioctl(sys.stdout, termios.TIOCGWINSZ, buf)
print((
'number of rows: {} number of columns: {}'
'screen width: {} screen height: {}').format(*buf))
Note that some terminals return ``0`` for the width and height values. Such
terminals should be modified to return the correct values. Examples of
@@ -91,32 +97,36 @@ features of the graphics protocol:
.. code-block:: python
import sys
from base64 import standard_b64encode
import sys
from base64 import standard_b64encode
def serialize_gr_command(cmd, payload=None):
cmd = ','.join('{}={}'.format(k, v) for k, v in cmd.items())
ans = []
w = ans.append
w(b'\033_G'), w(cmd.encode('ascii'))
if payload:
w(b';')
w(payload)
w(b'\033\\')
return b''.join(ans)
def write_chunked(cmd, data):
data = standard_b64encode(data)
while data:
chunk, data = data[:4096], data[4096:]
m = 1 if data else 0
cmd['m'] = m
sys.stdout.buffer.write(serialize_gr_command(cmd, chunk))
sys.stdout.flush()
cmd.clear()
def serialize_gr_command(**cmd):
payload = cmd.pop('payload', None)
cmd = ','.join('{}={}'.format(k, v) for k, v in cmd.items())
ans = []
w = ans.append
w(b'\033_G'), w(cmd.encode('ascii'))
if payload:
w(b';')
w(payload)
w(b'\033\\')
return b''.join(ans)
with open(sys.argv[-1], 'rb') as f:
write_chunked({'a': 'T', 'f': 100}, f.read())
def write_chunked(**cmd):
data = standard_b64encode(cmd.pop('data'))
while data:
chunk, data = data[:4096], data[4096:]
m = 1 if data else 0
sys.stdout.buffer.write(serialize_gr_command(payload=chunk, m=m,
**cmd))
sys.stdout.flush()
cmd.clear()
with open(sys.argv[-1], 'rb') as f:
write_chunked(a='T', f=100, data=f.read())
Save this script as :file:`png.py`, then you can use it to display any PNG
@@ -142,6 +152,8 @@ The meaning of the payload is interpreted based on the control data.
The first step is to transmit the actual image data.
.. _transferring_pixel_data:
Transferring pixel data
--------------------------
@@ -188,16 +200,17 @@ compression, then you must provide the ``S`` key with the size of the PNG data.
Compression
~~~~~~~~~~~~~
The client can send compressed image data to the terminal emulator, by specifying the
``o`` key. Currently, only zlib based deflate compression is supported, which is specified using
``o=z``. For example::
The client can send compressed image data to the terminal emulator, by
specifying the ``o`` key. Currently, only :rfc:`1950` ZLIB based deflate
compression is supported, which is specified using ``o=z``. For example::
<ESC>_Gf=24,s=10,v=20,o=z;<payload><ESC>\
This is the same as the example from the RGB data section, except that the
payload is now compressed using deflate. The terminal emulator will decompress
it before rendering. You can specify compression for any format. The terminal
emulator will decompress before interpreting the pixel data.
payload is now compressed using deflate (this occurs prior to base64-encoding).
The terminal emulator will decompress it before rendering. You can specify
compression for any format. The terminal emulator will decompress before
interpreting the pixel data.
The transmission medium
@@ -216,8 +229,13 @@ Value of `t` Meaning
is in a known temporary directory, such as :file:`/tmp`,
:file:`/dev/shm`, :file:`TMPDIR env var if present` and any platform
specific temporary directories.
``s`` A `POSIX shared memory object <http://man7.org/linux/man-pages/man7/shm_overview.7.html>`_.
The terminal emulator will delete it after reading the pixel data
``s`` A *shared memory object*, which on POSIX systems is a
`POSIX shared memory object <https://pubs.opengroup.org/onlinepubs/9699919799/functions/shm_open.html>`_
and on Windows is a
`Named shared memory object <https://docs.microsoft.com/en-us/windows/win32/memory/creating-named-shared-memory>`_.
The terminal emulator must read the data from the memory
object and then unlink and close it on POSIX and just
close it on Windows.
================== ============
Local client
@@ -263,7 +281,7 @@ sequence of escape codes to the terminal emulator::
<ESC>_Gm=0;<encoded pixel data last chunk><ESC>\
Note that only the first escape code needs to have the full set of control
codes such as width, height, format etc. Subsequent chunks must have
codes such as width, height, format etc. Subsequent chunks **must** have
only the ``m`` key. The client **must** finish sending all chunks for a single image
before sending any other graphics related escape codes. Note that the cursor
position used to display the image **must** be the position when the final chunk is
@@ -302,7 +320,7 @@ While as of May 2020, kitty is the only terminal emulator to support this
graphics protocol, we intend that any terminal emulator that wishes to support
it can. To check if a terminal emulator supports the graphics protocol the best way
is to send the above *query action* followed by a request for the
`primary device attributes <https://vt100.net/docs/vt510-rm/DA1.html>`. If you
`primary device attributes <https://vt100.net/docs/vt510-rm/DA1.html>`_. If you
get back an answer for the device attributes without getting back an answer for
the *query action* the terminal emulator does not support the graphics
protocol.
@@ -313,7 +331,7 @@ terminal emulators handle input in a FIFO manner, anyway.
So for example, you could send::
<ESC>_Gi=31,s=1,v=1,a=q,t=d,f=24;<NUL><NUL><NUL><ESC>\<ESC>[c
<ESC>_Gi=31,s=1,v=1,a=q,t=d,f=24;AAAA<ESC>\<ESC>[c
If you get back a response to the graphics query, the terminal emulator supports
the protocol, if you get back a response to the device attributes query without
@@ -325,11 +343,12 @@ Display images on screen
Every transmitted image can be displayed an arbitrary number of times on the
screen, in different locations, using different parts of the source image, as
needed. You can either simultaneously transmit and display an image using the
action ``a=T``, or first transmit the image with a id, such as ``i=10`` and then display
it with ``a=p,i=10`` which will display the previously transmitted image at the current
cursor position. When specifying an image id, the terminal emulator will reply with an
acknowledgement code, which will be either::
needed. Each such display of an image is called a *placement*. You can either
simultaneously transmit and display an image using the action ``a=T``, or first
transmit the image with a id, such as ``i=10`` and then display it with
``a=p,i=10`` which will display the previously transmitted image at the current
cursor position. When specifying an image id, the terminal emulator will reply
to the placement request with an acknowledgement code, which will be either::
<ESC>_Gi=<id>;OK<ESC>\
@@ -342,6 +361,24 @@ scheme described above for querying available transmission media, except that
here we are querying if the image with the specified id is available or needs to
be re-transmitted.
Since there can be many placements per image, you can also give placements an
id. To do so add the ``p`` key with a number between ``1`` and ``4294967295``.
When you specify a placement id, it will be added to the acknowledgement code
above. Every placement is uniquely identified by the pair of the ``image id``
and the ``placement id``. If you specify a placement id for an image that does
not have an id, it will be ignored. An example response::
<ESC>_Gi=<image id>,p=<placement id>;OK<ESC>\
If you send two placements with the same ``image id`` and ``placement id`` the
second one will replace the first. This can be used to resize or move
placements around the screen, without flicker.
.. versionadded:: 0.19.3
Support for specifying placement ids (see :doc:`kittens/query_terminal` to query kitty version)
Controlling displayed image layout
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -368,6 +405,19 @@ allows rendering of text on top of images. Negative z-index values below
INT32_MIN/2 (-1,073,741,824) will be drawn under cells with non-default background
colors.
.. note:: After placing an image on the screen the cursor must be moved to the
right by the number of cols in the image placement rectangle and down by the
number of rows in the image placement rectangle. If either of these cause
the cursor to leave either the screen or the scroll area, the exact
positioning of the cursor is undefined, and up to implementations.
The client can ask the terminal emulator to not move the cursor at all
by specifying ``C=1`` in the command, which sets the cursor movement policy
to no movement for placing the current image.
.. versionadded:: 0.20.0
Support for the C=1 cursor movement policy
Deleting images
---------------------
@@ -384,33 +434,257 @@ scrollback buffer. The values of the ``x`` and ``y`` keys are the same as cursor
================= ============
Value of ``d`` Meaning
================= ============
``a`` or ``A`` Delete all images visible on screen
``i`` or ``I`` Delete all images with the specified id, specified using the ``i`` key.
``c`` or ``C`` Delete all images that intersect with the current cursor position.
``p`` or ``P`` Delete all images that intersect a specific cell, the cell is specified using the ``x`` and ``y`` keys
``q`` or ``Q`` Delete all images that intersect a specific cell having a specific z-index. The cell and z-index is specified using the ``x``, ``y`` and ``z`` keys.
``x`` or ``X`` Delete all images that intersect the specified column, specified using the ``x`` key.
``y`` or ``Y`` Delete all images that intersect the specified row, specified using the ``y`` key.
``z`` or ``Z`` Delete all images that have the specified z-index, specified using the ``z`` key.
``a`` or ``A`` Delete all placements visible on screen
``i`` or ``I`` Delete all images with the specified id, specified using the ``i`` key. If you specify a ``p`` key for the placement id as well, then only the placement with the specified image id and placement id will be deleted.
``n`` or ``N`` Delete newest image with the specified number, specified using the ``I`` key. If you specify a ``p`` key for the
placement id as well, then only the placement with the specified number and placement id will be deleted.
``c`` or ``C`` Delete all placements that intersect with the current cursor position.
``f`` or ``F`` Delete animation frames.
``p`` or ``P`` Delete all placements that intersect a specific cell, the cell is specified using the ``x`` and ``y`` keys
``q`` or ``Q`` Delete all placements that intersect a specific cell having a specific z-index. The cell and z-index is specified using the ``x``, ``y`` and ``z`` keys.
``x`` or ``X`` Delete all placements that intersect the specified column, specified using the ``x`` key.
``y`` or ``Y`` Delete all placements that intersect the specified row, specified using the ``y`` key.
``z`` or ``Z`` Delete all placements that have the specified z-index, specified using the ``z`` key.
================= ============
Note when all placements for an image have been deleted, the image is also
deleted, if the capital letter form above is specified. Also, when the terminal
is running out of quota space for new images, existing images without
placements will be preferentially deleted.
Some examples::
<ESC>_Ga=d<ESC>\ # delete all visible images
<ESC>_Ga=d,d=i,i=10<ESC>\ # delete the image with id=10, without freeing data
<ESC>_Ga=d,d=Z,z=-1<ESC>\ # delete the images with z-index -1, also freeing up image data
<ESC>_Ga=d,d=p,x=3,y=4<ESC>\ # delete all images that intersect the cell at (3, 4), without freeing data
<ESC>_Ga=d<ESC>\ # delete all visible placements
<ESC>_Ga=d,d=i,i=10<ESC>\ # delete the image with id=10, without freeing data
<ESC>_Ga=d,d=i,i=10,p=7<ESC>\ # delete the image with id=10 and placement id=7, without freeing data
<ESC>_Ga=d,d=Z,z=-1<ESC>\ # delete the placements with z-index -1, also freeing up image data
<ESC>_Ga=d,d=p,x=3,y=4<ESC>\ # delete all placements that intersect the cell at (3, 4), without freeing data
Suppressing responses from the terminal
-------------------------------------------
If you are using the graphics protocol from a limited client, such as a shell
script, it might be useful to avoid having to process responses from the
terminal. For this, you can use the ``q`` key. Set it to ``1`` to suppress
``OK`` responses and to ``2`` to suppress failure responses.
.. versionadded:: 0.19.3
The ability to suppress responses (see :doc:`kittens/query_terminal` to query kitty version)
Requesting image ids from the terminal
-------------------------------------------
If you are writing a program that is going to share the screen with other
programs and you still want to use image ids, it is not possible to know
what image ids are free to use. In this case, instead of using the ``i``
key to specify an image id use the ``I`` key to specify an image number
instead. These numbers are not unique.
When creating a new image, even if an existing image has the same number a new
one is created. And the terminal will reply with the id of the newly created
image. For example, when creating an image with ``I=13``, the terminal will
send the response::
<ESC>_Gi=99,I=13;OK<ESC>\
Here, the value of ``i`` is the id for the newly created image and the value of
``I`` is the same as was sent in the creation command.
All future commands that refer to images using the image number, such as
creating placements or deleting images, will act on only the newest image with
that number. This allows the client program to send a bunch of commands dealing
with an image by image number without waiting for a response from the terminal
with the image id. Once such a response is received, the client program should
use the ``i`` key with the image id for all future communication.
.. note:: Specifying both ``i`` and ``I`` keys in any command is an error. The
terminal must reply with an EINVAL error message, unless silenced.
.. versionadded:: 0.19.3
The ability to use image numbers (see :doc:`kittens/query_terminal` to query kitty version)
.. _animation_protocol:
Animation
-------------------------------------------
.. versionadded:: 0.20.0
Animation support (see :doc:`kittens/query_terminal` to query kitty version)
When designing support for animation, the two main considerations were:
#. There should be a way for both client and terminal driven animations.
Since there is unknown and variable latency between client and terminal,
especially over SSH, client driven animations are not sufficient.
#. Animations often consist of small changes from one frame to the next, the
protocol should thus allow transmitting these deltas for efficiency and
performance reasons.
Animation support is added to the protocol by adding two new modes for the
``a`` (action) key. A ``f`` mode for transmitting frame data and an ``a`` mode
for controlling the animation of an image. Animation proceeds in two steps,
first a normal image is created as described earlier. Then animation frames are
added to the image to make it into an animation. Since every animation is
associated with a single image, all animation escape codes must specify either
the ``i`` or ``I`` keys to identify the image being operated on.
Transferring animation frame data
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Transferring animation frame data is very similar to
:ref:`transferring_pixel_data` above. The main difference is that the image
the frame belongs to must be specified and it is possible to transmit data for
only part of a frame, declaring the rest of the frame to be filled in by data
from a previous frame, or left blank. To transfer frame data the ``a=f``
key must be used in all escape codes.
First, to transfer a simple frame that has data for the full image area, the
escape codes used are exactly the same as for transferring image data, with the
addition of: ``a=f,i=<image id>`` or ``a=f,I=<image number>``.
If the frame has data for only a part of the image, you can specify the
rectangle for it using the ``x, y, s, v`` keys, for example::
x=10,y=5,s=100,v=200 # A 100x200 rectangle with its top left corner at (10, 5)
Frames are created by composing the transmitted data onto a background canvas.
This canvas can be either a single color, or the pixels from a previous frame.
The composition can be of two types, either a simple replacement (``X=1``) key
or a full alpha blend (the default).
To use a background color for the canvas, specify the ``Y`` key as a 32-bit
RGBA color. For example::
Y=4278190335 # 0xff0000ff opaque red
Y=16711816 # 0x00ff0088 translucent green (alpha=0.53)
The default background color when none is specified is ``0`` i.e. a black,
transparent pixel.
To use the data from a previous frame, specify the ``c`` key which is a 1-based
frame number. Thus ``c=1`` refers to the root frame (the base image data),
``c=2`` refers to the second frame and so on.
If the frame is composed of multiple rectangular blocks, these can be expressed
by using the ``r`` key. When specifying the ``r`` key the data for an existing
frame is edited. The same composition operation as above happens, but now the
background canvas is the existing frame itself. ``r`` is a 1-based index, so
``r=1`` is the root frame (base image data), ``r=2`` is the second frame and so
on.
Finally, while transferring frame data, the frame *gap* can also be specified
using the ``z`` key. The gap is the number of milliseconds to wait before
displaying the next frame when the animation is running. A value of ``z=0`` is
ignored, ``z=positive number`` sets the gap to the specified number of
milliseconds and ``z=negative number`` creates a *gapless* frame. Gapless
frames are not displayed to the user since they are instantly skipped over,
however they can be useful as the base data for subsequent frames. For example,
for an animation where the background remains the same and a small object or two
move.
Controlling animations
~~~~~~~~~~~~~~~~~~~~~~~~~~
Clients can control animations by using the ``a=a`` key in the escape code sent
to the terminal.
The simplest is client driven animations, where the client transmits the frame
data and then also instructs the terminal to make a particular frame the current
frame. To change the current frame, use the ``c`` key::
<ESC>_Ga=a,i=3,c=7<ESC>\
This will make the seventh frame in the image with id ``3`` the current frame.
However, client driven animations can be sub-optimal, since the latency between
the client and terminal is unknown and variable especially over the network.
Also they require the client to remain running for the lifetime of the
animation, which is not desirable for cat like utilities.
Terminal driven animations are achieved by the client specifying *gaps* (time
in milliseconds) between frames and instructing the terminal to stop or start
the animation.
The animation state is controlled by the ``s`` key. ``s=1`` stops the
animation. ``s=2`` runs the animation, but in *loading* mode, in this mode when
reaching the last frame, instead of looping, the terminal will wait for the
arrival of more frames. ``s=3`` runs the animation normally, after the last
frame, the terminal loops back to the first frame. The number of loops can be
controlled by the ``v`` key. ``v=0`` is ignored, ``v=1`` is loop infinitely,
and any other positive number is loop ``number - 1`` times. Note that stopping
the animation resets the loop counter.
Finally, the *gap* for frames can be set using the ``z`` key. This can be
specified either when the frame is created as part of the transmit escape code
or separately using the animation control escape code. The *gap* is the time in
milliseconds to wait before displaying the next frame in the animation.
For example::
<ESC>_Ga=a,i=7,r=3,z=48<ESC>\
This sets the gap for the third frame of the image with id ``7`` to ``48``
milliseconds. Note that *gapless* frames are not displayed to the user since
the next frame comes immediately, however they can be useful to store base data
for subsequent frames, such as in an animation with an object moving against a
static background.
In particular, the first frame or *root frame* is created with the base image
data and has no gap, so its gap must be set using this control code.
Composing animation frames
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. versionadded:: 0.22.0
Support for frame composition
Clients can *compose* animation frames, this means that they can compose pixels
in rectangular regions from one frame onto another frame. This allows for fast
and low band-width modification of frames.
To achieve this use the ``a=c`` key. The source frame is specified with
``r=frame number`` and the destination frame as ``c=frame number``. The size of
the rectangle is specified as ``w=width,h=height`` pixels. If unspecified, the
full image width and height are used. The offset of the rectangle from the
top-left corner for the source frame is specified by the ``x,y`` keys and the
destination frame by the ``X,Y`` keys. The composition operation is specified
by the ``C`` key with the default being to alpha blend the source rectangle
onto the destination rectangle. With ``C=1`` it will be a simple replacement
of pixels. For example::
<ESC>_Gi=1,r=7,c=9,w=23,h=27,X=4,Y=8,x=1,y=3<ESC>\
Will compose a ``23x27`` rectangle located at ``(4, 8)`` in the ``7th frame``
onto the rectangle located at ``(1, 3)`` in the ``9th frame``. These will be
in the image with ``id=1``.
If the frames or the image are not found the terminal emulator must
respond with `ENOENT`. If the rectangles go out of bounds of the image
the terminal must respond with `EINVAL`. If the source and destination frames are
the same and the rectangles overlap, the terminal must respond with `EINVAL`.
.. note::
In kitty, doing a composition will cause a frame to be *fully rendered*
potentially increasing its storage requirements, when the frame was previously
stored as a set of operations on other frames. If this happens and there
is not enough storage space, kitty will respond with ENOSPC.
Image persistence and storage quotas
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-----------------------------------------
In order to avoid *Denial-of-Service* attacks, terminal emulators should have a
maximum storage quota for image data. It should allow at least a few full
screen images. For example the quota in kitty is 320MB per buffer. When adding
a new image, if the total size exceeds the quota, the terminal emulator should
delete older images to make space for the new one.
delete older images to make space for the new one. In kitty, for animations,
the additional frame data is stored on disk and has a separate, larger quota of
five times the base quota.
Control data reference
@@ -423,7 +697,13 @@ take, and the default value they take when missing. All integers are 32-bit.
Key Value Default Description
======= ==================== ========= =================
``a`` Single character. ``t`` The overall action this graphics command is performing.
``(t, T, q, p, d)``
``(a, c, d, f, `` ``t`` - transmit data, ``T`` - transmit data and display image,
``p, q, t, T)`` ``q`` - query terminal, ``p`` - put (display) previous transmitted image,
``d`` - delete image, ``f`` - transmit data for animation frames,
``a`` - control animation, ``c`` - compose animation frames
``q`` ``0, 1, 2`` ``0`` Suppress responses from the terminal to this graphics command.
**Keys for image transmission**
-----------------------------------------------------------
``f`` Positive integer. ``32`` The format in which the image data is sent.
@@ -436,26 +716,77 @@ Key Value Default Description
``O`` Positive integer. ``0`` The offset from which to read data from a file.
``i`` Positive integer.
``(0 - 4294967295)`` ``0`` The image id
``I`` Positive integer.
``(0 - 4294967295)`` ``0`` The image number
``p`` Positive integer.
``(0 - 4294967295)`` ``0`` The placement id
``o`` Single character. ``null`` The type of data compression.
``only z``
``m`` zero or one ``0`` Whether there is more chunked data available.
**Keys for image display**
-----------------------------------------------------------
``x`` Positive integer ``0`` The left edge (in pixels) of the image area to display
``y`` Positive integer ``0`` The top edge (in pixels) of the image area to display
``w`` Positive integer ``0`` The width (in pixels) of the image area to display. By default, the entire width is used.
``w`` Positive integer ``0`` The width (in pixels) of the image area to display. By default, the entire width is used
``h`` Positive integer ``0`` The height (in pixels) of the image area to display. By default, the entire height is used
``X`` Positive integer ``0`` The x-offset within the first cell at which to start displaying the image
``Y`` Positive integer ``0`` The y-offset within the first cell at which to start displaying the image
``c`` Positive integer ``0`` The number of columns to display the image over
``r`` Positive integer ``0`` The number of rows to display the image over
``C`` Positive integer ``0`` Cursor movement policy. ``0`` is the default, to move the cursor to after the image.
``1`` is to not move the cursor at all when placing the image.
``z`` 32-bit integer ``0`` The *z-index* vertical stacking order of the image
**Keys for animation frame loading**
-----------------------------------------------------------
``x`` Positive integer ``0`` The left edge (in pixels) of where the frame data should be updated
``y`` Positive integer ``0`` The top edge (in pixels) of where the frame data should be updated
``c`` Positive integer ``0`` The 1-based frame number of the frame whose image data serves as the base data
when creating a new frame, by default the base data is black, fully transparent pixels
``r`` Positive integer ``0`` The 1-based frame number of the frame that is being edited. By default, a new frame is created
``z`` 32-bit integer ``0`` The gap (in milliseconds) of this frame from the next one. A value of
zero is ignored. Negative values create a *gapless* frame. If not specified,
frames have a default gap of ``40ms``. The root frame defaults to zero gap.
``X`` Positive integer ``0`` The composition mode for blending pixels when creating a new frame or
editing a frame's data. The default is full alpha blending. ``1`` means a
simple overwrite.
``Y`` Positive integer ``0`` The background color for pixels not
specified in the frame data. Must be in 32-bit RGBA format
**Keys for animation frame composition**
-----------------------------------------------------------
``c`` Positive integer ``0`` The 1-based frame number of the frame whose image data serves as the overlaid data
``r`` Positive integer ``0`` The 1-based frame number of the frame that is being edited.
``x`` Positive integer ``0`` The left edge (in pixels) of the destination rectangle
``y`` Positive integer ``0`` The top edge (in pixels) of the destination rectangle
``w`` Positive integer ``0`` The width (in pixels) of the source and destination rectangles. By default, the entire width is used
``h`` Positive integer ``0`` The height (in pixels) of the source and destination rectangles. By default, the entire height is used
``X`` Positive integer ``0`` The left edge (in pixels) of the source rectangle
``Y`` Positive integer ``0`` The top edge (in pixels) of the source rectangle
``C`` Positive integer ``0`` The composition mode for blending
pixels. Default is full alpha blending. ``1`` means a simple overwrite.
**Keys for animation control**
-----------------------------------------------------------
``s`` Positive integer ``0`` ``1`` - stop animation, ``2`` - run animation, but wait for new frames, ``3`` - run animation
``r`` Positive integer ``0`` The 1-based frame number of the frame that is being affected
``z`` 32-bit integer ``0`` The gap (in milliseconds) of this frame from the next one. A value of
zero is ignored. Negative values create a *gapless* frame.
``c`` Positive integer ``0`` The 1-based frame number of the frame that should be made the current frame
``v`` Positive integer ``0`` The number of loops to play. ``0`` is
ignored, ``1`` is play infinite and is the default and larger number
means play that number ``-1`` loops
**Keys for deleting images**
-----------------------------------------------------------
``d`` Single character. ``a`` What to delete.
``(a, A, c, C, i,
I, p, P, q, Q, x, X,
y, Y, z, Z)``.
``(a, A, c, C, n, N,
i, I, p, P, q, Q, x,
X, y, Y, z, Z)``.
======= ==================== ========= =================

View File

@@ -1,526 +1,66 @@
:tocdepth: 2
==========================================================
kitty - the fast, featureful, GPU based terminal emulator
kitty
==========================================================
.. container:: major-features
*The fast, feature-rich, GPU based terminal emulator*
* Offloads rendering to the GPU for :doc:`lower system load <performance>` and
buttery smooth scrolling. Uses threaded rendering to minimize input latency.
.. toctree::
:hidden:
* Supports all modern terminal features: :doc:`graphics (images)
<graphics-protocol>`, unicode, `true-color
<https://gist.github.com/XVilka/8346728>`_,
OpenType ligatures, mouse protocol, :doc:`hyperlinks <open_actions>`,
focus tracking, `bracketed paste <https://cirw.in/blog/bracketed-paste>`_
and several :doc:`new terminal protocol extensions
<protocol-extensions>`.
quickstart
overview
faq
support
performance
changelog
integrations
protocol-extensions
* Supports tiling multiple terminal windows side by side in different
:ref:`layouts <layouts>` without needing to use an extra program like tmux
* Can be :doc:`controlled from scripts or the shell prompt <remote-control>`,
even over SSH.
.. tab:: Fast
* Has a framework for :ref:`kittens`, small terminal programs that can be used to
extend |kitty|'s functionality. For example, they are used for
:doc:`Unicode input <kittens/unicode-input>`, :doc:`Hints <kittens/hints>` and
:doc:`Side-by-side diff <kittens/diff>`.
* Offloads rendering to the GPU for :doc:`lower system load <performance>`
* Uses threaded rendering for absolutely minimal latency
* Performance tradeoffs can be :ref:`tuned <conf-kitty-performance>`
* Supports :ref:`startup sessions <sessions>` which allow you to specify
the window/tab layout, working directories and programs to run on startup.
.. tab:: Capable
* Cross-platform: |kitty| works on Linux and macOS, but because it uses only
OpenGL for rendering, it should be trivial to port to other Unix-like platforms.
* Graphics, with :doc:`images and animations <graphics-protocol>`
* Ligatures and emoji, with :opt:`per glyph font substitution <symbol_map>`
* :term:`Hyperlinks<hyperlinks>`, with :doc:`configurable actions <open_actions>`
* Allows you to open :ref:`the scrollback buffer <scrollback>` in a
separate window using arbitrary programs of your choice. This is useful for
browsing the history comfortably in a pager or editor.
.. tab:: Scriptable
* Has :ref:`multiple copy/paste buffers <cpbuf>`, like vim.
* Control from :doc:`scripts or the shell <remote-control>`
* Extend with :ref:`kittens <kittens>` using the Python language
* Use :ref:`startup sessions <sessions>` to specify working environments
.. tab:: Composable
* Programmble tabs, :ref:`splits <splits_layout>` and multiple :doc:`layouts <layouts>` to manage windows
* Browse the :ref:`entire history <scrollback>` or the output from the last command comfortably in pagers and editors
* Edit or download :doc:`remote files <kittens/remote_file>` in an existing SSH session
.. tab:: Cross-platform
* Linux
* macOS
* Various BSDs
.. tab:: Innovative
Pioneered various extensions to move the entire terminal ecosystem forward
* :doc:`graphics-protocol`
* :doc:`keyboard-protocol`
* Lots more in :doc:`protocol-extensions`
.. figure:: screenshots/screenshot.png
:alt: Screenshot, showing three programs in the 'Tall' layout
:align: center
:scale: 100%
:width: 100%
Screenshot, showing vim, tig and git running in |kitty| with the 'Tall' layout
.. _quickstart:
Quickstart
--------------
Pre-built binaries of |kitty| are available for both macOS and Linux.
See the :doc:`binary install instructions </binary>`. You can
:doc:`build from source </build>`.
You can also use your favorite package manager to install the |kitty| package.
|kitty| packages are available for:
`macOS with Homebrew (Cask) <https://formulae.brew.sh/cask/kitty>`_,
`macOS and Linux with Nix <https://nixos.org/nixos/packages.html?channel=nixpkgs-unstable&query=kitty>`_,
`Ubuntu <https://launchpad.net/ubuntu/+source/kitty>`_,
`Debian <https://packages.debian.org/buster/kitty>`_,
`openSUSE <https://build.opensuse.org/package/show/X11:terminals/kitty>`_,
`Arch Linux <https://www.archlinux.org/packages/community/x86_64/kitty/>`_,
`Gentoo <https://packages.gentoo.org/packages/x11-terms/kitty>`_,
`Fedora <https://src.fedoraproject.org/rpms/kitty>`_,
`Void Linux <https://github.com/void-linux/void-packages/blob/master/srcpkgs/kitty/template>`_,
and `Solus <https://dev.getsol.us/source/kitty/>`_.
See :doc:`Configuring kitty <conf>` for help on configuring |kitty| and
:doc:`Invocation <invocation>` for the command line arguments |kitty| supports.
.. contents::
Design philosophy
-------------------
|kitty| is designed for power keyboard users. To that end all its controls
work with the keyboard (although it fully supports mouse interactions as
well). Its configuration is a simple, human editable, single file for
easy reproducibility (I like to store configuration in source control).
The code in |kitty| is designed to be simple, modular and hackable. It is
written in a mix of C (for performance sensitive parts) and Python (for
easy hackability of the UI). It does not depend on any large and complex
UI toolkit, using only OpenGL for rendering everything.
Finally, |kitty| is designed from the ground up to support all modern
terminal features, such as unicode, true color, bold/italic fonts, text
formatting, etc. It even extends existing text formatting escape codes,
to add support for features not available elsewhere, such as colored and
styled (curly) underlines. One of the design goals of |kitty| is to be
easily extensible so that new features can be added in the future with
relatively little effort.
Tabs and Windows
-------------------
|kitty| is capable of running multiple programs organized into tabs and
windows. The top level of organization is the *Tab*. Each tab consists
of one or more *windows*. The windows can be arranged in multiple
different layouts, like windows are organized in a tiling window
manager. The keyboard controls (which are all customizable) for tabs and
windows are:
Scrolling
~~~~~~~~~~~~~~
======================== =======================
Action Shortcut
======================== =======================
Scroll line up :sc:`scroll_line_up` (also :kbd:`⌥+⌘+⇞` and :kbd:`⌘+↑` on macOS)
Scroll line down :sc:`scroll_line_down` (also :kbd:`⌥+⌘+⇟` and :kbd:`⌘+↓` on macOS)
Scroll page up :sc:`scroll_page_up` (also :kbd:`⌘+⇞` on macOS)
Scroll page down :sc:`scroll_page_down` (also :kbd:`⌘+⇟` on macOS)
Scroll to top :sc:`scroll_home` (also :kbd:`⌘+↖` on macOS)
Scroll to bottom :sc:`scroll_end` (also :kbd:`⌘+↘` on macOS)
======================== =======================
Tabs
~~~~~~~~~~~
======================== =======================
Action Shortcut
======================== =======================
New tab :sc:`new_tab` (also :kbd:`⌘+t` on macOS)
Close tab :sc:`close_tab` (also :kbd:`⌘+w` on macOS)
Next tab :sc:`next_tab` (also :kbd:`^+⇥` and :kbd:`⇧+⌘+]` on macOS)
Previous tab :sc:`previous_tab` (also :kbd:`⇧+^+⇥` and :kbd:`⇧+⌘+[` on macOS)
Next layout :sc:`next_layout`
Move tab forward :sc:`move_tab_forward`
Move tab backward :sc:`move_tab_backward`
Set tab title :sc:`set_tab_title` (also :kbd:`⇧+⌘+i` on macOS)
======================== =======================
Windows
~~~~~~~~~~~~~~~~~~
======================== =======================
Action Shortcut
======================== =======================
New window :sc:`new_window` (also :kbd:`⌘+↩` on macOS)
New OS window :sc:`new_os_window` (also :kbd:`⌘+n` on macOS)
Close window :sc:`close_window` (also :kbd:`⇧+⌘+d` on macOS)
Next window :sc:`next_window`
Previous window :sc:`previous_window`
Move window forward :sc:`move_window_forward`
Move window backward :sc:`move_window_backward`
Move window to top :sc:`move_window_to_top`
Focus specific window :sc:`first_window`, :sc:`second_window` ... :sc:`tenth_window`
(also :kbd:`⌘+1`, :kbd:`⌘+2` ... :kbd:`⌘+9` on macOS)
(clockwise from the top-left)
======================== =======================
Additionally, you can define shortcuts in :file:`kitty.conf` to focus neighboring
windows and move windows around (similar to window movement in vim)::
map ctrl+left neighboring_window left
map shift+left move_window right
map ctrl+down neighboring_window down
map shift+down move_window up
...
You can also define a shortcut to switch to the previously active window::
map ctrl+p nth_window -1
``nth_window`` will focus the nth window for positive numbers and the
previously active windows for negative numbers.
.. _detach_window:
You can define shortcuts to detach the current window and
move it to another tab or another OS window::
# moves the window into a new OS window
map ctrl+f2 detach_window
# moves the window into a new Tab
map ctrl+f3 detach_window new-tab
# asks which tab to move the window into
map ctrl+f4 detach_window ask
Similarly, you can detach the current tab, with::
# moves the tab into a new OS window
map ctrl+f2 detach_tab
# asks which OS Window to move the tab into
map ctrl+f4 detach_tab ask
Finally, you can define a shortcut to close all windows in a tab other than
the currently active window::
map f9 close_other_windows_in_tab
Other keyboard shortcuts
----------------------------------
================================== =======================
Action Shortcut
================================== =======================
Copy to clipboard :sc:`copy_to_clipboard` (also :kbd:`⌘+c` on macOS)
Paste from clipboard :sc:`paste_from_clipboard` (also :kbd:`⌘+v` on macOS)
Paste from selection :sc:`paste_from_selection`
Increase font size :sc:`increase_font_size` (also :kbd:`⌘++` on macOS)
Decrease font size :sc:`decrease_font_size` (also :kbd:`⌘+-` on macOS)
Restore font size :sc:`reset_font_size` (also :kbd:`⌘+0` on macOS)
Toggle fullscreen :sc:`toggle_fullscreen` (also :kbd:`^+⌘+f` on macOS)
Toggle maximized :sc:`toggle_maximized`
Input unicode character :sc:`input_unicode_character`
Click URL using the keyboard :sc:`open_url`
Reset the terminal :sc:`reset_terminal`
Pass current selection to program :sc:`pass_selection_to_program`
Edit |kitty| config file :sc:`edit_config_file`
Open a |kitty| shell :sc:`kitty_shell`
Increase background opacity :sc:`increase_background_opacity`
Decrease background opacity :sc:`decrease_background_opacity`
Full background opacity :sc:`full_background_opacity`
Reset background opacity :sc:`reset_background_opacity`
================================== =======================
.. _layouts:
Layouts
----------
A layout is an arrangement of multiple kitty *windows* inside a top-level OS window. You can create a new window
using the :sc:`new_window` key combination.
Currently, there are six layouts available:
* **Fat** -- One (or optionally more) windows are shown full width on the top, the rest of the windows are shown side-by-side on the bottom
* **Grid** -- All windows are shown in a grid
* **Horizontal** -- All windows are shown side-by-side
* **Splits** -- Windows arranged in arbitrary patterns created using horizontal and vertical splits
* **Stack** -- Only a single maximized window is shown at a time
* **Tall** -- One (or optionally more) windows are shown full height on the left, the rest of the windows are shown one below the other on the right
* **Vertical** -- All windows are shown one below the other
By default, all layouts are enabled and you can switch between layouts using
the :sc:`next_layout` key combination. You can also create shortcuts to select
particular layouts, and choose which layouts you want to enable/disable, see
:ref:`conf-kitty-shortcuts.layout` for examples. The first layout listed in
:opt:`enabled_layouts` becomes the default layout.
For more details on the layouts and how to use them see :doc:`layouts`.
.. _kittens:
Kittens
------------------
|kitty| has a framework for easily creating terminal programs that make use of
its advanced features. These programs are called kittens. They are used both
to add features to |kitty| itself and to create useful standalone programs.
Some prominent kittens:
:doc:`icat <kittens/icat>`
Display images in the terminal
:doc:`diff <kittens/diff>`
A fast, side-by-side diff for the terminal with syntax highlighting and
images
:doc:`Unicode Input <kittens/unicode-input>`
Easily input arbitrary unicode characters in |kitty| by name or hex code.
:doc:`Hints <kittens/hints>`
Select and open/paste/insert arbitrary text snippets such as URLs,
filenames, words, lines, etc from the terminal screen.
:doc:`Panel <kittens/panel>`
Draw a GPU accelerated dock panel on your desktop showing the output
from an arbitrary terminal program.
:doc:`Clipboard <kittens/clipboard>`
Copy/paste to the clipboard from shell scripts, even over SSH.
You can also :doc:`Learn to create your own kittens <kittens/custom>`.
Configuring kitty
-------------------
|kitty| is highly configurable, everything from keyboard shortcuts to
painting frames-per-second. For details and a sample :file:`kitty.conf`,
see the :doc:`configuration docs <conf>`.
Remote control
------------------
|kitty| has a very powerful system that allows you to control it from the
:doc:`shell prompt, even over SSH <remote-control>`. You can change colors,
fonts, open new windows, tabs, set their titles, change window layout, get text
from one window and send text to another, etc, etc. The possibilities are
endless. See the :doc:`tutorial <remote-control>` to get started.
.. _sessions:
Startup Sessions
------------------
You can control the tabs, window layout, working directory, startup programs,
etc. by creating a "session" file and using the :option:`kitty --session`
command line flag or the :opt:`startup_session` option in :file:`kitty.conf`.
For example:
.. code-block:: session
# Set the window layout for the current tab
layout tall
# Set the working directory for windows in the current tab
cd ~
# Create a window and run the specified command in it
launch zsh
# Create a window with some environment variables set and run
# vim in it
launch env FOO=BAR vim
# Set the title for the next window
title Chat with x
launch irssi --profile x
# Create a new tab (the part after new_tab is the optional tab
# name which will be displayed in the tab bar, if omitted, the
# title of the active window will be used instead)
new_tab my tab
cd ~/somewhere
# Set the layouts allowed in this tab
enabled_layouts tall, stack
# Set the current layout
layout stack
launch zsh
# Create a new OS window
new_os_window
# set new window size to 80x25 cells
os_window_size 80c 25c
# set the --class for the new OS window
os_window_class mywindow
launch sh
# Make the current window the active (focused) window
focus
launch emacs
# Add a watcher that will be called with various events that occur
# on all subsequent windows. See the documentation of the launch command
# for details on watchers.
watcher /some/python/file.py
launch mpd
launch irssi
# Remove the watcher for further windows
watcher clear
Mouse features
-------------------
* You can hold down :kbd:`ctrl+shift` and click on a URL to open it in a browser.
* You can double click to select a word and then drag to select more words.
* You can triple click to select a line and then drag to select more lines.
* You can right click to extend a previous selection.
* You can hold down :kbd:`ctrl+alt` and drag with the mouse to select in
columns (see also :opt:`rectangle_select_modifiers`).
* Selecting text automatically copies it to the primary clipboard (on
platforms with a primary clipboard).
* You can select text with kitty even when a terminal program has grabbed
the mouse by holding down the :kbd:`shift` key (see also
:opt:`terminal_select_modifiers`).
Font control
-----------------
|kitty| has extremely flexible and powerful font selection features. You can
specify individual families for the regular, bold, italic and bold+italic
fonts. You can even specify specific font families for specific ranges of
unicode characters. This allows precise control over text rendering. It can
come in handy for applications like powerline, without the need to use patched
fonts. See the various font related configuration directives in
:ref:`conf-kitty-fonts`.
.. _scrollback:
The scrollback buffer
-----------------------
|kitty| supports scrolling back to view history, just like most terminals. You
can use either keyboard shortcuts or the mouse scroll wheel to do so. However,
|kitty| has an extra, neat feature. Sometimes you need to explore the
scrollback buffer in more detail, maybe search for some text or refer to it
side-by-side while typing in a follow-up command. |kitty| allows you to do this
by pressing the :sc:`show_scrollback` key-combination, which will open the
scrollback buffer in your favorite pager program (which is ``less`` by default).
Colors and text formatting are preserved. You can explore the scrollback buffer
comfortably within the pager.
Additionally, you can pipe the contents of the scrollback buffer to an
arbitrary, command running in a new window, tab or overlay, for example::
map f1 launch --stdin-source=@screen_scrollback --stdin-add-formatting less +G -R
Would open the scrollback buffer in a new window when you press the :kbd:`F1`
key. See :sc:`show_scrollback` for details.
If you wish to store very large amounts of scrollback to view using the piping or
:sc:`show_scrollback` features, you can use the :opt:`scrollback_pager_history_size`
option.
.. _cpbuf:
Multiple copy/paste buffers
-----------------------------
In addition to being able to copy/paste from the system clipboard, in |kitty| you
can also setup an arbitrary number of copy paste buffers. To do so, simply add
something like the following to your :file:`kitty.conf`::
map f1 copy_to_buffer a
map f2 paste_from_buffer a
This will allow you to press :kbd:`F1` to copy the current selection to an
internal buffer named ``a`` and :kbd:`F2` to paste from that buffer. The buffer
names are arbitrary strings, so you can define as many such buffers as you
need.
Marks
-------------
kitty has the ability to mark text on the screen based on regular expressions.
This can be useful to highlight words or phrases when browsing output from long
running programs or similar. To learn how this feature works, see :doc:`marks`.
Frequently Asked Questions
---------------------------------
The list of Frequently Asked Questions (*FAQ*) is :doc:`available here <faq>`.
.. _completion:
Cool integrations for kitty with other CLI tools
--------------------------------------------------
kitty provides extremely powerful interfaces such as :doc:`remote-control` and
:doc:`kittens/custom` and :doc:`kittens/icat`
that allow it to be integrated with other tools seamlessly. For a list of such
user created integrations, see: :doc:`integrations`.
Completion for kitty
---------------------------------
|kitty| comes with completion for the ``kitty`` command for popular shells.
bash
~~~~~~~~
Add the following to your :file:`~/.bashrc`
.. code-block:: sh
source <(kitty + complete setup bash)
Older versions of bash (for example, v3.2) do not support
process substitution with the source command, in which
case you can try an alternative:
.. code-block:: sh
source /dev/stdin <<<"$(kitty + complete setup bash)"
zsh
~~~~~~~~~
Add the following to your :file:`~/.zshrc`
.. code-block:: sh
autoload -Uz compinit
compinit
# Completion for kitty
kitty + complete setup zsh | source /dev/stdin
The important thing above is to make sure the call to |kitty| to load the zsh
completions happens after the call to :file:`compinit`.
fish
~~~~~~~~
For versions of fish earlier than 3.0.0, add the following to your
:file:`~/.config/fish/config.fish`. Later versions source completions by default.
.. code-block:: sh
kitty + complete setup fish | source
Changelog
------------------
See :doc:`changelog`.
.. toctree::
:hidden:
:glob:
*
kittens/*
generated/rc
To get started see :doc:`quickstart`.

View File

@@ -1,3 +1,5 @@
:tocdepth: 2
Integrations with other tools
================================
@@ -12,107 +14,245 @@ Image and document viewers
Powered by kitty's :doc:`graphics-protocol` there exist many tools for viewing
images and other types of documents directly in your terminal, even over SSH.
.. _tool_termpdf:
`termpdf.py <https://github.com/dsanson/termpdf.py>`_
a terminal PDF/DJVU/CBR viewer
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
A terminal PDF/DJVU/CBR viewer
.. _tool_mdcat:
`mdcat <https://github.com/lunaryorn/mdcat>`_
Display markdown files nicely formatted with images in the terminal
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Display markdown files nicely formatted with images in the terminal
.. _tool_ranger:
`ranger <https://github.com/ranger/ranger>`_
a terminal file manager, with previews of file contents powered by kitty's graphics protocol.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
A terminal file manager, with previews of file contents powered by kitty's graphics protocol.
.. _tool_nnn:
`nnn <https://github.com/jarun/nnn/>`_
another terminal file manager, with previews of file contents powered by kitty's graphics protocol.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Another terminal file manager, with previews of file contents powered by kitty's graphics protocol.
.. _tool_hunter:
`hunter <https://github.com/rabite0/hunter>`_
another terminal file manager, with previews of file contents powered by kitty's graphics protocol.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Another terminal file manager, with previews of file contents powered by kitty's graphics protocol.
.. _tool_koneko:
`koneko <https://github.com/twenty5151/koneko>`_
browse images from the pixiv artist community directly in kitty
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Browse images from the pixiv artist community directly in kitty.
.. _tool_viu:
`viu <https://github.com/atanunq/viu>`_
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
View images in the terminal, similar to kitty's icat.
.. _tool_nb:
`nb <https://github.com/xwmx/nb>`_
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
command line and local web note-taking, bookmarking, archiving, and
knowledge base application that uses kitty's graphics protocol for images.
.. _tool_w3m:
`w3m <https://github.com/tats/w3m>`_
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
A text mode WWW browser that supports kitty's graphics protocol to display
images.
.. _tool_timg:
`timg <https://github.com/hzeller/timg>`_
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
A terminal image and video viewer, that displays static and animated
images or plays videos. Fast multi-threaded loading, JPEG exif rotation,
grid view and connecting to the webcam make it a versatile terminal utility.
System and data visualisation tools
---------------------------------------
.. _tool_neofetch:
`neofetch <https://github.com/dylanaraps/neofetch>`_
A command line system information tool that shows images using kitty's graphics protocol
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
A command line system information tool that shows images using kitty's graphics protocol
.. _tool_matplotlib:
`matplotlib <https://github.com/jktr/matplotlib-backend-kitty>`_
show matplotlib plots directly in kitty
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Show matplotlib plots directly in kitty
.. _tool_KittyTerminalImage:
`KittyTerminalImages.jl <https://github.com/simonschoelly/KittyTerminalImages.jl>`_
show images from Julia directly in kitty
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Show images from Julia directly in kitty
.. _tool_euporie:
`euporie <https://github.com/joouha/euporie>`_
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
A text-based user interface for running and editing Jupyter notebooks,
powered by kitty's graphics protocol for displaying plots
.. _tool_gnuplot:
`gnuplot <http://www.gnuplot.info/>`_
a graphing and data visualization tool that can be made to display its
output in kitty with the following bash snippet::
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
function iplot {
cat <<EOF | gnuplot
set terminal pngcairo enhanced font 'Fira Sans,10'
set autoscale
set samples 1000
set output '|kitty +kitten icat --stdin yes'
set object 1 rectangle from screen 0,0 to screen 1,1 fillcolor rgb"#fdf6e3" behind
plot $@
set output '/dev/null'
EOF
}
A graphing and data visualization tool that can be made to display its
output in kitty with the following bash snippet:
Add this to bashrc and then to plot a function, simply do::
.. code-block:: sh
iplot 'sin(x*3)*exp(x*.2)'
function iplot {
cat <<EOF | gnuplot
set terminal pngcairo enhanced font 'Fira Sans,10'
set autoscale
set samples 1000
set output '|kitty +kitten icat --stdin yes'
set object 1 rectangle from screen 0,0 to screen 1,1 fillcolor rgb"#fdf6e3" behind
plot $@
set output '/dev/null'
EOF
}
Add this to bashrc and then to plot a function, simply do:
.. code-block:: sh
iplot 'sin(x*3)*exp(x*.2)'
.. tool_onefetch:
`onefetch <https://github.com/o2sh/onefetch>`_
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
A tool to fetch information about your git repositories
.. tool_patat:
`patat <https://github.com/jaspervdj/patat>`_
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Terminal based presentations using pandoc and kitty's image protocol for
images
.. tool_wttr:
`wttr.in <https://github.com/chubin/wttr.in>`_
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
A tool to display weather information in your terminal with curl
.. tool_wl_clipboard:
`wl-clipboard-manager <https://github.com/maximbaz/wl-clipboard-manager>`_
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
View and manage the system clipboard under Wayland in your kitty terminal
.. tool_dmenu_term:
`dmenu-term <https://github.com/maximbaz/dmenu-term>`_
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Run applications on your system with fuzzy find inside a kitty window
Editor integration
-----------------------
kitty can be integrated into many different terminal editors to add features
|kitty| can be integrated into many different terminal editors to add features
such a split windows, previews, REPLs etc.
.. tool_kakoune:
`kakoune <https://kakoune.org/>`_
integrates with kitty to use native kitty windows for its windows/panels and REPLs.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
integrates with kitty to use native kitty windows for its windows/panels and REPLs.
.. tool_vim_slime:
`vim-slime <https://github.com/jpalardy/vim-slime#kitty>`_
uses kitty remote control for a Lisp REPL.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
uses kitty remote control for a Lisp REPL.
.. tool_vim_kitty_navigator:
`vim-kitty-navigator <https://github.com/knubie/vim-kitty-navigator>`_
allows you to navigate seamlessly between vim and kitty splits using a consistent set of hotkeys.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
allows you to navigate seamlessly between vim and kitty splits using a consistent set of hotkeys.
.. tool_vim_test:
`vim-test <https://github.com/vim-test/vim-test>`_
allows easily running tests in a terminal window
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Allows easily running tests in a terminal window
.. tool_hologram:
`hologram.nvim <https://github.com/edluffy/hologram.nvim>`_
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Terminal image viewer for nvim
Scrollback manipulation
-------------------------
.. tool_kitty_search:
`kitty-search <https://github.com/trygveaa/kitty-kitten-search>`_
Live incremental search of the scrollback buffer.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Live incremental search of the scrollback buffer.
.. tool_kitty_grab:
`kitty-grab <https://github.com/yurikhan/kitty_grab>`_
keyboard based text selection for the kitty scrollback buffer.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Keyboard based text selection for the kitty scrollback buffer.
Miscellaneous
------------------
.. tool_kitty_smart_tab:
`kitty-smart-tab <https://github.com/yurikhan/kitty-smart-tab>`_
use keys to either control tabs or pass them onto running applications if
no tabs are present
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
use keys to either control tabs or pass them onto running applications if
no tabs are present
.. tool_kitty_smart_scroll:
`kitty-smart-scroll <https://github.com/yurikhan/kitty-smart-scroll>`_
use keys to either scroll or pass them onto running applications if
no scrollback buffer is present
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
use keys to either scroll or pass them onto running applications if
no scrollback buffer is present
`reload keybindings <https://github.com/kovidgoyal/kitty/issues/1292#issuecomment-582388769>`_
reload key bindings from :file:`kitty.conf` without needing to restart
kitty
.. tool_kitti3:
`kitti3 <https://github.com/LandingEllipse/kitti3>`_
allow using kitty as a drop-down terminal under the i3 window manager
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
allow using kitty as a drop-down terminal under the i3 window manager
.. tool_weechat_hints:
`weechat-hints <https://github.com/GermainZ/kitty-weechat-hints>`_
URL hints kitten for WeeChat that works without having to use WeeChat's
raw-mode.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
URL hints kitten for WeeChat that works without having to use WeeChat's
raw-mode.
.. tool_glkitty:
`glkitty <https://github.com/michaeljclark/glkitty>`_
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
C library to draw OpenGL shaders in the terminal with a glgears demo

View File

@@ -1,6 +1,15 @@
:orphan:
The kitty command line interface
====================================
.. program:: kitty
.. include:: generated/cli-kitty.rst
.. include:: basic.rst
See also
-----------
See kitty.conf(5)

View File

@@ -1,128 +0,0 @@
Key encoding for extended keyboard protocol
===============================================
See :ref:`extended-key-protocol` for more information and `this table in JSON
format <https://github.com/kovidgoyal/kitty/blob/master/key_encoding.json>`_.
===================== ======================
Name Encoded representation
0 ``G``
1 ``H``
2 ``I``
3 ``J``
4 ``K``
5 ``L``
6 ``M``
7 ``N``
8 ``O``
9 ``P``
A ``S``
APOSTROPHE ``B``
B ``T``
BACKSLASH ``t``
BACKSPACE ``1``
C ``U``
CAPS LOCK ``:``
COMMA ``C``
D ``V``
DELETE ``3``
DOWN ``6``
E ``W``
END ``-``
ENTER ``z``
EQUAL ``R``
ESCAPE ``y``
F ``X``
F1 ``/``
F10 ``]``
F11 ``{``
F12 ``}``
F13 ``@``
F14 ``%``
F15 ``$``
F16 ``#``
F17 ``BA``
F18 ``BB``
F19 ``BC``
F2 ``*``
F20 ``BD``
F21 ``BE``
F22 ``BF``
F23 ``BG``
F24 ``BH``
F25 ``BI``
F3 ``?``
F4 ``&``
F5 ``<``
F6 ``>``
F7 ``(``
F8 ``)``
F9 ``[``
G ``Y``
GRAVE ACCENT ``v``
H ``Z``
HOME ``.``
I ``a``
INSERT ``2``
J ``b``
K ``c``
KP 0 ``BJ``
KP 1 ``BK``
KP 2 ``BL``
KP 3 ``BM``
KP 4 ``BN``
KP 5 ``BO``
KP 6 ``BP``
KP 7 ``BQ``
KP 8 ``BR``
KP 9 ``BS``
KP ADD ``BX``
KP DECIMAL ``BT``
KP DIVIDE ``BU``
KP ENTER ``BY``
KP EQUAL ``BZ``
KP MULTIPLY ``BV``
KP SUBTRACT ``BW``
L ``d``
LEFT ``5``
LEFT ALT ``Bc``
LEFT BRACKET ``s``
LEFT CONTROL ``Bb``
LEFT SHIFT ``Ba``
LEFT SUPER ``Bd``
M ``e``
MINUS ``D``
N ``f``
NUM LOCK ``=``
O ``g``
P ``h``
PAGE DOWN ``9``
PAGE UP ``8``
PAUSE ``!``
PERIOD ``E``
PRINT SCREEN ``^``
Q ``i``
R ``j``
RIGHT ``4``
RIGHT ALT ``Bg``
RIGHT BRACKET ``u``
RIGHT CONTROL ``Bf``
RIGHT SHIFT ``Be``
RIGHT SUPER ``Bh``
S ``k``
SCROLL LOCK ``+``
SEMICOLON ``Q``
SLASH ``F``
SPACE ``A``
T ``l``
TAB ``0``
U ``m``
UP ``7``
V ``n``
W ``o``
WORLD 1 ``w``
WORLD 2 ``x``
X ``p``
Y ``q``
Z ``r``
===================== ======================

665
docs/keyboard-protocol.rst Normal file
View File

@@ -0,0 +1,665 @@
Comprehensive keyboard handling in terminals
==============================================
There are various problems with the current state of keyboard handling in
terminals. They include:
* No way to use modifiers other than ``ctrl`` and ``alt``
* No way to reliably use multiple modifier keys, other than, ``shift+alt`` and
``ctrl+alt``.
* Many of the existing escape codes used to encode these events are ambiguous
with different key presses mapping to the same escape code.
* No way to handle different types of keyboard events, such as press, release or repeat
* No reliable way to distinguish single ``Esc`` key presses from the start of a
escape sequence. Currently, client programs use fragile timing related hacks
for this, leading to bugs, for example:
`neovim #2035 <https://github.com/neovim/neovim/issues/2035>`_.
To solve these issues and others, kitty has created a new keyboard protocol,
that is backward compatible but allows applications to opt-in to support more
advanced usages. The protocol is based on initial work in `fixterms
<http://www.leonerd.org.uk/hacks/fixterms/>`_, however, it corrects various
issues in that proposal, listed at the :ref:`bottom of this document
<fixterms_bugs>`. For public discussion of this spec, see :iss:`3248`.
You can see this protocol with all enhancements in action by running::
kitty +kitten show_key -m kitty
inside the kitty terminal to report key events.
.. versionadded:: 0.20.0
Quickstart
---------------
If you are an application or library developer just interested in using this
protocol to make keyboard handling simpler and more robust in your application,
without too many changes, do the following:
#. Emit the escape code ``CSI > 1 u`` at application startup if using the main
screen or when entering alternate screen mode, if using the alternate
screen.
#. All key events will now be sent in only a few forms to your application,
that are easy to parse unambiguously.
#. Emit the escape sequence ``CSI < u`` at application exit if using the main
screen or just before leaving alternate screen mode if using the alternate screen,
to restore the previously used keyboard mode.
Key events will all be delivered to your application either as plain UTF-8
text, or using the following escape codes, for those keys that do not produce
text (``CSI`` is the bytes ``0x1b 0x5b``)::
CSI number ; modifiers [u~]
CSI 1; modifiers [ABCDEFHPQRS]
0x0d - for the Enter key
0x7f or 0x08 - for Backspace
0x09 - for Tab
The ``number`` in the first form above will be either the Unicode codepoint for a
key, such as ``97`` for the :kbd:`a` key, or one of the numbers from the
:ref:`functional` table below. The ``modifiers`` optional parameter encodes any
modifiers pressed for the key event. The encoding is described in the
:ref:`modifiers` section.
The second form is used for a few functional keys, such as the :kbd:`Home, End,
Arrow keys and F1-F4`, they are enumerated in the :ref:`functional` table below.
Note that if no modifiers are present the parameters are omitted entirely
giving an escape code of the form ``CSI [ABCDEFHPQRS]``.
If you want support for more advanced features such as repeat and release
events, alternate keys for shortcut matching et cetera, these can be turned on
using :ref:`progressive_enhancement` as documented in the rest of this
specification.
An overview
------------------
Key events are divided into two types, those that produce text and those that
do not. When a key event produces text, the text is sent directly as UTF-8
encoded bytes. This is safe as UTF-8 contains no C0 control codes.
When the key event does not have text, the key event is encoded as an escape code. In
legacy compatibility mode (the default) this uses legacy escape codes, so old terminal
applications continue to work. Key events that could not be represented in
legacy mode are encoded using a ``CSI u`` escape code, that most terminal
programs should just ignore. For more advanced features, such as release/repeat
reporting etc., applications can tell the terminal they want this information by
sending an escape code to :ref:`progressively enhance <progressive_enhancement>` the data reported for
key events.
The central escape code used to encode key events is::
CSI unicode-key-code:alternate-key-codes ; modifiers:event-type ; text-as-codepoints u
Spaces in the above definition are present for clarity and should be ignored.
``CSI`` is the bytes ``0x1b 0x5b``. All parameters are decimal numbers. Fields
are separated by the semi-colon and sub-fields by the colon. Only the
``unicode-key-code`` field is mandatory, everything else is optional. The
escape code is terminated by the ``u`` character (the byte ``0x75``).
.. _key_codes:
Key codes
~~~~~~~~~~~~~~
The ``unicode-key-code`` above is the Unicode codepoint representing the key, as a
decimal number. For example, the :kbd:`A` key is represented as ``97`` which is
the unicode code for lowercase ``a``. Note that the codepoint used is *always*
the lower-case (or more technically, un-shifted) version of the key. If the
user presses, for example, :kbd:`ctrl+shift+a` the escape code would be ``CSI
97;modifiers u``. It *must not* be ``CSI 65; modifiers u``.
If *alternate key reporting* is requested by the program running in the
terminal, the terminal can send two additional Unicode codepoints, the
*shifted key* and *base layout key*, separated by colons.
The shifted key is simply the upper-case version of ``unicode-codepoint``, or
more technically, the shifted version. So `a` becomes `A` and so on, based on
the current keyboard layout. This is needed to be able to match against a
shortcut such as :kbd:`ctrl+plus` which depending on the type of keyboard could
be either :kbd:`ctrl+shift+equal` or :kbd:`ctrl+plus`. Note that the shifted
key must be present only if shift is also present in the modifiers.
The *base layout key* is the key corresponding to the physical key in the
standard PC-101 key layout. So for example, if the user is using a Cyrillic
keyboard with a Cyrillic keyboard layout pressing the :kbd:`ctrl+С` key will
be :kbd:`ctrl+c` in the standard layout. So the terminal should send the *base
layout key* as ``99`` corresponding to the ``c`` key.
If only one alternate key is present, it is the *shifted key* if the terminal
wants to send only a base layout key but no shifted key, it must use an empty
sub-field for the shifted key, like this::
CSI unicode-key-code::base-layout-key
.. _modifiers:
Modifiers
~~~~~~~~~~~~~~
This protocol supports six modifier keys, :kbd:`shift, alt, ctrl, super, hyper
and meta` as well as :kbd:`num_lock and caps_lock`. Here :kbd:`super` is either
the *Windows/Linux* key or the *Cmd* key on mac keyboards. :kbd:`hyper` and
:kbd:`meta` are typically present only on X11 based systems with special XKB
rules. Modifiers are encoded as a bit field with::
shift 0b1 (1)
alt 0b10 (2)
ctrl 0b100 (4)
super 0b1000 (8)
hyper 0b10000 (16)
meta 0b100000 (32)
caps_lock 0b1000000 (64)
num_lock 0b10000000 (128)
In the escape code, the modifier value is encoded as a decimal number which is
``1 + actual modifiers``. So to represent :kbd:`shift` only, the value would be ``1 +
1 = 2``, to represent :kbd:`ctrl+shift` the value would be ``1 + 0b101 = 6``
and so on. If the modifier field is not present in the escape code, its default
value is ``1`` which means no modifiers.
.. _event_types:
Event types
~~~~~~~~~~~~~~~~
There are three key event types: ``press, repeat and release``. They are
reported (if requested ``0b10``) as a sub-field of the modifiers field
(separated by a colon). If no modifiers are present, the modifiers field must
have the value ``1`` and the event type sub-field the type of event. The
``press`` event type has value ``1`` and is the default if no event type sub
field is present. The ``repeat`` type is ``2`` and the ``release`` type is
``3``. So for example::
CSI key-code # this is a press event
CSI key-code;modifier # this is a press event
CSI key-code;modifier:1 # this is a press event
CSI key-code;modifier:2 # this is a repeat event
CSI key-code;modifier:3 # this is a release event
.. note:: Key events that result in text are reported as plain UTF-8 text, so
events are not supported for them, unless the application requests *key
report mode*, see below.
.. _text_as_codepoints:
Text as code points
~~~~~~~~~~~~~~~~~~~~~
The terminal can optionally send the text associated with key events as a
sequence of Unicode code points. This behavior is opt-in by the :ref:`progressive
enhancement <progressive_enhancement>` mechanism described below. Some examples::
shift+a -> CSI 97 ; 2 ; 65 u # The text 'A' is reported as 65
option+a -> CSI 97 ; ; 229 u # The text 'å' is reported as 229
If multiple code points are present, they must be separated by colons.
If no known key is associated with the text the key number ``0`` must be used.
Non-Unicode keys
~~~~~~~~~~~~~~~~~~~~~~~
There are many keys that don't correspond to letters from human languages, and
thus aren't represented in Unicode. Think of functional keys, such as
:kbd:`Escape, Play, Pause, F1, Home, etc`. These are encoded using Unicode code
points from the Private Use Area (``57344 - 63743``). The mapping of key
names to code points for these keys is in the
:ref:`Functional key definition table below <functional>`.
.. _progressive_enhancement:
Progressive enhancement
--------------------------
While, in theory, every key event could be completely represented by this
protocol and all would be hunk-dory, in reality there is a vast universe of
existing terminal programs that expect legacy control codes for key events and
that are not likely to ever be updated. To support these, in default mode,
the terminal will emit legacy escape codes for compatibility. If a terminal
program wants more robust key handling, it can request it from the terminal,
via the mechanism described here. Each enhancement is described in detail
below. The escape code for requesting enhancements is::
CSI = flags ; mode u
Here ``flags`` is a decimal encoded integer to specify a set of bit-flags. The
meanings of the flags are given below. The second, ``mode`` parameter is
optional (defaulting to ``1``) and specifies how the flags are applied.
The value ``1`` means all set bits are set and all unset bits are reset.
The value ``2`` means all set bits are set, unset bits are left unchanged.
The value ``3`` means all set bits are reset, unset bits are left unchanged.
.. csv-table:: The progressive enhancement flags
:header: "Bit", "Meaning"
"0b1 (1)", ":ref:`disambiguate`"
"0b10 (2)", ":ref:`report_events`"
"0b100 (4)", ":ref:`report_alternates`"
"0b1000 (8)", ":ref:`report_all_keys`"
"0b10000 (16)", ":ref:`report_text`"
The program running in the terminal can query the terminal for the
current values of the flags by sending::
CSI ? u
The terminal will reply with::
CSI ? flags u
The program can also push/pop the current flags onto a stack in the
terminal with::
CSI > flags u # for push, if flags ommitted default to zero
CSI < number u # to pop number entries, defaulting to 1 if unspecified
Terminals should limit the size of the stack as appropriate, to prevent
Denial-of-Service attacks. Terminals must maintain separate stacks for the main
and alternate screens. If a pop request is received that empties the stack,
all flags are reset. If a push request is received and the stack is full, the
oldest entry from the stack must be evicted.
.. note:: The main and alternate screens in the terminal emulator must maintain
their own, independent, keyboard mode stacks. This is so that a program that
uses the alternate screen such as an editor, can change the keyboard mode
in the alternate screen only, without affecting the mode in the main screen
or even knowing what that mode is. Without this, and if no stack is
implemented for keyboard modes (such as in some legacy terminal emulators)
the editor would have to somehow know what the keyboard mode of the main
screen is and restore to that mode on exit.
.. note:: In the interests of interoperation, the XTerm specific sequences
`CSI > 4; 1 m` and `CSI > 4; 0 m` are treated as `CSI > 1 u` and `CSI < 1 u`.
These codes cause XTerm to use the CSI u encoding for more keys and are therefore
treated as similar to the disambiguate progressive enhancement.
.. _disambiguate:
Disambiguate escape codes
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This type of progressive enhancement (``0b1``) fixes the problem of some legacy key press
encodings overlapping with other control codes. For instance, pressing the
:kbd:`Esc` key generates the byte ``0x1b`` which also is used to indicate the
start of an escape code. Similarly pressing the key :kbd:`alt+[` will generate
the bytes used for CSI control codes.
Turning on this flag will cause the terminal to report the :kbd:`Esc, alt+key,
ctrl+key, ctrl+alt+key, shift+alt+key` keys using ``CSI u`` sequences instead
of legacy ones. Here key is any ASCII key as described in :ref:`legacy_text`.
Additionally, all keypad keys will be reported as separate keys with ``CSI u``
encoding, using dedicated numbers from the :ref:`table below <functional>`.
With this flag turned on, all key events that do not generate text are
represented in one of the following two forms::
CSI number; modifier u
CSI 1; modifier [~ABCDEFHPQRS]
This makes it very easy to parse key events in an application. In particular,
:kbd:`ctrl+c` will no longer generate the ``SIGINT`` signal, but instead be
delivered as a ``CSI u`` escape code. This has the nice side effect of making it
much easier to integrate into the application event loop. The only exceptions
are the :kbd:`Enter, Tab and Backspace` keys which still generate the same
bytes as in legacy mode this is to allow the user to type and execute commands
in the shell such as ``reset`` after a program that sets this mode crashes
without clearing it.
.. _report_events:
Report event types
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This progressive enhancement (``0b10``) causes the terminal to report key repeat
and key release events. Normally only key press events are reported and key
repeat events are treated as key press events. See :ref:`event_types` for
details on how these are reported.
.. _report_alternates:
Report alternate keys
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This progressive enhancement (``0b100``) causes the terminal to report
alternate key values in addition to the main value, to aid in shortcut
matching. See :ref:`key_codes` for details on how these are reported.
.. _report_all_keys:
Report all keys as escape codes
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Key events that generate text, such as plain key presses without modifiers,
result in just the text being sent, in the legacy protocol. There is no way to
be notified of key repeat/release events. These types of events are needed for
some applications, such as games (think of movement using the ``WASD`` keys).
This progressive enhancement (``0b1000``) turns on key reporting even for key
events that generate text. When it is enabled, text will not be sent, instead
only key events are sent. If the text is needed as well, combine with the
Report associated text enhancement below.
Additionally, with this mode, events for pressing modifier keys are reported.
Note that *all* keys are reported as escape codes, including :kbd:`Enter, Tab,
Backspace` etc.
.. _report_text:
Report associated text
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This progressive enhancement (``0b10000``) causes key events that generate text
to be reported as ``CSI u`` escape codes with the text embedded in the escape
code. See :ref:`text_as_codepoints` above for details on the mechanism.
.. _detection:
Detection of support for this protocol
------------------------------------------
An application can query the terminal for support of this protocol by sending
the escape code querying for the :ref:`current progressive enhancement
<progressive_enhancement>` status
followed by request for the `primary device attributes
<https://vt100.net/docs/vt510-rm/DA1.html>`. If an answer for the device
attributes is received without getting back an answer for the progressive
enhancement the terminal does not support this protocol.
Legacy key event encoding
--------------------------------
In the default mode, the terminal uses a legacy encoding for key events. In
this encoding, only key press and repeat events are sent and there is no
way to distinguish between them. Text is sent directly as UTF-8 bytes.
Any key events not described in this section are sent using the standard
``CSI u`` encoding. This includes keys that are not encodable in the legacy
encoding, thereby increasing the space of usable key combinations even without
progressive enhancement.
Legacy functional keys
~~~~~~~~~~~~~~~~~~~~~~~~
These keys are encoded using three schemes::
CSI number ; modifier ~
CSI 1 ; modifier {ABCDEFHPQRS}
SS3 {ABCDEFHPQRS}
In the above, if there are no modifiers, the modifier parameter is omitted.
The modifier value is encoded as described in the :ref:`modifiers` section,
above. When the second form is used, the number is always ``1`` and must be
omitted if the modifiers field is also absent. The third form becomes the
second form when modifiers are present (``SS3 is the bytes 0x1b 0x4f``).
These sequences must match entries in the terminfo database for maximum
compatibility. The table below lists the key, its terminfo entry name and
the escape code used for it by kitty. A different terminal would use whatever
escape code is present in its terminfo database for the key.
Some keys have an alternate representation when the terminal is in *cursor key
mode* (the ``smkx/rmkx`` terminfo capabilities). This form is used only in
*cursor key mode* and only when no modifiers are present.
.. csv-table:: Legacy functional encoding
:header: "Name", "Terminfo name", "Escape code"
"INSERT", "kich1", "CSI 2 ~"
"DELETE", "kdch1", "CSI 3 ~"
"PAGE_UP", "kpp", "CSI 5 ~"
"PAGE_DOWN", "knp", "CSI 6 ~"
"UP", "cuu1,kcuu1", "CSI A, SS3 A"
"DOWN", "cud1,kcud1", "CSI B, SS3 B"
"RIGHT", "cuf1,kcuf1", "CSI C, SS3 C"
"LEFT", "cub1,kcub1", "CSI D, SS3 D"
"HOME", "home,khome", "CSI H, SS3 H"
"END", "-,kend", "CSI F, SS3 F"
"F1", "kf1", "SS3 P"
"F2", "kf2", "SS3 Q"
"F3", "kf3", "SS3 R"
"F4", "kf4", "SS3 S"
"F5", "kf5", "CSI 15 ~"
"F6", "kf6", "CSI 17 ~"
"F7", "kf7", "CSI 18 ~"
"F8", "kf8", "CSI 19 ~"
"F9", "kf9", "CSI 20 ~"
"F10", "kf10", "CSI 21 ~"
"F11", "kf11", "CSI 23 ~"
"F12", "kf12", "CSI 24 ~"
There are a few more functional keys that have special cased legacy encodings.
These are present because they are commonly used and for the sake of legacy
terminal applications that get confused when seeing CSI u escape codes:
.. csv-table:: C0 controls
:header: "Key", "No mods", "Ctrl", "Alt", "Shift", "Ctrl + Shift", "Alt + Shift", "Ctrl + Alt"
"Enter", "0xd", "0xd", "0x1b 0xd", "0xd", "0xd", "0x1b 0xd", "0x1b 0xd"
"Escape", "0x1b", "0x1b", "0x1b 0x1b", "0x1b", "0x1b", "0x1b 0x1b", "0x1b 0x1b"
"Backspace", "0x7f", "0x8", "0x1b 0x7f", "0x7f", "0x8", "0x1b 0x7f", "0x1b 0x8"
"Tab", "0x9", "0x9", "0x1b 0x9", "CSI Z", "CSI Z", "0x1b CSI Z", "0x1b 0x9"
"Space", "0x20", "0x0", "0x1b 0x20", "0x20", "0x0", "0x1b 0x20", "0x1b 0x0"
Note that :kbd:`Backspace` and :kbd:`ctrl+Backspace` are swapped in some
terminals, this can be detected using the ``kbs`` terminfo property that
must correspond to the :kbd:`Backspace` key.
All keypad keys are reported as their equivalent non-keypad keys. To
distinguish these, use the :ref:`disambiguate <disambiguate>` flag.
.. _legacy_text:
Legacy text keys
~~~~~~~~~~~~~~~~~~~
For legacy compatibility, the keys
:kbd:`a-z 0-9 \` - = [ ] \ ; ' , . /` with the modifiers
:kbd:`shift, alt, ctrl, shift+alt, ctrl+alt` are output using the
following algorithm:
#. If the :kbd:`alt` key is pressed output the byte for ``ESC (0x1b)``
#. If the :kbd:`ctrl` modifier is pressed map the key using the table
in :ref:`ctrl_mapping`.
#. Otherwise, if the :kbd:`shift` modifier is pressed, output the shifted key,
for example, ``A`` for ``a`` and ``$`` for ``4``.
#. Otherwise, output the key unmodified
Additionally, :kbd:`ctrl+space` is output as the NULL byte ``(0x0)``.
Any other combination of modifiers with these keys is output as the appropriate
``CSI u`` escape code.
.. csv-table:: Example encodings
:header: "Key", "Plain", "shift", "alt", "ctrl", "shift+alt", "alt+ctrl", "ctrl+shift"
"i", "i (105)", "I (73)", "ESC i", ") (41)", "ESC I", "ESC )", "CSI 105; 6 u"
"3", "3 (51)", "# (35)", "ESC 3", "3 (51)", "ESC #", "ESC 3", "CSI 51; 6 u"
";", "; (59)", ": (58)", "ESC ;", "; (59)", "ESC :", "ESC ;", "CSI 59; 6 u"
.. note::
Many of the legacy escape codes are ambiguous with multiple different key
presses yielding the same escape code(s), for example, :kbd:`ctrl+i` is the
same as :kbd:`tab`, :kbd:`ctrl+m` is the same as :kbd:`Enter`, :kbd:`ctrl+r`
is the same :kbd:`ctrl+shift+r`, etc. To resolve these use the
:ref:`disambiguate progressive enhancement <disambiguate>`.
.. _functional:
Functional key definitions
----------------------------
All numbers are in the Unicode Private Use Area (``57344 - 63743``) except
for a handful of keys that use numbers under 32 and 127 (C0 control codes) for legacy
compatibility reasons.
.. {{{
.. start functional key table (auto generated by gen-key-constants.py do not edit)
.. csv-table:: Functional key codes
:header: "Name", "CSI", "Name", "CSI"
"ESCAPE", "``27 u``", "ENTER", "``13 u``"
"TAB", "``9 u``", "BACKSPACE", "``127 u``"
"INSERT", "``2 ~``", "DELETE", "``3 ~``"
"LEFT", "``1 D``", "RIGHT", "``1 C``"
"UP", "``1 A``", "DOWN", "``1 B``"
"PAGE_UP", "``5 ~``", "PAGE_DOWN", "``6 ~``"
"HOME", "``1 H or 7 ~``", "END", "``1 F or 8 ~``"
"CAPS_LOCK", "``57358 u``", "SCROLL_LOCK", "``57359 u``"
"NUM_LOCK", "``57360 u``", "PRINT_SCREEN", "``57361 u``"
"PAUSE", "``57362 u``", "MENU", "``57363 u``"
"F1", "``1 P or 11 ~``", "F2", "``1 Q or 12 ~``"
"F3", "``1 R or 13 ~``", "F4", "``1 S or 14 ~``"
"F5", "``15 ~``", "F6", "``17 ~``"
"F7", "``18 ~``", "F8", "``19 ~``"
"F9", "``20 ~``", "F10", "``21 ~``"
"F11", "``23 ~``", "F12", "``24 ~``"
"F13", "``57376 u``", "F14", "``57377 u``"
"F15", "``57378 u``", "F16", "``57379 u``"
"F17", "``57380 u``", "F18", "``57381 u``"
"F19", "``57382 u``", "F20", "``57383 u``"
"F21", "``57384 u``", "F22", "``57385 u``"
"F23", "``57386 u``", "F24", "``57387 u``"
"F25", "``57388 u``", "F26", "``57389 u``"
"F27", "``57390 u``", "F28", "``57391 u``"
"F29", "``57392 u``", "F30", "``57393 u``"
"F31", "``57394 u``", "F32", "``57395 u``"
"F33", "``57396 u``", "F34", "``57397 u``"
"F35", "``57398 u``", "KP_0", "``57399 u``"
"KP_1", "``57400 u``", "KP_2", "``57401 u``"
"KP_3", "``57402 u``", "KP_4", "``57403 u``"
"KP_5", "``57404 u``", "KP_6", "``57405 u``"
"KP_7", "``57406 u``", "KP_8", "``57407 u``"
"KP_9", "``57408 u``", "KP_DECIMAL", "``57409 u``"
"KP_DIVIDE", "``57410 u``", "KP_MULTIPLY", "``57411 u``"
"KP_SUBTRACT", "``57412 u``", "KP_ADD", "``57413 u``"
"KP_ENTER", "``57414 u``", "KP_EQUAL", "``57415 u``"
"KP_SEPARATOR", "``57416 u``", "KP_LEFT", "``57417 u``"
"KP_RIGHT", "``57418 u``", "KP_UP", "``57419 u``"
"KP_DOWN", "``57420 u``", "KP_PAGE_UP", "``57421 u``"
"KP_PAGE_DOWN", "``57422 u``", "KP_HOME", "``57423 u``"
"KP_END", "``57424 u``", "KP_INSERT", "``57425 u``"
"KP_DELETE", "``57426 u``", "KP_BEGIN", "``1 E or 57427 ~``"
"MEDIA_PLAY", "``57428 u``", "MEDIA_PAUSE", "``57429 u``"
"MEDIA_PLAY_PAUSE", "``57430 u``", "MEDIA_REVERSE", "``57431 u``"
"MEDIA_STOP", "``57432 u``", "MEDIA_FAST_FORWARD", "``57433 u``"
"MEDIA_REWIND", "``57434 u``", "MEDIA_TRACK_NEXT", "``57435 u``"
"MEDIA_TRACK_PREVIOUS", "``57436 u``", "MEDIA_RECORD", "``57437 u``"
"LOWER_VOLUME", "``57438 u``", "RAISE_VOLUME", "``57439 u``"
"MUTE_VOLUME", "``57440 u``", "LEFT_SHIFT", "``57441 u``"
"LEFT_CONTROL", "``57442 u``", "LEFT_ALT", "``57443 u``"
"LEFT_SUPER", "``57444 u``", "LEFT_HYPER", "``57445 u``"
"LEFT_META", "``57446 u``", "RIGHT_SHIFT", "``57447 u``"
"RIGHT_CONTROL", "``57448 u``", "RIGHT_ALT", "``57449 u``"
"RIGHT_SUPER", "``57450 u``", "RIGHT_HYPER", "``57451 u``"
"RIGHT_META", "``57452 u``", "ISO_LEVEL3_SHIFT", "``57453 u``"
"ISO_LEVEL5_SHIFT", "``57454 u``"
.. end functional key table
.. }}}
Note that the escape codes above of the form ``CSI 1 letter`` will omit the
``1`` if there are no modifiers, since ``1`` is the default value.
.. _ctrl_mapping:
Legacy :kbd:`ctrl` mapping of ASCII keys
------------------------------------------
When the :kbd:`ctrl` key and another key are pressed on the keyboard, terminals
map the result *for some keys* to a *C0 control code* i.e. an value from ``0 -
31``. This mapping was historically dependent on the layout of hardware
terminal keyboards and is not specified anywhere, completely. The best known
reference is `Table 3-5 in the VT-100 docs <https://vt100.net/docs/vt100-ug/chapter3.html>`_.
The table below provides a mapping that is a commonly used superset of the table above.
Any ASCII keys not in the table must be left untouched by :kbd:`ctrl`.
.. {{{
.. start ctrl mapping (auto generated by gen-key-constants.py do not edit)
.. csv-table:: Emitted bytes when :kbd:`ctrl` is held down and a key is pressed
:header: "Key", "Byte", "Key", "Byte", "Key", "Byte"
"SPC ", "0", "/", "31", "0", "48"
"1", "49", "2", "0", "3", "27"
"4", "28", "5", "29", "6", "30"
"7", "31", "8", "127", "9", "57"
"?", "127", "@", "0", "[", "27"
"\\", "28", "]", "29", "^", "30"
"_", "31", "a", "1", "b", "2"
"c", "3", "d", "4", "e", "5"
"f", "6", "g", "7", "h", "8"
"i", "9", "j", "10", "k", "11"
"l", "12", "m", "13", "n", "14"
"o", "15", "p", "16", "q", "17"
"r", "18", "s", "19", "t", "20"
"u", "21", "v", "22", "w", "23"
"x", "24", "y", "25", "z", "26"
"~", "30"
.. end ctrl mapping
.. }}}
.. _fixterms_bugs:
Bugs in fixterms
-------------------
The following is a list of errata in the `original fixterms proposal
<http://www.leonerd.org.uk/hacks/fixterms/>`_, corrected in this
specification.
* No way to disambiguate :kbd:`Esc` key presses, other than using 8-bit controls
which are undesirable for other reasons
* Incorrectly claims special keys are sometimes encoded using ``CSI letter`` encodings when it
is actually ``SS3 letter`` in all terminals newer than a VT-52, which is
pretty much everything.
* :kbd:`ctrl+shift+tab` should be ``CSI 9 ; 6 u`` not ``CSI 1 ; 5 Z``
(shift+tab is not a separate key from tab)
* No support for the :kbd:`super` modifier.
* Makes no mention of cursor key mode and how it changes encodings
* Incorrectly encoding shifted keys when shift modifier is used, for instance,
for :kbd:`ctrl+shift+i` is encoded as :kbd:`ctrl+I`.
* No way to have non-conflicting escape codes for :kbd:`alt+letter,
ctrl+letter, ctrl+alt+letter` key presses
* No way to specify both shifted and unshifted keys for robust shortcut
matching (think matching :kbd:`ctrl+shift+equal` and :kbd:`ctrl+plus`)
* No way to specify alternate layout key. This is useful for keyboard layouts
such as Cyrillic where you want the shortcut :kbd:`ctrl+c` to work when
pressing the :kbd:`ctrl+С` on the keyboard.
* No way to report repeat and release key events, only key press events
* No way to report key events for presses that generate text, useful for
gaming. Think of using the :kbd:`WASD` keys to control movement.
* Only a small subset of all possible functional keys are assigned numbers.
* Claims the ``CSI u`` escape code has no fixed meaning, but has been used for
decades as ``SCORC`` for instance by xterm and ansi.sys and `DECSMBV
<https://vt100.net/docs/vt510-rm/DECSMBV.html>`_ by the VT-510 hardware
terminal. This doesn't really matter since these uses are for communication
to the terminal not from the terminal.
* Handwaves that :kbd:`ctrl` *tends to* mask with ``0x1f``. In actual fact it
does this only for some keys. The action of :kbd:`ctrl` is not specified and
varies between terminals, historically because of different keyboard layouts.

View File

@@ -0,0 +1,22 @@
broadcast
==================================================
*Type text in all kitty windows simultaneously*
The ``broadcast`` kitten can be used to type text simultaneously in
all kitty windows (or a subset as desired).
To use it, simply create a mapping in :file:`kitty.conf` such as::
map F1 launch --allow-remote-control kitty +kitten broadcast
Then press the :kbd:`F1` key and whatever you type in the newly created widow
will be sent to all kitty windows.
You can use the options described below to control which windows
are selected.
.. program:: kitty +kitten broadcast
.. include:: /generated/cli-kitten-broadcast.rst

View File

@@ -1,6 +1,8 @@
clipboard - copy/paste to the system clipboard
clipboard
==================================================
*Copy/paste to the system clipboard from shell scripts*
.. highlight:: sh
@@ -21,7 +23,4 @@ use::
.. program:: kitty +kitten clipboard
Command Line Interface
--------------------------
.. include:: /generated/cli-kitten-clipboard.rst

View File

@@ -20,6 +20,9 @@ your machine).
.. code-block:: python
from typing import List
from kitty.boss import Boss
def main(args: List[str]) -> str:
# this is the main entry point of the kitten, it will be executed in
# the overlay window when the kitten is launched
@@ -28,7 +31,7 @@ your machine).
# handle_result() function
return answer
def handle_result(args: List[str], answer: str, target_window_id: int, boss: kitty.boss.Boss) -> None:
def handle_result(args: List[str], answer: str, target_window_id: int, boss: Boss) -> None:
# get the kitty window into which to paste answer
w = boss.window_id_map.get(target_window_id)
if w is not None:
@@ -100,7 +103,8 @@ terminal program, you can tell the kittens system to run the
``handle_result()`` function without first running the ``main()`` function.
For example, here is a kitten that "zooms/unzooms" the current terminal window
by switching to the stack layout or back to the previous layout.
by switching to the stack layout or back to the previous layout. This is
equivalent to the builtin :ref:`action-toggle_layout` action.
Create a file in the kitty config folder, :file:`~/.config/kitty/zoom_toggle.py`
@@ -182,6 +186,104 @@ The output of print statements will go to the ``STDOUT`` of the kitty process.
So if you run kitty from another kitty instance, the output will be visible
in the first kitty instance.
Adding options to kittens
----------------------------
If you would like to use kitty's config framework to make your kittens
configurable, you will need some boilerplate. In the directory
of your kitten make the following files.
:file:`kitten_options_definition.py`
.. code-block:: python
from kitty.conf.types import Action, Definition
definition = Definition(
'!kitten_options_utils',
Action(
'map', 'parse_map',
{'key_definitions': 'kitty.conf.utils.KittensKeyMap'},
['kitty.types.ParsedShortcut', 'kitty.conf.utils.KeyAction']
),
)
agr = definition.add_group
egr = definition.end_group
opt = definition.add_option
map = definition.add_map
# main options {{{
agr('main', 'Main')
opt('some_option', '33',
option_type='some_option_parser',
long_text='''
Help text for this option
'''
)
egr() # }}}
# shortcuts {{{
agr('shortcuts', 'Keyboard shortcuts')
map('Quit', 'quit q quit')
egr() # }}}
:file:`kitten_options_utils.py`
.. code-block:: python
from kitty.conf.utils import KittensKeyDefinition, key_func, parse_kittens_key
func_with_args, args_funcs = key_func()
FuncArgsType = Tuple[str, Sequence[Any]]
def some_option_parser(val: str) -> int:
return int(val) + 3000
def parse_map(val: str) -> Iterable[KittensKeyDefinition]:
x = parse_kittens_key(val, args_funcs)
if x is not None:
yield x
Then run::
kitty +runpy 'from kitty.conf.generate import main; main()' /path/to/kitten_options_definition.py
You can parse and read the options in your kitten using the following code:
.. code-block:: python
from .kitten_options_types import Options, defaults
from kitty.conf.utils import load_config as _load_config, parse_config_base
from typing import Optional, Iterable, Dict, Any
def load_config(*paths: str, overrides: Optional[Iterable[str]] = None) -> Options:
from .kitten_options_parse import (
create_result_dict, merge_result_dicts, parse_conf_item
)
def parse_config(lines: Iterable[str]) -> Dict[str, Any]:
ans: Dict[str, Any] = create_result_dict()
parse_config_base(
lines,
parse_conf_item,
ans,
)
return ans
overrides = tuple(overrides) if overrides is not None else ()
opts_dict, paths = _load_config(defaults, parse_config, merge_result_dicts, *paths, overrides=overrides)
opts = Options(opts_dict)
opts.config_paths = paths
opts.config_overrides = overrides
return opts
See the code for the builtin diff kitten for examples of creating more options
and keyboard shortcuts.
.. _external_kittens:
Kittens created by kitty users

View File

@@ -1,6 +1,8 @@
kitty-diff - A fast side-by-side diff tool with syntax highlighting and images
kitty-diff
================================================================================
*A fast side-by-side diff tool with syntax highlighting and images*
.. highlight:: sh
Major Features
@@ -21,12 +23,10 @@ Major Features
.. figure:: ../screenshots/diff.png
:alt: Screenshot, showing a sample diff
:align: center
:scale: 100%
:width: 100%
Screenshot, showing a sample diff
.. contents::
Installation
---------------
@@ -34,7 +34,7 @@ Installation
Simply :ref:`install kitty <quickstart>`. You also need
to have either the `git <https://git-scm.com/>`_ program or the ``diff`` program
installed. Additionally, for syntax highlighting to work,
`pygments <http://pygments.org/>`_ must be installed (note that pygments is
`pygments <https://pygments.org/>`_ must be installed (note that pygments is
included in the macOS kitty app).
@@ -120,8 +120,8 @@ Why does this work only in kitty?
The diff kitten makes use of various features that are :doc:`kitty only
</protocol-extensions>`, such as the :doc:`kitty graphics protocol
</graphics-protocol>`, the :ref:`extended keyboard protocol
<extended-key-protocol>`, etc. It also leverages terminal program
</graphics-protocol>`, the :doc:`extended keyboard protocol
</keyboard-protocol>`, etc. It also leverages terminal program
infrastructure I created for all of kitty's other kittens to reduce the amount
of code needed (the entire implementation is under 2000 lines of code).
@@ -142,9 +142,6 @@ configuration directives.
.. include:: /generated/conf-kitten-diff.rst
Command Line Interface
-------------------------
.. include:: /generated/cli-kitten-diff.rst

View File

@@ -9,7 +9,7 @@ browser.
.. figure:: ../screenshots/hints_mode.png
:alt: URL hints mode
:align: center
:scale: 100%
:width: 100%
URL hints mode
@@ -28,11 +28,17 @@ to be used can be modified using options passed to the kitten. For example::
will open the selected file in a new tab inside neovim when you press
:kbd:`ctrl+g`.
Pressing :sc:`open_selected_hyperlink` will open hyperlinks, i.e. a URL
that has been marked as such by the program running in the terminal,
for example, by ``ls --hyperlink=auto``. You can also :doc:`customize what actions are
taken for different types of URLs <../open_actions>`.
The hints kitten is very powerful to see more detailed help on its various
options and modes of operation, see below. You can use these options to
create mappings in :file:`kitty.conf` to select various different text
snippets. See :sc:`insert_selected_path` for examples.
Completely customizing the matching and actions of the kitten
---------------------------------------------------------------
@@ -82,8 +88,14 @@ Now run kitty with::
When you press the :kbd:`F1` key you will be able to select a word to
look it up in the Google dictionary.
Command Line Interface
-------------------------
.. include:: ../generated/cli-kitten-hints.rst
.. note::
To avoid having to specify the same command line options on ever invocation,
you can use the :opt:`kitten_alias` option in :file:`kitty.conf` to create aliases
that have common sets of options. For example::
kitten_alias myhints hints --alphabet qfjdkslaureitywovmcxzpq1234567890
Documentation for the full set of options is below.

View File

@@ -1,11 +1,14 @@
Hyperlinked grep
=================
This kitten allows you to search your files using `ripgrep
<https://www.google.com/search?q=ripgrep>`_ and open the results
directly in your favorite editor in the terminal, at the line containing
the search result, simply by clicking on the result you want.
.. versionadded:: 0.19.0
To set it up, first create :file:`~/.config/kitty/open-actions.conf` with the
following contents:
@@ -55,7 +58,7 @@ Then, for example, for ZSH, add the following to :file:`.zshrc`::
compdef _rg hg
To learn more about kitty's powerful framework for customizing URL click
actions, :doc:`see here <../open_actions>`.
actions, :doc:`see here </open_actions>`.
Hopefully, someday this functionality will make it into some `upstream grep
<https://github.com/BurntSushi/ripgrep/issues/665>`_

View File

@@ -1,6 +1,8 @@
icat - Display images in the terminal
icat
========================================
*Display images in the terminal*
The ``icat`` kitten can be used to display arbitrary images in the |kitty|
terminal. Using it is as simple as::
@@ -35,7 +37,4 @@ The ``icat`` kitten has various command line arguments to allow it to be used
from inside other programs to display images. In particular, :option:`--place`,
:option:`--detect-support` and :option:`--print-window-size`.
Command Line Interface
--------------------------
.. include:: /generated/cli-kitten-icat.rst

View File

@@ -14,7 +14,7 @@ using terminal programs instead of GUI toolkits.
.. figure:: ../screenshots/panel.png
:alt: Screenshot, showing a sample panel
:align: center
:scale: 100%
:width: 100%
Screenshot, showing a sample panel
@@ -37,7 +37,4 @@ print out ``Hello, world!``. You can make the terminal program as complex as
you like, as demonstrated in the screenshot above.
Command Line Interface
-------------------------
.. include:: ../generated/cli-kitten-panel.rst

View File

@@ -0,0 +1,18 @@
Query terminal
=================
Used to query kitty from terminal programs about version, values of various
runtime options controlling its features, etc.
The querying is done using the (*semi*) standard XTGETTCAP escape sequence
pioneered by XTerm, so it works over SSH as well. The downside is that it
is slow, since it requires a roundtrip to the terminal emulator and back.
If you want to do some of the same querying in your terminal program without
depending on the kitten, you can do so, by processing the same escape codes.
Search `this page <https://invisible-island.net/xterm/ctlseqs/ctlseqs.html>`_
for *XTGETTCAP* to see the syntax for the escape code and read the source
of this kitten to find the values of the keys for the various queries.
.. include:: ../generated/cli-kitten-query_terminal.rst

View File

@@ -11,15 +11,18 @@ Then hold down :kbd:`ctrl+shift` and click the name of the file.
.. figure:: ../screenshots/remote_file.png
:alt: Remote file actions
:align: center
:scale: 100%
:width: 100%
Remote file actions
|kitty| will ask you what you want to do with the remote file. You can choose
to *Edit* it in which case kitty will download it and open it locally in your
``EDITOR``. As you make changes to the file, they are automatically transferred
to the remote computer. Note that this happens without needing to install *any*
special software on the server, beyond ``ls`` that supports hyperlinks.
:envvar:`EDITOR`. As you make changes to the file, they are automatically
transferred to the remote computer. Note that this happens without needing
to install *any* special software on the server, beyond ``ls`` that supports
hyperlinks.
.. versionadded:: 0.19.0
.. note::
Nested SSH sessions are not supported. The kitten will always try to copy

View File

@@ -7,7 +7,7 @@ Press :sc:`input_unicode_character` to start the unicode input widget, shown bel
.. figure:: ../screenshots/unicode.png
:alt: A screenshot of the unicode input widget
:align: center
:scale: 100%
:width: 100%
A screenshot of the unicode input widget
@@ -18,16 +18,14 @@ typing a leading period and then the two character index and pressing Enter.
The up and down arrow keys can be used to choose the previous and next unicode
symbol respectively.
In :guilabel:`Name` mode you instead type words from the character name and use the arrow
keys/tab to select the character from the displayed matches. You can also type
a leading period and the index for the match if you don't like to use arrow
keys.
In :guilabel:`Name` mode you instead type words from the character name and use
the arrow keys/tab to select the character from the displayed matches. You can
also type a space followed by a period and the index for the match if you don't
like to use arrow keys.
You can switch between modes using either the function keys or by pressing
:kbd:`Ctrl+[` and :kbd:`Ctrl+]`.
:kbd:`Ctrl+[` and :kbd:`Ctrl+]` or by pressing :kbd:`Ctrl+Tab` and
:kbd:`Ctrl+Shift+Tab`.
Command Line Interface
-------------------------
.. include:: ../generated/cli-kitten-unicode_input.rst

66
docs/kittens_intro.rst Normal file
View File

@@ -0,0 +1,66 @@
.. _kittens:
Extend with kittens
-----------------------
.. toctree::
:hidden:
:glob:
kittens/icat
kittens/diff
kittens/unicode-input
kittens/hints
kittens/remote_file
kittens/hyperlinked_grep
kittens/custom
kittens/*
|kitty| has a framework for easily creating terminal programs that make use of
its advanced features. These programs are called kittens. They are used both
to add features to |kitty| itself and to create useful standalone programs.
Some prominent kittens:
:doc:`icat <kittens/icat>`
Display images in the terminal
:doc:`diff <kittens/diff>`
A fast, side-by-side diff for the terminal with syntax highlighting and
images
:doc:`Unicode Input <kittens/unicode-input>`
Easily input arbitrary unicode characters in |kitty| by name or hex code.
:doc:`Hints <kittens/hints>`
Select and open/paste/insert arbitrary text snippets such as URLs,
filenames, words, lines, etc. from the terminal screen.
:doc:`Remote file <kittens/remote_file>`
Edit, open, or download remote files over SSH easily, by simply clicking on
the filename.
:doc:`Hyperlinked grep <kittens/hyperlinked_grep>`
Search your files using `ripgrep <https://github.com/BurntSushi/ripgrep>`_
and open the results directly in your favorite editor in the terminal,
at the line containing the search result, simply by clicking on the result you want.
:doc:`Broadcast <kittens/broadcast>`
Type in one :term:`kitty window <window>` and have it broadcast to all (or a subset) of
other :term:`kitty windows <window>`.
:doc:`Panel <kittens/panel>`
Draw a GPU accelerated dock panel on your desktop showing the output
from an arbitrary terminal program.
:doc:`Clipboard <kittens/clipboard>`
Copy/paste to the clipboard from shell scripts, even over SSH.
You can also :doc:`Learn to create your own kittens <kittens/custom>`.

View File

@@ -1,5 +1,5 @@
Launching programs in new windows/tabs
========================================
The :command:`launch` command
--------------------------------
.. program:: launch
@@ -19,7 +19,6 @@ launch::
map f1 launch vim path/to/some/file
To open a new window with the same working directory as the currently
active window::
@@ -29,6 +28,10 @@ To open the new window in a new tab::
map f1 launch --type=tab
To run multiple commands in a shell, use::
map f1 launch sh -c "ls && zsh"
To pass the contents of the current screen and scrollback to the started process::
map f1 launch --stdin-source=@screen_scrollback less
@@ -39,7 +42,7 @@ The piping environment
--------------------------
When using :option:`launch --stdin-source`, the program to which the data is
piped has a special environment variable declared, ``KITTY_PIPE_DATA`` whose
piped has a special environment variable declared, :envvar:`KITTY_PIPE_DATA` whose
contents are::
KITTY_PIPE_DATA={scrolled_by}:{cursor_x},{cursor_y}:{lines},{columns}
@@ -54,9 +57,34 @@ Special arguments
-------------------
There are a few special placeholder arguments that can be specified as part of
the command line. Namely ``@selection`` which is replaced by the current
selection and ``@active-kitty-window-id`` which is replaced by the id of the
currently active kitty window. For example::
the command line:
``@selection``
replaced by the currently selected text
``@active-kitty-window-id``
replaced by the id of the currently active kitty window
``@line-count``
replaced by the number of lines in STDIN. Only present when passing some
data to STDIN
``@input-line-number``
replaced the number of lines a pager should scroll to match the current
scroll position in kitty. See :opt:`scrollback_pager` for details
``@scrolled-by``
replaced by the number of lines kitty is currently scrolled by
``@cursor-x``
replaced by the current cursor x position with 1 being the leftmost cell
``@cursor-y``
replaced by the current cursor y position with 1 being the topmost cell
For example::
map f1 launch my-program @active-kitty-window-id
@@ -93,6 +121,16 @@ in the window and ``window.id`` is the internal kitty ``id`` of the
window.
Finding executables
-----------------------
When you specify a command to run as just a name rather than an absolute path,
it is searched for in the system-wide ``PATH`` environment variable. Note that
this **may not** be the value of ``PATH`` inside a shell, as shell startup scripts
often change the value of this variable. If it is not found there, then a
system specific list of default paths is searched. If it is still not found,
then your shell is run and the value of ``PATH`` inside the shell is used.
Syntax reference
------------------

View File

@@ -1,5 +1,5 @@
Layouts
============
Arrange windows
-------------------
kitty has the ability to define its own windows that can be tiled next to each
other in arbitrary arrangements, based on *Layouts*, see below for examples:
@@ -8,7 +8,7 @@ other in arbitrary arrangements, based on *Layouts*, see below for examples:
.. figure:: screenshots/screenshot.png
:alt: Screenshot, showing three programs in the 'Tall' layout
:align: center
:scale: 100%
:width: 100%
Screenshot, showing vim, tig and git running in |kitty| with the 'Tall' layout
@@ -16,7 +16,7 @@ other in arbitrary arrangements, based on *Layouts*, see below for examples:
.. figure:: screenshots/splits.png
:alt: Screenshot, showing windows in the 'Splits' layout
:align: center
:scale: 100%
:width: 100%
Screenshot, showing windows with arbitrary arrangement in the 'Splits'
layout
@@ -27,8 +27,6 @@ you can switch layouts using :sc:`next_layout`. To control which layouts
are available use :opt:`enabled_layouts`, the first listed layout becomes
the default. Individual layouts and how to use them are described below.
.. contents::
The Stack Layout
------------------
@@ -171,6 +169,8 @@ are placed into vertical or horizontal splits, by default::
│ │ │
└──────────────┴───────────────┘
.. versionadded:: 0.17.0
The Splits layout
The Horizontal Layout

View File

@@ -1,11 +1,14 @@
Marks
=================
Mark text on screen
---------------------
kitty has the ability to mark text on the screen based on regular expressions.
This can be useful to highlight words or phrases when browsing output from long
running programs or similar. Lets start with a few examples:
Examples
----------
Suppose we want to be able to highlight the word ERROR in the current window.
Add the following to :file:`kitty.conf`::
@@ -19,12 +22,12 @@ If you want to make it case-insensitive, use::
To make it match only complete words, use::
map f1 toggle_marker regex 1 \bERROR\b
map f1 toggle_marker regex 1 \\bERROR\\b
Suppose you want to highlight both :code:`ERROR` and :code:`WARNING`, case
insensitively::
map f1 toggle_marker iregex 1 \bERROR\b 2 \bWARNING\b
map f1 toggle_marker iregex 1 \\bERROR\\b 2 \\bWARNING\\b
kitty supports up to 3 mark groups (the numbers in the commands above). You
can control the colors used for these groups in :file:`kitty.conf` with::
@@ -89,12 +92,11 @@ The syntax of the :code:`toggle_marker` command is::
Here :code:`marker-type` is one of:
* :code:`text` - simple substring matching
* :code:`itext` - case-insensitive substring matching
* :code:`regex` - A python regular expression
* :code:`iregex` - A case-insensitive python regular expression
* :code:`function` - An arbitrary function defined in a python file, see
:ref:`marker_funcs`.
* :code:`text` - simple substring matching
* :code:`itext` - case-insensitive substring matching
* :code:`regex` - A python regular expression
* :code:`iregex` - A case-insensitive python regular expression
* :code:`function` - An arbitrary function defined in a python file, see :ref:`marker_funcs`.
.. _marker_funcs:

View File

@@ -1,10 +1,11 @@
Customizing the actions taken when clicking on links
Scripting the mouse click
======================================================
|kitty| has support for `terminal hyperlinks <https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda>`_. These
|kitty| has support for `terminal hyperlinks
<https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda>`_. These
are generated by many terminal programs, such as ``ls``, ``gcc``, ``systemd``,
``mdcat``, etc. You can customize exactly what happens when clicking on these hyperlinks
in |kitty|.
:ref:`tool_mdcat`, etc. You can customize exactly what happens when clicking on these
hyperlinks in |kitty|.
You can tell kitty to take arbitrarily many, complex actions
when a link is clicked. Let us illustrate with some examples, first. Create
@@ -63,7 +64,7 @@ Matching criteria
------------------
An entry in :file:`open-actions.conf` must have one or more matching criteria.
URLs that match all criteria for an entry will trigger that entries' actions.
URLs that match all criteria for an entry will trigger that entry's actions.
Processing stops at the first matching entry, so put more specific matching
criteria at the start of the list. Entries in the file are separated by blank
lines. The various available criteria are:
@@ -81,7 +82,11 @@ lines. The various available criteria are:
``mime``
A comma separated list of MIME types, for example: ``text/*, image/*,
application/pdf``
application/pdf``. You can add MIME types to kitty by creating the
:file:`mime.types` in the kitty configuration directory. Useful if your
system MIME database does not have definitions you need. This file is
in the standard format of one definition per line, like: ``text/plain rst
md``. Note that the MIME type for directories is ``inode/directory``.
``ext``
A comma separated list of file extensions, for example: ``jpeg, tar.gz``

283
docs/overview.rst Normal file
View File

@@ -0,0 +1,283 @@
Overview
==============
Design philosophy
-------------------
|kitty| is designed for power keyboard users. To that end all its controls
work with the keyboard (although it fully supports mouse interactions as
well). Its configuration is a simple, human editable, single file for
easy reproducibility (I like to store configuration in source control).
The code in |kitty| is designed to be simple, modular and hackable. It is
written in a mix of C (for performance sensitive parts) and Python (for
easy hackability of the UI). It does not depend on any large and complex
UI toolkit, using only OpenGL for rendering everything.
Finally, |kitty| is designed from the ground up to support all modern
terminal features, such as unicode, true color, bold/italic fonts, text
formatting, etc. It even extends existing text formatting escape codes,
to add support for features not available elsewhere, such as colored and
styled (curly) underlines. One of the design goals of |kitty| is to be
easily extensible so that new features can be added in the future with
relatively little effort.
.. include:: basic.rst
Configuring kitty
-------------------
|kitty| is highly configurable, everything from keyboard shortcuts to
painting frames-per-second. Press :sc:`edit_config_file` in kitty
to open its fully commented sample config file in your text editor.
For details see the :doc:`configuration docs <conf>`.
.. toctree::
:hidden:
conf
.. _layouts:
Layouts
----------
A :term:`layout` is an arrangement of multiple :term:`kitty windows <window>`
inside a top-level :term:`OS window <os_window>`. The layout manages all its
windows automatically, resizing and moving them as needed. You can create a new
:term:`window` using the :sc:`new_window` key combination.
Currently, there are seven layouts available:
* **Fat** -- One (or optionally more) windows are shown full width on the top, the rest of the windows are shown side-by-side on the bottom
* **Grid** -- All windows are shown in a grid
* **Horizontal** -- All windows are shown side-by-side
* **Splits** -- Windows arranged in arbitrary patterns created using horizontal and vertical splits
* **Stack** -- Only a single maximized window is shown at a time
* **Tall** -- One (or optionally more) windows are shown full height on the left, the rest of the windows are shown one below the other on the right
* **Vertical** -- All windows are shown one below the other
By default, all layouts are enabled and you can switch between layouts using
the :sc:`next_layout` key combination. You can also create shortcuts to select
particular layouts, and choose which layouts you want to enable/disable, see
:ref:`conf-kitty-shortcuts.layout` for examples. The first layout listed in
:opt:`enabled_layouts` becomes the default layout.
For more details on the layouts and how to use them see :doc:`the documentation
<layouts>`.
.. toctree::
:hidden:
layouts
Extending kitty
------------------
kitty has a powerful framework for scripting. You can create small terminal
programs called :doc:`kittens <kittens_intro>`. These can used to add features
to kitty, for example, :doc:`editing remote files <kittens/remote_file>` or
:doc:`inputting unicode characters <kittens/unicode-input>`. They can also be
used to create programs that leverage kitty's powerful features, for example,
:doc:`viewing images <kittens/icat>` or :doc:`diffing files with images
<kittens/diff>`.
You can :doc:`create your own kittens to scratch your own itches
<kittens/custom>`.
For a list of all the builtin kittens, :ref:`see here <kittens>`.
.. toctree::
:hidden:
kittens_intro
Remote control
------------------
|kitty| has a very powerful system that allows you to control it from the
:doc:`shell prompt, even over SSH <remote-control>`. You can change colors,
fonts, open new :term:`windows <window>`, :term:`tabs <tab>`, set their titles,
change window layout, get text
from one window and send text to another, etc, etc. The possibilities are
endless. See the :doc:`tutorial <remote-control>` to get started.
.. toctree::
:hidden:
remote-control
.. _sessions:
Startup Sessions
------------------
You can control the :term:`tabs <tab>`, `:term:`kitty window <window>` layout,
working directory, startup programs,
etc. by creating a "session" file and using the :option:`kitty --session`
command line flag or the :opt:`startup_session` option in :file:`kitty.conf`.
For example:
.. code-block:: session
# Set the layout for the current tab
layout tall
# Set the working directory for windows in the current tab
cd ~
# Create a window and run the specified command in it
launch zsh
# Create a window with some environment variables set and run
# vim in it
launch --env FOO=BAR vim
# Set the title for the next window
launch --title "Chat with x" irssi --profile x
# Create a new tab (the part after new_tab is the optional tab
# name which will be displayed in the tab bar, if omitted, the
# title of the active window will be used instead)
new_tab my tab
cd ~/somewhere
# Set the layouts allowed in this tab
enabled_layouts tall, stack
# Set the current layout
layout stack
launch zsh
# Create a new OS window
new_os_window
# set new window size to 80x25 cells
os_window_size 80c 25c
# set the --class for the new OS window
os_window_class mywindow
launch sh
# Make the current window the active (focused) window
focus
launch emacs
.. note::
The :doc:`launch <launch>` command when used in a session file
cannot create new OS windows, or tabs.
Creating tabs/windows
-------------------------------
kitty can be told to run arbitrary programs in new :term:`tabs <tab>`,
:term:`windows <window>` or :term:`overlays <overlay>` at a keypress.
To learn how to do this, see :doc:`here <launch>`.
.. toctree::
:hidden:
launch
Mouse features
-------------------
* You can click on a URL to open it in a browser.
* You can double click to select a word and then drag to select more words.
* You can triple click to select a line and then drag to select more lines.
* You can triple click while holding :kbd:`ctrl+alt` to select from clicked
point to end of line.
* You can right click to extend a previous selection.
* You can hold down :kbd:`ctrl+alt` and drag with the mouse to select in
columns.
* Selecting text automatically copies it to the primary clipboard (on
platforms with a primary clipboard).
* You can middle click to paste from the primary clipboard (on platforms
with a primary clipboard).
* You can select text with kitty even when a terminal program has grabbed
the mouse by holding down the :kbd:`shift` key.
All these actions can be customized in :file:`kitty.conf` as described
:ref:`here <conf-kitty-mouse.mousemap>`.
You can also customize what happens when clicking on :term:`hyperlinks` in kitty,
having it open files in your editor, download remote files, open things
in your browser, etc.
For details, see :doc:`here <open_actions>`.
.. toctree::
:hidden:
open_actions
Font control
-----------------
|kitty| has extremely flexible and powerful font selection features. You can
specify individual families for the regular, bold, italic and bold+italic
fonts. You can even specify specific font families for specific ranges of
unicode characters. This allows precise control over text rendering. It can
come in handy for applications like powerline, without the need to use patched
fonts. See the various font related configuration directives in
:ref:`conf-kitty-fonts`.
.. _scrollback:
The scrollback buffer
-----------------------
|kitty| supports scrolling back to view history, just like most terminals. You
can use either keyboard shortcuts or the mouse scroll wheel to do so. However,
|kitty| has an extra, neat feature. Sometimes you need to explore the
scrollback buffer in more detail, maybe search for some text or refer to it
side-by-side while typing in a follow-up command. |kitty| allows you to do this
by pressing the :sc:`show_scrollback` key-combination, which will open the
scrollback buffer in your favorite pager program (which is ``less`` by default).
Colors and text formatting are preserved. You can explore the scrollback buffer
comfortably within the pager.
Additionally, you can pipe the contents of the scrollback buffer to an
arbitrary, command running in a new :term:`window`, :term:`tab` or :term:`overlay`,
for example::
map f1 launch --stdin-source=@screen_scrollback --stdin-add-formatting less +G -R
Would open the scrollback buffer in a new :term:`window` when you press the :kbd:`F1`
key. See :sc:`show_scrollback` for details.
If you want to use it with an editor such as vim to get more powerful features,
you can see tips for doing so, in
`this thread <https://github.com/kovidgoyal/kitty/issues/719>`_.
If you wish to store very large amounts of scrollback to view using the piping or
:sc:`show_scrollback` features, you can use the :opt:`scrollback_pager_history_size`
option.
.. _cpbuf:
Multiple copy/paste buffers
-----------------------------
In addition to being able to copy/paste from the system clipboard, in |kitty| you
can also setup an arbitrary number of copy paste buffers. To do so, simply add
something like the following to your :file:`kitty.conf`::
map f1 copy_to_buffer a
map f2 paste_from_buffer a
This will allow you to press :kbd:`F1` to copy the current selection to an
internal buffer named ``a`` and :kbd:`F2` to paste from that buffer. The buffer
names are arbitrary strings, so you can define as many such buffers as you
need.
Marks
-------------
kitty has the ability to mark text on the screen based on regular expressions.
This can be useful to highlight words or phrases when browsing output from long
running programs or similar. To learn how this feature works, see :doc:`marks`.
.. toctree::
:hidden:
marks

View File

@@ -1,4 +1,4 @@
|kitty| Performance
Performance
===================
The main goals for |kitty| performance are user perceived latency while typing

View File

@@ -1,3 +1,5 @@
:orphan:
Working with the screen and history buffer contents
======================================================

View File

@@ -1,7 +1,7 @@
Extensions to the xterm protocol
Terminal protocol extensions
===================================
|kitty| has a few extensions to the xterm protocol, to enable advanced features.
|kitty| has extensions to the legacy terminal protocol, to enable advanced features.
These are typically in the form of new or re-purposed escape codes. While these
extensions are currently |kitty| specific, it would be nice to get some of them
adopted more broadly, to push the state of terminal emulators forward.
@@ -16,339 +16,17 @@ is to make it as easy to implement these protocol extensions as possible,
thereby hopefully encouraging their widespread adoption.
If you wish to discuss these extensions, propose additions/changes to them
please do so by opening issues in the github bug tracker.
please do so by opening issues in the `GitHub
<https://github.com/kovidgoyal/kitty/issues>`_ bug tracker.
.. contents::
Colored and styled underlines
-------------------------------
.. toctree::
:maxdepth: 1
|kitty| supports colored and styled (wavy) underlines. This is of particular
use in terminal editors such as vim and emacs to display red, wavy underlines
under mis-spelled words and/or syntax errors. This is done by re-purposing some
SGR escape codes that are not used in modern terminals (`CSI codes
<https://en.wikipedia.org/wiki/ANSI_escape_code#CSI_sequences>`_)
To set the underline style::
<ESC>[4:0m # this is no underline
<ESC>[4:1m # this is a straight underline
<ESC>[4:2m # this is a double underline
<ESC>[4:3m # this is a curly underline
<ESC>[4:4m # this is a dotted underline (not implemented in kitty)
<ESC>[4:5m # this is a dashed underline (not implemented in kitty)
<ESC>[4m # this is a straight underline (for backwards compat)
<ESC>[24m # this is no underline (for backwards compat)
To set the underline color (this is reserved and as far as I can tell not actually used for anything)::
<ESC>[58...m
This works exactly like the codes ``38, 48`` that are used to set foreground and
background color respectively.
To reset the underline color (also previously reserved and unused)::
<ESC>[59m
The underline color must remain the same under reverse video, if it has a
color, if not, it should follow the foreground color.
To detect support for this feature in a terminal emulator, query the terminfo database
for the ``Su`` boolean capability.
Graphics rendering
---------------------
See :doc:`/graphics-protocol` for a description
of this protocol to enable drawing of arbitrary raster images in the terminal.
.. _extended-key-protocol:
Keyboard handling
-------------------
There are various problems with the current state of keyboard handling. They
include:
* No way to use modifiers other than ``Ctrl`` and ``Alt``
* No way to reliably use multiple modifier keys, other than, ``Shift+Alt``.
* No way to handle different types of keyboard events, such as press, release or repeat
* No reliable way to distinguish single ``Esc`` keypresses from the start of a
escape sequence. Currently, client programs use fragile timing related hacks
for this, leading to bugs, for example:
`neovim #2035 <https://github.com/neovim/neovim/issues/2035>`_.
There are already two distinct keyboard handling modes, *normal mode* and
*application mode*. These modes generate different escape sequences for the
various special keys (arrow keys, function keys, home/end etc.) Most terminals
start out in normal mode, however, most shell programs like ``bash`` switch them to
application mode. We propose adding a third mode, named *full mode* that addresses
the shortcomings listed above.
Switching to the new *full mode* is accomplished using the standard private
mode DECSET escape sequence::
<ESC>[?2017h
and to leave *full mode*, use DECRST::
<ESC>[?2017l
The number ``2017`` above is not used for any existing modes, as far as I know.
Client programs can query if the terminal emulator is in *full mode* by using
the standard `DECRQM <https://vt100.net/docs/vt510-rm/DECRQM.html>`_ escape sequence.
The new mode works as follows:
* All printable key presses without modifier keys are sent just as in the
*normal mode*. This means all printable ASCII characters and in addition,
``Enter``, ``Space`` and ``Backspace``. Also any unicode characters generated by
platform specific extended input modes, such as using the ``AltGr`` key. This
is done so that client programs that are not aware of this mode can still
handle basic text entry, so if a *full mode* using program crashes and does
not reset, the user can still issue a ``reset`` command in the shell to restore
normal key handling. Note that this includes pressing the ``Shift`` modifier
and printable keys. Note that this means there are no repeat and release
events for these keys and also for the left and right shift keys.
* For non printable keys and key combinations including one or more modifiers,
an escape sequence encoding the key event is sent. For details on the
escape sequence, see below.
The escape sequence encodes the following properties:
* Type of event: ``press,repeat,release``
* Modifiers pressed at the time of the event
* The actual key being pressed
Schematically::
<ESC>_K<type><modifiers><key><ESC>\
Where ``<type>`` is one of ``p`` -- press, ``r`` -- release and ``t`` -- repeat.
Modifiers is a bitmask represented as a single base64 digit. Shift -- ``0x1``,
Alt -- ``0x2``, Control -- ``0x4`` and Super -- ``0x8``. ``<key>`` is a number
(encoded in base85) corresponding to the key pressed. The key name to number
mapping is defined in :doc:`this table <key-encoding>`.
Client programs must ignore events for keys they do not know. The mapping in
the above table is stable and will never change, however, new codes might be
added to it in the future, for new keys.
For example::
<ESC>_KpGp<ESC>\ is <Ctrl>+<Alt>+x (press)
<ESC>_KrP8<ESC>\ is <Ctrl>+<Alt>+<Shift>+<Super>+PageUp (release)
This encoding means each key event is represented by 8 or 9 printable ascii
only bytes, for maximum robustness.
To see the full mode in action, run::
kitty +kitten key_demo
Support for this mode is indicated by the ``fullkbd`` boolean capability
in the terminfo database, in case querying for it via DECQRM is inconvenient.
.. _ext_styles:
Setting text styles/colors in arbitrary regions of the screen
------------------------------------------------------------------
There already exists an escape code to set *some* text attributes in arbitrary
regions of the screen, `DECCARA
<https://vt100.net/docs/vt510-rm/DECCARA.html>`_. However, it is limited to
only a few attributes. |kitty| extends this to work with *all* SGR attributes.
So, for example, this can be used to set the background color in an arbitrary
region of the screen.
The motivation for this extension is the various problems with the existing
solution for erasing to background color, namely the *background color erase
(bce)* capability. See
`this discussion <https://github.com/kovidgoyal/kitty/issues/160#issuecomment-346470545>`_
and `this FAQ <https://invisible-island.net/ncurses/ncurses.faq.html#bce_mismatches>`_
for a summary of problems with *bce*.
For example, to set the background color to blue in a
rectangular region of the screen from (3, 4) to (10, 11), you use::
<ESC>[2*x<ESC>[4;3;11;10;44$r<ESC>[*x
Saving and restoring the default foreground/background/selection/cursor colors
---------------------------------------------------------------------------------
It is often useful for a full screen application with its own color themes
to set the default foreground, background, selection and cursor colors. This
allows for various performance optimizations when drawing the screen. The
problem is that if the user previously used the escape codes to change these
colors herself, then running the full screen application will lose her
changes even after it exits. To avoid this, kitty introduces a new pair of
*OSC* escape codes to push and pop the current color values from a stack::
<ESC>]30001<ESC>\ # push onto stack
<ESC>]30101<ESC>\ # pop from stack
These escape codes save/restore the so called *dynamic colors*, default
background, default foreground, selection background, selection foreground and
cursor color.
Pasting to clipboard
----------------------
|kitty| implements the OSC 52 escape code protocol to get/set the clipboard
contents (controlled via the :opt:`clipboard_control` setting). There is one
difference in kitty's implementation compared to some other terminal emulators.
|kitty| allows sending arbitrary amounts of text to the clipboard. It does so
by modifying the protocol slightly. Successive OSC 52 escape codes to set the
clipboard will concatenate, so::
<ESC>]52;c;<payload1><ESC>\
<ESC>]52;c;<payload2><ESC>\
will result in the clipboard having the contents ``payload1 + payload2``. To
send a new string to the clipboard send an OSC 52 sequence with an invalid payload
first, for example::
<ESC>]52;c;!<ESC>\
Here ``!`` is not valid base64 encoded text, so it clears the clipboard.
Further, since it is invalid, it should be ignored by terminal emulators
that do not support this extension, thereby making it safe to use, simply
always send it before starting a new OSC 52 paste, even if you aren't chunking
up large pastes, that way kitty won't concatenate your paste, and it will have
no ill-effects in other terminal emulators.
In case you're using software that can't be easily adapted to this
protocol extension, it can be disabled by specifying ``no-append`` to the
:opt:`clipboard_control` setting.
.. _desktop_notifications:
Desktop notifications
---------------------------------
|kitty| implements an extensible escape code (OSC 99) to show desktop
notifications. It is easy to use from shell scripts and fully extensible to
show title and body. Clicking on the notification can optionally focus the
window it came from, and/or send an escape code back to the application running
in that window.
The design of the escape code is partially based on the discussion in
the defunct
`terminal-wg <https://gitlab.freedesktop.org/terminal-wg/specifications/-/issues/13>`_
The escape code has the form::
<OSC> 99 ; metadata ; payload <terminator>
Here ``<OSC>`` is :code:`<ESC>]` and ``<terminator>`` is
:code:`<ESC><backslash>`. The metadata is a section of colon separated
:code:`key=value` pairs. Every key must be a single character from the set
:code:`a-zA-Z` and every value must be a word consisting of characters from
the set :code:`a-zA-Z0-9-_/\+.,(){}[]*&^%$#@!`~`. The payload must be
interpreted based on the metadata section. The two semi-colons *must* always be
present even when no metadata is present.
Before going into details, lets see how one can display a simple, single line
notification from a shell script::
printf '\x1b]99;;Hello world\x1b\\'
To show a message with a title and a body::
printf '\x1b]99;i=1:d=0;Hello world\x1b\\'
printf '\x1b]99;i=1:d=1:p=body;This is cool\x1b\\'
The most important key in the metadata is the ``p`` key, it controls how the
payload is interpreted. A value of ``title`` means the payload is setting the
title for the notification. A value of ``body`` means it is setting the body,
and so on, see the table below for full details.
The design of the escape code is fundamentally chunked, this is because
different terminal emulators have different limits on how large a single escape
code can be. Chunking is accomplished by the ``i`` and ``d`` keys. The ``i``
key is the *notification id* which can be any string containing the characters
``[a-zA-Z0-9_-+.]``. The ``d`` key stands for *done* and
can only take the values ``0`` and ``1``. A value of ``0`` means the
notification is not yet done and the terminal emulator should hold off
displaying it. A value of ``1`` means the notification is done, and should be
displayed. You can specify the title or body multiple times and the terminal
emulator will concatenate them, thereby allowing arbitrarily long text
(terminal emulators are free to impose a sensible limit to avoid
Denial-of-Service attacks).
Both the ``title`` and ``body`` payloads must be either UTF-8 encoded plain
text with no embedded escape codes, or UTF-8 text that is base64 encoded, in
which case there must be an ``e=1`` key in the metadata to indicate the payload
is base64 encoded.
When the user clicks the notification, a couple of things can happen, the
terminal emulator can focus the window from which the notification came, and/or
it can send back an escape code to the application indicating the notification
was activated. This is controlled by the ``a`` key which takes a comma
separated set of values, ``report`` and ``focus``. The value ``focus`` means
focus the window from which the notification was issued and is the default.
``report`` means send an escape code back to the application. The format of the
returned escape code is::
<OSC> 99 ; i=identifier ; <terminator>
The value of ``identifier`` comes from the ``i`` key in the escape code sent by
the application. If the application sends no identifier, then the terminal
*must* use ``i=0``. Actions can be preceded by a negative sign to turn them
off, so for example if you do not want any action, turn off the default
``focus`` action with::
a=-focus
Complete specification of all the metadata keys is in the table below. If a
terminal emulator encounters a key in the metadata it does not understand,
the key *must* be ignored, to allow for future extensibility of this escape
code. Similarly if values for known keys are unknown, the terminal emulator
*should* either ignore the entire escape code or perform a best guess effort
to display it based on what it does understand.
.. note::
It is possible to extend this escape code to allow specifying an icon for
the notification, however, given that some platforms, such as macOS, dont
allow displaying custom icons on a notification, at all, it was decided to
leave it out of the spec for the time being.
Similarly, features such as scheduled notifications could be added in future
revisions.
======= ==================== ========= =================
Key Value Default Description
======= ==================== ========= =================
``a`` Comma separated list ``focus`` What action to perform when the
of ``report``, notification is clicked
``focus``, with
optional leading
``-``
``d`` ``0`` or ``1`` ``1`` Indicates if the notification is
complete or not.
``e`` ``0`` or ``1`` ``0`` If set to ``1`` means the payload is base64 encoded UTF-8,
otherwise it is plain UTF-8 text with no C0 control codes in it
``i`` ``[a-zA-Z0-9-_+.]`` ``0`` Identifier for the notification
``p`` One of ``title`` or ``title`` Whether the payload is the notification title or body. If a
``body``. notification has no title, the body will be used as title.
======= ==================== ========= =================
.. note::
|kitty| also supports the legacy OSC 9 protocol developed by iTerm2 for
desktop notifications.
underlines
graphics-protocol
keyboard-protocol
desktop-notifications
unscroll
color-stack
deccara

28
docs/quickstart.rst Normal file
View File

@@ -0,0 +1,28 @@
.. _quickstart:
Quickstart
===========
.. toctree::
:hidden:
binary
build
Pre-built binaries of |kitty| are available for both macOS and Linux.
See the :doc:`binary install instructions </binary>`. You can also
:doc:`build from source </build>`.
Additionally, you can use your favorite package manager to install the |kitty|
package, but note that some Linux distribution packages are woefully outdated.
|kitty| is available in a vast number of package repositories for macOS
and Linux.
.. image:: https://repology.org/badge/tiny-repos/kitty.svg
:target: https://repology.org/project/kitty/versions
:alt: Number of repositories kitty is available in
See :doc:`Configuring kitty <conf>` for help on configuring |kitty| and
:doc:`Invocation <invocation>` for the command line arguments |kitty| supports.
For a tour of kitty's design and features, see the :doc:`/overview`.

View File

@@ -1,5 +1,5 @@
Documentation for the kitty remote control protocol
======================================================
The kitty remote control protocol
==================================
The kitty remote control protocol is a simple protocol that involves sending
data to kitty in the form of JSON. Any individual command of kitty has the
@@ -12,7 +12,7 @@ Where ``<ESC>`` is the byte ``0x1b``. The JSON object has the form::
{
"cmd": "command name",
"version": <kitty version>,
"no_response": Optional Boolean,
"no_response": <Optional Boolean>,
"payload": <Optional JSON object>,
}
@@ -26,4 +26,15 @@ Set ``no_response`` to ``true`` if you don't want a response from kitty.
The optional payload is a JSON object that is specific to the actual command being sent.
The fields in the object for every command are documented below.
As a quick example showing how easy to use this protocol is, we will implement
the ``@ ls`` command from the shell using only shell tools. First, run kitty
as::
kitty -o allow_remote_control=socket-only --listen-on unix:/tmp/test
Now, in a different terminal, you can get the pretty printed ``@ ls`` output
with the following command line::
echo -en '\eP@kitty-cmd{"cmd":"ls","version":[0,14,2]}\e\' | socat - unix:/tmp/test | awk '{ print substr($0, 13, length($0) - 14) }' | jq -c '.data | fromjson' | jq .
.. include:: generated/rc.rst

View File

@@ -1,17 +1,15 @@
:tocdepth: 2
Controlling kitty from scripts or the shell
==============================================
Control kitty from scripts
----------------------------
.. highlight:: sh
Tutorial
----------
|kitty| can be controlled from scripts or the shell prompt. You can open new
windows, send arbitrary text input to any window, name windows and tabs, etc.
Let's walk through a few examples of controlling |kitty|.
Tutorial
------------
Start by running |kitty| as::
kitty -o allow_remote_control=yes -o enabled_layouts=tall
@@ -115,8 +113,10 @@ shell. Run ``kitty @`` with no arguments and you will be dropped into the |kitty
shell with completion for |kitty| command names and options.
You can even open the |kitty| shell inside a running |kitty| using a simple
keyboard shortcut (:sc:`kitty_shell` by default). This has the added
advantage that you don't need to use ``allow_remote_control`` to make it work.
keyboard shortcut (:sc:`kitty_shell` by default).
.. note:: This has the added advantage that you don't need to use
``allow_remote_control`` to make it work.
Allowing only some windows to control kitty
@@ -134,6 +134,14 @@ still write to the pipes of any other program on the same computer and
therefore can control |kitty|. It can, however, be useful to block programs
running on other computers (for example, over ssh) or as other users.
.. note:: You dont need ``allow_remote_control`` to make this work as it is
limited to only programs running in that specific window. Be careful with
what programs you run in such windows, since they can effectively control
kitty, as if you were running with ``allow_remote_control`` turned on.
.. _rc_mapping:
Mapping key presses to remote control commands
--------------------------------------------------
@@ -146,11 +154,33 @@ Then pressing the :kbd:`F1` key will set the active window margins to 30.
The syntax for what follows :code:`remote_control` is exactly the same
as the syntax for what follows :code:`kitty @` above.
.. note:: You do not need ``allow_remote_control`` to use these mappings,
as they are not actual remote programs, but are simply a way to resuse
the remote control infrastructure via keybings.
Documentation for the remote control protocol
Broadcasting what you type to all kitty windows
--------------------------------------------------
As a simple illustration of the power of remote control, lets
have what we type sent to all open kitty windows. To do that define the
following mapping in :file:`kitty.conf`::
map F1 launch --allow-remote-control kitty +kitten broadcast
Now press, F1 and start typing, what you type will be sent to all windows,
live, as you type it.
The remote control protocol
-----------------------------------------------
If you wish to develop your own client to talk to |kitty|, you
can use the :doc:`rc_protocol`.
can use the :doc:`protocol specification <rc_protocol>`.
.. toctree::
:hidden:
rc_protocol
.. include:: generated/cli-kitty-at.rst

5
docs/requirements.txt Normal file
View File

@@ -0,0 +1,5 @@
sphinx
furo
sphinx-copybutton
sphinxext-opengraph
sphinx-inline-tabs

36
docs/underlines.rst Normal file
View File

@@ -0,0 +1,36 @@
Colored and styled underlines
================================
|kitty| supports colored and styled (wavy) underlines. This is of particular
use in terminal editors such as vim and emacs to display red, wavy underlines
under mis-spelled words and/or syntax errors. This is done by re-purposing some
SGR escape codes that are not used in modern terminals (`CSI codes
<https://en.wikipedia.org/wiki/ANSI_escape_code#CSI_(Control_Sequence_Introducer)_sequences>`_)
To set the underline style::
<ESC>[4:0m # this is no underline
<ESC>[4:1m # this is a straight underline
<ESC>[4:2m # this is a double underline
<ESC>[4:3m # this is a curly underline
<ESC>[4:4m # this is a dotted underline (not implemented in kitty)
<ESC>[4:5m # this is a dashed underline (not implemented in kitty)
<ESC>[4m # this is a straight underline (for backwards compat)
<ESC>[24m # this is no underline (for backwards compat)
To set the underline color (this is reserved and as far as I can tell not actually used for anything)::
<ESC>[58...m
This works exactly like the codes ``38, 48`` that are used to set foreground and
background color respectively.
To reset the underline color (also previously reserved and unused)::
<ESC>[59m
The underline color must remain the same under reverse video, if it has a
color, if not, it should follow the foreground color.
To detect support for this feature in a terminal emulator, query the terminfo database
for the ``Su`` boolean capability.

34
docs/unscroll.rst Normal file
View File

@@ -0,0 +1,34 @@
.. _unscroll:
Unscrolling the screen
========================
This is a small extension to the `SD (Pan up) escape code
<https://vt100.net/docs/vt510-rm/SD.html>`_ from the VT-420 terminal. The
``SD`` escape code normally causes the text on screen to scroll down by the
specified number of lines, with empty lines appearing at the top of the screen.
This extension allows the new lines to be filled in from the scrollback buffer
instead of being blank.
The motivation for this is that many modern shells will show completions in a
block of lines under the cursor, this causes some of the on-screen text to be
lost even after the completion is completed, because it has scrolled off
screen. This escape code allows that text to be restored.
If the scrollback buffer is empty or there is no scrollback buffer, such as for
the alternate screen, then the newly inserted lines must be empty, just as with
the original ``SD`` escape code. The maximum number of lines that can be
scrolled down is implementation defined, but must be at least one screen worth.
The syntax of the escape code is identical to that of ``SD`` except that it has
a trailing ``+`` modifier. This is legal under the `ECMA 48 standard
<https://www.ecma-international.org/publications-and-standards/standards/ecma-48/>`_
and unused for any other purpose as far as I can tell. So for example, to
unscroll three lines, the escape code would be::
CSI 3 + T
See `discussion here
<https://gitlab.freedesktop.org/terminal-wg/specifications/-/issues/30>`_.
.. versionadded:: 0.20.2

View File

@@ -250,13 +250,16 @@ def write_header(text: str, path: str) -> None:
def graphics_parser() -> None:
flag = frozenset
keymap: KeymapType = {
'a': ('action', flag('tTqpd')),
'd': ('delete_action', flag('aAiIcCpPqQxXyYzZ')),
'a': ('action', flag('tTqpdfac')),
'd': ('delete_action', flag('aAiIcCfFnNpPqQxXyYzZ')),
't': ('transmission_type', flag('dfts')),
'o': ('compressed', flag('z')),
'f': ('format', 'uint'),
'm': ('more', 'uint'),
'i': ('id', 'uint'),
'I': ('image_number', 'uint'),
'p': ('placement_id', 'uint'),
'q': ('quiet', 'uint'),
'w': ('width', 'uint'),
'h': ('height', 'uint'),
'x': ('x_offset', 'uint'),
@@ -270,6 +273,7 @@ def graphics_parser() -> None:
'X': ('cell_x_offset', 'uint'),
'Y': ('cell_y_offset', 'uint'),
'z': ('z_index', 'int'),
'C': ('cursor_movement', 'uint'),
}
text = generate('parse_graphics_code', 'screen_handle_graphics_command', 'graphics_command', keymap, 'GraphicsCommand')
write_header(text, 'kitty/parse-graphics-command.h')

17
gen-config.py Executable file
View File

@@ -0,0 +1,17 @@
#!/usr/bin/env python
# vim:fileencoding=utf-8
# License: GPLv3 Copyright: 2021, Kovid Goyal <kovid at kovidgoyal.net>
from kitty.conf.generate import write_output
def main() -> None:
from kitty.options.definition import definition
write_output('kitty', definition)
from kittens.diff.options.definition import definition as kd
write_output('kittens.diff', kd)
if __name__ == '__main__':
main()

412
gen-key-constants.py Executable file
View File

@@ -0,0 +1,412 @@
#!/usr/bin/env python
# vim:fileencoding=utf-8
# License: GPLv3 Copyright: 2021, Kovid Goyal <kovid at kovidgoyal.net>
import string
from typing import Dict, List, Any
from pprint import pformat
functional_key_defs = '''# {{{
# kitty XKB macVK macU
escape Escape 0x35 -
enter Return 0x24 NSCarriageReturnCharacter
tab Tab 0x30 NSTabCharacter
backspace BackSpace 0x33 NSBackspaceCharacter
insert Insert 0x72 Insert
delete Delete 0x75 Delete
left Left 0x7B LeftArrow
right Right 0x7C RightArrow
up Up 0x7E UpArrow
down Down 0x7D DownArrow
page_up Page_Up 0x74 PageUp
page_down Page_Down 0x79 PageDown
home Home 0x73 Home
end End 0x77 End
caps_lock Caps_Lock 0x39 -
scroll_lock Scroll_Lock - ScrollLock
num_lock Num_Lock 0x47 ClearLine
print_screen Print - PrintScreen
pause Pause - Pause
menu Menu 0x6E Menu
f1 F1 0x7A F1
f2 F2 0x78 F2
f3 F3 0x63 F3
f4 F4 0x76 F4
f5 F5 0x60 F5
f6 F6 0x61 F6
f7 F7 0x62 F7
f8 F8 0x64 F8
f9 F9 0x65 F9
f10 F10 0x6D F10
f11 F11 0x67 F11
f12 F12 0x6F F12
f13 F13 0x69 F13
f14 F14 0x6B F14
f15 F15 0x71 F15
f16 F16 0x6A F16
f17 F17 0x40 F17
f18 F18 0x4F F18
f19 F19 0x50 F19
f20 F20 0x5A F20
f21 F21 - F21
f22 F22 - F22
f23 F23 - F23
f24 F24 - F24
f25 F25 - F25
f26 F26 - F26
f27 F27 - F27
f28 F28 - F28
f29 F29 - F29
f30 F30 - F30
f31 F31 - F31
f32 F32 - F32
f33 F33 - F33
f34 F34 - F34
f35 F35 - F35
kp_0 KP_0 0x52 -
kp_1 KP_1 0x53 -
kp_2 KP_2 0x54 -
kp_3 KP_3 0x55 -
kp_4 KP_4 0x56 -
kp_5 KP_5 0x57 -
kp_6 KP_6 0x58 -
kp_7 KP_7 0x59 -
kp_8 KP_8 0x5B -
kp_9 KP_9 0x5C -
kp_decimal KP_Decimal 0x41 -
kp_divide KP_Divide 0x4B -
kp_multiply KP_Multiply 0x43 -
kp_subtract KP_Subtract 0x4E -
kp_add KP_Add 0x45 -
kp_enter KP_Enter 0x4C NSEnterCharacter
kp_equal KP_Equal 0x51 -
kp_separator KP_Separator - -
kp_left KP_Left - -
kp_right KP_Right - -
kp_up KP_Up - -
kp_down KP_Down - -
kp_page_up KP_Page_Up - -
kp_page_down KP_Page_Down - -
kp_home KP_Home - -
kp_end KP_End - -
kp_insert KP_Insert - -
kp_delete KP_Delete - -
kp_begin KP_Begin - -
media_play XF86AudioPlay - -
media_pause XF86AudioPause - -
media_play_pause - - -
media_reverse - - -
media_stop XF86AudioStop - -
media_fast_forward XF86AudioForward - -
media_rewind XF86AudioRewind - -
media_track_next XF86AudioNext - -
media_track_previous XF86AudioPrev - -
media_record XF86AudioRecord - -
lower_volume XF86AudioLowerVolume - -
raise_volume XF86AudioRaiseVolume - -
mute_volume XF86AudioMute - -
left_shift Shift_L 0x38 -
left_control Control_L 0x3B -
left_alt Alt_L 0x3A -
left_super Super_L 0x37 -
left_hyper Hyper_L - -
left_meta Meta_L - -
right_shift Shift_R 0x3C -
right_control Control_R 0x3E -
right_alt Alt_R 0x3D -
right_super Super_R 0x36 -
right_hyper Hyper_R - -
right_meta Meta_R - -
iso_level3_shift ISO_Level3_Shift - -
iso_level5_shift ISO_Level5_Shift - -
''' # }}}
shift_map = {x[0]: x[1] for x in '`~ 1! 2@ 3# 4$ 5% 6^ 7& 8* 9( 0) -_ =+ [{ ]} \\| ;: \'" ,< .> /?'.split()}
shift_map.update({x: x.upper() for x in string.ascii_lowercase})
functional_encoding_overrides = {
'insert': 2, 'delete': 3, 'page_up': 5, 'page_down': 6,
'home': 7, 'end': 8, 'tab': 9, 'f1': 11, 'f2': 12, 'f3': 13, 'enter': 13, 'f4': 14,
'f5': 15, 'f6': 17, 'f7': 18, 'f8': 19, 'f9': 20, 'f10': 21,
'f11': 23, 'f12': 24, 'escape': 27, 'backspace': 127
}
different_trailer_functionals = {
'up': 'A', 'down': 'B', 'right': 'C', 'left': 'D', 'kp_begin': 'E', 'end': 'F', 'home': 'H',
'f1': 'P', 'f2': 'Q', 'f3': 'R', 'f4': 'S', 'enter': 'u', 'tab': 'u',
'backspace': 'u', 'escape': 'u'
}
macos_ansi_key_codes = { # {{{
0x1D: ord('0'),
0x12: ord('1'),
0x13: ord('2'),
0x14: ord('3'),
0x15: ord('4'),
0x17: ord('5'),
0x16: ord('6'),
0x1A: ord('7'),
0x1C: ord('8'),
0x19: ord('9'),
0x00: ord('a'),
0x0B: ord('b'),
0x08: ord('c'),
0x02: ord('d'),
0x0E: ord('e'),
0x03: ord('f'),
0x05: ord('g'),
0x04: ord('h'),
0x22: ord('i'),
0x26: ord('j'),
0x28: ord('k'),
0x25: ord('l'),
0x2E: ord('m'),
0x2D: ord('n'),
0x1F: ord('o'),
0x23: ord('p'),
0x0C: ord('q'),
0x0F: ord('r'),
0x01: ord('s'),
0x11: ord('t'),
0x20: ord('u'),
0x09: ord('v'),
0x0D: ord('w'),
0x07: ord('x'),
0x10: ord('y'),
0x06: ord('z'),
0x27: ord('\''),
0x2A: ord('\\'),
0x2B: ord(','),
0x18: ord('='),
0x32: ord('`'),
0x21: ord('['),
0x1B: ord('-'),
0x2F: ord('.'),
0x1E: ord(']'),
0x29: ord(';'),
0x2C: ord('/'),
0x31: ord(' '),
} # }}}
functional_key_names: List[str] = []
name_to_code: Dict[str, int] = {}
name_to_xkb: Dict[str, str] = {}
name_to_vk: Dict[str, int] = {}
name_to_macu: Dict[str, str] = {}
start_code = 0xe000
for line in functional_key_defs.splitlines():
line = line.strip()
if not line or line.startswith('#'):
continue
parts = line.split()
name = parts[0]
functional_key_names.append(name)
name_to_code[name] = len(name_to_code) + start_code
if parts[1] != '-':
name_to_xkb[name] = parts[1]
if parts[2] != '-':
name_to_vk[name] = int(parts[2], 16)
if parts[3] != '-':
val = parts[3]
if not val.startswith('NS'):
val = f'NS{val}FunctionKey'
name_to_macu[name] = val
last_code = start_code + len(functional_key_names) - 1
ctrl_mapping = {
' ': 0, '@': 0, 'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5, 'f': 6, 'g': 7,
'h': 8, 'i': 9, 'j': 10, 'k': 11, 'l': 12, 'm': 13, 'n': 14, 'o': 15, 'p': 16,
'q': 17, 'r': 18, 's': 19, 't': 20, 'u': 21, 'v': 22, 'w': 23, 'x': 24,
'y': 25, 'z': 26, '[': 27, '\\': 28, ']': 29, '^': 30, '~': 30, '/': 31,
'_': 31, '?': 127, '0': 48, '1': 49, '2': 0, '3': 27, '4': 28,
'5': 29, '6': 30, '7': 31, '8': 127, '9': 57
}
def patch_file(path: str, what: str, text: str, start_marker: str = '/* ', end_marker: str = ' */') -> None:
simple_start_q = f'{start_marker}start {what}{end_marker}'
start_q = f'{start_marker}start {what} (auto generated by gen-key-constants.py do not edit){end_marker}'
end_q = f'{start_marker}end {what}{end_marker}'
with open(path, 'r+') as f:
raw = f.read()
try:
start = raw.index(start_q)
except ValueError:
try:
start = raw.index(simple_start_q)
except ValueError:
raise SystemExit(f'Failed to find "{simple_start_q}" in {path}')
try:
end = raw.index(end_q)
except ValueError:
raise SystemExit(f'Failed to find "{end_q}" in {path}')
raw = raw[:start] + start_q + '\n' + text + '\n' + raw[end:]
f.seek(0)
f.truncate(0)
f.write(raw)
def serialize_dict(x: dict) -> str:
return pformat(x, indent=4).replace('{', '{\n ', 1)
def generate_glfw_header() -> None:
lines = [
'typedef enum {',
f' GLFW_FKEY_FIRST = 0x{start_code:x}u,',
]
klines, pyi, names, knames = [], [], [], []
for name, code in name_to_code.items():
lines.append(f' GLFW_FKEY_{name.upper()} = 0x{code:x}u,')
klines.append(f' ADDC(GLFW_FKEY_{name.upper()});')
pyi.append(f'GLFW_FKEY_{name.upper()}: int')
names.append(f' case GLFW_FKEY_{name.upper()}: return "{name.upper()}";')
knames.append(f' case GLFW_FKEY_{name.upper()}: return PyUnicode_FromString("{name}");')
lines.append(f' GLFW_FKEY_LAST = 0x{last_code:x}u')
lines.append('} GLFWFunctionKey;')
patch_file('glfw/glfw3.h', 'functional key names', '\n'.join(lines))
patch_file('kitty/glfw.c', 'glfw functional keys', '\n'.join(klines))
patch_file('kitty/fast_data_types.pyi', 'glfw functional keys', '\n'.join(pyi), start_marker='# ', end_marker='')
patch_file('glfw/input.c', 'functional key names', '\n'.join(names))
patch_file('kitty/glfw.c', 'glfw functional key names', '\n'.join(knames))
def generate_xkb_mapping() -> None:
lines, rlines = [], []
for name, xkb in name_to_xkb.items():
lines.append(f' case XKB_KEY_{xkb}: return GLFW_FKEY_{name.upper()};')
rlines.append(f' case GLFW_FKEY_{name.upper()}: return XKB_KEY_{xkb};')
patch_file('glfw/xkb_glfw.c', 'xkb to glfw', '\n'.join(lines))
patch_file('glfw/xkb_glfw.c', 'glfw to xkb', '\n'.join(rlines))
def generate_functional_table() -> None:
lines = [
'',
'.. csv-table:: Functional key codes',
' :header: "Name", "CSI", "Name", "CSI"',
''
]
line_items = []
enc_lines = []
tilde_trailers = set()
for name, code in name_to_code.items():
if name in functional_encoding_overrides or name in different_trailer_functionals:
trailer = different_trailer_functionals.get(name, '~')
if trailer == '~':
tilde_trailers.add(code)
code = oc = functional_encoding_overrides.get(name, code)
code = code if trailer in '~u' else 1
enc_lines.append((' ' * 8) + f"case GLFW_FKEY_{name.upper()}: S({code}, '{trailer}');")
if code == 1 and name not in ('up', 'down', 'left', 'right'):
trailer += f' or {oc} ~'
else:
trailer = 'u'
line_items.append(name.upper())
line_items.append(f'``{code}\xa0{trailer}``')
for li in chunks(line_items, 4):
lines.append(' ' + ', '.join(f'"{x}"' for x in li))
lines.append('')
patch_file('docs/keyboard-protocol.rst', 'functional key table', '\n'.join(lines), start_marker='.. ', end_marker='')
patch_file('kitty/key_encoding.c', 'special numbers', '\n'.join(enc_lines))
code_to_name = {v: k.upper() for k, v in name_to_code.items()}
csi_map = {v: name_to_code[k] for k, v in functional_encoding_overrides.items()}
letter_trailer_codes = {
v: functional_encoding_overrides.get(k, name_to_code.get(k))
for k, v in different_trailer_functionals.items() if v in 'ABCDEHFPQRSZ'}
text = f'functional_key_number_to_name_map = {serialize_dict(code_to_name)}'
text += f'\ncsi_number_to_functional_number_map = {serialize_dict(csi_map)}'
text += f'\nletter_trailer_to_csi_number_map = {letter_trailer_codes!r}'
text += f'\ntilde_trailers = {tilde_trailers!r}'
patch_file('kitty/key_encoding.py', 'csi mapping', text, start_marker='# ', end_marker='')
def generate_legacy_text_key_maps() -> None:
tests = []
tp = ' ' * 8
shift, alt, ctrl = 1, 2, 4
def simple(c: str) -> None:
shifted = shift_map.get(c, c)
ctrled = chr(ctrl_mapping.get(c, ord(c)))
call = f'enc(ord({c!r}), shifted_key=ord({shifted!r})'
for m in range(16):
if m == 0:
tests.append(f'{tp}ae({call}), {c!r})')
elif m == shift:
tests.append(f'{tp}ae({call}, mods=shift), {shifted!r})')
elif m == alt:
tests.append(f'{tp}ae({call}, mods=alt), "\\x1b" + {c!r})')
elif m == ctrl:
tests.append(f'{tp}ae({call}, mods=ctrl), {ctrled!r})')
elif m == shift | alt:
tests.append(f'{tp}ae({call}, mods=shift | alt), "\\x1b" + {shifted!r})')
elif m == ctrl | alt:
tests.append(f'{tp}ae({call}, mods=ctrl | alt), "\\x1b" + {ctrled!r})')
for k in shift_map:
simple(k)
patch_file('kitty_tests/keys.py', 'legacy letter tests', '\n'.join(tests), start_marker='# ', end_marker='')
def chunks(lst: List, n: int) -> Any:
"""Yield successive n-sized chunks from lst."""
for i in range(0, len(lst), n):
yield lst[i:i + n]
def generate_ctrl_mapping() -> None:
lines = [
'.. csv-table:: Emitted bytes when :kbd:`ctrl` is held down and a key is pressed',
' :header: "Key", "Byte", "Key", "Byte", "Key", "Byte"',
''
]
items = []
mi = []
for k in sorted(ctrl_mapping):
prefix = '\\' if k == '\\' else ('SPC' if k == ' ' else '')
items.append(prefix + k)
val = str(ctrl_mapping[k])
items.append(val)
if k in "\\'":
k = '\\' + k
mi.append(f" case '{k}': return {val};")
for line_items in chunks(items, 6):
lines.append(' ' + ', '.join(f'"{x}"' for x in line_items))
lines.append('')
patch_file('docs/keyboard-protocol.rst', 'ctrl mapping', '\n'.join(lines), start_marker='.. ', end_marker='')
patch_file('kitty/key_encoding.c', 'ctrl mapping', '\n'.join(mi))
def generate_macos_mapping() -> None:
lines = []
for k in sorted(macos_ansi_key_codes):
v = macos_ansi_key_codes[k]
lines.append(f' case 0x{k:x}: return 0x{v:x};')
patch_file('glfw/cocoa_window.m', 'vk to unicode', '\n'.join(lines))
lines = []
for name, vk in name_to_vk.items():
lines.append(f' case 0x{vk:x}: return GLFW_FKEY_{name.upper()};')
patch_file('glfw/cocoa_window.m', 'vk to functional', '\n'.join(lines))
lines = []
for name, mac in name_to_macu.items():
lines.append(f' case {mac}: return GLFW_FKEY_{name.upper()};')
patch_file('glfw/cocoa_window.m', 'macu to functional', '\n'.join(lines))
lines = []
for name, mac in name_to_macu.items():
lines.append(f' case GLFW_FKEY_{name.upper()}: return {mac};')
patch_file('glfw/cocoa_window.m', 'functional to macu', '\n'.join(lines))
def main() -> None:
generate_glfw_header()
generate_xkb_mapping()
generate_functional_table()
generate_legacy_text_key_maps()
generate_ctrl_mapping()
generate_macos_mapping()
if __name__ == '__main__':
main()

View File

@@ -114,6 +114,7 @@ def parse_ucd() -> None:
word_search_map['bee'] |= word_search_map['honeybee']
word_search_map['lambda'] |= word_search_map['lamda']
word_search_map['lamda'] |= word_search_map['lambda']
word_search_map['diamond'] |= word_search_map['gem']
def parse_range_spec(spec: str) -> Set[int]:
@@ -387,7 +388,8 @@ def gen_ucd() -> None:
rmap[0xfe0e], rmap[0xfe0f]
))
with open('kittens/hints/url_regex.py', 'w') as f:
f.write("url_delimiters = '{}' # noqa".format(''.join(classes_to_regex(cz, exclude='\n'))))
f.write('# generated by gen-wcwidth.py, do not edit\n\n')
f.write("url_delimiters = '{}' # noqa".format(''.join(classes_to_regex(cz, exclude='\n\r'))))
def gen_names() -> None:
@@ -504,7 +506,7 @@ def gen_wcwidth() -> None:
p('\t\t// }}}\n')
with create_header('kitty/wcwidth-std.h') as p:
p('static int\nwcwidth_std(int32_t code) {')
p('static inline int\nwcwidth_std(int32_t code) {')
p('\tif (LIKELY(0x20 <= code && code <= 0x7e)) return 1;')
p('\tswitch(code) {')

70
glfw/backend_utils.c vendored
View File

@@ -8,6 +8,7 @@
#define _GNU_SOURCE
#include "backend_utils.h"
#include "internal.h"
#include "memfd.h"
#include <stdlib.h>
#include <string.h>
@@ -350,3 +351,72 @@ GLFWAPI char* utf_8_strndup(const char* source, size_t max_length) {
result[length] = 0;
return result;
}
/*
* Create a new, unique, anonymous file of the given size, and
* return the file descriptor for it. The file descriptor is set
* CLOEXEC. The file is immediately suitable for mmap()'ing
* the given size at offset zero.
*
* The file should not have a permanent backing store like a disk,
* but may have if XDG_RUNTIME_DIR is not properly implemented in OS.
*
* The file name is deleted from the file system.
*
* The file is suitable for buffer sharing between processes by
* transmitting the file descriptor over Unix sockets using the
* SCM_RIGHTS methods.
*
* posix_fallocate() is used to guarantee that disk space is available
* for the file at the given size. If disk space is insufficient, errno
* is set to ENOSPC. If posix_fallocate() is not supported, program may
* receive SIGBUS on accessing mmap()'ed file contents instead.
*/
int createAnonymousFile(off_t size) {
int ret, fd = -1, shm_anon = 0;
#ifdef HAS_MEMFD_CREATE
fd = glfw_memfd_create("glfw-shared", MFD_CLOEXEC | MFD_ALLOW_SEALING);
if (fd < 0) return -1;
// We can add this seal before calling posix_fallocate(), as the file
// is currently zero-sized anyway.
//
// There is also no need to check for the return value, we couldnt do
// anything with it anyway.
fcntl(fd, F_ADD_SEALS, F_SEAL_SHRINK | F_SEAL_SEAL);
#elif defined(SHM_ANON)
fd = shm_open(SHM_ANON, O_RDWR | O_CLOEXEC, 0600);
if (fd < 0) return -1;
shm_anon = 1;
#else
static const char template[] = "/glfw-shared-XXXXXX";
const char* path;
char* name;
path = getenv("XDG_RUNTIME_DIR");
if (!path)
{
errno = ENOENT;
return -1;
}
name = calloc(strlen(path) + sizeof(template), 1);
strcpy(name, path);
strcat(name, template);
fd = createTmpfileCloexec(name);
free(name);
if (fd < 0)
return -1;
#endif
// posix_fallocate does not work on SHM descriptors
ret = shm_anon ? ftruncate(fd, size) : posix_fallocate(fd, 0, size);
if (ret != 0)
{
close(fd);
errno = ret;
return -1;
}
return fd;
}

View File

@@ -1,7 +1,7 @@
//========================================================================
// GLFW 3.4 Wayland - www.glfw.org
// GLFW 3.4
//------------------------------------------------------------------------
// Copyright (c) 2014 Jonas Ådahl <jadahl@gmail.com>
// Copyright (c) 2014 Kovid Goyal
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
@@ -29,6 +29,7 @@
#include <poll.h>
#include <unistd.h>
#include <stdbool.h>
#include <sys/types.h>
#ifdef __has_include
#if __has_include(<sys/eventfd.h>)
@@ -96,3 +97,4 @@ void finalizePollData(EventLoopData *eld);
bool initPollData(EventLoopData *eld, int display_fd);
void wakeupEventLoop(EventLoopData *eld);
char* utf_8_strndup(const char* source, size_t max_length);
int createAnonymousFile(off_t size);

View File

@@ -175,138 +175,6 @@ static void createMenuBar(void)
[NSApp performSelector:setAppleMenuSelector withObject:appMenu];
}
// Create key code translation tables
//
static void createKeyTables(void)
{
int keycode;
memset(_glfw.ns.keycodes, -1, sizeof(_glfw.ns.keycodes));
memset(_glfw.ns.key_to_keycode, -1, sizeof(_glfw.ns.key_to_keycode));
_glfw.ns.keycodes[0x1D] = GLFW_KEY_0;
_glfw.ns.keycodes[0x12] = GLFW_KEY_1;
_glfw.ns.keycodes[0x13] = GLFW_KEY_2;
_glfw.ns.keycodes[0x14] = GLFW_KEY_3;
_glfw.ns.keycodes[0x15] = GLFW_KEY_4;
_glfw.ns.keycodes[0x17] = GLFW_KEY_5;
_glfw.ns.keycodes[0x16] = GLFW_KEY_6;
_glfw.ns.keycodes[0x1A] = GLFW_KEY_7;
_glfw.ns.keycodes[0x1C] = GLFW_KEY_8;
_glfw.ns.keycodes[0x19] = GLFW_KEY_9;
_glfw.ns.keycodes[0x00] = GLFW_KEY_A;
_glfw.ns.keycodes[0x0B] = GLFW_KEY_B;
_glfw.ns.keycodes[0x08] = GLFW_KEY_C;
_glfw.ns.keycodes[0x02] = GLFW_KEY_D;
_glfw.ns.keycodes[0x0E] = GLFW_KEY_E;
_glfw.ns.keycodes[0x03] = GLFW_KEY_F;
_glfw.ns.keycodes[0x05] = GLFW_KEY_G;
_glfw.ns.keycodes[0x04] = GLFW_KEY_H;
_glfw.ns.keycodes[0x22] = GLFW_KEY_I;
_glfw.ns.keycodes[0x26] = GLFW_KEY_J;
_glfw.ns.keycodes[0x28] = GLFW_KEY_K;
_glfw.ns.keycodes[0x25] = GLFW_KEY_L;
_glfw.ns.keycodes[0x2E] = GLFW_KEY_M;
_glfw.ns.keycodes[0x2D] = GLFW_KEY_N;
_glfw.ns.keycodes[0x1F] = GLFW_KEY_O;
_glfw.ns.keycodes[0x23] = GLFW_KEY_P;
_glfw.ns.keycodes[0x0C] = GLFW_KEY_Q;
_glfw.ns.keycodes[0x0F] = GLFW_KEY_R;
_glfw.ns.keycodes[0x01] = GLFW_KEY_S;
_glfw.ns.keycodes[0x11] = GLFW_KEY_T;
_glfw.ns.keycodes[0x20] = GLFW_KEY_U;
_glfw.ns.keycodes[0x09] = GLFW_KEY_V;
_glfw.ns.keycodes[0x0D] = GLFW_KEY_W;
_glfw.ns.keycodes[0x07] = GLFW_KEY_X;
_glfw.ns.keycodes[0x10] = GLFW_KEY_Y;
_glfw.ns.keycodes[0x06] = GLFW_KEY_Z;
_glfw.ns.keycodes[0x27] = GLFW_KEY_APOSTROPHE;
_glfw.ns.keycodes[0x2A] = GLFW_KEY_BACKSLASH;
_glfw.ns.keycodes[0x2B] = GLFW_KEY_COMMA;
_glfw.ns.keycodes[0x18] = GLFW_KEY_EQUAL;
_glfw.ns.keycodes[0x32] = GLFW_KEY_GRAVE_ACCENT;
_glfw.ns.keycodes[0x21] = GLFW_KEY_LEFT_BRACKET;
_glfw.ns.keycodes[0x1B] = GLFW_KEY_MINUS;
_glfw.ns.keycodes[0x2F] = GLFW_KEY_PERIOD;
_glfw.ns.keycodes[0x1E] = GLFW_KEY_RIGHT_BRACKET;
_glfw.ns.keycodes[0x29] = GLFW_KEY_SEMICOLON;
_glfw.ns.keycodes[0x2C] = GLFW_KEY_SLASH;
_glfw.ns.keycodes[0x0A] = GLFW_KEY_WORLD_1;
_glfw.ns.keycodes[0x33] = GLFW_KEY_BACKSPACE;
_glfw.ns.keycodes[0x39] = GLFW_KEY_CAPS_LOCK;
_glfw.ns.keycodes[0x75] = GLFW_KEY_DELETE;
_glfw.ns.keycodes[0x7D] = GLFW_KEY_DOWN;
_glfw.ns.keycodes[0x77] = GLFW_KEY_END;
_glfw.ns.keycodes[0x24] = GLFW_KEY_ENTER;
_glfw.ns.keycodes[0x35] = GLFW_KEY_ESCAPE;
_glfw.ns.keycodes[0x7A] = GLFW_KEY_F1;
_glfw.ns.keycodes[0x78] = GLFW_KEY_F2;
_glfw.ns.keycodes[0x63] = GLFW_KEY_F3;
_glfw.ns.keycodes[0x76] = GLFW_KEY_F4;
_glfw.ns.keycodes[0x60] = GLFW_KEY_F5;
_glfw.ns.keycodes[0x61] = GLFW_KEY_F6;
_glfw.ns.keycodes[0x62] = GLFW_KEY_F7;
_glfw.ns.keycodes[0x64] = GLFW_KEY_F8;
_glfw.ns.keycodes[0x65] = GLFW_KEY_F9;
_glfw.ns.keycodes[0x6D] = GLFW_KEY_F10;
_glfw.ns.keycodes[0x67] = GLFW_KEY_F11;
_glfw.ns.keycodes[0x6F] = GLFW_KEY_F12;
_glfw.ns.keycodes[0x69] = GLFW_KEY_F13;
_glfw.ns.keycodes[0x6B] = GLFW_KEY_F14;
_glfw.ns.keycodes[0x71] = GLFW_KEY_F15;
_glfw.ns.keycodes[0x6A] = GLFW_KEY_F16;
_glfw.ns.keycodes[0x40] = GLFW_KEY_F17;
_glfw.ns.keycodes[0x4F] = GLFW_KEY_F18;
_glfw.ns.keycodes[0x50] = GLFW_KEY_F19;
_glfw.ns.keycodes[0x5A] = GLFW_KEY_F20;
_glfw.ns.keycodes[0x73] = GLFW_KEY_HOME;
_glfw.ns.keycodes[0x72] = GLFW_KEY_INSERT;
_glfw.ns.keycodes[0x7B] = GLFW_KEY_LEFT;
_glfw.ns.keycodes[0x3A] = GLFW_KEY_LEFT_ALT;
_glfw.ns.keycodes[0x3B] = GLFW_KEY_LEFT_CONTROL;
_glfw.ns.keycodes[0x38] = GLFW_KEY_LEFT_SHIFT;
_glfw.ns.keycodes[0x37] = GLFW_KEY_LEFT_SUPER;
_glfw.ns.keycodes[0x6E] = GLFW_KEY_MENU;
_glfw.ns.keycodes[0x47] = GLFW_KEY_NUM_LOCK;
_glfw.ns.keycodes[0x79] = GLFW_KEY_PAGE_DOWN;
_glfw.ns.keycodes[0x74] = GLFW_KEY_PAGE_UP;
_glfw.ns.keycodes[0x7C] = GLFW_KEY_RIGHT;
_glfw.ns.keycodes[0x3D] = GLFW_KEY_RIGHT_ALT;
_glfw.ns.keycodes[0x3E] = GLFW_KEY_RIGHT_CONTROL;
_glfw.ns.keycodes[0x3C] = GLFW_KEY_RIGHT_SHIFT;
_glfw.ns.keycodes[0x36] = GLFW_KEY_RIGHT_SUPER;
_glfw.ns.keycodes[0x31] = GLFW_KEY_SPACE;
_glfw.ns.keycodes[0x30] = GLFW_KEY_TAB;
_glfw.ns.keycodes[0x7E] = GLFW_KEY_UP;
_glfw.ns.keycodes[0x52] = GLFW_KEY_KP_0;
_glfw.ns.keycodes[0x53] = GLFW_KEY_KP_1;
_glfw.ns.keycodes[0x54] = GLFW_KEY_KP_2;
_glfw.ns.keycodes[0x55] = GLFW_KEY_KP_3;
_glfw.ns.keycodes[0x56] = GLFW_KEY_KP_4;
_glfw.ns.keycodes[0x57] = GLFW_KEY_KP_5;
_glfw.ns.keycodes[0x58] = GLFW_KEY_KP_6;
_glfw.ns.keycodes[0x59] = GLFW_KEY_KP_7;
_glfw.ns.keycodes[0x5B] = GLFW_KEY_KP_8;
_glfw.ns.keycodes[0x5C] = GLFW_KEY_KP_9;
_glfw.ns.keycodes[0x45] = GLFW_KEY_KP_ADD;
_glfw.ns.keycodes[0x41] = GLFW_KEY_KP_DECIMAL;
_glfw.ns.keycodes[0x4B] = GLFW_KEY_KP_DIVIDE;
_glfw.ns.keycodes[0x4C] = GLFW_KEY_KP_ENTER;
_glfw.ns.keycodes[0x51] = GLFW_KEY_KP_EQUAL;
_glfw.ns.keycodes[0x43] = GLFW_KEY_KP_MULTIPLY;
_glfw.ns.keycodes[0x4E] = GLFW_KEY_KP_SUBTRACT;
for (keycode = 0; keycode < 256; keycode++)
{
// Store the reverse translation for faster key name lookup
if (_glfw.ns.keycodes[keycode] >= 0)
_glfw.ns.key_to_keycode[_glfw.ns.keycodes[keycode]] = keycode;
}
}
// Retrieve Unicode data for the current keyboard layout
//
static bool updateUnicodeDataNS(void)
@@ -478,10 +346,40 @@ static GLFWapplicationwillfinishlaunchingfun finish_launching_callback = NULL;
finish_launching_callback();
}
- (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename {
(void)theApplication;
if (!filename || !_glfw.ns.file_open_callback) return NO;
const char *path = NULL;
@try {
path = [[NSFileManager defaultManager] fileSystemRepresentationWithPath: filename];
} @catch(NSException *exc) {
NSLog(@"Converting openFile filename: %@ failed with error: %@", filename, exc.reason);
return NO;
}
if (!path) return NO;
return _glfw.ns.file_open_callback(path);
}
- (void)application:(NSApplication *)sender openFiles:(NSArray *)filenames {
(void)sender;
if (!_glfw.ns.file_open_callback || !filenames) return;
for (id x in filenames) {
NSString *filename = x;
const char *path = NULL;
@try {
path = [[NSFileManager defaultManager] fileSystemRepresentationWithPath: filename];
} @catch(NSException *exc) {
NSLog(@"Converting openFiles filename: %@ failed with error: %@", filename, exc.reason);
}
if (path) _glfw.ns.file_open_callback(path);
}
}
- (void)applicationDidFinishLaunching:(NSNotification *)notification
{
(void)notification;
[NSApp stop:nil];
if (_glfw.ns.file_open_callback) _glfw.ns.file_open_callback(":cocoa::application launched::");
CGDisplayRegisterReconfigurationCallback(display_reconfigured, NULL);
_glfwCocoaPostEmptyEvent();
@@ -648,8 +546,12 @@ int _glfwPlatformInit(void)
if (_glfw.hints.init.ns.chdir)
changeToResourcesDirectory();
// Press and Hold prevents some keys from emitting repeated characters
NSDictionary* defaults = @{@"ApplePressAndHoldEnabled":@NO};
NSDictionary* defaults = @{
// Press and Hold prevents some keys from emitting repeated characters
@"ApplePressAndHoldEnabled": @NO,
// Dont generate openFile events from command line arguments
@"NSTreatUnknownArgumentsAsOpen": @"NO",
};
[[NSUserDefaults standardUserDefaults] registerDefaults:defaults];
[[NSNotificationCenter defaultCenter]
@@ -658,8 +560,6 @@ int _glfwPlatformInit(void)
name:NSTextInputContextKeyboardSelectionDidChangeNotification
object:nil];
createKeyTables();
_glfw.ns.eventSource = CGEventSourceCreate(kCGEventSourceStateHIDSystemState);
if (!_glfw.ns.eventSource)
return false;

View File

@@ -41,18 +41,30 @@
// Get the name of the specified display, or NULL
//
static char* getDisplayName(CGDirectDisplayID displayID)
static char* getDisplayName(CGDirectDisplayID displayID, NSScreen* screen)
{
// IOKit doesn't work on Apple Silicon anymore
// Luckily, 10.15 introduced -[NSScreen localizedName].
// Use it if available, and fall back to IOKit otherwise.
if (screen)
{
if ([screen respondsToSelector:@selector(localizedName)])
{
NSString* name = [screen valueForKey:@"localizedName"];
if (name)
return _glfw_strdup([name UTF8String]);
}
}
io_iterator_t it;
io_service_t service;
CFDictionaryRef info;
if (IOServiceGetMatchingServices(kIOMasterPortDefault,
if (IOServiceGetMatchingServices(kIOMainPortDefault,
IOServiceMatching("IODisplayConnect"),
&it) != 0)
{
// This may happen if a desktop Mac is running headless
return NULL;
return _glfw_strdup("Display");
}
while ((service = IOIteratorNext(it)) != 0)
@@ -90,7 +102,7 @@ static char* getDisplayName(CGDirectDisplayID displayID)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Cocoa: Failed to find service port for display");
return NULL;
return _glfw_strdup("Display");
}
CFDictionaryRef names =
@@ -103,7 +115,7 @@ static char* getDisplayName(CGDirectDisplayID displayID)
{
// This may happen if a desktop Mac is running headless
CFRelease(info);
return NULL;
return _glfw_strdup("Display");
}
const CFIndex size =
@@ -245,7 +257,7 @@ static double getFallbackRefreshRate(CGDirectDisplayID displayID)
io_iterator_t it;
io_service_t service;
if (IOServiceGetMatchingServices(kIOMasterPortDefault,
if (IOServiceGetMatchingServices(kIOMainPortDefault,
IOServiceMatching("IOFramebuffer"),
&it) != 0)
{
@@ -316,6 +328,7 @@ void _glfwClearDisplayLinks() {
CVDisplayLinkRelease(_glfw.ns.displayLinks.entries[i].displayLink);
_glfw.ns.displayLinks.entries[i].displayLink = nil;
_glfw.ns.displayLinks.entries[i].lastRenderFrameRequestedAt = 0;
_glfw.ns.displayLinks.entries[i].first_unserviced_render_frame_request_at = 0;
}
}
_glfw.ns.displayLinks.count = 0;
@@ -326,14 +339,21 @@ static CVReturn displayLinkCallback(
const CVTimeStamp* now UNUSED, const CVTimeStamp* outputTime UNUSED,
CVOptionFlags flagsIn UNUSED, CVOptionFlags* flagsOut UNUSED, void* userInfo)
{
CGDirectDisplayID displayID = (CGDirectDisplayID)userInfo;
CGDirectDisplayID displayID = (uintptr_t)userInfo;
NSNumber *arg = [NSNumber numberWithUnsignedInt:displayID];
[NSApp performSelectorOnMainThread:@selector(render_frame_received:) withObject:arg waitUntilDone:NO];
[arg release];
return kCVReturnSuccess;
}
static inline void createDisplayLink(CGDirectDisplayID displayID) {
void
_glfw_create_cv_display_link(_GLFWDisplayLinkNS *entry) {
CVDisplayLinkCreateWithCGDisplay(entry->displayID, &entry->displayLink);
CVDisplayLinkSetOutputCallback(entry->displayLink, &displayLinkCallback, (void*)(uintptr_t)entry->displayID);
}
static void
createDisplayLink(CGDirectDisplayID displayID) {
if (_glfw.ns.displayLinks.count >= sizeof(_glfw.ns.displayLinks.entries)/sizeof(_glfw.ns.displayLinks.entries[0]) - 1) return;
for (size_t i = 0; i < _glfw.ns.displayLinks.count; i++) {
if (_glfw.ns.displayLinks.entries[i].displayID == displayID) return;
@@ -341,8 +361,7 @@ static inline void createDisplayLink(CGDirectDisplayID displayID) {
_GLFWDisplayLinkNS *entry = &_glfw.ns.displayLinks.entries[_glfw.ns.displayLinks.count++];
memset(entry, 0, sizeof(_GLFWDisplayLinkNS));
entry->displayID = displayID;
CVDisplayLinkCreateWithCGDisplay(displayID, &entry->displayLink);
CVDisplayLinkSetOutputCallback(entry->displayLink, &displayLinkCallback, (void*)(uintptr_t)displayID);
_glfw_create_cv_display_link(entry);
}
// Poll for changes in the set of connected monitors
@@ -374,28 +393,46 @@ void _glfwPollMonitorsNS(void)
if (CGDisplayIsAsleep(displays[i]))
continue;
const uint32_t unitNumber = CGDisplayUnitNumber(displays[i]);
NSScreen* screen = nil;
for (screen in [NSScreen screens])
{
NSNumber* screenNumber = [screen deviceDescription][@"NSScreenNumber"];
// HACK: Compare unit numbers instead of display IDs to work around
// display replacement on machines with automatic graphics
// switching
if (CGDisplayUnitNumber([screenNumber unsignedIntValue]) == unitNumber)
break;
}
// HACK: Compare unit numbers instead of display IDs to work around
// display replacement on machines with automatic graphics
// switching
const uint32_t unitNumber = CGDisplayUnitNumber(displays[i]);
for (uint32_t j = 0; j < disconnectedCount; j++)
uint32_t j;
for (j = 0; j < disconnectedCount; j++)
{
if (disconnected[j] && disconnected[j]->ns.unitNumber == unitNumber)
{
disconnected[j]->ns.screen = screen;
disconnected[j] = NULL;
break;
}
}
if (j < disconnectedCount)
continue;
const CGSize size = CGDisplayScreenSize(displays[i]);
char* name = getDisplayName(displays[i]);
char* name = getDisplayName(displays[i], screen);
if (!name)
name = _glfw_strdup("Unknown");
continue;
_GLFWmonitor* monitor = _glfwAllocMonitor(name, (int)size.width, (int)size.height);
monitor->ns.displayID = displays[i];
monitor->ns.unitNumber = unitNumber;
monitor->ns.screen = screen;
createDisplayLink(monitor->ns.displayID);
free(name);
@@ -547,15 +584,16 @@ GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count)
const GLFWvidmode mode =
vidmodeFromCGDisplayMode(dm, monitor->ns.fallbackRefreshRate);
CFIndex j;
for (CFIndex j = 0; j < *count; j++)
for (j = 0; j < *count; j++)
{
if (_glfwCompareVideoModes(result + j, &mode) == 0)
break;
}
// Skip duplicate modes
if (i < *count)
if (j < *count)
continue;
(*count)++;

14
glfw/cocoa_platform.h vendored
View File

@@ -39,6 +39,9 @@ typedef void* CVDisplayLinkRef;
// NOTE: Many Cocoa enum values have been renamed and we need to build across
// SDK versions where one is unavailable or the other deprecated
// We use the newer names in code and these macros to handle compatibility
#if (MAC_OS_X_VERSION_MAX_ALLOWED < 120000) // Before macOS 12 Monterey
#define kIOMainPortDefault kIOMasterPortDefault
#endif
#if MAC_OS_X_VERSION_MAX_ALLOWED < 101200
#define NSBitmapFormatAlphaNonpremultiplied NSAlphaNonpremultipliedBitmapFormat
#define NSEventMaskAny NSAnyEventMask
@@ -67,6 +70,7 @@ typedef void* CVDisplayLinkRef;
typedef int (* GLFWcocoatextinputfilterfun)(int,int,unsigned int, unsigned long);
typedef bool (* GLFWapplicationshouldhandlereopenfun)(int);
typedef bool (* GLFWhandlefileopen)(const char*);
typedef void (* GLFWapplicationwillfinishlaunchingfun)(void);
typedef bool (* GLFWcocoatogglefullscreenfun)(GLFWwindow*);
typedef void (* GLFWcocoarenderframefun)(GLFWwindow*);
@@ -128,6 +132,9 @@ typedef struct _GLFWwindowNS
bool maximized;
bool retina;
bool in_traditional_fullscreen;
bool titlebar_hidden;
unsigned long pre_full_screen_style_mask;
// Cached window properties to filter out duplicate events
int width, height;
@@ -154,7 +161,7 @@ typedef struct _GLFWDisplayLinkNS
{
CVDisplayLinkRef displayLink;
CGDirectDisplayID displayID;
monotonic_t lastRenderFrameRequestedAt;
monotonic_t lastRenderFrameRequestedAt, first_unserviced_render_frame_request_at;
} _GLFWDisplayLinkNS;
// Cocoa-specific global data
@@ -175,8 +182,6 @@ typedef struct _GLFWlibraryNS
char keyName[64];
char text[256];
short int keycodes[256];
short int key_to_keycode[GLFW_KEY_LAST + 1];
char* clipboardString;
CGPoint cascadePoint;
// Where to place the cursor when re-enabled
@@ -196,6 +201,8 @@ typedef struct _GLFWlibraryNS
_GLFWDisplayLinkNS entries[256];
size_t count;
} displayLinks;
// the callback to handle file open events
GLFWhandlefileopen file_open_callback;
} _GLFWlibraryNS;
@@ -242,3 +249,4 @@ void _glfwDispatchTickCallback(void);
void _glfwDispatchRenderFrame(CGDirectDisplayID);
void _glfwShutdownCVDisplayLink(unsigned long long, void*);
void _glfwCocoaPostEmptyEvent(void);
void _glfw_create_cv_display_link(_GLFWDisplayLinkNS *entry);

File diff suppressed because it is too large Load Diff

View File

@@ -55,7 +55,7 @@ def wayland_protocol_file_name(base: str, ext: str = 'c') -> str:
return 'wayland-{}-client-protocol.{}'.format(base, ext)
def init_env(env: Env, pkg_config: Callable, at_least_version: Callable, test_compile: Callable, module: str = 'x11') -> Env:
def init_env(env: Env, pkg_config: Callable, pkg_version: Callable, at_least_version: Callable, test_compile: Callable, module: str = 'x11') -> Env:
ans = env.copy()
ans.cflags.append('-fPIC')
ans.cppflags.append('-D_GLFW_' + module.upper())
@@ -76,7 +76,11 @@ def init_env(env: Env, pkg_config: Callable, at_least_version: Callable, test_co
ans.ldpaths.extend('-pthread -lm'.split())
if not is_openbsd:
ans.ldpaths.extend('-lrt -ldl'.split())
at_least_version('xkbcommon', 0, 5)
major, minor = pkg_version('xkbcommon')
if (major, minor) < (0, 5):
raise SystemExit('libxkbcommon >= 0.5 required')
if major < 1:
ans.cflags.append('-DXKB_HAS_NO_UTF32')
if module == 'x11':
for dep in 'x11 xrandr xinerama xcursor xkbcommon xkbcommon-x11 x11-xcb dbus-1'.split():
@@ -85,7 +89,7 @@ def init_env(env: Env, pkg_config: Callable, at_least_version: Callable, test_co
elif module == 'cocoa':
ans.cppflags.append('-DGL_SILENCE_DEPRECATION')
for f_ in 'Cocoa IOKit CoreFoundation CoreVideo'.split():
for f_ in 'Cocoa Carbon IOKit CoreFoundation CoreVideo'.split():
ans.ldpaths.extend(('-framework', f_))
elif module == 'wayland':
@@ -175,13 +179,12 @@ class Function:
)
def load(self) -> str:
ans = '*(void **) (&{name}_impl) = dlsym(handle, "{name}");'.format(
name=self.name
)
ans = f'*(void **) (&{self.name}_impl) = dlsym(handle, "{self.name}");'
ans += f'\n if ({self.name}_impl == NULL) '
if self.check_fail:
ans += '\n if ({name}_impl == NULL) fail("Failed to load glfw function {name} with error: %s", dlerror());'.format(
name=self.name
)
ans += f'fail("Failed to load glfw function {self.name} with error: %s", dlerror());'
else:
ans += 'dlerror(); // clear error indicator'
return ans
@@ -199,13 +202,15 @@ def generate_wrappers(glfw_header: str) -> None:
functions.append(Function(decl))
for line in '''\
void* glfwGetCocoaWindow(GLFWwindow* window)
void glfwHideCocoaTitlebar(GLFWwindow* window, bool yes)
void* glfwGetNSGLContext(GLFWwindow *window)
uint32_t glfwGetCocoaMonitor(GLFWmonitor* monitor)
GLFWcocoatextinputfilterfun glfwSetCocoaTextInputFilter(GLFWwindow* window, GLFWcocoatextinputfilterfun callback)
GLFWhandlefileopen glfwSetCocoaFileOpenCallback(GLFWhandlefileopen callback)
GLFWcocoatogglefullscreenfun glfwSetCocoaToggleFullscreenIntercept(GLFWwindow *window, GLFWcocoatogglefullscreenfun callback)
GLFWapplicationshouldhandlereopenfun glfwSetApplicationShouldHandleReopen(GLFWapplicationshouldhandlereopenfun callback)
GLFWapplicationwillfinishlaunchingfun glfwSetApplicationWillFinishLaunching(GLFWapplicationwillfinishlaunchingfun callback)
void glfwGetCocoaKeyEquivalent(int glfw_key, int glfw_mods, char* cocoa_key, size_t key_sz, int* cocoa_mods)
uint32_t glfwGetCocoaKeyEquivalent(uint32_t glfw_key, int glfw_mods, int* cocoa_mods)
void glfwCocoaRequestRenderFrame(GLFWwindow *w, GLFWcocoarenderframefun callback)
void* glfwGetX11Display(void)
int32_t glfwGetX11Window(GLFWwindow* window)
@@ -213,9 +218,11 @@ def generate_wrappers(glfw_header: str) -> None:
const char* glfwGetPrimarySelectionString(GLFWwindow* window, void)
int glfwGetNativeKeyForName(const char* key_name, int case_sensitive)
void glfwRequestWaylandFrameEvent(GLFWwindow *handle, unsigned long long id, GLFWwaylandframecallbackfunc callback)
bool glfwWaylandSetTitlebarColor(GLFWwindow *handle, uint32_t color, bool use_system_color)
unsigned long long glfwDBusUserNotify(const char *app_name, const char* icon, const char *summary, const char *body, \
const char *action_text, int32_t timeout, GLFWDBusnotificationcreatedfun callback, void *data)
void glfwDBusSetUserNotificationHandler(GLFWDBusnotificationactivatedfun handler)
int glfwSetX11LaunchCommand(GLFWwindow *handle, char **argv, int argc)
'''.splitlines():
if line:
functions.append(Function(line.strip(), check_fail=False))
@@ -243,6 +250,7 @@ const char *action_text, int32_t timeout, GLFWDBusnotificationcreatedfun callbac
typedef int (* GLFWcocoatextinputfilterfun)(int,int,unsigned int,unsigned long);
typedef bool (* GLFWapplicationshouldhandlereopenfun)(int);
typedef bool (* GLFWhandlefileopen)(const char*);
typedef void (* GLFWapplicationwillfinishlaunchingfun)(void);
typedef bool (* GLFWcocoatogglefullscreenfun)(GLFWwindow*);
typedef void (* GLFWcocoarenderframefun)(GLFWwindow*);

544
glfw/glfw3.h vendored
View File

@@ -300,31 +300,6 @@ extern "C" {
#define GLFW_VERSION_REVISION 0
/*! @} */
/*! @name Key and button actions
* @{ */
/*! @brief The key or mouse button was released.
*
* The key or mouse button was released.
*
* @ingroup input
*/
#define GLFW_RELEASE 0
/*! @brief The key or mouse button was pressed.
*
* The key or mouse button was pressed.
*
* @ingroup input
*/
#define GLFW_PRESS 1
/*! @brief The key was held down until it repeated.
*
* The key was held down until it repeated.
*
* @ingroup input
*/
#define GLFW_REPEAT 2
/*! @} */
/*! @defgroup hat_state Joystick hat states
* @brief Joystick hat states.
*
@@ -367,200 +342,123 @@ extern "C" {
* @{
*/
/* The unknown key */
#define GLFW_KEY_UNKNOWN -1
/* Printable keys */
#define GLFW_KEY_SPACE 32
#define GLFW_KEY_EXCLAM 33 /* ! */
#define GLFW_KEY_DOUBLE_QUOTE 34 /* " */
#define GLFW_KEY_NUMBER_SIGN 35 /* # */
#define GLFW_KEY_DOLLAR 36 /* $ */
#define GLFW_KEY_AMPERSAND 38 /* & */
#define GLFW_KEY_APOSTROPHE 39 /* ' */
#define GLFW_KEY_PARENTHESIS_LEFT 40 /* ( */
#define GLFW_KEY_PARENTHESIS_RIGHT 41 /* ) */
#define GLFW_KEY_PLUS 43 /* + */
#define GLFW_KEY_COMMA 44 /* , */
#define GLFW_KEY_MINUS 45 /* - */
#define GLFW_KEY_PERIOD 46 /* . */
#define GLFW_KEY_SLASH 47 /* / */
#define GLFW_KEY_0 48
#define GLFW_KEY_1 49
#define GLFW_KEY_2 50
#define GLFW_KEY_3 51
#define GLFW_KEY_4 52
#define GLFW_KEY_5 53
#define GLFW_KEY_6 54
#define GLFW_KEY_7 55
#define GLFW_KEY_8 56
#define GLFW_KEY_9 57
#define GLFW_KEY_COLON 58 /* : */
#define GLFW_KEY_SEMICOLON 59 /* ; */
#define GLFW_KEY_LESS 60 /* < */
#define GLFW_KEY_EQUAL 61 /* = */
#define GLFW_KEY_GREATER 62 /* > */
#define GLFW_KEY_AT 64 /* @ */
#define GLFW_KEY_A 65
#define GLFW_KEY_B 66
#define GLFW_KEY_C 67
#define GLFW_KEY_D 68
#define GLFW_KEY_E 69
#define GLFW_KEY_F 70
#define GLFW_KEY_G 71
#define GLFW_KEY_H 72
#define GLFW_KEY_I 73
#define GLFW_KEY_J 74
#define GLFW_KEY_K 75
#define GLFW_KEY_L 76
#define GLFW_KEY_M 77
#define GLFW_KEY_N 78
#define GLFW_KEY_O 79
#define GLFW_KEY_P 80
#define GLFW_KEY_Q 81
#define GLFW_KEY_R 82
#define GLFW_KEY_S 83
#define GLFW_KEY_T 84
#define GLFW_KEY_U 85
#define GLFW_KEY_V 86
#define GLFW_KEY_W 87
#define GLFW_KEY_X 88
#define GLFW_KEY_Y 89
#define GLFW_KEY_Z 90
#define GLFW_KEY_LEFT_BRACKET 91 /* [ */
#define GLFW_KEY_BACKSLASH 92 /* \ */
#define GLFW_KEY_RIGHT_BRACKET 93 /* ] */
#define GLFW_KEY_CIRCUMFLEX 94 /* ^ */
#define GLFW_KEY_UNDERSCORE 95 /* _ */
#define GLFW_KEY_GRAVE_ACCENT 96 /* ` */
#define GLFW_KEY_WORLD_1 161 /* non-US #1 */
#define GLFW_KEY_WORLD_2 162 /* non-US #2 */
#define GLFW_KEY_PARAGRAPH 167 /* § */
#define GLFW_KEY_MASCULINE 186 /* º */
#define GLFW_KEY_A_GRAVE 192 /* À */
#define GLFW_KEY_A_DIAERESIS 196 /* Ä */
#define GLFW_KEY_A_RING 197 /* Å */
#define GLFW_KEY_AE 198 /* Æ */
#define GLFW_KEY_C_CEDILLA 199 /* Ç */
#define GLFW_KEY_E_GRAVE 200 /* È */
#define GLFW_KEY_E_ACUTE 201 /* É */
#define GLFW_KEY_I_GRAVE 204 /* Ì */
#define GLFW_KEY_N_TILDE 209 /* Ñ */
#define GLFW_KEY_O_GRAVE 210 /* Ò */
#define GLFW_KEY_O_DIAERESIS 214 /* Ö */
#define GLFW_KEY_O_SLASH 216 /* Ø */
#define GLFW_KEY_U_GRAVE 217 /* Ù */
#define GLFW_KEY_U_DIAERESIS 220 /* Ü */
#define GLFW_KEY_S_SHARP 222 /* ß */
#define GLFW_KEY_CYRILLIC_A 223 /* А */
#define GLFW_KEY_CYRILLIC_BE 224 /* Б */
#define GLFW_KEY_CYRILLIC_VE 225 /* В */
#define GLFW_KEY_CYRILLIC_GHE 226 /* Г */
#define GLFW_KEY_CYRILLIC_DE 227 /* Д */
#define GLFW_KEY_CYRILLIC_IE 228 /* Е */
#define GLFW_KEY_CYRILLIC_ZHE 229 /* Ж */
#define GLFW_KEY_CYRILLIC_ZE 230 /* З */
#define GLFW_KEY_CYRILLIC_I 231 /* И */
#define GLFW_KEY_CYRILLIC_SHORT_I 232 /* Й */
#define GLFW_KEY_CYRILLIC_KA 233 /* К */
#define GLFW_KEY_CYRILLIC_EL 234 /* Л */
#define GLFW_KEY_CYRILLIC_EM 235 /* М */
#define GLFW_KEY_CYRILLIC_EN 236 /* Н */
#define GLFW_KEY_CYRILLIC_O 237 /* О */
#define GLFW_KEY_CYRILLIC_PE 238 /* П */
#define GLFW_KEY_CYRILLIC_ER 239 /* Р */
#define GLFW_KEY_CYRILLIC_ES 240 /* С */
#define GLFW_KEY_CYRILLIC_TE 241 /* Т */
#define GLFW_KEY_CYRILLIC_U 242 /* У */
#define GLFW_KEY_CYRILLIC_EF 243 /* Ф */
#define GLFW_KEY_CYRILLIC_HA 244 /* Х */
#define GLFW_KEY_CYRILLIC_TSE 245 /* Ц */
#define GLFW_KEY_CYRILLIC_CHE 246 /* Ч */
#define GLFW_KEY_CYRILLIC_SHA 247 /* Ш */
#define GLFW_KEY_CYRILLIC_SHCHA 248 /* Щ */
#define GLFW_KEY_CYRILLIC_HARD_SIGN 249 /* Ъ */
#define GLFW_KEY_CYRILLIC_YERU 250 /* Ы */
#define GLFW_KEY_CYRILLIC_SOFT_SIGN 251 /* Ь */
#define GLFW_KEY_CYRILLIC_E 252 /* Э */
#define GLFW_KEY_CYRILLIC_YU 253 /* Ю */
#define GLFW_KEY_CYRILLIC_YA 254 /* Я */
#define GLFW_KEY_CYRILLIC_IO 255 /* Ё */
#define GLFW_KEY_LAST_PRINTABLE GLFW_KEY_CYRILLIC_IO
/* Function keys */
#define GLFW_KEY_ESCAPE 256
#define GLFW_KEY_ENTER 257
#define GLFW_KEY_TAB 258
#define GLFW_KEY_BACKSPACE 259
#define GLFW_KEY_INSERT 260
#define GLFW_KEY_DELETE 261
#define GLFW_KEY_RIGHT 262
#define GLFW_KEY_LEFT 263
#define GLFW_KEY_DOWN 264
#define GLFW_KEY_UP 265
#define GLFW_KEY_PAGE_UP 266
#define GLFW_KEY_PAGE_DOWN 267
#define GLFW_KEY_HOME 268
#define GLFW_KEY_END 269
#define GLFW_KEY_CAPS_LOCK 280
#define GLFW_KEY_SCROLL_LOCK 281
#define GLFW_KEY_NUM_LOCK 282
#define GLFW_KEY_PRINT_SCREEN 283
#define GLFW_KEY_PAUSE 284
#define GLFW_KEY_F1 290
#define GLFW_KEY_F2 291
#define GLFW_KEY_F3 292
#define GLFW_KEY_F4 293
#define GLFW_KEY_F5 294
#define GLFW_KEY_F6 295
#define GLFW_KEY_F7 296
#define GLFW_KEY_F8 297
#define GLFW_KEY_F9 298
#define GLFW_KEY_F10 299
#define GLFW_KEY_F11 300
#define GLFW_KEY_F12 301
#define GLFW_KEY_F13 302
#define GLFW_KEY_F14 303
#define GLFW_KEY_F15 304
#define GLFW_KEY_F16 305
#define GLFW_KEY_F17 306
#define GLFW_KEY_F18 307
#define GLFW_KEY_F19 308
#define GLFW_KEY_F20 309
#define GLFW_KEY_F21 310
#define GLFW_KEY_F22 311
#define GLFW_KEY_F23 312
#define GLFW_KEY_F24 313
#define GLFW_KEY_F25 314
#define GLFW_KEY_KP_0 320
#define GLFW_KEY_KP_1 321
#define GLFW_KEY_KP_2 322
#define GLFW_KEY_KP_3 323
#define GLFW_KEY_KP_4 324
#define GLFW_KEY_KP_5 325
#define GLFW_KEY_KP_6 326
#define GLFW_KEY_KP_7 327
#define GLFW_KEY_KP_8 328
#define GLFW_KEY_KP_9 329
#define GLFW_KEY_KP_DECIMAL 330
#define GLFW_KEY_KP_DIVIDE 331
#define GLFW_KEY_KP_MULTIPLY 332
#define GLFW_KEY_KP_SUBTRACT 333
#define GLFW_KEY_KP_ADD 334
#define GLFW_KEY_KP_ENTER 335
#define GLFW_KEY_KP_EQUAL 336
#define GLFW_KEY_LEFT_SHIFT 340
#define GLFW_KEY_LEFT_CONTROL 341
#define GLFW_KEY_LEFT_ALT 342
#define GLFW_KEY_LEFT_SUPER 343
#define GLFW_KEY_RIGHT_SHIFT 344
#define GLFW_KEY_RIGHT_CONTROL 345
#define GLFW_KEY_RIGHT_ALT 346
#define GLFW_KEY_RIGHT_SUPER 347
#define GLFW_KEY_MENU 348
#define GLFW_KEY_LAST GLFW_KEY_MENU
/* start functional key names (auto generated by gen-key-constants.py do not edit) */
typedef enum {
GLFW_FKEY_FIRST = 0xe000u,
GLFW_FKEY_ESCAPE = 0xe000u,
GLFW_FKEY_ENTER = 0xe001u,
GLFW_FKEY_TAB = 0xe002u,
GLFW_FKEY_BACKSPACE = 0xe003u,
GLFW_FKEY_INSERT = 0xe004u,
GLFW_FKEY_DELETE = 0xe005u,
GLFW_FKEY_LEFT = 0xe006u,
GLFW_FKEY_RIGHT = 0xe007u,
GLFW_FKEY_UP = 0xe008u,
GLFW_FKEY_DOWN = 0xe009u,
GLFW_FKEY_PAGE_UP = 0xe00au,
GLFW_FKEY_PAGE_DOWN = 0xe00bu,
GLFW_FKEY_HOME = 0xe00cu,
GLFW_FKEY_END = 0xe00du,
GLFW_FKEY_CAPS_LOCK = 0xe00eu,
GLFW_FKEY_SCROLL_LOCK = 0xe00fu,
GLFW_FKEY_NUM_LOCK = 0xe010u,
GLFW_FKEY_PRINT_SCREEN = 0xe011u,
GLFW_FKEY_PAUSE = 0xe012u,
GLFW_FKEY_MENU = 0xe013u,
GLFW_FKEY_F1 = 0xe014u,
GLFW_FKEY_F2 = 0xe015u,
GLFW_FKEY_F3 = 0xe016u,
GLFW_FKEY_F4 = 0xe017u,
GLFW_FKEY_F5 = 0xe018u,
GLFW_FKEY_F6 = 0xe019u,
GLFW_FKEY_F7 = 0xe01au,
GLFW_FKEY_F8 = 0xe01bu,
GLFW_FKEY_F9 = 0xe01cu,
GLFW_FKEY_F10 = 0xe01du,
GLFW_FKEY_F11 = 0xe01eu,
GLFW_FKEY_F12 = 0xe01fu,
GLFW_FKEY_F13 = 0xe020u,
GLFW_FKEY_F14 = 0xe021u,
GLFW_FKEY_F15 = 0xe022u,
GLFW_FKEY_F16 = 0xe023u,
GLFW_FKEY_F17 = 0xe024u,
GLFW_FKEY_F18 = 0xe025u,
GLFW_FKEY_F19 = 0xe026u,
GLFW_FKEY_F20 = 0xe027u,
GLFW_FKEY_F21 = 0xe028u,
GLFW_FKEY_F22 = 0xe029u,
GLFW_FKEY_F23 = 0xe02au,
GLFW_FKEY_F24 = 0xe02bu,
GLFW_FKEY_F25 = 0xe02cu,
GLFW_FKEY_F26 = 0xe02du,
GLFW_FKEY_F27 = 0xe02eu,
GLFW_FKEY_F28 = 0xe02fu,
GLFW_FKEY_F29 = 0xe030u,
GLFW_FKEY_F30 = 0xe031u,
GLFW_FKEY_F31 = 0xe032u,
GLFW_FKEY_F32 = 0xe033u,
GLFW_FKEY_F33 = 0xe034u,
GLFW_FKEY_F34 = 0xe035u,
GLFW_FKEY_F35 = 0xe036u,
GLFW_FKEY_KP_0 = 0xe037u,
GLFW_FKEY_KP_1 = 0xe038u,
GLFW_FKEY_KP_2 = 0xe039u,
GLFW_FKEY_KP_3 = 0xe03au,
GLFW_FKEY_KP_4 = 0xe03bu,
GLFW_FKEY_KP_5 = 0xe03cu,
GLFW_FKEY_KP_6 = 0xe03du,
GLFW_FKEY_KP_7 = 0xe03eu,
GLFW_FKEY_KP_8 = 0xe03fu,
GLFW_FKEY_KP_9 = 0xe040u,
GLFW_FKEY_KP_DECIMAL = 0xe041u,
GLFW_FKEY_KP_DIVIDE = 0xe042u,
GLFW_FKEY_KP_MULTIPLY = 0xe043u,
GLFW_FKEY_KP_SUBTRACT = 0xe044u,
GLFW_FKEY_KP_ADD = 0xe045u,
GLFW_FKEY_KP_ENTER = 0xe046u,
GLFW_FKEY_KP_EQUAL = 0xe047u,
GLFW_FKEY_KP_SEPARATOR = 0xe048u,
GLFW_FKEY_KP_LEFT = 0xe049u,
GLFW_FKEY_KP_RIGHT = 0xe04au,
GLFW_FKEY_KP_UP = 0xe04bu,
GLFW_FKEY_KP_DOWN = 0xe04cu,
GLFW_FKEY_KP_PAGE_UP = 0xe04du,
GLFW_FKEY_KP_PAGE_DOWN = 0xe04eu,
GLFW_FKEY_KP_HOME = 0xe04fu,
GLFW_FKEY_KP_END = 0xe050u,
GLFW_FKEY_KP_INSERT = 0xe051u,
GLFW_FKEY_KP_DELETE = 0xe052u,
GLFW_FKEY_KP_BEGIN = 0xe053u,
GLFW_FKEY_MEDIA_PLAY = 0xe054u,
GLFW_FKEY_MEDIA_PAUSE = 0xe055u,
GLFW_FKEY_MEDIA_PLAY_PAUSE = 0xe056u,
GLFW_FKEY_MEDIA_REVERSE = 0xe057u,
GLFW_FKEY_MEDIA_STOP = 0xe058u,
GLFW_FKEY_MEDIA_FAST_FORWARD = 0xe059u,
GLFW_FKEY_MEDIA_REWIND = 0xe05au,
GLFW_FKEY_MEDIA_TRACK_NEXT = 0xe05bu,
GLFW_FKEY_MEDIA_TRACK_PREVIOUS = 0xe05cu,
GLFW_FKEY_MEDIA_RECORD = 0xe05du,
GLFW_FKEY_LOWER_VOLUME = 0xe05eu,
GLFW_FKEY_RAISE_VOLUME = 0xe05fu,
GLFW_FKEY_MUTE_VOLUME = 0xe060u,
GLFW_FKEY_LEFT_SHIFT = 0xe061u,
GLFW_FKEY_LEFT_CONTROL = 0xe062u,
GLFW_FKEY_LEFT_ALT = 0xe063u,
GLFW_FKEY_LEFT_SUPER = 0xe064u,
GLFW_FKEY_LEFT_HYPER = 0xe065u,
GLFW_FKEY_LEFT_META = 0xe066u,
GLFW_FKEY_RIGHT_SHIFT = 0xe067u,
GLFW_FKEY_RIGHT_CONTROL = 0xe068u,
GLFW_FKEY_RIGHT_ALT = 0xe069u,
GLFW_FKEY_RIGHT_SUPER = 0xe06au,
GLFW_FKEY_RIGHT_HYPER = 0xe06bu,
GLFW_FKEY_RIGHT_META = 0xe06cu,
GLFW_FKEY_ISO_LEVEL3_SHIFT = 0xe06du,
GLFW_FKEY_ISO_LEVEL5_SHIFT = 0xe06eu,
GLFW_FKEY_LAST = 0xe06eu
} GLFWFunctionKey;
/* end functional key names */
/*! @} */
@@ -577,33 +475,44 @@ extern "C" {
* If this bit is set one or more Shift keys were held down.
*/
#define GLFW_MOD_SHIFT 0x0001
/*! @brief If this bit is set one or more Control keys were held down.
*
* If this bit is set one or more Control keys were held down.
*/
#define GLFW_MOD_CONTROL 0x0002
/*! @brief If this bit is set one or more Alt keys were held down.
*
* If this bit is set one or more Alt keys were held down.
*/
#define GLFW_MOD_ALT 0x0004
#define GLFW_MOD_ALT 0x0002
/*! @brief If this bit is set one or more Alt keys were held down.
*
* If this bit is set one or more Alt keys were held down.
*/
#define GLFW_MOD_CONTROL 0x0004
/*! @brief If this bit is set one or more Super keys were held down.
*
* If this bit is set one or more Super keys were held down.
*/
#define GLFW_MOD_SUPER 0x0008
/*! @brief If this bit is set one or more Hyper keys were held down.
*
* If this bit is set one or more Hyper keys were held down.
*/
#define GLFW_MOD_HYPER 0x0010
/*! @brief If this bit is set one or more Meta keys were held down.
*
* If this bit is set one or more Meta keys were held down.
*/
#define GLFW_MOD_META 0x0020
/*! @brief If this bit is set the Caps Lock key is enabled.
*
* If this bit is set the Caps Lock key is enabled and the @ref
* GLFW_LOCK_KEY_MODS input mode is set.
*/
#define GLFW_MOD_CAPS_LOCK 0x0010
#define GLFW_MOD_CAPS_LOCK 0x0040
/*! @brief If this bit is set the Num Lock key is enabled.
*
* If this bit is set the Num Lock key is enabled and the @ref
* GLFW_LOCK_KEY_MODS input mode is set.
*/
#define GLFW_MOD_NUM_LOCK 0x0020
#define GLFW_MOD_NUM_LOCK 0x0080
#define GLFW_LOCK_MASK (GLFW_MOD_NUM_LOCK | GLFW_MOD_CAPS_LOCK)
/*! @} */
@@ -614,18 +523,20 @@ extern "C" {
*
* @ingroup input
* @{ */
#define GLFW_MOUSE_BUTTON_1 0
#define GLFW_MOUSE_BUTTON_2 1
#define GLFW_MOUSE_BUTTON_3 2
#define GLFW_MOUSE_BUTTON_4 3
#define GLFW_MOUSE_BUTTON_5 4
#define GLFW_MOUSE_BUTTON_6 5
#define GLFW_MOUSE_BUTTON_7 6
#define GLFW_MOUSE_BUTTON_8 7
#define GLFW_MOUSE_BUTTON_LAST GLFW_MOUSE_BUTTON_8
#define GLFW_MOUSE_BUTTON_LEFT GLFW_MOUSE_BUTTON_1
#define GLFW_MOUSE_BUTTON_RIGHT GLFW_MOUSE_BUTTON_2
#define GLFW_MOUSE_BUTTON_MIDDLE GLFW_MOUSE_BUTTON_3
typedef enum GLFWMouseButton {
GLFW_MOUSE_BUTTON_1 = 0,
GLFW_MOUSE_BUTTON_LEFT = 0,
GLFW_MOUSE_BUTTON_2 = 1,
GLFW_MOUSE_BUTTON_RIGHT = 1,
GLFW_MOUSE_BUTTON_3 = 2,
GLFW_MOUSE_BUTTON_MIDDLE = 2,
GLFW_MOUSE_BUTTON_4 = 3,
GLFW_MOUSE_BUTTON_5 = 4,
GLFW_MOUSE_BUTTON_6 = 5,
GLFW_MOUSE_BUTTON_7 = 6,
GLFW_MOUSE_BUTTON_8 = 7,
GLFW_MOUSE_BUTTON_LAST = 7
} GLFWMouseButton;
/*! @} */
/*! @defgroup joysticks Joysticks
@@ -1202,6 +1113,7 @@ typedef enum {
*/
#define GLFW_ANGLE_PLATFORM_TYPE 0x00050002
#define GLFW_DEBUG_KEYBOARD 0x00050003
#define GLFW_DEBUG_RENDERING 0x00050004
/*! @brief macOS specific init hint.
*
* macOS specific [init hint](@ref GLFW_COCOA_CHDIR_RESOURCES_hint).
@@ -1285,16 +1197,43 @@ typedef struct GLFWwindow GLFWwindow;
*/
typedef struct GLFWcursor GLFWcursor;
typedef enum {
GLFW_RELEASE = 0,
GLFW_PRESS = 1,
GLFW_REPEAT = 2
} GLFWKeyAction;
typedef enum {
GLFW_IME_NONE,
GLFW_IME_PREEDIT_CHANGED,
GLFW_IME_COMMIT_TEXT
} GLFWIMEState;
typedef enum {
GLFW_IME_UPDATE_FOCUS = 1,
GLFW_IME_UPDATE_CURSOR_POSITION = 2
} GLFWIMEUpdateType;
typedef struct GLFWIMEUpdateEvent {
GLFWIMEUpdateType type;
const char *before_text, *at_text, *after_text;
bool focused;
struct {
int left, top, width, height;
} cursor;
} GLFWIMEUpdateEvent;
typedef struct GLFWkeyevent
{
// The [keyboard key](@ref keys) that was pressed or released.
int key;
uint32_t key, shifted_key, alternate_key;
// The platform-specific identifier of the key.
int native_key;
// The event action. Either `GLFW_PRESS`, `GLFW_RELEASE` or `GLFW_REPEAT`.
int action;
GLFWKeyAction action;
// Bit field describing which [modifier keys](@ref mods) were held down.
int mods;
@@ -1303,9 +1242,9 @@ typedef struct GLFWkeyevent
const char *text;
// Used for Input Method events. Zero for normal key events.
// A value of 1 means the pre-edit text for the input event has been changed.
// A value of 2 means the text should be committed.
int ime_state;
// A value of GLFW_IME_PREEDIT_CHANGED means the pre-edit text for the input event has been changed.
// A value of GLFW_IME_COMMIT_TEXT means the text should be committed.
GLFWIMEState ime_state;
} GLFWkeyevent;
/*! @brief The function pointer type for error callbacks.
@@ -1661,7 +1600,7 @@ typedef void (* GLFWscrollfun)(GLFWwindow*,double,double,int,int);
* This is the function pointer type for key callbacks. A keyboard
* key callback function has the following signature:
* @code
* void function_name(GLFWwindow* window, int key, int native_key, int action, int mods)
* void function_name(GLFWwindow* window, uint32_t key, int native_key, int action, int mods)
* @endcode
* The semantics of this function are that the key that is interacted with on the
* keyboard is reported, and the text, if any generated by the key is reported.
@@ -1761,6 +1700,7 @@ typedef void (* GLFWjoystickfun)(int,int);
typedef void (* GLFWuserdatafun)(unsigned long long, void*);
typedef void (* GLFWtickcallback)(void*);
typedef bool (* GLFWdrawtextfun)(GLFWwindow *window, const char *text, uint32_t fg, uint32_t bg, uint8_t *output_buf, size_t width, size_t height, float x_offset, float y_offset, size_t right_margin);
/*! @brief Video mode type.
*
@@ -1917,6 +1857,7 @@ GLFWAPI void glfwStopMainLoop(void);
GLFWAPI unsigned long long glfwAddTimer(monotonic_t interval, bool repeats, GLFWuserdatafun callback, void * callback_data, GLFWuserdatafun free_callback);
GLFWAPI void glfwUpdateTimer(unsigned long long timer_id, monotonic_t interval, bool enabled);
GLFWAPI void glfwRemoveTimer(unsigned long long);
GLFWAPI GLFWdrawtextfun glfwSetDrawTextFunction(GLFWdrawtextfun function);
/*! @brief Terminates the GLFW library.
*
@@ -4300,108 +4241,19 @@ GLFWAPI int glfwRawMouseMotionSupported(void);
* __Do not use this function__ for [text input](@ref input_char). You will
* break text input for many languages even if it happens to work for yours.
*
* If the key is `GLFW_KEY_UNKNOWN`, the keycode is used to identify the key,
* If the key is `0`, the keycode is used to identify the key,
* otherwise the keycode is ignored. If you specify a non-printable key, or
* `GLFW_KEY_UNKNOWN` and a keycode that maps to a non-printable key, this
* `0` and a keycode that maps to a non-printable key, this
* function returns `NULL` but does not emit an error.
*
* This behavior allows you to always pass in the arguments in the
* [key callback](@ref input_key) without modification.
*
* The printable keys are:
* - `GLFW_KEY_SPACE`
* - `GLFW_KEY_EXCLAM`
* - `GLFW_KEY_DOUBLE_QUOTE`
* - `GLFW_KEY_NUMBER_SIGN`
* - `GLFW_KEY_DOLLAR`
* - `GLFW_KEY_AMPERSAND`
* - `GLFW_KEY_APOSTROPHE`
* - `GLFW_KEY_PARENTHESIS_LEFT`
* - `GLFW_KEY_PARENTHESIS_RIGHT`
* - `GLFW_KEY_PLUS`
* - `GLFW_KEY_COMMA`
* - `GLFW_KEY_MINUS`
* - `GLFW_KEY_PERIOD`
* - `GLFW_KEY_SLASH`
* - `GLFW_KEY_0` to `GLFW_KEY_9`
* - `GLFW_KEY_COLON`
* - `GLFW_KEY_SEMICOLON`
* - `GLFW_KEY_LESS`
* - `GLFW_KEY_EQUAL`
* - `GLFW_KEY_GREATER`
* - `GLFW_KEY_AT`
* - `GLFW_KEY_A` to `GLFW_KEY_Z`
* - `GLFW_KEY_LEFT_BRACKET`
* - `GLFW_KEY_BACKSLASH`
* - `GLFW_KEY_RIGHT_BRACKET`
* - `GLFW_KEY_CIRCUMFLEX`
* - `GLFW_KEY_UNDERSCORE`
* - `GLFW_KEY_GRAVE_ACCENT`
* - `GLFW_KEY_WORLD_1`
* - `GLFW_KEY_WORLD_2`
* - `GLFW_KEY_PARAGRAPH`
* - `GLFW_KEY_MASCULINE`
* - `GLFW_KEY_A_GRAVE`
* - `GLFW_KEY_A_DIAERESIS`
* - `GLFW_KEY_A_RING`
* - `GLFW_KEY_AE`
* - `GLFW_KEY_C_CEDILLA`
* - `GLFW_KEY_E_GRAVE`
* - `GLFW_KEY_E_ACUTE`
* - `GLFW_KEY_I_GRAVE`
* - `GLFW_KEY_N_TILDE`
* - `GLFW_KEY_O_GRAVE`
* - `GLFW_KEY_O_DIAERESIS`
* - `GLFW_KEY_O_SLASH`
* - `GLFW_KEY_U_GRAVE`
* - `GLFW_KEY_U_DIAERESIS`
* - `GLFW_KEY_S_SHARP`
* - `GLFW_KEY_CYRILLIC_A`
* - `GLFW_KEY_CYRILLIC_BE`
* - `GLFW_KEY_CYRILLIC_VE`
* - `GLFW_KEY_CYRILLIC_GHE`
* - `GLFW_KEY_CYRILLIC_DE`
* - `GLFW_KEY_CYRILLIC_IE`
* - `GLFW_KEY_CYRILLIC_ZHE`
* - `GLFW_KEY_CYRILLIC_ZE`
* - `GLFW_KEY_CYRILLIC_I`
* - `GLFW_KEY_CYRILLIC_SHORT_I`
* - `GLFW_KEY_CYRILLIC_KA`
* - `GLFW_KEY_CYRILLIC_EL`
* - `GLFW_KEY_CYRILLIC_EM`
* - `GLFW_KEY_CYRILLIC_EN`
* - `GLFW_KEY_CYRILLIC_O`
* - `GLFW_KEY_CYRILLIC_PE`
* - `GLFW_KEY_CYRILLIC_ER`
* - `GLFW_KEY_CYRILLIC_ES`
* - `GLFW_KEY_CYRILLIC_TE`
* - `GLFW_KEY_CYRILLIC_U`
* - `GLFW_KEY_CYRILLIC_EF`
* - `GLFW_KEY_CYRILLIC_HA`
* - `GLFW_KEY_CYRILLIC_TSE`
* - `GLFW_KEY_CYRILLIC_CHE`
* - `GLFW_KEY_CYRILLIC_SHA`
* - `GLFW_KEY_CYRILLIC_SHCHA`
* - `GLFW_KEY_CYRILLIC_HARD_SIGN`
* - `GLFW_KEY_CYRILLIC_YERU`
* - `GLFW_KEY_CYRILLIC_SOFT_SIGN`
* - `GLFW_KEY_CYRILLIC_E`
* - `GLFW_KEY_CYRILLIC_YU`
* - `GLFW_KEY_CYRILLIC_YA`
* - `GLFW_KEY_CYRILLIC_IO`
* - `GLFW_KEY_KP_0` to `GLFW_KEY_KP_9`
* - `GLFW_KEY_KP_DECIMAL`
* - `GLFW_KEY_KP_DIVIDE`
* - `GLFW_KEY_KP_MULTIPLY`
* - `GLFW_KEY_KP_SUBTRACT`
* - `GLFW_KEY_KP_ADD`
* - `GLFW_KEY_KP_EQUAL`
*
* Names for printable keys depend on keyboard layout, while names for
* non-printable keys are the same across layouts but depend on the application
* language and should be localized along with other user interface text.
*
* @param[in] key The key to query, or `GLFW_KEY_UNKNOWN`.
* @param[in] key The key to query, or `0`.
* @param[in] native_key The platform-specifc identifier of the key to query.
* @return The UTF-8 encoded, layout-specific name of the key, or `NULL`.
*
@@ -4422,13 +4274,13 @@ GLFWAPI int glfwRawMouseMotionSupported(void);
*
* @ingroup input
*/
GLFWAPI const char* glfwGetKeyName(int key, int native_key);
GLFWAPI const char* glfwGetKeyName(uint32_t key, int native_key);
/*! @brief Returns the platform-specific identifier of the specified key.
*
* This function returns the platform-specific identifier of the specified key.
*
* If the key is `GLFW_KEY_UNKNOWN` or does not exist on the keyboard this
* If the key is `0` or does not exist on the keyboard this
* method will return `-1`.
*
* @param[in] key Any [named key](@ref keys).
@@ -4446,7 +4298,7 @@ GLFWAPI const char* glfwGetKeyName(int key, int native_key);
*
* @ingroup input
*/
GLFWAPI int glfwGetNativeKeyForKey(int key);
GLFWAPI int glfwGetNativeKeyForKey(uint32_t key);
/*! @brief Returns the last reported state of a keyboard key for the specified
* window.
@@ -4470,7 +4322,7 @@ GLFWAPI int glfwGetNativeKeyForKey(int key);
* __Do not use this function__ to implement [text input](@ref input_char).
*
* @param[in] window The desired window.
* @param[in] key The desired [keyboard key](@ref keys). `GLFW_KEY_UNKNOWN` is
* @param[in] key The desired [keyboard key](@ref keys). `0` is
* not a valid key for this function.
* @return One of `GLFW_PRESS` or `GLFW_RELEASE`.
*
@@ -4486,7 +4338,7 @@ GLFWAPI int glfwGetNativeKeyForKey(int key);
*
* @ingroup input
*/
GLFWAPI int glfwGetKey(GLFWwindow* window, int key);
GLFWAPI GLFWKeyAction glfwGetKey(GLFWwindow* window, uint32_t key);
/*! @brief Returns the last reported state of a mouse button for the specified
* window.
@@ -4722,16 +4574,12 @@ GLFWAPI GLFWkeyboardfun glfwSetKeyboardCallback(GLFWwindow* window, GLFWkeyboard
* Used to notify the IME system of changes in state such as focus gained/lost
* and text cursor position.
*
* @param which: What data to notify. 1 means focus and 2 means cursor position.
* @param a, b, c, d: Interpreted based on the value of which. When which is 1
* a is interpreted as a boolean indicating focus gained/lost. When which is 2
* a, b, c, d are the cursor x, y, width and height values (in the window co-ordinate
* system).
* @param ev: What data to notify.
*
* @ingroup input
* @since Added in version 4.0
*/
GLFWAPI void glfwUpdateIMEState(GLFWwindow* window, int which, int a, int b, int c, int d);
GLFWAPI void glfwUpdateIMEState(GLFWwindow* window, const GLFWIMEUpdateEvent *ev);
/*! @brief Sets the mouse button callback.

10
glfw/ibus_glfw.c vendored
View File

@@ -107,11 +107,10 @@ get_ibus_text_from_message(DBusMessage *msg) {
}
static inline void
send_text(const char *text, int ime_state) {
send_text(const char *text, GLFWIMEState ime_state) {
_GLFWwindow *w = _glfwFocusedWindow();
if (w && w->callbacks.keyboard) {
GLFWkeyevent fake_ev;
_glfwInitializeKeyEvent(&fake_ev, GLFW_KEY_UNKNOWN, 0, GLFW_PRESS, 0);
GLFWkeyevent fake_ev = {.action = GLFW_PRESS};
fake_ev.text = text;
fake_ev.ime_state = ime_state;
w->callbacks.keyboard((GLFWwindow*) w, &fake_ev);
@@ -131,11 +130,11 @@ message_handler(DBusConnection *conn UNUSED, DBusMessage *msg, void *user_data)
case 0:
text = get_ibus_text_from_message(msg);
debug("IBUS: CommitText: '%s'\n", text ? text : "(nil)");
send_text(text, 2);
send_text(text, GLFW_IME_COMMIT_TEXT);
break;
case 1:
text = get_ibus_text_from_message(msg);
send_text(text, 1);
send_text(text, GLFW_IME_PREEDIT_CHANGED);
debug("IBUS: UpdatePreeditText: '%s'\n", text ? text : "(nil)");
break;
case 2:
@@ -390,6 +389,7 @@ ibus_key_state(unsigned int glfw_modifiers, int action) {
M(ALT, IBUS_MOD1_MASK);
M(NUM_LOCK, IBUS_MOD2_MASK);
M(SUPER, IBUS_MOD4_MASK);
/* To do: figure out how to get super/hyper/meta */
#undef M
return ans;
}

26
glfw/init.c vendored
View File

@@ -50,14 +50,14 @@ _GLFWlibrary _glfw = { false };
//
static _GLFWerror _glfwMainThreadError;
static GLFWerrorfun _glfwErrorCallback;
static _GLFWinitconfig _glfwInitHints =
{
true, // hat buttons
GLFW_ANGLE_PLATFORM_TYPE_NONE, // ANGLE backend
false, // debug keyboard
{
true, // macOS menu bar
true // macOS bundle chdir
static _GLFWinitconfig _glfwInitHints = {
.hatButtons = true,
.angleType = GLFW_ANGLE_PLATFORM_TYPE_NONE,
.debugKeyboard = false,
.debugRendering = false,
.ns = {
.menubar = true, // macOS menu bar
.chdir = true // macOS bundle chdir
}
};
@@ -285,6 +285,9 @@ GLFWAPI void glfwInitHint(int hint, int value)
case GLFW_DEBUG_KEYBOARD:
_glfwInitHints.debugKeyboard = value;
return;
case GLFW_DEBUG_RENDERING:
_glfwInitHints.debugRendering = value;
return;
case GLFW_COCOA_CHDIR_RESOURCES:
_glfwInitHints.ns.chdir = value;
return;
@@ -375,3 +378,10 @@ GLFWAPI GLFWapplicationclosefun glfwSetApplicationCloseCallback(GLFWapplicationc
_GLFW_SWAP_POINTERS(_glfw.callbacks.application_close, cbfun);
return cbfun;
}
GLFWAPI GLFWdrawtextfun glfwSetDrawTextFunction(GLFWdrawtextfun cbfun)
{
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFW_SWAP_POINTERS(_glfw.callbacks.draw_text, cbfun);
return cbfun;
}

455
glfw/input.c vendored
View File

@@ -273,34 +273,62 @@ static bool parseMapping(_GLFWmapping* mapping, const char* string)
////// GLFW event API //////
//////////////////////////////////////////////////////////////////////////
void _glfwInitializeKeyEvent(GLFWkeyevent *ev, int key, int native_key, int action, int mods)
{
ev->key = key;
ev->native_key = native_key;
ev->action = action;
ev->mods = mods;
ev->text = NULL;
ev->ime_state = 0;
static void
set_key_action(_GLFWwindow *window, uint32_t key, int val, int idx) {
const unsigned sz = arraysz(window->activated_keys);
if (idx < 0) {
for (unsigned i = 0; i < sz; i++) {
if (window->activated_keys[i].key == 0) {
idx = i;
break;
}
}
if (idx < 0) {
idx = sz - 1;
memmove(window->activated_keys, window->activated_keys + 1, sizeof(window->activated_keys[0]) * (sz - 1));
window->activated_keys[sz - 1].key = key;
}
}
if (val == GLFW_RELEASE) {
memset(window->activated_keys + idx, 0, sizeof(window->activated_keys[0]));
if (idx < (int)sz - 1) {
memmove(window->activated_keys + idx, window->activated_keys + idx + 1, sizeof(window->activated_keys[0]) * (sz - 1 - idx));
memset(window->activated_keys + sz - 1, 0, sizeof(window->activated_keys[0]));
}
} else {
window->activated_keys[idx].key = key;
window->activated_keys[idx].action = val;
}
}
// Notifies shared code of a physical key event
//
void _glfwInputKeyboard(_GLFWwindow* window, GLFWkeyevent* ev)
{
if (ev->key >= 0 && ev->key <= GLFW_KEY_LAST)
if (ev->key > 0)
{
bool repeated = false;
int idx = -1;
int current_action = GLFW_RELEASE;
const unsigned sz = arraysz(window->activated_keys);
for (unsigned i = 0; i < sz; i++) {
if (window->activated_keys[i].key == ev->key) {
idx = i;
current_action = window->activated_keys[i].action;
break;
}
}
if (ev->action == GLFW_RELEASE && window->keys[ev->key] == GLFW_RELEASE)
if (ev->action == GLFW_RELEASE && current_action == GLFW_RELEASE)
return;
if (ev->action == GLFW_PRESS && window->keys[ev->key] == GLFW_PRESS)
if (ev->action == GLFW_PRESS && current_action == GLFW_PRESS)
repeated = true;
if (ev->action == GLFW_RELEASE && window->stickyKeys)
window->keys[ev->key] = _GLFW_STICK;
set_key_action(window, ev->key, _GLFW_STICK, idx);
else
window->keys[ev->key] = (char) ev->action;
set_key_action(window, ev->key, ev->action, idx);
if (repeated)
ev->action = GLFW_REPEAT;
@@ -463,200 +491,156 @@ void _glfwFreeJoystick(_GLFWjoystick* js)
memset(js, 0, sizeof(_GLFWjoystick));
}
const char* _glfwGetKeyName(int key)
unsigned int
encode_utf8(uint32_t ch, char* dest) {
if (ch < 0x80) {
dest[0] = (char)ch;
return 1;
}
if (ch < 0x800) {
dest[0] = (ch>>6) | 0xC0;
dest[1] = (ch & 0x3F) | 0x80;
return 2;
}
if (ch < 0x10000) {
dest[0] = (ch>>12) | 0xE0;
dest[1] = ((ch>>6) & 0x3F) | 0x80;
dest[2] = (ch & 0x3F) | 0x80;
return 3;
}
if (ch < 0x110000) {
dest[0] = (ch>>18) | 0xF0;
dest[1] = ((ch>>12) & 0x3F) | 0x80;
dest[2] = ((ch>>6) & 0x3F) | 0x80;
dest[3] = (ch & 0x3F) | 0x80;
return 4;
}
return 0;
}
const char*
_glfwGetKeyName(int key)
{
switch (key)
{
// Printable keys
case GLFW_KEY_SPACE: return "SPACE";
case GLFW_KEY_EXCLAM: return "EXCLAM";
case GLFW_KEY_DOUBLE_QUOTE: return "DOUBLE_QUOTE";
case GLFW_KEY_NUMBER_SIGN: return "NUMBER_SIGN";
case GLFW_KEY_DOLLAR: return "DOLLAR";
case GLFW_KEY_AMPERSAND: return "AMPERSAND";
case GLFW_KEY_APOSTROPHE: return "APOSTROPHE";
case GLFW_KEY_PARENTHESIS_LEFT: return "PARENTHESIS_LEFT";
case GLFW_KEY_PARENTHESIS_RIGHT: return "PARENTHESIS_RIGHT";
case GLFW_KEY_PLUS: return "PLUS";
case GLFW_KEY_COMMA: return "COMMA";
case GLFW_KEY_MINUS: return "MINUS";
case GLFW_KEY_PERIOD: return "PERIOD";
case GLFW_KEY_SLASH: return "SLASH";
case GLFW_KEY_0: return "0";
case GLFW_KEY_1: return "1";
case GLFW_KEY_2: return "2";
case GLFW_KEY_3: return "3";
case GLFW_KEY_4: return "4";
case GLFW_KEY_5: return "5";
case GLFW_KEY_6: return "6";
case GLFW_KEY_7: return "7";
case GLFW_KEY_8: return "8";
case GLFW_KEY_9: return "9";
case GLFW_KEY_COLON: return "COLON";
case GLFW_KEY_SEMICOLON: return "SEMICOLON";
case GLFW_KEY_LESS: return "LESS";
case GLFW_KEY_EQUAL: return "EQUAL";
case GLFW_KEY_GREATER: return "GREATER";
case GLFW_KEY_AT: return "AT";
case GLFW_KEY_A: return "A";
case GLFW_KEY_B: return "B";
case GLFW_KEY_C: return "C";
case GLFW_KEY_D: return "D";
case GLFW_KEY_E: return "E";
case GLFW_KEY_F: return "F";
case GLFW_KEY_G: return "G";
case GLFW_KEY_H: return "H";
case GLFW_KEY_I: return "I";
case GLFW_KEY_J: return "J";
case GLFW_KEY_K: return "K";
case GLFW_KEY_L: return "L";
case GLFW_KEY_M: return "M";
case GLFW_KEY_N: return "N";
case GLFW_KEY_O: return "O";
case GLFW_KEY_P: return "P";
case GLFW_KEY_Q: return "Q";
case GLFW_KEY_R: return "R";
case GLFW_KEY_S: return "S";
case GLFW_KEY_T: return "T";
case GLFW_KEY_U: return "U";
case GLFW_KEY_V: return "V";
case GLFW_KEY_W: return "W";
case GLFW_KEY_X: return "X";
case GLFW_KEY_Y: return "Y";
case GLFW_KEY_Z: return "Z";
case GLFW_KEY_LEFT_BRACKET: return "LEFT_BRACKET";
case GLFW_KEY_BACKSLASH: return "BACKSLASH";
case GLFW_KEY_RIGHT_BRACKET: return "RIGHT_BRACKET";
case GLFW_KEY_CIRCUMFLEX: return "CIRCUMFLEX";
case GLFW_KEY_UNDERSCORE: return "UNDERSCORE";
case GLFW_KEY_GRAVE_ACCENT: return "GRAVE_ACCENT";
case GLFW_KEY_WORLD_1: return "WORLD_1";
case GLFW_KEY_WORLD_2: return "WORLD_2";
case GLFW_KEY_PARAGRAPH: return "PARAGRAPH";
case GLFW_KEY_MASCULINE: return "MASCULINE";
case GLFW_KEY_A_GRAVE: return "A_GRAVE";
case GLFW_KEY_A_DIAERESIS: return "A_DIAERESIS";
case GLFW_KEY_A_RING: return "A_RING";
case GLFW_KEY_AE: return "AE";
case GLFW_KEY_C_CEDILLA: return "C_CEDILLA";
case GLFW_KEY_E_GRAVE: return "E_GRAVE";
case GLFW_KEY_E_ACUTE: return "E_ACUTE";
case GLFW_KEY_I_GRAVE: return "I_GRAVE";
case GLFW_KEY_N_TILDE: return "N_TILDE";
case GLFW_KEY_O_GRAVE: return "O_GRAVE";
case GLFW_KEY_O_DIAERESIS: return "O_DIAERESIS";
case GLFW_KEY_O_SLASH: return "O_SLASH";
case GLFW_KEY_U_GRAVE: return "U_GRAVE";
case GLFW_KEY_U_DIAERESIS: return "U_DIAERESIS";
case GLFW_KEY_S_SHARP: return "S_SHARP";
case GLFW_KEY_CYRILLIC_A: return "CYRILLIC_A";
case GLFW_KEY_CYRILLIC_BE: return "CYRILLIC_BE";
case GLFW_KEY_CYRILLIC_VE: return "CYRILLIC_VE";
case GLFW_KEY_CYRILLIC_GHE: return "CYRILLIC_GHE";
case GLFW_KEY_CYRILLIC_DE: return "CYRILLIC_DE";
case GLFW_KEY_CYRILLIC_IE: return "CYRILLIC_IE";
case GLFW_KEY_CYRILLIC_ZHE: return "CYRILLIC_ZHE";
case GLFW_KEY_CYRILLIC_ZE: return "CYRILLIC_ZE";
case GLFW_KEY_CYRILLIC_I: return "CYRILLIC_I";
case GLFW_KEY_CYRILLIC_SHORT_I: return "CYRILLIC_SHORT_I";
case GLFW_KEY_CYRILLIC_KA: return "CYRILLIC_KA";
case GLFW_KEY_CYRILLIC_EL: return "CYRILLIC_EL";
case GLFW_KEY_CYRILLIC_EM: return "CYRILLIC_EM";
case GLFW_KEY_CYRILLIC_EN: return "CYRILLIC_EN";
case GLFW_KEY_CYRILLIC_O: return "CYRILLIC_O";
case GLFW_KEY_CYRILLIC_PE: return "CYRILLIC_PE";
case GLFW_KEY_CYRILLIC_ER: return "CYRILLIC_ER";
case GLFW_KEY_CYRILLIC_ES: return "CYRILLIC_ES";
case GLFW_KEY_CYRILLIC_TE: return "CYRILLIC_TE";
case GLFW_KEY_CYRILLIC_U: return "CYRILLIC_U";
case GLFW_KEY_CYRILLIC_EF: return "CYRILLIC_EF";
case GLFW_KEY_CYRILLIC_HA: return "CYRILLIC_HA";
case GLFW_KEY_CYRILLIC_TSE: return "CYRILLIC_TSE";
case GLFW_KEY_CYRILLIC_CHE: return "CYRILLIC_CHE";
case GLFW_KEY_CYRILLIC_SHA: return "CYRILLIC_SHA";
case GLFW_KEY_CYRILLIC_SHCHA: return "CYRILLIC_SHCHA";
case GLFW_KEY_CYRILLIC_HARD_SIGN: return "CYRILLIC_HARD_SIGN";
case GLFW_KEY_CYRILLIC_YERU: return "CYRILLIC_YERU";
case GLFW_KEY_CYRILLIC_SOFT_SIGN: return "CYRILLIC_SOFT_SIGN";
case GLFW_KEY_CYRILLIC_E: return "CYRILLIC_E";
case GLFW_KEY_CYRILLIC_YU: return "CYRILLIC_YU";
case GLFW_KEY_CYRILLIC_YA: return "CYRILLIC_YA";
case GLFW_KEY_CYRILLIC_IO: return "CYRILLIC_IO";
// Function keys
case GLFW_KEY_ESCAPE: return "ESCAPE";
case GLFW_KEY_F1: return "F1";
case GLFW_KEY_F2: return "F2";
case GLFW_KEY_F3: return "F3";
case GLFW_KEY_F4: return "F4";
case GLFW_KEY_F5: return "F5";
case GLFW_KEY_F6: return "F6";
case GLFW_KEY_F7: return "F7";
case GLFW_KEY_F8: return "F8";
case GLFW_KEY_F9: return "F9";
case GLFW_KEY_F10: return "F10";
case GLFW_KEY_F11: return "F11";
case GLFW_KEY_F12: return "F12";
case GLFW_KEY_F13: return "F13";
case GLFW_KEY_F14: return "F14";
case GLFW_KEY_F15: return "F15";
case GLFW_KEY_F16: return "F16";
case GLFW_KEY_F17: return "F17";
case GLFW_KEY_F18: return "F18";
case GLFW_KEY_F19: return "F19";
case GLFW_KEY_F20: return "F20";
case GLFW_KEY_F21: return "F21";
case GLFW_KEY_F22: return "F22";
case GLFW_KEY_F23: return "F23";
case GLFW_KEY_F24: return "F24";
case GLFW_KEY_F25: return "F25";
case GLFW_KEY_UP: return "UP";
case GLFW_KEY_DOWN: return "DOWN";
case GLFW_KEY_LEFT: return "LEFT";
case GLFW_KEY_RIGHT: return "RIGHT";
case GLFW_KEY_LEFT_SHIFT: return "LEFT SHIFT";
case GLFW_KEY_RIGHT_SHIFT: return "RIGHT SHIFT";
case GLFW_KEY_LEFT_CONTROL: return "LEFT CONTROL";
case GLFW_KEY_RIGHT_CONTROL: return "RIGHT CONTROL";
case GLFW_KEY_LEFT_ALT: return "LEFT ALT";
case GLFW_KEY_RIGHT_ALT: return "RIGHT ALT";
case GLFW_KEY_TAB: return "TAB";
case GLFW_KEY_ENTER: return "ENTER";
case GLFW_KEY_BACKSPACE: return "BACKSPACE";
case GLFW_KEY_INSERT: return "INSERT";
case GLFW_KEY_DELETE: return "DELETE";
case GLFW_KEY_PAGE_UP: return "PAGE UP";
case GLFW_KEY_PAGE_DOWN: return "PAGE DOWN";
case GLFW_KEY_HOME: return "HOME";
case GLFW_KEY_END: return "END";
case GLFW_KEY_KP_0: return "KEYPAD 0";
case GLFW_KEY_KP_1: return "KEYPAD 1";
case GLFW_KEY_KP_2: return "KEYPAD 2";
case GLFW_KEY_KP_3: return "KEYPAD 3";
case GLFW_KEY_KP_4: return "KEYPAD 4";
case GLFW_KEY_KP_5: return "KEYPAD 5";
case GLFW_KEY_KP_6: return "KEYPAD 6";
case GLFW_KEY_KP_7: return "KEYPAD 7";
case GLFW_KEY_KP_8: return "KEYPAD 8";
case GLFW_KEY_KP_9: return "KEYPAD 9";
case GLFW_KEY_KP_DIVIDE: return "KEYPAD DIVIDE";
case GLFW_KEY_KP_MULTIPLY: return "KEYPAD MULTIPLY";
case GLFW_KEY_KP_SUBTRACT: return "KEYPAD SUBTRACT";
case GLFW_KEY_KP_ADD: return "KEYPAD ADD";
case GLFW_KEY_KP_DECIMAL: return "KEYPAD DECIMAL";
case GLFW_KEY_KP_EQUAL: return "KEYPAD EQUAL";
case GLFW_KEY_KP_ENTER: return "KEYPAD ENTER";
case GLFW_KEY_PRINT_SCREEN: return "PRINT SCREEN";
case GLFW_KEY_NUM_LOCK: return "NUM LOCK";
case GLFW_KEY_CAPS_LOCK: return "CAPS LOCK";
case GLFW_KEY_SCROLL_LOCK: return "SCROLL LOCK";
case GLFW_KEY_PAUSE: return "PAUSE";
case GLFW_KEY_LEFT_SUPER: return "LEFT SUPER";
case GLFW_KEY_RIGHT_SUPER: return "RIGHT SUPER";
case GLFW_KEY_MENU: return "MENU";
default: return "UNKNOWN";
/* start functional key names (auto generated by gen-key-constants.py do not edit) */
case GLFW_FKEY_ESCAPE: return "ESCAPE";
case GLFW_FKEY_ENTER: return "ENTER";
case GLFW_FKEY_TAB: return "TAB";
case GLFW_FKEY_BACKSPACE: return "BACKSPACE";
case GLFW_FKEY_INSERT: return "INSERT";
case GLFW_FKEY_DELETE: return "DELETE";
case GLFW_FKEY_LEFT: return "LEFT";
case GLFW_FKEY_RIGHT: return "RIGHT";
case GLFW_FKEY_UP: return "UP";
case GLFW_FKEY_DOWN: return "DOWN";
case GLFW_FKEY_PAGE_UP: return "PAGE_UP";
case GLFW_FKEY_PAGE_DOWN: return "PAGE_DOWN";
case GLFW_FKEY_HOME: return "HOME";
case GLFW_FKEY_END: return "END";
case GLFW_FKEY_CAPS_LOCK: return "CAPS_LOCK";
case GLFW_FKEY_SCROLL_LOCK: return "SCROLL_LOCK";
case GLFW_FKEY_NUM_LOCK: return "NUM_LOCK";
case GLFW_FKEY_PRINT_SCREEN: return "PRINT_SCREEN";
case GLFW_FKEY_PAUSE: return "PAUSE";
case GLFW_FKEY_MENU: return "MENU";
case GLFW_FKEY_F1: return "F1";
case GLFW_FKEY_F2: return "F2";
case GLFW_FKEY_F3: return "F3";
case GLFW_FKEY_F4: return "F4";
case GLFW_FKEY_F5: return "F5";
case GLFW_FKEY_F6: return "F6";
case GLFW_FKEY_F7: return "F7";
case GLFW_FKEY_F8: return "F8";
case GLFW_FKEY_F9: return "F9";
case GLFW_FKEY_F10: return "F10";
case GLFW_FKEY_F11: return "F11";
case GLFW_FKEY_F12: return "F12";
case GLFW_FKEY_F13: return "F13";
case GLFW_FKEY_F14: return "F14";
case GLFW_FKEY_F15: return "F15";
case GLFW_FKEY_F16: return "F16";
case GLFW_FKEY_F17: return "F17";
case GLFW_FKEY_F18: return "F18";
case GLFW_FKEY_F19: return "F19";
case GLFW_FKEY_F20: return "F20";
case GLFW_FKEY_F21: return "F21";
case GLFW_FKEY_F22: return "F22";
case GLFW_FKEY_F23: return "F23";
case GLFW_FKEY_F24: return "F24";
case GLFW_FKEY_F25: return "F25";
case GLFW_FKEY_F26: return "F26";
case GLFW_FKEY_F27: return "F27";
case GLFW_FKEY_F28: return "F28";
case GLFW_FKEY_F29: return "F29";
case GLFW_FKEY_F30: return "F30";
case GLFW_FKEY_F31: return "F31";
case GLFW_FKEY_F32: return "F32";
case GLFW_FKEY_F33: return "F33";
case GLFW_FKEY_F34: return "F34";
case GLFW_FKEY_F35: return "F35";
case GLFW_FKEY_KP_0: return "KP_0";
case GLFW_FKEY_KP_1: return "KP_1";
case GLFW_FKEY_KP_2: return "KP_2";
case GLFW_FKEY_KP_3: return "KP_3";
case GLFW_FKEY_KP_4: return "KP_4";
case GLFW_FKEY_KP_5: return "KP_5";
case GLFW_FKEY_KP_6: return "KP_6";
case GLFW_FKEY_KP_7: return "KP_7";
case GLFW_FKEY_KP_8: return "KP_8";
case GLFW_FKEY_KP_9: return "KP_9";
case GLFW_FKEY_KP_DECIMAL: return "KP_DECIMAL";
case GLFW_FKEY_KP_DIVIDE: return "KP_DIVIDE";
case GLFW_FKEY_KP_MULTIPLY: return "KP_MULTIPLY";
case GLFW_FKEY_KP_SUBTRACT: return "KP_SUBTRACT";
case GLFW_FKEY_KP_ADD: return "KP_ADD";
case GLFW_FKEY_KP_ENTER: return "KP_ENTER";
case GLFW_FKEY_KP_EQUAL: return "KP_EQUAL";
case GLFW_FKEY_KP_SEPARATOR: return "KP_SEPARATOR";
case GLFW_FKEY_KP_LEFT: return "KP_LEFT";
case GLFW_FKEY_KP_RIGHT: return "KP_RIGHT";
case GLFW_FKEY_KP_UP: return "KP_UP";
case GLFW_FKEY_KP_DOWN: return "KP_DOWN";
case GLFW_FKEY_KP_PAGE_UP: return "KP_PAGE_UP";
case GLFW_FKEY_KP_PAGE_DOWN: return "KP_PAGE_DOWN";
case GLFW_FKEY_KP_HOME: return "KP_HOME";
case GLFW_FKEY_KP_END: return "KP_END";
case GLFW_FKEY_KP_INSERT: return "KP_INSERT";
case GLFW_FKEY_KP_DELETE: return "KP_DELETE";
case GLFW_FKEY_KP_BEGIN: return "KP_BEGIN";
case GLFW_FKEY_MEDIA_PLAY: return "MEDIA_PLAY";
case GLFW_FKEY_MEDIA_PAUSE: return "MEDIA_PAUSE";
case GLFW_FKEY_MEDIA_PLAY_PAUSE: return "MEDIA_PLAY_PAUSE";
case GLFW_FKEY_MEDIA_REVERSE: return "MEDIA_REVERSE";
case GLFW_FKEY_MEDIA_STOP: return "MEDIA_STOP";
case GLFW_FKEY_MEDIA_FAST_FORWARD: return "MEDIA_FAST_FORWARD";
case GLFW_FKEY_MEDIA_REWIND: return "MEDIA_REWIND";
case GLFW_FKEY_MEDIA_TRACK_NEXT: return "MEDIA_TRACK_NEXT";
case GLFW_FKEY_MEDIA_TRACK_PREVIOUS: return "MEDIA_TRACK_PREVIOUS";
case GLFW_FKEY_MEDIA_RECORD: return "MEDIA_RECORD";
case GLFW_FKEY_LOWER_VOLUME: return "LOWER_VOLUME";
case GLFW_FKEY_RAISE_VOLUME: return "RAISE_VOLUME";
case GLFW_FKEY_MUTE_VOLUME: return "MUTE_VOLUME";
case GLFW_FKEY_LEFT_SHIFT: return "LEFT_SHIFT";
case GLFW_FKEY_LEFT_CONTROL: return "LEFT_CONTROL";
case GLFW_FKEY_LEFT_ALT: return "LEFT_ALT";
case GLFW_FKEY_LEFT_SUPER: return "LEFT_SUPER";
case GLFW_FKEY_LEFT_HYPER: return "LEFT_HYPER";
case GLFW_FKEY_LEFT_META: return "LEFT_META";
case GLFW_FKEY_RIGHT_SHIFT: return "RIGHT_SHIFT";
case GLFW_FKEY_RIGHT_CONTROL: return "RIGHT_CONTROL";
case GLFW_FKEY_RIGHT_ALT: return "RIGHT_ALT";
case GLFW_FKEY_RIGHT_SUPER: return "RIGHT_SUPER";
case GLFW_FKEY_RIGHT_HYPER: return "RIGHT_HYPER";
case GLFW_FKEY_RIGHT_META: return "RIGHT_META";
case GLFW_FKEY_ISO_LEVEL3_SHIFT: return "ISO_LEVEL3_SHIFT";
case GLFW_FKEY_ISO_LEVEL5_SHIFT: return "ISO_LEVEL5_SHIFT";
/* end functional key names */
case 0: return "UNKNOWN";
}
static char buf[16];
encode_utf8(key, buf);
return buf;
}
// Center the cursor in the content area of the specified window
@@ -736,13 +720,15 @@ GLFWAPI void glfwSetInputMode(GLFWwindow* handle, int mode, int value)
if (!value)
{
int i;
// Release all sticky keys
for (i = 0; i <= GLFW_KEY_LAST; i++)
for (unsigned i = arraysz(window->activated_keys) - 1; i-- > 0;)
{
if (window->keys[i] == _GLFW_STICK)
window->keys[i] = GLFW_RELEASE;
if (window->activated_keys[i].action == _GLFW_STICK) {
if (i < arraysz(window->activated_keys) - 1) {
memmove(window->activated_keys + i, window->activated_keys + i + 1, sizeof(window->activated_keys[0]) * (arraysz(window->activated_keys) - 1 - i));
}
memset(window->activated_keys + arraysz(window->activated_keys) - 1, 0, sizeof(window->activated_keys[0]));
}
}
}
@@ -798,59 +784,50 @@ GLFWAPI int glfwRawMouseMotionSupported(void)
return _glfwPlatformRawMouseMotionSupported();
}
GLFWAPI const char* glfwGetKeyName(int key, int native_key)
GLFWAPI const char* glfwGetKeyName(uint32_t key, int native_key)
{
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
if (key) return _glfwGetKeyName(key);
if (key != GLFW_KEY_UNKNOWN)
{
if (key != GLFW_KEY_KP_EQUAL &&
(key < GLFW_KEY_KP_0 || key > GLFW_KEY_KP_ADD) &&
(key < GLFW_KEY_APOSTROPHE || key > GLFW_KEY_LAST_PRINTABLE))
{
return NULL;
}
native_key = _glfwPlatformGetNativeKeyForKey(key);
}
native_key = _glfwPlatformGetNativeKeyForKey(key);
return _glfwPlatformGetNativeKeyName(native_key);
}
GLFWAPI int glfwGetNativeKeyForKey(int key)
GLFWAPI int glfwGetNativeKeyForKey(uint32_t key)
{
_GLFW_REQUIRE_INIT_OR_RETURN(-1);
if (key < GLFW_KEY_SPACE || key > GLFW_KEY_LAST)
{
_glfwInputError(GLFW_INVALID_ENUM, "Invalid key %i", key);
return GLFW_RELEASE;
}
return _glfwPlatformGetNativeKeyForKey(key);
}
GLFWAPI int glfwGetKey(GLFWwindow* handle, int key)
GLFWAPI GLFWKeyAction glfwGetKey(GLFWwindow* handle, uint32_t key)
{
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_RELEASE);
if (!key) return GLFW_RELEASE;
if (key < GLFW_KEY_SPACE || key > GLFW_KEY_LAST)
{
_glfwInputError(GLFW_INVALID_ENUM, "Invalid key %i", key);
return GLFW_RELEASE;
int current_action = GLFW_RELEASE;
const unsigned sz = arraysz(window->activated_keys);
int idx = -1;
for (unsigned i = 0; i < sz; i++) {
if (window->activated_keys[i].key == key) {
idx = i;
current_action = window->activated_keys[i].action;
break;
}
}
if (window->keys[key] == _GLFW_STICK)
if (current_action == _GLFW_STICK)
{
// Sticky mode: release key now
window->keys[key] = GLFW_RELEASE;
return GLFW_PRESS;
set_key_action(window, key, GLFW_RELEASE, idx);
current_action = GLFW_PRESS;
}
return (int) window->keys[key];
return current_action;
}
GLFWAPI int glfwGetMouseButton(GLFWwindow* handle, int button)
@@ -1036,13 +1013,13 @@ GLFWAPI GLFWkeyboardfun glfwSetKeyboardCallback(GLFWwindow* handle, GLFWkeyboard
return cbfun;
}
GLFWAPI void glfwUpdateIMEState(GLFWwindow* handle, int which, int a, int b, int c, int d) {
GLFWAPI void glfwUpdateIMEState(GLFWwindow* handle, const GLFWIMEUpdateEvent *ev) {
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
_GLFW_REQUIRE_INIT();
#if defined(_GLFW_X11) || defined(_GLFW_WAYLAND) || defined(_GLFW_COCOA)
_glfwPlatformUpdateIMEState(window, which, a, b, c, d);
_glfwPlatformUpdateIMEState(window, ev);
#else
(void)window; (void)which; (void)a; (void)b; (void)c; (void)d;
#endif

15
glfw/internal.h vendored
View File

@@ -276,6 +276,7 @@ struct _GLFWinitconfig
bool hatButtons;
int angleType;
bool debugKeyboard;
bool debugRendering;
struct {
bool menubar;
bool chdir;
@@ -401,6 +402,11 @@ struct _GLFWcontext
_GLFWcontextOSMesa osmesa;
};
typedef struct GLFWKeyState {
uint32_t key;
char action;
} GLFWKeyState;
// Window and context structure
//
struct _GLFWwindow
@@ -431,7 +437,7 @@ struct _GLFWwindow
bool lockKeyMods;
int cursorMode;
char mouseButtons[GLFW_MOUSE_BUTTON_LAST + 1];
char keys[GLFW_KEY_LAST + 1];
GLFWKeyState activated_keys[16];
// Virtual cursor position when cursor is disabled
double virtualCursorPosX, virtualCursorPosY;
bool rawMouseMotion;
@@ -609,6 +615,7 @@ struct _GLFWlibrary
GLFWmonitorfun monitor;
GLFWjoystickfun joystick;
GLFWapplicationclosefun application_close;
GLFWdrawtextfun draw_text;
} callbacks;
@@ -649,7 +656,7 @@ void _glfwPlatformDestroyCursor(_GLFWcursor* cursor);
void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor);
const char* _glfwPlatformGetNativeKeyName(int native_key);
int _glfwPlatformGetNativeKeyForKey(int key);
int _glfwPlatformGetNativeKeyForKey(uint32_t key);
void _glfwPlatformFreeMonitor(_GLFWmonitor* monitor);
void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos);
@@ -723,7 +730,8 @@ void _glfwPlatformSetWindowDecorated(_GLFWwindow* window, bool enabled);
void _glfwPlatformSetWindowFloating(_GLFWwindow* window, bool enabled);
void _glfwPlatformSetWindowMousePassthrough(_GLFWwindow* window, bool enabled);
void _glfwPlatformSetWindowOpacity(_GLFWwindow* window, float opacity);
void _glfwPlatformUpdateIMEState(_GLFWwindow *w, int which, int a, int b, int c, int d);
void _glfwPlatformUpdateIMEState(_GLFWwindow *w, const GLFWIMEUpdateEvent *ev);
void _glfwPlatformChangeCursorTheme(void);
void _glfwPlatformPollEvents(void);
void _glfwPlatformWaitEvents(void);
@@ -771,7 +779,6 @@ void _glfwInputWindowDamage(_GLFWwindow* window);
void _glfwInputWindowCloseRequest(_GLFWwindow* window);
void _glfwInputWindowMonitor(_GLFWwindow* window, _GLFWmonitor* monitor);
void _glfwInitializeKeyEvent(GLFWkeyevent *ev, int key, int native_key, int action, int mods);
void _glfwInputKeyboard(_GLFWwindow *window, GLFWkeyevent *ev);
void _glfwInputScroll(_GLFWwindow* window, double xoffset, double yoffset, int flags, int mods);
void _glfwInputMouseClick(_GLFWwindow* window, int button, int action, int mods);

109
glfw/linux_desktop_settings.c vendored Normal file
View File

@@ -0,0 +1,109 @@
/*
* linux_cursor_settings.c
* Copyright (C) 2021 Kovid Goyal <kovid at kovidgoyal.net>
*
* Distributed under terms of the GPL3 license.
*/
#include "linux_desktop_settings.h"
#include <stdlib.h>
#include <strings.h>
#include <string.h>
static const char *DESKTOP_SERVICE = "org.freedesktop.portal.Desktop";
static const char *DESKTOP_PATH = "/org/freedesktop/portal/desktop";
static const char *DESKTOP_INTERFACE = "org.freedesktop.portal.Settings";
static const char *GNOME_DESKTOP_NAMESPACE = "org.gnome.desktop.interface";
static char theme_name[64] = {0};
static int theme_size = -1;
static bool gnome_cursor_theme_read = false, gnome_cursor_size_read = false;
static bool
parse_dbus_message_for_type(DBusMessage *const reply, const char *errmsg, const int type, void *value) {
DBusMessageIter iter[3];
dbus_message_iter_init(reply, &iter[0]);
#define FAIL { _glfwInputError(GLFW_PLATFORM_ERROR, "%s", errmsg); return false; }
if (dbus_message_iter_get_arg_type(&iter[0]) != DBUS_TYPE_VARIANT) FAIL;
dbus_message_iter_recurse(&iter[0], &iter[1]);
if (dbus_message_iter_get_arg_type(&iter[1]) != DBUS_TYPE_VARIANT) FAIL;
dbus_message_iter_recurse(&iter[1], &iter[2]);
if (dbus_message_iter_get_arg_type(&iter[2]) != type) FAIL;
dbus_message_iter_get_basic(&iter[2], value);
return true;
#undef FAIL
}
#define HANDLER(name) void name(DBusMessage *msg, const char* errmsg, void *data) { \
(void)data; \
if (errmsg) { \
_glfwInputError(GLFW_PLATFORM_ERROR, "%s: failed with error: %s", #name, errmsg); \
return; \
}
HANDLER(on_gnome_cursor_theme_read)
const char *name;
if (!parse_dbus_message_for_type(msg, "Failed to get cursor theme name from reply", DBUS_TYPE_STRING, &name)) return;
if (name && name[0]) {
gnome_cursor_theme_read = true;
strncpy(theme_name, name, sizeof(theme_name) - 1);
if (gnome_cursor_size_read) _glfwPlatformChangeCursorTheme();
}
}
HANDLER(on_gnome_cursor_size_read)
int32_t sz;
if (!parse_dbus_message_for_type(msg, "Failed to get cursor theme size from reply", DBUS_TYPE_INT32, &sz)) return;
gnome_cursor_size_read = true;
theme_size = sz;
if (gnome_cursor_theme_read) _glfwPlatformChangeCursorTheme();
}
#undef HANDLER
static bool
call_read(DBusConnection *session_bus, dbus_pending_callback callback, const char *namespace, const char *key) {
return glfw_dbus_call_method_with_reply(
session_bus, DESKTOP_SERVICE, DESKTOP_PATH, DESKTOP_INTERFACE, "Read", DBUS_TIMEOUT_USE_DEFAULT,
callback, NULL, DBUS_TYPE_STRING, &namespace, DBUS_TYPE_STRING, &key, DBUS_TYPE_INVALID);
}
static void
get_from_gnome(void) {
theme_size = 32;
DBusConnection *session_bus = glfw_dbus_session_bus();
if (session_bus) {
const char *theme_key = "cursor-theme";
call_read(session_bus, on_gnome_cursor_theme_read, GNOME_DESKTOP_NAMESPACE, theme_key);
const char *size_key = "cursor-size";
call_read(session_bus, on_gnome_cursor_size_read, GNOME_DESKTOP_NAMESPACE, size_key);
}
}
void
glfw_current_cursor_theme(const char **theme, int *size) {
*theme = theme_name[0] ? theme_name : NULL;
*size = (theme_size > 0 && theme_size < 2048) ? theme_size : 32;
}
static void
get_cursor_theme_from_env(void) {
const char *q = getenv("XCURSOR_THEME");
if (q) strncpy(theme_name, q, sizeof(theme_name)-1);
const char *env = getenv("XCURSOR_SIZE");
theme_size = 32;
if (env) {
const int retval = atoi(env);
if (retval > 0 && retval < 2048) theme_size = retval;
}
}
void
glfw_initialize_desktop_settings(void) {
get_cursor_theme_from_env();
const char *desktop = getenv("XDG_CURRENT_DESKTOP");
bool is_gnome = desktop && strncasecmp(desktop, "GNOME", sizeof("GNOME") - 1) == 0;
if (is_gnome) get_from_gnome();
}

14
glfw/linux_desktop_settings.h vendored Normal file
View File

@@ -0,0 +1,14 @@
/*
* Copyright (C) 2021 Kovid Goyal <kovid at kovidgoyal.net>
*
* Distributed under terms of the GPL3 license.
*/
#pragma once
#include "dbus_glfw.h"
#include "internal.h"
void glfw_initialize_desktop_settings(void);
void glfw_current_cursor_theme(const char **theme, int *size);

7
glfw/memfd.h vendored
View File

@@ -10,8 +10,8 @@
#include <unistd.h>
#include <sys/syscall.h>
static inline int memfd_create(const char *name, unsigned int flags) {
return syscall(__NR_memfd_create, name, flags);
static inline int glfw_memfd_create(const char *name, unsigned int flags) {
return (int)syscall(__NR_memfd_create, name, flags);
}
#ifndef F_LINUX_SPECIFIC_BASE
@@ -39,8 +39,7 @@ static inline int memfd_create(const char *name, unsigned int flags) {
#include <unistd.h>
#include <fcntl.h>
static inline int
createTmpfileCloexec(char* tmpname)
static inline int createTmpfileCloexec(char* tmpname)
{
int fd;

View File

@@ -55,6 +55,7 @@
"wl_platform.h",
"posix_thread.h",
"wl_cursors.h",
"wl_text_input.h",
"xkb_glfw.h",
"dbus_glfw.h",
"ibus_glfw.h",
@@ -64,6 +65,8 @@
"linux_joystick.h",
"null_joystick.h",
"linux_notify.h",
"linux_desktop_settings.h",
"wl_client_side_decorations.h",
"main_loop.h"
],
"protocols": [
@@ -73,13 +76,16 @@
"unstable/pointer-constraints/pointer-constraints-unstable-v1.xml",
"unstable/idle-inhibit/idle-inhibit-unstable-v1.xml",
"unstable/xdg-decoration/xdg-decoration-unstable-v1.xml",
"unstable/primary-selection/primary-selection-unstable-v1.xml"
"unstable/primary-selection/primary-selection-unstable-v1.xml",
"unstable/text-input/text-input-unstable-v3.xml"
],
"sources": [
"wl_init.c",
"wl_monitor.c",
"wl_window.c",
"wl_cursors.c",
"wl_text_input.c",
"wl_client_side_decorations.c",
"posix_thread.c",
"xkb_glfw.c",
"dbus_glfw.c",
@@ -88,6 +94,7 @@
"osmesa_context.c",
"backend_utils.c",
"linux_joystick.c",
"linux_desktop_settings.c",
"null_joystick.c",
"linux_notify.c"
]

16
glfw/window.c vendored
View File

@@ -50,21 +50,19 @@ void _glfwInputWindowFocus(_GLFWwindow* window, bool focused)
if (!focused)
{
int key, button;
_glfw.focusedWindowId = 0;
for (key = 0; key <= GLFW_KEY_LAST; key++)
for (unsigned i = 0; i < arraysz(window->activated_keys); i++)
{
if (window->keys[key] == GLFW_PRESS)
if (window->activated_keys[i].key > 0 && window->activated_keys[i].action == GLFW_PRESS)
{
const int native_key = _glfwPlatformGetNativeKeyForKey(key);
GLFWkeyevent ev;
_glfwInitializeKeyEvent(&ev, key, native_key, GLFW_RELEASE, 0);
const int native_key = _glfwPlatformGetNativeKeyForKey(window->activated_keys[i].key);
GLFWkeyevent ev = {.key = window->activated_keys[i].key, .native_key = native_key, .action = GLFW_RELEASE};
_glfwInputKeyboard(window, &ev);
}
}
for (button = 0; button <= GLFW_MOUSE_BUTTON_LAST; button++)
for (int button = 0; button <= GLFW_MOUSE_BUTTON_LAST; button++)
{
if (window->mouseButtons[button] == GLFW_PRESS)
_glfwInputMouseClick(window, button, GLFW_RELEASE, 0);
@@ -703,8 +701,8 @@ GLFWAPI void glfwSetWindowSizeIncrements(GLFWwindow* handle, int widthincr, int
{
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
assert(widthincr >= 0);
assert(heightincr >= 0);
assert(widthincr >= 0 || widthincr == GLFW_DONT_CARE);
assert(heightincr >= 0 || heightincr == GLFW_DONT_CARE);
_GLFW_REQUIRE_INIT();

438
glfw/wl_client_side_decorations.c vendored Normal file
View File

@@ -0,0 +1,438 @@
/*
* wl_client_side_decorations.c
* Copyright (C) 2021 Kovid Goyal <kovid at kovidgoyal.net>
*
* Distributed under terms of the GPL3 license.
*/
#include "wl_client_side_decorations.h"
#include "backend_utils.h"
#include <sys/mman.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#define debug(...) if (_glfw.hints.init.debugRendering) fprintf(stderr, __VA_ARGS__);
#define decs window->wl.decorations
#define ARGB(a, r, g, b) (((a) << 24) | ((r) << 16) | ((g) << 8) | (b))
#define A(x) (((x) >> 24) & 0xff)
#define R(x) (((x) >> 16) & 0xff)
#define G(x) (((x) >> 8) & 0xff)
#define B(x) ((x) & 0xff)
#define SWAP(x, y) do { __typeof__(x) SWAP = x; x = y; y = SWAP; } while (0)
static const uint32_t passive_bg_color = 0xffeeeeee;
static const uint32_t active_bg_color = 0xffdddad6;
typedef float kernel_type;
static void
build_blur_kernel(kernel_type *blur_kernel, const size_t size, kernel_type sigma) {
// 1D Normalized Gaussian
const kernel_type half = size / (kernel_type)2;
kernel_type sum = 0;
for (size_t i = 0; i < size; i++) {
kernel_type f = (i - half);
blur_kernel[i] = (kernel_type)exp(- f * f / sigma);
sum += blur_kernel[i];
}
for (size_t i = 0; i < size; i++) blur_kernel[i] /= sum;
}
static void
blur_mask(kernel_type *image_data, ssize_t width, ssize_t height, ssize_t kernel_size, kernel_type sigma, kernel_type *scratch, kernel_type *blur_kernel, ssize_t margin) {
(void)margin;
build_blur_kernel(blur_kernel, kernel_size, sigma);
const size_t half = kernel_size / 2;
for (ssize_t y = 0; y < height; y++) {
kernel_type *s = image_data + y * width, *d = scratch + y * width;
for (ssize_t x = 0; x < width; x++) {
kernel_type a = 0;
for (ssize_t k = 0; k < kernel_size; k++) {
const ssize_t px = x + k - half;
if (0 <= px && px < width) a += s[px] * blur_kernel[k];
}
d[x] = a;
}
}
for (ssize_t y = 0; y < height; y++) {
kernel_type *d = image_data + y * width;
for (ssize_t x = 0; x < width; x++) {
kernel_type a = 0;
for (ssize_t k = 0; k < kernel_size; k++) {
const ssize_t py = y + k - half;
if (0 <= py && py < height) {
kernel_type *s = scratch + py * width;
a += s[x] * blur_kernel[k];
}
}
d[x] = a;
}
}
}
static kernel_type*
create_shadow_mask(size_t width, size_t height, size_t margin, size_t kernel_size, kernel_type base_alpha, kernel_type sigma) {
kernel_type *mask = calloc(sizeof(kernel_type), 2 * width * height + kernel_size);
if (!mask) return NULL;
for (size_t y = margin; y < height - margin; y++) {
kernel_type *row = mask + y * width;
for (size_t x = margin; x < width - margin; x++) row[x] = base_alpha;
}
blur_mask(mask, width, height, kernel_size, sigma, mask + width * height, (kernel_type*)(mask + 2 * width * height), margin);
return mask;
}
static void
swap_buffers(_GLFWWaylandBufferPair *pair) {
SWAP(pair->front, pair->back);
SWAP(pair->data.front, pair->data.back);
}
static size_t
init_buffer_pair(_GLFWWaylandBufferPair *pair, size_t width, size_t height, unsigned scale) {
memset(pair, 0, sizeof(_GLFWWaylandBufferPair));
pair->width = width * scale;
pair->height = height * scale;
pair->stride = 4 * pair->width;
pair->size_in_bytes = pair->stride * pair->height;
return 2 * pair->size_in_bytes;
}
static void
alloc_buffer_pair(_GLFWWaylandBufferPair *pair, struct wl_shm_pool *pool, uint8_t *data, size_t *offset) {
pair->data.a = data + *offset;
pair->a = wl_shm_pool_create_buffer(pool, *offset, pair->width, pair->height, pair->stride, WL_SHM_FORMAT_ARGB8888);
*offset += pair->size_in_bytes;
pair->data.b = data + *offset;
pair->b = wl_shm_pool_create_buffer(pool, *offset, pair->width, pair->height, pair->stride, WL_SHM_FORMAT_ARGB8888);
*offset += pair->size_in_bytes;
pair->front = pair->a; pair->back = pair->b;
pair->data.front = pair->data.a; pair->data.back = pair->data.b;
}
#define st decs.shadow_tile
void
initialize_csd_metrics(_GLFWwindow *window) {
decs.metrics.width = 12;
decs.metrics.top = 36;
decs.metrics.visible_titlebar_height = window->wl.decorations.metrics.top - window->wl.decorations.metrics.width;
decs.metrics.horizontal = 2 * window->wl.decorations.metrics.width;
decs.metrics.vertical = window->wl.decorations.metrics.width + window->wl.decorations.metrics.top;
}
static size_t
create_shadow_tile(_GLFWwindow *window) {
const size_t margin = decs.bottom.buffer.height;
if (st.data && st.for_decoration_size == margin) return margin;
st.for_decoration_size = margin;
free(st.data);
st.segments = 7;
st.stride = st.segments * margin;
st.corner_size = margin * (st.segments - 1) / 2;
kernel_type* mask = create_shadow_mask(st.stride, st.stride, margin, 2 * margin + 1, (kernel_type)0.7, 32 * margin);
st.data = malloc(sizeof(uint32_t) * st.stride * st.stride);
if (st.data) for (size_t i = 0; i < st.stride * st.stride; i++) st.data[i] = ((uint8_t)(mask[i] * 255)) << 24;
free(mask);
return margin;
}
static void
render_title_bar(_GLFWwindow *window, bool to_front_buffer) {
const bool is_focused = window->id == _glfw.focusedWindowId;
uint32_t bg_color = is_focused ? active_bg_color : passive_bg_color;
uint32_t fg_color = is_focused ? 0xff444444 : 0xff888888;
if (decs.use_custom_titlebar_color) {
bg_color = 0xff000000 | (decs.titlebar_color & 0xffffff);
double red = ((bg_color >> 16) & 0xFF) / 255.0;
double green = ((bg_color >> 8) & 0xFF) / 255.0;
double blue = (bg_color & 0xFF) / 255.0;
double luma = 0.2126 * red + 0.7152 * green + 0.0722 * blue;
if (luma < 0.5) {
fg_color = is_focused ? 0xffeeeeee : 0xff888888;
}
}
uint8_t *output = to_front_buffer ? decs.top.buffer.data.front : decs.top.buffer.data.back;
// render shadow part
const size_t margin = create_shadow_tile(window);
const size_t edge_segment_size = st.corner_size - margin;
const uint8_t divisor = is_focused ? 1 : 2;
for (size_t y = 0; y < margin; y++) {
// left segment
uint32_t *s = st.data + y * st.stride + margin;
uint32_t *d = (uint32_t*)(output + y * decs.top.buffer.stride);
for (size_t x = 0; x < edge_segment_size; x++) d[x] = (A(s[x]) / divisor) << 24;
// middle segment
s += edge_segment_size;
size_t limit = decs.top.buffer.width > edge_segment_size ? decs.top.buffer.width - edge_segment_size : 0;
for (size_t x = edge_segment_size, sx = 0; x < limit; x++, sx = (sx + 1) % margin) d[x] = (A(s[sx]) / divisor) << 24;
// right segment
s += margin;
for (size_t x = limit; x < decs.top.buffer.width; x++, s++) d[x] = (A(*s) / divisor) << 24;
}
// render text part
output += decs.top.buffer.stride * margin;
if (window->wl.title && window->wl.title[0] && _glfw.callbacks.draw_text) {
if (_glfw.callbacks.draw_text((GLFWwindow*)window, window->wl.title, fg_color, bg_color, output, decs.top.buffer.width, decs.top.buffer.height - margin, 0, 0, 0)) return;
}
for (uint32_t *px = (uint32_t*)output, *end = (uint32_t*)(output + decs.top.buffer.size_in_bytes); px < end; px++) {
*px = bg_color;
}
}
static void
update_title_bar(_GLFWwindow *window) {
render_title_bar(window, false);
swap_buffers(&decs.top.buffer);
}
static void
render_edges(_GLFWwindow *window) {
const size_t margin = create_shadow_tile(window);
if (!st.data) return; // out of memory
// bottom edge
uint32_t *src = st.data + (st.segments - 1) * margin * st.stride;
for (size_t y = 0; y < margin; y++) {
uint32_t *d = (uint32_t*)(decs.bottom.buffer.data.front + y * decs.bottom.buffer.stride);
uint32_t *s = src + st.stride * y;
// left corner
for (size_t x = 0; x < st.corner_size && x < decs.bottom.buffer.width; x++) d[x] = s[x];
// middle
size_t pos = st.corner_size, limit = decs.bottom.buffer.width > st.corner_size ? decs.bottom.buffer.width - st.corner_size : 0;
s += st.corner_size;
while (pos < limit) {
uint32_t *p = d + pos;
for (size_t x = 0; x < margin && pos + x < limit; x++) p[x] = s[x];
pos += margin;
}
// right corner
s += margin;
for (size_t x = 0; x < st.corner_size && limit + x < decs.bottom.buffer.width; x++) d[limit + x] = s[x];
}
// upper corners
for (size_t y = 0; y < st.corner_size && y < decs.left.buffer.height; y++) {
uint32_t *left_src = st.data + st.stride * y;
uint32_t *left_dest = (uint32_t*)(decs.left.buffer.data.front + y * decs.left.buffer.stride);
memcpy(left_dest, left_src, margin * sizeof(uint32_t));
uint32_t *right_src = left_src + 2 * st.corner_size;
uint32_t *right_dest = (uint32_t*)(decs.right.buffer.data.front + y * decs.right.buffer.stride);
memcpy(right_dest, right_src, margin * sizeof(uint32_t));
}
// lower corners
size_t src_height = st.corner_size - margin;
size_t dest_top = decs.left.buffer.height > src_height ? decs.left.buffer.height - src_height : 0;
size_t src_top = st.corner_size + margin;
for (size_t src_y = src_top, dest_y = dest_top; src_y < src_top + src_height && dest_y < decs.left.buffer.height; src_y++, dest_y++) {
uint32_t *s = st.data + st.stride * src_y;
uint32_t *d = (uint32_t*)(decs.left.buffer.data.front + dest_y * decs.left.buffer.stride);
memcpy(d, s, margin * sizeof(uint32_t));
s += 2 * st.corner_size;
d = (uint32_t*)(decs.right.buffer.data.front + dest_y * decs.left.buffer.stride);
memcpy(d, s, margin * sizeof(uint32_t));
}
// sides
size_t limit = decs.left.buffer.height > src_height ? decs.left.buffer.height - src_height : 0;
for (size_t dest_y = st.corner_size, src_y = 0; dest_y < limit; dest_y++, src_y = (src_y + 1) % margin) {
uint32_t *src = st.data + (st.corner_size + src_y) * st.stride;
uint32_t *left_dest = (uint32_t*)(decs.left.buffer.data.front + dest_y * decs.left.buffer.stride);
memcpy(left_dest, src, margin * sizeof(uint32_t));
src += 2 * st.corner_size;
uint32_t *right_dest = (uint32_t*)(decs.right.buffer.data.front + dest_y * decs.right.buffer.stride);
memcpy(right_dest, src, margin * sizeof(uint32_t));
}
#define copy(which) for (uint32_t *src = (uint32_t*)decs.which.buffer.data.front, *dest = (uint32_t*)decs.which.buffer.data.back; src < (uint32_t*)(decs.which.buffer.data.front + decs.which.buffer.size_in_bytes); src++, dest++) *dest = (A(*src) / 2 ) << 24;
copy(left); copy(bottom); copy(right);
#undef copy
}
#undef st
static bool
create_shm_buffers(_GLFWwindow* window) {
const unsigned scale = window->wl.scale >= 1 ? window->wl.scale : 1;
const size_t vertical_width = decs.metrics.width, vertical_height = window->wl.height + decs.metrics.top;
const size_t horizontal_height = decs.metrics.width, horizontal_width = window->wl.width + 2 * decs.metrics.width;
decs.mapping.size = 0;
decs.mapping.size += init_buffer_pair(&decs.top.buffer, window->wl.width, decs.metrics.top, scale);
decs.mapping.size += init_buffer_pair(&decs.left.buffer, vertical_width, vertical_height, scale);
decs.mapping.size += init_buffer_pair(&decs.bottom.buffer, horizontal_width, horizontal_height, scale);
decs.mapping.size += init_buffer_pair(&decs.right.buffer, vertical_width, vertical_height, scale);
int fd = createAnonymousFile(decs.mapping.size);
if (fd < 0) {
_glfwInputError(GLFW_PLATFORM_ERROR, "Wayland: Creating a buffer file for %zu B failed: %s",
decs.mapping.size, strerror(errno));
return false;
}
decs.mapping.data = mmap(NULL, decs.mapping.size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (decs.mapping.data == MAP_FAILED) {
_glfwInputError(GLFW_PLATFORM_ERROR, "Wayland: mmap failed: %s", strerror(errno));
close(fd);
return false;
}
struct wl_shm_pool* pool = wl_shm_create_pool(_glfw.wl.shm, fd, decs.mapping.size);
close(fd);
size_t offset = 0;
#define a(which) alloc_buffer_pair(&decs.which.buffer, pool, decs.mapping.data, &offset)
a(top); a(left); a(bottom); a(right);
#undef a
wl_shm_pool_destroy(pool);
create_shadow_tile(window);
render_title_bar(window, true);
render_edges(window);
debug("Created decoration buffers at scale: %u vertical_height: %zu horizontal_width: %zu\n", scale, vertical_height, horizontal_width);
return true;
}
void
free_csd_surfaces(_GLFWwindow *window) {
#define d(which) {\
if (decs.which.subsurface) wl_subsurface_destroy(decs.which.subsurface); \
decs.which.subsurface = NULL; \
if (decs.which.surface) wl_surface_destroy(decs.which.surface); \
decs.which.surface = NULL; \
}
d(left); d(top); d(right); d(bottom);
#undef d
}
static void
free_csd_buffers(_GLFWwindow *window) {
#define d(which) { \
if (decs.which.buffer.a) wl_buffer_destroy(decs.which.buffer.a); \
if (decs.which.buffer.b) wl_buffer_destroy(decs.which.buffer.b); \
memset(&decs.which.buffer, 0, sizeof(_GLFWWaylandBufferPair)); \
}
d(left); d(top); d(right); d(bottom);
#undef d
if (decs.mapping.data) munmap(decs.mapping.data, decs.mapping.size);
decs.mapping.data = NULL; decs.mapping.size = 0;
}
static void
position_csd_surface(_GLFWWaylandCSDEdge *s, int x, int y, int scale) {
wl_surface_set_buffer_scale(s->surface, scale);
s->x = x; s->y = y;
wl_subsurface_set_position(s->subsurface, s->x, s->y);
}
static void
create_csd_surfaces(_GLFWwindow *window, _GLFWWaylandCSDEdge *s) {
s->surface = wl_compositor_create_surface(_glfw.wl.compositor);
s->subsurface = wl_subcompositor_get_subsurface(_glfw.wl.subcompositor, s->surface, window->wl.surface);
}
#define damage_csd(which, xbuffer) \
wl_surface_attach(decs.which.surface, xbuffer, 0, 0); \
wl_surface_damage(decs.which.surface, 0, 0, decs.which.buffer.width, decs.which.buffer.height); \
wl_surface_commit(decs.which.surface)
bool
ensure_csd_resources(_GLFWwindow *window) {
if (!window->decorated || window->wl.decorations.serverSide) return false;
const bool is_focused = window->id == _glfw.focusedWindowId;
const bool focus_changed = is_focused != decs.for_window_state.focused;
const bool size_changed = (
decs.for_window_state.width != window->wl.width ||
decs.for_window_state.height != window->wl.height ||
decs.for_window_state.scale != window->wl.scale ||
!decs.mapping.data
);
const bool needs_update = focus_changed || size_changed || !decs.left.surface;
if (!needs_update) return false;
if (size_changed) {
free_csd_buffers(window);
if (!create_shm_buffers(window)) return false;
}
int32_t x, y, scale = window->wl.scale < 1 ? 1 : window->wl.scale;
x = 0; y = -decs.metrics.top;
if (!decs.top.surface) create_csd_surfaces(window, &decs.top);
position_csd_surface(&decs.top, x, y, scale);
x = -decs.metrics.width; y = -decs.metrics.top;
if (!decs.left.surface) create_csd_surfaces(window, &decs.left);
position_csd_surface(&decs.left, x, y, scale);
x = -decs.metrics.width; y = window->wl.height;
if (!decs.bottom.surface) create_csd_surfaces(window, &decs.bottom);
position_csd_surface(&decs.bottom, x, y, scale);
x = window->wl.width; y = -decs.metrics.top;
if (!decs.right.surface) create_csd_surfaces(window, &decs.right);
position_csd_surface(&decs.right, x, y, scale);
if (focus_changed) update_title_bar(window);
damage_csd(top, decs.top.buffer.front);
damage_csd(left, is_focused ? decs.left.buffer.front : decs.left.buffer.back);
damage_csd(bottom, is_focused ? decs.bottom.buffer.front : decs.bottom.buffer.back);
damage_csd(right, is_focused ? decs.right.buffer.front : decs.right.buffer.back);
decs.for_window_state.width = window->wl.width;
decs.for_window_state.height = window->wl.height;
decs.for_window_state.scale = window->wl.scale;
decs.for_window_state.focused = is_focused;
return true;
}
void
free_all_csd_resources(_GLFWwindow *window) {
free_csd_surfaces(window);
free_csd_buffers(window);
if (decs.shadow_tile.data) free(decs.shadow_tile.data);
decs.shadow_tile.data = NULL;
}
void
change_csd_title(_GLFWwindow *window) {
if (!window->decorated || window->wl.decorations.serverSide) return;
if (ensure_csd_resources(window)) return; // CSD were re-rendered for other reasons
if (decs.top.surface) {
update_title_bar(window);
damage_csd(top, decs.top.buffer.front);
}
}
void
set_csd_window_geometry(_GLFWwindow *window, int32_t *width, int32_t *height) {
bool has_csd = window->decorated && !window->wl.decorations.serverSide && window->wl.decorations.left.surface && !(window->wl.toplevel_states & TOPLEVEL_STATE_FULLSCREEN);
bool size_specified_by_compositor = *width > 0 && *height > 0;
if (!size_specified_by_compositor) {
*width = window->wl.user_requested_content_size.width;
*height = window->wl.user_requested_content_size.height;
if (has_csd) *height += decs.metrics.visible_titlebar_height;
}
decs.geometry.x = 0; decs.geometry.y = 0;
decs.geometry.width = *width; decs.geometry.height = *height;
if (has_csd) {
decs.geometry.y = -decs.metrics.visible_titlebar_height;
*height -= decs.metrics.visible_titlebar_height;
}
}
void
set_titlebar_color(_GLFWwindow *window, uint32_t color, bool use_system_color) {
bool use_custom_color = !use_system_color;
if (use_custom_color != decs.use_custom_titlebar_color || color != decs.titlebar_color) {
decs.use_custom_titlebar_color = use_custom_color;
decs.titlebar_color = color;
}
if (window->decorated && decs.top.surface) {
update_title_bar(window);
damage_csd(top, decs.top.buffer.front);
}
}

17
glfw/wl_client_side_decorations.h vendored Normal file
View File

@@ -0,0 +1,17 @@
/*
* Copyright (C) 2021 Kovid Goyal <kovid at kovidgoyal.net>
*
* Distributed under terms of the GPL3 license.
*/
#pragma once
#include "internal.h"
void initialize_csd_metrics(_GLFWwindow *window);
void free_all_csd_resources(_GLFWwindow *window);
void free_csd_surfaces(_GLFWwindow *window);
void change_csd_title(_GLFWwindow *window);
bool ensure_csd_resources(_GLFWwindow *window);
void set_csd_window_geometry(_GLFWwindow *window, int32_t *width, int32_t *height);
void set_titlebar_color(_GLFWwindow *window, uint32_t color, bool use_system_color);

46
glfw/wl_cursors.c vendored
View File

@@ -1,6 +1,7 @@
// Future devs supporting whatever Wayland protocol stabilizes for cursor selection: see _themeAdd.
#include "internal.h"
#include "linux_desktop_settings.h"
#include <assert.h>
#include <errno.h>
@@ -8,38 +9,35 @@
#include <stdio.h>
#include <stdlib.h>
static GLFWWLCursorThemes cursor_themes;
static int
pixels_from_scale(int scale) {
static bool queried_env = false;
static int factor = 32;
if (!queried_env) {
const char *env = getenv("XCURSOR_SIZE");
if (env) {
const int retval = atoi(env);
if (retval > 0 && retval < 2048) factor = retval;
}
queried_env = true;
}
int factor;
const char* name;
glfw_current_cursor_theme(&name, &factor);
return factor * scale;
}
struct wl_cursor_theme*
glfw_wlc_theme_for_scale(int scale) {
GLFWWLCursorThemes *t = &_glfw.wl.cursor_themes;
for (size_t i = 0; i < t->count; i++) {
if (t->themes[i].scale == scale) return t->themes[i].theme;
for (size_t i = 0; i < cursor_themes.count; i++) {
if (cursor_themes.themes[i].scale == scale) return cursor_themes.themes[i].theme;
}
if (t->count >= t->capacity) {
t->themes = realloc(t->themes, sizeof(GLFWWLCursorTheme) * (t->count + 16));
if (!t->themes) {
if (cursor_themes.count >= cursor_themes.capacity) {
cursor_themes.themes = realloc(cursor_themes.themes, sizeof(GLFWWLCursorTheme) * (cursor_themes.count + 16));
if (!cursor_themes.themes) {
_glfwInputError(GLFW_PLATFORM_ERROR, "Wayland: Out of memory allocating space for cursor themes");
return NULL;
}
t->capacity = t->count + 16;
cursor_themes.capacity = cursor_themes.count + 16;
}
struct wl_cursor_theme *ans = wl_cursor_theme_load(getenv("XCURSOR_THEME"), pixels_from_scale(scale), _glfw.wl.shm);
int factor;
const char* name;
glfw_current_cursor_theme(&name, &factor);
struct wl_cursor_theme *ans = wl_cursor_theme_load(name, pixels_from_scale(scale), _glfw.wl.shm);
if (!ans) {
_glfwInputError(
GLFW_PLATFORM_ERROR, "Wayland: wl_cursor_theme_load failed at scale: %d pixels: %d",
@@ -47,7 +45,7 @@ glfw_wlc_theme_for_scale(int scale) {
);
return NULL;
}
GLFWWLCursorTheme *theme = t->themes + t->count++;
GLFWWLCursorTheme *theme = cursor_themes.themes + cursor_themes.count++;
theme->scale = scale;
theme->theme = ans;
return ans;
@@ -55,11 +53,9 @@ glfw_wlc_theme_for_scale(int scale) {
void
glfw_wlc_destroy(void) {
GLFWWLCursorThemes *t = &_glfw.wl.cursor_themes;
for (size_t i = 0; i < t->count; i++) {
wl_cursor_theme_destroy(t->themes[i].theme);
for (size_t i = 0; i < cursor_themes.count; i++) {
wl_cursor_theme_destroy(cursor_themes.themes[i].theme);
}
free(t->themes);
t->themes = NULL; t->capacity = 0; t->count = 0;
free(cursor_themes.themes);
cursor_themes.themes = NULL; cursor_themes.capacity = 0; cursor_themes.count = 0;
}

167
glfw/wl_init.c vendored
View File

@@ -29,6 +29,7 @@
#define _GNU_SOURCE
#include "internal.h"
#include "backend_utils.h"
#include "linux_desktop_settings.h"
#include "../kitty/monotonic.h"
#include <assert.h>
@@ -58,37 +59,21 @@ static inline int min(int n1, int n2)
return n1 < n2 ? n1 : n2;
}
static _GLFWwindow* findWindowFromDecorationSurface(struct wl_surface* surface,
int* which)
static _GLFWwindow*
findWindowFromDecorationSurface(struct wl_surface* surface, _GLFWdecorationSideWayland* which)
{
int focus;
_GLFWdecorationSideWayland focus;
if (!which) which = &focus;
_GLFWwindow* window = _glfw.windowListHead;
if (!which)
which = &focus;
while (window)
{
if (surface == window->wl.decorations.top.surface)
{
*which = topDecoration;
break;
}
if (surface == window->wl.decorations.left.surface)
{
*which = leftDecoration;
break;
}
if (surface == window->wl.decorations.right.surface)
{
*which = rightDecoration;
break;
}
if (surface == window->wl.decorations.bottom.surface)
{
*which = bottomDecoration;
break;
}
#define q(edge, result) if (surface == window->wl.decorations.edge.surface) { *which = result; break; }
while (window) {
q(top, TOP_DECORATION);
q(left, LEFT_DECORATION);
q(right, RIGHT_DECORATION);
q(bottom, BOTTOM_DECORATION);
window = window->next;
}
#undef q
return window;
}
@@ -103,7 +88,7 @@ static void pointerHandleEnter(void* data UNUSED,
if (!surface)
return;
int focus = 0;
_GLFWdecorationSideWayland focus = CENTRAL_WINDOW;
_GLFWwindow* window = wl_surface_get_user_data(surface);
if (!window)
{
@@ -173,6 +158,8 @@ static void setCursor(GLFWCursorShape shape, _GLFWwindow* window)
_glfw.wl.cursorPreviousShape = shape;
}
#define x window->wl.allCursorPosX
#define y window->wl.allCursorPosY
static void pointerHandleMotion(void* data UNUSED,
struct wl_pointer* pointer UNUSED,
uint32_t time UNUSED,
@@ -181,46 +168,45 @@ static void pointerHandleMotion(void* data UNUSED,
{
_GLFWwindow* window = _glfw.wl.pointerFocus;
GLFWCursorShape cursorShape = GLFW_ARROW_CURSOR;
double x, y;
if (!window)
return;
if (window->cursorMode == GLFW_CURSOR_DISABLED)
return;
x = wl_fixed_to_double(sx);
y = wl_fixed_to_double(sy);
window->wl.allCursorPosX = wl_fixed_to_double(sx);
window->wl.allCursorPosY = wl_fixed_to_double(sy);
switch (window->wl.decorations.focus)
{
case mainWindow:
case CENTRAL_WINDOW:
window->wl.cursorPosX = x;
window->wl.cursorPosY = y;
_glfwInputCursorPos(window, x, y);
_glfw.wl.cursorPreviousShape = GLFW_INVALID_CURSOR;
return;
case topDecoration:
if (y < _GLFW_DECORATION_WIDTH)
case TOP_DECORATION:
if (y < window->wl.decorations.metrics.width)
cursorShape = GLFW_VRESIZE_CURSOR;
else
cursorShape = GLFW_ARROW_CURSOR;
break;
case leftDecoration:
if (y < _GLFW_DECORATION_WIDTH)
case LEFT_DECORATION:
if (y < window->wl.decorations.metrics.width)
cursorShape = GLFW_NW_RESIZE_CURSOR;
else
cursorShape = GLFW_HRESIZE_CURSOR;
break;
case rightDecoration:
if (y < _GLFW_DECORATION_WIDTH)
case RIGHT_DECORATION:
if (y < window->wl.decorations.metrics.width)
cursorShape = GLFW_NE_RESIZE_CURSOR;
else
cursorShape = GLFW_HRESIZE_CURSOR;
break;
case bottomDecoration:
if (x < _GLFW_DECORATION_WIDTH)
case BOTTOM_DECORATION:
if (x < window->wl.decorations.metrics.width)
cursorShape = GLFW_SW_RESIZE_CURSOR;
else if (x > window->wl.width + _GLFW_DECORATION_WIDTH)
else if (x > window->wl.width + window->wl.decorations.metrics.width)
cursorShape = GLFW_SE_RESIZE_CURSOR;
else
cursorShape = GLFW_VRESIZE_CURSOR;
@@ -249,33 +235,46 @@ static void pointerHandleButton(void* data UNUSED,
{
switch (window->wl.decorations.focus)
{
case mainWindow:
case CENTRAL_WINDOW:
break;
case topDecoration:
if (window->wl.cursorPosY < _GLFW_DECORATION_WIDTH)
case TOP_DECORATION:
if (state == WL_POINTER_BUTTON_STATE_PRESSED) {
monotonic_t last_click_at = window->wl.decorations.last_click_on_top_decoration_at;
window->wl.decorations.last_click_on_top_decoration_at = monotonic();
if (window->wl.decorations.last_click_on_top_decoration_at - last_click_at <= _glfwPlatformGetDoubleClickInterval(window)) {
window->wl.decorations.last_click_on_top_decoration_at = 0;
if (window->wl.toplevel_states & TOPLEVEL_STATE_MAXIMIZED)
xdg_toplevel_unset_maximized(window->wl.xdg.toplevel);
else
xdg_toplevel_set_maximized(window->wl.xdg.toplevel);
return;
}
}
if (y < window->wl.decorations.metrics.width)
edges = XDG_TOPLEVEL_RESIZE_EDGE_TOP;
else
{
if (window->wl.xdg.toplevel)
xdg_toplevel_move(window->wl.xdg.toplevel, _glfw.wl.seat, serial);
}
break;
case leftDecoration:
if (window->wl.cursorPosY < _GLFW_DECORATION_WIDTH)
case LEFT_DECORATION:
if (y < window->wl.decorations.metrics.width)
edges = XDG_TOPLEVEL_RESIZE_EDGE_TOP_LEFT;
else
edges = XDG_TOPLEVEL_RESIZE_EDGE_LEFT;
break;
case rightDecoration:
if (window->wl.cursorPosY < _GLFW_DECORATION_WIDTH)
case RIGHT_DECORATION:
if (y < window->wl.decorations.metrics.width)
edges = XDG_TOPLEVEL_RESIZE_EDGE_TOP_RIGHT;
else
edges = XDG_TOPLEVEL_RESIZE_EDGE_RIGHT;
break;
case bottomDecoration:
if (window->wl.cursorPosX < _GLFW_DECORATION_WIDTH)
case BOTTOM_DECORATION:
if (x < window->wl.decorations.metrics.width)
edges = XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM_LEFT;
else if (window->wl.cursorPosX > window->wl.width + _GLFW_DECORATION_WIDTH)
else if (x > window->wl.width + window->wl.decorations.metrics.width)
edges = XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM_RIGHT;
else
edges = XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM;
@@ -291,18 +290,15 @@ static void pointerHandleButton(void* data UNUSED,
}
else if (button == BTN_RIGHT)
{
if (window->wl.decorations.focus != mainWindow && window->wl.xdg.toplevel)
if (window->wl.decorations.focus != CENTRAL_WINDOW && window->wl.xdg.toplevel)
{
xdg_toplevel_show_window_menu(window->wl.xdg.toplevel,
_glfw.wl.seat, serial,
(int32_t)window->wl.cursorPosX,
(int32_t)window->wl.cursorPosY);
xdg_toplevel_show_window_menu(window->wl.xdg.toplevel, _glfw.wl.seat, serial, (int32_t)x, (int32_t)y - window->wl.decorations.metrics.top);
return;
}
}
// Dont pass the button to the user if it was related to a decoration.
if (window->wl.decorations.focus != mainWindow)
if (window->wl.decorations.focus != CENTRAL_WINDOW)
return;
_glfw.wl.serial = serial;
@@ -318,6 +314,8 @@ static void pointerHandleButton(void* data UNUSED,
: GLFW_RELEASE,
_glfw.wl.xkb.states.modifiers);
}
#undef x
#undef y
static void pointerHandleAxis(void* data UNUSED,
struct wl_pointer* pointer UNUSED,
@@ -393,7 +391,7 @@ static void keyboardHandleEnter(void* data UNUSED,
}
_glfw.wl.serial = serial;
_glfw.wl.keyboardFocus = window;
_glfw.wl.keyboardFocusId = window->id;
_glfwInputWindowFocus(window, true);
uint32_t* key;
if (keys && _glfw.wl.keyRepeatInfo.key) {
@@ -411,21 +409,23 @@ static void keyboardHandleLeave(void* data UNUSED,
uint32_t serial,
struct wl_surface* surface UNUSED)
{
_GLFWwindow* window = _glfw.wl.keyboardFocus;
_GLFWwindow* window = _glfwWindowForId(_glfw.wl.keyboardFocusId);
if (!window)
return;
_glfw.wl.serial = serial;
_glfw.wl.keyboardFocus = NULL;
_glfw.wl.keyboardFocusId = 0;
_glfwInputWindowFocus(window, false);
toggleTimer(&_glfw.wl.eventLoopData, _glfw.wl.keyRepeatInfo.keyRepeatTimer, 0);
}
static void
dispatchPendingKeyRepeats(id_type timer_id UNUSED, void *data UNUSED) {
if (_glfw.wl.keyRepeatInfo.keyboardFocus != _glfw.wl.keyboardFocus || _glfw.wl.keyboardRepeatRate == 0) return;
glfw_xkb_handle_key_event(_glfw.wl.keyRepeatInfo.keyboardFocus, &_glfw.wl.xkb, _glfw.wl.keyRepeatInfo.key, GLFW_REPEAT);
if (_glfw.wl.keyRepeatInfo.keyboardFocusId != _glfw.wl.keyboardFocusId || _glfw.wl.keyboardRepeatRate == 0) return;
_GLFWwindow* window = _glfwWindowForId(_glfw.wl.keyboardFocusId);
if (!window) return;
glfw_xkb_handle_key_event(window, &_glfw.wl.xkb, _glfw.wl.keyRepeatInfo.key, GLFW_REPEAT);
changeTimerInterval(&_glfw.wl.eventLoopData, _glfw.wl.keyRepeatInfo.keyRepeatTimer, (s_to_monotonic_t(1ll) / (monotonic_t)_glfw.wl.keyboardRepeatRate));
toggleTimer(&_glfw.wl.eventLoopData, _glfw.wl.keyRepeatInfo.keyRepeatTimer, 1);
}
@@ -438,26 +438,24 @@ static void keyboardHandleKey(void* data UNUSED,
uint32_t key,
uint32_t state)
{
_GLFWwindow* window = _glfw.wl.keyboardFocus;
_GLFWwindow* window = _glfwWindowForId(_glfw.wl.keyboardFocusId);
if (!window)
return;
int action = state == WL_KEYBOARD_KEY_STATE_PRESSED ? GLFW_PRESS : GLFW_RELEASE;
_glfw.wl.serial = serial;
glfw_xkb_handle_key_event(window, &_glfw.wl.xkb, key, action);
bool repeatable = false;
_glfw.wl.keyRepeatInfo.key = 0;
if (action == GLFW_PRESS && _glfw.wl.keyboardRepeatRate > 0 && glfw_xkb_should_repeat(&_glfw.wl.xkb, key))
{
_glfw.wl.keyRepeatInfo.key = key;
repeatable = true;
_glfw.wl.keyRepeatInfo.keyboardFocus = window;
}
if (repeatable) {
_glfw.wl.keyRepeatInfo.keyboardFocusId = window->id;
changeTimerInterval(&_glfw.wl.eventLoopData, _glfw.wl.keyRepeatInfo.keyRepeatTimer, _glfw.wl.keyboardRepeatDelay);
toggleTimer(&_glfw.wl.eventLoopData, _glfw.wl.keyRepeatInfo.keyRepeatTimer, 1);
} else if (action == GLFW_RELEASE && key == _glfw.wl.keyRepeatInfo.key) {
_glfw.wl.keyRepeatInfo.key = 0;
toggleTimer(&_glfw.wl.eventLoopData, _glfw.wl.keyRepeatInfo.keyRepeatTimer, 0);
}
toggleTimer(&_glfw.wl.eventLoopData, _glfw.wl.keyRepeatInfo.keyRepeatTimer, repeatable ? 1 : 0);
}
static void keyboardHandleModifiers(void* data UNUSED,
@@ -584,6 +582,7 @@ static void registryHandleGlobal(void* data UNUSED,
if (_glfw.wl.primarySelectionDeviceManager && !_glfw.wl.primarySelectionDevice) {
_glfwSetupWaylandPrimarySelectionDevice();
}
_glfwWaylandInitTextInput();
}
}
else if (strcmp(interface, "xdg_wm_base") == 0)
@@ -598,11 +597,6 @@ static void registryHandleGlobal(void* data UNUSED,
wl_registry_bind(registry, name,
&zxdg_decoration_manager_v1_interface, 1);
}
else if (strcmp(interface, "wp_viewporter") == 0)
{
_glfw.wl.viewporter =
wl_registry_bind(registry, name, &wp_viewporter_interface, 1);
}
else if (strcmp(interface, "zwp_relative_pointer_manager_v1") == 0)
{
_glfw.wl.relativePointerManager =
@@ -617,6 +611,11 @@ static void registryHandleGlobal(void* data UNUSED,
&zwp_pointer_constraints_v1_interface,
1);
}
else if (strcmp(interface, GLFW_WAYLAND_TEXT_INPUT_INTERFACE_NAME) == 0)
{
_glfwWaylandBindTextInput(registry, name);
_glfwWaylandInitTextInput();
}
else if (strcmp(interface, "zwp_idle_inhibit_manager_v1") == 0)
{
_glfw.wl.idleInhibitManager =
@@ -717,6 +716,9 @@ glfwWaylandCheckForServerSideDecorations(void) {
int _glfwPlatformInit(void)
{
int i;
_GLFWmonitor* monitor;
_glfw.wl.cursor.handle = _glfw_dlopen("libwayland-cursor.so.0");
if (!_glfw.wl.cursor.handle)
{
@@ -754,6 +756,7 @@ int _glfwPlatformInit(void)
"Wayland: Failed to initialize event loop data");
}
glfw_dbus_init(&_glfw.wl.dbus, &_glfw.wl.eventLoopData);
glfw_initialize_desktop_settings();
_glfw.wl.keyRepeatInfo.keyRepeatTimer = addTimer(&_glfw.wl.eventLoopData, "wayland-key-repeat", ms_to_monotonic_t(500ll), 0, true, dispatchPendingKeyRepeats, NULL, NULL);
_glfw.wl.cursorAnimationTimer = addTimer(&_glfw.wl.eventLoopData, "wayland-cursor-animation", ms_to_monotonic_t(500ll), 0, true, animateCursorImage, NULL, NULL);
@@ -768,6 +771,17 @@ int _glfwPlatformInit(void)
// Sync so we got all initial output events
wl_display_roundtrip(_glfw.wl.display);
for (i = 0; i < _glfw.monitorCount; ++i)
{
monitor = _glfw.monitors[i];
if (monitor->widthMM <= 0 || monitor->heightMM <= 0)
{
// If Wayland does not provide a physical size, assume the default 96 DPI
monitor->widthMM = (int) (monitor->modes[monitor->wl.currentMode].width * 25.4f / 96.f);
monitor->heightMM = (int) (monitor->modes[monitor->wl.currentMode].height * 25.4f / 96.f);
}
}
if (!_glfw.wl.wmBase)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
@@ -817,8 +831,6 @@ void _glfwPlatformTerminate(void)
wl_compositor_destroy(_glfw.wl.compositor);
if (_glfw.wl.shm)
wl_shm_destroy(_glfw.wl.shm);
if (_glfw.wl.viewporter)
wp_viewporter_destroy(_glfw.wl.viewporter);
if (_glfw.wl.decorationManager)
zxdg_decoration_manager_v1_destroy(_glfw.wl.decorationManager);
if (_glfw.wl.wmBase)
@@ -833,6 +845,7 @@ void _glfwPlatformTerminate(void)
zwp_relative_pointer_manager_v1_destroy(_glfw.wl.relativePointerManager);
if (_glfw.wl.pointerConstraints)
zwp_pointer_constraints_v1_destroy(_glfw.wl.pointerConstraints);
_glfwWaylandDestroyTextInput();
if (_glfw.wl.idleInhibitManager)
zwp_idle_inhibit_manager_v1_destroy(_glfw.wl.idleInhibitManager);
if (_glfw.wl.dataSourceForClipboard)

112
glfw/wl_platform.h vendored
View File

@@ -53,12 +53,12 @@ typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR
#include "wl_cursors.h"
#include "wayland-xdg-shell-client-protocol.h"
#include "wayland-viewporter-client-protocol.h"
#include "wayland-xdg-decoration-unstable-v1-client-protocol.h"
#include "wayland-relative-pointer-unstable-v1-client-protocol.h"
#include "wayland-pointer-constraints-unstable-v1-client-protocol.h"
#include "wayland-idle-inhibit-unstable-v1-client-protocol.h"
#include "wayland-primary-selection-unstable-v1-client-protocol.h"
#include "wl_text_input.h"
#define _glfw_dlopen(name) dlopen(name, RTLD_LAZY | RTLD_LOCAL)
#define _glfw_dlclose(handle) dlclose(handle)
@@ -88,28 +88,45 @@ typedef void (* PFN_wl_egl_window_resize)(struct wl_egl_window*, int, int, int,
#define wl_egl_window_destroy _glfw.wl.egl.window_destroy
#define wl_egl_window_resize _glfw.wl.egl.window_resize
#define _GLFW_DECORATION_WIDTH 4
#define _GLFW_DECORATION_TOP 24
#define _GLFW_DECORATION_VERTICAL (_GLFW_DECORATION_TOP + _GLFW_DECORATION_WIDTH)
#define _GLFW_DECORATION_HORIZONTAL (2 * _GLFW_DECORATION_WIDTH)
typedef enum _GLFWdecorationSideWayland
{
mainWindow,
topDecoration,
leftDecoration,
rightDecoration,
bottomDecoration,
CENTRAL_WINDOW,
TOP_DECORATION,
LEFT_DECORATION,
RIGHT_DECORATION,
BOTTOM_DECORATION,
} _GLFWdecorationSideWayland;
typedef struct _GLFWdecorationWayland
{
struct wl_surface* surface;
struct wl_subsurface* subsurface;
struct wp_viewport* viewport;
typedef struct _GLFWWaylandBufferPair {
struct wl_buffer *a, *b, *front, *back;
struct { uint8_t *a, *b, *front, *back; } data;
bool has_pending_update;
size_t size_in_bytes, width, height, stride;
} _GLFWWaylandBufferPair;
typedef struct _GLFWWaylandCSDEdge {
struct wl_surface *surface;
struct wl_subsurface *subsurface;
_GLFWWaylandBufferPair buffer;
int x, y;
} _GLFWWaylandCSDEdge;
typedef enum WaylandWindowState {
TOPLEVEL_STATE_NONE = 0,
TOPLEVEL_STATE_MAXIMIZED = 1,
TOPLEVEL_STATE_FULLSCREEN = 2,
TOPLEVEL_STATE_RESIZING = 4,
TOPLEVEL_STATE_ACTIVATED = 8,
TOPLEVEL_STATE_TILED_LEFT = 16,
TOPLEVEL_STATE_TILED_RIGHT = 32,
TOPLEVEL_STATE_TILED_TOP = 64,
TOPLEVEL_STATE_TILED_BOTTOM = 128,
} WaylandWindowState;
static const WaylandWindowState TOPLEVEL_STATE_DOCKED = TOPLEVEL_STATE_MAXIMIZED | TOPLEVEL_STATE_FULLSCREEN | TOPLEVEL_STATE_TILED_TOP | TOPLEVEL_STATE_TILED_LEFT | TOPLEVEL_STATE_TILED_RIGHT | TOPLEVEL_STATE_TILED_BOTTOM;
} _GLFWdecorationWayland;
// Wayland-specific per-window data
//
@@ -117,7 +134,6 @@ typedef struct _GLFWwindowWayland
{
int width, height;
bool visible;
bool maximized;
bool hovered;
bool transparent;
struct wl_surface* surface;
@@ -131,7 +147,7 @@ typedef struct _GLFWwindowWayland
} xdg;
_GLFWcursor* currentCursor;
double cursorPosX, cursorPosY;
double cursorPosX, cursorPosY, allCursorPosX, allCursorPosY;
char* title;
char appId[256];
@@ -151,13 +167,37 @@ typedef struct _GLFWwindowWayland
struct zwp_idle_inhibitor_v1* idleInhibitor;
bool fullscreened;
struct {
bool serverSide;
struct wl_buffer* buffer;
_GLFWdecorationWayland top, left, right, bottom;
int focus;
bool serverSide;
_GLFWdecorationSideWayland focus;
_GLFWWaylandCSDEdge top, left, right, bottom;
struct {
uint8_t *data;
size_t size;
} mapping;
struct {
int width, height, scale;
bool focused;
} for_window_state;
struct {
unsigned int width, top, horizontal, vertical, visible_titlebar_height;
} metrics;
struct {
int32_t x, y, width, height;
} geometry;
struct {
uint32_t *data;
size_t for_decoration_size, stride, segments, corner_size;
} shadow_tile;
monotonic_t last_click_on_top_decoration_at;
uint32_t titlebar_color;
bool use_custom_titlebar_color;
} decorations;
struct {
@@ -166,6 +206,12 @@ typedef struct _GLFWwindowWayland
struct wl_callback *current_wl_callback;
} frameCallbackData;
struct {
int32_t width, height;
} user_requested_content_size;
uint32_t toplevel_states;
bool maximize_on_first_show;
} _GLFWwindowWayland;
@@ -204,14 +250,13 @@ typedef struct _GLFWlibraryWayland
struct wl_seat* seat;
struct wl_pointer* pointer;
struct wl_keyboard* keyboard;
struct wl_data_device_manager* dataDeviceManager;
struct wl_data_device* dataDevice;
struct xdg_wm_base* wmBase;
struct zxdg_decoration_manager_v1* decorationManager;
struct wp_viewporter* viewporter;
struct zwp_relative_pointer_manager_v1* relativePointerManager;
struct zwp_pointer_constraints_v1* pointerConstraints;
struct zwp_idle_inhibit_manager_v1* idleInhibitManager;
struct wl_data_device_manager* dataDeviceManager;
struct wl_data_device* dataDevice;
struct wl_data_source* dataSourceForClipboard;
struct zwp_primary_selection_device_manager_v1* primarySelectionDeviceManager;
struct zwp_primary_selection_device_v1* primarySelectionDevice;
@@ -226,17 +271,18 @@ typedef struct _GLFWlibraryWayland
int32_t keyboardRepeatRate;
monotonic_t keyboardRepeatDelay;
struct {
uint32_t key;
id_type keyRepeatTimer;
_GLFWwindow* keyboardFocus;
GLFWid keyboardFocusId;
} keyRepeatInfo;
id_type cursorAnimationTimer;
_GLFWXKBData xkb;
_GLFWDBUSData dbus;
_GLFWwindow* pointerFocus;
_GLFWwindow* keyboardFocus;
GLFWid keyboardFocusId;
struct {
void* handle;
@@ -261,7 +307,6 @@ typedef struct _GLFWlibraryWayland
size_t dataOffersCounter;
_GLFWWaylandDataOffer dataOffers[8];
char* primarySelectionString;
GLFWWLCursorThemes cursor_themes;
} _GLFWlibraryWayland;
// Wayland-specific per-monitor data
@@ -275,7 +320,8 @@ typedef struct _GLFWmonitorWayland
int x;
int y;
int scale;
} _GLFWmonitorWayland;
} _GLFWmonitorWayland;
// Wayland-specific per-cursor data
//

154
glfw/wl_text_input.c vendored Normal file
View File

@@ -0,0 +1,154 @@
/*
* wl_text_input.c
* Copyright (C) 2021 Kovid Goyal <kovid at kovidgoyal.net>
*
* Distributed under terms of the GPL3 license.
*/
#include "wl_text_input.h"
#include "internal.h"
#include "wayland-text-input-unstable-v3-client-protocol.h"
#include <stdlib.h>
#define debug(...) if (_glfw.hints.init.debugKeyboard) printf(__VA_ARGS__);
static struct zwp_text_input_v3* text_input;
static struct zwp_text_input_manager_v3* text_input_manager;
static char *pending_pre_edit = NULL;
static char *pending_commit = NULL;
uint32_t commit_serial = 0;
static void commit(void) {
if (text_input) {
zwp_text_input_v3_commit (text_input);
commit_serial++;
}
}
static void
text_input_enter(void *data UNUSED, struct zwp_text_input_v3 *text_input UNUSED, struct wl_surface *surface UNUSED) {
debug("text-input: enter event\n");
if (text_input) {
zwp_text_input_v3_enable(text_input);
zwp_text_input_v3_set_content_type(text_input, ZWP_TEXT_INPUT_V3_CONTENT_HINT_NONE, ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_TERMINAL);
commit();
}
}
static void
text_input_leave(void *data UNUSED, struct zwp_text_input_v3 *text_input UNUSED, struct wl_surface *surface UNUSED) {
debug("text-input: leave event\n");
if (text_input) {
zwp_text_input_v3_disable(text_input);
commit();
}
}
static inline void
send_text(const char *text, GLFWIMEState ime_state) {
_GLFWwindow *w = _glfwFocusedWindow();
if (w && w->callbacks.keyboard) {
GLFWkeyevent fake_ev = {.action = GLFW_PRESS};
fake_ev.text = text;
fake_ev.ime_state = ime_state;
w->callbacks.keyboard((GLFWwindow*) w, &fake_ev);
}
}
static void
text_input_preedit_string(
void *data UNUSED,
struct zwp_text_input_v3 *text_input UNUSED,
const char *text,
int32_t cursor_begin,
int32_t cursor_end
) {
debug("text-input: preedit_string event: text: %s cursor_begin: %d cursor_end: %d\n", text, cursor_begin, cursor_end);
free(pending_pre_edit);
pending_pre_edit = text ? _glfw_strdup(text) : NULL;
}
static void
text_input_commit_string(void *data UNUSED, struct zwp_text_input_v3 *text_input UNUSED, const char *text) {
debug("text-input: commit_string event: text: %s\n", text);
free(pending_commit);
pending_commit = text ? _glfw_strdup(text) : NULL;
}
static void
text_input_delete_surrounding_text(
void *data UNUSED,
struct zwp_text_input_v3 *zwp_text_input_v3 UNUSED,
uint32_t before_length,
uint32_t after_length) {
debug("text-input: delete_surrounding_text event: before_length: %u after_length: %u\n", before_length, after_length);
}
static void
text_input_done(void *data UNUSED, struct zwp_text_input_v3 *zwp_text_input_v3 UNUSED, uint32_t serial UNUSED) {
debug("text-input: done event: serial: %u current_commit_serial: %u\n", serial, commit_serial);
if (serial != commit_serial) {
_glfwInputError(GLFW_PLATFORM_ERROR, "Wayland: text_input_done serial mismatch, expected=%u got=%u\n", commit_serial, serial);
return;
}
if (pending_pre_edit) {
send_text(pending_pre_edit, GLFW_IME_PREEDIT_CHANGED);
free(pending_pre_edit); pending_pre_edit = NULL;
}
if (pending_commit) {
send_text(pending_commit, GLFW_IME_COMMIT_TEXT);
free(pending_commit); pending_commit = NULL;
}
}
void
_glfwWaylandBindTextInput(struct wl_registry* registry, uint32_t name) {
if (!text_input_manager) text_input_manager = wl_registry_bind(registry, name, &zwp_text_input_manager_v3_interface, 1);
}
void
_glfwWaylandInitTextInput(void) {
static const struct zwp_text_input_v3_listener text_input_listener = {
.enter = text_input_enter,
.leave = text_input_leave,
.preedit_string = text_input_preedit_string,
.commit_string = text_input_commit_string,
.delete_surrounding_text = text_input_delete_surrounding_text,
.done = text_input_done,
};
if (!text_input) {
if (text_input_manager && _glfw.wl.seat) {
text_input = zwp_text_input_manager_v3_get_text_input(
text_input_manager, _glfw.wl.seat);
if (text_input) zwp_text_input_v3_add_listener(text_input, &text_input_listener, NULL);
}
}
}
void
_glfwWaylandDestroyTextInput(void) {
if (text_input) zwp_text_input_v3_destroy(text_input);
if (text_input_manager) zwp_text_input_manager_v3_destroy(text_input_manager);
text_input = NULL; text_input_manager = NULL;
free(pending_pre_edit); pending_pre_edit = NULL;
free(pending_commit); pending_commit = NULL;
}
void
_glfwPlatformUpdateIMEState(_GLFWwindow *w, const GLFWIMEUpdateEvent *ev) {
if (!text_input) return;
switch(ev->type) {
case GLFW_IME_UPDATE_FOCUS:
debug("\ntext-input: updating IME focus state, focused: %d\n", ev->focused);
if (ev->focused) zwp_text_input_v3_enable(text_input); else zwp_text_input_v3_disable(text_input);
commit();
break;
case GLFW_IME_UPDATE_CURSOR_POSITION: {
const int scale = w->wl.scale;
const int left = ev->cursor.left / scale, top = ev->cursor.top / scale, width = ev->cursor.width / scale, height = ev->cursor.height / scale;
debug("\ntext-input: updating cursor position: left=%d top=%d width=%d height=%d\n", left, top, width, height);
zwp_text_input_v3_set_cursor_rectangle(text_input, left, top, width, height);
commit();
}
break;
}
}

14
glfw/wl_text_input.h vendored Normal file
View File

@@ -0,0 +1,14 @@
/*
* Copyright (C) 2021 Kovid Goyal <kovid at kovidgoyal.net>
*
* Distributed under terms of the GPL3 license.
*/
#pragma once
#include <wayland-client.h>
#define GLFW_WAYLAND_TEXT_INPUT_INTERFACE_NAME "zwp_text_input_manager_v3"
void _glfwWaylandBindTextInput(struct wl_registry* registry, uint32_t name);
void _glfwWaylandInitTextInput(void);
void _glfwWaylandDestroyTextInput(void);

538
glfw/wl_window.c vendored
View File

@@ -32,6 +32,7 @@
#include "backend_utils.h"
#include "memfd.h"
#include "linux_notify.h"
#include "wl_client_side_decorations.h"
#include "../kitty/monotonic.h"
#include <stdio.h>
@@ -41,10 +42,65 @@
#include <fcntl.h>
#include <sys/mman.h>
#define debug(...) if (_glfw.hints.init.debugRendering) fprintf(stderr, __VA_ARGS__);
static struct wl_buffer* createShmBuffer(const GLFWimage* image, bool is_opaque, bool init_data)
{
struct wl_shm_pool* pool;
struct wl_buffer* buffer;
int stride = image->width * 4;
int length = image->width * image->height * 4;
void* data;
int fd, i;
fd = createAnonymousFile(length);
if (fd < 0)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Wayland: Creating a buffer file for %d B failed: %s",
length, strerror(errno));
return NULL;
}
data = mmap(NULL, length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (data == MAP_FAILED)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Wayland: mmap failed: %s", strerror(errno));
close(fd);
return NULL;
}
pool = wl_shm_create_pool(_glfw.wl.shm, fd, length);
close(fd);
if (init_data) {
unsigned char* source = (unsigned char*) image->pixels;
unsigned char* target = data;
for (i = 0; i < image->width * image->height; i++, source += 4)
{
unsigned int alpha = source[3];
*target++ = (unsigned char) ((source[2] * alpha) / 255);
*target++ = (unsigned char) ((source[1] * alpha) / 255);
*target++ = (unsigned char) ((source[0] * alpha) / 255);
*target++ = (unsigned char) alpha;
}
}
buffer =
wl_shm_pool_create_buffer(pool, 0,
image->width,
image->height,
stride, is_opaque ? WL_SHM_FORMAT_XRGB8888 : WL_SHM_FORMAT_ARGB8888);
munmap(data, length);
wl_shm_pool_destroy(pool);
return buffer;
}
static void
setCursorImage(_GLFWwindow* window)
{
setCursorImage(_GLFWwindow* window, bool on_theme_change) {
_GLFWcursorWayland defaultCursor = {.shape = GLFW_ARROW_CURSOR};
_GLFWcursorWayland* cursorWayland = window->cursor ? &window->cursor->wl : &defaultCursor;
struct wl_cursor_image* image = NULL;
@@ -55,9 +111,8 @@ setCursorImage(_GLFWwindow* window)
if (cursorWayland->scale < 0) {
buffer = cursorWayland->buffer;
toggleTimer(&_glfw.wl.eventLoopData, _glfw.wl.cursorAnimationTimer, 0);
} else
{
if (cursorWayland->scale != scale) {
} else {
if (on_theme_change || cursorWayland->scale != scale) {
struct wl_cursor *newCursor = NULL;
struct wl_cursor_theme *theme = glfw_wlc_theme_for_scale(scale);
if (theme) newCursor = _glfwLoadCursor(cursorWayland->shape, theme);
@@ -132,7 +187,7 @@ static bool checkScaleChange(_GLFWwindow* window)
{
window->wl.scale = scale;
wl_surface_set_buffer_scale(window->wl.surface, scale);
setCursorImage(window);
setCursorImage(window, false);
return true;
}
if (window->wl.monitorsCount > 0 && !window->wl.initial_scale_notified) {
@@ -158,42 +213,15 @@ static void setOpaqueRegion(_GLFWwindow* window)
}
static void resizeFramebuffer(_GLFWwindow* window)
{
static void
resizeFramebuffer(_GLFWwindow* window) {
int scale = window->wl.scale;
int scaledWidth = window->wl.width * scale;
int scaledHeight = window->wl.height * scale;
debug("Resizing framebuffer to: %dx%d at scale: %d\n", window->wl.width, window->wl.height, scale);
wl_egl_window_resize(window->wl.native, scaledWidth, scaledHeight, 0, 0);
if (!window->wl.transparent)
setOpaqueRegion(window);
if (!window->wl.transparent) setOpaqueRegion(window);
_glfwInputFramebufferSize(window, scaledWidth, scaledHeight);
if (!window->wl.decorations.top.surface)
return;
// Top decoration.
wp_viewport_set_destination(window->wl.decorations.top.viewport,
window->wl.width, _GLFW_DECORATION_TOP);
wl_surface_commit(window->wl.decorations.top.surface);
// Left decoration.
wp_viewport_set_destination(window->wl.decorations.left.viewport,
_GLFW_DECORATION_WIDTH, window->wl.height + _GLFW_DECORATION_TOP);
wl_surface_commit(window->wl.decorations.left.surface);
// Right decoration.
wl_subsurface_set_position(window->wl.decorations.right.subsurface,
window->wl.width, -_GLFW_DECORATION_TOP);
wp_viewport_set_destination(window->wl.decorations.right.viewport,
_GLFW_DECORATION_WIDTH, window->wl.height + _GLFW_DECORATION_TOP);
wl_surface_commit(window->wl.decorations.right.surface);
// Bottom decoration.
wl_subsurface_set_position(window->wl.decorations.bottom.subsurface,
-_GLFW_DECORATION_WIDTH, window->wl.height);
wp_viewport_set_destination(window->wl.decorations.bottom.viewport,
window->wl.width + _GLFW_DECORATION_HORIZONTAL, _GLFW_DECORATION_WIDTH);
wl_surface_commit(window->wl.decorations.bottom.surface);
}
@@ -206,15 +234,15 @@ clipboard_mime(void) {
return buf;
}
static void dispatchChangesAfterConfigure(_GLFWwindow *window, int32_t width, int32_t height) {
if (width <= 0) width = window->wl.width;
if (height <= 0) height = window->wl.height;
static void
dispatchChangesAfterConfigure(_GLFWwindow *window, int32_t width, int32_t height) {
bool size_changed = width != window->wl.width || height != window->wl.height;
bool scale_changed = checkScaleChange(window);
if (size_changed) {
_glfwInputWindowSize(window, width, height);
_glfwPlatformSetWindowSize(window, width, height);
window->wl.width = width; window->wl.height = height;
resizeFramebuffer(window);
}
if (scale_changed) {
@@ -227,221 +255,23 @@ static void dispatchChangesAfterConfigure(_GLFWwindow *window, int32_t width, in
}
/*
* Create a new, unique, anonymous file of the given size, and
* return the file descriptor for it. The file descriptor is set
* CLOEXEC. The file is immediately suitable for mmap()'ing
* the given size at offset zero.
*
* The file should not have a permanent backing store like a disk,
* but may have if XDG_RUNTIME_DIR is not properly implemented in OS.
*
* The file name is deleted from the file system.
*
* The file is suitable for buffer sharing between processes by
* transmitting the file descriptor over Unix sockets using the
* SCM_RIGHTS methods.
*
* posix_fallocate() is used to guarantee that disk space is available
* for the file at the given size. If disk space is insufficient, errno
* is set to ENOSPC. If posix_fallocate() is not supported, program may
* receive SIGBUS on accessing mmap()'ed file contents instead.
*/
static int
createAnonymousFile(off_t size)
{
int ret, fd = -1, shm_anon = 0;
#ifdef HAS_MEMFD_CREATE
fd = memfd_create("glfw-shared", MFD_CLOEXEC | MFD_ALLOW_SEALING);
if (fd < 0) return -1;
// We can add this seal before calling posix_fallocate(), as the file
// is currently zero-sized anyway.
//
// There is also no need to check for the return value, we couldnt do
// anything with it anyway.
fcntl(fd, F_ADD_SEALS, F_SEAL_SHRINK | F_SEAL_SEAL);
#elif defined(SHM_ANON)
fd = shm_open(SHM_ANON, O_RDWR | O_CLOEXEC, 0600);
if (fd < 0) return -1;
shm_anon = 1;
#else
static const char template[] = "/glfw-shared-XXXXXX";
const char* path;
char* name;
path = getenv("XDG_RUNTIME_DIR");
if (!path)
{
errno = ENOENT;
return -1;
}
name = calloc(strlen(path) + sizeof(template), 1);
strcpy(name, path);
strcat(name, template);
fd = createTmpfileCloexec(name);
free(name);
if (fd < 0)
return -1;
#endif
// posix_fallocate does not work on SHM descriptors
ret = shm_anon ? ftruncate(fd, size) : posix_fallocate(fd, 0, size);
if (ret != 0)
{
close(fd);
errno = ret;
return -1;
}
return fd;
}
static struct wl_buffer* createShmBuffer(const GLFWimage* image)
{
struct wl_shm_pool* pool;
struct wl_buffer* buffer;
int stride = image->width * 4;
int length = image->width * image->height * 4;
void* data;
int fd, i;
fd = createAnonymousFile(length);
if (fd < 0)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Wayland: Creating a buffer file for %d B failed: %s",
length, strerror(errno));
return NULL;
}
data = mmap(NULL, length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (data == MAP_FAILED)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Wayland: mmap failed: %s", strerror(errno));
close(fd);
return NULL;
}
pool = wl_shm_create_pool(_glfw.wl.shm, fd, length);
close(fd);
unsigned char* source = (unsigned char*) image->pixels;
unsigned char* target = data;
for (i = 0; i < image->width * image->height; i++, source += 4)
{
unsigned int alpha = source[3];
*target++ = (unsigned char) ((source[2] * alpha) / 255);
*target++ = (unsigned char) ((source[1] * alpha) / 255);
*target++ = (unsigned char) ((source[0] * alpha) / 255);
*target++ = (unsigned char) alpha;
}
buffer =
wl_shm_pool_create_buffer(pool, 0,
image->width,
image->height,
stride, WL_SHM_FORMAT_ARGB8888);
munmap(data, length);
wl_shm_pool_destroy(pool);
return buffer;
}
static void createDecoration(_GLFWdecorationWayland* decoration,
struct wl_surface* parent,
struct wl_buffer* buffer, bool opaque,
int x, int y,
int width, int height)
{
struct wl_region* region;
decoration->surface = wl_compositor_create_surface(_glfw.wl.compositor);
decoration->subsurface =
wl_subcompositor_get_subsurface(_glfw.wl.subcompositor,
decoration->surface, parent);
wl_subsurface_set_position(decoration->subsurface, x, y);
decoration->viewport = wp_viewporter_get_viewport(_glfw.wl.viewporter,
decoration->surface);
wp_viewport_set_destination(decoration->viewport, width, height);
wl_surface_attach(decoration->surface, buffer, 0, 0);
if (opaque)
{
region = wl_compositor_create_region(_glfw.wl.compositor);
wl_region_add(region, 0, 0, width, height);
wl_surface_set_opaque_region(decoration->surface, region);
wl_surface_commit(decoration->surface);
wl_region_destroy(region);
}
else
wl_surface_commit(decoration->surface);
}
static void createDecorations(_GLFWwindow* window)
{
unsigned char data[] = { 224, 224, 224, 255 };
const GLFWimage image = { 1, 1, data };
bool opaque = (data[3] == 255);
if (!_glfw.wl.viewporter || !window->decorated || window->wl.decorations.serverSide)
return;
if (!window->wl.decorations.buffer)
window->wl.decorations.buffer = createShmBuffer(&image);
if (!window->wl.decorations.buffer)
return;
createDecoration(&window->wl.decorations.top, window->wl.surface,
window->wl.decorations.buffer, opaque,
0, -_GLFW_DECORATION_TOP,
window->wl.width, _GLFW_DECORATION_TOP);
createDecoration(&window->wl.decorations.left, window->wl.surface,
window->wl.decorations.buffer, opaque,
-_GLFW_DECORATION_WIDTH, -_GLFW_DECORATION_TOP,
_GLFW_DECORATION_WIDTH, window->wl.height + _GLFW_DECORATION_TOP);
createDecoration(&window->wl.decorations.right, window->wl.surface,
window->wl.decorations.buffer, opaque,
window->wl.width, -_GLFW_DECORATION_TOP,
_GLFW_DECORATION_WIDTH, window->wl.height + _GLFW_DECORATION_TOP);
createDecoration(&window->wl.decorations.bottom, window->wl.surface,
window->wl.decorations.buffer, opaque,
-_GLFW_DECORATION_WIDTH, window->wl.height,
window->wl.width + _GLFW_DECORATION_HORIZONTAL, _GLFW_DECORATION_WIDTH);
}
static void destroyDecoration(_GLFWdecorationWayland* decoration)
{
if (decoration->surface)
wl_surface_destroy(decoration->surface);
if (decoration->subsurface)
wl_subsurface_destroy(decoration->subsurface);
if (decoration->viewport)
wp_viewport_destroy(decoration->viewport);
decoration->surface = NULL;
decoration->subsurface = NULL;
decoration->viewport = NULL;
}
static void destroyDecorations(_GLFWwindow* window)
{
destroyDecoration(&window->wl.decorations.top);
destroyDecoration(&window->wl.decorations.left);
destroyDecoration(&window->wl.decorations.right);
destroyDecoration(&window->wl.decorations.bottom);
}
static void xdgDecorationHandleConfigure(void* data,
static void
xdgDecorationHandleConfigure(void* data,
struct zxdg_toplevel_decoration_v1* decoration UNUSED,
uint32_t mode)
{
_GLFWwindow* window = data;
window->wl.decorations.serverSide = (mode == ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE);
if (!window->wl.decorations.serverSide)
createDecorations(window);
bool has_server_side_decorations = (mode == ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE);
debug("XDG decoration configure event received: Has server side decorations: %d\n", has_server_side_decorations);
if (!has_server_side_decorations && window->wl.decorations.serverSide) {
// this can happen for example on sway where it has a "border toggle" function
// that turns on/off the server side decorations. In such a case, we dont turn
// on client side decorations, as that causes things to break.
return;
}
window->wl.decorations.serverSide = has_server_side_decorations;
ensure_csd_resources(window);
}
static const struct zxdg_toplevel_decoration_v1_listener xdgDecorationListener = {
@@ -468,6 +298,7 @@ static void surfaceHandleEnter(void *data,
if (checkScaleChange(window)) {
resizeFramebuffer(window);
_glfwInputWindowContentScale(window, window->wl.scale, window->wl.scale);
ensure_csd_resources(window);
}
}
@@ -492,6 +323,7 @@ static void surfaceHandleLeave(void *data,
if (checkScaleChange(window)) {
resizeFramebuffer(window);
_glfwInputWindowContentScale(window, window->wl.scale, window->wl.scale);
ensure_csd_resources(window);
}
}
@@ -539,6 +371,8 @@ static bool createSurface(_GLFWwindow* window,
window->wl.width = wndconfig->width;
window->wl.height = wndconfig->height;
window->wl.user_requested_content_size.width = wndconfig->width;
window->wl.user_requested_content_size.height = wndconfig->height;
window->wl.scale = 1;
if (!window->wl.transparent)
@@ -547,8 +381,7 @@ static bool createSurface(_GLFWwindow* window,
return true;
}
static void
setFullscreen(_GLFWwindow* window, _GLFWmonitor* monitor, bool on)
static void setFullscreen(_GLFWwindow* window, _GLFWmonitor* monitor, bool on)
{
if (window->wl.xdg.toplevel)
{
@@ -556,12 +389,10 @@ setFullscreen(_GLFWwindow* window, _GLFWmonitor* monitor, bool on)
xdg_toplevel_set_fullscreen(
window->wl.xdg.toplevel,
monitor ? monitor->wl.output : NULL);
if (!window->wl.decorations.serverSide)
destroyDecorations(window);
if (!window->wl.decorations.serverSide) free_csd_surfaces(window);
} else {
xdg_toplevel_unset_fullscreen(window->wl.xdg.toplevel);
if (!_glfw.wl.decorationManager)
createDecorations(window);
ensure_csd_resources(window);
}
}
setIdleInhibitor(window, on);
@@ -569,12 +400,21 @@ setFullscreen(_GLFWwindow* window, _GLFWmonitor* monitor, bool on)
bool
_glfwPlatformToggleFullscreen(_GLFWwindow *window, unsigned int flags UNUSED) {
bool already_fullscreen = window->wl.fullscreened;
bool already_fullscreen = window->wl.toplevel_states & TOPLEVEL_STATE_FULLSCREEN;
setFullscreen(window, NULL, !already_fullscreen);
return !already_fullscreen;
}
static void xdgToplevelHandleConfigure(void* data,
static void
inform_compositor_of_window_geometry(_GLFWwindow *window, const char *event) {
#define geometry window->wl.decorations.geometry
debug("Setting window geometry in %s event: x=%d y=%d %dx%d\n", event, geometry.x, geometry.y, geometry.width, geometry.height);
xdg_surface_set_window_geometry(window->wl.xdg.surface, geometry.x, geometry.y, geometry.width, geometry.height);
#undef geometry
}
static void
xdgToplevelHandleConfigure(void* data,
struct xdg_toplevel* toplevel UNUSED,
int32_t width,
int32_t height,
@@ -583,32 +423,33 @@ static void xdgToplevelHandleConfigure(void* data,
_GLFWwindow* window = data;
float aspectRatio;
float targetRatio;
uint32_t* state;
bool maximized = false;
bool fullscreen = false;
bool activated = false;
enum xdg_toplevel_state* state;
uint32_t new_states = 0;
debug("top-level configure event: size: %dx%d states: ", width, height);
wl_array_for_each(state, states)
{
switch (*state)
{
case XDG_TOPLEVEL_STATE_MAXIMIZED:
maximized = true;
break;
case XDG_TOPLEVEL_STATE_FULLSCREEN:
fullscreen = true;
break;
case XDG_TOPLEVEL_STATE_RESIZING:
break;
case XDG_TOPLEVEL_STATE_ACTIVATED:
activated = true;
break;
wl_array_for_each(state, states) {
switch (*state) {
#define C(x) case XDG_##x: new_states |= x; debug("%s ", #x); break
C(TOPLEVEL_STATE_RESIZING);
C(TOPLEVEL_STATE_MAXIMIZED);
C(TOPLEVEL_STATE_FULLSCREEN);
C(TOPLEVEL_STATE_ACTIVATED);
C(TOPLEVEL_STATE_TILED_LEFT);
C(TOPLEVEL_STATE_TILED_RIGHT);
C(TOPLEVEL_STATE_TILED_TOP);
C(TOPLEVEL_STATE_TILED_BOTTOM);
#undef C
}
}
debug("\n");
if (new_states & TOPLEVEL_STATE_RESIZING) {
if (width) window->wl.user_requested_content_size.width = width;
if (height) window->wl.user_requested_content_size.height = height;
if (!(window->wl.toplevel_states & TOPLEVEL_STATE_RESIZING)) _glfwInputLiveResize(window, true);
}
if (width != 0 && height != 0)
{
if (!maximized && !fullscreen)
if (!(new_states & TOPLEVEL_STATE_DOCKED))
{
if (window->numer != GLFW_DONT_CARE && window->denom != GLFW_DONT_CARE)
{
@@ -621,15 +462,16 @@ static void xdgToplevelHandleConfigure(void* data,
}
}
}
window->wl.fullscreened = fullscreen;
if (!fullscreen) {
if (window->decorated && !window->wl.decorations.serverSide && window->wl.decorations.buffer) {
width -= _GLFW_DECORATION_HORIZONTAL;
height -= _GLFW_DECORATION_VERTICAL;
}
}
bool live_resize_done = !(new_states & TOPLEVEL_STATE_RESIZING) && (window->wl.toplevel_states & TOPLEVEL_STATE_RESIZING);
window->wl.toplevel_states = new_states;
set_csd_window_geometry(window, &width, &height);
dispatchChangesAfterConfigure(window, width, height);
_glfwInputWindowFocus(window, activated);
debug("final window content size: %dx%d\n", window->wl.width, window->wl.height);
_glfwInputWindowFocus(window, window->wl.toplevel_states & TOPLEVEL_STATE_ACTIVATED);
ensure_csd_resources(window);
wl_surface_commit(window->wl.surface);
inform_compositor_of_window_geometry(window, "configure");
if (live_resize_done) _glfwInputLiveResize(window, false);
}
static void xdgToplevelHandleClose(void* data,
@@ -655,10 +497,12 @@ static const struct xdg_surface_listener xdgSurfaceListener = {
xdgSurfaceHandleConfigure
};
static void setXdgDecorations(_GLFWwindow* window)
static void
setXdgDecorations(_GLFWwindow* window)
{
if (_glfw.wl.decorationManager)
{
window->wl.decorations.serverSide = true;
window->wl.xdg.decoration =
zxdg_decoration_manager_v1_get_toplevel_decoration(
_glfw.wl.decorationManager, window->wl.xdg.toplevel);
@@ -672,11 +516,12 @@ static void setXdgDecorations(_GLFWwindow* window)
else
{
window->wl.decorations.serverSide = false;
createDecorations(window);
ensure_csd_resources(window);
}
}
static bool createXdgSurface(_GLFWwindow* window)
static bool
createXdgSurface(_GLFWwindow* window)
{
window->wl.xdg.surface = xdg_wm_base_get_xdg_surface(_glfw.wl.wmBase,
window->wl.surface);
@@ -719,8 +564,9 @@ static bool createXdgSurface(_GLFWwindow* window)
window->monitor->wl.output);
setIdleInhibitor(window, true);
}
else if (window->wl.maximized)
else if (window->wl.maximize_on_first_show)
{
window->wl.maximize_on_first_show = false;
xdg_toplevel_set_maximized(window->wl.xdg.toplevel);
setIdleInhibitor(window, false);
setXdgDecorations(window);
@@ -739,16 +585,15 @@ static bool createXdgSurface(_GLFWwindow* window)
return true;
}
static void
incrementCursorImage(_GLFWwindow* window)
static void incrementCursorImage(_GLFWwindow* window)
{
if (window && window->wl.decorations.focus == mainWindow && window->cursorMode != GLFW_CURSOR_HIDDEN) {
if (window && window->wl.decorations.focus == CENTRAL_WINDOW && window->cursorMode != GLFW_CURSOR_HIDDEN) {
_GLFWcursor* cursor = window->wl.currentCursor;
if (cursor && cursor->wl.cursor)
{
cursor->wl.currentImage += 1;
cursor->wl.currentImage %= cursor->wl.cursor->image_count;
setCursorImage(window);
setCursorImage(window, false);
toggleTimer(&_glfw.wl.eventLoopData, _glfw.wl.cursorAnimationTimer, cursor->wl.cursor->image_count > 1);
return;
}
@@ -788,8 +633,7 @@ wayland_read_events(int poll_result, int events, void *data UNUSED) {
else wl_display_cancel_read(_glfw.wl.display);
}
static void
handleEvents(monotonic_t timeout)
static void handleEvents(monotonic_t timeout)
{
struct wl_display* display = _glfw.wl.display;
errno = 0;
@@ -886,6 +730,7 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig)
{
initialize_csd_metrics(window);
window->wl.transparent = fbconfig->transparent;
strncpy(window->wl.appId, wndconfig->wl.appId, sizeof(window->wl.appId));
@@ -913,6 +758,8 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
if (wndconfig->title)
window->wl.title = _glfw_strdup(wndconfig->title);
if (wndconfig->maximized)
window->wl.maximize_on_first_show = true;
if (wndconfig->visible)
{
@@ -945,11 +792,14 @@ void _glfwPlatformDestroyWindow(_GLFWwindow* window)
_glfw.wl.pointerFocus = NULL;
_glfwInputCursorEnter(window, false);
}
if (window == _glfw.wl.keyboardFocus)
if (window->id == _glfw.wl.keyboardFocusId)
{
_glfw.wl.keyboardFocus = NULL;
_glfw.wl.keyboardFocusId = 0;
_glfwInputWindowFocus(window, false);
}
if (window->id == _glfw.wl.keyRepeatInfo.keyboardFocusId) {
_glfw.wl.keyRepeatInfo.keyboardFocusId = 0;
}
if (window->wl.idleInhibitor)
zwp_idle_inhibitor_v1_destroy(window->wl.idleInhibitor);
@@ -957,14 +807,10 @@ void _glfwPlatformDestroyWindow(_GLFWwindow* window)
if (window->context.destroy)
window->context.destroy(window);
destroyDecorations(window);
free_all_csd_resources(window);
if (window->wl.xdg.decoration)
zxdg_toplevel_decoration_v1_destroy(window->wl.xdg.decoration);
if (window->wl.decorations.buffer)
wl_buffer_destroy(window->wl.decorations.buffer);
if (window->wl.native)
wl_egl_window_destroy(window->wl.native);
@@ -985,14 +831,16 @@ void _glfwPlatformDestroyWindow(_GLFWwindow* window)
void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title)
{
if (window->wl.title)
if (window->wl.title) {
if (title && strcmp(title, window->wl.title) == 0) return;
free(window->wl.title);
} else if (!title) return;
// Wayland cannot handle requests larger than ~8200 bytes. Sending
// one causes an abort(). Since titles this large are meaningless anyway
// ensure they do not happen.
window->wl.title = utf_8_strndup(title, 2048);
if (window->wl.xdg.toplevel)
xdg_toplevel_set_title(window->wl.xdg.toplevel, window->wl.title);
if (window->wl.xdg.toplevel) xdg_toplevel_set_title(window->wl.xdg.toplevel, window->wl.title);
change_csd_title(window);
}
void _glfwPlatformSetWindowIcon(_GLFWwindow* window UNUSED,
@@ -1006,9 +854,12 @@ void _glfwPlatformGetWindowPos(_GLFWwindow* window UNUSED, int* xpos UNUSED, int
{
// A Wayland client is not aware of its position, so just warn and leave it
// as (0, 0)
_glfwInputError(GLFW_FEATURE_UNAVAILABLE,
"Wayland: The platform does not provide the window position");
static bool warned_once = false;
if (!warned_once) {
_glfwInputError(GLFW_FEATURE_UNAVAILABLE,
"Wayland: The platform does not provide the window position");
warned_once = true;
}
}
void _glfwPlatformSetWindowPos(_GLFWwindow* window UNUSED, int xpos UNUSED, int ypos UNUSED)
@@ -1030,9 +881,15 @@ void _glfwPlatformGetWindowSize(_GLFWwindow* window, int* width, int* height)
void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height)
{
if (width != window->wl.width || height != window->wl.height) {
window->wl.width = width;
window->wl.height = height;
window->wl.user_requested_content_size.width = width;
window->wl.user_requested_content_size.height = height;
int32_t width = 0, height = 0;
set_csd_window_geometry(window, &width, &height);
window->wl.width = width; window->wl.height = height;
resizeFramebuffer(window);
ensure_csd_resources(window);
wl_surface_commit(window->wl.surface);
inform_compositor_of_window_geometry(window, "SetWindowSize");
}
}
@@ -1085,13 +942,13 @@ void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window,
if (window->decorated && !window->monitor && !window->wl.decorations.serverSide)
{
if (top)
*top = _GLFW_DECORATION_TOP;
*top = window->wl.decorations.metrics.top;
if (left)
*left = _GLFW_DECORATION_WIDTH;
*left = window->wl.decorations.metrics.width;
if (right)
*right = _GLFW_DECORATION_WIDTH;
*right = window->wl.decorations.metrics.width;
if (bottom)
*bottom = _GLFW_DECORATION_WIDTH;
*bottom = window->wl.decorations.metrics.width;
}
}
@@ -1121,13 +978,12 @@ void _glfwPlatformRestoreWindow(_GLFWwindow* window)
{
if (window->monitor)
xdg_toplevel_unset_fullscreen(window->wl.xdg.toplevel);
if (window->wl.maximized)
if (window->wl.toplevel_states & TOPLEVEL_STATE_MAXIMIZED)
xdg_toplevel_unset_maximized(window->wl.xdg.toplevel);
// There is no way to unset minimized, or even to know if we are
// minimized, so there is nothing to do in this case.
}
_glfwInputWindowMonitor(window, NULL);
window->wl.maximized = false;
}
void _glfwPlatformMaximizeWindow(_GLFWwindow* window)
@@ -1136,7 +992,6 @@ void _glfwPlatformMaximizeWindow(_GLFWwindow* window)
{
xdg_toplevel_set_maximized(window->wl.xdg.toplevel);
}
window->wl.maximized = true;
}
void _glfwPlatformShowWindow(_GLFWwindow* window)
@@ -1202,7 +1057,7 @@ void _glfwPlatformSetWindowMonitor(_GLFWwindow* window,
int _glfwPlatformWindowFocused(_GLFWwindow* window)
{
return _glfw.wl.keyboardFocus == window;
return _glfw.wl.keyboardFocusId = window ? window->id : 0;
}
int _glfwPlatformWindowOccluded(_GLFWwindow* window UNUSED)
@@ -1224,7 +1079,7 @@ int _glfwPlatformWindowVisible(_GLFWwindow* window)
int _glfwPlatformWindowMaximized(_GLFWwindow* window)
{
return window->wl.maximized;
return window->wl.toplevel_states & TOPLEVEL_STATE_MAXIMIZED;
}
int _glfwPlatformWindowHovered(_GLFWwindow* window)
@@ -1249,9 +1104,9 @@ void _glfwPlatformSetWindowDecorated(_GLFWwindow* window, bool enabled)
if (!window->monitor)
{
if (enabled)
createDecorations(window);
ensure_csd_resources(window);
else
destroyDecorations(window);
free_csd_surfaces(window);
}
}
@@ -1350,7 +1205,7 @@ const char* _glfwPlatformGetNativeKeyName(int native_key)
return glfw_xkb_keysym_name(native_key);
}
int _glfwPlatformGetNativeKeyForKey(int key)
int _glfwPlatformGetNativeKeyForKey(uint32_t key)
{
return glfw_xkb_sym_for_key(key);
}
@@ -1359,9 +1214,10 @@ int _glfwPlatformCreateCursor(_GLFWcursor* cursor,
const GLFWimage* image,
int xhot, int yhot, int count UNUSED)
{
cursor->wl.buffer = createShmBuffer(image);
cursor->wl.buffer = createShmBuffer(image, false, true);
if (!cursor->wl.buffer)
return false;
cursor->wl.width = image->width;
cursor->wl.height = image->height;
cursor->wl.xhot = xhot;
@@ -1509,7 +1365,7 @@ void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor)
// If we're not in the correct window just save the cursor
// the next time the pointer enters the window the cursor will change
if (window != _glfw.wl.pointerFocus || window->wl.decorations.focus != mainWindow)
if (window != _glfw.wl.pointerFocus || window->wl.decorations.focus != CENTRAL_WINDOW)
return;
// Unlock possible pointer lock if no longer disabled.
@@ -1518,7 +1374,7 @@ void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor)
if (window->cursorMode == GLFW_CURSOR_NORMAL)
{
setCursorImage(window);
setCursorImage(window, false);
}
else if (window->cursorMode == GLFW_CURSOR_DISABLED)
{
@@ -2101,11 +1957,6 @@ VkResult _glfwPlatformCreateWindowSurface(VkInstance instance,
return err;
}
void
_glfwPlatformUpdateIMEState(_GLFWwindow *w, int which, int a, int b, int c, int d) {
glfw_xkb_update_ime_state(w, &_glfw.wl.xkb, which, a, b, c, d);
}
static void
frame_handle_redraw(void *data, struct wl_callback *callback, uint32_t time UNUSED) {
_GLFWwindow* window = (_GLFWwindow*) data;
@@ -2116,6 +1967,16 @@ frame_handle_redraw(void *data, struct wl_callback *callback, uint32_t time UNUS
wl_callback_destroy(callback);
}
void
_glfwPlatformChangeCursorTheme(void) {
glfw_wlc_destroy();
_GLFWwindow *w = _glfw.windowListHead;
while (w) {
setCursorImage(w, true);
w = w->next;
}
}
//////////////////////////////////////////////////////////////////////////
////// GLFW native API //////
@@ -2158,3 +2019,12 @@ GLFWAPI unsigned long long glfwDBusUserNotify(const char *app_name, const char*
GLFWAPI void glfwDBusSetUserNotificationHandler(GLFWDBusnotificationactivatedfun handler) {
glfw_dbus_set_user_notification_activated_handler(handler);
}
GLFWAPI bool glfwWaylandSetTitlebarColor(GLFWwindow *handle, uint32_t color, bool use_system_color) {
_GLFWwindow* window = (_GLFWwindow*) handle;
if (!window->wl.decorations.serverSide) {
set_titlebar_color(window, color, use_system_color);
return true;
}
return false;
}

Some files were not shown because too many files have changed in this diff Show More