Work on moving launch services handling into C
This will make it faster and also more robust, not recuring hacks like re-execs.
This commit is contained in:
parent
76ac66fc8c
commit
05f0839add
5 changed files with 49 additions and 50 deletions
|
|
@ -1,7 +1,6 @@
|
|||
#!/usr/bin/env python
|
||||
# License: GPL v3 Copyright: 2016, Kovid Goyal <kovid at kovidgoyal.net>
|
||||
|
||||
import errno
|
||||
import os
|
||||
import pwd
|
||||
import sys
|
||||
|
|
@ -32,6 +31,7 @@ class Version(NamedTuple):
|
|||
RC_ENCRYPTION_PROTOCOL_VERSION = '1'
|
||||
website_base_url = 'https://sw.kovidgoyal.net/kitty/'
|
||||
default_pager_for_help = ('less', '-iRXF')
|
||||
launched_by_launch_services = getattr(sys, 'kitty_run_data')['launched_by_launch_services']
|
||||
if getattr(sys, 'frozen', False):
|
||||
extensions_dir: str = getattr(sys, 'kitty_run_data')['extensions_dir']
|
||||
|
||||
|
|
@ -86,46 +86,17 @@ def kitten_exe() -> str:
|
|||
|
||||
|
||||
def _get_config_dir() -> str:
|
||||
if 'KITTY_CONFIG_DIRECTORY' in os.environ:
|
||||
return os.path.abspath(os.path.expanduser(os.environ['KITTY_CONFIG_DIRECTORY']))
|
||||
|
||||
locations = []
|
||||
if 'XDG_CONFIG_HOME' in os.environ:
|
||||
locations.append(os.path.abspath(os.path.expanduser(os.environ['XDG_CONFIG_HOME'])))
|
||||
locations.append(os.path.expanduser('~/.config'))
|
||||
if is_macos:
|
||||
locations.append(os.path.expanduser('~/Library/Preferences'))
|
||||
for loc in filter(None, os.environ.get('XDG_CONFIG_DIRS', '').split(os.pathsep)):
|
||||
locations.append(os.path.abspath(os.path.expanduser(loc)))
|
||||
for loc in locations:
|
||||
if loc:
|
||||
q = os.path.join(loc, appname)
|
||||
if os.access(q, os.W_OK) and os.path.exists(os.path.join(q, 'kitty.conf')):
|
||||
return q
|
||||
|
||||
def make_tmp_conf() -> None:
|
||||
import atexit
|
||||
import tempfile
|
||||
ans = tempfile.mkdtemp(prefix='kitty-conf-')
|
||||
|
||||
def cleanup() -> None:
|
||||
import shutil
|
||||
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(os.path.realpath(ans), exist_ok=True)
|
||||
except FileExistsError:
|
||||
raise SystemExit(f'A file {ans} already exists. It must be a directory, not a file.')
|
||||
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()
|
||||
cdir = getattr(sys, 'kitty_run_data').get('config_dir', '')
|
||||
if cdir:
|
||||
return str(cdir)
|
||||
import atexit
|
||||
import tempfile
|
||||
ans = tempfile.mkdtemp(prefix='kitty-conf-')
|
||||
def cleanup() -> None:
|
||||
import shutil
|
||||
with suppress(Exception):
|
||||
shutil.rmtree(ans)
|
||||
atexit.register(cleanup)
|
||||
return ans
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -16,12 +16,14 @@
|
|||
#else
|
||||
#include <limits.h>
|
||||
#endif
|
||||
#include <pwd.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#include <fcntl.h>
|
||||
#include "launcher.h"
|
||||
#include "utils.h"
|
||||
|
||||
#ifndef KITTY_LIB_PATH
|
||||
#define KITTY_LIB_PATH "../.."
|
||||
|
|
@ -45,9 +47,10 @@ safe_realpath(const char* src, char *buf, size_t buf_sz) {
|
|||
#endif
|
||||
|
||||
typedef struct {
|
||||
const char *exe, *exe_dir, *lc_ctype, *lib_dir;
|
||||
const char *exe, *exe_dir, *lc_ctype, *lib_dir, *config_dir;
|
||||
char **argv;
|
||||
int argc;
|
||||
bool launched_by_launch_services;
|
||||
} RunData;
|
||||
|
||||
static bool
|
||||
|
|
@ -70,6 +73,20 @@ set_kitty_run_data(RunData *run_data, bool from_source, wchar_t *extensions_dir)
|
|||
PyObject *ed = PyUnicode_FromWideChar(extensions_dir, -1);
|
||||
S(extensions_dir, ed);
|
||||
}
|
||||
PyObject *lbls = run_data->launched_by_launch_services ? Py_True : Py_False;
|
||||
Py_INCREF(lbls);
|
||||
S(launched_by_launch_services, lbls);
|
||||
|
||||
char buf[PATH_MAX + 1];
|
||||
if (run_data->config_dir == NULL) {
|
||||
if (get_config_dir(buf, sizeof(buf))) run_data->config_dir = buf;
|
||||
}
|
||||
if (run_data->config_dir) {
|
||||
PyObject *cdir = PyUnicode_DecodeFSDefaultAndSize(run_data->config_dir, strlen(run_data->config_dir));
|
||||
if (!cdir) { PyErr_Print(); return false; }
|
||||
S(config_dir, cdir);
|
||||
}
|
||||
|
||||
#undef S
|
||||
int ret = PySys_SetObject("kitty_run_data", ans);
|
||||
Py_CLEAR(ans);
|
||||
|
|
@ -493,9 +510,18 @@ int main(int argc, char *argv[], char* envp[]) {
|
|||
char exe[PATH_MAX+1] = {0};
|
||||
char exe_dir_buf[PATH_MAX+1] = {0};
|
||||
RAII_ALLOC(const char, lc_ctype, NULL);
|
||||
bool launched_by_launch_services = false;
|
||||
const char *config_dir = NULL;
|
||||
#ifdef __APPLE__
|
||||
lc_ctype = getenv("LC_CTYPE");
|
||||
if (lc_ctype) lc_ctype = strdup(lc_ctype);
|
||||
if (getenv("KITTY_LAUNCHED_BY_LAUNCH_SERVICES")) {
|
||||
launched_by_launch_services = true;
|
||||
unsetenv("KITTY_LAUNCHED_BY_LAUNCH_SERVICES");
|
||||
char buf[PATH_MAX+1];
|
||||
if (!get_config_dir(buf,sizeof(buf))) buf[0] = 0;
|
||||
config_dir = buf;
|
||||
}
|
||||
#endif
|
||||
if (!read_exe_path(exe, sizeof(exe))) return 1;
|
||||
strncpy(exe_dir_buf, exe, sizeof(exe_dir_buf));
|
||||
|
|
@ -510,7 +536,10 @@ int main(int argc, char *argv[], char* envp[]) {
|
|||
}
|
||||
|
||||
if (num < 0 || num >= PATH_MAX) { fprintf(stderr, "Failed to create path to kitty lib\n"); return 1; }
|
||||
RunData run_data = {.exe = exe, .exe_dir = exe_dir, .lib_dir = lib, .argc = argc, .argv = argv, .lc_ctype = lc_ctype};
|
||||
RunData run_data = {
|
||||
.exe = exe, .exe_dir = exe_dir, .lib_dir = lib, .argc = argc, .argv = argv, .lc_ctype = lc_ctype,
|
||||
.launched_by_launch_services=launched_by_launch_services, .config_dir = config_dir,
|
||||
};
|
||||
ret = run_embedded(&run_data);
|
||||
single_instance_main(-1, NULL, NULL);
|
||||
Py_FinalizeEx();
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ home_path_for(const char *username) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static inline void
|
||||
static void
|
||||
expand_tilde(const char* path, char *ans, size_t ans_sz) {
|
||||
if (path[0] != '~') {
|
||||
snprintf(ans, ans_sz, "%s", path);
|
||||
|
|
@ -162,7 +162,7 @@ is_dir_ok_for_config(char *q) {
|
|||
return access(q, W_OK) == 0;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
static bool
|
||||
get_config_dir(char *output, size_t outputsz) {
|
||||
const char *q;
|
||||
char buf1[PATH_MAX], buf2[PATH_MAX];
|
||||
|
|
|
|||
|
|
@ -85,9 +85,5 @@ static PyMethodDef module_methods[] = {
|
|||
bool
|
||||
init_logging(PyObject *module) {
|
||||
if (PyModule_AddFunctions(module, module_methods) != 0) return false;
|
||||
#ifdef __APPLE__
|
||||
// This env var can be either 1 or 2
|
||||
if (getenv("KITTY_LAUNCHED_BY_LAUNCH_SERVICES") != NULL) use_os_log = true;
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@
|
|||
is_wayland,
|
||||
kitten_exe,
|
||||
kitty_exe,
|
||||
launched_by_launch_services,
|
||||
logo_png_file,
|
||||
running_in_kitty,
|
||||
supports_window_occlusion,
|
||||
|
|
@ -46,6 +47,7 @@
|
|||
set_custom_cursor,
|
||||
set_default_window_icon,
|
||||
set_options,
|
||||
set_use_os_log,
|
||||
)
|
||||
from .fonts.render import dump_font_debug, set_font_family
|
||||
from .options.types import Options
|
||||
|
|
@ -479,9 +481,10 @@ def _main() -> None:
|
|||
running_in_kitty(True)
|
||||
|
||||
args = sys.argv[1:]
|
||||
if is_macos and os.environ.pop('KITTY_LAUNCHED_BY_LAUNCH_SERVICES', None) == '1':
|
||||
if is_macos and launched_by_launch_services:
|
||||
os.chdir(os.path.expanduser('~'))
|
||||
args = macos_cmdline(args)
|
||||
set_use_os_log(True)
|
||||
try:
|
||||
cwd_ok = os.path.isdir(os.getcwd())
|
||||
except Exception:
|
||||
|
|
|
|||
Loading…
Reference in a new issue