mirror of
https://github.com/kovidgoyal/kitty
synced 2026-07-28 03:01:57 +02:00
X11: Add support for custom window icon
This commit is contained in:
@@ -56,8 +56,10 @@ from .utils import (
|
|||||||
cleanup_ssh_control_masters,
|
cleanup_ssh_control_masters,
|
||||||
detach,
|
detach,
|
||||||
expandvars,
|
expandvars,
|
||||||
|
get_custom_window_icon,
|
||||||
log_error,
|
log_error,
|
||||||
parse_os_window_state,
|
parse_os_window_state,
|
||||||
|
safe_mtime,
|
||||||
single_instance,
|
single_instance,
|
||||||
startup_notification_handler,
|
startup_notification_handler,
|
||||||
unix_socket_paths,
|
unix_socket_paths,
|
||||||
@@ -170,40 +172,43 @@ 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'):
|
custom_icon_mtime, custom_icon_path = get_custom_window_icon()
|
||||||
icon_path = os.path.join(config_dir, name)
|
if custom_icon_mtime is not None and custom_icon_path is not None:
|
||||||
custom_icon_mtime = safe_mtime(icon_path)
|
from .fast_data_types import cocoa_set_app_icon, cocoa_set_dock_icon
|
||||||
if custom_icon_mtime is not None:
|
krd = getattr(sys, 'kitty_run_data')
|
||||||
from .fast_data_types import cocoa_set_app_icon, cocoa_set_dock_icon
|
bundle_path = os.path.dirname(os.path.dirname(krd.get('bundle_exe_dir')))
|
||||||
krd = getattr(sys, 'kitty_run_data')
|
icon_sentinel = os.path.join(bundle_path, 'Icon\r')
|
||||||
bundle_path = os.path.dirname(os.path.dirname(krd.get('bundle_exe_dir')))
|
sentinel_mtime = safe_mtime(icon_sentinel)
|
||||||
icon_sentinel = os.path.join(bundle_path, 'Icon\r')
|
if sentinel_mtime is None or sentinel_mtime < custom_icon_mtime:
|
||||||
sentinel_mtime = safe_mtime(icon_sentinel)
|
try:
|
||||||
if sentinel_mtime is None or sentinel_mtime < custom_icon_mtime:
|
cocoa_set_app_icon(custom_icon_path, bundle_path)
|
||||||
try:
|
except (FileNotFoundError, OSError) as e:
|
||||||
cocoa_set_app_icon(icon_path, bundle_path)
|
log_error(str(e))
|
||||||
except (FileNotFoundError, OSError) as e:
|
log_error('Failed to set custom app icon, ignoring')
|
||||||
log_error(str(e))
|
# macOS Dock does not reload icons until it is restarted, so we set
|
||||||
log_error('Failed to set custom app icon, ignoring')
|
# the application icon here. This will revert when kitty quits, but
|
||||||
# macOS Dock does not reload icons until it is restarted, so we set
|
# can't be helped since there appears to be no way to get the dock
|
||||||
# the application icon here. This will revert when kitty quits, but
|
# to reload short of killing it.
|
||||||
# can't be helped since there appears to be no way to get the dock
|
cocoa_set_dock_icon(custom_icon_path)
|
||||||
# to reload short of killing it.
|
|
||||||
cocoa_set_dock_icon(icon_path)
|
|
||||||
break
|
def get_icon128_path(base_path: str) -> str:
|
||||||
|
# max icon size on X11 64bits is 128x128
|
||||||
|
path, ext = os.path.splitext(base_path)
|
||||||
|
return f'{path}-128{ext}'
|
||||||
|
|
||||||
|
|
||||||
def set_x11_window_icon() -> None:
|
def set_x11_window_icon() -> None:
|
||||||
# max icon size on X11 64bits is 128x128
|
custom_icon_path = get_custom_window_icon()[1]
|
||||||
path, ext = os.path.splitext(logo_png_file)
|
if custom_icon_path is not None:
|
||||||
set_default_window_icon(f'{path}-128{ext}')
|
custom_icon128_path = get_icon128_path(custom_icon_path)
|
||||||
|
if safe_mtime(custom_icon128_path) is None:
|
||||||
|
set_default_window_icon(custom_icon_path)
|
||||||
|
else:
|
||||||
|
set_default_window_icon(custom_icon128_path)
|
||||||
|
else:
|
||||||
|
set_default_window_icon(get_icon128_path(logo_png_file))
|
||||||
|
|
||||||
|
|
||||||
def _run_app(opts: Options, args: CLIOptions, bad_lines: Sequence[BadLine] = ()) -> None:
|
def _run_app(opts: Options, args: CLIOptions, bad_lines: Sequence[BadLine] = ()) -> None:
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ from typing import Callable, Dict, Optional
|
|||||||
from .constants import is_macos, logo_png_file
|
from .constants import is_macos, logo_png_file
|
||||||
from .fast_data_types import get_boss
|
from .fast_data_types import get_boss
|
||||||
from .types import run_once
|
from .types import run_once
|
||||||
from .utils import log_error
|
from .utils import get_custom_window_icon, log_error
|
||||||
|
|
||||||
NotifyImplementation = Callable[[str, str, str], None]
|
NotifyImplementation = Callable[[str, str, str], None]
|
||||||
|
|
||||||
@@ -57,7 +57,7 @@ else:
|
|||||||
) -> None:
|
) -> None:
|
||||||
icf = ''
|
icf = ''
|
||||||
if icon is True:
|
if icon is True:
|
||||||
icf = logo_png_file
|
icf = get_custom_window_icon()[1] or logo_png_file
|
||||||
alloc_id = dbus_send_notification(application, icf, title, body, 'Click to see changes', timeout)
|
alloc_id = dbus_send_notification(application, icf, title, body, 'Click to see changes', timeout)
|
||||||
if alloc_id and identifier is not None:
|
if alloc_id and identifier is not None:
|
||||||
alloc_map[alloc_id] = identifier
|
alloc_map[alloc_id] = identifier
|
||||||
|
|||||||
@@ -1183,3 +1183,23 @@ def cmdline_for_hold(cmd: Sequence[str] = (), opts: Optional['Options'] = None)
|
|||||||
import shlex
|
import shlex
|
||||||
shell = shlex.join(resolved_shell(opts))
|
shell = shlex.join(resolved_shell(opts))
|
||||||
return [kitten_exe(), 'run-shell', f'--shell={shell}', f'--shell-integration={ksi}'] + list(cmd)
|
return [kitten_exe(), 'run-shell', f'--shell={shell}', f'--shell-integration={ksi}'] + list(cmd)
|
||||||
|
|
||||||
|
|
||||||
|
def safe_mtime(path: str) -> Optional[float]:
|
||||||
|
with suppress(OSError):
|
||||||
|
return os.path.getmtime(path)
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
@run_once
|
||||||
|
def get_custom_window_icon() -> Union[Tuple[float, str], Tuple[None, None]]:
|
||||||
|
filenames = ['kitty.app.png']
|
||||||
|
if is_macos:
|
||||||
|
# On macOS, prefer icns to png.
|
||||||
|
filenames.insert(0, 'kitty.app.icns')
|
||||||
|
for name in filenames:
|
||||||
|
custom_icon_path = os.path.join(config_dir, name)
|
||||||
|
custom_icon_mtime = safe_mtime(custom_icon_path)
|
||||||
|
if custom_icon_mtime is not None:
|
||||||
|
return custom_icon_mtime, custom_icon_path
|
||||||
|
return None, None
|
||||||
|
|||||||
Reference in New Issue
Block a user