Compare commits

..

69 Commits

Author SHA1 Message Date
Kovid Goyal
97af84a063 version 0.15.1 2019-12-21 14:20:28 +05:30
Kovid Goyal
18faee6250 Merge branch 'glad2-regen' of https://github.com/Dav1dde/kitty 2019-12-20 20:19:54 +05:30
David Herberth
fd90a3ddc3 regenerates glad to fix missing APIENTRY 2019-12-20 15:04:23 +01:00
Kovid Goyal
a08931d84d Fix window not being rendered for the first time until some input has been received from child process
Fixes #2216
2019-12-20 08:46:50 +05:30
Kovid Goyal
2f0b6e24c9 Use pre-multiplied alpha when clearing windows
Apparently most systems expect this. See https://github.com/glfw/glfw/issues/1538
2019-12-20 08:16:10 +05:30
Kovid Goyal
33c5fc0fb6 typo 2019-12-20 07:59:55 +05:30
Kovid Goyal
71adb2dcf8 Merge branch 'new_os_window_key_macos' of https://github.com/Luflosi/kitty 2019-12-20 07:59:08 +05:30
Luflosi
1ae324691d Change keyboard shortcut selection algorithm for new_os_window on macOS
On macOS the keyboard shortcuts are visible in the menu bar. When the keyboard shortcut is used, the corresponding menu bar item flashes to indicate which action was just executed.
kitty allows defining multiple keyboard shortcuts for the same action but macOS allows only one, so kitty needs to decide which one should be handled by macOS. Currently it chooses the first keyboard shortcut with only the command key as a modifier key or the first shortcut when there are no shortcuts with only the command key as a modifier.
When a user tries to set their own keyboard shortcut (and doesn't use `clear_all_shortcuts yes`), this won't change the shortcut displayed in the menu bar since the first (default) shortcut with the command key is <kbd>⌘</kbd>+<kbd>n</kbd>.
I think simply choosing the last defined keyboard shortcut is better. This will even allow the user to specify modifier keys other than the command key while still changing the shortcut in the menu bar. This change will not change the default behaviour because all the macOS specific keyboard shortcuts are defined after the non-macOS specific ones.
2019-12-19 22:15:41 +01:00
Kovid Goyal
689d059517 Fix lines at the edge of the window at certain windows sizes when drawing images on a transparent window
Fixes #2079
Fixes #2214
2019-12-19 20:41:31 +05:30
Kovid Goyal
18f0ab9e02 Merge branch 'fix_typo' of https://github.com/Luflosi/kitty 2019-12-19 20:01:12 +05:30
Luflosi
088ab5f137 Fix typo 2019-12-19 13:40:08 +01:00
Kovid Goyal
3dd83975ba Dont cast double to monotonic_t for literals 2019-12-19 17:33:12 +05:30
Kovid Goyal
a796a6cbef Use exponential notation in monotonic.h 2019-12-19 17:22:33 +05:30
Kovid Goyal
4766d7de82 Merge branch 'glfw_upstream' of https://github.com/Luflosi/kitty 2019-12-19 17:19:42 +05:30
Luflosi
4a3686c16c X11: Cleanup
From upstream: 73a8ebb691.
2019-12-19 12:38:56 +01:00
Kovid Goyal
b49105495c Merge branch 'glfw_upstream' of https://github.com/Luflosi/kitty 2019-12-19 17:07:42 +05:30
Luflosi
ca2eda2c5b X11: Cleanup
From upstream: 4e70c95aa3.
2019-12-19 12:35:44 +01:00
Kovid Goyal
4fc7c4aafc Merge branch 'glfw_upstream' of https://github.com/Luflosi/kitty 2019-12-19 17:05:10 +05:30
Luflosi
0981828493 X11: Fix updating GLFW_FLOATING on a hidden window
From upstream: 9db156421f.
2019-12-19 12:31:31 +01:00
Kovid Goyal
6bc4f18a59 Merge branch 'glfw_upstream' of https://github.com/Luflosi/kitty 2019-12-19 16:59:26 +05:30
Luflosi
79532a315c X11: Fix invalid read when clearing GLFW_FLOATING
From upstream: 0b652a44d2.
2019-12-19 12:27:36 +01:00
Kovid Goyal
7472a992ed Merge branch 'glfw_upstream' of https://github.com/Luflosi/kitty 2019-12-19 16:56:48 +05:30
Luflosi
e40616a0db X11: Fix missing checks for EWMH attention atoms
From upstream: 9b6d68ec70.
2019-12-19 12:25:09 +01:00
Kovid Goyal
dd8b97a86c Merge branch 'glfw_upstream' of https://github.com/Luflosi/kitty 2019-12-19 16:53:38 +05:30
Luflosi
5eff3897de X11: Fix maximization of hidden windows
From upstream: 4837b78ffe.
2019-12-19 12:20:58 +01:00
Kovid Goyal
530cf2eb14 monotonic.h no longer depends on time.h 2019-12-19 16:48:35 +05:30
Kovid Goyal
2baa34beb8 Move a couple of functions to where they are actually needed 2019-12-19 16:43:51 +05:30
Kovid Goyal
87e2f7f86d Missed a couple of macOS timer calls 2019-12-19 16:34:47 +05:30
Kovid Goyal
e142083d53 Remove unused code
Strip out the GLFW timer code, since we use our own kitty based
monotonic clock.
2019-12-19 16:27:25 +05:30
Kovid Goyal
2e850a0d0d Merge branch 'glfw_upstream' of https://github.com/Luflosi/kitty 2019-12-19 07:56:04 +05:30
Luflosi
aec9c31bca Formatting
From upstream: 506a6aafde.
2019-12-18 18:34:55 +01:00
Kovid Goyal
598a147500 Merge branch 'glfw_upstream' of https://github.com/Luflosi/kitty 2019-12-18 22:51:17 +05:30
Luflosi
ba201c4c92 Add curly braces
From upstream: 9486ec0c02.

The upstream commit mainly changes some cmake stuff, which we don't use and only really adds curly braces to `egl_context.c` (and changes some formatting).
2019-12-18 18:12:48 +01:00
Kovid Goyal
5bc7cfaa43 Merge branch 'glfw_upstream' of https://github.com/Luflosi/kitty 2019-12-18 20:33:44 +05:30
Luflosi
2804e1ff81 Cocoa: Update outdated comment
From upstream: b3544ca43e.
2019-12-18 15:41:31 +01:00
Kovid Goyal
ae27d36902 Fix previous merge 2019-12-18 18:42:59 +05:30
Kovid Goyal
08182fbe4d Merge branch 'glfw_upstream' of https://github.com/Luflosi/kitty 2019-12-18 18:36:31 +05:30
Luflosi
778474f436 Wayland: Unset the cursor shape on border exit
From upstream: ef6189f348.
2019-12-18 14:01:29 +01:00
Kovid Goyal
c6698ce305 Merge branch 'comment' of https://github.com/Luflosi/kitty 2019-12-18 18:15:30 +05:30
Luflosi
21bc215313 Make comment more accurate
Since all the time values use `monotonic_t` now, `maximum_wait` is no longer measured in seconds. Instead of replacing seconds with nanoseconds, I removed it because the definition of `monotonic_t` is supposed to be changed easily, in which case this comment would not be accurate again.
2019-12-18 12:54:14 +01:00
Kovid Goyal
88a9cc42d2 Merge branch 'fix-panel' of https://github.com/natnat-mc/kitty 2019-12-18 07:32:25 +05:30
Kovid Goyal
28f33a67cf Merge branch 'fix_oserror' of https://github.com/Luflosi/kitty 2019-12-18 07:30:37 +05:30
Nathan DECHER
6742fabfba fix kitty +kitten panel -c <config> resulting in no config at all 2019-12-18 00:33:40 +01:00
Luflosi
b3806f4533 Fix OSError when failing to create config directory on read-only file system
When calling the completion code, kitty tries to access the config directory and create it if it does not exist. If kitty has no permission to create it, a temporary directory will be created instead. This will fail on a read-only file system because that raises an `OSError` and not a `PermissionError`.
In practice this happens when building kitty on macOS Catalina using Nix because `HOME` is set to `/homeless-shelter` for purity and `/` is a read-only filesystem.
2019-12-17 23:42:31 +01:00
Kovid Goyal
6d5fb4ccc6 Fix docs build warning 2019-12-17 20:44:32 +05:30
Kovid Goyal
2487f18f24 Add a new option active_tab_title_template to specify a different template for active tab titles
Fixes #2198
2019-12-17 20:39:46 +05:30
Kovid Goyal
f59afff1d1 Add a new option tab_bar_background to specify a different color for the tab bar
Fixes #2198
2019-12-17 20:08:33 +05:30
Kovid Goyal
b92f95b092 NSGL: Fix disabling of Retina resolution
From upstream: fa60269245
2019-12-15 20:54:21 +05:30
Kovid Goyal
d68ae01448 Make the active window history available when doing kitty @ ls
Fixes #2194
2019-12-13 18:17:13 +05:30
Kovid Goyal
87eda834d3 Use a token for github 2019-12-12 10:05:11 +05:30
Kovid Goyal
7bf0afa621 Fix #2187 2019-12-08 22:37:47 +05:30
Kovid Goyal
e3e02c7271 Fix #2180 2019-12-01 22:34:56 +05:30
Kovid Goyal
24e17cb7d8 Fix background_opacity incorrectly applying to selected text and reverse video text
Fixes #2177
2019-12-01 15:14:15 +05:30
Kovid Goyal
769998adca Document valid values for pointer_shape_when_grabbed 2019-12-01 08:22:21 +05:30
Kovid Goyal
9b5d88e92d Fix choose item mapping 2019-11-30 17:18:02 +05:30
Kovid Goyal
6d7bebee3a Merge branch 'master' of https://github.com/l-yc/kitty 2019-11-30 16:58:28 +05:30
lyc
1c38654321 Fixed bug in loading libcanberra when falling back on alternative library names 2019-11-30 14:36:22 +08:00
Kovid Goyal
da7a78691f Merge branch 'simplify' of https://github.com/Luflosi/kitty 2019-11-29 09:21:32 +05:30
Luflosi
1eaf7083ef Simplify expression 2019-11-28 23:38:42 +01:00
Kovid Goyal
79a6fcdc5c Oops 2019-11-28 10:12:21 +05:30
Kovid Goyal
90bcbbf426 No need to add index to titles when using hits kitten to choose tab/os_window 2019-11-28 10:11:14 +05:30
Kovid Goyal
41049e2a40 Avoid traceback when cancelling tab selection 2019-11-28 09:42:55 +05:30
Kovid Goyal
c9b8510e9c Also use ascending order for os window selection 2019-11-28 09:23:08 +05:30
Kovid Goyal
d854fc1cd0 Better numbering when asking for tab to detach window to
Fixes #2174
2019-11-28 09:20:38 +05:30
Kovid Goyal
5f7bcae072 hints kitten: Add an option --ascending to control if the hints numbers increase or decrease from top to bottom 2019-11-28 09:20:02 +05:30
Kovid Goyal
652eec3033 Fix a crash/incorrect rendering when detaching a window in some circumstances
Fixes #2173

Ensure all cell related GPU data is resent
2019-11-28 09:01:40 +05:30
Kovid Goyal
a9928ec98a Merge branch 'format' of https://github.com/Luflosi/kitty 2019-11-28 07:24:06 +05:30
Luflosi
e1dfb608ca Format code in kitty/cocoa_window.m a little 2019-11-27 19:56:30 +01:00
Kovid Goyal
2cee3a8809 Better fix for getting clock_gettime() from time.h
Fixes #2169
2019-11-27 22:20:55 +05:30
47 changed files with 406 additions and 557 deletions

View File

@@ -4,6 +4,31 @@ Changelog
|kitty| is a feature full, cross-platform, *fast*, GPU based terminal emulator.
To update |kitty|, :doc:`follow the instructions <binary>`.
0.15.1 [2019-12-21]
--------------------
- Fix a crash/incorrect rendering when detaching a window in some circumstances
(:iss:`2173`)
- hints kitten: Add an option :option:`kitty +kitten hints --ascending` to
control if the hints numbers increase or decrease from top to bottom
- Fix :opt:`background_opacity` incorrectly applying to selected text and
reverse video text (:iss:`2177`)
- Add a new option :opt:`tab_bar_background` to specify a different color
for the tab bar (:iss:`2198`)
- Add a new option :opt:`active_tab_title_template` to specify a different
template for active tab titles (:iss:`2198`)
- Fix lines at the edge of the window at certain windows sizes when drawing
images on a transparent window (:iss:`2079`)
- Fix window not being rendered for the first time until some input has been
received from child process (:iss:`2216`)
0.15.0 [2019-11-27]
--------------------

View File

@@ -163,6 +163,14 @@ prepareForPoll(EventLoopData *eld, monotonic_t timeout) {
return timeout;
}
static inline struct timespec
calc_time(monotonic_t nsec) {
struct timespec result;
result.tv_sec = nsec / (1000LL * 1000LL * 1000LL);
result.tv_nsec = nsec % (1000LL * 1000LL * 1000LL);
return result;
}
int
pollWithTimeout(struct pollfd *fds, nfds_t nfds, monotonic_t timeout) {
struct timespec tv = calc_time(timeout);

View File

@@ -466,9 +466,8 @@ static GLFWapplicationwillfinishlaunchingfun finish_launching_callback = NULL;
// In case we are unbundled, make us a proper UI application
[NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
// Menu bar setup must go between sharedApplication above and
// finishLaunching below, in order to properly emulate the behavior
// of NSApplicationMain
// Menu bar setup must go between sharedApplication and finishLaunching
// in order to properly emulate the behavior of NSApplicationMain
if ([[NSBundle mainBundle] pathForResource:@"MainMenu" ofType:@"nib"])
{
@@ -648,7 +647,6 @@ int _glfwPlatformInit(void)
if (!initializeTIS())
return false;
_glfwInitTimerNS();
_glfwInitJoysticksNS();
_glfwPollMonitorsNS();

View File

@@ -221,8 +221,6 @@ typedef struct _GLFWtimerNS
} _GLFWtimerNS;
void _glfwInitTimerNS(void);
void _glfwPollMonitorsNS(void);
void _glfwSetVideoModeNS(_GLFWmonitor* monitor, const GLFWvidmode* desired);
void _glfwRestoreVideoModeNS(_GLFWmonitor* monitor);

61
glfw/cocoa_time.c vendored
View File

@@ -1,61 +0,0 @@
//========================================================================
// GLFW 3.4 macOS - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2009-2016 Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
// It is fine to use C99 in this file because it will not be built with VS
//========================================================================
#include "internal.h"
#include <mach/mach_time.h>
//////////////////////////////////////////////////////////////////////////
////// GLFW internal API //////
//////////////////////////////////////////////////////////////////////////
// Initialise timer
//
void _glfwInitTimerNS(void)
{
mach_timebase_info_data_t info;
mach_timebase_info(&info);
_glfw.timer.ns.frequency = (unsigned long long)((info.denom * 1e9) / info.numer);
}
//////////////////////////////////////////////////////////////////////////
////// GLFW platform API //////
//////////////////////////////////////////////////////////////////////////
uint64_t _glfwPlatformGetTimerValue(void)
{
return mach_absolute_time();
}
uint64_t _glfwPlatformGetTimerFrequency(void)
{
return _glfw.timer.ns.frequency;
}

View File

@@ -1498,7 +1498,7 @@ void _glfwPlatformDestroyWindow(_GLFWwindow* window)
window->ns.object = nil;
}
void _glfwPlatformSetWindowTitle(_GLFWwindow* window UNUSED, const char *title)
void _glfwPlatformSetWindowTitle(_GLFWwindow* window UNUSED, const char* title)
{
NSString* string = @(title);
[window->ns.object setTitle:string];

31
glfw/egl_context.c vendored
View File

@@ -123,23 +123,24 @@ static bool chooseEGLConfig(const _GLFWctxconfig* ctxconfig,
continue;
#if defined(_GLFW_X11)
XVisualInfo vi = {0};
// Only consider EGLConfigs with associated Visuals
vi.visualid = getEGLConfigAttrib(n, EGL_NATIVE_VISUAL_ID);
if (!vi.visualid)
continue;
if (desired->transparent)
{
int count;
XVisualInfo* vis = XGetVisualInfo(_glfw.x11.display,
VisualIDMask, &vi,
&count);
if (vis)
XVisualInfo vi = {0};
// Only consider EGLConfigs with associated Visuals
vi.visualid = getEGLConfigAttrib(n, EGL_NATIVE_VISUAL_ID);
if (!vi.visualid)
continue;
if (desired->transparent)
{
u->transparent = _glfwIsVisualTransparentX11(vis[0].visual);
XFree(vis);
int count;
XVisualInfo* vis =
XGetVisualInfo(_glfw.x11.display, VisualIDMask, &vi, &count);
if (vis)
{
u->transparent = _glfwIsVisualTransparentX11(vis[0].visual);
XFree(vis);
}
}
}
#endif // _GLFW_X11

75
glfw/glfw3.h vendored
View File

@@ -5227,9 +5227,6 @@ GLFWAPI const char* glfwGetClipboardString(GLFWwindow* window);
* has been set using @ref glfwSetTime it measures time elapsed since GLFW was
* initialized.
*
* This function and @ref glfwSetTime are helper functions on top of @ref
* glfwGetTimerFrequency and @ref glfwGetTimerValue.
*
* The resolution of the timer is system dependent, but is usually on the order
* of a few micro- or nanoseconds. It uses the highest-resolution monotonic
* time source on each supported platform.
@@ -5251,78 +5248,6 @@ GLFWAPI const char* glfwGetClipboardString(GLFWwindow* window);
*/
GLFWAPI monotonic_t glfwGetTime(void);
/*! @brief Sets the GLFW time.
*
* This function sets the current GLFW time, in seconds. The value must be
* a positive finite number less than or equal to 18446744073.0, which is
* approximately 584.5 years.
*
* This function and @ref glfwGetTime are helper functions on top of @ref
* glfwGetTimerFrequency and @ref glfwGetTimerValue.
*
* @param[in] time The new value, in seconds.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_INVALID_VALUE.
*
* @remark The upper limit of GLFW time is calculated as
* floor((2<sup>64</sup> - 1) / 10<sup>9</sup>) and is due to implementations
* storing nanoseconds in 64 bits. The limit may be increased in the future.
*
* @thread_safety This function may be called from any thread. Reading and
* writing of the internal base time is not atomic, so it needs to be
* externally synchronized with calls to @ref glfwGetTime.
*
* @sa @ref time
*
* @since Added in version 2.2.
*
* @ingroup input
*/
GLFWAPI void glfwSetTime(monotonic_t time);
/*! @brief Returns the current value of the raw timer.
*
* This function returns the current value of the raw timer, measured in
* 1&nbsp;/&nbsp;frequency seconds. To get the frequency, call @ref
* glfwGetTimerFrequency.
*
* @return The value of the timer, or zero if an
* [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
*
* @thread_safety This function may be called from any thread.
*
* @sa @ref time
* @sa @ref glfwGetTimerFrequency
*
* @since Added in version 3.2.
*
* @ingroup input
*/
GLFWAPI uint64_t glfwGetTimerValue(void);
/*! @brief Returns the frequency, in Hz, of the raw timer.
*
* This function returns the frequency, in Hz, of the raw timer.
*
* @return The frequency of the timer, in Hz, or zero if an
* [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
*
* @thread_safety This function may be called from any thread.
*
* @sa @ref time
* @sa @ref glfwGetTimerValue
*
* @since Added in version 3.2.
*
* @ingroup input
*/
GLFWAPI uint64_t glfwGetTimerFrequency(void);
/*! @brief Makes the context of the specified window current for the calling
* thread.
*

2
glfw/init.c vendored
View File

@@ -27,7 +27,6 @@
// Please use C89 style variable declarations in this file because VS 2010
//========================================================================
#define MONOTONIC_START_MODULE
#include "internal.h"
#include "mappings.h"
@@ -241,7 +240,6 @@ GLFWAPI int glfwInit(monotonic_t start_time)
_glfwPlatformSetTls(&_glfw.errorSlot, &_glfwMainThreadError);
_glfw.initialized = true;
_glfw.timer.offset = _glfwPlatformGetTimerValue();
glfwDefaultWindowHints();

25
glfw/input.c vendored
View File

@@ -1483,28 +1483,3 @@ GLFWAPI monotonic_t glfwGetTime(void)
_GLFW_REQUIRE_INIT_OR_RETURN(0);
return monotonic();
}
GLFWAPI void glfwSetTime(monotonic_t time)
{
_GLFW_REQUIRE_INIT();
if (time < 0)
{
_glfwInputError(GLFW_INVALID_VALUE, "Invalid time %f", monotonic_t_to_s_double(time));
return;
}
// Do nothing
}
GLFWAPI uint64_t glfwGetTimerValue(void)
{
_GLFW_REQUIRE_INIT_OR_RETURN(0);
return _glfwPlatformGetTimerValue();
}
GLFWAPI uint64_t glfwGetTimerFrequency(void)
{
_GLFW_REQUIRE_INIT_OR_RETURN(0);
return _glfwPlatformGetTimerFrequency();
}

9
glfw/internal.h vendored
View File

@@ -574,12 +574,6 @@ struct _GLFWlibrary
_GLFWtls contextSlot;
_GLFWmutex errorLock;
struct {
uint64_t offset;
// This is defined in the platform's time.h
_GLFW_PLATFORM_LIBRARY_TIMER_STATE;
} timer;
struct {
bool available;
void* handle;
@@ -663,9 +657,6 @@ const char* _glfwPlatformGetPrimarySelectionString(void);
int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode);
void _glfwPlatformUpdateGamepadGUID(char* guid);
uint64_t _glfwPlatformGetTimerValue(void);
uint64_t _glfwPlatformGetTimerFrequency(void);
int _glfwPlatformCreateWindow(_GLFWwindow* window,
const _GLFWwndconfig* wndconfig,
const _GLFWctxconfig* ctxconfig,

10
glfw/monotonic.c vendored Normal file
View File

@@ -0,0 +1,10 @@
/*
* monotonic.c
* Copyright (C) 2019 Kovid Goyal <kovid at kovidgoyal.net>
*
* Distributed under terms of the GPL3 license.
*/
#define _POSIX_C_SOURCE 200809L
#define MONOTONIC_IMPLEMENTATION
#include "../kitty/monotonic.h"

View File

@@ -293,8 +293,7 @@ bool _glfwCreateContextNSGL(_GLFWwindow* window,
forParameter:NSOpenGLContextParameterSurfaceOpacity];
}
if (window->ns.retina)
[window->ns.view setWantsBestResolutionOpenGLSurface:YES];
[window->ns.view setWantsBestResolutionOpenGLSurface:window->ns.retina];
GLint interval = 0;
[window->context.nsgl.object setValues:&interval

2
glfw/null_init.c vendored
View File

@@ -36,7 +36,6 @@
int _glfwPlatformInit(void)
{
_glfwInitTimerPOSIX();
return true;
}
@@ -49,4 +48,3 @@ const char* _glfwPlatformGetVersionString(void)
{
return _GLFW_VERSION_NUMBER " null OSMesa";
}

87
glfw/posix_time.c vendored
View File

@@ -1,87 +0,0 @@
//========================================================================
// GLFW 3.4 POSIX - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2017 Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
// It is fine to use C99 in this file because it will not be built with VS
//========================================================================
#include "internal.h"
#include <sys/time.h>
#include <time.h>
//////////////////////////////////////////////////////////////////////////
////// GLFW internal API //////
//////////////////////////////////////////////////////////////////////////
// Initialise timer
//
void _glfwInitTimerPOSIX(void)
{
#if defined(CLOCK_MONOTONIC)
struct timespec ts;
if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0)
{
_glfw.timer.posix.monotonic = true;
_glfw.timer.posix.frequency = 1000000000;
}
else
#endif
{
_glfw.timer.posix.monotonic = false;
_glfw.timer.posix.frequency = 1000000;
}
}
//////////////////////////////////////////////////////////////////////////
////// GLFW platform API //////
//////////////////////////////////////////////////////////////////////////
uint64_t _glfwPlatformGetTimerValue(void)
{
#if defined(CLOCK_MONOTONIC)
if (_glfw.timer.posix.monotonic)
{
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
return (uint64_t) ts.tv_sec * (uint64_t) 1000000000 + (uint64_t) ts.tv_nsec;
}
else
#endif
{
struct timeval tv;
gettimeofday(&tv, NULL);
return (uint64_t) tv.tv_sec * (uint64_t) 1000000 + (uint64_t) tv.tv_usec;
}
}
uint64_t _glfwPlatformGetTimerFrequency(void)
{
return _glfw.timer.posix.frequency;
}

44
glfw/posix_time.h vendored
View File

@@ -1,44 +0,0 @@
//========================================================================
// GLFW 3.4 POSIX - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2017 Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#define _GLFW_PLATFORM_LIBRARY_TIMER_STATE _GLFWtimerPOSIX posix
#include <stdint.h>
// POSIX-specific global timer data
//
typedef struct _GLFWtimerPOSIX
{
bool monotonic;
uint64_t frequency;
} _GLFWtimerPOSIX;
void _glfwInitTimerPOSIX(void);

View File

@@ -13,7 +13,6 @@
"cocoa_joystick.m",
"cocoa_monitor.m",
"cocoa_window.m",
"cocoa_time.c",
"posix_thread.c",
"nsgl_context.m",
"egl_context.c",
@@ -31,6 +30,7 @@
"input.c",
"monitor.c",
"vulkan.c",
"monotonic.c",
"window.c"
]
},
@@ -38,7 +38,6 @@
"headers": [
"null_platform.h",
"null_joystick.h",
"posix_time.h",
"posix_thread.h",
"osmesa_context.h"
],
@@ -47,7 +46,6 @@
"null_monitor.c",
"null_window.c",
"null_joystick.c",
"posix_time.c",
"posix_thread.c",
"osmesa_context.c"
]
@@ -55,7 +53,6 @@
"wayland": {
"headers": [
"wl_platform.h",
"posix_time.h",
"posix_thread.h",
"xkb_glfw.h",
"dbus_glfw.h",
@@ -81,7 +78,6 @@
"wl_init.c",
"wl_monitor.c",
"wl_window.c",
"posix_time.c",
"posix_thread.c",
"xkb_glfw.c",
"dbus_glfw.c",
@@ -125,7 +121,6 @@
"dbus_glfw.h",
"ibus_glfw.h",
"backend_utils.h",
"posix_time.h",
"posix_thread.h",
"glx_context.h",
"egl_context.h",
@@ -142,7 +137,6 @@
"xkb_glfw.c",
"dbus_glfw.c",
"ibus_glfw.c",
"posix_time.c",
"posix_thread.c",
"glx_context.c",
"egl_context.c",

3
glfw/wl_init.c vendored
View File

@@ -137,6 +137,7 @@ static void pointerHandleLeave(void* data UNUSED,
_glfw.wl.pointerSerial = serial;
_glfw.wl.pointerFocus = NULL;
_glfwInputCursorEnter(window, false);
_glfw.wl.cursorPreviousShape = GLFW_INVALID_CURSOR;
}
static void setCursor(GLFWCursorShape shape)
@@ -192,6 +193,7 @@ static void pointerHandleMotion(void* data UNUSED,
window->wl.cursorPosX = x;
window->wl.cursorPosY = y;
_glfwInputCursorPos(window, x, y);
_glfw.wl.cursorPreviousShape = GLFW_INVALID_CURSOR;
return;
case topDecoration:
if (y < _GLFW_DECORATION_WIDTH)
@@ -764,7 +766,6 @@ int _glfwPlatformInit(void)
}
#endif
_glfwInitTimerPOSIX();
if (!_glfw.wl.wmBase)
{
_glfwInputError(GLFW_PLATFORM_ERROR,

1
glfw/wl_platform.h vendored
View File

@@ -43,7 +43,6 @@ typedef VkResult (APIENTRY *PFN_vkCreateWaylandSurfaceKHR)(VkInstance,const VkWa
typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR)(VkPhysicalDevice,uint32_t,struct wl_display*);
#include "posix_thread.h"
#include "posix_time.h"
#ifdef __linux__
#include "linux_joystick.h"
#else

2
glfw/x11_init.c vendored
View File

@@ -635,8 +635,6 @@ int _glfwPlatformInit(void)
}
#endif
_glfwInitTimerPOSIX();
_glfwPollMonitorsX11();
return true;
}

1
glfw/x11_platform.h vendored
View File

@@ -152,7 +152,6 @@ typedef VkResult (APIENTRY *PFN_vkCreateXcbSurfaceKHR)(VkInstance,const VkXcbSur
typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR)(VkPhysicalDevice,uint32_t,xcb_connection_t*,xcb_visualid_t);
#include "posix_thread.h"
#include "posix_time.h"
#include "glx_context.h"
#include "egl_context.h"
#include "osmesa_context.h"

115
glfw/x11_window.c vendored
View File

@@ -594,7 +594,7 @@ static bool createNativeWindow(_GLFWwindow* window,
{
XChangeProperty(_glfw.x11.display, window->x11.handle,
_glfw.x11.NET_WM_STATE, XA_ATOM, 32,
PropModeReplace, (unsigned char*) &states, count);
PropModeReplace, (unsigned char*) states, count);
}
}
@@ -2146,18 +2146,67 @@ void _glfwPlatformRestoreWindow(_GLFWwindow* window)
void _glfwPlatformMaximizeWindow(_GLFWwindow* window)
{
if (_glfw.x11.NET_WM_STATE &&
_glfw.x11.NET_WM_STATE_MAXIMIZED_VERT &&
_glfw.x11.NET_WM_STATE_MAXIMIZED_HORZ)
if (!_glfw.x11.NET_WM_STATE ||
!_glfw.x11.NET_WM_STATE_MAXIMIZED_VERT ||
!_glfw.x11.NET_WM_STATE_MAXIMIZED_HORZ)
{
return;
}
if (_glfwPlatformWindowVisible(window))
{
sendEventToWM(window,
_glfw.x11.NET_WM_STATE,
_NET_WM_STATE_ADD,
_glfw.x11.NET_WM_STATE_MAXIMIZED_VERT,
_glfw.x11.NET_WM_STATE_MAXIMIZED_HORZ,
1, 0);
XFlush(_glfw.x11.display);
_glfw.x11.NET_WM_STATE,
_NET_WM_STATE_ADD,
_glfw.x11.NET_WM_STATE_MAXIMIZED_VERT,
_glfw.x11.NET_WM_STATE_MAXIMIZED_HORZ,
1, 0);
}
else
{
Atom* states = NULL;
unsigned long count =
_glfwGetWindowPropertyX11(window->x11.handle,
_glfw.x11.NET_WM_STATE,
XA_ATOM,
(unsigned char**) &states);
// NOTE: We don't check for failure as this property may not exist yet
// and that's fine (and we'll create it implicitly with append)
Atom missing[2] =
{
_glfw.x11.NET_WM_STATE_MAXIMIZED_VERT,
_glfw.x11.NET_WM_STATE_MAXIMIZED_HORZ
};
unsigned long missingCount = 2;
for (unsigned long i = 0; i < count; i++)
{
for (unsigned long j = 0; j < missingCount; j++)
{
if (states[i] == missing[j])
{
missing[j] = missing[missingCount - 1];
missingCount--;
}
}
}
if (states)
XFree(states);
if (!missingCount)
return;
XChangeProperty(_glfw.x11.display, window->x11.handle,
_glfw.x11.NET_WM_STATE, XA_ATOM, 32,
PropModeAppend,
(unsigned char*) missing,
missingCount);
}
XFlush(_glfw.x11.display);
}
void _glfwPlatformShowWindow(_GLFWwindow* window)
@@ -2177,6 +2226,9 @@ void _glfwPlatformHideWindow(_GLFWwindow* window)
void _glfwPlatformRequestWindowAttention(_GLFWwindow* window)
{
if (!_glfw.x11.NET_WM_STATE || !_glfw.x11.NET_WM_STATE_DEMANDS_ATTENTION)
return;
sendEventToWM(window,
_glfw.x11.NET_WM_STATE,
_NET_WM_STATE_ADD,
@@ -2382,7 +2434,7 @@ void _glfwPlatformSetWindowFloating(_GLFWwindow* window, bool enabled)
if (_glfwPlatformWindowVisible(window))
{
const Atom action = enabled ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE;
const long action = enabled ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE;
sendEventToWM(window,
_glfw.x11.NET_WM_STATE,
action,
@@ -2391,15 +2443,16 @@ void _glfwPlatformSetWindowFloating(_GLFWwindow* window, bool enabled)
}
else
{
Atom* states;
Atom* states = NULL;
unsigned long i, count;
count = _glfwGetWindowPropertyX11(window->x11.handle,
_glfw.x11.NET_WM_STATE,
XA_ATOM,
(unsigned char**) &states);
if (!states)
return;
// NOTE: We don't check for failure as this property may not exist yet
// and that's fine (and we'll create it implicitly with append)
if (enabled)
{
@@ -2409,32 +2462,36 @@ void _glfwPlatformSetWindowFloating(_GLFWwindow* window, bool enabled)
break;
}
if (i == count)
{
XChangeProperty(_glfw.x11.display, window->x11.handle,
_glfw.x11.NET_WM_STATE, XA_ATOM, 32,
PropModeAppend,
(unsigned char*) &_glfw.x11.NET_WM_STATE_ABOVE,
1);
}
if (i < count)
return;
XChangeProperty(_glfw.x11.display, window->x11.handle,
_glfw.x11.NET_WM_STATE, XA_ATOM, 32,
PropModeAppend,
(unsigned char*) &_glfw.x11.NET_WM_STATE_ABOVE,
1);
}
else
else if (states)
{
for (i = 0; i < count; i++)
{
if (states[i] == _glfw.x11.NET_WM_STATE_ABOVE)
{
states[i] = states[count - 1];
count--;
}
break;
}
if (i == count)
return;
states[i] = states[count - 1];
count--;
XChangeProperty(_glfw.x11.display, window->x11.handle,
_glfw.x11.NET_WM_STATE, XA_ATOM, 32,
PropModeReplace, (unsigned char*) &states, count);
PropModeReplace, (unsigned char*) states, count);
}
XFree(states);
if (states)
XFree(states);
}
XFlush(_glfw.x11.display);

View File

@@ -324,6 +324,10 @@ def parse_input(text):
def load_custom_processor(customize_processing):
if customize_processing.startswith('::import::'):
import importlib
m = importlib.import_module(customize_processing[len('::import::'):])
return {k: getattr(m, k) for k in dir(m)}
from kitty.constants import config_dir
customize_processing = os.path.expandvars(os.path.expanduser(customize_processing))
if os.path.isabs(customize_processing):
@@ -355,7 +359,10 @@ def run(args, text, extra_cli_args=()):
largest_index = all_marks[-1].index
offset = max(0, args.hints_offset)
for m in all_marks:
m.index = largest_index - m.index + offset
if args.ascending:
m.index += offset
else:
m.index = largest_index - m.index + offset
index_map = {m.index: m for m in all_marks}
except Exception:
import traceback
@@ -451,6 +458,11 @@ unless you specify the hints offset as zero the first match will be highlighted
the second character you specify.
--ascending
type=bool-set
Have the hints increase from top to bottom instead of decreasing from top to bottom.
--customize-processing
Name of a python file in the kitty config directory which will be imported to provide
custom implementations for pattern finding and performing actions

View File

@@ -130,8 +130,8 @@ def main(sys_args):
if not items:
raise SystemExit('You must specify the program to run')
sys.argv = ['kitty']
if args.config:
sys.argv.append('--config={}'.format(args.config))
for config in args.config:
sys.argv.append('--config={}'.format(config))
for override in args.override:
sys.argv.append('--override={}'.format(override))
sys.argv.extend(items)

View File

@@ -1191,23 +1191,26 @@ class Boss:
'Choose a tab to move the window to',
''
]
fmt = ': {1}'
tab_id_map = {}
current_tab = self.active_tab
for i, tab in enumerate(self.all_tabs):
if tab is not current_tab:
tab_id_map[i + 1] = tab.id
lines.append('{} {}'.format(i + 1, tab.title))
tab_id_map[len(tab_id_map)] = tab.id
lines.append(fmt.format(i + 1, tab.title))
new_idx = len(tab_id_map) + 1
tab_id_map[new_idx] = 'new'
lines.append('{} {}'.format(new_idx, 'New tab'))
tab_id_map[new_idx - 1] = 'new'
lines.append(fmt.format(new_idx, 'New tab'))
new_idx = len(tab_id_map) + 1
tab_id_map[new_idx] = None
lines.append('{} {}'.format(new_idx, 'New OS Window'))
tab_id_map[new_idx - 1] = None
lines.append(fmt.format(new_idx, 'New OS Window'))
def done(data, target_window_id, self):
done.tab_id = tab_id_map[int(data['match'][0].partition(' ')[0])]
done.tab_id = tab_id_map[int(data['groupdicts'][0]['index'])]
def done2(target_window_id, self):
if not hasattr(done, 'tab_id'):
return
tab_id = done.tab_id
target_window = None
for w in self.all_windows:
@@ -1220,8 +1223,11 @@ class Boss:
self._move_window_to(window=target_window, target_tab_id=tab_id)
self._run_kitten(
'hints', args=('--type=regex', r'--regex=(?m)^\d+ .+$',),
input_data='\r\n'.join(lines).encode('utf-8'), custom_callback=done, action_on_removal=done2)
'hints', args=(
'--ascending', '--customize-processing=::import::kitty.choose_entry',
r'--regex=(?m)^:\s+.+$',
), input_data='\r\n'.join(lines).encode('utf-8'), custom_callback=done, action_on_removal=done2
)
def detach_tab(self, *args):
if not args or args[0] == 'new':
@@ -1231,21 +1237,24 @@ class Boss:
'Choose an OS window to move the tab to',
''
]
fmt = ': {1}'
os_window_id_map = {}
current_os_window = getattr(self.active_tab, 'os_window_id', 0)
for i, osw in enumerate(self.os_window_map):
tm = self.os_window_map[osw]
if current_os_window != osw and tm.active_tab and tm.active_tab:
os_window_id_map[i + 1] = osw
lines.append('{} {}'.format(i + 1, tm.active_tab.title))
os_window_id_map[len(os_window_id_map)] = osw
lines.append(fmt.format(i + 1, tm.active_tab.title))
new_idx = len(os_window_id_map) + 1
os_window_id_map[new_idx] = None
lines.append('{} {}'.format(new_idx, 'New OS Window'))
os_window_id_map[new_idx - 1] = None
lines.append(fmt.format(new_idx, 'New OS Window'))
def done(data, target_window_id, self):
done.os_window_id = os_window_id_map[int(data['match'][0].partition(' ')[0])]
done.os_window_id = os_window_id_map[int(data['groupdicts'][0]['index'])]
def done2(target_window_id, self):
if not hasattr(done, 'os_window_id'):
return
os_window_id = done.os_window_id
target_tab = self.active_tab
for w in self.all_windows:
@@ -1257,5 +1266,8 @@ class Boss:
self._move_tab_to(tab=target_tab, target_os_window_id=os_window_id)
self._run_kitten(
'hints', args=('--type=regex', r'--regex=(?m)^\d+ .+$',),
input_data='\r\n'.join(lines).encode('utf-8'), custom_callback=done, action_on_removal=done2)
'hints', args=(
'--ascending', '--customize-processing=::import::kitty.choose_entry',
r'--regex=(?m)^:\s+.+$',
), input_data='\r\n'.join(lines).encode('utf-8'), custom_callback=done, action_on_removal=done2
)

View File

@@ -151,7 +151,8 @@ void main() {
// set cell color indices {{{
uvec2 default_colors = uvec2(default_fg, default_bg);
uint text_attrs = sprite_coords[3];
uint is_inverted = ((text_attrs >> REVERSE_SHIFT) & ONE) + inverted;
uint is_reversed = ((text_attrs >> REVERSE_SHIFT) & ONE);
uint is_inverted = is_reversed + inverted;
int fg_index = fg_index_map[is_inverted];
int bg_index = 1 - fg_index;
float cell_has_cursor = is_cursor(c, r);
@@ -200,21 +201,28 @@ void main() {
background = bg;
#endif
#if defined(TRANSPARENT) && !defined(SPECIAL)
// If the background color is default, set its opacity to background_opacity, otherwise it should be opaque
bg_alpha = step(0.5, float(colors[bg_index] & BYTE_MASK));
// Cursor must not be affected by background_opacity
bg_alpha = mix(bg_alpha, 1.0, cell_has_block_cursor);
#if defined(TRANSPARENT)
// Set bg_alpha to background_opacity on cells that have the default background color
// Which means they must not have a block cursor or a selection or reverse video
// On other cells it should be 1. For the SPECIAL program it should be 1 on cells with
// selections/block cursor and 0 everywhere else.
float is_special_cell = cell_has_block_cursor + float(is_selected & ONE);
#ifndef SPECIAL
is_special_cell += float(colors[bg_index] & BYTE_MASK) + float(is_reversed);
#endif
bg_alpha = step(0.5, is_special_cell);
#ifndef SPECIAL
bg_alpha = bg_alpha + (1.0f - bg_alpha) * background_opacity;
#endif
#endif
#if defined(SPECIAL) || defined(SIMPLE)
// Selection and cursor
bg = choose_color(float(is_selected & ONE), color_to_vec(highlight_bg), bg);
background = choose_color(cell_has_block_cursor, color_to_vec(cursor_color), bg);
#ifdef SPECIAL
// bg_alpha should be 1 if cursor/selection otherwise 0
bg_alpha = mix(0.0, 1.0, step(0.5, float(is_selected & ONE) + cell_has_block_cursor));
#if !defined(TRANSPARENT) && defined(SPECIAL)
float is_special_cell = cell_has_block_cursor + float(is_selected & ONE);
bg_alpha = step(0.5, is_special_cell);
#endif
#endif

View File

@@ -109,7 +109,7 @@ static size_t reaped_pids_count = 0;
#define INCREF_CHILD(x) XREF_CHILD(x, Py_INCREF)
#define DECREF_CHILD(x) XREF_CHILD(x, Py_DECREF)
// The max time (in secs) to wait for events from the window system
// The max time to wait for events from the window system
// before ticking over the main loop. Negative values mean wait forever.
static monotonic_t maximum_wait = -1;
@@ -649,7 +649,7 @@ static inline void
render(monotonic_t now, bool input_read) {
EVDBG("input_read: %d", input_read);
static monotonic_t last_render_at = MONOTONIC_T_MIN;
monotonic_t time_since_last_render = now - last_render_at;
monotonic_t time_since_last_render = last_render_at == MONOTONIC_T_MIN ? OPT(repaint_delay) : now - last_render_at;
if (!input_read && time_since_last_render < OPT(repaint_delay)) {
set_maximum_wait(OPT(repaint_delay) - time_since_last_render);
return;
@@ -916,10 +916,14 @@ process_global_state(void *data) {
ChildMonitor *self = data;
maximum_wait = -1;
bool state_check_timer_enabled = false;
bool input_read = false;
monotonic_t now = monotonic();
if (global_state.has_pending_resizes) process_pending_resizes(now);
bool input_read = parse_input(self);
if (global_state.has_pending_resizes) {
process_pending_resizes(now);
input_read = true;
}
if (parse_input(self)) input_read = true;
render(now, input_read);
#ifdef __APPLE__
if (cocoa_pending_actions) {

12
kitty/choose_entry.py Normal file
View File

@@ -0,0 +1,12 @@
#!/usr/bin/env python
# vim:fileencoding=utf-8
# License: GPLv3 Copyright: 2019, Kovid Goyal <kovid at kovidgoyal.net>
import re
def mark(text, args, Mark, extra_cli_args, *a):
for idx, m in enumerate(re.finditer(args.regex, text)):
start, end = m.span()
mark_text = text[start:end].replace('\n', '').replace('\0', '')
yield Mark(idx, start, end, mark_text, {'index': idx})

View File

@@ -73,12 +73,12 @@ find_app_name(void) {
@implementation GlobalMenuTarget
- (void) show_preferences : (id)sender {
- (void)show_preferences:(id)sender {
(void)sender;
set_cocoa_pending_action(PREFERENCES_WINDOW, NULL);
}
- (void) new_os_window : (id)sender {
- (void)new_os_window:(id)sender {
(void)sender;
set_cocoa_pending_action(NEW_OS_WINDOW, NULL);
}
@@ -118,9 +118,10 @@ get_dock_menu(id self UNUSED, SEL _cmd UNUSED, NSApplication *sender UNUSED) {
if (!dockMenu) {
GlobalMenuTarget *global_menu_target = [GlobalMenuTarget shared_instance];
dockMenu = [[NSMenu alloc] init];
NSMenuItem *newWindowItem = [dockMenu addItemWithTitle:@"New OS window"
action:@selector(new_os_window:)
keyEquivalent:@""];
NSMenuItem *newWindowItem =
[dockMenu addItemWithTitle:@"New OS window"
action:@selector(new_os_window:)
keyEquivalent:@""];
[newWindowItem setTarget:global_menu_target];
}
return dockMenu;
@@ -238,13 +239,15 @@ cocoa_create_global_menu(void) {
[NSApp setMainMenu:bar];
NSMenuItem* appMenuItem =
[bar addItemWithTitle:@"" action:NULL keyEquivalent:@""];
[bar addItemWithTitle:@""
action:NULL
keyEquivalent:@""];
NSMenu* appMenu = [[NSMenu alloc] init];
[appMenuItem setSubmenu:appMenu];
[appMenu addItemWithTitle:[NSString stringWithFormat:@"About %@", app_name]
action:@selector(orderFrontStandardAboutPanel:)
keyEquivalent:@""];
keyEquivalent:@""];
[appMenu addItem:[NSMenuItem separatorItem]];
NSMenuItem* preferences_menu_item = [[NSMenuItem alloc] initWithTitle:@"Preferences..." action:@selector(show_preferences:) keyEquivalent:@","], *new_os_window_menu_item = NULL;
[preferences_menu_item setTarget:global_menu_target];
@@ -263,8 +266,8 @@ cocoa_create_global_menu(void) {
action:@selector(hide:)
keyEquivalent:@"h"];
[[appMenu addItemWithTitle:@"Hide Others"
action:@selector(hideOtherApplications:)
keyEquivalent:@"h"]
action:@selector(hideOtherApplications:)
keyEquivalent:@"h"]
setKeyEquivalentModifierMask:NSEventModifierFlagOption | NSEventModifierFlagCommand];
[appMenu addItemWithTitle:@"Show All"
action:@selector(unhideAllApplications:)
@@ -274,19 +277,21 @@ cocoa_create_global_menu(void) {
NSMenu* servicesMenu = [[NSMenu alloc] init];
[NSApp setServicesMenu:servicesMenu];
[[appMenu addItemWithTitle:@"Services"
action:NULL
keyEquivalent:@""] setSubmenu:servicesMenu];
action:NULL
keyEquivalent:@""] setSubmenu:servicesMenu];
[servicesMenu release];
[appMenu addItem:[NSMenuItem separatorItem]];
[appMenu addItemWithTitle:[NSString stringWithFormat:@"Quit %@", app_name]
action:@selector(terminate:)
keyEquivalent:@"q"];
keyEquivalent:@"q"];
[appMenu release];
NSMenuItem* windowMenuItem =
[bar addItemWithTitle:@"" action:NULL keyEquivalent:@""];
[bar addItemWithTitle:@""
action:NULL
keyEquivalent:@""];
NSMenu* windowMenu = [[NSMenu alloc] initWithTitle:@"Window"];
[windowMenuItem setSubmenu:windowMenu];
@@ -316,10 +321,10 @@ cocoa_create_global_menu(void) {
[bar release];
class_addMethod(
object_getClass([NSApp delegate]),
@selector(applicationDockMenu:),
(IMP)get_dock_menu,
"@@:@");
object_getClass([NSApp delegate]),
@selector(applicationDockMenu:),
(IMP)get_dock_menu,
"@@:@");
[NSApp setServicesProvider:[[[ServiceProvider alloc] init] autorelease]];
@@ -363,7 +368,7 @@ cocoa_make_window_resizable(void *w, bool resizable) {
bool
cocoa_alt_option_key_pressed(NSUInteger flags) {
NSUInteger q = (OPT(macos_option_as_alt) == 1) ? NSRightAlternateKeyMask : NSLeftAlternateKeyMask;
return ((q & flags) == q) ? true : false;
return (q & flags) == q;
}
void

View File

@@ -479,6 +479,7 @@ moving the mouse around'''))
o('pointer_shape_when_grabbed', 'arrow', option_type=choices('arrow', 'beam', 'hand'), long_text=('''
The shape of the mouse pointer when the program running in the terminal grabs the mouse.
Valid values are: :code:`arrow`, :code:`beam` and :code:`hand`
'''))
# }}}
@@ -715,12 +716,20 @@ entries to this list.
o('tab_separator', '"{}"'.format(default_tab_separator), option_type=tab_separator, long_text=_('''
The separator between tabs in the tab bar when using :code:`separator` as the :opt:`tab_bar_style`.'''))
def active_tab_title_template(x):
return None if x == 'none' else x
o('tab_title_template', '{title}', long_text=_('''
A template to render the tab title. The default just renders
the title. If you wish to include the tab-index as well,
use something like: :code:`{index}: {title}`. Useful
if you have shortcuts mapped for :code:`goto_tab N`.
'''))
o('active_tab_title_template', 'none', option_type=active_tab_title_template, long_text=_('''
Template to use for active tabs, if not specified falls back
to :opt:`tab_title_template`.'''))
o('active_tab_foreground', '#000', option_type=to_color, long_text=_('''
Tab bar colors and styles'''))
@@ -729,6 +738,8 @@ o('active_tab_font_style', 'bold-italic', option_type=tab_font_style)
o('inactive_tab_foreground', '#444', option_type=to_color)
o('inactive_tab_background', '#999', option_type=to_color)
o('inactive_tab_font_style', 'normal', option_type=tab_font_style)
o('tab_bar_background', 'none', option_type=to_color_or_none, long_text=_('''
Background color for the tab bar. Defaults to using the terminal background color.'''))
# }}}

View File

@@ -5,11 +5,12 @@
import os
import pwd
import sys
import errno
from collections import namedtuple
from contextlib import suppress
appname = 'kitty'
version = (0, 15, 0)
version = (0, 15, 1)
str_version = '.'.join(map(str, version))
_plat = sys.platform.lower()
is_macos = 'darwin' in _plat
@@ -57,13 +58,7 @@ def _get_config_dir():
if os.access(q, os.W_OK) and os.path.exists(os.path.join(q, 'kitty.conf')):
return q
candidate = os.path.abspath(os.path.expanduser(os.environ.get('XDG_CONFIG_HOME') or '~/.config'))
ans = os.path.join(candidate, appname)
try:
os.makedirs(ans, exist_ok=True)
except FileExistsError:
raise SystemExit('A file {} already exists. It must be a directory, not a file.'.format(ans))
except PermissionError:
def make_tmp_conf():
import tempfile
import atexit
ans = tempfile.mkdtemp(prefix='kitty-conf-')
@@ -73,6 +68,19 @@ def _get_config_dir():
with suppress(Exception):
shutil.rmtree(ans)
atexit.register(cleanup)
candidate = os.path.abspath(os.path.expanduser(os.environ.get('XDG_CONFIG_HOME') or '~/.config'))
ans = os.path.join(candidate, appname)
try:
os.makedirs(ans, exist_ok=True)
except FileExistsError:
raise SystemExit('A file {} already exists. It must be a directory, not a file.'.format(ans))
except PermissionError:
make_tmp_conf()
except OSError as err:
if err.errno != errno.EROFS: # Error other than read-only file system
raise
make_tmp_conf()
return ans

View File

@@ -5,7 +5,6 @@
* Distributed under terms of the GPL3 license.
*/
#define MONOTONIC_START_MODULE
#ifdef __APPLE__
// Needed for _CS_DARWIN_USER_CACHE_DIR
#define _DARWIN_C_SOURCE

View File

@@ -113,8 +113,8 @@ load_libcanberra(void) {
if (done) return;
done = true;
libcanberra_handle = dlopen(libname, RTLD_LAZY);
if (libcanberra_handle == NULL) libsn_handle = dlopen(libname2, RTLD_LAZY);
if (libcanberra_handle == NULL) libsn_handle = dlopen(libname3, RTLD_LAZY);
if (libcanberra_handle == NULL) libcanberra_handle = dlopen(libname2, RTLD_LAZY);
if (libcanberra_handle == NULL) libcanberra_handle = dlopen(libname3, RTLD_LAZY);
if (libcanberra_handle == NULL) {
fprintf(stderr, "Failed to load %s, cannot play beep sound, with error: %s\n", libname, dlerror());
return;

38
kitty/gl-wrapper.h generated
View File

@@ -1,5 +1,5 @@
/**
* Loader generated by glad 2.0.0-beta on Sun Jul 7 20:35:06 2019
* Loader generated by glad 2.0.0-beta on Fri Dec 20 14:59:05 2019
*
* Generator: C/C++
* Specification: gl
@@ -9,19 +9,19 @@
* - gl:core=3.3
*
* Options:
* - ALIAS = False
* - DEBUG = True
* - HEADER_ONLY = True
* - LOADER = False
* - MX = False
* - MX_GLOBAL = False
* - ON_DEMAND = False
* - LOADER = False
* - ALIAS = False
* - HEADER_ONLY = True
* - DEBUG = True
* - MX = False
*
* Commandline:
* --api='gl:core=3.3' --extensions='GL_ARB_copy_image,GL_ARB_multisample,GL_ARB_robustness,GL_ARB_texture_storage,GL_KHR_debug' c --header-only --debug
* --api='gl:core=3.3' --extensions='GL_ARB_copy_image,GL_ARB_multisample,GL_ARB_robustness,GL_ARB_texture_storage,GL_KHR_debug' c --debug --header-only
*
* Online:
* http://glad.sh/#api=gl%3Acore%3D3.3&extensions=GL_ARB_copy_image%2CGL_ARB_multisample%2CGL_ARB_robustness%2CGL_ARB_texture_storage%2CGL_KHR_debug&generator=c&options=HEADER_ONLY%2CDEBUG
* http://glad.sh/#api=gl%3Acore%3D3.3&extensions=GL_ARB_copy_image%2CGL_ARB_multisample%2CGL_ARB_robustness%2CGL_ARB_texture_storage%2CGL_KHR_debug&generator=c&options=DEBUG%2CHEADER_ONLY
*
*/
#ifndef GLAD_GL_H_
@@ -31,8 +31,8 @@
#endif
#define __gl_h_ 1
#define GLAD_GL
#define GLAD_OPTION_GL_HEADER_ONLY
#define GLAD_OPTION_GL_DEBUG
#define GLAD_OPTION_GL_HEADER_ONLY
#ifdef __cplusplus
extern "C" {
#endif
@@ -1324,13 +1324,13 @@ typedef khronos_uint64_t GLuint64EXT;
typedef struct __GLsync *GLsync;
struct _cl_context;
struct _cl_event;
typedef void ( *GLDEBUGPROC)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam);
typedef void ( *GLDEBUGPROCARB)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam);
typedef void ( *GLDEBUGPROCKHR)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam);
typedef void ( *GLDEBUGPROCAMD)(GLuint id,GLenum category,GLenum severity,GLsizei length,const GLchar *message,void *userParam);
typedef void (GLAD_API_PTR *GLDEBUGPROC)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam);
typedef void (GLAD_API_PTR *GLDEBUGPROCARB)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam);
typedef void (GLAD_API_PTR *GLDEBUGPROCKHR)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam);
typedef void (GLAD_API_PTR *GLDEBUGPROCAMD)(GLuint id,GLenum category,GLenum severity,GLsizei length,const GLchar *message,void *userParam);
typedef unsigned short GLhalfNV;
typedef GLintptr GLvdpauSurfaceNV;
typedef void ( *GLVULKANPROCNV)(void);
typedef void (GLAD_API_PTR *GLVULKANPROCNV)(void);
#define GL_VERSION_1_0 1
GLAD_API_CALL int GLAD_GL_VERSION_1_0;
#define GL_VERSION_1_1 1
@@ -1522,7 +1522,7 @@ typedef void (GLAD_API_PTR *PFNGLGETSHADERSOURCEPROC)(GLuint shader, GLsizei buf
typedef void (GLAD_API_PTR *PFNGLGETSHADERIVPROC)(GLuint shader, GLenum pname, GLint * params);
typedef const GLubyte * (GLAD_API_PTR *PFNGLGETSTRINGPROC)(GLenum name);
typedef const GLubyte * (GLAD_API_PTR *PFNGLGETSTRINGIPROC)(GLenum name, GLuint index);
typedef void (GLAD_API_PTR *PFNGLGETSYNCIVPROC)(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei * length, GLint * values);
typedef void (GLAD_API_PTR *PFNGLGETSYNCIVPROC)(GLsync sync, GLenum pname, GLsizei count, GLsizei * length, GLint * values);
typedef void (GLAD_API_PTR *PFNGLGETTEXIMAGEPROC)(GLenum target, GLint level, GLenum format, GLenum type, void * pixels);
typedef void (GLAD_API_PTR *PFNGLGETTEXLEVELPARAMETERFVPROC)(GLenum target, GLint level, GLenum pname, GLfloat * params);
typedef void (GLAD_API_PTR *PFNGLGETTEXLEVELPARAMETERIVPROC)(GLenum target, GLint level, GLenum pname, GLint * params);
@@ -4037,10 +4037,10 @@ static const GLubyte * GLAD_API_PTR glad_debug_impl_glGetStringi(GLenum name, GL
}
PFNGLGETSTRINGIPROC glad_debug_glGetStringi = glad_debug_impl_glGetStringi;
PFNGLGETSYNCIVPROC glad_glGetSynciv = NULL;
static void GLAD_API_PTR glad_debug_impl_glGetSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei * length, GLint * values) {
_pre_call_gl_callback("glGetSynciv", (GLADapiproc) glad_glGetSynciv, 5, sync, pname, bufSize, length, values);
glad_glGetSynciv(sync, pname, bufSize, length, values);
_post_call_gl_callback(NULL, "glGetSynciv", (GLADapiproc) glad_glGetSynciv, 5, sync, pname, bufSize, length, values);
static void GLAD_API_PTR glad_debug_impl_glGetSynciv(GLsync sync, GLenum pname, GLsizei count, GLsizei * length, GLint * values) {
_pre_call_gl_callback("glGetSynciv", (GLADapiproc) glad_glGetSynciv, 5, sync, pname, count, length, values);
glad_glGetSynciv(sync, pname, count, length, values);
_post_call_gl_callback(NULL, "glGetSynciv", (GLADapiproc) glad_glGetSynciv, 5, sync, pname, count, length, values);
}
PFNGLGETSYNCIVPROC glad_debug_glGetSynciv = glad_debug_impl_glGetSynciv;
PFNGLGETTEXIMAGEPROC glad_glGetTexImage = NULL;

9
kitty/glfw-wrapper.c generated
View File

@@ -344,15 +344,6 @@ load_glfw(const char* path) {
*(void **) (&glfwGetTime_impl) = dlsym(handle, "glfwGetTime");
if (glfwGetTime_impl == NULL) fail("Failed to load glfw function glfwGetTime with error: %s", dlerror());
*(void **) (&glfwSetTime_impl) = dlsym(handle, "glfwSetTime");
if (glfwSetTime_impl == NULL) fail("Failed to load glfw function glfwSetTime with error: %s", dlerror());
*(void **) (&glfwGetTimerValue_impl) = dlsym(handle, "glfwGetTimerValue");
if (glfwGetTimerValue_impl == NULL) fail("Failed to load glfw function glfwGetTimerValue with error: %s", dlerror());
*(void **) (&glfwGetTimerFrequency_impl) = dlsym(handle, "glfwGetTimerFrequency");
if (glfwGetTimerFrequency_impl == NULL) fail("Failed to load glfw function glfwGetTimerFrequency with error: %s", dlerror());
*(void **) (&glfwMakeContextCurrent_impl) = dlsym(handle, "glfwMakeContextCurrent");
if (glfwMakeContextCurrent_impl == NULL) fail("Failed to load glfw function glfwMakeContextCurrent with error: %s", dlerror());

12
kitty/glfw-wrapper.h generated
View File

@@ -2022,18 +2022,6 @@ typedef monotonic_t (*glfwGetTime_func)(void);
glfwGetTime_func glfwGetTime_impl;
#define glfwGetTime glfwGetTime_impl
typedef void (*glfwSetTime_func)(monotonic_t);
glfwSetTime_func glfwSetTime_impl;
#define glfwSetTime glfwSetTime_impl
typedef uint64_t (*glfwGetTimerValue_func)(void);
glfwGetTimerValue_func glfwGetTimerValue_impl;
#define glfwGetTimerValue glfwGetTimerValue_impl
typedef uint64_t (*glfwGetTimerFrequency_func)(void);
glfwGetTimerFrequency_func glfwGetTimerFrequency_impl;
#define glfwGetTimerFrequency glfwGetTimerFrequency_impl
typedef void (*glfwMakeContextCurrent_func)(GLFWwindow*);
glfwMakeContextCurrent_func glfwMakeContextCurrent_impl;
#define glfwMakeContextCurrent glfwMakeContextCurrent_impl

View File

@@ -18,7 +18,7 @@ from .constants import (
is_wayland, kitty_exe, logo_data_file
)
from .fast_data_types import (
GLFW_IBEAM_CURSOR, GLFW_MOD_SUPER, create_os_window, free_font_data,
GLFW_IBEAM_CURSOR, create_os_window, free_font_data,
glfw_init, glfw_terminate, load_png_data, set_custom_cursor,
set_default_window_icon, set_options
)
@@ -95,10 +95,6 @@ def init_glfw(opts, debug_keyboard=False):
return glfw_module
def prefer_cmd_shortcuts(x):
return x[0] == GLFW_MOD_SUPER
def get_new_os_window_trigger(opts):
new_os_window_trigger = None
if is_macos:
@@ -108,8 +104,8 @@ def get_new_os_window_trigger(opts):
new_os_window_shortcuts.append(k)
if new_os_window_shortcuts:
from .fast_data_types import cocoa_set_new_window_trigger
new_os_window_shortcuts.sort(key=prefer_cmd_shortcuts, reverse=True)
for candidate in new_os_window_shortcuts:
# Reverse list so that later defined keyboard shortcuts take priority over earlier defined ones
for candidate in reversed(new_os_window_shortcuts):
if cocoa_set_new_window_trigger(candidate[0], candidate[2]):
new_os_window_trigger = candidate
break

10
kitty/monotonic.c Normal file
View File

@@ -0,0 +1,10 @@
/*
* monotonic.c
* Copyright (C) 2019 Kovid Goyal <kovid at kovidgoyal.net>
*
* Distributed under terms of the GPL3 license.
*/
#define _POSIX_C_SOURCE 200809L
#define MONOTONIC_IMPLEMENTATION
#include "monotonic.h"

View File

@@ -9,66 +9,68 @@
#include <stdint.h>
#include <time.h>
#define MONOTONIC_T_MAX INT64_MAX
#define MONOTONIC_T_MIN INT64_MIN
#define MONOTONIC_T_1e6 1000000ll
#define MONOTONIC_T_1e9 1000000000ll
typedef int64_t monotonic_t;
static inline monotonic_t calc_nano_time(struct timespec time) {
int64_t result = (monotonic_t)time.tv_sec;
result *= 1000LL;
result *= 1000LL;
result *= 1000LL;
result += (monotonic_t)time.tv_nsec;
return result;
static inline monotonic_t
s_double_to_monotonic_t(double time) {
return (monotonic_t)(time * 1e9);
}
static inline struct timespec calc_time(monotonic_t nsec) {
struct timespec result;
result.tv_sec = nsec / (1000LL * 1000LL * 1000LL);
result.tv_nsec = nsec % (1000LL * 1000LL * 1000LL);
return result;
static inline monotonic_t
ms_double_to_monotonic_t(double time) {
return (monotonic_t)(time * 1e6);
}
static inline monotonic_t s_double_to_monotonic_t(double time) {
time *= 1000.0;
time *= 1000.0;
time *= 1000.0;
return (monotonic_t)time;
static inline monotonic_t
s_to_monotonic_t(monotonic_t time) {
return time * MONOTONIC_T_1e9;
}
static inline monotonic_t ms_double_to_monotonic_t(double time) {
time *= 1000.0;
time *= 1000.0;
return (monotonic_t)time;
static inline monotonic_t
ms_to_monotonic_t(monotonic_t time) {
return time * MONOTONIC_T_1e6;
}
static inline monotonic_t s_to_monotonic_t(monotonic_t time) {
return time * 1000ll * 1000ll * 1000ll;
static inline int
monotonic_t_to_ms(monotonic_t time) {
return (int)(time / MONOTONIC_T_1e6);
}
static inline monotonic_t ms_to_monotonic_t(monotonic_t time) {
return time * 1000ll * 1000ll;
static inline double
monotonic_t_to_s_double(monotonic_t time) {
return ((double)time) / 1e9;
}
static inline int monotonic_t_to_ms(monotonic_t time) {
return (int)(time / 1000ll / 1000ll);
}
static inline double monotonic_t_to_s_double(monotonic_t time) {
return (double)time / 1000.0 / 1000.0 / 1000.0;
}
#ifdef MONOTONIC_START_MODULE
monotonic_t monotonic_start_time = 0;
#else
extern monotonic_t monotonic_start_time;
#endif
extern monotonic_t monotonic_(void);
static inline monotonic_t
monotonic(void) {
return monotonic_() - monotonic_start_time;
}
static inline monotonic_t monotonic_(void) {
static inline void
init_monotonic(void) {
monotonic_start_time = monotonic_();
}
#ifdef MONOTONIC_IMPLEMENTATION
#include <time.h>
monotonic_t monotonic_start_time = 0;
static inline monotonic_t
calc_nano_time(struct timespec time) {
return ((monotonic_t)time.tv_sec * MONOTONIC_T_1e9) + (monotonic_t)time.tv_nsec;
}
monotonic_t
monotonic_(void) {
struct timespec ts = {0};
#ifdef CLOCK_HIGHRES
clock_gettime(CLOCK_HIGHRES, &ts);
@@ -79,11 +81,4 @@ static inline monotonic_t monotonic_(void) {
#endif
return calc_nano_time(ts);
}
static inline monotonic_t monotonic(void) {
return monotonic_() - monotonic_start_time;
}
static inline void init_monotonic(void) {
monotonic_start_time = monotonic_();
}
#endif

View File

@@ -76,7 +76,7 @@ typedef struct {
Selection selection;
SelectionBoundary last_rendered_selection_start, last_rendered_selection_end, last_rendered_url_start, last_rendered_url_end;
Selection url_range;
bool use_latin1, selection_updated_once, is_dirty, scroll_changed;
bool use_latin1, selection_updated_once, is_dirty, scroll_changed, reload_all_gpu_data;
Cursor *cursor;
SavepointBuffer main_savepoints, alt_savepoints;
SavemodesBuffer modes_savepoints;

View File

@@ -239,7 +239,7 @@ cell_update_uniform_block(ssize_t vao_idx, Screen *screen, int uniform_buffer, G
// Send the uniform data
rd = (struct CellRenderData*)map_vao_buffer(vao_idx, uniform_buffer, GL_WRITE_ONLY);
if (UNLIKELY(screen->color_profile->dirty)) {
if (UNLIKELY(screen->color_profile->dirty || screen->reload_all_gpu_data)) {
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
@@ -295,7 +295,7 @@ cell_prepare_to_render(ssize_t vao_idx, ssize_t gvao_idx, Screen *screen, GLfloa
|| screen->cursor->y != screen->last_rendered_cursor_y;
bool disable_ligatures = screen->disable_ligatures == DISABLE_LIGATURES_CURSOR;
if (screen->scroll_changed || screen->is_dirty || (disable_ligatures && cursor_pos_changed)) {
if (screen->reload_all_gpu_data || screen->scroll_changed || screen->is_dirty || (disable_ligatures && cursor_pos_changed)) {
sz = sizeof(GPUCell) * screen->lines * screen->columns;
address = alloc_and_map_vao_buffer(vao_idx, sz, cell_data_buffer, GL_STREAM_DRAW, GL_WRITE_ONLY);
screen_update_cell_data(screen, address, fonts_data, disable_ligatures && cursor_pos_changed);
@@ -308,7 +308,7 @@ cell_prepare_to_render(ssize_t vao_idx, ssize_t gvao_idx, Screen *screen, GLfloa
screen->last_rendered_cursor_y = screen->cursor->y;
}
if (screen_is_selection_dirty(screen)) {
if (screen->reload_all_gpu_data || screen_is_selection_dirty(screen)) {
sz = screen->lines * screen->columns;
address = alloc_and_map_vao_buffer(vao_idx, sz, selection_buffer, GL_STREAM_DRAW, GL_WRITE_ONLY);
screen_apply_selection(screen, address, sz);
@@ -453,8 +453,8 @@ draw_cells_interleaved_premult(ssize_t vao_idx, ssize_t gvao_idx, Screen *screen
}
static inline void
set_cell_uniforms(float current_inactive_text_alpha) {
if (!cell_uniform_data.constants_set) {
set_cell_uniforms(float current_inactive_text_alpha, bool force) {
if (!cell_uniform_data.constants_set || force) {
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");
@@ -467,7 +467,7 @@ set_cell_uniforms(float current_inactive_text_alpha) {
#undef S
cell_uniform_data.constants_set = true;
}
if (current_inactive_text_alpha != cell_uniform_data.prev_inactive_text_alpha) {
if (current_inactive_text_alpha != cell_uniform_data.prev_inactive_text_alpha || force) {
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);
@@ -477,10 +477,11 @@ set_cell_uniforms(float current_inactive_text_alpha) {
void
blank_canvas(float background_opacity, color_type color) {
#define C(shift) (((GLfloat)((color >> shift) & 0xFF)) / 255.0f)
glClearColor(C(16), C(8), C(0), background_opacity);
// See https://github.com/glfw/glfw/issues/1538 for why we use pre-multiplied alpha
#define C(shift) ((((GLfloat)((color >> shift) & 0xFF)) / 255.0f) * background_opacity)
glClearColor(C(16), C(8), C(0), background_opacity);
#undef C
glClear(GL_COLOR_BUFFER_BIT);
glClear(GL_COLOR_BUFFER_BIT);
}
bool
@@ -503,18 +504,21 @@ draw_cells(ssize_t vao_idx, ssize_t gvao_idx, GLfloat xstart, GLfloat ystart, GL
bind_vertex_array(vao_idx);
float current_inactive_text_alpha = (!can_be_focused || screen->cursor_render_info.is_focused) && is_active_window ? 1.0f : (float)OPT(inactive_text_alpha);
set_cell_uniforms(current_inactive_text_alpha);
set_cell_uniforms(current_inactive_text_alpha, screen->reload_all_gpu_data);
screen->reload_all_gpu_data = false;
GLfloat w = (GLfloat)screen->columns * dx, h = (GLfloat)screen->lines * dy;
// The scissor limits below are calculated to ensure that they do not
// overlap with the pixels outside the draw area,
// for a test case (scissor is also used to blit framebuffer in draw_cells_interleaved_premult) run:
// kitty -o background=cyan -o background_opacity=0.7 -o window_margin_width=40 sh -c "kitty +kitten icat logo/kitty.png; read"
// kitty -o background=cyan -o background_opacity=0.7 -o cursor_blink_interval=0 -o window_margin_width=40 sh -c "kitty +kitten icat logo/kitty.png; read"
#define SCALE(w, x) ((GLfloat)(os_window->viewport_##w) * (GLfloat)(x))
/* printf("columns=%d dx=%f w=%f vw=%d vh=%d left=%f width=%f\n", screen->columns, dx, w, os_window->viewport_width, os_window->viewport_height, SCALE(width, (xstart + 1.f)/2.f), SCALE(width, w / 2.f)); */
glScissor(
(GLint)(ceilf(SCALE(width, (xstart + 1.0f) / 2.0f))), // x
(GLint)(ceilf(SCALE(height, ((ystart - h) + 1.0f) / 2.0f))), // y
(GLsizei)(floorf(SCALE(width, w / 2.0f))), // width
(GLsizei)(floorf(SCALE(height, h / 2.0f))) // height
(GLint)roundf(SCALE(width, (xstart + 1.f)/2.f)), // x
(GLint)roundf(SCALE(height, (ystart - h + 1.f)/2.f)), // y
(GLsizei)roundf(SCALE(width, w / 2.f)), // width
(GLsizei)roundf(SCALE(height, h / 2.f)) // height
);
#undef SCALE
if (os_window->is_semi_transparent) {

View File

@@ -219,6 +219,7 @@ attach_window(id_type os_window_id, id_type tab_id, id_type id) {
w->render_data.screen->cell_size.height != osw->fonts_data->cell_height
) resize_screen(osw, w->render_data.screen, true);
else screen_dirty_sprite_positions(w->render_data.screen);
w->render_data.screen->reload_all_gpu_data = true;
break;
}
}

View File

@@ -18,25 +18,32 @@ from .rgb import alpha_blend, color_from_int
TabBarData = namedtuple('TabBarData', 'title is_active needs_attention')
DrawData = namedtuple(
'DrawData', 'leading_spaces sep trailing_spaces bell_on_tab'
' bell_fg alpha active_fg active_bg inactive_fg inactive_bg default_bg title_template')
' bell_fg alpha active_fg active_bg inactive_fg inactive_bg'
' default_bg title_template active_title_template')
def as_rgb(x):
return (x << 8) | 2
template_failures = set()
def draw_title(draw_data, screen, tab, index):
if tab.needs_attention and draw_data.bell_on_tab:
fg = screen.cursor.fg
screen.cursor.fg = draw_data.bell_fg
screen.draw('🔔 ')
screen.cursor.fg = fg
template = draw_data.title_template
if tab.is_active and draw_data.active_title_template is not None:
template = draw_data.active_title_template
try:
title = draw_data.title_template.format(title=tab.title, index=index)
title = template.format(title=tab.title, index=index)
except Exception as e:
if not hasattr(draw_title, 'template_failure_reported'):
draw_title.template_failure_reported = True
log_error('Invalid tab title template: "{}" with error: {}'.format(draw_data.title_template, e))
if template not in template_failures:
template_failures.add(template)
log_error('Invalid tab title template: "{}" with error: {}'.format(template, e))
title = tab.title
screen.draw(title)
@@ -144,7 +151,6 @@ class TabBar:
def __init__(self, os_window_id, opts):
self.os_window_id = os_window_id
self.opts = opts
draw_title.template = opts.tab_title_template
self.num_tabs = 1
self.margin_width = pt_to_px(self.opts.tab_bar_margin_width, self.os_window_id)
self.cell_width, cell_height = cell_size_for_window(self.os_window_id)
@@ -177,7 +183,8 @@ class TabBar:
self.leading_spaces, self.sep, self.trailing_spaces, self.opts.bell_on_tab, self.bell_fg,
self.opts.tab_fade, self.opts.active_tab_foreground, self.opts.active_tab_background,
self.opts.inactive_tab_foreground, self.opts.inactive_tab_background,
self.opts.background, self.opts.tab_title_template
self.opts.tab_bar_background or self.opts.background, self.opts.tab_title_template,
self.opts.active_tab_title_template
)
if self.opts.tab_bar_style == 'separator':
self.draw_func = draw_tab_with_separator
@@ -194,7 +201,9 @@ class TabBar:
self.draw_data = self.draw_data._replace(active_bg=color_from_int(spec['active_tab_background']))
if 'inactive_tab_background' in spec:
self.draw_data = self.draw_data._replace(inactive_bg=color_from_int(spec['inactive_tab_background']))
if 'background' in spec:
if 'tab_bar_background' in spec:
self.draw_data = self.draw_data._replace(default_bg=color_from_int(spec['tab_bar_background']))
elif 'background' in spec and not self.opts.tab_bar_background:
self.draw_data = self.draw_data._replace(default_bg=color_from_int(spec['background']))
self.screen.color_profile.set_configured_colors(
spec.get('inactive_tab_foreground', color_as_int(self.opts.inactive_tab_foreground)),

View File

@@ -580,6 +580,7 @@ class TabManager: # {{{
'title': tab.name or tab.title,
'layout': tab.current_layout.name,
'windows': list(tab.list_windows(active_window)),
'active_window_history': list(tab.active_window_history),
}
@property

View File

@@ -215,7 +215,7 @@ string_capabilities = {
'smam': r'\E[?7h',
# Start alternate screen
'smcup': r'\E[?1049h',
# Enster insert mode
# Enter insert mode
'smir': r'\E[4h',
# Enter application keymap mode
'smkx': r'\E[?1h',

View File

@@ -321,7 +321,7 @@ class GitHub(Base): # {{{
def get_github_data():
with open(os.environ['PENV'] + '/github') as f:
with open(os.environ['PENV'] + '/github-token') as f:
un, pw = f.read().strip().split(':')
return {'username': un, 'password': pw}

View File

@@ -212,14 +212,12 @@ def init_env(
cppflags = shlex.split(cppflags)
for el in extra_logging:
cppflags.append('-DDEBUG_{}'.format(el.upper().replace('-', '_')))
# gnu11 is needed to get monotonic.h to build on older Linux distros
std = 'c' if is_macos or ccver[0] >= 5 else 'gnu'
cflags = os.environ.get(
'OVERRIDE_CFLAGS', (
'-Wextra {} -Wno-missing-field-initializers -Wall -Wstrict-prototypes -std={}11'
'-Wextra {} -Wno-missing-field-initializers -Wall -Wstrict-prototypes -std=c11'
' -pedantic-errors -Werror {} {} -fwrapv {} {} -pipe {} -fvisibility=hidden'
).format(
float_conversion, std,
float_conversion,
optimize,
' '.join(sanitize_args),
stack_protector,
@@ -338,8 +336,11 @@ def newer(dest, *sources):
except EnvironmentError:
return True
for s in sources:
if os.path.getmtime(s) >= dtime:
return True
try:
if os.path.getmtime(s) >= dtime:
return True
except FileNotFoundError:
pass
return False