Cleanup previous PR

1) Dont use deprecated code
2) Always set the dock icon on startup as the dock icon doesnt change
   till the dock is restarted
3) Update the app icon automatically if the mtime on the custom icon in
   the config dir is newer than the mtime of the sentinel file apple
   puts inside the application bundle to indicate it has a custom icon
This commit is contained in:
Kovid Goyal 2022-09-25 18:11:17 +05:30
parent d0769f3979
commit 901e00cab1
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
5 changed files with 42 additions and 62 deletions

View File

@ -38,9 +38,10 @@ Detailed list of changes
0.26.4 [future] 0.26.4 [future]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- macOS: Allow changing the kitty icon by placing a custom icon in the kitty config folder (:pull:`5464`)
- X11: Fix a regression in the previous release that caused pasting from GTK based applications to have extra newlines (:iss:`5528`) - X11: Fix a regression in the previous release that caused pasting from GTK based applications to have extra newlines (:iss:`5528`)
- macOS: Allow to set custom app icon automatically (:pull:`5464`)
0.26.3 [2022-09-22] 0.26.3 [2022-09-22]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@ -289,12 +289,16 @@ homepage:
On macOS you can put :file:`kitty.app.icns` or :file:`kitty.app.png` in the On macOS you can put :file:`kitty.app.icns` or :file:`kitty.app.png` in the
:ref:`kitty configuration directory <confloc>`, and this icon will be applied :ref:`kitty configuration directory <confloc>`, and this icon will be applied
automatically at startup if the :file:`kitty.app` bundle has no custom icon. This is automatically at startup. Unfortunately, Apple's Dock does not change its
convenient because updates under macOS replace the entire :file:`kitty.app` bundle cached icon so the custom icon will revert when kitty is quit. Run the
and the custom icon will be removed as well. To automatically update a new icon following to force the Dock to update its cached icons:
at startup, you need to remove the custom icon on :file:`kitty.app` first.
You can set custom icon via CLI, which can be used in shell scripts: .. code-block:: sh
rm /var/folders/*/*/*/com.apple.dock.iconcache; killall Dock
If you prefer not to keep a custom icon in the kitty config folder, you can
also set it with the following command:
.. code-block:: sh .. code-block:: sh
@ -308,9 +312,11 @@ You can also change the icon manually by following the steps:
#. Find :file:`kitty.app` in the Applications folder, select it and press :kbd:`⌘+I` #. Find :file:`kitty.app` in the Applications folder, select it and press :kbd:`⌘+I`
#. Drag :file:`kitty.icns` onto the application icon in the kitty info pane #. Drag :file:`kitty.icns` onto the application icon in the kitty info pane
#. Delete the icon cache and restart Dock:: #. Delete the icon cache and restart Dock:
$ rm /var/folders/*/*/*/com.apple.dock.iconcache; killall Dock .. code-block:: sh
rm /var/folders/*/*/*/com.apple.dock.iconcache; killall Dock
How do I map key presses in kitty to different keys in the terminal program? How do I map key presses in kitty to different keys in the terminal program?

View File

@ -862,39 +862,6 @@ cocoa_set_url_handler(PyObject UNUSED *self, PyObject *args) {
} // autoreleasepool } // autoreleasepool
} }
static PyObject*
cocoa_app_has_custom_icon(PyObject UNUSED *self, PyObject *args) {
@autoreleasepool {
const char *app_path = NULL;
if (!PyArg_ParseTuple(args, "|z", &app_path)) return NULL;
NSString *bundle_path;
if (app_path && app_path[0] != '\0') bundle_path = [NSString stringWithUTF8String:app_path];
else bundle_path = [[NSBundle mainBundle] bundlePath];
if (!bundle_path || bundle_path.length == 0) bundle_path = @"/Applications/kitty.app";
// These APIs have been marked as deprecated.
// However support for NSURLCustomIconKey has never been implemented by Apple (so far, macOS 12.5.x and below).
// so the following NSImage icon_image will be nil even if a custom icon is set:
// [[NSURL fileURLWithPath:bundle_path] getResourceValue:&icon_image forKey:NSURLCustomIconKey error:nil]
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
FSRef ref;
FSCatalogInfo catalog_info;
OSStatus err = FSPathMakeRef((const UInt8 *)[bundle_path fileSystemRepresentation], &ref, NULL);
if (err == noErr) {
err = FSGetCatalogInfo(&ref, kFSCatInfoFinderInfo, &catalog_info, NULL, NULL, NULL);
if (err == noErr) {
FileInfo *file_info = (FileInfo *)(&catalog_info.finderInfo);
if ((file_info->finderFlags & kHasCustomIcon) != 0) Py_RETURN_TRUE;
}
}
#pragma clang diagnostic pop
Py_RETURN_FALSE;
} // autoreleasepool
}
static PyObject* static PyObject*
cocoa_set_app_icon(PyObject UNUSED *self, PyObject *args) { cocoa_set_app_icon(PyObject UNUSED *self, PyObject *args) {
@autoreleasepool { @autoreleasepool {
@ -1015,7 +982,6 @@ static PyMethodDef module_methods[] = {
{"cocoa_send_notification", (PyCFunction)cocoa_send_notification, METH_VARARGS, ""}, {"cocoa_send_notification", (PyCFunction)cocoa_send_notification, METH_VARARGS, ""},
{"cocoa_set_notification_activated_callback", (PyCFunction)set_notification_activated_callback, METH_O, ""}, {"cocoa_set_notification_activated_callback", (PyCFunction)set_notification_activated_callback, METH_O, ""},
{"cocoa_set_url_handler", (PyCFunction)cocoa_set_url_handler, METH_VARARGS, ""}, {"cocoa_set_url_handler", (PyCFunction)cocoa_set_url_handler, METH_VARARGS, ""},
{"cocoa_app_has_custom_icon", (PyCFunction)cocoa_app_has_custom_icon, METH_VARARGS, ""},
{"cocoa_set_app_icon", (PyCFunction)cocoa_set_app_icon, METH_VARARGS, ""}, {"cocoa_set_app_icon", (PyCFunction)cocoa_set_app_icon, METH_VARARGS, ""},
{"cocoa_set_dock_icon", (PyCFunction)cocoa_set_dock_icon, METH_VARARGS, ""}, {"cocoa_set_dock_icon", (PyCFunction)cocoa_set_dock_icon, METH_VARARGS, ""},
{NULL, NULL, 0, NULL} /* Sentinel */ {NULL, NULL, 0, NULL} /* Sentinel */

View File

@ -734,10 +734,6 @@ def cocoa_set_url_handler(url_scheme: str, bundle_id: Optional[str] = None) -> N
pass pass
def cocoa_app_has_custom_icon(app_path: Optional[str] = None) -> bool:
pass
def cocoa_set_app_icon(icon_path: str, app_path: Optional[str] = None) -> None: def cocoa_set_app_icon(icon_path: str, app_path: Optional[str] = None) -> None:
pass pass

View File

@ -16,14 +16,13 @@ from .cli_stub import CLIOptions
from .conf.utils import BadLine from .conf.utils import BadLine
from .config import cached_values_for from .config import cached_values_for
from .constants import ( from .constants import (
appname, beam_cursor_data_file, clear_handled_signals, config_dir, appname, beam_cursor_data_file, clear_handled_signals, config_dir, glfw_path,
glfw_path, is_macos, is_wayland, kitty_exe, logo_png_file, is_macos, is_wayland, kitty_exe, logo_png_file, running_in_kitty, website_url,
running_in_kitty, website_url
) )
from .fast_data_types import ( from .fast_data_types import (
GLFW_IBEAM_CURSOR, GLFW_MOD_ALT, GLFW_MOD_SHIFT, SingleKey, GLFW_IBEAM_CURSOR, GLFW_MOD_ALT, GLFW_MOD_SHIFT, SingleKey, create_os_window,
create_os_window, free_font_data, glfw_init, glfw_terminate, load_png_data, free_font_data, glfw_init, glfw_terminate, load_png_data, set_custom_cursor,
set_custom_cursor, set_default_window_icon, set_options set_default_window_icon, set_options,
) )
from .fonts.box_drawing import set_scale from .fonts.box_drawing import set_scale
from .fonts.render import set_font_family from .fonts.render import set_font_family
@ -33,8 +32,8 @@ from .os_window_size import initial_window_size_func
from .prewarm import PrewarmProcess, fork_prewarm_process from .prewarm import PrewarmProcess, fork_prewarm_process
from .session import create_sessions, get_os_window_sizing_data from .session import create_sessions, get_os_window_sizing_data
from .utils import ( from .utils import (
cleanup_ssh_control_masters, detach, expandvars, log_error, cleanup_ssh_control_masters, detach, expandvars, log_error, single_instance,
single_instance, startup_notification_handler, unix_socket_paths startup_notification_handler, unix_socket_paths,
) )
from .window import load_shader_programs from .window import load_shader_programs
@ -135,16 +134,28 @@ def get_macos_shortcut_for(
return ans return ans
def safe_mtime(path: str) -> Optional[float]:
with suppress(OSError):
return os.path.getmtime(path)
return None
def set_macos_app_custom_icon() -> None: def set_macos_app_custom_icon() -> None:
for name in ('kitty.app.icns', 'kitty.app.png'): for name in ('kitty.app.icns', 'kitty.app.png'):
icon_path = os.path.join(config_dir, name) icon_path = os.path.join(config_dir, name)
if os.path.exists(icon_path): custom_icon_mtime = safe_mtime(icon_path)
from .fast_data_types import cocoa_app_has_custom_icon, cocoa_set_app_icon, cocoa_set_dock_icon if custom_icon_mtime is not None:
if not cocoa_app_has_custom_icon(): from .fast_data_types import cocoa_set_app_icon, cocoa_set_dock_icon
krd = getattr(sys, 'kitty_run_data')
bundle_path = os.path.dirname(os.path.dirname(krd.get('bundle_exe_dir')))
icon_sentinel = os.path.join(bundle_path, 'Icon\r')
sentinel_mtime = safe_mtime(icon_sentinel)
if sentinel_mtime is None or sentinel_mtime < custom_icon_mtime:
cocoa_set_app_icon(icon_path) cocoa_set_app_icon(icon_path)
# kitty dock icon doesn't refresh automatically, so set it explicitly # macOS Dock does not reload icons until it is restarted, so we set
# This has the drawback that the dock icon reverts to the original icon after exiting the application, # the application icon here. This will revert when kitty quits, but
# even if the custom icon has been successfully updated, until the next launch. # cant be helped since there appears to be no way to get the dock
# to reload short of killing it.
cocoa_set_dock_icon(icon_path) cocoa_set_dock_icon(icon_path)
break break
@ -225,7 +236,7 @@ class AppRunner:
free_font_data() # must free font data before glfw/freetype/fontconfig/opengl etc are finalized free_font_data() # must free font data before glfw/freetype/fontconfig/opengl etc are finalized
if is_macos: if is_macos:
from kitty.fast_data_types import ( from kitty.fast_data_types import (
cocoa_set_notification_activated_callback cocoa_set_notification_activated_callback,
) )
cocoa_set_notification_activated_callback(None) cocoa_set_notification_activated_callback(None)