Fix window icon not working on X11 with 64bits

Apparently on X11 the maximum icon size is 128x128. 256x256 is too
large for the X11 protocol because the X server unserializes the icons
using "unsigned long" which is 64 bits on Linux. So we have to use
64bits per pixel instead of 32, with 32bits padded to 0.

While there I also got rid of the kitty.rgba file replacing it with a
128x128 PNG file.

Fixes #3260
This commit is contained in:
Kovid Goyal 2021-01-25 20:51:34 +05:30
parent 6e73d3fac8
commit 5a2f2767ad
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
10 changed files with 28 additions and 19 deletions

View File

@ -44,6 +44,8 @@ To update |kitty|, :doc:`follow the instructions <binary>`.
- Fix extra space at bottom of OS window when using the fat layout with the tab bar at the
top (:iss:`3258`)
- Fix window icon not working on X11 with 64bits (:iss:`3260`)
0.19.3 [2020-12-19]
-------------------

11
glfw/x11_window.c vendored
View File

@ -1990,8 +1990,8 @@ void _glfwPlatformSetWindowIcon(_GLFWwindow* window,
for (i = 0; i < count; i++)
longCount += 2 + images[i].width * images[i].height;
long* icon = calloc(longCount, sizeof(long));
long* target = icon;
unsigned long* icon = calloc(longCount, sizeof(unsigned long));
unsigned long* target = icon;
for (i = 0; i < count; i++)
{
@ -2000,10 +2000,9 @@ void _glfwPlatformSetWindowIcon(_GLFWwindow* window,
for (j = 0; j < images[i].width * images[i].height; j++)
{
*target++ = (images[i].pixels[j * 4 + 0] << 16) |
(images[i].pixels[j * 4 + 1] << 8) |
(images[i].pixels[j * 4 + 2] << 0) |
(images[i].pixels[j * 4 + 3] << 24);
unsigned char *p = images->pixels + j * 4;
const unsigned char r = *p++, g = *p++, b = *p++, a = *p++;
*target++ = a << 24 | (r << 16) | (g << 8) | b;
}
}

View File

@ -118,7 +118,6 @@ def wakeup() -> None:
base_dir = os.path.dirname(base)
terminfo_dir = os.path.join(base_dir, 'terminfo')
logo_data_file = os.path.join(base_dir, 'logo', 'kitty.rgba')
logo_png_file = os.path.join(base_dir, 'logo', 'kitty.png')
beam_cursor_data_file = os.path.join(base_dir, 'logo', 'beam-cursor.png')
try:

View File

@ -525,7 +525,7 @@ def set_smallest_allowed_resize(width: int, height: int) -> None:
pass
def set_default_window_icon(data: bytes, width: int, height: int) -> None:
def set_default_window_icon(path: str) -> None:
pass

View File

@ -393,12 +393,15 @@ static GLFWimage logo = {0};
static PyObject*
set_default_window_icon(PyObject UNUSED *self, PyObject *args) {
Py_ssize_t sz;
const char *logo_data;
if(!PyArg_ParseTuple(args, "s#ii", &(logo_data), &sz, &(logo.width), &(logo.height))) return NULL;
sz = (MAX(logo.width * logo.height, sz));
logo.pixels = malloc(sz);
if (logo.pixels) memcpy(logo.pixels, logo_data, sz);
size_t sz;
unsigned int width, height;
const char *path;
uint8_t *data;
if(!PyArg_ParseTuple(args, "s", &path)) return NULL;
if (png_path_to_bitmap(path, &data, &width, &height, &sz)) {
logo.width = width; logo.height = height;
logo.pixels = data;
}
Py_RETURN_NONE;
}

View File

@ -18,7 +18,7 @@ from .conf.utils import BadLine
from .config import cached_values_for
from .constants import (
appname, beam_cursor_data_file, config_dir, glfw_path, is_macos,
is_wayland, kitty_exe, logo_data_file, running_in_kitty
is_wayland, kitty_exe, logo_png_file, running_in_kitty
)
from .fast_data_types import (
GLFW_IBEAM_CURSOR, create_os_window, free_font_data, glfw_init,
@ -121,6 +121,12 @@ def get_macos_shortcut_for(opts: OptionsStub, function: str = 'new_os_window') -
return ans
def set_x11_window_icon() -> None:
# max icon size on X11 64bits is 128x128
path = logo_png_file.replace('.', '-128.')
set_default_window_icon(path)
def _run_app(opts: OptionsStub, args: CLIOptions, bad_lines: Sequence[BadLine] = ()) -> None:
global_shortcuts: Dict[str, SingleKey] = {}
if is_macos:
@ -131,8 +137,7 @@ def _run_app(opts: OptionsStub, args: CLIOptions, bad_lines: Sequence[BadLine] =
if is_macos and opts.macos_custom_beam_cursor:
set_custom_ibeam_cursor()
if not is_wayland() and not is_macos: # no window icons on wayland
with open(logo_data_file, 'rb') as f:
set_default_window_icon(f.read(), 256, 256)
set_x11_window_icon()
load_shader_programs.use_selection_fg = opts.selection_foreground is not None
with cached_values_for(run_app.cached_values_name) as cached_values:
with startup_notification_handler(extra_callback=run_app.first_window_callback) as pre_show_callback:

BIN
logo/kitty-128.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

View File

@ -29,7 +29,6 @@ def render(output, sz=256):
def main():
render(abspath('kitty.png'))
run('convert', abspath('kitty.png'), '-depth', '8', abspath('kitty.rgba'))
iconset = abspath('kitty.iconset')
if os.path.exists(iconset):
shutil.rmtree(iconset)
@ -39,6 +38,8 @@ def main():
iname = os.path.join(iconset, 'icon_{0}x{0}.png'.format(sz))
iname2x = 'icon_{0}x{0}@2x.png'.format(sz // 2)
render(iname, sz)
if sz == 128:
shutil.copyfile(iname, abspath('kitty-128.png'))
if sz > 16 and sz != 128:
shutil.copy2(iname, iname2x)
if sz in (64, 1024):

View File

@ -1034,7 +1034,7 @@ def package(args: Options, bundle_type: str) -> None:
safe_makedirs(odir)
build_terminfo['compile_terminfo'](odir)
shutil.copy2('__main__.py', libdir)
shutil.copy2('logo/kitty.rgba', os.path.join(libdir, 'logo'))
shutil.copy2('logo/kitty-128.png', os.path.join(libdir, 'logo'))
shutil.copy2('logo/kitty.png', os.path.join(libdir, 'logo'))
shutil.copy2('logo/beam-cursor.png', os.path.join(libdir, 'logo'))
shutil.copy2('logo/beam-cursor@2x.png', os.path.join(libdir, 'logo'))