Compare commits
69 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
97af84a063 | ||
|
|
18faee6250 | ||
|
|
fd90a3ddc3 | ||
|
|
a08931d84d | ||
|
|
2f0b6e24c9 | ||
|
|
33c5fc0fb6 | ||
|
|
71adb2dcf8 | ||
|
|
1ae324691d | ||
|
|
689d059517 | ||
|
|
18f0ab9e02 | ||
|
|
088ab5f137 | ||
|
|
3dd83975ba | ||
|
|
a796a6cbef | ||
|
|
4766d7de82 | ||
|
|
4a3686c16c | ||
|
|
b49105495c | ||
|
|
ca2eda2c5b | ||
|
|
4fc7c4aafc | ||
|
|
0981828493 | ||
|
|
6bc4f18a59 | ||
|
|
79532a315c | ||
|
|
7472a992ed | ||
|
|
e40616a0db | ||
|
|
dd8b97a86c | ||
|
|
5eff3897de | ||
|
|
530cf2eb14 | ||
|
|
2baa34beb8 | ||
|
|
87e2f7f86d | ||
|
|
e142083d53 | ||
|
|
2e850a0d0d | ||
|
|
aec9c31bca | ||
|
|
598a147500 | ||
|
|
ba201c4c92 | ||
|
|
5bc7cfaa43 | ||
|
|
2804e1ff81 | ||
|
|
ae27d36902 | ||
|
|
08182fbe4d | ||
|
|
778474f436 | ||
|
|
c6698ce305 | ||
|
|
21bc215313 | ||
|
|
88a9cc42d2 | ||
|
|
28f33a67cf | ||
|
|
6742fabfba | ||
|
|
b3806f4533 | ||
|
|
6d5fb4ccc6 | ||
|
|
2487f18f24 | ||
|
|
f59afff1d1 | ||
|
|
b92f95b092 | ||
|
|
d68ae01448 | ||
|
|
87eda834d3 | ||
|
|
7bf0afa621 | ||
|
|
e3e02c7271 | ||
|
|
24e17cb7d8 | ||
|
|
769998adca | ||
|
|
9b5d88e92d | ||
|
|
6d7bebee3a | ||
|
|
1c38654321 | ||
|
|
da7a78691f | ||
|
|
1eaf7083ef | ||
|
|
79a6fcdc5c | ||
|
|
90bcbbf426 | ||
|
|
41049e2a40 | ||
|
|
c9b8510e9c | ||
|
|
d854fc1cd0 | ||
|
|
5f7bcae072 | ||
|
|
652eec3033 | ||
|
|
a9928ec98a | ||
|
|
e1dfb608ca | ||
|
|
2cee3a8809 |
@@ -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]
|
||||
--------------------
|
||||
|
||||
|
||||
8
glfw/backend_utils.c
vendored
8
glfw/backend_utils.c
vendored
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
2
glfw/cocoa_platform.h
vendored
2
glfw/cocoa_platform.h
vendored
@@ -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
61
glfw/cocoa_time.c
vendored
@@ -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;
|
||||
}
|
||||
@@ -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
31
glfw/egl_context.c
vendored
@@ -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
75
glfw/glfw3.h
vendored
@@ -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 / 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
2
glfw/init.c
vendored
@@ -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
25
glfw/input.c
vendored
@@ -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
9
glfw/internal.h
vendored
@@ -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
10
glfw/monotonic.c
vendored
Normal 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"
|
||||
@@ -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
2
glfw/null_init.c
vendored
@@ -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
87
glfw/posix_time.c
vendored
@@ -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
44
glfw/posix_time.h
vendored
@@ -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);
|
||||
|
||||
@@ -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
3
glfw/wl_init.c
vendored
@@ -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
1
glfw/wl_platform.h
vendored
@@ -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
2
glfw/x11_init.c
vendored
@@ -635,8 +635,6 @@ int _glfwPlatformInit(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
_glfwInitTimerPOSIX();
|
||||
|
||||
_glfwPollMonitorsX11();
|
||||
return true;
|
||||
}
|
||||
|
||||
1
glfw/x11_platform.h
vendored
1
glfw/x11_platform.h
vendored
@@ -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
115
glfw/x11_window.c
vendored
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
)
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
12
kitty/choose_entry.py
Normal 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})
|
||||
@@ -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
|
||||
|
||||
@@ -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.'''))
|
||||
|
||||
# }}}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
38
kitty/gl-wrapper.h
generated
@@ -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
9
kitty/glfw-wrapper.c
generated
@@ -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
12
kitty/glfw-wrapper.h
generated
@@ -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
|
||||
|
||||
@@ -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
10
kitty/monotonic.c
Normal 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"
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)),
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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}
|
||||
|
||||
|
||||
13
setup.py
13
setup.py
@@ -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
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user