Compare commits
29 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
115de36599 | ||
|
|
b01c3483de | ||
|
|
db7f566a0c | ||
|
|
9f806e76e7 | ||
|
|
12bdd4dddd | ||
|
|
72a1eb237d | ||
|
|
6a89289907 | ||
|
|
7ed835cf13 | ||
|
|
4621ff41d9 | ||
|
|
60e17d5224 | ||
|
|
1e2f7c705d | ||
|
|
1ebf0b95c4 | ||
|
|
c5acd94456 | ||
|
|
448ffe01c3 | ||
|
|
5c882f3290 | ||
|
|
70a4720bf9 | ||
|
|
c8aee8c881 | ||
|
|
c2ad0607b8 | ||
|
|
d1282b9f55 | ||
|
|
11ee317884 | ||
|
|
e69de2f968 | ||
|
|
2f4f3e3331 | ||
|
|
020f8a2047 | ||
|
|
b8faba2a16 | ||
|
|
0fcce6ec58 | ||
|
|
15f5ea92b8 | ||
|
|
2bbb5d25eb | ||
|
|
8d94285a5d | ||
|
|
eed11361c5 |
2
.gitattributes
vendored
2
.gitattributes
vendored
@@ -1,4 +1,4 @@
|
|||||||
kitty/wcwidth9.h linguist-generated=true
|
kitty/wcwidth-std.h linguist-generated=true
|
||||||
kitty/emoji.h linguist-generated=true
|
kitty/emoji.h linguist-generated=true
|
||||||
kitty/keys.h linguist-generated=true
|
kitty/keys.h linguist-generated=true
|
||||||
kitty/charsets.c linguist-generated=true
|
kitty/charsets.c linguist-generated=true
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ matrix:
|
|||||||
env:
|
env:
|
||||||
- RUN_FLAKE=1 BUILD_PKG=1
|
- RUN_FLAKE=1 BUILD_PKG=1
|
||||||
language: python
|
language: python
|
||||||
python: "3.5"
|
python: "3.6"
|
||||||
addons:
|
addons:
|
||||||
apt:
|
apt:
|
||||||
packages:
|
packages:
|
||||||
@@ -123,6 +123,7 @@ before_script:
|
|||||||
- $PYTHON setup.py build --debug --verbose $SANITIZE_ARG;
|
- $PYTHON setup.py build --debug --verbose $SANITIZE_ARG;
|
||||||
|
|
||||||
script:
|
script:
|
||||||
|
- if grep -Inr '\s$' kitty kitty_tests *.py *.asciidoc .gitattributes .gitignore; then echo Trailing whitespace found, aborting.; exit 1; fi
|
||||||
- if [[ -z $SANITIZE_ARG ]]; then $PYTHON test.py; else ./asan-launcher test.py; fi
|
- if [[ -z $SANITIZE_ARG ]]; then $PYTHON test.py; else ./asan-launcher test.py; fi
|
||||||
- if [[ "$RUN_FLAKE" == "1" ]]; then flake8 --count .; fi
|
- if [[ "$RUN_FLAKE" == "1" ]]; then flake8 --count .; fi
|
||||||
- if [[ "$BUILD_PKG" == "1" ]]; then $PYTHON setup.py linux-package; fi
|
- if [[ "$BUILD_PKG" == "1" ]]; then $PYTHON setup.py linux-package; fi
|
||||||
|
|||||||
@@ -3,6 +3,34 @@ Changelog
|
|||||||
|
|
||||||
kitty is a feature full, cross-platform, *fast*, GPU based terminal emulator.
|
kitty is a feature full, cross-platform, *fast*, GPU based terminal emulator.
|
||||||
|
|
||||||
|
version 0.6.1 [2017-12-28]
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
- Add an option to fade the text in inactive windows
|
||||||
|
|
||||||
|
- Add new actions to open windows/tabs/etc. with the working directory set to
|
||||||
|
the working directory of the current window.
|
||||||
|
|
||||||
|
- Automatically adjust cell size when DPI changes, for example when kitty is
|
||||||
|
moved from one monitor to another with a different DPI
|
||||||
|
|
||||||
|
- Ensure underlines are rendered even for fonts with very poor metrics
|
||||||
|
|
||||||
|
- Fix some emoji glyphs not colored on Linux
|
||||||
|
|
||||||
|
- Internal wcwidth() implementation is now auto-generated from the unicode
|
||||||
|
standard database
|
||||||
|
|
||||||
|
- Allow configuring the modifiers to use for rectangular selection with the
|
||||||
|
mouse.
|
||||||
|
|
||||||
|
- Fix incorrect minimum wayland version in the build script
|
||||||
|
|
||||||
|
- Fix a crash when detecting a URL that ends at the end of the line
|
||||||
|
|
||||||
|
- Fix regression that broke drawing of hollow cursor when window loses focus
|
||||||
|
|
||||||
|
|
||||||
version 0.6.0 [2017-12-18]
|
version 0.6.0 [2017-12-18]
|
||||||
---------------------------
|
---------------------------
|
||||||
|
|
||||||
|
|||||||
@@ -119,7 +119,9 @@ python3 /path/to/kitty/folder
|
|||||||
|
|
||||||
=== Linux packages
|
=== Linux packages
|
||||||
|
|
||||||
* Arch linux: AUR git package https://aur.archlinux.org/packages/kitty-git/
|
* Arch Linux: AUR git package https://aur.archlinux.org/packages/kitty-git/
|
||||||
|
|
||||||
|
* Arch Linux: AUR stable package https://aur.archlinux.org/packages/kitty/
|
||||||
|
|
||||||
* NixOS / nixpkgs: https://github.com/NixOS/nixpkgs/blob/master/pkgs/applications/misc/kitty/default.nix
|
* NixOS / nixpkgs: https://github.com/NixOS/nixpkgs/blob/master/pkgs/applications/misc/kitty/default.nix
|
||||||
|
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
cloc --exclude-list-file <(echo -e 'kitty/wcwidth9.h\nkitty/glfw.c\nkitty/keys.h\nkitty/charsets.c\nkitty/key_encoding.py\nkitty/rgb.py\nkitty/gl.h\nkitty/gl-wrapper.h\nkitty/gl-wrapper.c\nkitty/khrplatform.h\nkitty/glfw-wrapper.h\nkitty/glfw-wrapper.c\nkitty/emoji.h') kitty
|
cloc --exclude-list-file <(echo -e 'kitty/wcwidth-std.h\nkitty/glfw.c\nkitty/keys.h\nkitty/charsets.c\nkitty/key_encoding.py\nkitty/rgb.py\nkitty/gl.h\nkitty/gl-wrapper.h\nkitty/gl-wrapper.c\nkitty/khrplatform.h\nkitty/glfw-wrapper.h\nkitty/glfw-wrapper.c\nkitty/emoji.h') kitty
|
||||||
|
|||||||
75
gen-emoji.py
75
gen-emoji.py
@@ -1,75 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
# vim:fileencoding=utf-8
|
|
||||||
# License: GPL v3 Copyright: 2017, Kovid Goyal <kovid at kovidgoyal.net>
|
|
||||||
|
|
||||||
import os
|
|
||||||
from collections import defaultdict
|
|
||||||
from functools import partial
|
|
||||||
from itertools import groupby
|
|
||||||
from operator import itemgetter
|
|
||||||
from urllib.request import urlopen
|
|
||||||
|
|
||||||
os.chdir(os.path.dirname(os.path.abspath(__file__)))
|
|
||||||
|
|
||||||
raw = urlopen('http://unicode.org/Public/emoji/5.0/emoji-data.txt').read().decode('utf-8')
|
|
||||||
seen = set()
|
|
||||||
cmap = defaultdict(set)
|
|
||||||
for line in raw.splitlines():
|
|
||||||
line = line.strip()
|
|
||||||
if not line or line.startswith('#'):
|
|
||||||
continue
|
|
||||||
spec, rest = line.partition(';')[::2]
|
|
||||||
spec, rest = spec.strip(), rest.strip().split(' ', 1)[0].strip()
|
|
||||||
if '.' in spec:
|
|
||||||
spec = tuple(map(lambda x: int(x, 16), filter(None, spec.split('.'))))
|
|
||||||
spec = set(range(spec[0], spec[1] + 1))
|
|
||||||
else:
|
|
||||||
spec = {int(spec, 16)}
|
|
||||||
cmap[rest] |= spec
|
|
||||||
seen |= spec
|
|
||||||
items = list(seen)
|
|
||||||
|
|
||||||
|
|
||||||
def get_ranges(items):
|
|
||||||
items.sort()
|
|
||||||
for k, g in groupby(enumerate(items), lambda m: m[0]-m[1]):
|
|
||||||
group = tuple(map(itemgetter(1), g))
|
|
||||||
a, b = group[0], group[-1]
|
|
||||||
if a == b:
|
|
||||||
yield a
|
|
||||||
else:
|
|
||||||
yield a, b
|
|
||||||
|
|
||||||
|
|
||||||
def write_case(spec, p):
|
|
||||||
if isinstance(spec, tuple):
|
|
||||||
p('\t\tcase 0x{:x} ... 0x{:x}:'.format(*spec))
|
|
||||||
else:
|
|
||||||
p('\t\tcase 0x{:x}:'.format(spec))
|
|
||||||
|
|
||||||
|
|
||||||
with open('kitty/emoji.h', 'w') as f:
|
|
||||||
p = partial(print, file=f)
|
|
||||||
p('#pragma once')
|
|
||||||
p('#include "data-types.h"\n')
|
|
||||||
p('START_ALLOW_CASE_RANGE')
|
|
||||||
p('static inline bool is_emoji(uint32_t code) {')
|
|
||||||
p('\tswitch(code) {')
|
|
||||||
for spec in get_ranges(items):
|
|
||||||
last = spec[1] if isinstance(spec, tuple) else spec
|
|
||||||
if last < 0x231a:
|
|
||||||
continue
|
|
||||||
write_case(spec, p)
|
|
||||||
p('\t\t\treturn true;')
|
|
||||||
p('\t\tdefault: return false;')
|
|
||||||
p('\t}')
|
|
||||||
p('\treturn false; \n}')
|
|
||||||
p('static inline bool is_emoji_modifier(uint32_t code) {')
|
|
||||||
p('\tswitch(code) {')
|
|
||||||
for spec in get_ranges(list(cmap['Emoji_Modifier'])):
|
|
||||||
write_case(spec, p)
|
|
||||||
p('\t\t\treturn true;')
|
|
||||||
p('\t\tdefault: return false;')
|
|
||||||
p('\t}')
|
|
||||||
p('\treturn false; \n}')
|
|
||||||
p('END_ALLOW_CASE_RANGE')
|
|
||||||
199
gen-wcwidth.py
Executable file
199
gen-wcwidth.py
Executable file
@@ -0,0 +1,199 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# vim:fileencoding=utf-8
|
||||||
|
# License: GPL v3 Copyright: 2017, Kovid Goyal <kovid at kovidgoyal.net>
|
||||||
|
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
from contextlib import contextmanager
|
||||||
|
from datetime import date
|
||||||
|
from functools import partial
|
||||||
|
from itertools import groupby
|
||||||
|
from operator import itemgetter
|
||||||
|
from urllib.request import urlopen
|
||||||
|
|
||||||
|
# We ignore the first few emojis as they are widely assumed to be single width
|
||||||
|
# in legacy applications
|
||||||
|
FIRST_EMOJI = 0x2194
|
||||||
|
os.chdir(os.path.dirname(os.path.abspath(__file__)))
|
||||||
|
|
||||||
|
|
||||||
|
def get_data(fname, folder='UCD'):
|
||||||
|
url = f'https://www.unicode.org/Public/{folder}/latest/{fname}'
|
||||||
|
bn = os.path.basename(url)
|
||||||
|
local = os.path.join('/tmp', bn)
|
||||||
|
if os.path.exists(local):
|
||||||
|
data = open(local, 'rb').read()
|
||||||
|
else:
|
||||||
|
data = urlopen(url).read()
|
||||||
|
open(local, 'wb').write(data)
|
||||||
|
for line in data.decode('utf-8').splitlines():
|
||||||
|
line = line.strip()
|
||||||
|
if line and not line.startswith('#'):
|
||||||
|
yield line
|
||||||
|
|
||||||
|
|
||||||
|
# Map of class names to set of codepoints in class
|
||||||
|
class_maps = {}
|
||||||
|
combining_codepoints = set()
|
||||||
|
not_assigned = set(range(0, sys.maxunicode))
|
||||||
|
|
||||||
|
|
||||||
|
def parse_ucd():
|
||||||
|
first = None
|
||||||
|
for line in get_data('ucd/UnicodeData.txt'):
|
||||||
|
parts = [x.strip() for x in line.split(';')]
|
||||||
|
codepoint = int(parts[0], 16)
|
||||||
|
category = parts[2]
|
||||||
|
s = class_maps.setdefault(category, set())
|
||||||
|
desc = parts[1]
|
||||||
|
codepoints = (codepoint,)
|
||||||
|
if first is None:
|
||||||
|
if desc.endswith(', First>'):
|
||||||
|
first = codepoint
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
codepoints = range(first, codepoint + 1)
|
||||||
|
first = None
|
||||||
|
for codepoint in codepoints:
|
||||||
|
s.add(codepoint)
|
||||||
|
not_assigned.discard(codepoint)
|
||||||
|
cc = parts[3]
|
||||||
|
if cc and cc != '0':
|
||||||
|
combining_codepoints.add(codepoint)
|
||||||
|
|
||||||
|
|
||||||
|
def split_two(line):
|
||||||
|
spec, rest = line.split(';', 1)
|
||||||
|
spec, rest = spec.strip(), rest.strip().split(' ', 1)[0].strip()
|
||||||
|
if '..' in spec:
|
||||||
|
chars = tuple(map(lambda x: int(x, 16), filter(None, spec.split('.'))))
|
||||||
|
chars = set(range(chars[0], chars[1] + 1))
|
||||||
|
else:
|
||||||
|
chars = {int(spec, 16)}
|
||||||
|
return chars, rest
|
||||||
|
|
||||||
|
|
||||||
|
all_emoji = set()
|
||||||
|
emoji_categories = {}
|
||||||
|
|
||||||
|
|
||||||
|
def parse_emoji():
|
||||||
|
for line in get_data('emoji-data.txt', 'emoji'):
|
||||||
|
chars, rest = split_two(line)
|
||||||
|
if max(chars) >= FIRST_EMOJI:
|
||||||
|
s = emoji_categories.setdefault(rest, set())
|
||||||
|
s |= chars
|
||||||
|
all_emoji.update(chars)
|
||||||
|
|
||||||
|
|
||||||
|
doublewidth, ambiguous = set(), set()
|
||||||
|
|
||||||
|
|
||||||
|
def parse_eaw():
|
||||||
|
global doublewidth, ambiguous
|
||||||
|
seen = set()
|
||||||
|
for line in get_data('ucd/EastAsianWidth.txt'):
|
||||||
|
chars, eaw = split_two(line)
|
||||||
|
if eaw == 'A':
|
||||||
|
ambiguous |= chars
|
||||||
|
seen |= chars
|
||||||
|
elif eaw == 'W' or eaw == 'F':
|
||||||
|
doublewidth |= chars
|
||||||
|
seen |= chars
|
||||||
|
doublewidth |= set(range(0x3400, 0x4DBF + 1)) - seen
|
||||||
|
doublewidth |= set(range(0x4E00, 0x9FFF + 1)) - seen
|
||||||
|
doublewidth |= set(range(0xF900, 0xFAFF + 1)) - seen
|
||||||
|
doublewidth |= set(range(0x20000, 0x2FFFD + 1)) - seen
|
||||||
|
doublewidth |= set(range(0x30000, 0x3FFFD + 1)) - seen
|
||||||
|
|
||||||
|
|
||||||
|
def get_ranges(items):
|
||||||
|
items.sort()
|
||||||
|
for k, g in groupby(enumerate(items), lambda m: m[0]-m[1]):
|
||||||
|
group = tuple(map(itemgetter(1), g))
|
||||||
|
a, b = group[0], group[-1]
|
||||||
|
if a == b:
|
||||||
|
yield a
|
||||||
|
else:
|
||||||
|
yield a, b
|
||||||
|
|
||||||
|
|
||||||
|
def write_case(spec, p):
|
||||||
|
if isinstance(spec, tuple):
|
||||||
|
p('\t\tcase 0x{:x} ... 0x{:x}:'.format(*spec))
|
||||||
|
else:
|
||||||
|
p('\t\tcase 0x{:x}:'.format(spec))
|
||||||
|
|
||||||
|
|
||||||
|
@contextmanager
|
||||||
|
def create_header(path):
|
||||||
|
f = open(path, 'w')
|
||||||
|
p = partial(print, file=f)
|
||||||
|
p('// unicode data, built from the unicode standard on:', date.today())
|
||||||
|
p('// see gen-wcwidth.py')
|
||||||
|
p('#pragma once')
|
||||||
|
p('#include "data-types.h"\n')
|
||||||
|
p('START_ALLOW_CASE_RANGE')
|
||||||
|
p()
|
||||||
|
yield p
|
||||||
|
p()
|
||||||
|
p('END_ALLOW_CASE_RANGE')
|
||||||
|
f.close()
|
||||||
|
|
||||||
|
|
||||||
|
def gen_emoji():
|
||||||
|
with create_header('kitty/emoji.h') as p:
|
||||||
|
p('static inline bool\nis_emoji(char_type code) {')
|
||||||
|
p('\tswitch(code) {')
|
||||||
|
for spec in get_ranges(list(all_emoji)):
|
||||||
|
write_case(spec, p)
|
||||||
|
p('\t\t\treturn true;')
|
||||||
|
p('\t\tdefault: return false;')
|
||||||
|
p('\t}')
|
||||||
|
p('\treturn false;\n}')
|
||||||
|
p('static inline bool\nis_emoji_modifier(char_type code) {')
|
||||||
|
p('\tswitch(code) {')
|
||||||
|
for spec in get_ranges(list(emoji_categories['Emoji_Modifier'])):
|
||||||
|
write_case(spec, p)
|
||||||
|
p('\t\t\treturn true;')
|
||||||
|
p('\t\tdefault: return false;')
|
||||||
|
p('\t}')
|
||||||
|
p('\treturn false;\n}')
|
||||||
|
|
||||||
|
|
||||||
|
def gen_wcwidth():
|
||||||
|
seen = set()
|
||||||
|
|
||||||
|
def add(p, comment, chars_, ret):
|
||||||
|
chars = chars_ - seen
|
||||||
|
seen.update(chars)
|
||||||
|
p(f'\t\t// {comment} ({len(chars)} codepoints)' + ' {{{')
|
||||||
|
for spec in get_ranges(list(chars)):
|
||||||
|
write_case(spec, p)
|
||||||
|
p(f'\t\t\treturn {ret};')
|
||||||
|
p('\t\t// }}}\n')
|
||||||
|
|
||||||
|
with create_header('kitty/wcwidth-std.h') as p:
|
||||||
|
p('static int\nwcwidth_std(int32_t code) {')
|
||||||
|
p('\tswitch(code) {')
|
||||||
|
|
||||||
|
non_printing = class_maps['Cc'] | class_maps['Cf'] | class_maps['Cs']
|
||||||
|
add(p, 'Non-printing characters', non_printing, -1)
|
||||||
|
add(p, 'Combining characters', combining_codepoints, -1)
|
||||||
|
add(p, 'Private use', class_maps['Co'], -3)
|
||||||
|
add(p, 'East Asian ambiguous width', ambiguous, -2)
|
||||||
|
add(p, 'East Asian double width', doublewidth, 2)
|
||||||
|
add(p, 'Emoji', all_emoji, 2)
|
||||||
|
|
||||||
|
add(p, 'Not assigned in the unicode character database', not_assigned, -1)
|
||||||
|
|
||||||
|
p('\t\tdefault: return 1;')
|
||||||
|
p('\t}')
|
||||||
|
p('\treturn 1;\n}')
|
||||||
|
|
||||||
|
|
||||||
|
parse_ucd()
|
||||||
|
parse_emoji()
|
||||||
|
parse_eaw()
|
||||||
|
gen_wcwidth()
|
||||||
|
gen_emoji()
|
||||||
@@ -43,6 +43,7 @@
|
|||||||
#define NSEventModifierFlagControl NSControlKeyMask
|
#define NSEventModifierFlagControl NSControlKeyMask
|
||||||
#define NSEventModifierFlagOption NSAlternateKeyMask
|
#define NSEventModifierFlagOption NSAlternateKeyMask
|
||||||
#define NSEventModifierFlagShift NSShiftKeyMask
|
#define NSEventModifierFlagShift NSShiftKeyMask
|
||||||
|
#define NSEventModifierFlagCapsLock NSAlphaShiftKeyMask
|
||||||
#define NSEventModifierFlagDeviceIndependentFlagsMask NSDeviceIndependentModifierFlagsMask
|
#define NSEventModifierFlagDeviceIndependentFlagsMask NSDeviceIndependentModifierFlagsMask
|
||||||
#define NSEventMaskAny NSAnyEventMask
|
#define NSEventMaskAny NSAnyEventMask
|
||||||
#define NSEventTypeApplicationDefined NSApplicationDefined
|
#define NSEventTypeApplicationDefined NSApplicationDefined
|
||||||
@@ -177,6 +178,8 @@ static int translateFlags(NSUInteger flags)
|
|||||||
mods |= GLFW_MOD_ALT;
|
mods |= GLFW_MOD_ALT;
|
||||||
if (flags & NSEventModifierFlagCommand)
|
if (flags & NSEventModifierFlagCommand)
|
||||||
mods |= GLFW_MOD_SUPER;
|
mods |= GLFW_MOD_SUPER;
|
||||||
|
if (flags & NSEventModifierFlagCapsLock)
|
||||||
|
mods |= GLFW_MOD_CAPS_LOCK;
|
||||||
|
|
||||||
return mods;
|
return mods;
|
||||||
}
|
}
|
||||||
@@ -1087,8 +1090,8 @@ static GLFWbool createNativeWindow(_GLFWwindow* window,
|
|||||||
[window->ns.object zoom:nil];
|
[window->ns.object zoom:nil];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wndconfig->ns.frame)
|
if (strlen(wndconfig->ns.frameName))
|
||||||
[window->ns.object setFrameAutosaveName:[NSString stringWithUTF8String:wndconfig->title]];
|
[window->ns.object setFrameAutosaveName:[NSString stringWithUTF8String:wndconfig->ns.frameName]];
|
||||||
|
|
||||||
window->ns.view = [[GLFWContentView alloc] initWithGlfwWindow:window];
|
window->ns.view = [[GLFWContentView alloc] initWithGlfwWindow:window];
|
||||||
|
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ def init_env(env, pkg_config, at_least_version, module='x11'):
|
|||||||
ans.ldpaths.extend(('-framework', f))
|
ans.ldpaths.extend(('-framework', f))
|
||||||
|
|
||||||
elif module == 'wayland':
|
elif module == 'wayland':
|
||||||
at_least_version('wayland-protocols', 1, 1)
|
at_least_version('wayland-protocols', 1, 6)
|
||||||
ans.wayland_packagedir = os.path.abspath(pkg_config('wayland-protocols', '--variable=pkgdatadir')[0])
|
ans.wayland_packagedir = os.path.abspath(pkg_config('wayland-protocols', '--variable=pkgdatadir')[0])
|
||||||
ans.wayland_scanner = os.path.abspath(pkg_config('wayland-scanner', '--variable=wayland_scanner')[0])
|
ans.wayland_scanner = os.path.abspath(pkg_config('wayland-scanner', '--variable=wayland_scanner')[0])
|
||||||
ans.wayland_protocols = tuple(sinfo[module]['protocols'])
|
ans.wayland_protocols = tuple(sinfo[module]['protocols'])
|
||||||
@@ -69,6 +69,8 @@ def init_env(env, pkg_config, at_least_version, module='x11'):
|
|||||||
def build_wayland_protocols(env, run_tool, emphasis, newer, dest_dir):
|
def build_wayland_protocols(env, run_tool, emphasis, newer, dest_dir):
|
||||||
for protocol in env.wayland_protocols:
|
for protocol in env.wayland_protocols:
|
||||||
src = os.path.join(env.wayland_packagedir, protocol)
|
src = os.path.join(env.wayland_packagedir, protocol)
|
||||||
|
if not os.path.exists(src):
|
||||||
|
raise SystemExit('The wayland-protocols package on your system is missing the {} protocol definition file'.format(protocol))
|
||||||
for ext in 'hc':
|
for ext in 'hc':
|
||||||
dest = wayland_protocol_file_name(src, ext)
|
dest = wayland_protocol_file_name(src, ext)
|
||||||
dest = os.path.join(dest_dir, dest)
|
dest = os.path.join(dest_dir, dest)
|
||||||
|
|||||||
263
glfw/glfw3.h
vendored
263
glfw/glfw3.h
vendored
@@ -493,17 +493,37 @@ extern "C" {
|
|||||||
* @{ */
|
* @{ */
|
||||||
|
|
||||||
/*! @brief If this bit is set one or more Shift keys were held down.
|
/*! @brief If this bit is set one or more Shift keys were held down.
|
||||||
|
*
|
||||||
|
* If this bit is set one or more Shift keys were held down.
|
||||||
*/
|
*/
|
||||||
#define GLFW_MOD_SHIFT 0x0001
|
#define GLFW_MOD_SHIFT 0x0001
|
||||||
/*! @brief If this bit is set one or more Control keys were held down.
|
/*! @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
|
#define GLFW_MOD_CONTROL 0x0002
|
||||||
/*! @brief If this bit is set one or more Alt keys were held down.
|
/*! @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 0x0004
|
||||||
/*! @brief If this bit is set one or more Super keys were held down.
|
/*! @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
|
#define GLFW_MOD_SUPER 0x0008
|
||||||
|
/*! @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
|
||||||
|
/*! @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
|
||||||
|
|
||||||
/*! @} */
|
/*! @} */
|
||||||
|
|
||||||
@@ -944,8 +964,11 @@ extern "C" {
|
|||||||
#define GLFW_CONTEXT_CREATION_API 0x0002200B
|
#define GLFW_CONTEXT_CREATION_API 0x0002200B
|
||||||
|
|
||||||
#define GLFW_COCOA_RETINA_FRAMEBUFFER 0x00023001
|
#define GLFW_COCOA_RETINA_FRAMEBUFFER 0x00023001
|
||||||
#define GLFW_COCOA_FRAME_AUTOSAVE 0x00023002
|
#define GLFW_COCOA_FRAME_NAME 0x00023002
|
||||||
#define GLFW_COCOA_GRAPHICS_SWITCHING 0x00023003
|
#define GLFW_COCOA_GRAPHICS_SWITCHING 0x00023003
|
||||||
|
|
||||||
|
#define GLFW_X11_CLASS_NAME 0x00024001
|
||||||
|
#define GLFW_X11_INSTANCE_NAME 0x00024002
|
||||||
/*! @} */
|
/*! @} */
|
||||||
|
|
||||||
#define GLFW_NO_API 0
|
#define GLFW_NO_API 0
|
||||||
@@ -963,6 +986,7 @@ extern "C" {
|
|||||||
#define GLFW_CURSOR 0x00033001
|
#define GLFW_CURSOR 0x00033001
|
||||||
#define GLFW_STICKY_KEYS 0x00033002
|
#define GLFW_STICKY_KEYS 0x00033002
|
||||||
#define GLFW_STICKY_MOUSE_BUTTONS 0x00033003
|
#define GLFW_STICKY_MOUSE_BUTTONS 0x00033003
|
||||||
|
#define GLFW_LOCK_KEY_MODS 0x00033004
|
||||||
|
|
||||||
#define GLFW_CURSOR_NORMAL 0x00034001
|
#define GLFW_CURSOR_NORMAL 0x00034001
|
||||||
#define GLFW_CURSOR_HIDDEN 0x00034002
|
#define GLFW_CURSOR_HIDDEN 0x00034002
|
||||||
@@ -1025,9 +1049,6 @@ extern "C" {
|
|||||||
|
|
||||||
#define GLFW_COCOA_CHDIR_RESOURCES 0x00051001
|
#define GLFW_COCOA_CHDIR_RESOURCES 0x00051001
|
||||||
#define GLFW_COCOA_MENUBAR 0x00051002
|
#define GLFW_COCOA_MENUBAR 0x00051002
|
||||||
|
|
||||||
#define GLFW_X11_WM_CLASS_NAME 0x00052001
|
|
||||||
#define GLFW_X11_WM_CLASS_CLASS 0x00052002
|
|
||||||
/*! @} */
|
/*! @} */
|
||||||
|
|
||||||
#define GLFW_DONT_CARE -1
|
#define GLFW_DONT_CARE -1
|
||||||
@@ -1046,7 +1067,7 @@ extern "C" {
|
|||||||
* @sa @ref glfwGetProcAddress
|
* @sa @ref glfwGetProcAddress
|
||||||
*
|
*
|
||||||
* @since Added in version 3.0.
|
* @since Added in version 3.0.
|
||||||
|
*
|
||||||
* @ingroup context
|
* @ingroup context
|
||||||
*/
|
*/
|
||||||
typedef void (*GLFWglproc)(void);
|
typedef void (*GLFWglproc)(void);
|
||||||
@@ -1623,8 +1644,7 @@ GLFWAPI void glfwTerminate(void);
|
|||||||
|
|
||||||
/*! @brief Sets the specified init hint to the desired value.
|
/*! @brief Sets the specified init hint to the desired value.
|
||||||
*
|
*
|
||||||
* This function sets hints for the next initialization of GLFW. Only integer
|
* This function sets hints for the next initialization of GLFW.
|
||||||
* type hints can be set with this function.
|
|
||||||
*
|
*
|
||||||
* The values you set hints to are never reset by GLFW, but they only take
|
* The values you set hints to are never reset by GLFW, but they only take
|
||||||
* effect during initialization. Once GLFW has been initialized, any values
|
* effect during initialization. Once GLFW has been initialized, any values
|
||||||
@@ -1647,7 +1667,6 @@ GLFWAPI void glfwTerminate(void);
|
|||||||
*
|
*
|
||||||
* @sa init_hints
|
* @sa init_hints
|
||||||
* @sa glfwInit
|
* @sa glfwInit
|
||||||
* @sa glfwInitHintString
|
|
||||||
*
|
*
|
||||||
* @since Added in version 3.3.
|
* @since Added in version 3.3.
|
||||||
*
|
*
|
||||||
@@ -1655,40 +1674,6 @@ GLFWAPI void glfwTerminate(void);
|
|||||||
*/
|
*/
|
||||||
GLFWAPI void glfwInitHint(int hint, int value);
|
GLFWAPI void glfwInitHint(int hint, int value);
|
||||||
|
|
||||||
/*! @brief Sets the specified init hint to the desired value.
|
|
||||||
*
|
|
||||||
* This function sets hints for the next initialization of GLFW. Only string
|
|
||||||
* type hints can be set with this function.
|
|
||||||
*
|
|
||||||
* The values you set hints to are never reset by GLFW, but they only take
|
|
||||||
* effect during initialization. Once GLFW has been initialized, any values
|
|
||||||
* you set will be ignored until the library is terminated and initialized
|
|
||||||
* again.
|
|
||||||
*
|
|
||||||
* Some hints are platform specific. These may be set on any platform but they
|
|
||||||
* will only affect their specific platform. Other platforms will ignore them.
|
|
||||||
* Setting these hints requires no platform specific headers or functions.
|
|
||||||
*
|
|
||||||
* @param[in] hint The [init hint](@ref init_hints) to set.
|
|
||||||
* @param[in] value The new value of the init hint.
|
|
||||||
*
|
|
||||||
* @errors Possible errors include @ref GLFW_INVALID_ENUM and @ref
|
|
||||||
* GLFW_INVALID_VALUE.
|
|
||||||
*
|
|
||||||
* @remarks This function may be called before @ref glfwInit.
|
|
||||||
*
|
|
||||||
* @thread_safety This function must only be called from the main thread.
|
|
||||||
*
|
|
||||||
* @sa init_hints
|
|
||||||
* @sa glfwInit
|
|
||||||
* @sa glfwInitHint
|
|
||||||
*
|
|
||||||
* @since Added in version 3.3.
|
|
||||||
*
|
|
||||||
* @ingroup init
|
|
||||||
*/
|
|
||||||
GLFWAPI void glfwInitHintString(int hint, const char* value);
|
|
||||||
|
|
||||||
/*! @brief Retrieves the version of the GLFW library.
|
/*! @brief Retrieves the version of the GLFW library.
|
||||||
*
|
*
|
||||||
* This function retrieves the major, minor and revision numbers of the GLFW
|
* This function retrieves the major, minor and revision numbers of the GLFW
|
||||||
@@ -1985,6 +1970,56 @@ GLFWAPI void glfwGetMonitorContentScale(GLFWmonitor* monitor, float* xscale, flo
|
|||||||
*/
|
*/
|
||||||
GLFWAPI const char* glfwGetMonitorName(GLFWmonitor* monitor);
|
GLFWAPI const char* glfwGetMonitorName(GLFWmonitor* monitor);
|
||||||
|
|
||||||
|
/*! @brief Sets the user pointer of the specified monitor.
|
||||||
|
*
|
||||||
|
* This function sets the user-defined pointer of the specified monitor. The
|
||||||
|
* current value is retained until the monitor is disconnected. The initial
|
||||||
|
* value is `NULL`.
|
||||||
|
*
|
||||||
|
* This function may be called from the monitor callback, even for a monitor
|
||||||
|
* that is being disconnected.
|
||||||
|
*
|
||||||
|
* @param[in] monitor The monitor whose pointer to set.
|
||||||
|
* @param[in] pointer The new value.
|
||||||
|
*
|
||||||
|
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
|
||||||
|
*
|
||||||
|
* @thread_safety This function may be called from any thread. Access is not
|
||||||
|
* synchronized.
|
||||||
|
*
|
||||||
|
* @sa @ref monitor_userptr
|
||||||
|
* @sa @ref glfwGetMonitorUserPointer
|
||||||
|
*
|
||||||
|
* @since Added in version 3.3.
|
||||||
|
*
|
||||||
|
* @ingroup monitor
|
||||||
|
*/
|
||||||
|
GLFWAPI void glfwSetMonitorUserPointer(GLFWmonitor* monitor, void* pointer);
|
||||||
|
|
||||||
|
/*! @brief Returns the user pointer of the specified monitor.
|
||||||
|
*
|
||||||
|
* This function returns the current value of the user-defined pointer of the
|
||||||
|
* specified monitor. The initial value is `NULL`.
|
||||||
|
*
|
||||||
|
* This function may be called from the monitor callback, even for a monitor
|
||||||
|
* that is being disconnected.
|
||||||
|
*
|
||||||
|
* @param[in] monitor The monitor whose pointer to return.
|
||||||
|
*
|
||||||
|
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
|
||||||
|
*
|
||||||
|
* @thread_safety This function may be called from any thread. Access is not
|
||||||
|
* synchronized.
|
||||||
|
*
|
||||||
|
* @sa @ref monitor_userptr
|
||||||
|
* @sa @ref glfwSetMonitorUserPointer
|
||||||
|
*
|
||||||
|
* @since Added in version 3.3.
|
||||||
|
*
|
||||||
|
* @ingroup monitor
|
||||||
|
*/
|
||||||
|
GLFWAPI void* glfwGetMonitorUserPointer(GLFWmonitor* monitor);
|
||||||
|
|
||||||
/*! @brief Sets the monitor configuration callback.
|
/*! @brief Sets the monitor configuration callback.
|
||||||
*
|
*
|
||||||
* This function sets the monitor configuration callback, or removes the
|
* This function sets the monitor configuration callback, or removes the
|
||||||
@@ -2184,6 +2219,7 @@ GLFWAPI void glfwSetGammaRamp(GLFWmonitor* monitor, const GLFWgammaramp* ramp);
|
|||||||
*
|
*
|
||||||
* @sa @ref window_hints
|
* @sa @ref window_hints
|
||||||
* @sa @ref glfwWindowHint
|
* @sa @ref glfwWindowHint
|
||||||
|
* @sa @ref glfwWindowHintString
|
||||||
*
|
*
|
||||||
* @since Added in version 3.0.
|
* @since Added in version 3.0.
|
||||||
*
|
*
|
||||||
@@ -2194,14 +2230,20 @@ GLFWAPI void glfwDefaultWindowHints(void);
|
|||||||
/*! @brief Sets the specified window hint to the desired value.
|
/*! @brief Sets the specified window hint to the desired value.
|
||||||
*
|
*
|
||||||
* This function sets hints for the next call to @ref glfwCreateWindow. The
|
* This function sets hints for the next call to @ref glfwCreateWindow. The
|
||||||
* hints, once set, retain their values until changed by a call to @ref
|
* hints, once set, retain their values until changed by a call to this
|
||||||
* glfwWindowHint or @ref glfwDefaultWindowHints, or until the library is
|
* function or @ref glfwDefaultWindowHints, or until the library is terminated.
|
||||||
* terminated.
|
*
|
||||||
|
* Only integer value hints can be set with this function. String value hints
|
||||||
|
* are set with @ref glfwWindowHintString.
|
||||||
*
|
*
|
||||||
* This function does not check whether the specified hint values are valid.
|
* This function does not check whether the specified hint values are valid.
|
||||||
* If you set hints to invalid values this will instead be reported by the next
|
* If you set hints to invalid values this will instead be reported by the next
|
||||||
* call to @ref glfwCreateWindow.
|
* call to @ref glfwCreateWindow.
|
||||||
*
|
*
|
||||||
|
* Some hints are platform specific. These may be set on any platform but they
|
||||||
|
* will only affect their specific platform. Other platforms will ignore them.
|
||||||
|
* Setting these hints requires no platform specific headers or functions.
|
||||||
|
*
|
||||||
* @param[in] hint The [window hint](@ref window_hints) to set.
|
* @param[in] hint The [window hint](@ref window_hints) to set.
|
||||||
* @param[in] value The new value of the window hint.
|
* @param[in] value The new value of the window hint.
|
||||||
*
|
*
|
||||||
@@ -2211,6 +2253,7 @@ GLFWAPI void glfwDefaultWindowHints(void);
|
|||||||
* @thread_safety This function must only be called from the main thread.
|
* @thread_safety This function must only be called from the main thread.
|
||||||
*
|
*
|
||||||
* @sa @ref window_hints
|
* @sa @ref window_hints
|
||||||
|
* @sa @ref glfwWindowHintString
|
||||||
* @sa @ref glfwDefaultWindowHints
|
* @sa @ref glfwDefaultWindowHints
|
||||||
*
|
*
|
||||||
* @since Added in version 3.0. Replaces `glfwOpenWindowHint`.
|
* @since Added in version 3.0. Replaces `glfwOpenWindowHint`.
|
||||||
@@ -2219,6 +2262,44 @@ GLFWAPI void glfwDefaultWindowHints(void);
|
|||||||
*/
|
*/
|
||||||
GLFWAPI void glfwWindowHint(int hint, int value);
|
GLFWAPI void glfwWindowHint(int hint, int value);
|
||||||
|
|
||||||
|
/*! @brief Sets the specified window hint to the desired value.
|
||||||
|
*
|
||||||
|
* This function sets hints for the next call to @ref glfwCreateWindow. The
|
||||||
|
* hints, once set, retain their values until changed by a call to this
|
||||||
|
* function or @ref glfwDefaultWindowHints, or until the library is terminated.
|
||||||
|
*
|
||||||
|
* Only string type hints can be set with this function. Integer value hints
|
||||||
|
* are set with @ref glfwWindowHint.
|
||||||
|
*
|
||||||
|
* This function does not check whether the specified hint values are valid.
|
||||||
|
* If you set hints to invalid values this will instead be reported by the next
|
||||||
|
* call to @ref glfwCreateWindow.
|
||||||
|
*
|
||||||
|
* Some hints are platform specific. These may be set on any platform but they
|
||||||
|
* will only affect their specific platform. Other platforms will ignore them.
|
||||||
|
* Setting these hints requires no platform specific headers or functions.
|
||||||
|
*
|
||||||
|
* @param[in] hint The [window hint](@ref window_hints) to set.
|
||||||
|
* @param[in] value The new value of the window hint.
|
||||||
|
*
|
||||||
|
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
|
||||||
|
* GLFW_INVALID_ENUM.
|
||||||
|
*
|
||||||
|
* @pointer_lifetime The specified string is copied before this function
|
||||||
|
* returns.
|
||||||
|
*
|
||||||
|
* @thread_safety This function must only be called from the main thread.
|
||||||
|
*
|
||||||
|
* @sa @ref window_hints
|
||||||
|
* @sa @ref glfwWindowHint
|
||||||
|
* @sa @ref glfwDefaultWindowHints
|
||||||
|
*
|
||||||
|
* @since Added in version 3.3.
|
||||||
|
*
|
||||||
|
* @ingroup window
|
||||||
|
*/
|
||||||
|
GLFWAPI void glfwWindowHintString(int hint, const char* value);
|
||||||
|
|
||||||
/*! @brief Creates a window and its associated context.
|
/*! @brief Creates a window and its associated context.
|
||||||
*
|
*
|
||||||
* This function creates a window and its associated OpenGL or OpenGL ES
|
* This function creates a window and its associated OpenGL or OpenGL ES
|
||||||
@@ -2329,9 +2410,8 @@ GLFWAPI void glfwWindowHint(int hint, int value);
|
|||||||
* `CMake/MacOSXBundleInfo.plist.in` in the source tree.
|
* `CMake/MacOSXBundleInfo.plist.in` in the source tree.
|
||||||
*
|
*
|
||||||
* @remark @macos When activating frame autosaving with
|
* @remark @macos When activating frame autosaving with
|
||||||
* [GLFW_COCOA_FRAME_AUTOSAVE](@ref GLFW_COCOA_FRAME_AUTOSAVE_hint), the
|
* [GLFW_COCOA_FRAME_NAME](@ref GLFW_COCOA_FRAME_NAME_hint), the specified
|
||||||
* specified window size may be overriden by a previously saved size and
|
* window size and position may be overriden by previously saved values.
|
||||||
* position.
|
|
||||||
*
|
*
|
||||||
* @remark @x11 Some window managers will not respect the placement of
|
* @remark @x11 Some window managers will not respect the placement of
|
||||||
* initially hidden windows.
|
* initially hidden windows.
|
||||||
@@ -2341,15 +2421,12 @@ GLFWAPI void glfwWindowHint(int hint, int value);
|
|||||||
* query the final size, position or other attributes directly after window
|
* query the final size, position or other attributes directly after window
|
||||||
* creation.
|
* creation.
|
||||||
*
|
*
|
||||||
* @remark @x11 The name and class of the `WM_CLASS` window property will by
|
* @remark @x11 The class part of the `WM_CLASS` window property will by
|
||||||
* default be set to the window title passed to this function. Set the @ref
|
* default be set to the window title passed to this function. The instance
|
||||||
* GLFW_X11_WM_CLASS_NAME and @ref GLFW_X11_WM_CLASS_CLASS init hints before
|
* part will use the contents of the `RESOURCE_NAME` environment variable, if
|
||||||
* initialization to override this. You can also set the title int he following
|
* present and not empty, or fall back to the window title. Set the @ref
|
||||||
* special format, which allows setting the two parts of the WM_CLASS property
|
* GLFW_X11_CLASS_NAME and @ref GLFW_X11_INSTANCE_NAME window hints to override
|
||||||
* and the window title independently:
|
* this.
|
||||||
* <01> WM_CLASS name <30> WM_CLASS class <30> title
|
|
||||||
* Here <01> refers to the byte value 01 (ASCII start-of-header) and <30> refers
|
|
||||||
* to the byte value 30 (ASCII record separator).
|
|
||||||
*
|
*
|
||||||
* @remark @wayland The window frame is currently unimplemented, as if
|
* @remark @wayland The window frame is currently unimplemented, as if
|
||||||
* [GLFW_DECORATED](@ref GLFW_DECORATED_hint) was always set to `GLFW_FALSE`.
|
* [GLFW_DECORATED](@ref GLFW_DECORATED_hint) was always set to `GLFW_FALSE`.
|
||||||
@@ -3689,12 +3766,12 @@ GLFWAPI void glfwPostEmptyEvent(void);
|
|||||||
/*! @brief Returns the value of an input option for the specified window.
|
/*! @brief Returns the value of an input option for the specified window.
|
||||||
*
|
*
|
||||||
* This function returns the value of an input option for the specified window.
|
* This function returns the value of an input option for the specified window.
|
||||||
* The mode must be one of @ref GLFW_CURSOR, @ref GLFW_STICKY_KEYS or
|
* The mode must be one of @ref GLFW_CURSOR, @ref GLFW_STICKY_KEYS,
|
||||||
* @ref GLFW_STICKY_MOUSE_BUTTONS.
|
* @ref GLFW_STICKY_MOUSE_BUTTONS or @ref GLFW_LOCK_KEY_MODS.
|
||||||
*
|
*
|
||||||
* @param[in] window The window to query.
|
* @param[in] window The window to query.
|
||||||
* @param[in] mode One of `GLFW_CURSOR`, `GLFW_STICKY_KEYS` or
|
* @param[in] mode One of `GLFW_CURSOR`, `GLFW_STICKY_KEYS`,
|
||||||
* `GLFW_STICKY_MOUSE_BUTTONS`.
|
* `GLFW_STICKY_MOUSE_BUTTONS` or `GLFW_LOCK_KEY_MODS`.
|
||||||
*
|
*
|
||||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
|
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
|
||||||
* GLFW_INVALID_ENUM.
|
* GLFW_INVALID_ENUM.
|
||||||
@@ -3712,8 +3789,8 @@ GLFWAPI int glfwGetInputMode(GLFWwindow* window, int mode);
|
|||||||
/*! @brief Sets an input option for the specified window.
|
/*! @brief Sets an input option for the specified window.
|
||||||
*
|
*
|
||||||
* This function sets an input mode option for the specified window. The mode
|
* This function sets an input mode option for the specified window. The mode
|
||||||
* must be one of @ref GLFW_CURSOR, @ref GLFW_STICKY_KEYS or
|
* must be one of @ref GLFW_CURSOR, @ref GLFW_STICKY_KEYS,
|
||||||
* @ref GLFW_STICKY_MOUSE_BUTTONS.
|
* @ref GLFW_STICKY_MOUSE_BUTTONS or @ref GLFW_LOCK_KEY_MODS.
|
||||||
*
|
*
|
||||||
* If the mode is `GLFW_CURSOR`, the value must be one of the following cursor
|
* If the mode is `GLFW_CURSOR`, the value must be one of the following cursor
|
||||||
* modes:
|
* modes:
|
||||||
@@ -3739,9 +3816,15 @@ GLFWAPI int glfwGetInputMode(GLFWwindow* window, int mode);
|
|||||||
* you are only interested in whether mouse buttons have been pressed but not
|
* you are only interested in whether mouse buttons have been pressed but not
|
||||||
* when or in which order.
|
* when or in which order.
|
||||||
*
|
*
|
||||||
|
* If the mode is `GLFW_LOCK_KEY_MODS`, the value must be either `GLFW_TRUE` to
|
||||||
|
* enable lock key modifier bits, or `GLFW_FALSE` to disable them. If enabled,
|
||||||
|
* callbacks that receive modifier bits will also have the @ref
|
||||||
|
* GLFW_MOD_CAPS_LOCK bit set when the event was generated with Caps Lock on,
|
||||||
|
* and the @ref GLFW_MOD_NUM_LOCK bit when Num Lock was on.
|
||||||
|
*
|
||||||
* @param[in] window The window whose input mode to set.
|
* @param[in] window The window whose input mode to set.
|
||||||
* @param[in] mode One of `GLFW_CURSOR`, `GLFW_STICKY_KEYS` or
|
* @param[in] mode One of `GLFW_CURSOR`, `GLFW_STICKY_KEYS`,
|
||||||
* `GLFW_STICKY_MOUSE_BUTTONS`.
|
* `GLFW_STICKY_MOUSE_BUTTONS` or `GLFW_LOCK_KEY_MODS`.
|
||||||
* @param[in] value The new value of the specified input mode.
|
* @param[in] value The new value of the specified input mode.
|
||||||
*
|
*
|
||||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
|
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
|
||||||
@@ -4588,6 +4671,56 @@ GLFWAPI const char* glfwGetJoystickName(int jid);
|
|||||||
*/
|
*/
|
||||||
GLFWAPI const char* glfwGetJoystickGUID(int jid);
|
GLFWAPI const char* glfwGetJoystickGUID(int jid);
|
||||||
|
|
||||||
|
/*! @brief Sets the user pointer of the specified joystick.
|
||||||
|
*
|
||||||
|
* This function sets the user-defined pointer of the specified joystick. The
|
||||||
|
* current value is retained until the joystick is disconnected. The initial
|
||||||
|
* value is `NULL`.
|
||||||
|
*
|
||||||
|
* This function may be called from the joystick callback, even for a joystick
|
||||||
|
* that is being disconnected.
|
||||||
|
*
|
||||||
|
* @param[in] joystick The joystick whose pointer to set.
|
||||||
|
* @param[in] pointer The new value.
|
||||||
|
*
|
||||||
|
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
|
||||||
|
*
|
||||||
|
* @thread_safety This function may be called from any thread. Access is not
|
||||||
|
* synchronized.
|
||||||
|
*
|
||||||
|
* @sa @ref joystick_userptr
|
||||||
|
* @sa @ref glfwGetJoystickUserPointer
|
||||||
|
*
|
||||||
|
* @since Added in version 3.3.
|
||||||
|
*
|
||||||
|
* @ingroup input
|
||||||
|
*/
|
||||||
|
GLFWAPI void glfwSetJoystickUserPointer(int jid, void* pointer);
|
||||||
|
|
||||||
|
/*! @brief Returns the user pointer of the specified joystick.
|
||||||
|
*
|
||||||
|
* This function returns the current value of the user-defined pointer of the
|
||||||
|
* specified joystick. The initial value is `NULL`.
|
||||||
|
*
|
||||||
|
* This function may be called from the joystick callback, even for a joystick
|
||||||
|
* that is being disconnected.
|
||||||
|
*
|
||||||
|
* @param[in] joystick The joystick whose pointer to return.
|
||||||
|
*
|
||||||
|
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
|
||||||
|
*
|
||||||
|
* @thread_safety This function may be called from any thread. Access is not
|
||||||
|
* synchronized.
|
||||||
|
*
|
||||||
|
* @sa @ref joystick_userptr
|
||||||
|
* @sa @ref glfwSetJoystickUserPointer
|
||||||
|
*
|
||||||
|
* @since Added in version 3.3.
|
||||||
|
*
|
||||||
|
* @ingroup input
|
||||||
|
*/
|
||||||
|
GLFWAPI void* glfwGetJoystickUserPointer(int jid);
|
||||||
|
|
||||||
/*! @brief Returns whether the specified joystick has a gamepad mapping.
|
/*! @brief Returns whether the specified joystick has a gamepad mapping.
|
||||||
*
|
*
|
||||||
* This function returns whether the specified joystick is both present and has
|
* This function returns whether the specified joystick is both present and has
|
||||||
|
|||||||
26
glfw/init.c
vendored
26
glfw/init.c
vendored
@@ -53,10 +53,6 @@ static _GLFWinitconfig _glfwInitHints =
|
|||||||
{
|
{
|
||||||
GLFW_TRUE, // macOS menu bar
|
GLFW_TRUE, // macOS menu bar
|
||||||
GLFW_TRUE // macOS bundle chdir
|
GLFW_TRUE // macOS bundle chdir
|
||||||
},
|
|
||||||
{
|
|
||||||
"", // X11 WM_CLASS name
|
|
||||||
"" // X11 WM_CLASS class
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -260,27 +256,7 @@ GLFWAPI void glfwInitHint(int hint, int value)
|
|||||||
}
|
}
|
||||||
|
|
||||||
_glfwInputError(GLFW_INVALID_ENUM,
|
_glfwInputError(GLFW_INVALID_ENUM,
|
||||||
"Invalid integer type init hint 0x%08X", hint);
|
"Invalid init hint 0x%08X", hint);
|
||||||
}
|
|
||||||
|
|
||||||
GLFWAPI void glfwInitHintString(int hint, const char* value)
|
|
||||||
{
|
|
||||||
assert(value != NULL);
|
|
||||||
|
|
||||||
switch (hint)
|
|
||||||
{
|
|
||||||
case GLFW_X11_WM_CLASS_NAME:
|
|
||||||
strncpy(_glfwInitHints.x11.className, value,
|
|
||||||
sizeof(_glfwInitHints.x11.className) - 1);
|
|
||||||
return;
|
|
||||||
case GLFW_X11_WM_CLASS_CLASS:
|
|
||||||
strncpy(_glfwInitHints.x11.classClass, value,
|
|
||||||
sizeof(_glfwInitHints.x11.classClass) - 1);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_glfwInputError(GLFW_INVALID_ENUM,
|
|
||||||
"Invalid string type init hint 0x%08X", hint);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GLFWAPI void glfwGetVersion(int* major, int* minor, int* rev)
|
GLFWAPI void glfwGetVersion(int* major, int* minor, int* rev)
|
||||||
|
|||||||
109
glfw/input.c
vendored
109
glfw/input.c
vendored
@@ -57,6 +57,58 @@ static _GLFWmapping* findMapping(const char* guid)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Checks whether a gamepad mapping element is present in the hardware
|
||||||
|
//
|
||||||
|
static GLFWbool isValidElementForJoystick(const _GLFWmapelement* e,
|
||||||
|
const _GLFWjoystick* js)
|
||||||
|
{
|
||||||
|
if (e->type == _GLFW_JOYSTICK_HATBIT && (e->value >> 4) >= js->hatCount)
|
||||||
|
return GLFW_FALSE;
|
||||||
|
else if (e->type == _GLFW_JOYSTICK_BUTTON && e->value >= js->buttonCount)
|
||||||
|
return GLFW_FALSE;
|
||||||
|
else if (e->type == _GLFW_JOYSTICK_AXIS && e->value >= js->axisCount)
|
||||||
|
return GLFW_FALSE;
|
||||||
|
|
||||||
|
return GLFW_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Finds a mapping based on joystick GUID and verifies element indices
|
||||||
|
//
|
||||||
|
static _GLFWmapping* findValidMapping(const _GLFWjoystick* js)
|
||||||
|
{
|
||||||
|
_GLFWmapping* mapping = findMapping(js->guid);
|
||||||
|
if (mapping)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i <= GLFW_GAMEPAD_BUTTON_LAST; i++)
|
||||||
|
{
|
||||||
|
if (!isValidElementForJoystick(mapping->buttons + i, js))
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_INVALID_VALUE,
|
||||||
|
"Invalid button in gamepad mapping %s (%s)",
|
||||||
|
mapping->guid,
|
||||||
|
mapping->name);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i <= GLFW_GAMEPAD_AXIS_LAST; i++)
|
||||||
|
{
|
||||||
|
if (!isValidElementForJoystick(mapping->axes + i, js))
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_INVALID_VALUE,
|
||||||
|
"Invalid axis in gamepad mapping %s (%s)",
|
||||||
|
mapping->guid,
|
||||||
|
mapping->name);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return mapping;
|
||||||
|
}
|
||||||
|
|
||||||
// Parses an SDL_GameControllerDB line and adds it to the mapping list
|
// Parses an SDL_GameControllerDB line and adds it to the mapping list
|
||||||
//
|
//
|
||||||
static GLFWbool parseMapping(_GLFWmapping* mapping, const char* string)
|
static GLFWbool parseMapping(_GLFWmapping* mapping, const char* string)
|
||||||
@@ -193,6 +245,9 @@ void _glfwInputKey(_GLFWwindow* window, int key, int scancode, int action, int m
|
|||||||
action = GLFW_REPEAT;
|
action = GLFW_REPEAT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!window->lockKeyMods)
|
||||||
|
mods &= ~(GLFW_MOD_CAPS_LOCK | GLFW_MOD_NUM_LOCK);
|
||||||
|
|
||||||
if (window->callbacks.key)
|
if (window->callbacks.key)
|
||||||
window->callbacks.key((GLFWwindow*) window, key, scancode, action, mods);
|
window->callbacks.key((GLFWwindow*) window, key, scancode, action, mods);
|
||||||
}
|
}
|
||||||
@@ -202,6 +257,9 @@ void _glfwInputChar(_GLFWwindow* window, unsigned int codepoint, int mods, GLFWb
|
|||||||
if (codepoint < 32 || (codepoint > 126 && codepoint < 160))
|
if (codepoint < 32 || (codepoint > 126 && codepoint < 160))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (!window->lockKeyMods)
|
||||||
|
mods &= ~(GLFW_MOD_CAPS_LOCK | GLFW_MOD_NUM_LOCK);
|
||||||
|
|
||||||
if (window->callbacks.charmods)
|
if (window->callbacks.charmods)
|
||||||
window->callbacks.charmods((GLFWwindow*) window, codepoint, mods);
|
window->callbacks.charmods((GLFWwindow*) window, codepoint, mods);
|
||||||
|
|
||||||
@@ -223,6 +281,9 @@ void _glfwInputMouseClick(_GLFWwindow* window, int button, int action, int mods)
|
|||||||
if (button < 0 || button > GLFW_MOUSE_BUTTON_LAST)
|
if (button < 0 || button > GLFW_MOUSE_BUTTON_LAST)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (!window->lockKeyMods)
|
||||||
|
mods &= ~(GLFW_MOD_CAPS_LOCK | GLFW_MOD_NUM_LOCK);
|
||||||
|
|
||||||
if (action == GLFW_RELEASE && window->stickyMouseButtons)
|
if (action == GLFW_RELEASE && window->stickyMouseButtons)
|
||||||
window->mouseButtons[button] = _GLFW_STICK;
|
window->mouseButtons[button] = _GLFW_STICK;
|
||||||
else
|
else
|
||||||
@@ -318,9 +379,9 @@ _GLFWjoystick* _glfwAllocJoystick(const char* name,
|
|||||||
js->axisCount = axisCount;
|
js->axisCount = axisCount;
|
||||||
js->buttonCount = buttonCount;
|
js->buttonCount = buttonCount;
|
||||||
js->hatCount = hatCount;
|
js->hatCount = hatCount;
|
||||||
js->mapping = findMapping(guid);
|
|
||||||
|
|
||||||
strcpy(js->guid, guid);
|
strcpy(js->guid, guid);
|
||||||
|
js->mapping = findValidMapping(js);
|
||||||
|
|
||||||
return js;
|
return js;
|
||||||
}
|
}
|
||||||
@@ -354,6 +415,8 @@ GLFWAPI int glfwGetInputMode(GLFWwindow* handle, int mode)
|
|||||||
return window->stickyKeys;
|
return window->stickyKeys;
|
||||||
case GLFW_STICKY_MOUSE_BUTTONS:
|
case GLFW_STICKY_MOUSE_BUTTONS:
|
||||||
return window->stickyMouseButtons;
|
return window->stickyMouseButtons;
|
||||||
|
case GLFW_LOCK_KEY_MODS:
|
||||||
|
return window->lockKeyMods;
|
||||||
}
|
}
|
||||||
|
|
||||||
_glfwInputError(GLFW_INVALID_ENUM, "Invalid input mode 0x%08X", mode);
|
_glfwInputError(GLFW_INVALID_ENUM, "Invalid input mode 0x%08X", mode);
|
||||||
@@ -409,7 +472,7 @@ GLFWAPI void glfwSetInputMode(GLFWwindow* handle, int mode, int value)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
window->stickyKeys = value ? GLFW_TRUE : GLFW_FALSE;
|
window->stickyKeys = value;
|
||||||
}
|
}
|
||||||
else if (mode == GLFW_STICKY_MOUSE_BUTTONS)
|
else if (mode == GLFW_STICKY_MOUSE_BUTTONS)
|
||||||
{
|
{
|
||||||
@@ -429,8 +492,10 @@ GLFWAPI void glfwSetInputMode(GLFWwindow* handle, int mode, int value)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
window->stickyMouseButtons = value ? GLFW_TRUE : GLFW_FALSE;
|
window->stickyMouseButtons = value;
|
||||||
}
|
}
|
||||||
|
else if (mode == GLFW_LOCK_KEY_MODS)
|
||||||
|
window->lockKeyMods = value ? GLFW_TRUE : GLFW_FALSE;
|
||||||
else
|
else
|
||||||
_glfwInputError(GLFW_INVALID_ENUM, "Invalid input mode 0x%08X", mode);
|
_glfwInputError(GLFW_INVALID_ENUM, "Invalid input mode 0x%08X", mode);
|
||||||
}
|
}
|
||||||
@@ -914,6 +979,38 @@ GLFWAPI const char* glfwGetJoystickGUID(int jid)
|
|||||||
return js->guid;
|
return js->guid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GLFWAPI void glfwSetJoystickUserPointer(int jid, void* pointer)
|
||||||
|
{
|
||||||
|
_GLFWjoystick* js;
|
||||||
|
|
||||||
|
assert(jid >= GLFW_JOYSTICK_1);
|
||||||
|
assert(jid <= GLFW_JOYSTICK_LAST);
|
||||||
|
|
||||||
|
_GLFW_REQUIRE_INIT();
|
||||||
|
|
||||||
|
js = _glfw.joysticks + jid;
|
||||||
|
if (!js->present)
|
||||||
|
return;
|
||||||
|
|
||||||
|
js->userPointer = pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLFWAPI void* glfwGetJoystickUserPointer(int jid)
|
||||||
|
{
|
||||||
|
_GLFWjoystick* js;
|
||||||
|
|
||||||
|
assert(jid >= GLFW_JOYSTICK_1);
|
||||||
|
assert(jid <= GLFW_JOYSTICK_LAST);
|
||||||
|
|
||||||
|
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||||
|
|
||||||
|
js = _glfw.joysticks + jid;
|
||||||
|
if (!js->present)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return js->userPointer;
|
||||||
|
}
|
||||||
|
|
||||||
GLFWAPI GLFWjoystickfun glfwSetJoystickCallback(GLFWjoystickfun cbfun)
|
GLFWAPI GLFWjoystickfun glfwSetJoystickCallback(GLFWjoystickfun cbfun)
|
||||||
{
|
{
|
||||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||||
@@ -973,7 +1070,7 @@ GLFWAPI int glfwUpdateGamepadMappings(const char* string)
|
|||||||
{
|
{
|
||||||
_GLFWjoystick* js = _glfw.joysticks + jid;
|
_GLFWjoystick* js = _glfw.joysticks + jid;
|
||||||
if (js->present)
|
if (js->present)
|
||||||
js->mapping = findMapping(js->guid);
|
js->mapping = findValidMapping(js);
|
||||||
}
|
}
|
||||||
|
|
||||||
return GLFW_TRUE;
|
return GLFW_TRUE;
|
||||||
@@ -1085,8 +1182,8 @@ GLFWAPI int glfwGetGamepadState(int jid, GLFWgamepadstate* state)
|
|||||||
state->axes[i] = js->axes[js->mapping->axes[i].value];
|
state->axes[i] = js->axes[js->mapping->axes[i].value];
|
||||||
else if (js->mapping->buttons[i].type == _GLFW_JOYSTICK_HATBIT)
|
else if (js->mapping->buttons[i].type == _GLFW_JOYSTICK_HATBIT)
|
||||||
{
|
{
|
||||||
const unsigned int hat = js->mapping->buttons[i].value >> 4;
|
const unsigned int hat = js->mapping->axes[i].value >> 4;
|
||||||
const unsigned int bit = js->mapping->buttons[i].value & 0xf;
|
const unsigned int bit = js->mapping->axes[i].value & 0xf;
|
||||||
if (js->hats[hat] & bit)
|
if (js->hats[hat] & bit)
|
||||||
state->axes[i] = 1.f;
|
state->axes[i] = 1.f;
|
||||||
}
|
}
|
||||||
|
|||||||
13
glfw/internal.h
vendored
13
glfw/internal.h
vendored
@@ -281,10 +281,6 @@ struct _GLFWinitconfig
|
|||||||
GLFWbool menubar;
|
GLFWbool menubar;
|
||||||
GLFWbool chdir;
|
GLFWbool chdir;
|
||||||
} ns;
|
} ns;
|
||||||
struct {
|
|
||||||
char className[256];
|
|
||||||
char classClass[256];
|
|
||||||
} x11;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*! @brief Window configuration.
|
/*! @brief Window configuration.
|
||||||
@@ -308,8 +304,12 @@ struct _GLFWwndconfig
|
|||||||
GLFWbool centerCursor;
|
GLFWbool centerCursor;
|
||||||
struct {
|
struct {
|
||||||
GLFWbool retina;
|
GLFWbool retina;
|
||||||
GLFWbool frame;
|
char frameName[256];
|
||||||
} ns;
|
} ns;
|
||||||
|
struct {
|
||||||
|
char className[256];
|
||||||
|
char instanceName[256];
|
||||||
|
} x11;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*! @brief Context configuration.
|
/*! @brief Context configuration.
|
||||||
@@ -419,6 +419,7 @@ struct _GLFWwindow
|
|||||||
|
|
||||||
GLFWbool stickyKeys;
|
GLFWbool stickyKeys;
|
||||||
GLFWbool stickyMouseButtons;
|
GLFWbool stickyMouseButtons;
|
||||||
|
GLFWbool lockKeyMods;
|
||||||
int cursorMode;
|
int cursorMode;
|
||||||
char mouseButtons[GLFW_MOUSE_BUTTON_LAST + 1];
|
char mouseButtons[GLFW_MOUSE_BUTTON_LAST + 1];
|
||||||
char keys[GLFW_KEY_LAST + 1];
|
char keys[GLFW_KEY_LAST + 1];
|
||||||
@@ -455,6 +456,7 @@ struct _GLFWwindow
|
|||||||
struct _GLFWmonitor
|
struct _GLFWmonitor
|
||||||
{
|
{
|
||||||
char* name;
|
char* name;
|
||||||
|
void* userPointer;
|
||||||
|
|
||||||
// Physical dimensions in millimeters.
|
// Physical dimensions in millimeters.
|
||||||
int widthMM, heightMM;
|
int widthMM, heightMM;
|
||||||
@@ -513,6 +515,7 @@ struct _GLFWjoystick
|
|||||||
unsigned char* hats;
|
unsigned char* hats;
|
||||||
int hatCount;
|
int hatCount;
|
||||||
char* name;
|
char* name;
|
||||||
|
void* userPointer;
|
||||||
char guid[33];
|
char guid[33];
|
||||||
_GLFWmapping* mapping;
|
_GLFWmapping* mapping;
|
||||||
|
|
||||||
|
|||||||
28
glfw/monitor.c
vendored
28
glfw/monitor.c
vendored
@@ -351,6 +351,24 @@ GLFWAPI const char* glfwGetMonitorName(GLFWmonitor* handle)
|
|||||||
return monitor->name;
|
return monitor->name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GLFWAPI void glfwSetMonitorUserPointer(GLFWmonitor* handle, void* pointer)
|
||||||
|
{
|
||||||
|
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
|
||||||
|
assert(monitor != NULL);
|
||||||
|
|
||||||
|
_GLFW_REQUIRE_INIT();
|
||||||
|
monitor->userPointer = pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLFWAPI void* glfwGetMonitorUserPointer(GLFWmonitor* handle)
|
||||||
|
{
|
||||||
|
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
|
||||||
|
assert(monitor != NULL);
|
||||||
|
|
||||||
|
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||||
|
return monitor->userPointer;
|
||||||
|
}
|
||||||
|
|
||||||
GLFWAPI GLFWmonitorfun glfwSetMonitorCallback(GLFWmonitorfun cbfun)
|
GLFWAPI GLFWmonitorfun glfwSetMonitorCallback(GLFWmonitorfun cbfun)
|
||||||
{
|
{
|
||||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||||
@@ -406,16 +424,16 @@ GLFWAPI void glfwSetGamma(GLFWmonitor* handle, float gamma)
|
|||||||
|
|
||||||
for (i = 0; i < 256; i++)
|
for (i = 0; i < 256; i++)
|
||||||
{
|
{
|
||||||
double value;
|
float value;
|
||||||
|
|
||||||
// Calculate intensity
|
// Calculate intensity
|
||||||
value = i / 255.0;
|
value = i / 255.f;
|
||||||
// Apply gamma curve
|
// Apply gamma curve
|
||||||
value = pow(value, 1.0 / gamma) * 65535.0 + 0.5;
|
value = powf(value, 1.f / gamma) * 65535.f + 0.5f;
|
||||||
|
|
||||||
// Clamp to value range
|
// Clamp to value range
|
||||||
if (value > 65535.0)
|
if (value > 65535.f)
|
||||||
value = 65535.0;
|
value = 65535.f;
|
||||||
|
|
||||||
values[i] = (unsigned short) value;
|
values[i] = (unsigned short) value;
|
||||||
}
|
}
|
||||||
|
|||||||
11
glfw/win32_platform.h
vendored
11
glfw/win32_platform.h
vendored
@@ -105,12 +105,11 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if WINVER < 0x0601
|
#if WINVER < 0x0601
|
||||||
typedef struct tagCHANGEFILTERSTRUCT
|
typedef struct
|
||||||
{
|
{
|
||||||
DWORD cbSize;
|
DWORD cbSize;
|
||||||
DWORD ExtStatus;
|
DWORD ExtStatus;
|
||||||
|
} CHANGEFILTERSTRUCT;
|
||||||
} CHANGEFILTERSTRUCT, *PCHANGEFILTERSTRUCT;
|
|
||||||
#ifndef MSGFLT_ALLOW
|
#ifndef MSGFLT_ALLOW
|
||||||
#define MSGFLT_ALLOW 1
|
#define MSGFLT_ALLOW 1
|
||||||
#endif
|
#endif
|
||||||
@@ -129,13 +128,13 @@ typedef struct
|
|||||||
#endif /*Windows Vista*/
|
#endif /*Windows Vista*/
|
||||||
|
|
||||||
#ifndef DPI_ENUMS_DECLARED
|
#ifndef DPI_ENUMS_DECLARED
|
||||||
typedef enum PROCESS_DPI_AWARENESS
|
typedef enum
|
||||||
{
|
{
|
||||||
PROCESS_DPI_UNAWARE = 0,
|
PROCESS_DPI_UNAWARE = 0,
|
||||||
PROCESS_SYSTEM_DPI_AWARE = 1,
|
PROCESS_SYSTEM_DPI_AWARE = 1,
|
||||||
PROCESS_PER_MONITOR_DPI_AWARE = 2
|
PROCESS_PER_MONITOR_DPI_AWARE = 2
|
||||||
} PROCESS_DPI_AWARENESS;
|
} PROCESS_DPI_AWARENESS;
|
||||||
typedef enum MONITOR_DPI_TYPE
|
typedef enum
|
||||||
{
|
{
|
||||||
MDT_EFFECTIVE_DPI = 0,
|
MDT_EFFECTIVE_DPI = 0,
|
||||||
MDT_ANGULAR_DPI = 1,
|
MDT_ANGULAR_DPI = 1,
|
||||||
@@ -209,7 +208,7 @@ typedef HRESULT (WINAPI * PFN_DirectInput8Create)(HINSTANCE,DWORD,REFIID,LPVOID*
|
|||||||
|
|
||||||
// user32.dll function pointer typedefs
|
// user32.dll function pointer typedefs
|
||||||
typedef BOOL (WINAPI * PFN_SetProcessDPIAware)(void);
|
typedef BOOL (WINAPI * PFN_SetProcessDPIAware)(void);
|
||||||
typedef BOOL (WINAPI * PFN_ChangeWindowMessageFilterEx)(HWND,UINT,DWORD,PCHANGEFILTERSTRUCT);
|
typedef BOOL (WINAPI * PFN_ChangeWindowMessageFilterEx)(HWND,UINT,DWORD,CHANGEFILTERSTRUCT*);
|
||||||
#define SetProcessDPIAware _glfw.win32.user32.SetProcessDPIAware_
|
#define SetProcessDPIAware _glfw.win32.user32.SetProcessDPIAware_
|
||||||
#define ChangeWindowMessageFilterEx _glfw.win32.user32.ChangeWindowMessageFilterEx_
|
#define ChangeWindowMessageFilterEx _glfw.win32.user32.ChangeWindowMessageFilterEx_
|
||||||
|
|
||||||
|
|||||||
24
glfw/win32_window.c
vendored
24
glfw/win32_window.c
vendored
@@ -384,14 +384,18 @@ static int getKeyMods(void)
|
|||||||
{
|
{
|
||||||
int mods = 0;
|
int mods = 0;
|
||||||
|
|
||||||
if (GetKeyState(VK_SHIFT) & (1 << 31))
|
if (GetKeyState(VK_SHIFT) & 0x8000)
|
||||||
mods |= GLFW_MOD_SHIFT;
|
mods |= GLFW_MOD_SHIFT;
|
||||||
if (GetKeyState(VK_CONTROL) & (1 << 31))
|
if (GetKeyState(VK_CONTROL) & 0x8000)
|
||||||
mods |= GLFW_MOD_CONTROL;
|
mods |= GLFW_MOD_CONTROL;
|
||||||
if (GetKeyState(VK_MENU) & (1 << 31))
|
if (GetKeyState(VK_MENU) & 0x8000)
|
||||||
mods |= GLFW_MOD_ALT;
|
mods |= GLFW_MOD_ALT;
|
||||||
if ((GetKeyState(VK_LWIN) | GetKeyState(VK_RWIN)) & (1 << 31))
|
if ((GetKeyState(VK_LWIN) | GetKeyState(VK_RWIN)) & 0x8000)
|
||||||
mods |= GLFW_MOD_SUPER;
|
mods |= GLFW_MOD_SUPER;
|
||||||
|
if (GetKeyState(VK_CAPITAL) & 1)
|
||||||
|
mods |= GLFW_MOD_CAPS_LOCK;
|
||||||
|
if (GetKeyState(VK_NUMLOCK) & 1)
|
||||||
|
mods |= GLFW_MOD_NUM_LOCK;
|
||||||
|
|
||||||
return mods;
|
return mods;
|
||||||
}
|
}
|
||||||
@@ -402,14 +406,18 @@ static int getAsyncKeyMods(void)
|
|||||||
{
|
{
|
||||||
int mods = 0;
|
int mods = 0;
|
||||||
|
|
||||||
if (GetAsyncKeyState(VK_SHIFT) & (1 << 31))
|
if (GetAsyncKeyState(VK_SHIFT) & 0x8000)
|
||||||
mods |= GLFW_MOD_SHIFT;
|
mods |= GLFW_MOD_SHIFT;
|
||||||
if (GetAsyncKeyState(VK_CONTROL) & (1 << 31))
|
if (GetAsyncKeyState(VK_CONTROL) & 0x8000)
|
||||||
mods |= GLFW_MOD_CONTROL;
|
mods |= GLFW_MOD_CONTROL;
|
||||||
if (GetAsyncKeyState(VK_MENU) & (1 << 31))
|
if (GetAsyncKeyState(VK_MENU) & 0x8000)
|
||||||
mods |= GLFW_MOD_ALT;
|
mods |= GLFW_MOD_ALT;
|
||||||
if ((GetAsyncKeyState(VK_LWIN) | GetAsyncKeyState(VK_RWIN)) & (1 << 31))
|
if ((GetAsyncKeyState(VK_LWIN) | GetAsyncKeyState(VK_RWIN)) & 0x8000)
|
||||||
mods |= GLFW_MOD_SUPER;
|
mods |= GLFW_MOD_SUPER;
|
||||||
|
if (GetAsyncKeyState(VK_CAPITAL) & 1)
|
||||||
|
mods |= GLFW_MOD_CAPS_LOCK;
|
||||||
|
if (GetAsyncKeyState(VK_NUMLOCK) & 1)
|
||||||
|
mods |= GLFW_MOD_NUM_LOCK;
|
||||||
|
|
||||||
return mods;
|
return mods;
|
||||||
}
|
}
|
||||||
|
|||||||
28
glfw/window.c
vendored
28
glfw/window.c
vendored
@@ -349,9 +349,6 @@ GLFWAPI void glfwWindowHint(int hint, int value)
|
|||||||
case GLFW_COCOA_RETINA_FRAMEBUFFER:
|
case GLFW_COCOA_RETINA_FRAMEBUFFER:
|
||||||
_glfw.hints.window.ns.retina = value ? GLFW_TRUE : GLFW_FALSE;
|
_glfw.hints.window.ns.retina = value ? GLFW_TRUE : GLFW_FALSE;
|
||||||
return;
|
return;
|
||||||
case GLFW_COCOA_FRAME_AUTOSAVE:
|
|
||||||
_glfw.hints.window.ns.frame = value ? GLFW_TRUE : GLFW_FALSE;
|
|
||||||
return;
|
|
||||||
case GLFW_COCOA_GRAPHICS_SWITCHING:
|
case GLFW_COCOA_GRAPHICS_SWITCHING:
|
||||||
_glfw.hints.context.nsgl.offline = value ? GLFW_TRUE : GLFW_FALSE;
|
_glfw.hints.context.nsgl.offline = value ? GLFW_TRUE : GLFW_FALSE;
|
||||||
return;
|
return;
|
||||||
@@ -396,6 +393,31 @@ GLFWAPI void glfwWindowHint(int hint, int value)
|
|||||||
_glfwInputError(GLFW_INVALID_ENUM, "Invalid window hint 0x%08X", hint);
|
_glfwInputError(GLFW_INVALID_ENUM, "Invalid window hint 0x%08X", hint);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GLFWAPI void glfwWindowHintString(int hint, const char* value)
|
||||||
|
{
|
||||||
|
assert(value != NULL);
|
||||||
|
|
||||||
|
_GLFW_REQUIRE_INIT();
|
||||||
|
|
||||||
|
switch (hint)
|
||||||
|
{
|
||||||
|
case GLFW_COCOA_FRAME_NAME:
|
||||||
|
strncpy(_glfw.hints.window.ns.frameName, value,
|
||||||
|
sizeof(_glfw.hints.window.ns.frameName) - 1);
|
||||||
|
return;
|
||||||
|
case GLFW_X11_CLASS_NAME:
|
||||||
|
strncpy(_glfw.hints.window.x11.className, value,
|
||||||
|
sizeof(_glfw.hints.window.x11.className) - 1);
|
||||||
|
return;
|
||||||
|
case GLFW_X11_INSTANCE_NAME:
|
||||||
|
strncpy(_glfw.hints.window.x11.instanceName, value,
|
||||||
|
sizeof(_glfw.hints.window.x11.instanceName) - 1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_glfwInputError(GLFW_INVALID_ENUM, "Invalid window hint string 0x%08X", hint);
|
||||||
|
}
|
||||||
|
|
||||||
GLFWAPI void glfwDestroyWindow(GLFWwindow* handle)
|
GLFWAPI void glfwDestroyWindow(GLFWwindow* handle)
|
||||||
{
|
{
|
||||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||||
|
|||||||
17
glfw/wl_init.c
vendored
17
glfw/wl_init.c
vendored
@@ -132,11 +132,14 @@ static void pointerHandleAxis(void* data,
|
|||||||
{
|
{
|
||||||
_GLFWwindow* window = _glfw.wl.pointerFocus;
|
_GLFWwindow* window = _glfw.wl.pointerFocus;
|
||||||
double scrollFactor;
|
double scrollFactor;
|
||||||
double x = 0.0, y = 0.0;
|
double x = 0, y = 0;
|
||||||
|
|
||||||
if (!window)
|
if (!window)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
assert(axis == WL_POINTER_AXIS_HORIZONTAL_SCROLL ||
|
||||||
|
axis == WL_POINTER_AXIS_VERTICAL_SCROLL);
|
||||||
|
|
||||||
/* Wayland scroll events are in pointer motion coordinate space (think
|
/* Wayland scroll events are in pointer motion coordinate space (think
|
||||||
* two finger scroll). The factor 10 is commonly used to convert to
|
* two finger scroll). The factor 10 is commonly used to convert to
|
||||||
* "scroll step means 1.0. */
|
* "scroll step means 1.0. */
|
||||||
@@ -152,9 +155,6 @@ static void pointerHandleAxis(void* data,
|
|||||||
x = 0.0;
|
x = 0.0;
|
||||||
y = wl_fixed_to_double(value) * scrollFactor;
|
y = wl_fixed_to_double(value) * scrollFactor;
|
||||||
break;
|
break;
|
||||||
default:
|
|
||||||
assert(GLFW_FALSE);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_glfwInputScroll(window, x, y);
|
_glfwInputScroll(window, x, y);
|
||||||
@@ -264,6 +264,10 @@ static void keyboardHandleKeymap(void* data,
|
|||||||
1 << xkb_keymap_mod_get_index(_glfw.wl.xkb.keymap, "Shift");
|
1 << xkb_keymap_mod_get_index(_glfw.wl.xkb.keymap, "Shift");
|
||||||
_glfw.wl.xkb.superMask =
|
_glfw.wl.xkb.superMask =
|
||||||
1 << xkb_keymap_mod_get_index(_glfw.wl.xkb.keymap, "Mod4");
|
1 << xkb_keymap_mod_get_index(_glfw.wl.xkb.keymap, "Mod4");
|
||||||
|
_glfw.wl.xkb.capsLockMask =
|
||||||
|
1 << xkb_keymap_mod_get_index(_glfw.wl.xkb.keymap, "Lock");
|
||||||
|
_glfw.wl.xkb.numLockMask =
|
||||||
|
1 << xkb_keymap_mod_get_index(_glfw.wl.xkb.keymap, "Mod2");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void keyboardHandleEnter(void* data,
|
static void keyboardHandleEnter(void* data,
|
||||||
@@ -409,6 +413,10 @@ static void keyboardHandleModifiers(void* data,
|
|||||||
modifiers |= GLFW_MOD_SHIFT;
|
modifiers |= GLFW_MOD_SHIFT;
|
||||||
if (mask & _glfw.wl.xkb.superMask)
|
if (mask & _glfw.wl.xkb.superMask)
|
||||||
modifiers |= GLFW_MOD_SUPER;
|
modifiers |= GLFW_MOD_SUPER;
|
||||||
|
if (mask & _glfw.wl.xkb.capsLockMask)
|
||||||
|
modifiers |= GLFW_MOD_CAPS_LOCK;
|
||||||
|
if (mask & _glfw.wl.xkb.numLockMask)
|
||||||
|
modifiers |= GLFW_MOD_NUM_LOCK;
|
||||||
_glfw.wl.xkb.modifiers = modifiers;
|
_glfw.wl.xkb.modifiers = modifiers;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -818,4 +826,3 @@ const char* _glfwPlatformGetVersionString(void)
|
|||||||
#endif
|
#endif
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
2
glfw/wl_platform.h
vendored
2
glfw/wl_platform.h
vendored
@@ -183,6 +183,8 @@ typedef struct _GLFWlibraryWayland
|
|||||||
xkb_mod_mask_t altMask;
|
xkb_mod_mask_t altMask;
|
||||||
xkb_mod_mask_t shiftMask;
|
xkb_mod_mask_t shiftMask;
|
||||||
xkb_mod_mask_t superMask;
|
xkb_mod_mask_t superMask;
|
||||||
|
xkb_mod_mask_t capsLockMask;
|
||||||
|
xkb_mod_mask_t numLockMask;
|
||||||
unsigned int modifiers;
|
unsigned int modifiers;
|
||||||
|
|
||||||
PFN_xkb_context_new context_new;
|
PFN_xkb_context_new context_new;
|
||||||
|
|||||||
54
glfw/x11_window.c
vendored
54
glfw/x11_window.c
vendored
@@ -212,6 +212,10 @@ static int translateState(int state)
|
|||||||
mods |= GLFW_MOD_ALT;
|
mods |= GLFW_MOD_ALT;
|
||||||
if (state & Mod4Mask)
|
if (state & Mod4Mask)
|
||||||
mods |= GLFW_MOD_SUPER;
|
mods |= GLFW_MOD_SUPER;
|
||||||
|
if (state & LockMask)
|
||||||
|
mods |= GLFW_MOD_CAPS_LOCK;
|
||||||
|
if (state & Mod2Mask)
|
||||||
|
mods |= GLFW_MOD_NUM_LOCK;
|
||||||
|
|
||||||
return mods;
|
return mods;
|
||||||
}
|
}
|
||||||
@@ -703,49 +707,34 @@ static GLFWbool createNativeWindow(_GLFWwindow* window,
|
|||||||
|
|
||||||
updateNormalHints(window, wndconfig->width, wndconfig->height);
|
updateNormalHints(window, wndconfig->width, wndconfig->height);
|
||||||
|
|
||||||
// Set ICCCM WM_CLASS property and window title
|
// Set ICCCM WM_CLASS property
|
||||||
{
|
{
|
||||||
XClassHint* hint = XAllocClassHint();
|
XClassHint* hint = XAllocClassHint();
|
||||||
char *wm_cclass = NULL, *wm_cname = NULL;
|
|
||||||
const char *real_title = wndconfig->title;
|
|
||||||
|
|
||||||
if (strlen(_glfw.hints.init.x11.className) &&
|
if (strlen(wndconfig->x11.instanceName) &&
|
||||||
strlen(_glfw.hints.init.x11.classClass))
|
strlen(wndconfig->x11.className))
|
||||||
{
|
{
|
||||||
hint->res_name = (char*) _glfw.hints.init.x11.className;
|
hint->res_name = (char*) wndconfig->x11.instanceName;
|
||||||
hint->res_class = (char*) _glfw.hints.init.x11.classClass;
|
hint->res_class = (char*) wndconfig->x11.className;
|
||||||
}
|
|
||||||
else if (strlen(real_title))
|
|
||||||
{
|
|
||||||
if (*real_title == 1) {
|
|
||||||
char *p = strchr(real_title, 30);
|
|
||||||
if (p && p > real_title + 1) {
|
|
||||||
wm_cname = calloc(p - real_title + 1, 1);
|
|
||||||
if (wm_cname) memcpy(wm_cname, real_title + 1, p - real_title - 1);
|
|
||||||
hint->res_name = wm_cname;
|
|
||||||
char *q = strchr(p + 1, 30);
|
|
||||||
if (q && q > p + 1) {
|
|
||||||
wm_cclass = calloc(q - p + 1, 1);
|
|
||||||
if (wm_cclass) memcpy(wm_cclass, p + 1, q - p - 1);
|
|
||||||
hint->res_class = wm_cclass;
|
|
||||||
real_title = q + 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
hint->res_name = (char*) real_title;
|
|
||||||
hint->res_class = (char*) real_title;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
hint->res_name = (char*) "glfw-application";
|
const char* resourceName = getenv("RESOURCE_NAME");
|
||||||
hint->res_class = (char*) "GLFW-Application";
|
if (resourceName && strlen(resourceName))
|
||||||
|
hint->res_name = (char*) resourceName;
|
||||||
|
else if (strlen(wndconfig->title))
|
||||||
|
hint->res_name = (char*) wndconfig->title;
|
||||||
|
else
|
||||||
|
hint->res_name = (char*) "glfw-application";
|
||||||
|
|
||||||
|
if (strlen(wndconfig->title))
|
||||||
|
hint->res_class = (char*) wndconfig->title;
|
||||||
|
else
|
||||||
|
hint->res_class = (char*) "GLFW-Application";
|
||||||
}
|
}
|
||||||
|
|
||||||
XSetClassHint(_glfw.x11.display, window->x11.handle, hint);
|
XSetClassHint(_glfw.x11.display, window->x11.handle, hint);
|
||||||
XFree(hint);
|
XFree(hint);
|
||||||
free(wm_cclass); free(wm_cname);
|
|
||||||
_glfwPlatformSetWindowTitle(window, real_title);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Announce support for Xdnd (drag and drop)
|
// Announce support for Xdnd (drag and drop)
|
||||||
@@ -756,6 +745,7 @@ static GLFWbool createNativeWindow(_GLFWwindow* window,
|
|||||||
PropModeReplace, (unsigned char*) &version, 1);
|
PropModeReplace, (unsigned char*) &version, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_glfwPlatformSetWindowTitle(window, wndconfig->title);
|
||||||
|
|
||||||
if (_glfw.x11.im)
|
if (_glfw.x11.im)
|
||||||
{
|
{
|
||||||
|
|||||||
103
kitty/boss.py
103
kitty/boss.py
@@ -7,21 +7,20 @@ from weakref import WeakValueDictionary
|
|||||||
|
|
||||||
from .cli import create_opts, parse_args
|
from .cli import create_opts, parse_args
|
||||||
from .config import MINIMUM_FONT_SIZE, cached_values, initial_window_size
|
from .config import MINIMUM_FONT_SIZE, cached_values, initial_window_size
|
||||||
from .constants import set_boss, wakeup
|
from .constants import appname, set_boss, wakeup
|
||||||
from .fast_data_types import (
|
from .fast_data_types import (
|
||||||
ChildMonitor, create_os_window, current_os_window, destroy_global_data,
|
ChildMonitor, create_os_window, current_os_window, destroy_global_data,
|
||||||
destroy_sprite_map, get_clipboard_string, glfw_post_empty_event,
|
destroy_sprite_map, get_clipboard_string, glfw_post_empty_event,
|
||||||
layout_sprite_map, mark_os_window_for_close, show_window,
|
layout_sprite_map, mark_os_window_for_close, set_dpi_from_os_window,
|
||||||
toggle_fullscreen, viewport_for_window
|
show_window, toggle_fullscreen, viewport_for_window
|
||||||
)
|
)
|
||||||
from .fonts.render import prerender, resize_fonts, set_font_family
|
from .fonts.render import prerender, resize_fonts, set_font_family
|
||||||
from .keys import get_shortcut
|
from .keys import get_shortcut
|
||||||
from .session import create_session
|
from .session import create_session
|
||||||
from .tabs import SpecialWindow, TabManager
|
from .tabs import SpecialWindow, TabManager
|
||||||
from .utils import (
|
from .utils import (
|
||||||
encode_wm_class, end_startup_notification, get_primary_selection,
|
end_startup_notification, get_primary_selection, init_startup_notification,
|
||||||
init_startup_notification, open_url, safe_print, set_primary_selection,
|
open_url, safe_print, set_primary_selection, single_instance
|
||||||
single_instance
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -79,18 +78,34 @@ class Boss:
|
|||||||
startup_session = create_session(opts, args)
|
startup_session = create_session(opts, args)
|
||||||
self.add_os_window(startup_session, os_window_id=os_window_id)
|
self.add_os_window(startup_session, os_window_id=os_window_id)
|
||||||
|
|
||||||
def add_os_window(self, startup_session, os_window_id=None, wclass=None, wname=None, size=None, visible=True):
|
def add_os_window(self, startup_session, os_window_id=None, wclass=None, wname=None, size=None, startup_id=None):
|
||||||
|
dpi_changed = False
|
||||||
if os_window_id is None:
|
if os_window_id is None:
|
||||||
w, h = initial_window_size(self.opts) if size is None else size
|
w, h = initial_window_size(self.opts) if size is None else size
|
||||||
os_window_id = create_os_window(w, h, encode_wm_class(wname or self.args.name, wclass or self.args.cls), visible)
|
cls = wclass or self.args.cls or appname
|
||||||
|
os_window_id = create_os_window(w, h, appname, wname or self.args.name or cls, cls)
|
||||||
|
if startup_id:
|
||||||
|
ctx = init_startup_notification(os_window_id, startup_id)
|
||||||
|
dpi_changed = show_window(os_window_id)
|
||||||
|
if startup_id:
|
||||||
|
end_startup_notification(ctx)
|
||||||
tm = TabManager(os_window_id, self.opts, self.args, startup_session)
|
tm = TabManager(os_window_id, self.opts, self.args, startup_session)
|
||||||
self.os_window_map[os_window_id] = tm
|
self.os_window_map[os_window_id] = tm
|
||||||
return os_window_id
|
if dpi_changed:
|
||||||
|
self.on_dpi_change(os_window_id)
|
||||||
|
|
||||||
|
def _new_os_window(self, args, cwd_from=None):
|
||||||
|
sw = self.args_to_special_window(args, cwd_from) if args else None
|
||||||
|
startup_session = create_session(self.opts, special_window=sw, cwd_from=cwd_from)
|
||||||
|
self.add_os_window(startup_session)
|
||||||
|
|
||||||
def new_os_window(self, *args):
|
def new_os_window(self, *args):
|
||||||
sw = self.args_to_special_window(args) if args else None
|
self._new_os_window(args)
|
||||||
startup_session = create_session(self.opts, special_window=sw)
|
|
||||||
return self.add_os_window(startup_session)
|
def new_os_window_with_cwd(self, *args):
|
||||||
|
w = self.active_window
|
||||||
|
cwd_from = w.child.pid if w is not None else None
|
||||||
|
self._new_os_window(args, cwd_from)
|
||||||
|
|
||||||
def add_child(self, window):
|
def add_child(self, window):
|
||||||
self.child_monitor.add_child(window.id, window.child.pid, window.child.child_fd, window.screen)
|
self.child_monitor.add_child(window.id, window.child.pid, window.child.child_fd, window.screen)
|
||||||
@@ -106,12 +121,7 @@ class Boss:
|
|||||||
args.args = rest
|
args.args = rest
|
||||||
opts = create_opts(args)
|
opts = create_opts(args)
|
||||||
session = create_session(opts, args)
|
session = create_session(opts, args)
|
||||||
os_window_id = self.add_os_window(session, wclass=args.cls, wname=args.name, size=initial_window_size(opts), visible=False)
|
self.add_os_window(session, wclass=args.cls, wname=args.name, size=initial_window_size(opts), startup_id=startup_id)
|
||||||
if startup_id:
|
|
||||||
ctx = init_startup_notification(os_window_id, startup_id)
|
|
||||||
show_window(os_window_id)
|
|
||||||
if startup_id:
|
|
||||||
end_startup_notification(ctx)
|
|
||||||
else:
|
else:
|
||||||
safe_print('Unknown message received from peer, ignoring')
|
safe_print('Unknown message received from peer, ignoring')
|
||||||
|
|
||||||
@@ -162,10 +172,16 @@ class Boss:
|
|||||||
if tm is not None:
|
if tm is not None:
|
||||||
tm.activate_tab_at(x)
|
tm.activate_tab_at(x)
|
||||||
|
|
||||||
def on_window_resize(self, os_window_id, w, h):
|
def on_window_resize(self, os_window_id, w, h, dpi_changed):
|
||||||
tm = self.os_window_map.get(os_window_id)
|
tm = self.os_window_map.get(os_window_id)
|
||||||
if tm is not None:
|
if tm is not None:
|
||||||
tm.resize()
|
if dpi_changed:
|
||||||
|
if set_dpi_from_os_window(os_window_id):
|
||||||
|
self.on_dpi_change(os_window_id)
|
||||||
|
else:
|
||||||
|
tm.resize()
|
||||||
|
else:
|
||||||
|
tm.resize()
|
||||||
|
|
||||||
def increase_font_size(self):
|
def increase_font_size(self):
|
||||||
self.change_font_size(
|
self.change_font_size(
|
||||||
@@ -182,10 +198,9 @@ class Boss:
|
|||||||
def restore_font_size(self):
|
def restore_font_size(self):
|
||||||
self.change_font_size(self.opts.font_size)
|
self.change_font_size(self.opts.font_size)
|
||||||
|
|
||||||
def change_font_size(self, new_size):
|
def _change_font_size(self, new_size=None):
|
||||||
if new_size == self.current_font_size:
|
if new_size is not None:
|
||||||
return
|
self.current_font_size = new_size
|
||||||
self.current_font_size = new_size
|
|
||||||
old_cell_width, old_cell_height = viewport_for_window()[-2:]
|
old_cell_width, old_cell_height = viewport_for_window()[-2:]
|
||||||
windows = tuple(filter(None, self.window_id_map.values()))
|
windows = tuple(filter(None, self.window_id_map.values()))
|
||||||
resize_fonts(self.current_font_size)
|
resize_fonts(self.current_font_size)
|
||||||
@@ -199,6 +214,14 @@ class Boss:
|
|||||||
tm.refresh_sprite_positions()
|
tm.refresh_sprite_positions()
|
||||||
glfw_post_empty_event()
|
glfw_post_empty_event()
|
||||||
|
|
||||||
|
def change_font_size(self, new_size):
|
||||||
|
if new_size == self.current_font_size:
|
||||||
|
return
|
||||||
|
self._change_font_size(new_size)
|
||||||
|
|
||||||
|
def on_dpi_change(self, os_window_id):
|
||||||
|
self._change_font_size()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def active_tab_manager(self):
|
def active_tab_manager(self):
|
||||||
os_window_id = current_os_window()
|
os_window_id = current_os_window()
|
||||||
@@ -342,7 +365,7 @@ class Boss:
|
|||||||
if tm is not None:
|
if tm is not None:
|
||||||
tm.next_tab(-1)
|
tm.next_tab(-1)
|
||||||
|
|
||||||
def args_to_special_window(self, args):
|
def args_to_special_window(self, args, cwd_from=None):
|
||||||
args = list(args)
|
args = list(args)
|
||||||
stdin = None
|
stdin = None
|
||||||
w = self.active_window
|
w = self.active_window
|
||||||
@@ -368,23 +391,39 @@ class Boss:
|
|||||||
if not arg:
|
if not arg:
|
||||||
continue
|
continue
|
||||||
cmd.append(arg)
|
cmd.append(arg)
|
||||||
return SpecialWindow(cmd, stdin)
|
return SpecialWindow(cmd, stdin, cwd_from=cwd_from)
|
||||||
|
|
||||||
def new_tab(self, *args):
|
def _new_tab(self, args, cwd_from=None):
|
||||||
special_window = None
|
special_window = None
|
||||||
if args:
|
if args:
|
||||||
special_window = self.args_to_special_window(args)
|
special_window = self.args_to_special_window(args, cwd_from=cwd_from)
|
||||||
tm = self.active_tab_manager
|
tm = self.active_tab_manager
|
||||||
if tm is not None:
|
if tm is not None:
|
||||||
tm.new_tab(special_window=special_window)
|
tm.new_tab(special_window=special_window, cwd_from=cwd_from)
|
||||||
|
|
||||||
def new_window(self, *args):
|
def new_tab(self, *args):
|
||||||
|
self._new_tab(args)
|
||||||
|
|
||||||
|
def new_tab_with_cwd(self, *args):
|
||||||
|
w = self.active_window
|
||||||
|
cwd_from = w.child.pid if w is not None else None
|
||||||
|
self._new_tab(args, cwd_from=cwd_from)
|
||||||
|
|
||||||
|
def _new_window(self, args, cwd_from=None):
|
||||||
tab = self.active_tab
|
tab = self.active_tab
|
||||||
if tab is not None:
|
if tab is not None:
|
||||||
if args:
|
if args:
|
||||||
tab.new_special_window(self.args_to_special_window(args))
|
tab.new_special_window(self.args_to_special_window(args, cwd_from=cwd_from))
|
||||||
else:
|
else:
|
||||||
tab.new_window()
|
tab.new_window(cwd_from=cwd_from)
|
||||||
|
|
||||||
|
def new_window(self, *args):
|
||||||
|
self._new_window(args)
|
||||||
|
|
||||||
|
def new_window_with_cwd(self, *args):
|
||||||
|
w = self.active_window
|
||||||
|
cwd_from = w.child.pid if w is not None else None
|
||||||
|
self._new_window(args, cwd_from=cwd_from)
|
||||||
|
|
||||||
def move_tab_forward(self):
|
def move_tab_forward(self):
|
||||||
tm = self.active_tab_manager
|
tm = self.active_tab_manager
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ in float bg_alpha;
|
|||||||
|
|
||||||
#ifdef NEEDS_FOREGROUND
|
#ifdef NEEDS_FOREGROUND
|
||||||
uniform sampler2DArray sprites;
|
uniform sampler2DArray sprites;
|
||||||
|
uniform float inactive_text_alpha;
|
||||||
in vec3 sprite_pos;
|
in vec3 sprite_pos;
|
||||||
in vec3 underline_pos;
|
in vec3 underline_pos;
|
||||||
in vec3 strike_pos;
|
in vec3 strike_pos;
|
||||||
@@ -60,7 +61,7 @@ vec4 calculate_foreground() {
|
|||||||
// Since strike and text are the same color, we simply add the alpha values
|
// Since strike and text are the same color, we simply add the alpha values
|
||||||
float combined_alpha = min(text_alpha + strike_alpha, 1.0f);
|
float combined_alpha = min(text_alpha + strike_alpha, 1.0f);
|
||||||
// Underline color might be different, so alpha blend
|
// Underline color might be different, so alpha blend
|
||||||
return alpha_blend(decoration_fg, underline_alpha, fg, combined_alpha);
|
return alpha_blend(decoration_fg, underline_alpha * inactive_text_alpha, fg, combined_alpha * inactive_text_alpha);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -99,7 +100,7 @@ void main() {
|
|||||||
final_color = alpha_blend_premul(fg.rgb, fg.a, background * bg_alpha, bg_alpha);
|
final_color = alpha_blend_premul(fg.rgb, fg.a, background * bg_alpha, bg_alpha);
|
||||||
final_color = vec4(final_color.rgb / final_color.a, final_color.a);
|
final_color = vec4(final_color.rgb / final_color.a, final_color.a);
|
||||||
#else
|
#else
|
||||||
// since background alpha is 1.0, it is effectively premultipled
|
// since background alpha is 1.0, it is effectively pre-multiplied
|
||||||
final_color = vec4(premul_blend(fg.rgb, fg.a, background), 1.0f);
|
final_color = vec4(premul_blend(fg.rgb, fg.a, background), 1.0f);
|
||||||
final_color = vec4(final_color.rgb / final_color.a, final_color.a);
|
final_color = vec4(final_color.rgb / final_color.a, final_color.a);
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -517,7 +517,8 @@ collect_cursor_info(CursorRenderInfo *ans, Window *w, double now, OSWindow *os_w
|
|||||||
ColorProfile *cp = rd->screen->color_profile;
|
ColorProfile *cp = rd->screen->color_profile;
|
||||||
ans->shape = cursor->shape ? cursor->shape : OPT(cursor_shape);
|
ans->shape = cursor->shape ? cursor->shape : OPT(cursor_shape);
|
||||||
ans->color = colorprofile_to_color(cp, cp->overridden.cursor_color, cp->configured.cursor_color);
|
ans->color = colorprofile_to_color(cp, cp->overridden.cursor_color, cp->configured.cursor_color);
|
||||||
if (ans->shape == CURSOR_BLOCK) return;
|
ans->is_focused = os_window->is_focused;
|
||||||
|
if (ans->shape == CURSOR_BLOCK && ans->is_focused) return;
|
||||||
double left = rd->xstart + cursor->x * rd->dx;
|
double left = rd->xstart + cursor->x * rd->dx;
|
||||||
double top = rd->ystart - cursor->y * rd->dy;
|
double top = rd->ystart - cursor->y * rd->dy;
|
||||||
unsigned long mult = MAX(1, screen_current_char_width(rd->screen));
|
unsigned long mult = MAX(1, screen_current_char_width(rd->screen));
|
||||||
@@ -550,7 +551,7 @@ simple_render_screen(PyObject UNUSED *self, PyObject *args) {
|
|||||||
if (vao_idx == -1) vao_idx = create_cell_vao();
|
if (vao_idx == -1) vao_idx = create_cell_vao();
|
||||||
if (gvao_idx == -1) gvao_idx = create_graphics_vao();
|
if (gvao_idx == -1) gvao_idx = create_graphics_vao();
|
||||||
if (!PyArg_ParseTuple(args, "O!ffff", &Screen_Type, &screen, &xstart, &ystart, &dx, &dy)) return NULL;
|
if (!PyArg_ParseTuple(args, "O!ffff", &Screen_Type, &screen, &xstart, &ystart, &dx, &dy)) return NULL;
|
||||||
draw_cells(vao_idx, gvao_idx, xstart, ystart, dx, dy, screen, current_os_window());
|
draw_cells(vao_idx, gvao_idx, xstart, ystart, dx, dy, screen, current_os_window(), true);
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -576,8 +577,8 @@ render_os_window(OSWindow *os_window, double now, unsigned int *active_window_id
|
|||||||
collect_cursor_info(&WD.screen->cursor_render_info, w, now, os_window);
|
collect_cursor_info(&WD.screen->cursor_render_info, w, now, os_window);
|
||||||
update_window_title(w, os_window);
|
update_window_title(w, os_window);
|
||||||
} else WD.screen->cursor_render_info.is_visible = false;
|
} else WD.screen->cursor_render_info.is_visible = false;
|
||||||
draw_cells(WD.vao_idx, WD.gvao_idx, WD.xstart, WD.ystart, WD.dx, WD.dy, WD.screen, os_window);
|
draw_cells(WD.vao_idx, WD.gvao_idx, WD.xstart, WD.ystart, WD.dx, WD.dy, WD.screen, os_window, is_active_window);
|
||||||
if (is_active_window && WD.screen->cursor_render_info.is_visible && WD.screen->cursor_render_info.shape != CURSOR_BLOCK) {
|
if (is_active_window && WD.screen->cursor_render_info.is_visible && (!WD.screen->cursor_render_info.is_focused || WD.screen->cursor_render_info.shape != CURSOR_BLOCK)) {
|
||||||
draw_cursor(&WD.screen->cursor_render_info, os_window->is_focused);
|
draw_cursor(&WD.screen->cursor_render_info, os_window->is_focused);
|
||||||
}
|
}
|
||||||
if (WD.screen->start_visual_bell_at != 0) {
|
if (WD.screen->start_visual_bell_at != 0) {
|
||||||
@@ -612,7 +613,7 @@ render(double now) {
|
|||||||
Tab *active_tab = w->tabs + w->active_tab;
|
Tab *active_tab = w->tabs + w->active_tab;
|
||||||
BorderRects *br = &active_tab->border_rects;
|
BorderRects *br = &active_tab->border_rects;
|
||||||
draw_borders(br->vao_idx, br->num_border_rects, br->rect_buf, br->is_dirty, w->viewport_width, w->viewport_height);
|
draw_borders(br->vao_idx, br->num_border_rects, br->rect_buf, br->is_dirty, w->viewport_width, w->viewport_height);
|
||||||
if (TD.screen && w->num_tabs > 1) draw_cells(TD.vao_idx, 0, TD.xstart, TD.ystart, TD.dx, TD.dy, TD.screen, w);
|
if (TD.screen && w->num_tabs > 1) draw_cells(TD.vao_idx, 0, TD.xstart, TD.ystart, TD.dx, TD.dy, TD.screen, w, true);
|
||||||
swap_window_buffers(w);
|
swap_window_buffers(w);
|
||||||
w->last_active_tab = w->active_tab; w->last_num_tabs = w->num_tabs; w->last_active_window_id = active_window_id;
|
w->last_active_tab = w->active_tab; w->last_num_tabs = w->num_tabs; w->last_active_window_id = active_window_id;
|
||||||
br->is_dirty = false;
|
br->is_dirty = false;
|
||||||
@@ -1029,4 +1030,3 @@ init_child_monitor(PyObject *module) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// }}}
|
// }}}
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,16 @@ import sys
|
|||||||
|
|
||||||
import kitty.fast_data_types as fast_data_types
|
import kitty.fast_data_types as fast_data_types
|
||||||
|
|
||||||
from .constants import terminfo_dir
|
from .constants import terminfo_dir, is_macos
|
||||||
|
|
||||||
|
|
||||||
|
def cwd_of_process(pid):
|
||||||
|
if is_macos:
|
||||||
|
from kitty.fast_data_types import cwd_of_process
|
||||||
|
ans = cwd_of_process(pid)
|
||||||
|
else:
|
||||||
|
ans = '/proc/{}/cwd'.format(pid)
|
||||||
|
return os.path.realpath(ans)
|
||||||
|
|
||||||
|
|
||||||
def remove_cloexec(fd):
|
def remove_cloexec(fd):
|
||||||
@@ -20,9 +29,17 @@ class Child:
|
|||||||
child_fd = pid = None
|
child_fd = pid = None
|
||||||
forked = False
|
forked = False
|
||||||
|
|
||||||
def __init__(self, argv, cwd, opts, stdin=None, env=None):
|
def __init__(self, argv, cwd, opts, stdin=None, env=None, cwd_from=None):
|
||||||
self.argv = argv
|
self.argv = argv
|
||||||
self.cwd = os.path.abspath(os.path.expandvars(os.path.expanduser(cwd or os.getcwd())))
|
if cwd_from is not None:
|
||||||
|
try:
|
||||||
|
cwd = cwd_of_process(cwd_from)
|
||||||
|
except Exception:
|
||||||
|
import traceback
|
||||||
|
traceback.print_exc()
|
||||||
|
else:
|
||||||
|
cwd = os.path.expandvars(os.path.expanduser(cwd or os.getcwd()))
|
||||||
|
self.cwd = os.path.abspath(cwd)
|
||||||
self.opts = opts
|
self.opts = opts
|
||||||
self.stdin = stdin
|
self.stdin = stdin
|
||||||
self.env = env or {}
|
self.env = env or {}
|
||||||
|
|||||||
@@ -12,6 +12,8 @@
|
|||||||
#include <AvailabilityMacros.h>
|
#include <AvailabilityMacros.h>
|
||||||
// Needed for _NSGetProgname
|
// Needed for _NSGetProgname
|
||||||
#include <crt_externs.h>
|
#include <crt_externs.h>
|
||||||
|
typedef void* rusage_info_t; // needed for libproc.h
|
||||||
|
#include <libproc.h>
|
||||||
|
|
||||||
#if (MAC_OS_X_VERSION_MAX_ALLOWED < 101200)
|
#if (MAC_OS_X_VERSION_MAX_ALLOWED < 101200)
|
||||||
#define NSWindowStyleMaskResizable NSResizableWindowMask
|
#define NSWindowStyleMaskResizable NSResizableWindowMask
|
||||||
@@ -166,8 +168,19 @@ cocoa_get_lang(PyObject UNUSED *self) {
|
|||||||
return Py_BuildValue("s", [locale UTF8String]);
|
return Py_BuildValue("s", [locale UTF8String]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PyObject*
|
||||||
|
cwd_of_process(PyObject *self UNUSED, PyObject *pid_) {
|
||||||
|
long pid = PyLong_AsLong(pid_);
|
||||||
|
struct proc_vnodepathinfo vpi;
|
||||||
|
int ret = proc_pidinfo(pid, PROC_PIDVNODEPATHINFO, 0, &vpi, sizeof(vpi));
|
||||||
|
if (ret < 0) { PyErr_SetFromErrno(PyExc_OSError); return NULL; }
|
||||||
|
return PyUnicode_FromString(vpi.pvi_cdir.vip_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static PyMethodDef module_methods[] = {
|
static PyMethodDef module_methods[] = {
|
||||||
{"cocoa_get_lang", (PyCFunction)cocoa_get_lang, METH_NOARGS, ""},
|
{"cocoa_get_lang", (PyCFunction)cocoa_get_lang, METH_NOARGS, ""},
|
||||||
|
{"cwd_of_process", (PyCFunction)cwd_of_process, METH_O, ""},
|
||||||
{NULL, NULL, 0, NULL} /* Sentinel */
|
{NULL, NULL, 0, NULL} /* Sentinel */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ def parse_shortcut(sc):
|
|||||||
|
|
||||||
|
|
||||||
KeyAction = namedtuple('KeyAction', 'func args')
|
KeyAction = namedtuple('KeyAction', 'func args')
|
||||||
shlex_actions = {'pass_selection_to_program', 'new_window', 'new_tab'}
|
shlex_actions = {'pass_selection_to_program', 'new_window', 'new_tab', 'new_os_window', 'new_window_with_cwd', 'new_tab_with_cwd', 'new_os_window_with_cwd'}
|
||||||
|
|
||||||
|
|
||||||
def parse_key_action(action):
|
def parse_key_action(action):
|
||||||
@@ -195,7 +195,7 @@ def parse_send_text(val, keymap):
|
|||||||
return parse_key(key_str, keymap)
|
return parse_key(key_str, keymap)
|
||||||
|
|
||||||
|
|
||||||
def to_open_url_modifiers(val):
|
def to_modifiers(val):
|
||||||
return parse_mods(val.split('+'))
|
return parse_mods(val.split('+'))
|
||||||
|
|
||||||
|
|
||||||
@@ -264,7 +264,8 @@ type_map = {
|
|||||||
'font_size_delta': positive_float,
|
'font_size_delta': positive_float,
|
||||||
'focus_follows_mouse': to_bool,
|
'focus_follows_mouse': to_bool,
|
||||||
'cursor_shape': to_cursor_shape,
|
'cursor_shape': to_cursor_shape,
|
||||||
'open_url_modifiers': to_open_url_modifiers,
|
'open_url_modifiers': to_modifiers,
|
||||||
|
'rectangle_select_modifiers': to_modifiers,
|
||||||
'repaint_delay': positive_int,
|
'repaint_delay': positive_int,
|
||||||
'input_delay': positive_int,
|
'input_delay': positive_int,
|
||||||
'window_border_width': positive_float,
|
'window_border_width': positive_float,
|
||||||
@@ -290,6 +291,7 @@ type_map = {
|
|||||||
'tab_separator': tab_separator,
|
'tab_separator': tab_separator,
|
||||||
'active_tab_font_style': tab_font_style,
|
'active_tab_font_style': tab_font_style,
|
||||||
'inactive_tab_font_style': tab_font_style,
|
'inactive_tab_font_style': tab_font_style,
|
||||||
|
'inactive_text_alpha': unit_float,
|
||||||
'url_style': url_style,
|
'url_style': url_style,
|
||||||
'prefer_color_emoji': to_bool,
|
'prefer_color_emoji': to_bool,
|
||||||
}
|
}
|
||||||
@@ -350,7 +352,9 @@ with open(
|
|||||||
defaults = parse_config(f.read().decode('utf-8').splitlines(), check_keys=False)
|
defaults = parse_config(f.read().decode('utf-8').splitlines(), check_keys=False)
|
||||||
Options = namedtuple('Defaults', ','.join(defaults.keys()))
|
Options = namedtuple('Defaults', ','.join(defaults.keys()))
|
||||||
defaults = Options(**defaults)
|
defaults = Options(**defaults)
|
||||||
actions = frozenset(a.func for a in defaults.keymap.values()) | frozenset({'combine', 'send_text', 'goto_tab'})
|
actions = frozenset(a.func for a in defaults.keymap.values()) | frozenset(
|
||||||
|
'combine send_text goto_tab new_tab_with_cwd new_window_with_cwd new_os_window_with_cwd'.split()
|
||||||
|
)
|
||||||
no_op_actions = frozenset({'noop', 'no-op', 'no_op'})
|
no_op_actions = frozenset({'noop', 'no-op', 'no_op'})
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ from collections import namedtuple
|
|||||||
from .fast_data_types import set_boss as set_c_boss
|
from .fast_data_types import set_boss as set_c_boss
|
||||||
|
|
||||||
appname = 'kitty'
|
appname = 'kitty'
|
||||||
version = (0, 6, 0)
|
version = (0, 6, 1)
|
||||||
str_version = '.'.join(map(str, version))
|
str_version = '.'.join(map(str, version))
|
||||||
_plat = sys.platform.lower()
|
_plat = sys.platform.lower()
|
||||||
is_macos = 'darwin' in _plat
|
is_macos = 'darwin' in _plat
|
||||||
@@ -22,9 +22,8 @@ WindowGeometry = namedtuple('WindowGeometry', 'left top right bottom xnum ynum')
|
|||||||
|
|
||||||
|
|
||||||
def _get_config_dir():
|
def _get_config_dir():
|
||||||
# This must be called before calling setApplicationName
|
|
||||||
if 'KITTY_CONFIG_DIRECTORY' in os.environ:
|
if 'KITTY_CONFIG_DIRECTORY' in os.environ:
|
||||||
return os.path.abspath(os.path.expanduser(os.environ['VISE_CONFIG_DIRECTORY']))
|
return os.path.abspath(os.path.expanduser(os.environ['KITTY_CONFIG_DIRECTORY']))
|
||||||
|
|
||||||
candidate = os.path.abspath(os.path.expanduser(os.environ.get('XDG_CONFIG_HOME') or ('~/Library/Preferences' if is_macos else '~/.config')))
|
candidate = os.path.abspath(os.path.expanduser(os.environ.get('XDG_CONFIG_HOME') or ('~/Library/Preferences' if is_macos else '~/.config')))
|
||||||
ans = os.path.join(candidate, appname)
|
ans = os.path.join(candidate, appname)
|
||||||
|
|||||||
@@ -181,7 +181,7 @@ typedef struct {
|
|||||||
} Cursor;
|
} Cursor;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
bool is_visible;
|
bool is_visible, is_focused;
|
||||||
CursorShape shape;
|
CursorShape shape;
|
||||||
unsigned int x, y;
|
unsigned int x, y;
|
||||||
double left, right, top, bottom;
|
double left, right, top, bottom;
|
||||||
|
|||||||
14
kitty/emoji.h
generated
14
kitty/emoji.h
generated
@@ -1,9 +1,17 @@
|
|||||||
|
// unicode data, built from the unicode standard on: 2017-12-20
|
||||||
|
// see gen-wcwidth.py
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "data-types.h"
|
#include "data-types.h"
|
||||||
|
|
||||||
START_ALLOW_CASE_RANGE
|
START_ALLOW_CASE_RANGE
|
||||||
static inline bool is_emoji(uint32_t code) {
|
|
||||||
|
static inline bool
|
||||||
|
is_emoji(char_type code) {
|
||||||
switch(code) {
|
switch(code) {
|
||||||
|
case 0x2194 ... 0x2199:
|
||||||
|
return true;
|
||||||
|
case 0x21a9 ... 0x21aa:
|
||||||
|
return true;
|
||||||
case 0x231a ... 0x231b:
|
case 0x231a ... 0x231b:
|
||||||
return true;
|
return true;
|
||||||
case 0x2328:
|
case 0x2328:
|
||||||
@@ -276,7 +284,8 @@ static inline bool is_emoji(uint32_t code) {
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
static inline bool is_emoji_modifier(uint32_t code) {
|
static inline bool
|
||||||
|
is_emoji_modifier(char_type code) {
|
||||||
switch(code) {
|
switch(code) {
|
||||||
case 0x1f3fb ... 0x1f3ff:
|
case 0x1f3fb ... 0x1f3ff:
|
||||||
return true;
|
return true;
|
||||||
@@ -284,4 +293,5 @@ static inline bool is_emoji_modifier(uint32_t code) {
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
END_ALLOW_CASE_RANGE
|
END_ALLOW_CASE_RANGE
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
|
* vim:fileencoding=utf-8
|
||||||
* fonts.c
|
* fonts.c
|
||||||
* Copyright (C) 2017 Kovid Goyal <kovid at kovidgoyal.net>
|
* Copyright (C) 2017 Kovid Goyal <kovid at kovidgoyal.net>
|
||||||
*
|
*
|
||||||
@@ -289,6 +290,8 @@ update_cell_metrics() {
|
|||||||
if (cell_height < 4) { PyErr_SetString(PyExc_ValueError, "line height too small after adjustment"); return NULL; }
|
if (cell_height < 4) { PyErr_SetString(PyExc_ValueError, "line height too small after adjustment"); return NULL; }
|
||||||
if (cell_height > 1000) { PyErr_SetString(PyExc_ValueError, "line height too large after adjustment"); return NULL; }
|
if (cell_height > 1000) { PyErr_SetString(PyExc_ValueError, "line height too large after adjustment"); return NULL; }
|
||||||
underline_position = MIN(cell_height - 1, underline_position);
|
underline_position = MIN(cell_height - 1, underline_position);
|
||||||
|
// ensure there is at least a couple of pixels available to render styled underlines
|
||||||
|
while (underline_position > baseline + 1 && cell_height - underline_position < 2) underline_position--;
|
||||||
if (line_height_adjustment > 1) {
|
if (line_height_adjustment > 1) {
|
||||||
baseline += MIN(cell_height - 1, (unsigned)line_height_adjustment / 2);
|
baseline += MIN(cell_height - 1, (unsigned)line_height_adjustment / 2);
|
||||||
underline_position += MIN(cell_height - 1, (unsigned)line_height_adjustment / 2);
|
underline_position += MIN(cell_height - 1, (unsigned)line_height_adjustment / 2);
|
||||||
@@ -329,20 +332,11 @@ has_cell_text(Font *self, Cell *cell) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static inline ssize_t
|
static inline ssize_t
|
||||||
fallback_font(Cell *cell) {
|
load_fallback_font(Cell *cell, bool bold, bool italic) {
|
||||||
bool bold = (cell->attrs >> BOLD_SHIFT) & 1;
|
|
||||||
bool italic = (cell->attrs >> ITALIC_SHIFT) & 1;
|
|
||||||
ssize_t f;
|
|
||||||
|
|
||||||
for (size_t i = 0, j = fonts.first_fallback_font_idx; i < fonts.fallback_fonts_count; i++, j++) {
|
|
||||||
Font *ff = fonts.fonts +j;
|
|
||||||
if (ff->bold == bold && ff->italic == italic && has_cell_text(ff, cell)) {
|
|
||||||
return j;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fonts.fallback_fonts_count > 100) { fprintf(stderr, "Too many fallback fonts\n"); return MISSING_FONT; }
|
if (fonts.fallback_fonts_count > 100) { fprintf(stderr, "Too many fallback fonts\n"); return MISSING_FONT; }
|
||||||
|
ssize_t f;
|
||||||
|
|
||||||
if (bold) f = fonts.italic_font_idx > 0 ? fonts.bi_font_idx : fonts.bold_font_idx;
|
if (bold) f = fonts.italic_font_idx > 0 ? fonts.bi_font_idx : fonts.bold_font_idx;
|
||||||
else f = italic ? fonts.italic_font_idx : fonts.medium_font_idx;
|
else f = italic ? fonts.italic_font_idx : fonts.medium_font_idx;
|
||||||
@@ -363,6 +357,31 @@ fallback_font(Cell *cell) {
|
|||||||
return ans;
|
return ans;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static inline ssize_t
|
||||||
|
fallback_font(Cell *cell) {
|
||||||
|
bool bold = (cell->attrs >> BOLD_SHIFT) & 1;
|
||||||
|
bool italic = (cell->attrs >> ITALIC_SHIFT) & 1;
|
||||||
|
|
||||||
|
// Load the emoji fallback font first as on Linux there are a bunch of
|
||||||
|
// non-color fonts that provide some emoji glyphs.
|
||||||
|
if (fonts.fallback_fonts_count < 1) {
|
||||||
|
Cell c = {0};
|
||||||
|
c.ch = 0x1f648; // 🙈
|
||||||
|
load_fallback_font(&c, false, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if one of the existing fallback fonts has this text
|
||||||
|
for (size_t i = 0, j = fonts.first_fallback_font_idx; i < fonts.fallback_fonts_count; i++, j++) {
|
||||||
|
Font *ff = fonts.fonts +j;
|
||||||
|
if (ff->bold == bold && ff->italic == italic && has_cell_text(ff, cell)) {
|
||||||
|
return j;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return load_fallback_font(cell, bold, italic);
|
||||||
|
}
|
||||||
|
|
||||||
static inline ssize_t
|
static inline ssize_t
|
||||||
in_symbol_maps(char_type ch) {
|
in_symbol_maps(char_type ch) {
|
||||||
for (size_t i = 0; i < fonts.symbol_maps_count; i++) {
|
for (size_t i = 0; i < fonts.symbol_maps_count; i++) {
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ def resize_fonts(new_sz):
|
|||||||
|
|
||||||
def add_line(buf, cell_width, position, thickness, cell_height):
|
def add_line(buf, cell_width, position, thickness, cell_height):
|
||||||
y = position - thickness // 2
|
y = position - thickness // 2
|
||||||
while thickness > 0 and y > -1 and y < cell_height - 1:
|
while thickness > 0 and y > -1 and y < cell_height:
|
||||||
thickness -= 1
|
thickness -= 1
|
||||||
ctypes.memset(ctypes.addressof(buf) + (cell_width * y), 255, cell_width)
|
ctypes.memset(ctypes.addressof(buf) + (cell_width * y), 255, cell_width)
|
||||||
y += 1
|
y += 1
|
||||||
|
|||||||
18
kitty/glfw-wrapper.c
generated
18
kitty/glfw-wrapper.c
generated
@@ -23,9 +23,6 @@ load_glfw(const char* path) {
|
|||||||
*(void **) (&glfwInitHint_impl) = dlsym(handle, "glfwInitHint");
|
*(void **) (&glfwInitHint_impl) = dlsym(handle, "glfwInitHint");
|
||||||
if (glfwInitHint_impl == NULL) fail("Failed to load glfw function glfwInitHint with error: %s", dlerror());
|
if (glfwInitHint_impl == NULL) fail("Failed to load glfw function glfwInitHint with error: %s", dlerror());
|
||||||
|
|
||||||
*(void **) (&glfwInitHintString_impl) = dlsym(handle, "glfwInitHintString");
|
|
||||||
if (glfwInitHintString_impl == NULL) fail("Failed to load glfw function glfwInitHintString with error: %s", dlerror());
|
|
||||||
|
|
||||||
*(void **) (&glfwGetVersion_impl) = dlsym(handle, "glfwGetVersion");
|
*(void **) (&glfwGetVersion_impl) = dlsym(handle, "glfwGetVersion");
|
||||||
if (glfwGetVersion_impl == NULL) fail("Failed to load glfw function glfwGetVersion with error: %s", dlerror());
|
if (glfwGetVersion_impl == NULL) fail("Failed to load glfw function glfwGetVersion with error: %s", dlerror());
|
||||||
|
|
||||||
@@ -56,6 +53,12 @@ load_glfw(const char* path) {
|
|||||||
*(void **) (&glfwGetMonitorName_impl) = dlsym(handle, "glfwGetMonitorName");
|
*(void **) (&glfwGetMonitorName_impl) = dlsym(handle, "glfwGetMonitorName");
|
||||||
if (glfwGetMonitorName_impl == NULL) fail("Failed to load glfw function glfwGetMonitorName with error: %s", dlerror());
|
if (glfwGetMonitorName_impl == NULL) fail("Failed to load glfw function glfwGetMonitorName with error: %s", dlerror());
|
||||||
|
|
||||||
|
*(void **) (&glfwSetMonitorUserPointer_impl) = dlsym(handle, "glfwSetMonitorUserPointer");
|
||||||
|
if (glfwSetMonitorUserPointer_impl == NULL) fail("Failed to load glfw function glfwSetMonitorUserPointer with error: %s", dlerror());
|
||||||
|
|
||||||
|
*(void **) (&glfwGetMonitorUserPointer_impl) = dlsym(handle, "glfwGetMonitorUserPointer");
|
||||||
|
if (glfwGetMonitorUserPointer_impl == NULL) fail("Failed to load glfw function glfwGetMonitorUserPointer with error: %s", dlerror());
|
||||||
|
|
||||||
*(void **) (&glfwSetMonitorCallback_impl) = dlsym(handle, "glfwSetMonitorCallback");
|
*(void **) (&glfwSetMonitorCallback_impl) = dlsym(handle, "glfwSetMonitorCallback");
|
||||||
if (glfwSetMonitorCallback_impl == NULL) fail("Failed to load glfw function glfwSetMonitorCallback with error: %s", dlerror());
|
if (glfwSetMonitorCallback_impl == NULL) fail("Failed to load glfw function glfwSetMonitorCallback with error: %s", dlerror());
|
||||||
|
|
||||||
@@ -80,6 +83,9 @@ load_glfw(const char* path) {
|
|||||||
*(void **) (&glfwWindowHint_impl) = dlsym(handle, "glfwWindowHint");
|
*(void **) (&glfwWindowHint_impl) = dlsym(handle, "glfwWindowHint");
|
||||||
if (glfwWindowHint_impl == NULL) fail("Failed to load glfw function glfwWindowHint with error: %s", dlerror());
|
if (glfwWindowHint_impl == NULL) fail("Failed to load glfw function glfwWindowHint with error: %s", dlerror());
|
||||||
|
|
||||||
|
*(void **) (&glfwWindowHintString_impl) = dlsym(handle, "glfwWindowHintString");
|
||||||
|
if (glfwWindowHintString_impl == NULL) fail("Failed to load glfw function glfwWindowHintString with error: %s", dlerror());
|
||||||
|
|
||||||
*(void **) (&glfwCreateWindow_impl) = dlsym(handle, "glfwCreateWindow");
|
*(void **) (&glfwCreateWindow_impl) = dlsym(handle, "glfwCreateWindow");
|
||||||
if (glfwCreateWindow_impl == NULL) fail("Failed to load glfw function glfwCreateWindow with error: %s", dlerror());
|
if (glfwCreateWindow_impl == NULL) fail("Failed to load glfw function glfwCreateWindow with error: %s", dlerror());
|
||||||
|
|
||||||
@@ -287,6 +293,12 @@ load_glfw(const char* path) {
|
|||||||
*(void **) (&glfwGetJoystickGUID_impl) = dlsym(handle, "glfwGetJoystickGUID");
|
*(void **) (&glfwGetJoystickGUID_impl) = dlsym(handle, "glfwGetJoystickGUID");
|
||||||
if (glfwGetJoystickGUID_impl == NULL) fail("Failed to load glfw function glfwGetJoystickGUID with error: %s", dlerror());
|
if (glfwGetJoystickGUID_impl == NULL) fail("Failed to load glfw function glfwGetJoystickGUID with error: %s", dlerror());
|
||||||
|
|
||||||
|
*(void **) (&glfwSetJoystickUserPointer_impl) = dlsym(handle, "glfwSetJoystickUserPointer");
|
||||||
|
if (glfwSetJoystickUserPointer_impl == NULL) fail("Failed to load glfw function glfwSetJoystickUserPointer with error: %s", dlerror());
|
||||||
|
|
||||||
|
*(void **) (&glfwGetJoystickUserPointer_impl) = dlsym(handle, "glfwGetJoystickUserPointer");
|
||||||
|
if (glfwGetJoystickUserPointer_impl == NULL) fail("Failed to load glfw function glfwGetJoystickUserPointer with error: %s", dlerror());
|
||||||
|
|
||||||
*(void **) (&glfwJoystickIsGamepad_impl) = dlsym(handle, "glfwJoystickIsGamepad");
|
*(void **) (&glfwJoystickIsGamepad_impl) = dlsym(handle, "glfwJoystickIsGamepad");
|
||||||
if (glfwJoystickIsGamepad_impl == NULL) fail("Failed to load glfw function glfwJoystickIsGamepad with error: %s", dlerror());
|
if (glfwJoystickIsGamepad_impl == NULL) fail("Failed to load glfw function glfwJoystickIsGamepad with error: %s", dlerror());
|
||||||
|
|
||||||
|
|||||||
55
kitty/glfw-wrapper.h
generated
55
kitty/glfw-wrapper.h
generated
@@ -251,17 +251,37 @@
|
|||||||
* @{ */
|
* @{ */
|
||||||
|
|
||||||
/*! @brief If this bit is set one or more Shift keys were held down.
|
/*! @brief If this bit is set one or more Shift keys were held down.
|
||||||
|
*
|
||||||
|
* If this bit is set one or more Shift keys were held down.
|
||||||
*/
|
*/
|
||||||
#define GLFW_MOD_SHIFT 0x0001
|
#define GLFW_MOD_SHIFT 0x0001
|
||||||
/*! @brief If this bit is set one or more Control keys were held down.
|
/*! @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
|
#define GLFW_MOD_CONTROL 0x0002
|
||||||
/*! @brief If this bit is set one or more Alt keys were held down.
|
/*! @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 0x0004
|
||||||
/*! @brief If this bit is set one or more Super keys were held down.
|
/*! @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
|
#define GLFW_MOD_SUPER 0x0008
|
||||||
|
/*! @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
|
||||||
|
/*! @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
|
||||||
|
|
||||||
/*! @} */
|
/*! @} */
|
||||||
|
|
||||||
@@ -702,8 +722,11 @@
|
|||||||
#define GLFW_CONTEXT_CREATION_API 0x0002200B
|
#define GLFW_CONTEXT_CREATION_API 0x0002200B
|
||||||
|
|
||||||
#define GLFW_COCOA_RETINA_FRAMEBUFFER 0x00023001
|
#define GLFW_COCOA_RETINA_FRAMEBUFFER 0x00023001
|
||||||
#define GLFW_COCOA_FRAME_AUTOSAVE 0x00023002
|
#define GLFW_COCOA_FRAME_NAME 0x00023002
|
||||||
#define GLFW_COCOA_GRAPHICS_SWITCHING 0x00023003
|
#define GLFW_COCOA_GRAPHICS_SWITCHING 0x00023003
|
||||||
|
|
||||||
|
#define GLFW_X11_CLASS_NAME 0x00024001
|
||||||
|
#define GLFW_X11_INSTANCE_NAME 0x00024002
|
||||||
/*! @} */
|
/*! @} */
|
||||||
|
|
||||||
#define GLFW_NO_API 0
|
#define GLFW_NO_API 0
|
||||||
@@ -721,6 +744,7 @@
|
|||||||
#define GLFW_CURSOR 0x00033001
|
#define GLFW_CURSOR 0x00033001
|
||||||
#define GLFW_STICKY_KEYS 0x00033002
|
#define GLFW_STICKY_KEYS 0x00033002
|
||||||
#define GLFW_STICKY_MOUSE_BUTTONS 0x00033003
|
#define GLFW_STICKY_MOUSE_BUTTONS 0x00033003
|
||||||
|
#define GLFW_LOCK_KEY_MODS 0x00033004
|
||||||
|
|
||||||
#define GLFW_CURSOR_NORMAL 0x00034001
|
#define GLFW_CURSOR_NORMAL 0x00034001
|
||||||
#define GLFW_CURSOR_HIDDEN 0x00034002
|
#define GLFW_CURSOR_HIDDEN 0x00034002
|
||||||
@@ -783,9 +807,6 @@
|
|||||||
|
|
||||||
#define GLFW_COCOA_CHDIR_RESOURCES 0x00051001
|
#define GLFW_COCOA_CHDIR_RESOURCES 0x00051001
|
||||||
#define GLFW_COCOA_MENUBAR 0x00051002
|
#define GLFW_COCOA_MENUBAR 0x00051002
|
||||||
|
|
||||||
#define GLFW_X11_WM_CLASS_NAME 0x00052001
|
|
||||||
#define GLFW_X11_WM_CLASS_CLASS 0x00052002
|
|
||||||
/*! @} */
|
/*! @} */
|
||||||
|
|
||||||
#define GLFW_DONT_CARE -1
|
#define GLFW_DONT_CARE -1
|
||||||
@@ -804,7 +825,7 @@
|
|||||||
* @sa @ref glfwGetProcAddress
|
* @sa @ref glfwGetProcAddress
|
||||||
*
|
*
|
||||||
* @since Added in version 3.0.
|
* @since Added in version 3.0.
|
||||||
|
*
|
||||||
* @ingroup context
|
* @ingroup context
|
||||||
*/
|
*/
|
||||||
typedef void (*GLFWglproc)(void);
|
typedef void (*GLFWglproc)(void);
|
||||||
@@ -1359,10 +1380,6 @@ typedef void (*glfwInitHint_func)(int, int);
|
|||||||
glfwInitHint_func glfwInitHint_impl;
|
glfwInitHint_func glfwInitHint_impl;
|
||||||
#define glfwInitHint glfwInitHint_impl
|
#define glfwInitHint glfwInitHint_impl
|
||||||
|
|
||||||
typedef void (*glfwInitHintString_func)(int, const char*);
|
|
||||||
glfwInitHintString_func glfwInitHintString_impl;
|
|
||||||
#define glfwInitHintString glfwInitHintString_impl
|
|
||||||
|
|
||||||
typedef void (*glfwGetVersion_func)(int*, int*, int*);
|
typedef void (*glfwGetVersion_func)(int*, int*, int*);
|
||||||
glfwGetVersion_func glfwGetVersion_impl;
|
glfwGetVersion_func glfwGetVersion_impl;
|
||||||
#define glfwGetVersion glfwGetVersion_impl
|
#define glfwGetVersion glfwGetVersion_impl
|
||||||
@@ -1403,6 +1420,14 @@ typedef const char* (*glfwGetMonitorName_func)(GLFWmonitor*);
|
|||||||
glfwGetMonitorName_func glfwGetMonitorName_impl;
|
glfwGetMonitorName_func glfwGetMonitorName_impl;
|
||||||
#define glfwGetMonitorName glfwGetMonitorName_impl
|
#define glfwGetMonitorName glfwGetMonitorName_impl
|
||||||
|
|
||||||
|
typedef void (*glfwSetMonitorUserPointer_func)(GLFWmonitor*, void*);
|
||||||
|
glfwSetMonitorUserPointer_func glfwSetMonitorUserPointer_impl;
|
||||||
|
#define glfwSetMonitorUserPointer glfwSetMonitorUserPointer_impl
|
||||||
|
|
||||||
|
typedef void* (*glfwGetMonitorUserPointer_func)(GLFWmonitor*);
|
||||||
|
glfwGetMonitorUserPointer_func glfwGetMonitorUserPointer_impl;
|
||||||
|
#define glfwGetMonitorUserPointer glfwGetMonitorUserPointer_impl
|
||||||
|
|
||||||
typedef GLFWmonitorfun (*glfwSetMonitorCallback_func)(GLFWmonitorfun);
|
typedef GLFWmonitorfun (*glfwSetMonitorCallback_func)(GLFWmonitorfun);
|
||||||
glfwSetMonitorCallback_func glfwSetMonitorCallback_impl;
|
glfwSetMonitorCallback_func glfwSetMonitorCallback_impl;
|
||||||
#define glfwSetMonitorCallback glfwSetMonitorCallback_impl
|
#define glfwSetMonitorCallback glfwSetMonitorCallback_impl
|
||||||
@@ -1435,6 +1460,10 @@ typedef void (*glfwWindowHint_func)(int, int);
|
|||||||
glfwWindowHint_func glfwWindowHint_impl;
|
glfwWindowHint_func glfwWindowHint_impl;
|
||||||
#define glfwWindowHint glfwWindowHint_impl
|
#define glfwWindowHint glfwWindowHint_impl
|
||||||
|
|
||||||
|
typedef void (*glfwWindowHintString_func)(int, const char*);
|
||||||
|
glfwWindowHintString_func glfwWindowHintString_impl;
|
||||||
|
#define glfwWindowHintString glfwWindowHintString_impl
|
||||||
|
|
||||||
typedef GLFWwindow* (*glfwCreateWindow_func)(int, int, const char*, GLFWmonitor*, GLFWwindow*);
|
typedef GLFWwindow* (*glfwCreateWindow_func)(int, int, const char*, GLFWmonitor*, GLFWwindow*);
|
||||||
glfwCreateWindow_func glfwCreateWindow_impl;
|
glfwCreateWindow_func glfwCreateWindow_impl;
|
||||||
#define glfwCreateWindow glfwCreateWindow_impl
|
#define glfwCreateWindow glfwCreateWindow_impl
|
||||||
@@ -1711,6 +1740,14 @@ typedef const char* (*glfwGetJoystickGUID_func)(int);
|
|||||||
glfwGetJoystickGUID_func glfwGetJoystickGUID_impl;
|
glfwGetJoystickGUID_func glfwGetJoystickGUID_impl;
|
||||||
#define glfwGetJoystickGUID glfwGetJoystickGUID_impl
|
#define glfwGetJoystickGUID glfwGetJoystickGUID_impl
|
||||||
|
|
||||||
|
typedef void (*glfwSetJoystickUserPointer_func)(int, void*);
|
||||||
|
glfwSetJoystickUserPointer_func glfwSetJoystickUserPointer_impl;
|
||||||
|
#define glfwSetJoystickUserPointer glfwSetJoystickUserPointer_impl
|
||||||
|
|
||||||
|
typedef void* (*glfwGetJoystickUserPointer_func)(int);
|
||||||
|
glfwGetJoystickUserPointer_func glfwGetJoystickUserPointer_impl;
|
||||||
|
#define glfwGetJoystickUserPointer glfwGetJoystickUserPointer_impl
|
||||||
|
|
||||||
typedef int (*glfwJoystickIsGamepad_func)(int);
|
typedef int (*glfwJoystickIsGamepad_func)(int);
|
||||||
glfwJoystickIsGamepad_func glfwJoystickIsGamepad_impl;
|
glfwJoystickIsGamepad_func glfwJoystickIsGamepad_impl;
|
||||||
#define glfwJoystickIsGamepad glfwJoystickIsGamepad_impl
|
#define glfwJoystickIsGamepad glfwJoystickIsGamepad_impl
|
||||||
|
|||||||
42
kitty/glfw.c
42
kitty/glfw.c
@@ -21,12 +21,14 @@ update_os_window_viewport(OSWindow *window, bool notify_boss) {
|
|||||||
int w, h;
|
int w, h;
|
||||||
glfwGetFramebufferSize(window->handle, &window->viewport_width, &window->viewport_height);
|
glfwGetFramebufferSize(window->handle, &window->viewport_width, &window->viewport_height);
|
||||||
glfwGetWindowSize(window->handle, &w, &h);
|
glfwGetWindowSize(window->handle, &w, &h);
|
||||||
|
double xr = window->viewport_x_ratio, yr = window->viewport_y_ratio;
|
||||||
window->viewport_x_ratio = (double)window->viewport_width / (double)w;
|
window->viewport_x_ratio = (double)window->viewport_width / (double)w;
|
||||||
window->viewport_y_ratio = (double)window->viewport_height / (double)h;
|
window->viewport_y_ratio = (double)window->viewport_height / (double)h;
|
||||||
|
bool dpi_changed = (xr != 0.0 && xr != window->viewport_x_ratio) || (yr != 0.0 && yr != window->viewport_y_ratio);
|
||||||
window->viewport_size_dirty = true;
|
window->viewport_size_dirty = true;
|
||||||
window->has_pending_resizes = false;
|
window->has_pending_resizes = false;
|
||||||
if (notify_boss) {
|
if (notify_boss) {
|
||||||
call_boss(on_window_resize, "Kii", window->id, window->viewport_width, window->viewport_height);
|
call_boss(on_window_resize, "KiiO", window->id, window->viewport_width, window->viewport_height, dpi_changed ? Py_True : Py_False);
|
||||||
}
|
}
|
||||||
window->last_resize_at = monotonic();
|
window->last_resize_at = monotonic();
|
||||||
}
|
}
|
||||||
@@ -246,8 +248,8 @@ current_monitor(GLFWwindow *window) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static inline void
|
void
|
||||||
set_dpi_from_window(OSWindow *w) {
|
set_dpi_from_os_window(OSWindow *w) {
|
||||||
GLFWmonitor *monitor = NULL;
|
GLFWmonitor *monitor = NULL;
|
||||||
if (w) { monitor = current_monitor(w->handle); }
|
if (w) { monitor = current_monitor(w->handle); }
|
||||||
if (monitor == NULL) monitor = glfwGetPrimaryMonitor();
|
if (monitor == NULL) monitor = glfwGetPrimaryMonitor();
|
||||||
@@ -265,13 +267,14 @@ set_dpi_from_window(OSWindow *w) {
|
|||||||
|
|
||||||
static PyObject*
|
static PyObject*
|
||||||
create_os_window(PyObject UNUSED *self, PyObject *args) {
|
create_os_window(PyObject UNUSED *self, PyObject *args) {
|
||||||
int width, height, visible = 1, swap_interval = 0, x = -1, y = -1;
|
int width, height, swap_interval = 0, x = -1, y = -1;
|
||||||
char *title;
|
char *title, *wm_class_class, *wm_class_name;
|
||||||
PyObject *load_programs = NULL;
|
PyObject *load_programs = NULL;
|
||||||
if (!PyArg_ParseTuple(args, "iis|pOiii", &width, &height, &title, &visible, &load_programs, &swap_interval, &x, &y)) return NULL;
|
if (!PyArg_ParseTuple(args, "iisss|Oiii", &width, &height, &title, &wm_class_name, &wm_class_class, &load_programs, &swap_interval, &x, &y)) return NULL;
|
||||||
bool is_first_window = standard_cursor == NULL;
|
bool is_first_window = standard_cursor == NULL;
|
||||||
|
|
||||||
if (is_first_window) {
|
if (is_first_window) {
|
||||||
|
glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
|
||||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, OPENGL_REQUIRED_VERSION_MAJOR);
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, OPENGL_REQUIRED_VERSION_MAJOR);
|
||||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, OPENGL_REQUIRED_VERSION_MINOR);
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, OPENGL_REQUIRED_VERSION_MINOR);
|
||||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
||||||
@@ -292,11 +295,15 @@ create_os_window(PyObject UNUSED *self, PyObject *args) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef __APPLE__
|
||||||
|
glfwWindowHintString(GLFW_X11_INSTANCE_NAME, wm_class_name);
|
||||||
|
glfwWindowHintString(GLFW_X11_CLASS_NAME, wm_class_class);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (global_state.num_os_windows >= MAX_CHILDREN) {
|
if (global_state.num_os_windows >= MAX_CHILDREN) {
|
||||||
PyErr_SetString(PyExc_ValueError, "Too many windows");
|
PyErr_SetString(PyExc_ValueError, "Too many windows");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
glfwWindowHint(GLFW_VISIBLE, visible ? GLFW_TRUE : GLFW_FALSE);
|
|
||||||
bool want_semi_transparent = (1.0 - OPT(background_opacity) > 0.1) ? true : false;
|
bool want_semi_transparent = (1.0 - OPT(background_opacity) > 0.1) ? true : false;
|
||||||
glfwWindowHint(GLFW_TRANSPARENT_FRAMEBUFFER, want_semi_transparent);
|
glfwWindowHint(GLFW_TRANSPARENT_FRAMEBUFFER, want_semi_transparent);
|
||||||
GLFWwindow *glfw_window = glfwCreateWindow(width, height, title, NULL, global_state.num_os_windows ? global_state.os_windows[0].handle : NULL);
|
GLFWwindow *glfw_window = glfwCreateWindow(width, height, title, NULL, global_state.num_os_windows ? global_state.os_windows[0].handle : NULL);
|
||||||
@@ -310,7 +317,7 @@ create_os_window(PyObject UNUSED *self, PyObject *args) {
|
|||||||
current_os_window_ctx = glfw_window;
|
current_os_window_ctx = glfw_window;
|
||||||
glfwSwapInterval(swap_interval); // a value of 1 makes mouse selection laggy
|
glfwSwapInterval(swap_interval); // a value of 1 makes mouse selection laggy
|
||||||
if (is_first_window) {
|
if (is_first_window) {
|
||||||
set_dpi_from_window(NULL);
|
set_dpi_from_os_window(NULL);
|
||||||
gl_init();
|
gl_init();
|
||||||
PyObject *ret = PyObject_CallFunction(load_programs, "i", glfwGetWindowAttrib(glfw_window, GLFW_TRANSPARENT_FRAMEBUFFER));
|
PyObject *ret = PyObject_CallFunction(load_programs, "i", glfwGetWindowAttrib(glfw_window, GLFW_TRANSPARENT_FRAMEBUFFER));
|
||||||
if (ret == NULL) return NULL;
|
if (ret == NULL) return NULL;
|
||||||
@@ -364,15 +371,28 @@ static PyObject*
|
|||||||
show_window(PyObject UNUSED *self, PyObject *args) {
|
show_window(PyObject UNUSED *self, PyObject *args) {
|
||||||
id_type os_window_id;
|
id_type os_window_id;
|
||||||
int yes = 1;
|
int yes = 1;
|
||||||
|
bool dpi_changed = false;
|
||||||
if (!PyArg_ParseTuple(args, "K|p", &os_window_id, &yes)) return NULL;
|
if (!PyArg_ParseTuple(args, "K|p", &os_window_id, &yes)) return NULL;
|
||||||
for (size_t i = 0; i < global_state.num_os_windows; i++) {
|
for (size_t i = 0; i < global_state.num_os_windows; i++) {
|
||||||
OSWindow *w = global_state.os_windows + i;
|
OSWindow *w = global_state.os_windows + i;
|
||||||
if (w->id == os_window_id) {
|
if (w->id == os_window_id) {
|
||||||
if (yes) glfwShowWindow(w->handle); else glfwHideWindow(w->handle);
|
if (yes) {
|
||||||
|
bool first_show = !w->shown_once;
|
||||||
|
glfwShowWindow(w->handle);
|
||||||
|
w->shown_once = true;
|
||||||
|
if (first_show) {
|
||||||
|
double before_x = global_state.logical_dpi_x, before_y = global_state.logical_dpi_y;
|
||||||
|
set_dpi_from_os_window(w);
|
||||||
|
dpi_changed = before_x != global_state.logical_dpi_x || before_y != global_state.logical_dpi_y;
|
||||||
|
w->has_pending_resizes = true;
|
||||||
|
global_state.has_pending_resizes = true;
|
||||||
|
}
|
||||||
|
} else glfwHideWindow(w->handle);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Py_RETURN_NONE;
|
if (dpi_changed) Py_RETURN_TRUE;
|
||||||
|
Py_RETURN_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -710,8 +730,6 @@ bool
|
|||||||
init_glfw(PyObject *m) {
|
init_glfw(PyObject *m) {
|
||||||
if (PyModule_AddFunctions(m, module_methods) != 0) return false;
|
if (PyModule_AddFunctions(m, module_methods) != 0) return false;
|
||||||
#define ADDC(n) if(PyModule_AddIntConstant(m, #n, n) != 0) return false;
|
#define ADDC(n) if(PyModule_AddIntConstant(m, #n, n) != 0) return false;
|
||||||
ADDC(GLFW_X11_WM_CLASS_NAME)
|
|
||||||
ADDC(GLFW_X11_WM_CLASS_CLASS)
|
|
||||||
ADDC(GLFW_RELEASE);
|
ADDC(GLFW_RELEASE);
|
||||||
ADDC(GLFW_PRESS);
|
ADDC(GLFW_PRESS);
|
||||||
ADDC(GLFW_REPEAT);
|
ADDC(GLFW_REPEAT);
|
||||||
|
|||||||
@@ -2,12 +2,14 @@
|
|||||||
#define ALPHA_TYPE
|
#define ALPHA_TYPE
|
||||||
|
|
||||||
uniform sampler2D image;
|
uniform sampler2D image;
|
||||||
|
uniform float inactive_text_alpha;
|
||||||
|
|
||||||
in vec2 texcoord;
|
in vec2 texcoord;
|
||||||
out vec4 color;
|
out vec4 color;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
color = texture(image, texcoord);
|
color = texture(image, texcoord);
|
||||||
|
color.a *= inactive_text_alpha;
|
||||||
#ifdef PREMULT
|
#ifdef PREMULT
|
||||||
color = vec4(color.rgb * color.a, color.a);
|
color = vec4(color.rgb * color.a, color.a);
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -149,6 +149,10 @@ open_url_modifiers ctrl+shift
|
|||||||
# use the operating system's default URL handler.
|
# use the operating system's default URL handler.
|
||||||
open_url_with default
|
open_url_with default
|
||||||
|
|
||||||
|
# The modifiers to use rectangular selection (i.e. to select text in a
|
||||||
|
# rectangular block with the mouse)
|
||||||
|
rectangle_select_modifiers ctrl+alt
|
||||||
|
|
||||||
# Choose whether to use the system implementation of wcwidth() (used to
|
# Choose whether to use the system implementation of wcwidth() (used to
|
||||||
# control how many cells a character is rendered in). If you use the system
|
# control how many cells a character is rendered in). If you use the system
|
||||||
# implementation, then kitty and any programs running in it will agree. The
|
# implementation, then kitty and any programs running in it will agree. The
|
||||||
@@ -177,6 +181,10 @@ active_border_color #00ff00
|
|||||||
# The color for the border of inactive windows
|
# The color for the border of inactive windows
|
||||||
inactive_border_color #cccccc
|
inactive_border_color #cccccc
|
||||||
|
|
||||||
|
# Fade the text in inactive windows by the specified amount (a number between
|
||||||
|
# zero and one, with 0 being fully faded).
|
||||||
|
inactive_text_alpha 1.0
|
||||||
|
|
||||||
# Tab-bar customization
|
# Tab-bar customization
|
||||||
active_tab_foreground #000
|
active_tab_foreground #000
|
||||||
active_tab_background #eee
|
active_tab_background #eee
|
||||||
@@ -278,14 +286,20 @@ map ctrl+shift+7 seventh_window
|
|||||||
map ctrl+shift+8 eighth_window
|
map ctrl+shift+8 eighth_window
|
||||||
map ctrl+shift+9 ninth_window
|
map ctrl+shift+9 ninth_window
|
||||||
map ctrl+shift+0 tenth_window
|
map ctrl+shift+0 tenth_window
|
||||||
# You can also open a new window running an arbitrary program, for example:
|
# You can open a new window running an arbitrary program, for example:
|
||||||
# map ctrl+shift+y new_window mutt
|
# map ctrl+shift+y new_window mutt
|
||||||
# You can also pass the current selection to the new program by using the @selection placeholder
|
#
|
||||||
|
# You can pass the current selection to the new program by using the @selection placeholder
|
||||||
# map ctrl+shift+y new_window less @selection
|
# map ctrl+shift+y new_window less @selection
|
||||||
# Finally, you can even send the contents of the current screen + history buffer as stdin using
|
#
|
||||||
|
# You can even send the contents of the current screen + history buffer as stdin using
|
||||||
# the placeholders @text (which is the plain text) and @ansi (which includes text styling escape codes)
|
# the placeholders @text (which is the plain text) and @ansi (which includes text styling escape codes)
|
||||||
# For example, the following command opens the scrollback buffer in less in a new window.
|
# For example, the following command opens the scrollback buffer in less in a new window.
|
||||||
# map ctrl+shift+y new_window @ansi less +G -R
|
# map ctrl+shift+y new_window @ansi less +G -R
|
||||||
|
#
|
||||||
|
# You can open a new window with the current working directory set to the
|
||||||
|
# working directory of the current window using
|
||||||
|
# map ctrl+alt+enter new_window_with_cwd
|
||||||
|
|
||||||
|
|
||||||
# Tab management
|
# Tab management
|
||||||
@@ -301,7 +315,7 @@ map ctrl+shift+, move_tab_backward
|
|||||||
# map ctrl+alt+2 goto_tab 2
|
# map ctrl+alt+2 goto_tab 2
|
||||||
|
|
||||||
# Just as with new_window above, you can also pass the name of arbitrary
|
# Just as with new_window above, you can also pass the name of arbitrary
|
||||||
# commands to run when using new_tab.
|
# commands to run when using new_tab and use new_tab_with_cwd.
|
||||||
|
|
||||||
|
|
||||||
# Miscellaneous
|
# Miscellaneous
|
||||||
|
|||||||
@@ -139,7 +139,7 @@ line_url_end_at(Line *self, index_type x, bool check_short) {
|
|||||||
index_type ans = x;
|
index_type ans = x;
|
||||||
if (x >= self->xnum || (check_short && self->xnum <= MIN_URL_LEN + 3)) return 0;
|
if (x >= self->xnum || (check_short && self->xnum <= MIN_URL_LEN + 3)) return 0;
|
||||||
while (ans < self->xnum && is_url_char(self->cells[ans].ch)) ans++;
|
while (ans < self->xnum && is_url_char(self->cells[ans].ch)) ans++;
|
||||||
ans--;
|
if (ans) ans--;
|
||||||
while (ans > x && can_strip_from_end_of_url(self->cells[ans].ch)) ans--;
|
while (ans > x && can_strip_from_end_of_url(self->cells[ans].ch)) ans--;
|
||||||
return ans;
|
return ans;
|
||||||
}
|
}
|
||||||
@@ -618,4 +618,3 @@ copy_char(Line* self, PyObject *args) {
|
|||||||
COPY_CELL(self, src, to, dest);
|
COPY_CELL(self, src, to, dest);
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,15 +12,15 @@ from .borders import load_borders_program
|
|||||||
from .boss import Boss
|
from .boss import Boss
|
||||||
from .cli import create_opts, parse_args
|
from .cli import create_opts, parse_args
|
||||||
from .config import initial_window_size, load_cached_values, save_cached_values
|
from .config import initial_window_size, load_cached_values, save_cached_values
|
||||||
from .constants import glfw_path, is_macos, is_wayland, logo_data_file
|
from .constants import appname, glfw_path, is_macos, is_wayland, logo_data_file
|
||||||
from .fast_data_types import (
|
from .fast_data_types import (
|
||||||
change_wcwidth, create_os_window, glfw_init, glfw_terminate,
|
change_wcwidth, create_os_window, glfw_init, glfw_terminate,
|
||||||
install_sigchld_handler, set_default_window_icon, set_options, show_window
|
install_sigchld_handler, set_default_window_icon, set_options, show_window
|
||||||
)
|
)
|
||||||
from .fonts.box_drawing import set_scale
|
from .fonts.box_drawing import set_scale
|
||||||
from .utils import (
|
from .utils import (
|
||||||
detach, encode_wm_class, end_startup_notification,
|
detach, end_startup_notification, init_startup_notification,
|
||||||
init_startup_notification, single_instance
|
single_instance
|
||||||
)
|
)
|
||||||
from .window import load_shader_programs
|
from .window import load_shader_programs
|
||||||
|
|
||||||
@@ -42,7 +42,7 @@ def run_app(opts, args):
|
|||||||
set_options(opts, is_wayland, args.debug_gl)
|
set_options(opts, is_wayland, args.debug_gl)
|
||||||
load_cached_values()
|
load_cached_values()
|
||||||
w, h = initial_window_size(opts)
|
w, h = initial_window_size(opts)
|
||||||
window_id = create_os_window(w, h, encode_wm_class(args.name, args.cls), False, load_all_shaders)
|
window_id = create_os_window(w, h, appname, args.name or args.cls or appname, args.cls or appname, load_all_shaders)
|
||||||
startup_ctx = init_startup_notification(window_id)
|
startup_ctx = init_startup_notification(window_id)
|
||||||
show_window(window_id)
|
show_window(window_id)
|
||||||
if not is_wayland and not is_macos: # no window icons on wayland
|
if not is_wayland and not is_macos: # no window icons on wayland
|
||||||
|
|||||||
@@ -111,7 +111,7 @@ update_drag(bool from_button, Window *w, bool is_release, int modifiers) {
|
|||||||
Screen *screen = w->render_data.screen;
|
Screen *screen = w->render_data.screen;
|
||||||
if (from_button) {
|
if (from_button) {
|
||||||
if (is_release) screen_update_selection(screen, w->mouse_cell_x, w->mouse_cell_y, true);
|
if (is_release) screen_update_selection(screen, w->mouse_cell_x, w->mouse_cell_y, true);
|
||||||
else screen_start_selection(screen, w->mouse_cell_x, w->mouse_cell_y, modifiers == (GLFW_MOD_CONTROL | GLFW_MOD_ALT));
|
else screen_start_selection(screen, w->mouse_cell_x, w->mouse_cell_y, modifiers == (int)OPT(rectangle_select_modifiers));
|
||||||
} else if (screen->selection.in_progress) {
|
} else if (screen->selection.in_progress) {
|
||||||
screen_update_selection(screen, w->mouse_cell_x, w->mouse_cell_y, false);
|
screen_update_selection(screen, w->mouse_cell_x, w->mouse_cell_y, false);
|
||||||
call_boss(set_primary_selection, NULL);
|
call_boss(set_primary_selection, NULL);
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include "unicode-data.h"
|
#include "unicode-data.h"
|
||||||
#include "modes.h"
|
#include "modes.h"
|
||||||
#include "wcwidth9.h"
|
#include "wcwidth-std.h"
|
||||||
#include "control-codes.h"
|
#include "control-codes.h"
|
||||||
|
|
||||||
static const ScreenModes empty_modes = {0, .mDECAWM=true, .mDECTCEM=true, .mDECARM=true};
|
static const ScreenModes empty_modes = {0, .mDECAWM=true, .mDECTCEM=true, .mDECARM=true};
|
||||||
@@ -275,8 +275,8 @@ safe_wcwidth(uint32_t ch) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
change_wcwidth(bool use9) {
|
change_wcwidth(bool use_std) {
|
||||||
wcwidth_impl = (use9) ? wcwidth9 : wcwidth;
|
wcwidth_impl = use_std ? wcwidth_std : wcwidth;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ def parse_session(raw, opts):
|
|||||||
return ans
|
return ans
|
||||||
|
|
||||||
|
|
||||||
def create_session(opts, args=None, special_window=None):
|
def create_session(opts, args=None, special_window=None, cwd_from=None):
|
||||||
if args and args.session:
|
if args and args.session:
|
||||||
with open(args.session) as f:
|
with open(args.session) as f:
|
||||||
return parse_session(f.read(), opts)
|
return parse_session(f.read(), opts)
|
||||||
@@ -100,11 +100,11 @@ def create_session(opts, args=None, special_window=None):
|
|||||||
ans.tabs[-1].layout = current_layout
|
ans.tabs[-1].layout = current_layout
|
||||||
if special_window is None:
|
if special_window is None:
|
||||||
cmd = args.args if args and args.args else [shell_path]
|
cmd = args.args if args and args.args else [shell_path]
|
||||||
|
from kitty.tabs import SpecialWindow
|
||||||
if getattr(args, 'title', None):
|
if getattr(args, 'title', None):
|
||||||
from kitty.tabs import SpecialWindow
|
ans.add_window(SpecialWindow(cmd, override_title=args.title, cwd_from=cwd_from))
|
||||||
ans.add_window(SpecialWindow(cmd, override_title=args.title))
|
|
||||||
else:
|
else:
|
||||||
ans.add_window(cmd)
|
ans.add_window(SpecialWindow(cmd, cwd_from=cwd_from))
|
||||||
else:
|
else:
|
||||||
ans.add_special_window(special_window)
|
ans.add_special_window(special_window)
|
||||||
return ans
|
return ans
|
||||||
|
|||||||
@@ -201,6 +201,14 @@ create_graphics_vao() {
|
|||||||
return vao_idx;
|
return vao_idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct CellUniformData {
|
||||||
|
bool constants_set;
|
||||||
|
GLint gploc, gpploc, cploc, cfploc;
|
||||||
|
GLfloat prev_inactive_text_alpha;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct CellUniformData cell_uniform_data = {0, .prev_inactive_text_alpha=-1};
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
cell_update_uniform_block(ssize_t vao_idx, Screen *screen, int uniform_buffer, GLfloat xstart, GLfloat ystart, GLfloat dx, GLfloat dy, CursorRenderInfo *cursor, bool inverted) {
|
cell_update_uniform_block(ssize_t vao_idx, Screen *screen, int uniform_buffer, GLfloat xstart, GLfloat ystart, GLfloat dx, GLfloat dy, CursorRenderInfo *cursor, bool inverted) {
|
||||||
struct CellRenderData {
|
struct CellRenderData {
|
||||||
@@ -220,7 +228,7 @@ cell_update_uniform_block(ssize_t vao_idx, Screen *screen, int uniform_buffer, G
|
|||||||
copy_color_table_to_buffer(screen->color_profile, (GLuint*)rd, cell_program_layouts[CELL_PROGRAM].color_table.offset / sizeof(GLuint), cell_program_layouts[CELL_PROGRAM].color_table.stride / sizeof(GLuint));
|
copy_color_table_to_buffer(screen->color_profile, (GLuint*)rd, cell_program_layouts[CELL_PROGRAM].color_table.offset / sizeof(GLuint), cell_program_layouts[CELL_PROGRAM].color_table.stride / sizeof(GLuint));
|
||||||
}
|
}
|
||||||
// Cursor position
|
// Cursor position
|
||||||
if (cursor->is_visible && cursor->shape == CURSOR_BLOCK) {
|
if (cursor->is_visible && cursor->shape == CURSOR_BLOCK && cursor->is_focused) {
|
||||||
rd->cursor_x = screen->cursor->x, rd->cursor_y = screen->cursor->y;
|
rd->cursor_x = screen->cursor->x, rd->cursor_y = screen->cursor->y;
|
||||||
} else {
|
} else {
|
||||||
rd->cursor_x = screen->columns, rd->cursor_y = screen->lines;
|
rd->cursor_x = screen->columns, rd->cursor_y = screen->lines;
|
||||||
@@ -284,12 +292,6 @@ static void
|
|||||||
draw_graphics(int program, ssize_t vao_idx, ssize_t gvao_idx, ImageRenderData *data, GLuint start, GLuint count) {
|
draw_graphics(int program, ssize_t vao_idx, ssize_t gvao_idx, ImageRenderData *data, GLuint start, GLuint count) {
|
||||||
bind_program(program);
|
bind_program(program);
|
||||||
bind_vertex_array(gvao_idx);
|
bind_vertex_array(gvao_idx);
|
||||||
static bool graphics_constants_set = false;
|
|
||||||
if (!graphics_constants_set) {
|
|
||||||
glUniform1i(glGetUniformLocation(program_id(GRAPHICS_PROGRAM), "image"), GRAPHICS_UNIT);
|
|
||||||
glUniform1i(glGetUniformLocation(program_id(GRAPHICS_PREMULT_PROGRAM), "image"), GRAPHICS_UNIT);
|
|
||||||
graphics_constants_set = true;
|
|
||||||
}
|
|
||||||
glActiveTexture(GL_TEXTURE0 + GRAPHICS_UNIT);
|
glActiveTexture(GL_TEXTURE0 + GRAPHICS_UNIT);
|
||||||
|
|
||||||
GLuint base = 4 * start;
|
GLuint base = 4 * start;
|
||||||
@@ -389,8 +391,29 @@ draw_cells_interleaved_premult(ssize_t vao_idx, ssize_t gvao_idx, Screen *screen
|
|||||||
glDisable(GL_SCISSOR_TEST);
|
glDisable(GL_SCISSOR_TEST);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
set_cell_uniforms(float current_inactive_text_alpha) {
|
||||||
|
if (!cell_uniform_data.constants_set) {
|
||||||
|
cell_uniform_data.gploc = glGetUniformLocation(program_id(GRAPHICS_PROGRAM), "inactive_text_alpha");
|
||||||
|
cell_uniform_data.gpploc = glGetUniformLocation(program_id(GRAPHICS_PREMULT_PROGRAM), "inactive_text_alpha");
|
||||||
|
cell_uniform_data.cploc = glGetUniformLocation(program_id(CELL_PROGRAM), "inactive_text_alpha");
|
||||||
|
cell_uniform_data.cfploc = glGetUniformLocation(program_id(CELL_FG_PROGRAM), "inactive_text_alpha");
|
||||||
|
#define S(prog, name, val) { bind_program(prog); glUniform1i(glGetUniformLocation(program_id(prog), #name), val); }
|
||||||
|
S(GRAPHICS_PROGRAM, image, GRAPHICS_UNIT); S(GRAPHICS_PREMULT_PROGRAM, image, GRAPHICS_UNIT);
|
||||||
|
S(CELL_PROGRAM, sprites, SPRITE_MAP_UNIT); S(CELL_FG_PROGRAM, sprites, SPRITE_MAP_UNIT);
|
||||||
|
#undef S
|
||||||
|
cell_uniform_data.constants_set = true;
|
||||||
|
}
|
||||||
|
if (current_inactive_text_alpha != cell_uniform_data.prev_inactive_text_alpha) {
|
||||||
|
cell_uniform_data.prev_inactive_text_alpha = current_inactive_text_alpha;
|
||||||
|
#define S(prog, loc) { bind_program(prog); glUniform1f(cell_uniform_data.loc, current_inactive_text_alpha); }
|
||||||
|
S(CELL_PROGRAM, cploc); S(CELL_FG_PROGRAM, cfploc); S(GRAPHICS_PROGRAM, gploc); S(GRAPHICS_PREMULT_PROGRAM, gpploc);
|
||||||
|
#undef S
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
draw_cells(ssize_t vao_idx, ssize_t gvao_idx, GLfloat xstart, GLfloat ystart, GLfloat dx, GLfloat dy, Screen *screen, OSWindow *os_window) {
|
draw_cells(ssize_t vao_idx, ssize_t gvao_idx, GLfloat xstart, GLfloat ystart, GLfloat dx, GLfloat dy, Screen *screen, OSWindow *os_window, bool is_active_window) {
|
||||||
if (os_window->clear_count < 2) {
|
if (os_window->clear_count < 2) {
|
||||||
os_window->clear_count++;
|
os_window->clear_count++;
|
||||||
#define C(shift) (((GLfloat)((OPT(background) >> shift) & 0xFF)) / 255.0f)
|
#define C(shift) (((GLfloat)((OPT(background) >> shift) & 0xFF)) / 255.0f)
|
||||||
@@ -400,6 +423,8 @@ draw_cells(ssize_t vao_idx, ssize_t gvao_idx, GLfloat xstart, GLfloat ystart, GL
|
|||||||
}
|
}
|
||||||
|
|
||||||
cell_prepare_to_render(vao_idx, gvao_idx, screen, xstart, ystart, dx, dy);
|
cell_prepare_to_render(vao_idx, gvao_idx, screen, xstart, ystart, dx, dy);
|
||||||
|
float current_inactive_text_alpha = screen->cursor_render_info.is_focused && is_active_window ? 1.0 : OPT(inactive_text_alpha);
|
||||||
|
set_cell_uniforms(current_inactive_text_alpha);
|
||||||
GLfloat w = (GLfloat)screen->columns * dx, h = (GLfloat)screen->lines * dy;
|
GLfloat w = (GLfloat)screen->columns * dx, h = (GLfloat)screen->lines * dy;
|
||||||
#define SCALE(w, x) ((GLfloat)(os_window->viewport_##w) * (GLfloat)(x))
|
#define SCALE(w, x) ((GLfloat)(os_window->viewport_##w) * (GLfloat)(x))
|
||||||
glScissor(
|
glScissor(
|
||||||
@@ -409,13 +434,6 @@ draw_cells(ssize_t vao_idx, ssize_t gvao_idx, GLfloat xstart, GLfloat ystart, GL
|
|||||||
(GLsizei)(ceilf(SCALE(height, h / 2.0f)))
|
(GLsizei)(ceilf(SCALE(height, h / 2.0f)))
|
||||||
);
|
);
|
||||||
#undef SCALE
|
#undef SCALE
|
||||||
static bool cell_constants_set = false;
|
|
||||||
if (!cell_constants_set) {
|
|
||||||
bind_program(CELL_PROGRAM);
|
|
||||||
glUniform1i(glGetUniformLocation(program_id(CELL_PROGRAM), "sprites"), SPRITE_MAP_UNIT);
|
|
||||||
glUniform1i(glGetUniformLocation(program_id(CELL_FG_PROGRAM), "sprites"), SPRITE_MAP_UNIT);
|
|
||||||
cell_constants_set = true;
|
|
||||||
}
|
|
||||||
if (os_window->is_semi_transparent) {
|
if (os_window->is_semi_transparent) {
|
||||||
if (screen->grman->count) draw_cells_interleaved_premult(vao_idx, gvao_idx, screen, os_window);
|
if (screen->grman->count) draw_cells_interleaved_premult(vao_idx, gvao_idx, screen, os_window);
|
||||||
else draw_cells_simple(vao_idx, gvao_idx, screen);
|
else draw_cells_simple(vao_idx, gvao_idx, screen);
|
||||||
|
|||||||
@@ -311,12 +311,14 @@ PYWRAP1(set_options) {
|
|||||||
S(cursor_blink_interval, PyFloat_AsDouble);
|
S(cursor_blink_interval, PyFloat_AsDouble);
|
||||||
S(cursor_stop_blinking_after, PyFloat_AsDouble);
|
S(cursor_stop_blinking_after, PyFloat_AsDouble);
|
||||||
S(background_opacity, PyFloat_AsDouble);
|
S(background_opacity, PyFloat_AsDouble);
|
||||||
|
S(inactive_text_alpha, PyFloat_AsDouble);
|
||||||
S(cursor_shape, PyLong_AsLong);
|
S(cursor_shape, PyLong_AsLong);
|
||||||
S(url_style, PyLong_AsUnsignedLong);
|
S(url_style, PyLong_AsUnsignedLong);
|
||||||
S(x11_bell_volume, PyLong_AsLong);
|
S(x11_bell_volume, PyLong_AsLong);
|
||||||
S(mouse_hide_wait, PyFloat_AsDouble);
|
S(mouse_hide_wait, PyFloat_AsDouble);
|
||||||
S(wheel_scroll_multiplier, PyFloat_AsDouble);
|
S(wheel_scroll_multiplier, PyFloat_AsDouble);
|
||||||
S(open_url_modifiers, PyLong_AsUnsignedLong);
|
S(open_url_modifiers, PyLong_AsUnsignedLong);
|
||||||
|
S(rectangle_select_modifiers, PyLong_AsUnsignedLong);
|
||||||
S(click_interval, PyFloat_AsDouble);
|
S(click_interval, PyFloat_AsDouble);
|
||||||
S(url_color, color_as_int);
|
S(url_color, color_as_int);
|
||||||
S(background, color_as_int);
|
S(background, color_as_int);
|
||||||
@@ -373,6 +375,15 @@ PYWRAP1(viewport_for_window) {
|
|||||||
return Py_BuildValue("iiII", 400, 400, global_state.cell_width, global_state.cell_height);
|
return Py_BuildValue("iiII", 400, 400, global_state.cell_width, global_state.cell_height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PYWRAP1(set_dpi_from_os_window) {
|
||||||
|
id_type os_window_id = PyLong_AsUnsignedLongLong(args);
|
||||||
|
WITH_OS_WINDOW(os_window_id)
|
||||||
|
set_dpi_from_os_window(os_window);
|
||||||
|
Py_RETURN_TRUE;
|
||||||
|
END_WITH_OS_WINDOW
|
||||||
|
Py_RETURN_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
PYWRAP1(mark_os_window_for_close) {
|
PYWRAP1(mark_os_window_for_close) {
|
||||||
id_type os_window_id;
|
id_type os_window_id;
|
||||||
int yes = 1;
|
int yes = 1;
|
||||||
@@ -476,6 +487,7 @@ static PyMethodDef module_methods[] = {
|
|||||||
MW(set_logical_dpi, METH_VARARGS),
|
MW(set_logical_dpi, METH_VARARGS),
|
||||||
MW(pt_to_px, METH_O),
|
MW(pt_to_px, METH_O),
|
||||||
MW(pt_to_px_ceil, METH_O),
|
MW(pt_to_px_ceil, METH_O),
|
||||||
|
MW(set_dpi_from_os_window, METH_O),
|
||||||
MW(add_tab, METH_O),
|
MW(add_tab, METH_O),
|
||||||
MW(add_window, METH_VARARGS),
|
MW(add_window, METH_VARARGS),
|
||||||
MW(update_window_title, METH_VARARGS),
|
MW(update_window_title, METH_VARARGS),
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ typedef struct {
|
|||||||
bool enable_audio_bell;
|
bool enable_audio_bell;
|
||||||
CursorShape cursor_shape;
|
CursorShape cursor_shape;
|
||||||
unsigned int open_url_modifiers;
|
unsigned int open_url_modifiers;
|
||||||
|
unsigned int rectangle_select_modifiers;
|
||||||
unsigned int url_style;
|
unsigned int url_style;
|
||||||
char_type select_by_word_characters[256]; size_t select_by_word_characters_count;
|
char_type select_by_word_characters[256]; size_t select_by_word_characters_count;
|
||||||
color_type url_color, background;
|
color_type url_color, background;
|
||||||
@@ -26,6 +27,7 @@ typedef struct {
|
|||||||
int x11_bell_volume;
|
int x11_bell_volume;
|
||||||
float adjust_line_height_frac;
|
float adjust_line_height_frac;
|
||||||
float background_opacity;
|
float background_opacity;
|
||||||
|
float inactive_text_alpha;
|
||||||
} Options;
|
} Options;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -105,6 +107,7 @@ typedef struct {
|
|||||||
double last_resize_at;
|
double last_resize_at;
|
||||||
bool has_pending_resizes;
|
bool has_pending_resizes;
|
||||||
bool is_semi_transparent;
|
bool is_semi_transparent;
|
||||||
|
bool shown_once;
|
||||||
uint32_t offscreen_texture_id;
|
uint32_t offscreen_texture_id;
|
||||||
unsigned int clear_count;
|
unsigned int clear_count;
|
||||||
} OSWindow;
|
} OSWindow;
|
||||||
@@ -146,6 +149,7 @@ void mark_os_window_for_close(OSWindow* w, bool yes);
|
|||||||
void update_os_window_viewport(OSWindow *window, bool);
|
void update_os_window_viewport(OSWindow *window, bool);
|
||||||
bool should_os_window_close(OSWindow* w);
|
bool should_os_window_close(OSWindow* w);
|
||||||
bool should_os_window_be_rendered(OSWindow* w);
|
bool should_os_window_be_rendered(OSWindow* w);
|
||||||
|
void set_dpi_from_os_window(OSWindow *w);
|
||||||
void wakeup_main_loop();
|
void wakeup_main_loop();
|
||||||
void event_loop_wait(double timeout);
|
void event_loop_wait(double timeout);
|
||||||
void swap_window_buffers(OSWindow *w);
|
void swap_window_buffers(OSWindow *w);
|
||||||
@@ -161,7 +165,7 @@ void draw_borders(ssize_t vao_idx, unsigned int num_border_rects, BorderRect *re
|
|||||||
ssize_t create_cell_vao();
|
ssize_t create_cell_vao();
|
||||||
ssize_t create_graphics_vao();
|
ssize_t create_graphics_vao();
|
||||||
ssize_t create_border_vao();
|
ssize_t create_border_vao();
|
||||||
void draw_cells(ssize_t, ssize_t, float, float, float, float, Screen *, OSWindow *);
|
void draw_cells(ssize_t, ssize_t, float, float, float, float, Screen *, OSWindow *, bool);
|
||||||
void draw_cursor(CursorRenderInfo *, bool);
|
void draw_cursor(CursorRenderInfo *, bool);
|
||||||
void update_surface_size(int, int, uint32_t);
|
void update_surface_size(int, int, uint32_t);
|
||||||
void free_texture(uint32_t*);
|
void free_texture(uint32_t*);
|
||||||
|
|||||||
@@ -22,16 +22,16 @@ from .utils import color_as_int
|
|||||||
from .window import Window, calculate_gl_geometry
|
from .window import Window, calculate_gl_geometry
|
||||||
|
|
||||||
TabbarData = namedtuple('TabbarData', 'title is_active is_last')
|
TabbarData = namedtuple('TabbarData', 'title is_active is_last')
|
||||||
SpecialWindowInstance = namedtuple('SpecialWindow', 'cmd stdin override_title')
|
SpecialWindowInstance = namedtuple('SpecialWindow', 'cmd stdin override_title cwd_from')
|
||||||
|
|
||||||
|
|
||||||
def SpecialWindow(cmd, stdin=None, override_title=None):
|
def SpecialWindow(cmd, stdin=None, override_title=None, cwd_from=None):
|
||||||
return SpecialWindowInstance(cmd, stdin, override_title)
|
return SpecialWindowInstance(cmd, stdin, override_title, cwd_from)
|
||||||
|
|
||||||
|
|
||||||
class Tab: # {{{
|
class Tab: # {{{
|
||||||
|
|
||||||
def __init__(self, tab_manager, session_tab=None, special_window=None):
|
def __init__(self, tab_manager, session_tab=None, special_window=None, cwd_from=None):
|
||||||
self.tab_manager_ref = weakref.ref(tab_manager)
|
self.tab_manager_ref = weakref.ref(tab_manager)
|
||||||
self.os_window_id = tab_manager.os_window_id
|
self.os_window_id = tab_manager.os_window_id
|
||||||
self.id = add_tab(self.os_window_id)
|
self.id = add_tab(self.os_window_id)
|
||||||
@@ -50,7 +50,7 @@ class Tab: # {{{
|
|||||||
sl = self.enabled_layouts[0]
|
sl = self.enabled_layouts[0]
|
||||||
self.current_layout = all_layouts[sl](self.os_window_id, self.opts, self.borders.border_width, self.windows)
|
self.current_layout = all_layouts[sl](self.os_window_id, self.opts, self.borders.border_width, self.windows)
|
||||||
if special_window is None:
|
if special_window is None:
|
||||||
self.new_window()
|
self.new_window(cwd_from=cwd_from)
|
||||||
else:
|
else:
|
||||||
self.new_special_window(special_window)
|
self.new_special_window(special_window)
|
||||||
else:
|
else:
|
||||||
@@ -109,7 +109,7 @@ class Tab: # {{{
|
|||||||
w.set_visible_in_layout(i, True)
|
w.set_visible_in_layout(i, True)
|
||||||
self.relayout()
|
self.relayout()
|
||||||
|
|
||||||
def launch_child(self, use_shell=False, cmd=None, stdin=None):
|
def launch_child(self, use_shell=False, cmd=None, stdin=None, cwd_from=None):
|
||||||
if cmd is None:
|
if cmd is None:
|
||||||
if use_shell:
|
if use_shell:
|
||||||
cmd = [shell_path]
|
cmd = [shell_path]
|
||||||
@@ -122,12 +122,12 @@ class Tab: # {{{
|
|||||||
except Exception:
|
except Exception:
|
||||||
import traceback
|
import traceback
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
ans = Child(cmd, self.cwd, self.opts, stdin, env)
|
ans = Child(cmd, self.cwd, self.opts, stdin, env, cwd_from)
|
||||||
ans.fork()
|
ans.fork()
|
||||||
return ans
|
return ans
|
||||||
|
|
||||||
def new_window(self, use_shell=True, cmd=None, stdin=None, override_title=None):
|
def new_window(self, use_shell=True, cmd=None, stdin=None, override_title=None, cwd_from=None):
|
||||||
child = self.launch_child(use_shell=use_shell, cmd=cmd, stdin=stdin)
|
child = self.launch_child(use_shell=use_shell, cmd=cmd, stdin=stdin, cwd_from=cwd_from)
|
||||||
window = Window(self, child, self.opts, self.args, override_title=override_title)
|
window = Window(self, child, self.opts, self.args, override_title=override_title)
|
||||||
# Must add child before laying out so that resize_pty succeeds
|
# Must add child before laying out so that resize_pty succeeds
|
||||||
get_boss().add_child(window)
|
get_boss().add_child(window)
|
||||||
@@ -401,10 +401,10 @@ class TabManager: # {{{
|
|||||||
def title_changed(self, new_title):
|
def title_changed(self, new_title):
|
||||||
self.update_tab_bar()
|
self.update_tab_bar()
|
||||||
|
|
||||||
def new_tab(self, special_window=None):
|
def new_tab(self, special_window=None, cwd_from=None):
|
||||||
needs_resize = len(self.tabs) == 1
|
needs_resize = len(self.tabs) == 1
|
||||||
idx = len(self.tabs)
|
idx = len(self.tabs)
|
||||||
self._add_tab(Tab(self, special_window=special_window))
|
self._add_tab(Tab(self, special_window=special_window, cwd_from=cwd_from))
|
||||||
self._set_active_tab(idx)
|
self._set_active_tab(idx)
|
||||||
self.update_tab_bar()
|
self.update_tab_bar()
|
||||||
if needs_resize:
|
if needs_resize:
|
||||||
|
|||||||
@@ -264,9 +264,3 @@ def single_instance(group_id=None):
|
|||||||
s.set_inheritable(False)
|
s.set_inheritable(False)
|
||||||
atexit.register(remove_socket_file, s)
|
atexit.register(remove_socket_file, s)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def encode_wm_class(name, cls, title=appname):
|
|
||||||
if is_macos:
|
|
||||||
return title
|
|
||||||
return '\x01' + (name or cls) + '\x1e' + cls + '\x1e' + title
|
|
||||||
|
|||||||
2435
kitty/wcwidth-std.h
generated
Normal file
2435
kitty/wcwidth-std.h
generated
Normal file
File diff suppressed because it is too large
Load Diff
1321
kitty/wcwidth9.h
1321
kitty/wcwidth9.h
File diff suppressed because it is too large
Load Diff
@@ -269,6 +269,9 @@ class TestDataTypes(BaseTest):
|
|||||||
no_url('http: //acme.com')
|
no_url('http: //acme.com')
|
||||||
no_url('http:/ /acme.com')
|
no_url('http:/ /acme.com')
|
||||||
|
|
||||||
|
l4 = create(' xxxxxtekljhgdkjgd')
|
||||||
|
self.ae(l4.url_end_at(0), 0)
|
||||||
|
|
||||||
def rewrap(self, lb, lb2):
|
def rewrap(self, lb, lb2):
|
||||||
hb = HistoryBuf(lb2.ynum, lb2.xnum)
|
hb = HistoryBuf(lb2.ynum, lb2.xnum)
|
||||||
cy = lb.rewrap(lb2, hb)
|
cy = lb.rewrap(lb2, hb)
|
||||||
|
|||||||
7
setup.py
7
setup.py
@@ -401,7 +401,12 @@ def compile_glfw(incremental, compilation_database, all_keys):
|
|||||||
sources = [os.path.join('glfw', x) for x in genv.sources]
|
sources = [os.path.join('glfw', x) for x in genv.sources]
|
||||||
all_headers = [os.path.join('glfw', x) for x in genv.all_headers]
|
all_headers = [os.path.join('glfw', x) for x in genv.all_headers]
|
||||||
if module == 'wayland':
|
if module == 'wayland':
|
||||||
glfw.build_wayland_protocols(genv, run_tool, emphasis, newer, os.path.join(base, 'glfw'))
|
try:
|
||||||
|
glfw.build_wayland_protocols(genv, run_tool, emphasis, newer, os.path.join(base, 'glfw'))
|
||||||
|
except SystemExit as err:
|
||||||
|
print(err, file=sys.stderr)
|
||||||
|
print(error('Disabling building of wayland backend'), file=sys.stderr)
|
||||||
|
continue
|
||||||
compile_c_extension(genv, 'kitty/glfw-' + module, incremental, compilation_database, all_keys, sources, all_headers)
|
compile_c_extension(genv, 'kitty/glfw-' + module, incremental, compilation_database, all_keys, sources, all_headers)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user